diff --git a/changelog.md b/changelog.md index e69de29..529b983 100644 --- a/changelog.md +++ b/changelog.md @@ -0,0 +1 @@ +Fix a bug breaking creative search when operator tab was enabled \ No newline at end of file diff --git a/common/src/main/java/dev/terminalmc/clientsort/ClientSort.java b/common/src/main/java/dev/terminalmc/clientsort/ClientSort.java index a112dda..3658d48 100644 --- a/common/src/main/java/dev/terminalmc/clientsort/ClientSort.java +++ b/common/src/main/java/dev/terminalmc/clientsort/ClientSort.java @@ -25,6 +25,8 @@ public class ClientSort { translationKey("key", "sort"), InputConstants.Type.MOUSE, InputConstants.MOUSE_BUTTON_MIDDLE, translationKey("key_group")); + public static boolean searchOrderUpdated = false; + public static int lastUpdatedSlot = -1; public static int cooldown = 0; diff --git a/common/src/main/java/dev/terminalmc/clientsort/mixin/MixinClientPacketListener.java b/common/src/main/java/dev/terminalmc/clientsort/mixin/MixinClientPacketListener.java index f6cd046..505a880 100644 --- a/common/src/main/java/dev/terminalmc/clientsort/mixin/MixinClientPacketListener.java +++ b/common/src/main/java/dev/terminalmc/clientsort/mixin/MixinClientPacketListener.java @@ -26,6 +26,7 @@ import net.minecraft.client.multiplayer.CommonListenerCookie; import net.minecraft.network.Connection; import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket; +import net.minecraft.network.protocol.game.ClientboundLoginPacket; import net.minecraft.network.protocol.game.ClientboundSetCarriedItemPacket; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -38,13 +39,18 @@ protected MixinClientPacketListener(Minecraft client, Connection connection, Com super(client, connection, connectionState); } + @Inject(method = "handleLogin", at = @At("HEAD")) + private void onLogin(ClientboundLoginPacket packet, CallbackInfo ci) { + ClientSort.searchOrderUpdated = false; + } + @Inject(method = "handleSetCarriedItem", at = @At("HEAD")) - public void onHeldItemChangeBegin(ClientboundSetCarriedItemPacket packet, CallbackInfo callbackInfo) { + public void onHeldItemChangeBegin(ClientboundSetCarriedItemPacket packet, CallbackInfo ci) { InteractionManager.triggerSend(InteractionManager.TriggerType.HELD_ITEM_CHANGE); } @Inject(method = "handleContainerSetSlot", at = @At("RETURN")) - public void onGuiSlotUpdateBegin(ClientboundContainerSetSlotPacket packet, CallbackInfo callbackInfo) { + public void onGuiSlotUpdateBegin(ClientboundContainerSetSlotPacket packet, CallbackInfo ci) { ClientSort.lastUpdatedSlot = packet.getSlot(); InteractionManager.triggerSend(InteractionManager.TriggerType.CONTAINER_SLOT_UPDATE); } diff --git a/common/src/main/java/dev/terminalmc/clientsort/mixin/MixinLocalPlayer.java b/common/src/main/java/dev/terminalmc/clientsort/mixin/MixinLocalPlayer.java index 076e1b0..533b3f7 100644 --- a/common/src/main/java/dev/terminalmc/clientsort/mixin/MixinLocalPlayer.java +++ b/common/src/main/java/dev/terminalmc/clientsort/mixin/MixinLocalPlayer.java @@ -20,6 +20,7 @@ import com.mojang.authlib.GameProfile; import dev.terminalmc.clientsort.network.InteractionManager; +import dev.terminalmc.clientsort.util.CreativeSearchOrder; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.player.AbstractClientPlayer; import net.minecraft.client.player.LocalPlayer; @@ -28,6 +29,8 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import static dev.terminalmc.clientsort.ClientSort.searchOrderUpdated; + @Mixin(LocalPlayer.class) public abstract class MixinLocalPlayer extends AbstractClientPlayer { public MixinLocalPlayer(ClientLevel world, GameProfile profile) { @@ -38,4 +41,12 @@ public MixinLocalPlayer(ClientLevel world, GameProfile profile) { public void onContainerClosed(CallbackInfo callbackInfo) { InteractionManager.clear(); } + + @Inject(method = "setPermissionLevel", at = @At("RETURN")) + public void onSetPermissionLevel(int level, CallbackInfo ci) { + if (!searchOrderUpdated) { + CreativeSearchOrder.refreshItemSearchPositionLookup(); + searchOrderUpdated = true; + } + } } diff --git a/common/src/main/java/dev/terminalmc/clientsort/screen/ClothConfigScreenProvider.java b/common/src/main/java/dev/terminalmc/clientsort/screen/ClothConfigScreenProvider.java index 9baa226..6981b8d 100644 --- a/common/src/main/java/dev/terminalmc/clientsort/screen/ClothConfigScreenProvider.java +++ b/common/src/main/java/dev/terminalmc/clientsort/screen/ClothConfigScreenProvider.java @@ -7,6 +7,7 @@ import dev.terminalmc.clientsort.config.Config; import dev.terminalmc.clientsort.inventory.sort.SortMode; +import dev.terminalmc.clientsort.util.CreativeSearchOrder; import me.shedaniel.clothconfig2.api.ConfigBuilder; import me.shedaniel.clothconfig2.api.ConfigCategory; import me.shedaniel.clothconfig2.api.ConfigEntryBuilder; @@ -106,7 +107,10 @@ else if (val > 100) return Optional.of( sort.addEntry(eb.startBooleanToggle(localized("option", "optimized_creative_sorting"), options.optimizedCreativeSorting) .setDefaultValue(Config.Options.defaultOptimizedCreativeSorting) - .setSaveConsumer(val -> options.optimizedCreativeSorting = val) + .setSaveConsumer(val -> { + options.optimizedCreativeSorting = val; + CreativeSearchOrder.refreshItemSearchPositionLookup(); + }) .build()); return builder.build(); diff --git a/common/src/main/java/dev/terminalmc/clientsort/util/CreativeSearchOrder.java b/common/src/main/java/dev/terminalmc/clientsort/util/CreativeSearchOrder.java index 129d354..4b49eda 100644 --- a/common/src/main/java/dev/terminalmc/clientsort/util/CreativeSearchOrder.java +++ b/common/src/main/java/dev/terminalmc/clientsort/util/CreativeSearchOrder.java @@ -22,19 +22,18 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import net.minecraft.client.Minecraft; +import net.minecraft.client.player.LocalPlayer; import net.minecraft.world.flag.FeatureFlagSet; import net.minecraft.world.item.CreativeModeTabs; import net.minecraft.world.item.ItemStack; import java.util.ArrayList; import java.util.Collection; -import java.util.Objects; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class CreativeSearchOrder { - private static FeatureFlagSet lastFeatureSet = null; private static final Object2IntMap stackToSearchPositionLookup = new Object2IntOpenHashMap<>(); static { stackToSearchPositionLookup.defaultReturnValue(Integer.MAX_VALUE); @@ -53,40 +52,42 @@ public static int getStackSearchPosition(ItemStack stack) { return pos; } - // Called on config change and when the feature set changes (on world join) + // Called when the feature set changes (on world join) public static void refreshItemSearchPositionLookup() { if (Config.get().options.optimizedCreativeSorting) { - Minecraft client = Minecraft.getInstance(); - if (client.level == null) { + Minecraft mc = Minecraft.getInstance(); + if (mc.level == null || mc.player == null) { return; } - FeatureFlagSet enabledFeatures = client.level.enabledFeatures(); + FeatureFlagSet enabledFeatures = mc.level.enabledFeatures(); - if (stackToSearchPositionLookup.isEmpty() || !Objects.equals(enabledFeatures, lastFeatureSet)) { - CreativeModeTabs.tryRebuildTabContents(enabledFeatures, true, client.level.registryAccess()); - Collection displayStacks = new ArrayList<>(CreativeModeTabs.searchTab().getDisplayItems()); - new Thread(() -> { - Lock lock = stackToSearchPositionLookupLock.writeLock(); - lock.lock(); - stackToSearchPositionLookup.clear(); - if (displayStacks.isEmpty()) { - lock.unlock(); - return; - } + LocalPlayer player = mc.player; + boolean op = mc.options.operatorItemsTab().get() && player.canUseGameMasterBlocks(); - int i = 0; - for (ItemStack stack : displayStacks) { - StackMatcher plainMatcher = StackMatcher.ignoreNbt(stack); - if (!stack.hasFoil() || !stackToSearchPositionLookup.containsKey(plainMatcher)) { - stackToSearchPositionLookup.put(plainMatcher, i); - i++; - } - stackToSearchPositionLookup.put(StackMatcher.of(stack), i); - i++; - } - lock.unlock(); - }, "Mouse Wheelie: creative search stack position lookup builder").start(); - } + CreativeModeTabs.tryRebuildTabContents(enabledFeatures, !op, mc.level.registryAccess()); + + Collection displayStacks = new ArrayList<>(CreativeModeTabs.searchTab().getDisplayItems()); + new Thread(() -> { + Lock lock = stackToSearchPositionLookupLock.writeLock(); + lock.lock(); + stackToSearchPositionLookup.clear(); + if (displayStacks.isEmpty()) { + lock.unlock(); + return; + } + + int i = 0; + for (ItemStack stack : displayStacks) { + StackMatcher plainMatcher = StackMatcher.ignoreNbt(stack); + if (!stack.hasFoil() || !stackToSearchPositionLookup.containsKey(plainMatcher)) { + stackToSearchPositionLookup.put(plainMatcher, i); + i++; + } + stackToSearchPositionLookup.put(StackMatcher.of(stack), i); + i++; + } + lock.unlock(); + }, "Mouse Wheelie: creative search stack position lookup builder").start(); } else { Lock lock = stackToSearchPositionLookupLock.writeLock(); diff --git a/common/src/main/resources/clientsort.mixins.json b/common/src/main/resources/clientsort.mixins.json index f37b38b..08fa2d2 100644 --- a/common/src/main/resources/clientsort.mixins.json +++ b/common/src/main/resources/clientsort.mixins.json @@ -1,22 +1,22 @@ { - "required": true, - "minVersion": "0.8", - "package": "dev.terminalmc.clientsort.mixin", - "refmap": "${mod_id}.refmap.json", - "compatibilityLevel": "JAVA_${java_version}", - "mixins": [ + "required" : true, + "minVersion" : "0.8", + "package" : "dev.terminalmc.clientsort.mixin", + "refmap" : "${mod_id}.refmap.json", + "compatibilityLevel" : "JAVA_${java_version}", + "mixins" : [ "MixinSlot" ], - "client": [ + "client" : [ "KeyMappingAccessor", "MixinAbstractContainerScreen", "MixinClientPacketListener", "MixinCreativeSlot", "MixinLocalPlayer" ], - "server": [ + "server" : [ ], - "injectors": { - "defaultRequire": 1 + "injectors" : { + "defaultRequire" : 1 } } diff --git a/fabric/src/main/java/dev/terminalmc/clientsort/ClientSortFabric.java b/fabric/src/main/java/dev/terminalmc/clientsort/ClientSortFabric.java index 96ca4f5..7bd715d 100644 --- a/fabric/src/main/java/dev/terminalmc/clientsort/ClientSortFabric.java +++ b/fabric/src/main/java/dev/terminalmc/clientsort/ClientSortFabric.java @@ -5,11 +5,9 @@ package dev.terminalmc.clientsort; -import dev.terminalmc.clientsort.util.CreativeSearchOrder; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; -import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; public class ClientSortFabric implements ClientModInitializer { @Override @@ -20,10 +18,6 @@ public void onInitializeClient() { // Tick events ClientTickEvents.END_CLIENT_TICK.register(ClientSort::onEndTick); - // Game join events - ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> - CreativeSearchOrder.refreshItemSearchPositionLookup()); - // Main initialization ClientSort.init(); } diff --git a/gradle.properties b/gradle.properties index d542026..a9bd74a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ # Neo/Forge version ranges: https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html # Project -mod_version=0.2.0 +mod_version=0.3.0 mod_group=dev.terminalmc mod_id=clientsort mod_name=ClientSort diff --git a/neoforge/src/main/java/dev/terminalmc/clientsort/ClientSortNeoForge.java b/neoforge/src/main/java/dev/terminalmc/clientsort/ClientSortNeoForge.java index bbb13ea..d8075af 100644 --- a/neoforge/src/main/java/dev/terminalmc/clientsort/ClientSortNeoForge.java +++ b/neoforge/src/main/java/dev/terminalmc/clientsort/ClientSortNeoForge.java @@ -6,14 +6,12 @@ package dev.terminalmc.clientsort; import dev.terminalmc.clientsort.screen.ConfigScreenProvider; -import dev.terminalmc.clientsort.util.CreativeSearchOrder; import net.minecraft.client.Minecraft; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.ModLoadingContext; import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.Mod; -import net.neoforged.neoforge.client.event.ClientPlayerNetworkEvent; import net.neoforged.neoforge.client.event.ClientTickEvent; import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent; import net.neoforged.neoforge.client.gui.IConfigScreenFactory; @@ -38,12 +36,6 @@ static void registerKeyMappingsEvent(RegisterKeyMappingsEvent event) { @EventBusSubscriber(modid = ClientSort.MOD_ID, value = Dist.CLIENT) static class ClientEventHandler { - // Game join events - @SubscribeEvent - public static void loginEvent(ClientPlayerNetworkEvent.LoggingIn event) { - CreativeSearchOrder.refreshItemSearchPositionLookup(); - } - // Tick events @SubscribeEvent public static void clientTickEvent(ClientTickEvent.Post event) {