2323import java .util .Iterator ;
2424import java .util .Map ;
2525
26- import net .minecraftforge .common .MinecraftForge ;
27- import net .minecraftforge .event .world .WorldEvent ;
2826import org .spongepowered .asm .mixin .Final ;
2927import org .spongepowered .asm .mixin .Mixin ;
3028import org .spongepowered .asm .mixin .Shadow ;
3735import net .minecraft .util .NonBlockingThreadExecutor ;
3836import net .minecraft .world .dimension .DimensionType ;
3937
38+ import com .patchworkmc .impl .event .world .WorldEvents ;
39+
4040@ Mixin (MinecraftServer .class )
4141public abstract class MixinMinecraftServer extends NonBlockingThreadExecutor <ServerTask > {
4242 public MixinMinecraftServer (String name ) {
@@ -47,66 +47,72 @@ public MixinMinecraftServer(String name) {
4747 @ Final
4848 private Map <DimensionType , ServerWorld > worlds ;
4949
50+ /*
51+ // This is a varient of the world load hook that is less likely to break mods and more likely to break on updates.
5052 // Should get called once per loop, regardless of which if branch it takes.
51- // @Inject(
52- // method = "createWorlds",
53- // slice = @Slice(
54- // from = @At(value = "INVOKE", target = "java/util/Iterator.hasNext ()Z")
55- // ),
56- // at = @At(value = "JUMP", opcode = Opcodes.GOTO),
57- // locals = LocalCapture.CAPTURE_FAILHARD
58- // )
59- // private void hookCreateWorlds(WorldSaveHandler worldSaveHandler, LevelProperties properties, LevelInfo levelInfo, WorldGenerationProgressListener worldGenerationProgressListener, CallbackInfo ci, ServerWorld serverWorld, ServerWorld serverWorld2, Iterator var7, DimensionType dimensionType) {
60- // MinecraftForge.EVENT_BUS.post(new WorldEvent.Load(this.worlds.get(dimensionType)));
61- // }
62-
63- // Alternatively, mixin to the put call, and special case overworld.
64- // Perhaps move the special case outside of the loop?
53+ @Inject(
54+ method = "createWorlds",
55+ slice = @Slice(
56+ from = @At(value = "INVOKE", target = "java/util/Iterator.hasNext ()Z")
57+ ),
58+ at = @At(value = "JUMP", opcode = Opcodes.GOTO),
59+ locals = LocalCapture.CAPTURE_FAILHARD
60+ )
61+ private void hookCreateWorlds(WorldSaveHandler worldSaveHandler, LevelProperties properties, LevelInfo levelInfo, WorldGenerationProgressListener worldGenerationProgressListener, CallbackInfo ci, ServerWorld serverWorld, ServerWorld serverWorld2, Iterator var7, DimensionType dimensionType) {
62+ WorldEvents.onWorldLoad(this.worlds.get(dimensionType));
63+ }
64+
65+ */
66+
67+ // This injection gets called at the beginning of each loop, and is used to special case the overworld dimension type.
6568 @ Redirect (method = "createWorlds" , at = @ At (value = "INVOKE" , target = "java/util/Iterator.next ()Ljava/lang/Object;" ))
6669 private Object proxyNextWorldToSpecialCaseOverworld (Iterator iterator ) {
6770 DimensionType type = (DimensionType ) iterator .next ();
6871
6972 if (type == DimensionType .OVERWORLD ) {
70- MinecraftForge . EVENT_BUS . post ( new WorldEvent . Load ( this .worlds .get (type ) ));
73+ WorldEvents . onWorldLoad ( this .worlds .get (type ));
7174 }
7275
7376 return type ;
7477 }
7578
79+ // This injection handles every other dimension type.
7680 @ Redirect (method = "createWorlds" , at = @ At (value = "INVOKE" , target = "java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;" , ordinal = 1 ))
7781 private Object proxyPutWorld (Map worlds , Object type , Object world ) {
7882 worlds .put (type , world );
79- MinecraftForge . EVENT_BUS . post ( new WorldEvent . Load (( ServerWorld ) world ) );
83+ WorldEvents . onWorldLoad (( ServerWorld ) world );
8084 return world ;
8185 }
8286
83- // TODO: Should we Inject into ServerWorld.close instead? Currently, this follows Forge's patch location.
8487 @ Redirect (method = "shutdown" , at = @ At (value = "INVOKE" , target = "net/minecraft/server/world/ServerWorld.close ()V" ))
8588 private void proxyClose (ServerWorld world ) throws IOException {
86- MinecraftForge . EVENT_BUS . post ( new WorldEvent . Unload ( world ) );
89+ WorldEvents . onWorldUnload ( world );
8790 world .close ();
8891 }
8992
93+ /*
94+ // TODO: DimensionManager, and move this into a seperate module
95+ @Inject(method = "createWorlds", at = @At(value = "HEAD"))
96+ private void hookCreateWorldsForDimensionRegistration(CallbackInfo info) {
97+ DimensionManager.fireRegister();
98+ }
99+
90100 @Shadow
91101 private int ticks;
92102
93- // TODO: DimensionManager, and move this into a seperate module
94- // @Inject(method = "createWorlds", at = @At(value = "HEAD"))
95- // private void hookCreateWorldsForDimensionRegistration(CallbackInfo info) {
96- // DimensionManager.fireRegister();
97- // }
98-
99- // @Redirect(method = "tickWorlds", at = @At(value = "INVOKE_STRING", target = "net/minecraft/util/profiler/DisableableProfiler.swap (Ljava/lang/String;)V", args = { "ldc=connection" }))
100- // private void hookTickWorldsForDimensionUnload(DisableableProfiler profiler, String section) {
101- // MinecraftServer server = (MinecraftServer) (Object) this;
102- // profiler.swap("dim_unloading");
103- // DimensionManager.unloadWorlds(server, this.ticks % 200);
104- // profiler.swap(section);
105- // }
106-
107- // @Redirect(method = "getWorld", at = @At(value = "INVOKE", target = "java/util/Map.get (Ljava/lang/Object;)Ljava/lang/Object;"))
108- // private Object hookGetWorld(Map worlds, Object type) {
109- // MinecraftServer server = (MinecraftServer) (Object) this;
110- // return DimensionManager.getWorld(server, type, true, true);
111- // }
103+ @Redirect(method = "tickWorlds", at = @At(value = "INVOKE_STRING", target = "net/minecraft/util/profiler/DisableableProfiler.swap (Ljava/lang/String;)V", args = { "ldc=connection" }))
104+ private void hookTickWorldsForDimensionUnload(DisableableProfiler profiler, String section) {
105+ MinecraftServer server = (MinecraftServer) (Object) this;
106+ profiler.swap("dim_unloading");
107+ DimensionManager.unloadWorlds(server, this.ticks % 200);
108+ profiler.swap(section);
109+ }
110+
111+ @Redirect(method = "getWorld", at = @At(value = "INVOKE", target = "java/util/Map.get (Ljava/lang/Object;)Ljava/lang/Object;"))
112+ private Object hookGetWorld(Map worlds, Object type) {
113+ MinecraftServer server = (MinecraftServer) (Object) this;
114+ return DimensionManager.getWorld(server, type, true, true);
115+ }
116+
117+ */
112118}
0 commit comments