From 489d6f824dca8c4623e643262ffa4825ee8219ee Mon Sep 17 00:00:00 2001
From: deirn <deirn@bai.lol>
Date: Wed, 29 Jun 2022 01:25:06 +0700
Subject: [PATCH] Port fix for MC-195468 to 1.18.2 (#2343)

* re-enable custom dimension test

* port ServerBugfixMixin to 1.18.2
---
 .../mixin/dimension/ServerBugfixMixin.java    | 54 ++++++++++++++++++-
 .../test/dimension/FabricDimensionTest.java   |  5 --
 2 files changed, 52 insertions(+), 7 deletions(-)

diff --git a/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/ServerBugfixMixin.java b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/ServerBugfixMixin.java
index 68fe93409..d45b9ef50 100644
--- a/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/ServerBugfixMixin.java
+++ b/fabric-dimensions-v1/src/main/java/net/fabricmc/fabric/mixin/dimension/ServerBugfixMixin.java
@@ -16,9 +16,22 @@
 
 package net.fabricmc.fabric.mixin.dimension;
 
+import com.mojang.serialization.DynamicOps;
+import com.mojang.serialization.Lifecycle;
 import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Unique;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.ModifyVariable;
+import org.spongepowered.asm.mixin.injection.Redirect;
 
+import net.minecraft.nbt.NbtElement;
+import net.minecraft.resource.DataPackSettings;
 import net.minecraft.server.Main;
+import net.minecraft.util.registry.DynamicRegistryManager;
+import net.minecraft.world.gen.GeneratorOptions;
+import net.minecraft.world.level.LevelInfo;
+import net.minecraft.world.level.LevelProperties;
+import net.minecraft.world.level.storage.LevelStorage;
 
 /**
  * This Mixin aims to solve a Minecraft Vanilla bug where datapacks are ignored during creation of the
@@ -33,11 +46,48 @@ import net.minecraft.server.Main;
  *
  * <p>See https://bugs.mojang.com/browse/MC-195468 for a related bug report.
  *
- * <p>In 1.18: Retest if this bug still occurs without this Mixin by launching a dedicated server with the
+ * <p>In 1.19: Retest if this bug still occurs without this Mixin by launching a dedicated server with the
  * dimension testmod, and no world directory. If the dimension is available (i.e. in /execute in, or via
  * the testmod's commands), then the bug is fixed and this Mixin can be removed.
  */
 @Mixin(value = Main.class)
 public class ServerBugfixMixin {
-	// TODO fix me 22w06a
+	@Unique
+	private static LevelStorage.Session session;
+
+	@Unique
+	private static DynamicRegistryManager.Mutable drm;
+
+	@Unique
+	private static DynamicOps<NbtElement> ops;
+
+	@ModifyVariable(method = "main", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/level/storage/LevelStorage;createSession(Ljava/lang/String;)Lnet/minecraft/world/level/storage/LevelStorage$Session;"))
+	private static LevelStorage.Session captureSession(LevelStorage.Session value) {
+		session = value;
+		return value;
+	}
+
+	@ModifyVariable(method = "method_40373", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/util/registry/DynamicRegistryManager;createAndLoad()Lnet/minecraft/util/registry/DynamicRegistryManager$Mutable;"))
+	private static DynamicRegistryManager.Mutable captureDrm(DynamicRegistryManager.Mutable value) {
+		drm = value;
+		return value;
+	}
+
+	// The value is stored as DynamicOps instead of RegistryOps in the bytecode
+	@ModifyVariable(method = "method_40373", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/util/dynamic/RegistryOps;ofLoaded(Lcom/mojang/serialization/DynamicOps;Lnet/minecraft/util/registry/DynamicRegistryManager$Mutable;Lnet/minecraft/resource/ResourceManager;)Lnet/minecraft/util/dynamic/RegistryOps;"))
+	private static DynamicOps<NbtElement> captureOps(DynamicOps<NbtElement> value) {
+		ops = value;
+		return value;
+	}
+
+	@Redirect(method = "method_40373", at = @At(value = "NEW", target = "net/minecraft/world/level/LevelProperties"))
+	private static LevelProperties onCreateNewLevelProperties(LevelInfo levelInfo, GeneratorOptions generatorOptions, Lifecycle lifecycle) {
+		DataPackSettings dataPackSettings = levelInfo.getDataPackSettings();
+
+		// Save the level.dat file
+		session.backupLevelDataFile(drm, new LevelProperties(levelInfo, generatorOptions, lifecycle));
+
+		// And reload it again, and replace the actual level properties with it
+		return (LevelProperties) session.readLevelProperties(ops, dataPackSettings, drm.getRegistryLifecycle());
+	}
 }
diff --git a/fabric-dimensions-v1/src/testmod/java/net/fabricmc/fabric/test/dimension/FabricDimensionTest.java b/fabric-dimensions-v1/src/testmod/java/net/fabricmc/fabric/test/dimension/FabricDimensionTest.java
index 5e58e3b17..5efd28584 100644
--- a/fabric-dimensions-v1/src/testmod/java/net/fabricmc/fabric/test/dimension/FabricDimensionTest.java
+++ b/fabric-dimensions-v1/src/testmod/java/net/fabricmc/fabric/test/dimension/FabricDimensionTest.java
@@ -74,11 +74,6 @@ public class FabricDimensionTest implements ModInitializer {
 		}
 
 		ServerLifecycleEvents.SERVER_STARTED.register(server -> {
-			if (true) {
-				// TODO 22w06a ServerBugfixMixin
-				return;
-			}
-
 			ServerWorld overworld = server.getWorld(World.OVERWORLD);
 			ServerWorld world = server.getWorld(WORLD_KEY);