embeddedt 2023-01-01 16:16:52 -05:00
parent 94b5c8dd8e
commit 055721f494
No known key found for this signature in database
GPG Key ID: A69433EC199B5613
6 changed files with 230 additions and 2 deletions

View File

@ -0,0 +1,5 @@
package org.embeddedt.modernfix.duck;
public interface ILevelSave {
public void runWorldPersistenceHooks();
}

View File

@ -0,0 +1,32 @@
package org.embeddedt.modernfix.mixin;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.world.storage.SaveFormat;
import org.embeddedt.modernfix.ModernFix;
import org.embeddedt.modernfix.duck.ILevelSave;
import org.embeddedt.modernfix.util.DummyServerConfiguration;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import java.nio.file.Path;
@Mixin(SaveFormat.LevelSave.class)
public class LevelSaveMixin implements ILevelSave {
@Shadow @Final private SaveFormat this$0;
@Shadow @Final private Path saveDir;
public void runWorldPersistenceHooks() {
((SaveFormatAccessor)this.this$0).invokeReadFromLevelData(this.saveDir.toFile(), (file, dataFixer) -> {
try {
CompoundNBT compoundTag = CompressedStreamTools.readCompressed(file);
net.minecraftforge.fml.WorldPersistenceHooks.handleWorldDataLoad((SaveFormat.LevelSave)(Object)this, new DummyServerConfiguration(), compoundTag);
} catch (Exception e) {
ModernFix.LOGGER.error("Exception reading {}", file, e);
}
return null;
});
}
}

View File

