diff --git a/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/event/common/AddPackFindersCallback.java b/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/event/common/AddPackFindersCallback.java index 0bbba3ea..514469f7 100644 --- a/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/event/common/AddPackFindersCallback.java +++ b/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/event/common/AddPackFindersCallback.java @@ -6,6 +6,10 @@ import net.fabricmc.fabric.api.event.EventFactory; import net.minecraft.server.packs.repository.RepositorySource; +/** + * Use {@link AddPackFindersEvent} + */ +@Deprecated(forRemoval = true) public interface AddPackFindersCallback { Event EVENT = EventFactory.createArrayBacked(AddPackFindersCallback.class, callbacks -> (sources) -> { for (AddPackFindersCallback e : callbacks) { diff --git a/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/event/common/AddPackFindersEvent.java b/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/event/common/AddPackFindersEvent.java new file mode 100644 index 00000000..6956b55e --- /dev/null +++ b/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/event/common/AddPackFindersEvent.java @@ -0,0 +1,52 @@ +package io.github.fabricators_of_create.porting_lib.event.common; + +import java.util.function.Consumer; + +import io.github.fabricators_of_create.porting_lib.core.event.BaseEvent; +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.server.packs.PackType; +import net.minecraft.server.packs.repository.PackRepository; +import net.minecraft.server.packs.repository.RepositorySource; + +/** + * Fired on {@link PackRepository} creation to allow mods to add new pack finders. + */ +public class AddPackFindersEvent extends BaseEvent { + public static final Event EVENT = EventFactory.createArrayBacked(Callback.class, callbacks -> event -> { + for (Callback c : callbacks) + c.findPacks(event); + }); + private final PackType packType; + private final Consumer sources; + + public AddPackFindersEvent(PackType packType, Consumer sources) { + this.packType = packType; + this.sources = sources; + } + + /** + * Adds a new source to the list of pack finders. + * + * @param source the pack finder + */ + public void addRepositorySource(RepositorySource source) { + sources.accept(source); + } + + /** + * @return the {@link PackType} of the pack repository being constructed. + */ + public PackType getPackType() { + return packType; + } + + @Override + public void sendEvent() { + EVENT.invoker().findPacks(this); + } + + public interface Callback { + void findPacks(AddPackFindersEvent event); + } +} diff --git a/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/extensions/PackRepositoryExtension.java b/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/extensions/PackRepositoryExtension.java new file mode 100644 index 00000000..3f6ab5cf --- /dev/null +++ b/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/extensions/PackRepositoryExtension.java @@ -0,0 +1,9 @@ +package io.github.fabricators_of_create.porting_lib.extensions; + +import net.minecraft.server.packs.repository.RepositorySource; + +public interface PackRepositoryExtension { + default void pl$addPackFinder(RepositorySource packFinder) { + throw new RuntimeException("PackRepository implementation does not support adding sources!"); + } +} diff --git a/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/mixin/client/CreateWorldScreenMixin.java b/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/mixin/client/CreateWorldScreenMixin.java new file mode 100644 index 00000000..03218926 --- /dev/null +++ b/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/mixin/client/CreateWorldScreenMixin.java @@ -0,0 +1,24 @@ +package io.github.fabricators_of_create.porting_lib.mixin.client; + +import com.llamalad7.mixinextras.sugar.Local; + +import io.github.fabricators_of_create.porting_lib.event.common.AddPackFindersEvent; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.gui.screens.worldselection.CreateWorldScreen; + +import net.minecraft.server.packs.PackType; +import net.minecraft.server.packs.repository.PackRepository; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(CreateWorldScreen.class) +public class CreateWorldScreenMixin { + @Inject(method = "openFresh", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/worldselection/CreateWorldScreen;createDefaultLoadConfig(Lnet/minecraft/server/packs/repository/PackRepository;Lnet/minecraft/world/level/WorldDataConfiguration;)Lnet/minecraft/server/WorldLoader$InitConfig;")) + private static void addPacks(Minecraft minecraft, Screen screen, CallbackInfo ci, @Local(index = 2) PackRepository repository) { + new AddPackFindersEvent(PackType.SERVER_DATA, repository::pl$addPackFinder).sendEvent(); + } +} diff --git a/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/mixin/client/MinecraftMixin.java b/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/mixin/client/MinecraftMixin.java index 3d0e6ef8..977ac728 100644 --- a/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/mixin/client/MinecraftMixin.java +++ b/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/mixin/client/MinecraftMixin.java @@ -3,13 +3,17 @@ import com.llamalad7.mixinextras.injector.WrapWithCondition; import io.github.fabricators_of_create.porting_lib.block.CustomHitEffectsBlock; +import io.github.fabricators_of_create.porting_lib.event.common.AddPackFindersEvent; import net.minecraft.client.particle.ParticleEngine; +import net.minecraft.server.packs.PackType; +import net.minecraft.server.packs.repository.PackRepository; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.Nullable; import org.objectweb.asm.Opcodes; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -56,6 +60,10 @@ public abstract class MinecraftMixin { @Nullable public HitResult hitResult; + @Shadow + @Final + private PackRepository resourcePackRepository; + @Inject( method = "", at = @At( @@ -79,6 +87,11 @@ public abstract class MinecraftMixin { ModsLoadedCallback.EVENT.invoker().onAllModsLoaded(EnvType.CLIENT); } + @Inject(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/packs/repository/PackRepository;reload()V")) + private void addClientResources(GameConfig gameConfig, CallbackInfo ci) { + new AddPackFindersEvent(PackType.CLIENT_RESOURCES, this.resourcePackRepository::pl$addPackFinder).sendEvent(); + } + @Inject(method = "setLevel", at = @At("HEAD")) public void port_lib$onHeadJoinWorld(ClientLevel world, CallbackInfo ci) { if (this.level != null) { diff --git a/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/mixin/common/PackRepositoryMixin.java b/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/mixin/common/PackRepositoryMixin.java index 5d8ff363..5eac582c 100644 --- a/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/mixin/common/PackRepositoryMixin.java +++ b/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/mixin/common/PackRepositoryMixin.java @@ -1,8 +1,9 @@ package io.github.fabricators_of_create.porting_lib.mixin.common; import io.github.fabricators_of_create.porting_lib.event.common.AddPackFindersCallback; -import net.minecraft.server.packs.repository.PackRepository; +import io.github.fabricators_of_create.porting_lib.extensions.PackRepositoryExtension; +import net.minecraft.server.packs.repository.PackRepository; import net.minecraft.server.packs.repository.RepositorySource; import org.spongepowered.asm.mixin.Final; @@ -15,13 +16,18 @@ import java.util.Set; @Mixin(PackRepository.class) -public abstract class PackRepositoryMixin { +public class PackRepositoryMixin implements PackRepositoryExtension { @Shadow @Final private Set sources; + @Override + public synchronized void pl$addPackFinder(RepositorySource packFinder) { + this.sources.add(packFinder); + } + @Inject(method = "", at = @At("TAIL")) - public void port_lib$addModdedPacks(RepositorySource[] repositorySources, CallbackInfo ci) { - AddPackFindersCallback.EVENT.invoker().addPack(sources::add); + public void addModdedPacks(RepositorySource[] repositorySources, CallbackInfo ci) { + AddPackFindersCallback.EVENT.invoker().addPack(this::pl$addPackFinder); } } diff --git a/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/mixin/common/ServerPacksSourceMixin.java b/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/mixin/common/ServerPacksSourceMixin.java new file mode 100644 index 00000000..5ee7ffc3 --- /dev/null +++ b/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/mixin/common/ServerPacksSourceMixin.java @@ -0,0 +1,21 @@ +package io.github.fabricators_of_create.porting_lib.mixin.common; + +import io.github.fabricators_of_create.porting_lib.event.common.AddPackFindersEvent; +import net.minecraft.server.packs.PackType; +import net.minecraft.server.packs.repository.PackRepository; +import net.minecraft.server.packs.repository.ServerPacksSource; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.nio.file.Path; + +@Mixin(ServerPacksSource.class) +public class ServerPacksSourceMixin { + @Inject(method = "createPackRepository(Ljava/nio/file/Path;)Lnet/minecraft/server/packs/repository/PackRepository;", at = @At("RETURN")) + private static void firePackFinders(Path path, CallbackInfoReturnable cir) { + new AddPackFindersEvent(PackType.SERVER_DATA, cir.getReturnValue()::pl$addPackFinder).sendEvent(); + } +} diff --git a/modules/base/src/main/resources/fabric.mod.json b/modules/base/src/main/resources/fabric.mod.json index 170beba8..0838ac7c 100644 --- a/modules/base/src/main/resources/fabric.mod.json +++ b/modules/base/src/main/resources/fabric.mod.json @@ -14,6 +14,7 @@ }, "custom": { "loom:injected_interfaces": { + "net/minecraft/class_3283": ["io/github/fabricators_of_create/porting_lib/extensions/PackRepositoryExtension"], "net/minecraft/class_2680": ["io/github/fabricators_of_create/porting_lib/extensions/BaseBlockStateExtension"] } } diff --git a/modules/base/src/main/resources/porting_lib_base.mixins.json b/modules/base/src/main/resources/porting_lib_base.mixins.json index 19f03b3f..cacff800 100644 --- a/modules/base/src/main/resources/porting_lib_base.mixins.json +++ b/modules/base/src/main/resources/porting_lib_base.mixins.json @@ -7,6 +7,7 @@ "compatibilityLevel": "JAVA_17", "mixins": [ "client.BoatRendererMixin", + "client.CreateWorldScreenMixin", "common.AbstractMinecartMixin", "common.AnvilMenuMixin", "common.BambooStalkBlockMixin", @@ -82,6 +83,7 @@ "common.SculkShriekerBlockMixin", "common.SeagrassBlockMixin", "common.ServerLevelMixin", + "common.ServerPacksSourceMixin", "common.ServerPlayerGameModeMixin", "common.ShapedRecipeMixin", "common.ShapelessRecipe$SerializerMixin",