mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-12-16 17:05:20 +01:00
Use thread executors to speed up the database loading process
This commit is contained in:
@@ -1,8 +1,5 @@
|
|||||||
package emu.grasscutter;
|
package emu.grasscutter;
|
||||||
|
|
||||||
import static emu.grasscutter.config.Configuration.SERVER;
|
|
||||||
import static emu.grasscutter.utils.lang.Language.translate;
|
|
||||||
|
|
||||||
import ch.qos.logback.classic.Level;
|
import ch.qos.logback.classic.Level;
|
||||||
import ch.qos.logback.classic.Logger;
|
import ch.qos.logback.classic.Logger;
|
||||||
import emu.grasscutter.auth.AuthenticationSystem;
|
import emu.grasscutter.auth.AuthenticationSystem;
|
||||||
@@ -33,12 +30,7 @@ import emu.grasscutter.utils.JsonUtils;
|
|||||||
import emu.grasscutter.utils.StartupArguments;
|
import emu.grasscutter.utils.StartupArguments;
|
||||||
import emu.grasscutter.utils.Utils;
|
import emu.grasscutter.utils.Utils;
|
||||||
import emu.grasscutter.utils.lang.Language;
|
import emu.grasscutter.utils.lang.Language;
|
||||||
import java.io.File;
|
import io.netty.util.concurrent.FastThreadLocalThread;
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOError;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Calendar;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.jline.reader.EndOfFileException;
|
import org.jline.reader.EndOfFileException;
|
||||||
@@ -50,6 +42,20 @@ import org.jline.terminal.TerminalBuilder;
|
|||||||
import org.reflections.Reflections;
|
import org.reflections.Reflections;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOError;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.LinkedBlockingDeque;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static emu.grasscutter.config.Configuration.SERVER;
|
||||||
|
import static emu.grasscutter.utils.lang.Language.translate;
|
||||||
|
|
||||||
public final class Grasscutter {
|
public final class Grasscutter {
|
||||||
public static final File configFile = new File("./config.json");
|
public static final File configFile = new File("./config.json");
|
||||||
public static final Reflections reflector = new Reflections("emu.grasscutter");
|
public static final Reflections reflector = new Reflections("emu.grasscutter");
|
||||||
@@ -75,6 +81,13 @@ public final class Grasscutter {
|
|||||||
|
|
||||||
private static LineReader consoleLineReader = null;
|
private static LineReader consoleLineReader = null;
|
||||||
|
|
||||||
|
@Getter private static final ExecutorService threadPool = new ThreadPoolExecutor(
|
||||||
|
6, 6, 60, TimeUnit.SECONDS,
|
||||||
|
new LinkedBlockingDeque<>(),
|
||||||
|
FastThreadLocalThread::new,
|
||||||
|
new ThreadPoolExecutor.AbortPolicy()
|
||||||
|
);
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// Declare logback configuration.
|
// Declare logback configuration.
|
||||||
System.setProperty("logback.configurationFile", "src/main/resources/logback.xml");
|
System.setProperty("logback.configurationFile", "src/main/resources/logback.xml");
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
package emu.grasscutter.database;
|
package emu.grasscutter.database;
|
||||||
|
|
||||||
import static com.mongodb.client.model.Filters.eq;
|
|
||||||
|
|
||||||
import com.mongodb.client.result.DeleteResult;
|
|
||||||
import dev.morphia.query.FindOptions;
|
import dev.morphia.query.FindOptions;
|
||||||
import dev.morphia.query.Sort;
|
import dev.morphia.query.Sort;
|
||||||
import dev.morphia.query.experimental.filters.Filters;
|
import dev.morphia.query.experimental.filters.Filters;
|
||||||
@@ -22,10 +19,74 @@ import emu.grasscutter.game.mail.Mail;
|
|||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.game.quest.GameMainQuest;
|
import emu.grasscutter.game.quest.GameMainQuest;
|
||||||
import emu.grasscutter.game.world.SceneGroupInstance;
|
import emu.grasscutter.game.world.SceneGroupInstance;
|
||||||
|
import emu.grasscutter.utils.objects.Returnable;
|
||||||
|
import io.netty.util.concurrent.FastThreadLocalThread;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.*;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static com.mongodb.client.model.Filters.eq;
|
||||||
|
|
||||||
public final class DatabaseHelper {
|
public final class DatabaseHelper {
|
||||||
|
private static final ExecutorService eventExecutor = new ThreadPoolExecutor(
|
||||||
|
6, 6, 60, TimeUnit.SECONDS,
|
||||||
|
new LinkedBlockingDeque<>(),
|
||||||
|
FastThreadLocalThread::new,
|
||||||
|
new ThreadPoolExecutor.AbortPolicy()
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves an object on the account datastore.
|
||||||
|
*
|
||||||
|
* @param object The object to save.
|
||||||
|
*/
|
||||||
|
public static void saveAccountAsync(Object object) {
|
||||||
|
DatabaseHelper.eventExecutor.submit(() ->
|
||||||
|
DatabaseManager.getAccountDatastore().save(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves an object on the game datastore.
|
||||||
|
*
|
||||||
|
* @param object The object to save.
|
||||||
|
*/
|
||||||
|
public static void saveGameAsync(Object object) {
|
||||||
|
DatabaseHelper.eventExecutor.submit(() ->
|
||||||
|
DatabaseHelper.saveGameAsync(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs a runnable on the event executor.
|
||||||
|
* Should be limited to database-related operations.
|
||||||
|
*
|
||||||
|
* @param runnable The runnable to run.
|
||||||
|
*/
|
||||||
|
public static void asyncOperation(Runnable runnable) {
|
||||||
|
DatabaseHelper.eventExecutor.submit(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches an object asynchronously.
|
||||||
|
*
|
||||||
|
* @param task The task to run.
|
||||||
|
* @return The future.
|
||||||
|
*/
|
||||||
|
public static <T> CompletableFuture<T> fetchAsync(Returnable<T> task) {
|
||||||
|
var future = new CompletableFuture<T>();
|
||||||
|
|
||||||
|
// Run the task on the event executor.
|
||||||
|
DatabaseHelper.eventExecutor.submit(() -> {
|
||||||
|
try {
|
||||||
|
future.complete(task.invoke());
|
||||||
|
} catch (Exception e) {
|
||||||
|
future.completeExceptionally(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return future;
|
||||||
|
}
|
||||||
|
|
||||||
public static Account createAccount(String username) {
|
public static Account createAccount(String username) {
|
||||||
return createAccountWithUid(username, 0);
|
return createAccountWithUid(username, 0);
|
||||||
}
|
}
|
||||||
@@ -85,7 +146,7 @@ public final class DatabaseHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void saveAccount(Account account) {
|
public static void saveAccount(Account account) {
|
||||||
DatabaseManager.getAccountDatastore().save(account);
|
DatabaseHelper.saveAccountAsync(account);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Account getAccountByName(String username) {
|
public static Account getAccountByName(String username) {
|
||||||
@@ -159,31 +220,34 @@ public final class DatabaseHelper {
|
|||||||
if (player == null) return;
|
if (player == null) return;
|
||||||
}
|
}
|
||||||
int uid = player.getUid();
|
int uid = player.getUid();
|
||||||
// Delete data from collections
|
|
||||||
DatabaseManager.getGameDatabase().getCollection("achievements").deleteMany(eq("uid", uid));
|
|
||||||
DatabaseManager.getGameDatabase().getCollection("activities").deleteMany(eq("uid", uid));
|
|
||||||
DatabaseManager.getGameDatabase().getCollection("homes").deleteMany(eq("ownerUid", uid));
|
|
||||||
DatabaseManager.getGameDatabase().getCollection("mail").deleteMany(eq("ownerUid", uid));
|
|
||||||
DatabaseManager.getGameDatabase().getCollection("avatars").deleteMany(eq("ownerId", uid));
|
|
||||||
DatabaseManager.getGameDatabase().getCollection("gachas").deleteMany(eq("ownerId", uid));
|
|
||||||
DatabaseManager.getGameDatabase().getCollection("items").deleteMany(eq("ownerId", uid));
|
|
||||||
DatabaseManager.getGameDatabase().getCollection("quests").deleteMany(eq("ownerUid", uid));
|
|
||||||
DatabaseManager.getGameDatabase().getCollection("battlepass").deleteMany(eq("ownerUid", uid));
|
|
||||||
|
|
||||||
// Delete friendships.
|
DatabaseHelper.asyncOperation(() -> {
|
||||||
// Here, we need to make sure to not only delete the deleted account's friendships,
|
// Delete data from collections
|
||||||
// but also all friendship entries for that account's friends.
|
DatabaseManager.getGameDatabase().getCollection("achievements").deleteMany(eq("uid", uid));
|
||||||
DatabaseManager.getGameDatabase().getCollection("friendships").deleteMany(eq("ownerId", uid));
|
DatabaseManager.getGameDatabase().getCollection("activities").deleteMany(eq("uid", uid));
|
||||||
DatabaseManager.getGameDatabase().getCollection("friendships").deleteMany(eq("friendId", uid));
|
DatabaseManager.getGameDatabase().getCollection("homes").deleteMany(eq("ownerUid", uid));
|
||||||
|
DatabaseManager.getGameDatabase().getCollection("mail").deleteMany(eq("ownerUid", uid));
|
||||||
|
DatabaseManager.getGameDatabase().getCollection("avatars").deleteMany(eq("ownerId", uid));
|
||||||
|
DatabaseManager.getGameDatabase().getCollection("gachas").deleteMany(eq("ownerId", uid));
|
||||||
|
DatabaseManager.getGameDatabase().getCollection("items").deleteMany(eq("ownerId", uid));
|
||||||
|
DatabaseManager.getGameDatabase().getCollection("quests").deleteMany(eq("ownerUid", uid));
|
||||||
|
DatabaseManager.getGameDatabase().getCollection("battlepass").deleteMany(eq("ownerUid", uid));
|
||||||
|
|
||||||
// Delete the player last.
|
// Delete friendships.
|
||||||
DatabaseManager.getGameDatastore().find(Player.class).filter(Filters.eq("id", uid)).delete();
|
// Here, we need to make sure to not only delete the deleted account's friendships,
|
||||||
|
// but also all friendship entries for that account's friends.
|
||||||
|
DatabaseManager.getGameDatabase().getCollection("friendships").deleteMany(eq("ownerId", uid));
|
||||||
|
DatabaseManager.getGameDatabase().getCollection("friendships").deleteMany(eq("friendId", uid));
|
||||||
|
|
||||||
// Finally, delete the account itself.
|
// Delete the player last.
|
||||||
DatabaseManager.getAccountDatastore()
|
DatabaseManager.getGameDatastore().find(Player.class).filter(Filters.eq("id", uid)).delete();
|
||||||
|
|
||||||
|
// Finally, delete the account itself.
|
||||||
|
DatabaseManager.getAccountDatastore()
|
||||||
.find(Account.class)
|
.find(Account.class)
|
||||||
.filter(Filters.eq("id", target.getId()))
|
.filter(Filters.eq("id", target.getId()))
|
||||||
.delete();
|
.delete();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> Stream<T> getByGameClass(Class<T> classType) {
|
public static <T> Stream<T> getByGameClass(Class<T> classType) {
|
||||||
@@ -239,7 +303,7 @@ public final class DatabaseHelper {
|
|||||||
> 0;
|
> 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized Player generatePlayerUid(Player character, int reservedId) {
|
public static synchronized void generatePlayerUid(Player character, int reservedId) {
|
||||||
// Check if reserved id
|
// Check if reserved id
|
||||||
int id;
|
int id;
|
||||||
if (reservedId > 0 && !checkIfPlayerExists(reservedId)) {
|
if (reservedId > 0 && !checkIfPlayerExists(reservedId)) {
|
||||||
@@ -251,9 +315,9 @@ public final class DatabaseHelper {
|
|||||||
} while (checkIfPlayerExists(id));
|
} while (checkIfPlayerExists(id));
|
||||||
character.setUid(id);
|
character.setUid(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save to database
|
// Save to database
|
||||||
DatabaseManager.getGameDatastore().save(character);
|
DatabaseHelper.saveGameAsync(character);
|
||||||
return character;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized int getNextPlayerId(int reservedId) {
|
public static synchronized int getNextPlayerId(int reservedId) {
|
||||||
@@ -270,36 +334,48 @@ public final class DatabaseHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void savePlayer(Player character) {
|
public static void savePlayer(Player character) {
|
||||||
DatabaseManager.getGameDatastore().save(character);
|
DatabaseHelper.saveGameAsync(character);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void saveAvatar(Avatar avatar) {
|
public static void saveAvatar(Avatar avatar) {
|
||||||
DatabaseManager.getGameDatastore().save(avatar);
|
DatabaseHelper.saveGameAsync(avatar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all avatars of a player.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
* @return The list of avatars.
|
||||||
|
*/
|
||||||
public static List<Avatar> getAvatars(Player player) {
|
public static List<Avatar> getAvatars(Player player) {
|
||||||
return DatabaseManager.getGameDatastore()
|
return DatabaseManager.getGameDatastore()
|
||||||
.find(Avatar.class)
|
.find(Avatar.class)
|
||||||
.filter(Filters.eq("ownerId", player.getUid()))
|
.filter(Filters.eq("ownerId", player.getUid()))
|
||||||
.stream()
|
.stream()
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void saveItem(GameItem item) {
|
public static void saveItem(GameItem item) {
|
||||||
DatabaseManager.getGameDatastore().save(item);
|
DatabaseHelper.saveGameAsync(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean deleteItem(GameItem item) {
|
public static void deleteItem(GameItem item) {
|
||||||
DeleteResult result = DatabaseManager.getGameDatastore().delete(item);
|
DatabaseHelper.asyncOperation(() ->
|
||||||
return result.wasAcknowledged();
|
DatabaseManager.getGameDatastore().delete(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all items of a player.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
* @return The list of items.
|
||||||
|
*/
|
||||||
public static List<GameItem> getInventoryItems(Player player) {
|
public static List<GameItem> getInventoryItems(Player player) {
|
||||||
return DatabaseManager.getGameDatastore()
|
return DatabaseManager.getGameDatastore()
|
||||||
.find(GameItem.class)
|
.find(GameItem.class)
|
||||||
.filter(Filters.eq("ownerId", player.getUid()))
|
.filter(Filters.eq("ownerId", player.getUid()))
|
||||||
.stream()
|
.stream()
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Friendship> getFriends(Player player) {
|
public static List<Friendship> getFriends(Player player) {
|
||||||
@@ -319,11 +395,12 @@ public final class DatabaseHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void saveFriendship(Friendship friendship) {
|
public static void saveFriendship(Friendship friendship) {
|
||||||
DatabaseManager.getGameDatastore().save(friendship);
|
DatabaseHelper.saveGameAsync(friendship);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void deleteFriendship(Friendship friendship) {
|
public static void deleteFriendship(Friendship friendship) {
|
||||||
DatabaseManager.getGameDatastore().delete(friendship);
|
DatabaseHelper.asyncOperation(() ->
|
||||||
|
DatabaseManager.getGameDatastore().delete(friendship));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Friendship getReverseFriendship(Friendship friendship) {
|
public static Friendship getReverseFriendship(Friendship friendship) {
|
||||||
@@ -367,7 +444,7 @@ public final class DatabaseHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void saveGachaRecord(GachaRecord gachaRecord) {
|
public static void saveGachaRecord(GachaRecord gachaRecord) {
|
||||||
DatabaseManager.getGameDatastore().save(gachaRecord);
|
DatabaseHelper.saveGameAsync(gachaRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Mail> getAllMail(Player player) {
|
public static List<Mail> getAllMail(Player player) {
|
||||||
@@ -379,12 +456,12 @@ public final class DatabaseHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void saveMail(Mail mail) {
|
public static void saveMail(Mail mail) {
|
||||||
DatabaseManager.getGameDatastore().save(mail);
|
DatabaseHelper.saveGameAsync(mail);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean deleteMail(Mail mail) {
|
public static void deleteMail(Mail mail) {
|
||||||
DeleteResult result = DatabaseManager.getGameDatastore().delete(mail);
|
DatabaseHelper.asyncOperation(() ->
|
||||||
return result.wasAcknowledged();
|
DatabaseManager.getGameDatastore().delete(mail));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<GameMainQuest> getAllQuests(Player player) {
|
public static List<GameMainQuest> getAllQuests(Player player) {
|
||||||
@@ -396,11 +473,12 @@ public final class DatabaseHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void saveQuest(GameMainQuest quest) {
|
public static void saveQuest(GameMainQuest quest) {
|
||||||
DatabaseManager.getGameDatastore().save(quest);
|
DatabaseHelper.saveGameAsync(quest);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean deleteQuest(GameMainQuest quest) {
|
public static void deleteQuest(GameMainQuest quest) {
|
||||||
return DatabaseManager.getGameDatastore().delete(quest).wasAcknowledged();
|
DatabaseHelper.asyncOperation(() ->
|
||||||
|
DatabaseManager.getGameDatastore().delete(quest));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GameHome getHomeByUid(int id) {
|
public static GameHome getHomeByUid(int id) {
|
||||||
@@ -411,7 +489,7 @@ public final class DatabaseHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void saveHome(GameHome gameHome) {
|
public static void saveHome(GameHome gameHome) {
|
||||||
DatabaseManager.getGameDatastore().save(gameHome);
|
DatabaseHelper.saveGameAsync(gameHome);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BattlePassManager loadBattlePass(Player player) {
|
public static BattlePassManager loadBattlePass(Player player) {
|
||||||
@@ -430,7 +508,7 @@ public final class DatabaseHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void saveBattlePass(BattlePassManager manager) {
|
public static void saveBattlePass(BattlePassManager manager) {
|
||||||
DatabaseManager.getGameDatastore().save(manager);
|
DatabaseHelper.saveGameAsync(manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PlayerActivityData getPlayerActivityData(int uid, int activityId) {
|
public static PlayerActivityData getPlayerActivityData(int uid, int activityId) {
|
||||||
@@ -441,7 +519,7 @@ public final class DatabaseHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void savePlayerActivityData(PlayerActivityData playerActivityData) {
|
public static void savePlayerActivityData(PlayerActivityData playerActivityData) {
|
||||||
DatabaseManager.getGameDatastore().save(playerActivityData);
|
DatabaseHelper.saveGameAsync(playerActivityData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MusicGameBeatmap getMusicGameBeatmap(long musicShareId) {
|
public static MusicGameBeatmap getMusicGameBeatmap(long musicShareId) {
|
||||||
@@ -452,7 +530,7 @@ public final class DatabaseHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void saveMusicGameBeatmap(MusicGameBeatmap musicGameBeatmap) {
|
public static void saveMusicGameBeatmap(MusicGameBeatmap musicGameBeatmap) {
|
||||||
DatabaseManager.getGameDatastore().save(musicGameBeatmap);
|
DatabaseHelper.saveGameAsync(musicGameBeatmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Achievements getAchievementData(int uid) {
|
public static Achievements getAchievementData(int uid) {
|
||||||
@@ -463,11 +541,11 @@ public final class DatabaseHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void saveAchievementData(Achievements achievements) {
|
public static void saveAchievementData(Achievements achievements) {
|
||||||
DatabaseManager.getGameDatastore().save(achievements);
|
DatabaseHelper.saveGameAsync(achievements);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void saveGroupInstance(SceneGroupInstance instance) {
|
public static void saveGroupInstance(SceneGroupInstance instance) {
|
||||||
DatabaseManager.getGameDatastore().save(instance);
|
DatabaseHelper.saveGameAsync(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SceneGroupInstance loadGroupInstance(int groupId, Player owner) {
|
public static SceneGroupInstance loadGroupInstance(int groupId, Player owner) {
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package emu.grasscutter.database;
|
package emu.grasscutter.database;
|
||||||
|
|
||||||
import static emu.grasscutter.config.Configuration.DATABASE;
|
|
||||||
|
|
||||||
import com.mongodb.MongoCommandException;
|
import com.mongodb.MongoCommandException;
|
||||||
import com.mongodb.client.MongoClient;
|
import com.mongodb.client.MongoClient;
|
||||||
import com.mongodb.client.MongoClients;
|
import com.mongodb.client.MongoClients;
|
||||||
@@ -18,6 +16,8 @@ import emu.grasscutter.Grasscutter.ServerRunMode;
|
|||||||
import emu.grasscutter.game.Account;
|
import emu.grasscutter.game.Account;
|
||||||
import org.reflections.Reflections;
|
import org.reflections.Reflections;
|
||||||
|
|
||||||
|
import static emu.grasscutter.config.Configuration.DATABASE;
|
||||||
|
|
||||||
public final class DatabaseManager {
|
public final class DatabaseManager {
|
||||||
private static Datastore gameDatastore;
|
private static Datastore gameDatastore;
|
||||||
private static Datastore dispatchDatastore;
|
private static Datastore dispatchDatastore;
|
||||||
@@ -107,10 +107,11 @@ public final class DatabaseManager {
|
|||||||
if (counter == null) {
|
if (counter == null) {
|
||||||
counter = new DatabaseCounter(c.getSimpleName());
|
counter = new DatabaseCounter(c.getSimpleName());
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return counter.getNextId();
|
return counter.getNextId();
|
||||||
} finally {
|
} finally {
|
||||||
getGameDatastore().save(counter);
|
DatabaseHelper.saveGameAsync(counter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package emu.grasscutter.game.inventory;
|
package emu.grasscutter.game.inventory;
|
||||||
|
|
||||||
import static emu.grasscutter.config.Configuration.INVENTORY_LIMITS;
|
|
||||||
|
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.data.GameData;
|
import emu.grasscutter.data.GameData;
|
||||||
import emu.grasscutter.data.common.ItemParamData;
|
import emu.grasscutter.data.common.ItemParamData;
|
||||||
@@ -22,11 +20,14 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
|||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static emu.grasscutter.config.Configuration.INVENTORY_LIMITS;
|
||||||
|
|
||||||
public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
|
public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
|
||||||
private final Long2ObjectMap<GameItem> store;
|
private final Long2ObjectMap<GameItem> store;
|
||||||
private final Int2ObjectMap<InventoryTab> inventoryTypes;
|
private final Int2ObjectMap<InventoryTab> inventoryTypes;
|
||||||
@@ -572,6 +573,9 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load avatars after inventory.
|
||||||
|
this.getPlayer().getAvatars().postLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1313,16 +1313,17 @@ public class Player implements PlayerHook, FieldFetch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load from db
|
// Load from db
|
||||||
this.achievements = Achievements.getByPlayer(this);
|
var runner = Grasscutter.getThreadPool();
|
||||||
this.getAvatars().loadFromDatabase();
|
runner.submit(() -> this.achievements = Achievements.getByPlayer(this));
|
||||||
this.getInventory().loadFromDatabase();
|
|
||||||
|
|
||||||
this.getFriendsList().loadFromDatabase();
|
runner.submit(this.getAvatars()::loadFromDatabase);
|
||||||
this.getMailHandler().loadFromDatabase();
|
runner.submit(this.getInventory()::loadFromDatabase);
|
||||||
this.getQuestManager().loadFromDatabase();
|
|
||||||
|
|
||||||
this.loadBattlePassManager();
|
runner.submit(this.getFriendsList()::loadFromDatabase);
|
||||||
this.getAvatars().postLoad(); // Needs to be called after inventory is handled
|
runner.submit(this.getMailHandler()::loadFromDatabase);
|
||||||
|
runner.submit(this.getQuestManager()::loadFromDatabase);
|
||||||
|
|
||||||
|
runner.submit(this::loadBattlePassManager);
|
||||||
|
|
||||||
this.getPlayerProgress().setPlayer(this); // Add reference to the player.
|
this.getPlayerProgress().setPlayer(this); // Add reference to the player.
|
||||||
}
|
}
|
||||||
@@ -1397,7 +1398,7 @@ public class Player implements PlayerHook, FieldFetch {
|
|||||||
home = GameHome.getByUid(getUid());
|
home = GameHome.getByUid(getUid());
|
||||||
home.onOwnerLogin(this);
|
home.onOwnerLogin(this);
|
||||||
// Activity
|
// Activity
|
||||||
activityManager = new ActivityManager(this);
|
this.activityManager = new ActivityManager(this);
|
||||||
|
|
||||||
session.send(new PacketPlayerEnterSceneNotify(this)); // Enter game world
|
session.send(new PacketPlayerEnterSceneNotify(this)); // Enter game world
|
||||||
session.send(new PacketPlayerLevelRewardUpdateNotify(rewardedLevels));
|
session.send(new PacketPlayerLevelRewardUpdateNotify(rewardedLevels));
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package emu.grasscutter.utils.objects;
|
||||||
|
|
||||||
|
public interface Returnable<T> {
|
||||||
|
/**
|
||||||
|
* @return The value.
|
||||||
|
*/
|
||||||
|
T invoke();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user