@ -9,17 +9,24 @@ import net.minecraft.world.storage.IServerConfiguration;
import net.minecraft.world.storage.SaveFormat;
import org.embeddedt.modernfix.ModernFix;
import org.embeddedt.modernfix.ModernFixClient;
import org.embeddedt.modernfix.duck.ILevelSave;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.concurrent.ExecutionException;
import java.util.function.Function;
@Mixin(Minecraft.class)
public class MinecraftMixin {
public abstract class MinecraftMixin {
@Shadow public abstract Minecraft.PackManager reloadDatapacks(DynamicRegistries.Impl dynamicRegistries, Function<SaveFormat.LevelSave, DatapackCodec> worldStorageToDatapackFunction, Function4<SaveFormat.LevelSave, DynamicRegistries.Impl, IResourceManager, DatapackCodec, IServerConfiguration> quadFunction, boolean vanillaOnly, SaveFormat.LevelSave worldStorage) throws InterruptedException, ExecutionException;
private long datapackReloadStartTime;
private int registryHash;
@Inject(method = "reloadDatapacks", at = @At(value = "HEAD"))
private void recordReloadStart(DynamicRegistries.Impl p_238189_1_, Function<SaveFormat.LevelSave, DatapackCodec> p_238189_2_, Function4<SaveFormat.LevelSave, DynamicRegistries.Impl, IResourceManager, DatapackCodec, IServerConfiguration> p_238189_3_, boolean p_238189_4_, SaveFormat.LevelSave p_238189_5_, CallbackInfoReturnable<Minecraft.PackManager> cir) {
datapackReloadStartTime = System.nanoTime();
@ -35,4 +42,21 @@ public class MinecraftMixin {
private void recordWorldLoadStart(String worldName, DynamicRegistries.Impl dynamicRegistries, Function<SaveFormat.LevelSave, DatapackCodec> levelSaveToDatapackFunction, Function4<SaveFormat.LevelSave, DynamicRegistries.Impl, IResourceManager, DatapackCodec, IServerConfiguration> quadFunction, boolean vanillaOnly, Minecraft.WorldSelectionType selectionType, boolean creating, CallbackInfo ci) {
ModernFixClient.worldLoadStartTime = System.nanoTime();
}
@Redirect(method = "loadWorld(Ljava/lang/String;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/registry/DynamicRegistries;func_239770_b_()Lnet/minecraft/util/registry/DynamicRegistries$Impl;"))
private DynamicRegistries.Impl useNullRegistry() {
return null;
}
@Redirect(method = "loadWorld(Ljava/lang/String;Lnet/minecraft/util/registry/DynamicRegistries$Impl;Ljava/util/function/Function;Lcom/mojang/datafixers/util/Function4;ZLnet/minecraft/client/Minecraft$WorldSelectionType;Z)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;reloadDatapacks(Lnet/minecraft/util/registry/DynamicRegistries$Impl;Ljava/util/function/Function;Lcom/mojang/datafixers/util/Function4;ZLnet/minecraft/world/storage/SaveFormat$LevelSave;)Lnet/minecraft/client/Minecraft$PackManager;", ordinal = 0))
private Minecraft.PackManager skipFirstReload(Minecraft client, DynamicRegistries.Impl dynamicRegistries, Function<SaveFormat.LevelSave, DatapackCodec> worldStorageToDatapackFunction, Function4<SaveFormat.LevelSave, DynamicRegistries.Impl, IResourceManager, DatapackCodec, IServerConfiguration> quadFunction, boolean vanillaOnly, SaveFormat.LevelSave levelSave, String worldName, DynamicRegistries.Impl originalRegistries, Function<SaveFormat.LevelSave, DatapackCodec> levelSaveToDatapackFunction, Function4<SaveFormat.LevelSave, DynamicRegistries.Impl, IResourceManager, DatapackCodec, IServerConfiguration> quadFunction2, boolean vanillaOnly2, Minecraft.WorldSelectionType selectionType, boolean creating) throws InterruptedException, ExecutionException {
if(!creating) {
ModernFix.LOGGER.warn("Skipping first reload, this is still experimental");
((ILevelSave)levelSave).runWorldPersistenceHooks();
return null;
} else {
/* allow reload */
return reloadDatapacks(dynamicRegistries, worldStorageToDatapackFunction, quadFunction, vanillaOnly, levelSave);
}
}
}

View File

@ -0,0 +1,15 @@
package org.embeddedt.modernfix.mixin;
import com.mojang.datafixers.DataFixer;
import net.minecraft.world.storage.SaveFormat;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
import java.io.File;
import java.util.function.BiFunction;
@Mixin(SaveFormat.class)
public interface SaveFormatAccessor {
@Invoker
<T> T invokeReadFromLevelData(File saveDir, BiFunction<File, DataFixer, T> levelDatReader);
}

View File

@ -0,0 +1,150 @@
package org.embeddedt.modernfix.util;
import com.google.common.collect.ImmutableSet;
import com.mojang.serialization.Lifecycle;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.datafix.codec.DatapackCodec;
import net.minecraft.util.registry.DynamicRegistries;
import net.minecraft.world.Difficulty;
import net.minecraft.world.GameRules;
import net.minecraft.world.GameType;
import net.minecraft.world.WorldSettings;
import net.minecraft.world.gen.settings.DimensionGeneratorSettings;
import net.minecraft.world.storage.IServerConfiguration;
import net.minecraft.world.storage.IServerWorldInfo;
import javax.annotation.Nullable;
import java.util.Set;
public class DummyServerConfiguration implements IServerConfiguration {
@Override
public DatapackCodec getDatapackCodec() {
return DatapackCodec.VANILLA_CODEC;
}
@Override
public void setDatapackCodec(DatapackCodec codec) {
}
@Override
public boolean isModded() {
return true;
}
@Override
public Set<String> getServerBranding() {
return ImmutableSet.of("forge");
}
@Override
public void addServerBranding(String name, boolean isModded) {
}
@Nullable
@Override
public CompoundNBT getCustomBossEventData() {
return null;
}
@Override
public void setCustomBossEventData(@Nullable CompoundNBT nbt) {
}
@Override
public IServerWorldInfo getServerWorldInfo() {
return null;
}
@Override
public WorldSettings getWorldSettings() {
return null;
}
@Override
public CompoundNBT serialize(DynamicRegistries registries, @Nullable CompoundNBT hostPlayerNBT) {
return null;
}
@Override
public boolean isHardcore() {
return false;
}
@Override
public int getStorageVersionId() {
return 0;
}
@Override
public String getWorldName() {
return null;
}
@Override
public GameType getGameType() {
return null;
}
@Override
public void setGameType(GameType type) {
}
@Override
public boolean areCommandsAllowed() {
return false;
}
@Override
public Difficulty getDifficulty() {
return null;
}
@Override
public void setDifficulty(Difficulty difficulty) {
}
@Override
public boolean isDifficultyLocked() {
return false;
}
@Override
public void setDifficultyLocked(boolean locked) {
}
@Override
public GameRules getGameRulesInstance() {
return null;
}
@Override
public CompoundNBT getHostPlayerNBT() {
return null;
}
@Override
public CompoundNBT getDragonFightData() {
return null;
}
@Override
public void setDragonFightData(CompoundNBT nbt) {
}
@Override
public DimensionGeneratorSettings getDimensionGeneratorSettings() {
return null;
}
@Override
public Lifecycle getLifecycle() {
return Lifecycle.stable();
}
}

View File

@ -6,7 +6,9 @@
"refmap": "modernfix.refmap.json",
"mixins": [
"ModFileResourcePackMixin",
"VanillaPackMixin"
"VanillaPackMixin",
"LevelSaveMixin",
"SaveFormatAccessor"
],
"client": [
"MinecraftMixin"