Merge pull request #15 from quiqueck/feature/PatchTools
Redesigned `DataFixerAPI`-Management
This commit is contained in:
commit
c677787f91
8 changed files with 374 additions and 24 deletions
289
src/main/java/ru/bclib/api/DataFixerAPI2.java
Normal file
289
src/main/java/ru/bclib/api/DataFixerAPI2.java
Normal file
|
@ -0,0 +1,289 @@
|
||||||
|
package ru.bclib.api;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.nbt.ListTag;
|
||||||
|
import net.minecraft.nbt.NbtIo;
|
||||||
|
import net.minecraft.world.level.ChunkPos;
|
||||||
|
import net.minecraft.world.level.chunk.storage.RegionFile;
|
||||||
|
import ru.bclib.BCLib;
|
||||||
|
import ru.bclib.config.Configs;
|
||||||
|
import ru.bclib.config.PathConfig;
|
||||||
|
import ru.bclib.config.SessionConfig;
|
||||||
|
import ru.bclib.util.Logger;
|
||||||
|
|
||||||
|
public class DataFixerAPI2 {
|
||||||
|
private static final Logger LOGGER = new Logger("DataFixerAPI");
|
||||||
|
|
||||||
|
public static void fixData(SessionConfig config) {
|
||||||
|
if (true || !Configs.MAIN_CONFIG.getBoolean(Configs.MAIN_PATCH_CATEGORY, "applyPatches", true)){
|
||||||
|
LOGGER.info("World Patches are disabled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final File dir = config.levelFolder;
|
||||||
|
Patch.MigrationData data = Patch.createMigrationData(config);
|
||||||
|
if (!data.hasAnyFixes()) {
|
||||||
|
LOGGER.info("Everything up to date");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<File> regions = getAllRegions(dir, null);
|
||||||
|
regions.parallelStream().forEach((file) -> {
|
||||||
|
try {
|
||||||
|
LOGGER.info("Inspecting " + file);
|
||||||
|
boolean[] changed = new boolean[1];
|
||||||
|
RegionFile region = new RegionFile(file, file.getParentFile(), true);
|
||||||
|
for (int x = 0; x < 32; x++) {
|
||||||
|
for (int z = 0; z < 32; z++) {
|
||||||
|
ChunkPos pos = new ChunkPos(x, z);
|
||||||
|
changed[0] = false;
|
||||||
|
if (region.hasChunk(pos)) {
|
||||||
|
DataInputStream input = region.getChunkDataInputStream(pos);
|
||||||
|
CompoundTag root = NbtIo.read(input);
|
||||||
|
// if ((root.toString().contains("betternether") || root.toString().contains("bclib")) && root.toString().contains("chest")) {
|
||||||
|
// NbtIo.write(root, new File(file.toString() + "-" + x + "-" + z + ".nbt"));
|
||||||
|
// }
|
||||||
|
input.close();
|
||||||
|
|
||||||
|
ListTag tileEntities = root.getCompound("Level").getList("TileEntities", 10);
|
||||||
|
fixItemArrayWithID(tileEntities, changed, data, true);
|
||||||
|
|
||||||
|
ListTag sections = root.getCompound("Level").getList("Sections", 10);
|
||||||
|
sections.forEach((tag) -> {
|
||||||
|
ListTag palette = ((CompoundTag) tag).getList("Palette", 10);
|
||||||
|
palette.forEach((blockTag) -> {
|
||||||
|
CompoundTag blockTagCompound = ((CompoundTag) blockTag);
|
||||||
|
changed[0] = data.replaceStringFromIDs(blockTagCompound, "Name");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
if (changed[0]) {
|
||||||
|
LOGGER.warning("Writing '{}': {}/{}", file, x, z);
|
||||||
|
DataOutputStream output = region.getChunkDataOutputStream(pos);
|
||||||
|
NbtIo.write(root, output);
|
||||||
|
output.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
region.close();
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
data.markApplied();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean fixItemArrayWithID(ListTag items, boolean[] changed, Patch.MigrationData data, boolean recursive){
|
||||||
|
items.forEach(inTag -> {
|
||||||
|
final CompoundTag tag = (CompoundTag) inTag;
|
||||||
|
|
||||||
|
changed[0] |= data.replaceStringFromIDs(tag, "id");
|
||||||
|
|
||||||
|
if (recursive && tag.contains("Items")){
|
||||||
|
changed[0] |= fixItemArrayWithID(tag.getList("Items", 10), changed, data, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return changed[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<File> getAllRegions(File dir, List<File> list) {
|
||||||
|
if (list == null) {
|
||||||
|
list = new ArrayList<>();
|
||||||
|
}
|
||||||
|
for (File file : dir.listFiles()) {
|
||||||
|
if (file.isDirectory()) {
|
||||||
|
getAllRegions(file, list);
|
||||||
|
}
|
||||||
|
else if (file.isFile() && file.getName().endsWith(".mca")) {
|
||||||
|
list.add(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract static class Patch {
|
||||||
|
private static List<Patch> ALL = new ArrayList<>(10);
|
||||||
|
private final int level;
|
||||||
|
@NotNull
|
||||||
|
private final String modID;
|
||||||
|
|
||||||
|
static List<Patch> getALL() {
|
||||||
|
return ALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* register a new Patch
|
||||||
|
* @param patch A #Supplier that will instantiate the new Patch Object
|
||||||
|
*/
|
||||||
|
public static void registerPatch(Supplier<Patch> patch){
|
||||||
|
ALL.add(patch.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the highest patch-level that is available for the given mod. If no patches were
|
||||||
|
* registerd for the mod, this will return 0
|
||||||
|
* @param modID The ID of the mod you want to query
|
||||||
|
* @return The highest Patch-Level that was found
|
||||||
|
*/
|
||||||
|
public static int maxPatchLevel(@NotNull String modID){
|
||||||
|
return ALL.stream()
|
||||||
|
.filter(p-> p.getModID().equals(modID))
|
||||||
|
.mapToInt(p->p.level)
|
||||||
|
.max()
|
||||||
|
.orElse(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by inheriting classes.
|
||||||
|
*
|
||||||
|
* Performs some sanity checks on the values and might throw a #RuntimeException if any
|
||||||
|
* inconsistencies are found.
|
||||||
|
*
|
||||||
|
* @param modID The ID of the Mod you want to register a patch for. This should be your
|
||||||
|
* ModID only. The ModID can not be {@code null} or an empty String.
|
||||||
|
* @param level The level of the Patch. This needs to be a non-zero positive value.
|
||||||
|
* Developers are responsible for registering their patches in the correct
|
||||||
|
* order (with increasing levels). You are not allowed to register a new
|
||||||
|
* Patch with a Patch-level lower or equal than
|
||||||
|
* {@link Patch#maxPatchLevel(String)}
|
||||||
|
*/
|
||||||
|
protected Patch(@NotNull String modID, int level) {
|
||||||
|
//Patchlevels need to be unique and registered in ascending order
|
||||||
|
if (modID==null || "".equals(modID)){
|
||||||
|
throw new RuntimeException("[INTERNAL ERROR] Patches need a valid modID!");
|
||||||
|
}
|
||||||
|
if (!ALL.stream().filter(p-> p.getModID().equals(modID)).noneMatch(p -> p.getLevel() >= level) || level <= 0){
|
||||||
|
throw new RuntimeException("[INTERNAL ERROR] Patch-levels need to be created in ascending order beginning with 1.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BCLib.LOGGER.info("Creating Patchlevel {} ({}, {})", level, ALL, ALL.stream().noneMatch(p -> p.getLevel() >= level));
|
||||||
|
this.level = level;
|
||||||
|
this.modID = modID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Patch{" +
|
||||||
|
"level=" + getModID() + ":" + getLevel() +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
final public int getLevel() {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Mod-ID that registered this Patch
|
||||||
|
* @return The ID
|
||||||
|
*/
|
||||||
|
final public String getModID() {
|
||||||
|
return modID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return block data fixes. Fixes will be applied on world load if current patch-level for
|
||||||
|
* the linked mod is lower than the {@link #level}.
|
||||||
|
*
|
||||||
|
* The default implementation of this method returns an empty map.
|
||||||
|
*
|
||||||
|
* @return The returned Map should contain the replacements. All occurences of the
|
||||||
|
* {@code KeySet} are replaced with the associated value.
|
||||||
|
*/
|
||||||
|
public Map<String, String> getIDReplacements(){
|
||||||
|
return new HashMap<String, String>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates ready to use data for all currently registered patches. The list of
|
||||||
|
* patches is selected by the current patch-level of the world.
|
||||||
|
*
|
||||||
|
* A {@link #Patch} with a given {@link #level} is only included if the patch-level of the
|
||||||
|
* world is less
|
||||||
|
* @return a new {@link MigrationData} Object.
|
||||||
|
*/
|
||||||
|
static MigrationData createMigrationData(PathConfig config){
|
||||||
|
return new MigrationData(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class MigrationData{
|
||||||
|
final Set<String> mods;
|
||||||
|
final Map<String, String> idReplacements;
|
||||||
|
private final PathConfig config;
|
||||||
|
|
||||||
|
private MigrationData(PathConfig config){
|
||||||
|
this.config = config;
|
||||||
|
|
||||||
|
this.mods = Collections.unmodifiableSet(Patch.getALL().stream().map(p -> p.modID).collect(Collectors.toSet()));
|
||||||
|
|
||||||
|
HashMap<String, String> replacements = new HashMap<String, String>();
|
||||||
|
for(String modID : mods){
|
||||||
|
Patch.getALL().stream().filter(p -> p.modID.equals(modID)).forEach(patch -> {
|
||||||
|
if (currentPatchLevel(modID) < patch.level) {
|
||||||
|
replacements.putAll(patch.getIDReplacements());
|
||||||
|
LOGGER.info("Applying " + patch);
|
||||||
|
} else {
|
||||||
|
LOGGER.info("Ignoring " + patch);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.idReplacements = Collections.unmodifiableMap(replacements);
|
||||||
|
}
|
||||||
|
|
||||||
|
final public void markApplied(){
|
||||||
|
for(String modID : mods){
|
||||||
|
LOGGER.info("Updating Patch-Level for '{}' from {} to {} -> {}",
|
||||||
|
modID,
|
||||||
|
currentPatchLevel(modID),
|
||||||
|
Patch.maxPatchLevel(modID),
|
||||||
|
config.setInt(Configs.MAIN_PATCH_CATEGORY, modID, Patch.maxPatchLevel(modID))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
config.saveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int currentPatchLevel(@NotNull String modID){
|
||||||
|
return config.getInt(Configs.MAIN_PATCH_CATEGORY, modID, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasAnyFixes(){
|
||||||
|
return idReplacements.size()>0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean replaceStringFromIDs(@NotNull CompoundTag tag, @NotNull String key){
|
||||||
|
if (!tag.contains(key)) return false;
|
||||||
|
|
||||||
|
final String val = tag.getString(key);
|
||||||
|
final String replace = idReplacements.get(val);
|
||||||
|
|
||||||
|
if (replace != null){
|
||||||
|
LOGGER.warning("Replacing ID '{}' with '{}'.", val, replace);
|
||||||
|
tag.putString(key, replace);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
package ru.bclib.config;
|
package ru.bclib.config;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import ru.bclib.BCLib;
|
import ru.bclib.BCLib;
|
||||||
import ru.bclib.config.ConfigKeeper.BooleanEntry;
|
import ru.bclib.config.ConfigKeeper.BooleanEntry;
|
||||||
|
@ -13,9 +15,13 @@ public abstract class Config {
|
||||||
protected final ConfigKeeper keeper;
|
protected final ConfigKeeper keeper;
|
||||||
|
|
||||||
protected abstract void registerEntries();
|
protected abstract void registerEntries();
|
||||||
|
|
||||||
|
public Config(String modID, String group){
|
||||||
|
this(modID, group, null);
|
||||||
|
}
|
||||||
|
|
||||||
public Config(String modID, String group) {
|
protected Config(String modID, String group, File path) {
|
||||||
this.keeper = new ConfigKeeper(modID, group);
|
this.keeper = new ConfigKeeper(modID, group, path);
|
||||||
this.registerEntries();
|
this.registerEntries();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,20 @@
|
||||||
package ru.bclib.config;
|
package ru.bclib.config;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.reflect.TypeToken;
|
import com.google.common.reflect.TypeToken;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import net.minecraft.util.GsonHelper;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import ru.bclib.util.JsonFactory;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
import net.minecraft.util.GsonHelper;
|
||||||
import java.util.Map;
|
import ru.bclib.util.JsonFactory;
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
public final class ConfigKeeper {
|
public final class ConfigKeeper {
|
||||||
private final Map<ConfigKey, Entry<?>> configEntries = Maps.newHashMap();
|
private final Map<ConfigKey, Entry<?>> configEntries = Maps.newHashMap();
|
||||||
|
@ -21,7 +24,11 @@ public final class ConfigKeeper {
|
||||||
private boolean changed = false;
|
private boolean changed = false;
|
||||||
|
|
||||||
public ConfigKeeper(String modID, String group) {
|
public ConfigKeeper(String modID, String group) {
|
||||||
this.writer = new ConfigWriter(modID, group);
|
this(modID, group, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ConfigKeeper(String modID, String group, File path) {
|
||||||
|
this.writer = new ConfigWriter(modID, group, path);
|
||||||
this.configObject = writer.load();
|
this.configObject = writer.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
package ru.bclib.config;
|
package ru.bclib.config;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
|
||||||
import ru.bclib.util.JsonFactory;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
|
import ru.bclib.util.JsonFactory;
|
||||||
|
|
||||||
public class ConfigWriter {
|
public class ConfigWriter {
|
||||||
private final static Path GAME_CONFIG_DIR = FabricLoader.getInstance().getConfigDir();
|
private final static Path GAME_CONFIG_DIR = FabricLoader.getInstance().getConfigDir();
|
||||||
|
|
||||||
|
@ -15,7 +16,16 @@ public class ConfigWriter {
|
||||||
private JsonObject configObject;
|
private JsonObject configObject;
|
||||||
|
|
||||||
public ConfigWriter(String modID, String configFile) {
|
public ConfigWriter(String modID, String configFile) {
|
||||||
this.configFile = new File(new File(GAME_CONFIG_DIR.toFile(), modID), configFile + ".json");
|
this(modID, configFile, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigWriter(String modID, String configFile, File configFolder) {
|
||||||
|
this.configFile = new File(
|
||||||
|
(configFolder==null
|
||||||
|
? GAME_CONFIG_DIR.resolve(modID).toFile()
|
||||||
|
: new File(configFolder, modID)),
|
||||||
|
configFile + ".json"
|
||||||
|
);
|
||||||
File parent = this.configFile.getParentFile();
|
File parent = this.configFile.getParentFile();
|
||||||
if (!parent.exists()) {
|
if (!parent.exists()) {
|
||||||
parent.mkdirs();
|
parent.mkdirs();
|
||||||
|
|
|
@ -3,9 +3,13 @@ package ru.bclib.config;
|
||||||
import ru.bclib.BCLib;
|
import ru.bclib.BCLib;
|
||||||
|
|
||||||
public class Configs {
|
public class Configs {
|
||||||
|
public static final PathConfig MAIN_CONFIG = new PathConfig(BCLib.MOD_ID, "main");
|
||||||
|
public static final String MAIN_PATCH_CATEGORY = "patches";
|
||||||
|
|
||||||
public static final PathConfig RECIPE_CONFIG = new PathConfig(BCLib.MOD_ID, "recipes");
|
public static final PathConfig RECIPE_CONFIG = new PathConfig(BCLib.MOD_ID, "recipes");
|
||||||
|
|
||||||
public static void save() {
|
public static void save() {
|
||||||
|
MAIN_CONFIG.saveChanges();
|
||||||
RECIPE_CONFIG.saveChanges();
|
RECIPE_CONFIG.saveChanges();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package ru.bclib.config;
|
package ru.bclib.config;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import ru.bclib.config.ConfigKeeper.Entry;
|
import ru.bclib.config.ConfigKeeper.Entry;
|
||||||
import ru.bclib.config.ConfigKeeper.FloatRange;
|
import ru.bclib.config.ConfigKeeper.FloatRange;
|
||||||
|
@ -8,7 +10,11 @@ import ru.bclib.config.ConfigKeeper.IntegerRange;
|
||||||
public class PathConfig extends Config {
|
public class PathConfig extends Config {
|
||||||
|
|
||||||
public PathConfig(String modID, String group) {
|
public PathConfig(String modID, String group) {
|
||||||
super(modID, group);
|
this(modID, group, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected PathConfig(String modID, String group, File path) {
|
||||||
|
super(modID, group, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
25
src/main/java/ru/bclib/config/SessionConfig.java
Normal file
25
src/main/java/ru/bclib/config/SessionConfig.java
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
package ru.bclib.config;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||||
|
import ru.bclib.BCLib;
|
||||||
|
|
||||||
|
public class SessionConfig extends PathConfig{
|
||||||
|
private static File getWorldFolder(LevelStorageSource.LevelStorageAccess session, ServerLevel world){
|
||||||
|
File dir = session.getDimensionPath(world.dimension());
|
||||||
|
if (!new File(dir, "level.dat").exists()) {
|
||||||
|
dir = dir.getParentFile();
|
||||||
|
}
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final File levelFolder;
|
||||||
|
|
||||||
|
public SessionConfig(String modID, String group, LevelStorageSource.LevelStorageAccess session, ServerLevel world) {
|
||||||
|
super(modID, group, new File(getWorldFolder(session, world), BCLib.MOD_ID));
|
||||||
|
|
||||||
|
this.levelFolder = new File(getWorldFolder(session, world), BCLib.MOD_ID);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,10 @@
|
||||||
package ru.bclib.mixin.common;
|
package ru.bclib.mixin.common;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
@ -16,14 +21,11 @@ import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
import ru.bclib.BCLib;
|
||||||
import ru.bclib.api.BiomeAPI;
|
import ru.bclib.api.BiomeAPI;
|
||||||
import ru.bclib.api.DataFixerAPI;
|
import ru.bclib.api.DataFixerAPI2;
|
||||||
import ru.bclib.api.WorldDataAPI;
|
import ru.bclib.api.WorldDataAPI;
|
||||||
|
import ru.bclib.config.SessionConfig;
|
||||||
import java.io.File;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
@Mixin(ServerLevel.class)
|
@Mixin(ServerLevel.class)
|
||||||
public abstract class ServerLevelMixin extends Level {
|
public abstract class ServerLevelMixin extends Level {
|
||||||
|
@ -49,7 +51,8 @@ public abstract class ServerLevelMixin extends Level {
|
||||||
dir = dir.getParentFile();
|
dir = dir.getParentFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
DataFixerAPI.fixData(dir);
|
//DataFixerAPI.fixData(dir);
|
||||||
|
DataFixerAPI2.fixData(new SessionConfig(BCLib.MOD_ID, "patches", session, world));
|
||||||
WorldDataAPI.load(new File(dir, "data"));
|
WorldDataAPI.load(new File(dir, "data"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue