mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-02-13 16:02:54 +08:00
Revert Multi-threaded resource loading
This commit is contained in:
parent
1a6fa43367
commit
cad6e90c90
@ -125,7 +125,7 @@ public final class Grasscutter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize database.
|
// Initialize database.
|
||||||
DatabaseManager.initializeAsync();
|
DatabaseManager.initialize();
|
||||||
|
|
||||||
// Initialize the default systems.
|
// Initialize the default systems.
|
||||||
authenticationSystem = new DefaultAuthentication();
|
authenticationSystem = new DefaultAuthentication();
|
||||||
|
@ -25,7 +25,6 @@ import emu.grasscutter.scripts.ScriptLoader;
|
|||||||
import emu.grasscutter.utils.FileUtils;
|
import emu.grasscutter.utils.FileUtils;
|
||||||
import emu.grasscutter.utils.JsonUtils;
|
import emu.grasscutter.utils.JsonUtils;
|
||||||
import emu.grasscutter.utils.TsvUtils;
|
import emu.grasscutter.utils.TsvUtils;
|
||||||
import emu.grasscutter.utils.lang.Language;
|
|
||||||
import it.unimi.dsi.fastutil.Pair;
|
import it.unimi.dsi.fastutil.Pair;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||||
@ -42,7 +41,6 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
@ -100,151 +98,87 @@ public final class ResourceLoader {
|
|||||||
return List.copyOf(map.values());
|
return List.copyOf(map.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs a task asynchronously.
|
|
||||||
*
|
|
||||||
* @param task The task to run.
|
|
||||||
* @return A CompletableFuture that will complete when the task is done.
|
|
||||||
*/
|
|
||||||
public static CompletableFuture<Boolean> runAsync(Runnable task) {
|
|
||||||
return CompletableFuture.supplyAsync(
|
|
||||||
() -> {
|
|
||||||
task.run();
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Waits for all futures to complete.
|
|
||||||
*
|
|
||||||
* @param futures The futures to wait for.
|
|
||||||
*/
|
|
||||||
public static void waitForAll(Collection<CompletableFuture<Boolean>> futures) {
|
|
||||||
futures.forEach(CompletableFuture::join);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public static void loadAll() {
|
public static void loadAll() {
|
||||||
if (loadedAll) return;
|
if (loadedAll) return;
|
||||||
loadedAll = true;
|
|
||||||
|
|
||||||
Grasscutter.getLogger().info(translate("messages.status.resources.loading"));
|
Grasscutter.getLogger().info(translate("messages.status.resources.loading"));
|
||||||
|
|
||||||
// Mark the starting time.
|
|
||||||
var startTime = System.nanoTime();
|
|
||||||
|
|
||||||
// Initialize the script loader.
|
// Initialize the script loader.
|
||||||
ScriptLoader.init();
|
ScriptLoader.init();
|
||||||
|
|
||||||
// Load 'TextMaps'.
|
loadConfigData();
|
||||||
var textMaps = ResourceLoader.runAsync(Language::loadTextMaps);
|
// Load ability lists
|
||||||
// Load 'BinOutput'.
|
loadAbilityEmbryos();
|
||||||
var binOutput = ResourceLoader.loadConfigData();
|
loadOpenConfig();
|
||||||
// Load ability lists.
|
loadAbilityModifiers();
|
||||||
var abilities =
|
// Load resources
|
||||||
ResourceLoader.runAsync(
|
loadResources(true);
|
||||||
() -> {
|
// Process into depots
|
||||||
ResourceLoader.loadAbilityEmbryos();
|
GameDepot.load();
|
||||||
ResourceLoader.loadOpenConfig();
|
// Load spawn data and quests
|
||||||
ResourceLoader.loadAbilityModifiers();
|
loadSpawnData();
|
||||||
});
|
loadQuests();
|
||||||
// Load 'ExcelBinOutput'.
|
loadScriptSceneData();
|
||||||
var errors = new ConcurrentLinkedQueue<Pair<String, Exception>>();
|
// Load scene points - must be done AFTER resources are loaded
|
||||||
var excelBinOutput = ResourceLoader.loadResources(true, errors);
|
loadScenePoints();
|
||||||
// Load spawn data and quests.
|
|
||||||
var scene =
|
|
||||||
ResourceLoader.runAsync(
|
|
||||||
() -> {
|
|
||||||
ResourceLoader.loadSpawnData();
|
|
||||||
ResourceLoader.loadQuests();
|
|
||||||
ResourceLoader.loadScriptSceneData();
|
|
||||||
});
|
|
||||||
// Load default home layout
|
// Load default home layout
|
||||||
var entities =
|
loadHomeworldDefaultSaveData();
|
||||||
ResourceLoader.runAsync(
|
loadNpcBornData();
|
||||||
() -> {
|
loadBlossomResources();
|
||||||
ResourceLoader.loadHomeworldDefaultSaveData();
|
cacheTalentLevelSets();
|
||||||
ResourceLoader.loadNpcBornData();
|
|
||||||
ResourceLoader.loadBlossomResources();
|
|
||||||
ResourceLoader.cacheTalentLevelSets();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Load custom server resources.
|
// Load custom server resources.
|
||||||
var customServer =
|
loadConfigLevelEntityData();
|
||||||
ResourceLoader.runAsync(
|
loadQuestShareConfig();
|
||||||
() -> {
|
loadGadgetMappings();
|
||||||
ResourceLoader.loadConfigLevelEntityData();
|
loadActivityCondGroups();
|
||||||
ResourceLoader.loadQuestShareConfig();
|
loadGroupReplacements();
|
||||||
ResourceLoader.loadGadgetMappings();
|
loadTrialAvatarCustomData();
|
||||||
ResourceLoader.loadActivityCondGroups();
|
|
||||||
ResourceLoader.loadGroupReplacements();
|
|
||||||
ResourceLoader.loadTrialAvatarCustomData();
|
|
||||||
|
|
||||||
EntityControllerScriptManager.load();
|
EntityControllerScriptManager.load();
|
||||||
});
|
|
||||||
|
|
||||||
// Wait for all futures to complete.
|
|
||||||
var futures = new ArrayList<>(List.of(textMaps, abilities, scene, entities, customServer));
|
|
||||||
futures.addAll(binOutput);
|
|
||||||
futures.addAll(excelBinOutput);
|
|
||||||
ResourceLoader.waitForAll(futures);
|
|
||||||
|
|
||||||
// Load dependent-resources.
|
|
||||||
GameDepot.load(); // Process into depots
|
|
||||||
ResourceLoader.loadScenePoints(); // Load scene points.
|
|
||||||
|
|
||||||
// Log any errors.
|
|
||||||
errors.forEach(
|
|
||||||
pair ->
|
|
||||||
Grasscutter.getLogger()
|
|
||||||
.error("Error loading resource file: " + pair.left(), pair.right() + "."));
|
|
||||||
|
|
||||||
// Calculate the ending time.
|
|
||||||
var endTime = System.nanoTime();
|
|
||||||
var ns = (endTime - startTime); // divide by 1000000 to get milliseconds.
|
|
||||||
Grasscutter.getLogger().debug("Loading resources took " + ns + "ns (" + ns / 1000000 + "ms).");
|
|
||||||
|
|
||||||
Grasscutter.getLogger().info(translate("messages.status.resources.finish"));
|
Grasscutter.getLogger().info(translate("messages.status.resources.finish"));
|
||||||
|
loadedAll = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void loadResources() {
|
public static void loadResources() {
|
||||||
loadResources(false, new ConcurrentLinkedQueue<>());
|
loadResources(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static void loadResources(boolean doReload) {
|
||||||
* Loads all resources from annotated classes.
|
long startTime = System.nanoTime();
|
||||||
*
|
val errors =
|
||||||
* @param doReload Whether to reload resources.
|
new ConcurrentLinkedQueue<
|
||||||
*/
|
Pair<String, Exception>>(); // Logger in a parallel stream will deadlock
|
||||||
public static List<CompletableFuture<Boolean>> loadResources(
|
|
||||||
boolean doReload, Queue<Pair<String, Exception>> errors) {
|
|
||||||
// Load all resources in parallel.
|
|
||||||
return ResourceLoader.getResourceDefClassesPrioritySets().stream()
|
|
||||||
.map(
|
|
||||||
classes ->
|
|
||||||
classes.stream()
|
|
||||||
.parallel()
|
|
||||||
.unordered()
|
|
||||||
.map(
|
|
||||||
c -> {
|
|
||||||
var type = c.getAnnotation(ResourceType.class);
|
|
||||||
if (type == null) return null;
|
|
||||||
|
|
||||||
var map = GameData.getMapByResourceDef(c);
|
getResourceDefClassesPrioritySets()
|
||||||
if (map == null) return null;
|
.forEach(
|
||||||
|
classes -> {
|
||||||
|
classes.stream()
|
||||||
|
.parallel()
|
||||||
|
.unordered()
|
||||||
|
.forEach(
|
||||||
|
c -> {
|
||||||
|
val type = c.getAnnotation(ResourceType.class);
|
||||||
|
if (type == null) return;
|
||||||
|
|
||||||
return ResourceLoader.runAsync(
|
val map = GameData.getMapByResourceDef(c);
|
||||||
() -> {
|
if (map == null) return;
|
||||||
try {
|
|
||||||
loadFromResource(c, type, map, doReload);
|
try {
|
||||||
} catch (Exception e) {
|
loadFromResource(c, type, map, doReload);
|
||||||
errors.add(Pair.of(Arrays.toString(type.name()), e));
|
} catch (Exception e) {
|
||||||
}
|
errors.add(Pair.of(Arrays.toString(type.name()), e));
|
||||||
});
|
}
|
||||||
})
|
});
|
||||||
.toList())
|
});
|
||||||
.flatMap(Collection::stream)
|
errors.forEach(
|
||||||
.toList();
|
pair ->
|
||||||
|
Grasscutter.getLogger()
|
||||||
|
.error("Error loading resource file: " + pair.left(), pair.right()));
|
||||||
|
long endTime = System.nanoTime();
|
||||||
|
long ns = (endTime - startTime); // divide by 1000000 to get milliseconds.
|
||||||
|
Grasscutter.getLogger().debug("Loading resources took " + ns + "ns == " + ns / 1000000 + "ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
@ -292,38 +226,38 @@ public final class ResourceLoader {
|
|||||||
|
|
||||||
private static void loadScenePoints() {
|
private static void loadScenePoints() {
|
||||||
val pattern = Pattern.compile("scene([0-9]+)_point\\.json");
|
val pattern = Pattern.compile("scene([0-9]+)_point\\.json");
|
||||||
try (var stream =
|
try {
|
||||||
Files.newDirectoryStream(getResourcePath("BinOutput/Scene/Point"), "scene*_point.json")) {
|
Files.newDirectoryStream(getResourcePath("BinOutput/Scene/Point"), "scene*_point.json")
|
||||||
stream.forEach(
|
.forEach(
|
||||||
path -> {
|
path -> {
|
||||||
var matcher = pattern.matcher(path.getFileName().toString());
|
val matcher = pattern.matcher(path.getFileName().toString());
|
||||||
if (!matcher.find()) return;
|
if (!matcher.find()) return;
|
||||||
var sceneId = Integer.parseInt(matcher.group(1));
|
int sceneId = Integer.parseInt(matcher.group(1));
|
||||||
|
|
||||||
ScenePointConfig config;
|
ScenePointConfig config;
|
||||||
try {
|
try {
|
||||||
config = JsonUtils.loadToClass(path, ScenePointConfig.class);
|
config = JsonUtils.loadToClass(path, ScenePointConfig.class);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.points == null) return;
|
if (config.points == null) return;
|
||||||
|
|
||||||
var scenePoints = new IntArrayList();
|
val scenePoints = new IntArrayList();
|
||||||
config.points.forEach(
|
config.points.forEach(
|
||||||
(pointId, pointData) -> {
|
(pointId, pointData) -> {
|
||||||
var scenePoint = new ScenePointEntry(sceneId, pointData);
|
val scenePoint = new ScenePointEntry(sceneId, pointData);
|
||||||
scenePoints.add((int) pointId);
|
scenePoints.add((int) pointId);
|
||||||
pointData.setId(pointId);
|
pointData.setId(pointId);
|
||||||
|
|
||||||
GameData.getScenePointIdList().add((int) pointId);
|
GameData.getScenePointIdList().add((int) pointId);
|
||||||
GameData.getScenePointEntryMap().put((sceneId << 16) + pointId, scenePoint);
|
GameData.getScenePointEntryMap().put((sceneId << 16) + pointId, scenePoint);
|
||||||
|
|
||||||
pointData.updateDailyDungeon();
|
pointData.updateDailyDungeon();
|
||||||
});
|
});
|
||||||
GameData.getScenePointsPerScene().put(sceneId, scenePoints);
|
GameData.getScenePointsPerScene().put(sceneId, scenePoints);
|
||||||
});
|
});
|
||||||
} catch (IOException ignored) {
|
} catch (IOException ignored) {
|
||||||
Grasscutter.getLogger()
|
Grasscutter.getLogger()
|
||||||
.error("Scene point files cannot be found, you cannot use teleport waypoints!");
|
.error("Scene point files cannot be found, you cannot use teleport waypoints!");
|
||||||
@ -674,34 +608,12 @@ public final class ResourceLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Loads data from parsed files. */
|
private static void loadConfigData() {
|
||||||
private static List<CompletableFuture<Boolean>> loadConfigData() {
|
loadConfigData(GameData.getAvatarConfigData(), "BinOutput/Avatar/", ConfigEntityAvatar.class);
|
||||||
var tasks = new ArrayList<CompletableFuture<Boolean>>();
|
loadConfigData(
|
||||||
|
GameData.getMonsterConfigData(), "BinOutput/Monster/", ConfigEntityMonster.class);
|
||||||
// Load config data.
|
loadConfigDataMap(
|
||||||
tasks.add(
|
GameData.getGadgetConfigData(), "BinOutput/Gadget/", ConfigEntityGadget.class);
|
||||||
ResourceLoader.runAsync(
|
|
||||||
() ->
|
|
||||||
loadConfigData(
|
|
||||||
GameData.getAvatarConfigData(),
|
|
||||||
"BinOutput/Avatar/",
|
|
||||||
ConfigEntityAvatar.class)));
|
|
||||||
tasks.add(
|
|
||||||
ResourceLoader.runAsync(
|
|
||||||
() ->
|
|
||||||
loadConfigData(
|
|
||||||
GameData.getMonsterConfigData(),
|
|
||||||
"BinOutput/Monster/",
|
|
||||||
ConfigEntityMonster.class)));
|
|
||||||
tasks.add(
|
|
||||||
ResourceLoader.runAsync(
|
|
||||||
() ->
|
|
||||||
loadConfigDataMap(
|
|
||||||
GameData.getGadgetConfigData(),
|
|
||||||
"BinOutput/Gadget/",
|
|
||||||
ConfigEntityGadget.class)));
|
|
||||||
|
|
||||||
return tasks;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T extends ConfigEntityBase> void loadConfigData(
|
private static <T extends ConfigEntityBase> void loadConfigData(
|
||||||
|
@ -35,12 +35,6 @@ public final class DatabaseManager {
|
|||||||
return getGameDatastore().getDatabase();
|
return getGameDatastore().getDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Performs the database initialization process. This occurs on a separate thread. */
|
|
||||||
public static void initializeAsync() {
|
|
||||||
new Thread(DatabaseManager::initialize).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Performs the database initialization process. This method is blocking. */
|
|
||||||
public static void initialize() {
|
public static void initialize() {
|
||||||
// Initialize
|
// Initialize
|
||||||
MongoClient gameMongoClient = MongoClients.create(DATABASE.game.connectionUri);
|
MongoClient gameMongoClient = MongoClients.create(DATABASE.game.connectionUri);
|
||||||
|
@ -3,7 +3,6 @@ package emu.grasscutter.game.drop;
|
|||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.data.DataLoader;
|
import emu.grasscutter.data.DataLoader;
|
||||||
import emu.grasscutter.data.GameData;
|
import emu.grasscutter.data.GameData;
|
||||||
import emu.grasscutter.data.ResourceLoader;
|
|
||||||
import emu.grasscutter.data.excels.ItemData;
|
import emu.grasscutter.data.excels.ItemData;
|
||||||
import emu.grasscutter.game.entity.EntityItem;
|
import emu.grasscutter.game.entity.EntityItem;
|
||||||
import emu.grasscutter.game.entity.EntityMonster;
|
import emu.grasscutter.game.entity.EntityMonster;
|
||||||
@ -27,8 +26,7 @@ public class DropSystemLegacy extends BaseGameSystem {
|
|||||||
public DropSystemLegacy(GameServer server) {
|
public DropSystemLegacy(GameServer server) {
|
||||||
super(server);
|
super(server);
|
||||||
this.dropData = new Int2ObjectOpenHashMap<>();
|
this.dropData = new Int2ObjectOpenHashMap<>();
|
||||||
|
this.load();
|
||||||
ResourceLoader.runAsync(this::load);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Int2ObjectMap<List<DropData>> getDropData() {
|
public Int2ObjectMap<List<DropData>> getDropData() {
|
||||||
|
@ -2,7 +2,6 @@ package emu.grasscutter.game.expedition;
|
|||||||
|
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.data.DataLoader;
|
import emu.grasscutter.data.DataLoader;
|
||||||
import emu.grasscutter.data.ResourceLoader;
|
|
||||||
import emu.grasscutter.server.game.BaseGameSystem;
|
import emu.grasscutter.server.game.BaseGameSystem;
|
||||||
import emu.grasscutter.server.game.GameServer;
|
import emu.grasscutter.server.game.GameServer;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
@ -14,9 +13,8 @@ public class ExpeditionSystem extends BaseGameSystem {
|
|||||||
|
|
||||||
public ExpeditionSystem(GameServer server) {
|
public ExpeditionSystem(GameServer server) {
|
||||||
super(server);
|
super(server);
|
||||||
|
|
||||||
this.expeditionRewardData = new Int2ObjectOpenHashMap<>();
|
this.expeditionRewardData = new Int2ObjectOpenHashMap<>();
|
||||||
ResourceLoader.runAsync(this::load);
|
this.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Int2ObjectMap<List<ExpeditionRewardDataList>> getExpeditionRewardDataList() {
|
public Int2ObjectMap<List<ExpeditionRewardDataList>> getExpeditionRewardDataList() {
|
||||||
|
@ -6,7 +6,6 @@ import com.sun.nio.file.SensitivityWatchEventModifier;
|
|||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.data.DataLoader;
|
import emu.grasscutter.data.DataLoader;
|
||||||
import emu.grasscutter.data.GameData;
|
import emu.grasscutter.data.GameData;
|
||||||
import emu.grasscutter.data.ResourceLoader;
|
|
||||||
import emu.grasscutter.data.common.ItemParamData;
|
import emu.grasscutter.data.common.ItemParamData;
|
||||||
import emu.grasscutter.data.excels.ItemData;
|
import emu.grasscutter.data.excels.ItemData;
|
||||||
import emu.grasscutter.database.DatabaseHelper;
|
import emu.grasscutter.database.DatabaseHelper;
|
||||||
@ -46,9 +45,8 @@ public class GachaSystem extends BaseGameSystem {
|
|||||||
|
|
||||||
public GachaSystem(GameServer server) {
|
public GachaSystem(GameServer server) {
|
||||||
super(server);
|
super(server);
|
||||||
|
|
||||||
this.gachaBanners = new Int2ObjectOpenHashMap<>();
|
this.gachaBanners = new Int2ObjectOpenHashMap<>();
|
||||||
ResourceLoader.runAsync(this::load);
|
this.load();
|
||||||
this.startWatcher(server);
|
this.startWatcher(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
|
|||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.data.DataLoader;
|
import emu.grasscutter.data.DataLoader;
|
||||||
import emu.grasscutter.data.GameData;
|
import emu.grasscutter.data.GameData;
|
||||||
import emu.grasscutter.data.ResourceLoader;
|
|
||||||
import emu.grasscutter.data.common.ItemParamData;
|
import emu.grasscutter.data.common.ItemParamData;
|
||||||
import emu.grasscutter.data.excels.ShopGoodsData;
|
import emu.grasscutter.data.excels.ShopGoodsData;
|
||||||
import emu.grasscutter.server.game.BaseGameSystem;
|
import emu.grasscutter.server.game.BaseGameSystem;
|
||||||
@ -25,10 +24,9 @@ public class ShopSystem extends BaseGameSystem {
|
|||||||
|
|
||||||
public ShopSystem(GameServer server) {
|
public ShopSystem(GameServer server) {
|
||||||
super(server);
|
super(server);
|
||||||
|
|
||||||
this.shopData = new Int2ObjectOpenHashMap<>();
|
this.shopData = new Int2ObjectOpenHashMap<>();
|
||||||
this.shopChestData = new Int2ObjectOpenHashMap<>();
|
this.shopChestData = new Int2ObjectOpenHashMap<>();
|
||||||
ResourceLoader.runAsync(this::load);
|
this.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getShopNextRefreshTime(ShopInfo shopInfo) {
|
public static int getShopNextRefreshTime(ShopInfo shopInfo) {
|
||||||
|
@ -2,7 +2,6 @@ package emu.grasscutter.game.systems;
|
|||||||
|
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.data.DataLoader;
|
import emu.grasscutter.data.DataLoader;
|
||||||
import emu.grasscutter.data.ResourceLoader;
|
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.game.world.World;
|
import emu.grasscutter.game.world.World;
|
||||||
import emu.grasscutter.net.proto.AnnounceDataOuterClass;
|
import emu.grasscutter.net.proto.AnnounceDataOuterClass;
|
||||||
@ -24,7 +23,7 @@ public class AnnouncementSystem extends BaseGameSystem {
|
|||||||
public AnnouncementSystem(GameServer server) {
|
public AnnouncementSystem(GameServer server) {
|
||||||
super(server);
|
super(server);
|
||||||
this.announceConfigItemMap = new HashMap<>();
|
this.announceConfigItemMap = new HashMap<>();
|
||||||
ResourceLoader.runAsync(this::loadConfig);
|
loadConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int loadConfig() {
|
private int loadConfig() {
|
||||||
|
@ -3,7 +3,6 @@ package emu.grasscutter.game.tower;
|
|||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.data.DataLoader;
|
import emu.grasscutter.data.DataLoader;
|
||||||
import emu.grasscutter.data.GameData;
|
import emu.grasscutter.data.GameData;
|
||||||
import emu.grasscutter.data.ResourceLoader;
|
|
||||||
import emu.grasscutter.data.excels.tower.TowerScheduleData;
|
import emu.grasscutter.data.excels.tower.TowerScheduleData;
|
||||||
import emu.grasscutter.server.game.BaseGameSystem;
|
import emu.grasscutter.server.game.BaseGameSystem;
|
||||||
import emu.grasscutter.server.game.GameServer;
|
import emu.grasscutter.server.game.GameServer;
|
||||||
@ -16,8 +15,7 @@ public class TowerSystem extends BaseGameSystem {
|
|||||||
|
|
||||||
public TowerSystem(GameServer server) {
|
public TowerSystem(GameServer server) {
|
||||||
super(server);
|
super(server);
|
||||||
|
this.load();
|
||||||
ResourceLoader.runAsync(this::load);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void load() {
|
public synchronized void load() {
|
||||||
|
@ -3,7 +3,6 @@ package emu.grasscutter.game.world;
|
|||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.data.DataLoader;
|
import emu.grasscutter.data.DataLoader;
|
||||||
import emu.grasscutter.data.GameData;
|
import emu.grasscutter.data.GameData;
|
||||||
import emu.grasscutter.data.ResourceLoader;
|
|
||||||
import emu.grasscutter.data.excels.InvestigationMonsterData;
|
import emu.grasscutter.data.excels.InvestigationMonsterData;
|
||||||
import emu.grasscutter.data.excels.RewardPreviewData;
|
import emu.grasscutter.data.excels.RewardPreviewData;
|
||||||
import emu.grasscutter.data.excels.world.WorldLevelData;
|
import emu.grasscutter.data.excels.world.WorldLevelData;
|
||||||
@ -32,7 +31,7 @@ public class WorldDataSystem extends BaseGameSystem {
|
|||||||
this.chestInteractHandlerMap = new HashMap<>();
|
this.chestInteractHandlerMap = new HashMap<>();
|
||||||
this.sceneInvestigationGroupMap = new ConcurrentHashMap<>();
|
this.sceneInvestigationGroupMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
ResourceLoader.runAsync(this::loadChestConfig);
|
loadChestConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void loadChestConfig() {
|
public synchronized void loadChestConfig() {
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
package emu.grasscutter.plugin;
|
package emu.grasscutter.plugin;
|
||||||
|
|
||||||
|
import static emu.grasscutter.utils.lang.Language.translate;
|
||||||
|
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.server.event.Event;
|
import emu.grasscutter.server.event.Event;
|
||||||
import emu.grasscutter.server.event.EventHandler;
|
import emu.grasscutter.server.event.EventHandler;
|
||||||
import emu.grasscutter.server.event.HandlerPriority;
|
import emu.grasscutter.server.event.HandlerPriority;
|
||||||
import emu.grasscutter.utils.FileUtils;
|
import emu.grasscutter.utils.FileUtils;
|
||||||
import emu.grasscutter.utils.JsonUtils;
|
import emu.grasscutter.utils.JsonUtils;
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
@ -20,8 +18,9 @@ import java.net.URLClassLoader;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.jar.JarEntry;
|
import java.util.jar.JarEntry;
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import static emu.grasscutter.utils.lang.Language.translate;
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
/** Manages the server's plugins and the event system. */
|
/** Manages the server's plugins and the event system. */
|
||||||
public final class PluginManager {
|
public final class PluginManager {
|
||||||
|
@ -3,7 +3,6 @@ package emu.grasscutter.server.game;
|
|||||||
import emu.grasscutter.GameConstants;
|
import emu.grasscutter.GameConstants;
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.Grasscutter.ServerRunMode;
|
import emu.grasscutter.Grasscutter.ServerRunMode;
|
||||||
import emu.grasscutter.data.ResourceLoader;
|
|
||||||
import emu.grasscutter.database.DatabaseHelper;
|
import emu.grasscutter.database.DatabaseHelper;
|
||||||
import emu.grasscutter.game.Account;
|
import emu.grasscutter.game.Account;
|
||||||
import emu.grasscutter.game.battlepass.BattlePassSystem;
|
import emu.grasscutter.game.battlepass.BattlePassSystem;
|
||||||
@ -143,15 +142,11 @@ public final class GameServer extends KcpServer implements Iterable<Player> {
|
|||||||
|
|
||||||
this.init(GameSessionManager.getListener(), channelConfig, address);
|
this.init(GameSessionManager.getListener(), channelConfig, address);
|
||||||
|
|
||||||
// Load game managers asyncronously.
|
EnergyManager.initialize();
|
||||||
ResourceLoader.runAsync(
|
StaminaManager.initialize();
|
||||||
() -> {
|
CookingManager.initialize();
|
||||||
EnergyManager.initialize();
|
CookingCompoundManager.initialize();
|
||||||
StaminaManager.initialize();
|
CombineManger.initialize();
|
||||||
CookingManager.initialize();
|
|
||||||
CookingCompoundManager.initialize();
|
|
||||||
CombineManger.initialize();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Game Server base
|
// Game Server base
|
||||||
this.address = address;
|
this.address = address;
|
||||||
|
@ -342,13 +342,11 @@ public final class Language {
|
|||||||
*/
|
*/
|
||||||
public static void loadTextMaps(boolean bypassCache) {
|
public static void loadTextMaps(boolean bypassCache) {
|
||||||
// Check system timestamps on cache and resources
|
// Check system timestamps on cache and resources
|
||||||
if (!bypassCache) {
|
if (!bypassCache)
|
||||||
try {
|
try {
|
||||||
long cacheModified = Files.getLastModifiedTime(TEXTMAP_CACHE_PATH).toMillis();
|
long cacheModified = Files.getLastModifiedTime(TEXTMAP_CACHE_PATH).toMillis();
|
||||||
|
long textmapsModified =
|
||||||
var stream = Files.list(getResourcePath("TextMap"));
|
Files.list(getResourcePath("TextMap"))
|
||||||
var textmapsModified =
|
|
||||||
stream
|
|
||||||
.filter(path -> path.toString().endsWith(".json"))
|
.filter(path -> path.toString().endsWith(".json"))
|
||||||
.map(
|
.map(
|
||||||
path -> {
|
path -> {
|
||||||
@ -356,17 +354,16 @@ public final class Language {
|
|||||||
return Files.getLastModifiedTime(path).toMillis();
|
return Files.getLastModifiedTime(path).toMillis();
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
Grasscutter.getLogger()
|
Grasscutter.getLogger()
|
||||||
.debug("Exception while checking modified time: {}.", path);
|
.debug("Exception while checking modified time: ", path);
|
||||||
return Long.MAX_VALUE; // Don't use cache, something has gone wrong
|
return Long.MAX_VALUE; // Don't use cache, something has gone wrong
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.max(Long::compare)
|
.max(Long::compare)
|
||||||
.get();
|
.get();
|
||||||
stream.close();
|
|
||||||
|
|
||||||
Grasscutter.getLogger()
|
Grasscutter.getLogger()
|
||||||
.debug(
|
.debug(
|
||||||
"Cache modified %d, textmap modified %d."
|
"Cache modified %d, textmap modified %d"
|
||||||
.formatted(cacheModified, textmapsModified));
|
.formatted(cacheModified, textmapsModified));
|
||||||
if (textmapsModified < cacheModified) {
|
if (textmapsModified < cacheModified) {
|
||||||
// Try loading from cache
|
// Try loading from cache
|
||||||
@ -375,9 +372,8 @@ public final class Language {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (Exception exception) {
|
} catch (Exception exception) {
|
||||||
Grasscutter.getLogger().error("Error loading textmaps cache: " + exception);
|
Grasscutter.getLogger().error("Error loading textmaps cache: " + exception.toString());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Regenerate cache
|
// Regenerate cache
|
||||||
Grasscutter.getLogger().debug("Generating TextMaps cache");
|
Grasscutter.getLogger().debug("Generating TextMaps cache");
|
||||||
|
Loading…
Reference in New Issue
Block a user