DatabaseManager.java 4.28 KB
Newer Older
Melledy's avatar
Melledy committed
1
2
3
package emu.grasscutter.database;

import com.mongodb.MongoCommandException;
KingRainbow44's avatar
KingRainbow44 committed
4
5
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
Melledy's avatar
Melledy committed
6
7
8
9
10
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoIterable;

import dev.morphia.Datastore;
import dev.morphia.Morphia;
KingRainbow44's avatar
KingRainbow44 committed
11
12
import dev.morphia.mapping.MapperOptions;
import dev.morphia.query.experimental.filters.Filters;
Melledy's avatar
Melledy committed
13
import emu.grasscutter.Grasscutter;
14
import emu.grasscutter.Grasscutter.ServerRunMode;
Melledy's avatar
Melledy committed
15
import emu.grasscutter.game.Account;
Akka's avatar
Akka committed
16
import emu.grasscutter.game.activity.PlayerActivityData;
Akka's avatar
Akka committed
17
import emu.grasscutter.game.activity.musicgame.MusicGameBeatmap;
18
import emu.grasscutter.game.avatar.Avatar;
19
import emu.grasscutter.game.battlepass.BattlePassManager;
Melledy's avatar
Melledy committed
20
import emu.grasscutter.game.friends.Friendship;
21
import emu.grasscutter.game.gacha.GachaRecord;
22
import emu.grasscutter.game.home.GameHome;
23
import emu.grasscutter.game.inventory.GameItem;
24
import emu.grasscutter.game.mail.Mail;
Melledy's avatar
Melledy committed
25
import emu.grasscutter.game.player.Player;
Melledy's avatar
Melledy committed
26
27
import emu.grasscutter.game.quest.GameMainQuest;
import emu.grasscutter.game.quest.GameQuest;
Melledy's avatar
Melledy committed
28

29
import static emu.grasscutter.Configuration.*;
30

31
public final class DatabaseManager {
32
	private static Datastore gameDatastore;
33
	private static Datastore dispatchDatastore;
Akka's avatar
Akka committed
34

KingRainbow44's avatar
KingRainbow44 committed
35
	private static final Class<?>[] mappedClasses = new Class<?>[] {
Akka's avatar
Akka committed
36
		DatabaseCounter.class, Account.class, Player.class, Avatar.class, GameItem.class, Friendship.class,
Akka's avatar
Akka committed
37
38
		GachaRecord.class, Mail.class, GameMainQuest.class, GameHome.class, BattlePassManager.class,
        PlayerActivityData.class, MusicGameBeatmap.class
Melledy's avatar
Melledy committed
39
	};
Akka's avatar
Akka committed
40

41
42
    public static Datastore getGameDatastore() {
    	return gameDatastore;
Melledy's avatar
Melledy committed
43
    }
Akka's avatar
Akka committed
44

45
46
    public static MongoDatabase getGameDatabase() {
    	return getGameDatastore().getDatabase();
Melledy's avatar
Melledy committed
47
    }
48

Benjamin Elsdon's avatar
Benjamin Elsdon committed
49
50
	// Yes. I very dislike this method. However, this will be good for now.
	// TODO: Add dispatch routes for player account management
51
	public static Datastore getAccountDatastore() {
52
		if(SERVER.runMode == ServerRunMode.GAME_ONLY) {
53
54
			return dispatchDatastore;
		} else {
55
			return gameDatastore;
56
57
		}
	}
Melledy's avatar
Melledy committed
58
59
60
	
	public static void initialize() {
		// Initialize
61
		MongoClient gameMongoClient = MongoClients.create(DATABASE.game.connectionUri);
Melledy's avatar
Melledy committed
62
		
KingRainbow44's avatar
KingRainbow44 committed
63
64
65
66
		// Set mapper options.
		MapperOptions mapperOptions = MapperOptions.builder()
				.storeEmpties(true).storeNulls(false).build();
		// Create data store.
67
		gameDatastore = Morphia.createDatastore(gameMongoClient, DATABASE.game.collection, mapperOptions);
KingRainbow44's avatar
KingRainbow44 committed
68
		// Map classes.
69
		gameDatastore.getMapper().map(mappedClasses);
Melledy's avatar
Melledy committed
70
71
72
		
		// Ensure indexes
		try {
73
			gameDatastore.ensureIndexes();
KingRainbow44's avatar
KingRainbow44 committed
74
75
		} catch (MongoCommandException exception) {
			Grasscutter.getLogger().info("Mongo index error: ", exception);
Melledy's avatar
Melledy committed
76
			// Duplicate index error
KingRainbow44's avatar
KingRainbow44 committed
77
			if (exception.getCode() == 85) {
Melledy's avatar
Melledy committed
78
				// Drop all indexes and re add them
79
				MongoIterable<String> collections = gameDatastore.getDatabase().listCollectionNames();
Melledy's avatar
Melledy committed
80
				for (String name : collections) {
81
					gameDatastore.getDatabase().getCollection(name).dropIndexes();
Melledy's avatar
Melledy committed
82
83
				}
				// Add back indexes
84
				gameDatastore.ensureIndexes();
Melledy's avatar
Melledy committed
85
86
			}
		}
87

88
		if(SERVER.runMode == ServerRunMode.GAME_ONLY) {
89
90
			MongoClient dispatchMongoClient = MongoClients.create(DATABASE.server.connectionUri);
			dispatchDatastore = Morphia.createDatastore(dispatchMongoClient, DATABASE.server.collection);
Benjamin Elsdon's avatar
Benjamin Elsdon committed
91
92
93

			// Ensure indexes for dispatch server
			try {
94
				dispatchDatastore.ensureIndexes();
Benjamin Elsdon's avatar
Benjamin Elsdon committed
95
96
97
98
99
100
101
102
103
104
105
106
			} 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();
				}
107
108
			}
		}
Melledy's avatar
Melledy committed
109
	}
KingRainbow44's avatar
KingRainbow44 committed
110

Melledy's avatar
Melledy committed
111
	public static synchronized int getNextId(Class<?> c) {
112
		DatabaseCounter counter = getGameDatastore().find(DatabaseCounter.class).filter(Filters.eq("_id", c.getSimpleName())).first();
Melledy's avatar
Melledy committed
113
114
115
116
117
118
		if (counter == null) {
			counter = new DatabaseCounter(c.getSimpleName());
		}
		try {
			return counter.getNextId();
		} finally {
119
			getGameDatastore().save(counter);
Melledy's avatar
Melledy committed
120
121
		}
	}
KingRainbow44's avatar
KingRainbow44 committed
122

Melledy's avatar
Melledy committed
123
124
125
126
	public static synchronized int getNextId(Object o) {
		return getNextId(o.getClass());
	}
}