diff --git a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java deleted file mode 100644 index bd4fa5d..0000000 --- a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/EditWorldScreenMixin.java +++ /dev/null @@ -1,90 +0,0 @@ -package ml.unbreakinggold.datapackinstaller.mixin; - -import com.google.common.collect.ImmutableList; -import com.mojang.datafixers.util.Pair; -import it.unimi.dsi.fastutil.booleans.BooleanConsumer; -import ml.unbreakinggold.datapackinstaller.client.DatapackInstallerClient; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.pack.PackScreen; -import net.minecraft.client.gui.screen.world.EditWorldScreen; -import net.minecraft.client.gui.screen.world.WorldCreator; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.DirectionalLayoutWidget; -import net.minecraft.client.world.GeneratorOptionsHolder; -import net.minecraft.resource.DataConfiguration; -import net.minecraft.resource.DataPackSettings; -import net.minecraft.resource.ResourcePackManager; -import net.minecraft.resource.VanillaDataPackProvider; -import net.minecraft.server.SaveLoading; -import net.minecraft.server.command.CommandManager; -import net.minecraft.text.Text; -import net.minecraft.world.level.LevelInfo; -import net.minecraft.world.level.LevelProperties; -import net.minecraft.world.level.storage.LevelStorage; -import net.minecraft.world.level.storage.LevelSummary; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.io.IOException; -import java.util.List; - -@Mixin(EditWorldScreen.class) -public class EditWorldScreenMixin extends Screen { - @Shadow @Final private DirectionalLayoutWidget layout; - @Shadow @Final private LevelStorage.Session storageSession; - @Unique private final Logger LOGGER = LogManager.getLogger(EditWorldScreenMixin.class); - @Unique private static final Text SELECT_DATAPACKS_TEXT = Text.translatable("dataPack.title"); - @Unique @Nullable private ResourcePackManager packManager; - @Unique @Nullable private DataConfiguration dataConfiguration; - @Unique @Nullable private LevelSummary levelSummary; - - protected EditWorldScreenMixin(Text title) { - super(title); - } - - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/widget/EmptyWidget;(II)V", ordinal = 1), method = "") - private void addButton(CallbackInfo info) { - this.layout.add(ButtonWidget.builder(SELECT_DATAPACKS_TEXT, (button) -> { - try { - this.levelSummary = this.storageSession.getLevelSummary(this.storageSession.readLevelProperties()); - } catch (IOException primaryException) { - LOGGER.warn("Failed to load world data from main level.dat. Attempting to load from fallback.", primaryException); - - try { - this.levelSummary = this.storageSession.getLevelSummary(this.storageSession.readOldLevelProperties()); - } catch (IOException fallbackException) { - LOGGER.error("Failed to load world data from fallback level.dat.", fallbackException); - return; - } - } - - this.dataConfiguration = this.levelSummary.getLevelInfo().getDataConfiguration(); - - if (this.packManager == null) { - this.packManager = VanillaDataPackProvider.createManager(DatapackInstallerClient.MAIN_PATH, client.getSymlinkFinder()); - this.packManager.scanPacks(); - } - - this.packManager.setEnabledProfiles(this.dataConfiguration.dataPacks().getEnabled()); - - this.client.setScreen(new PackScreen(this.packManager, (resourcePackManager) -> { - List enabledIds = ImmutableList.copyOf(resourcePackManager.getEnabledIds()); - List disabledIds = resourcePackManager.getIds().stream().filter((name) -> !enabledIds.contains(name)).collect(ImmutableList.toImmutableList()); - - this.dataConfiguration = new DataConfiguration(new DataPackSettings(enabledIds, disabledIds), this.dataConfiguration.enabledFeatures()); - }, DatapackInstallerClient.MAIN_PATH, Text.translatable("dataPack.title"))); - }).width(200).build()); - - // Reduce spacing so vanilla buttons remain on screen. - this.layout.spacing(1); - } -} diff --git a/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/GameMenuScreenMixin.java b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/GameMenuScreenMixin.java new file mode 100644 index 0000000..10ebcb5 --- /dev/null +++ b/src/main/java/ml/unbreakinggold/datapackinstaller/mixin/GameMenuScreenMixin.java @@ -0,0 +1,40 @@ +package ml.unbreakinggold.datapackinstaller.mixin; + +import ml.unbreakinggold.datapackinstaller.client.DatapackInstallerClient; +import net.minecraft.client.gui.screen.GameMenuScreen; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.pack.PackScreen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.gui.widget.GridWidget; +import net.minecraft.resource.ResourcePackManager; +import net.minecraft.text.Text; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import java.util.function.Supplier; + +@Mixin(GameMenuScreen.class) +public abstract class GameMenuScreenMixin extends Screen { + @Shadow private ButtonWidget createButton(Text text, Supplier screenSupplier) { return null; }; + @Unique private static final Text DATA_PACK_TEXT = Text.translatable("dataPack.title"); + + private GameMenuScreenMixin(Text title) { + super(title); + } + + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;isInSingleplayer()Z"), method = "initWidgets", locals = LocalCapture.CAPTURE_FAILHARD) + private void onInitWidgets(CallbackInfo ci, GridWidget gridWidget, GridWidget.Adder adder) { + if (!this.client.isIntegratedServerRunning() || this.client.getServer().isRemote()) return; + + adder.add(this.createButton(DATA_PACK_TEXT, () -> { + ResourcePackManager dataPackManager = this.client.getServer().getDataPackManager(); + + return new PackScreen(dataPackManager, (manager) -> {}, DatapackInstallerClient.MAIN_PATH, DATA_PACK_TEXT); + })); + } +} diff --git a/src/main/resources/DatapackInstaller.mixins.json b/src/main/resources/DatapackInstaller.mixins.json index 7e0849f..57636c4 100644 --- a/src/main/resources/DatapackInstaller.mixins.json +++ b/src/main/resources/DatapackInstaller.mixins.json @@ -7,7 +7,7 @@ ], "client": [ "CreateWorldScreenMixin", - "EditWorldScreenMixin" + "GameMenuScreenMixin" ], "injectors": { "defaultRequire": 1