From a7c317789010c382b5561670b7786d403b4191b9 Mon Sep 17 00:00:00 2001 From: KosmX Date: Sat, 15 Jul 2023 18:14:32 +0200 Subject: [PATCH 1/5] Add ClothConfig (autoconfig) and modmenu config screen --- build.gradle | 10 +++++++ gradle.properties | 4 +++ .../slotswap/config/ModMenuEntry.java | 12 +++++++++ .../slotswap/config/SwapConfig.java | 26 +++++++++++++++++++ src/main/resources/fabric.mod.json | 3 +++ 5 files changed, 55 insertions(+) create mode 100644 src/main/java/com/turtlearmymc/slotswap/config/ModMenuEntry.java create mode 100644 src/main/java/com/turtlearmymc/slotswap/config/SwapConfig.java diff --git a/build.gradle b/build.gradle index 8d0e21a..9eb173f 100644 --- a/build.gradle +++ b/build.gradle @@ -10,6 +10,8 @@ archivesBaseName = project.archives_base_name version = project.mod_version + "+mc" + project.minecraft_version repositories { + maven { url "https://maven.shedaniel.me/" } + maven { url "https://maven.terraformersmc.com/releases/" } } dependencies { @@ -18,6 +20,14 @@ dependencies { modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + + + modApi("me.shedaniel.cloth:cloth-config-fabric:${project.cloth_config}") { + exclude(group: "net.fabricmc.fabric-api") + } + + modApi "com.terraformersmc:modmenu:${project.modmenu}" + } processResources { diff --git a/gradle.properties b/gradle.properties index 330117c..8bf36e3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,3 +12,7 @@ loader_version = 0.14.21 # Dependencies fabric_version = 0.85.0+1.20.1 + +# These can be easily found here https://linkie.shedaniel.dev/dependencies +cloth_config = 11.1.106 +modmenu = 7.1.0 diff --git a/src/main/java/com/turtlearmymc/slotswap/config/ModMenuEntry.java b/src/main/java/com/turtlearmymc/slotswap/config/ModMenuEntry.java new file mode 100644 index 0000000..04b1b2b --- /dev/null +++ b/src/main/java/com/turtlearmymc/slotswap/config/ModMenuEntry.java @@ -0,0 +1,12 @@ +package com.turtlearmymc.slotswap.config; + +import com.terraformersmc.modmenu.api.ConfigScreenFactory; +import com.terraformersmc.modmenu.api.ModMenuApi; +import me.shedaniel.autoconfig.AutoConfig; + +public class ModMenuEntry implements ModMenuApi { + @Override + public ConfigScreenFactory getModConfigScreenFactory() { + return parent -> AutoConfig.getConfigScreen(SwapConfig.class, parent).get(); + } +} diff --git a/src/main/java/com/turtlearmymc/slotswap/config/SwapConfig.java b/src/main/java/com/turtlearmymc/slotswap/config/SwapConfig.java new file mode 100644 index 0000000..871c34a --- /dev/null +++ b/src/main/java/com/turtlearmymc/slotswap/config/SwapConfig.java @@ -0,0 +1,26 @@ +package com.turtlearmymc.slotswap.config; + +import me.shedaniel.autoconfig.ConfigData; +import me.shedaniel.autoconfig.annotation.Config; + +@Config(name = "slotswap") +public class SwapConfig implements ConfigData { + + public SwapMode swapMode = SwapMode.COMPATIBLE; + + public enum SwapMode { + /** + * Swap items using vanilla pick-item packet, likely safe to use everywhere but having issues + */ + COMPATIBLE, + + /** + * Use PlayerHandler swap packet, precisely swaps the items, may trigger anti-cheat + */ + SWAP, + /** + * Use same method as SWAP, but instead of swapping items, it cyclic-shift the column, it shouldn't shuffle items in inventory. + */ + SHIFT, + } +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index ab8858c..4c78087 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -20,6 +20,9 @@ "entrypoints": { "client": [ "com.turtlearmymc.slotswap.SwapManager" + ], + "modmenu": [ + "com.turtlearmymc.slotswap.config.ModMenuEntry" ] }, "mixins": [ From 417255187b25ff321f4309db8beae2f2540ea6fc Mon Sep 17 00:00:00 2001 From: KosmX Date: Sat, 15 Jul 2023 18:15:11 +0200 Subject: [PATCH 2/5] Implement swap modes --- .../turtlearmymc/slotswap/SwapManager.java | 58 ++++++++++++++++++- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/turtlearmymc/slotswap/SwapManager.java b/src/main/java/com/turtlearmymc/slotswap/SwapManager.java index 6740262..221c67e 100644 --- a/src/main/java/com/turtlearmymc/slotswap/SwapManager.java +++ b/src/main/java/com/turtlearmymc/slotswap/SwapManager.java @@ -1,11 +1,16 @@ package com.turtlearmymc.slotswap; +import com.turtlearmymc.slotswap.config.SwapConfig; +import me.shedaniel.autoconfig.AutoConfig; +import me.shedaniel.autoconfig.serializer.JanksonConfigSerializer; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.network.ClientPlayerInteractionManager; import net.minecraft.client.option.KeyBinding; import net.minecraft.client.util.InputUtil; import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.screen.slot.SlotActionType; import org.jetbrains.annotations.Nullable; import org.lwjgl.glfw.GLFW; @@ -16,6 +21,7 @@ public class SwapManager implements ClientModInitializer { public static final int ROW_COUNT = PlayerInventory.MAIN_SIZE / PlayerInventory.getHotbarSize(); private static int currentRow; private static boolean active; + public static SwapConfig CONFIG; private static @Nullable KeyBinding selectSlotKey = null; @@ -54,6 +60,10 @@ public static int getCurrentRow() { return active ? currentRow : 0; } + private static ClientPlayerInteractionManager getInteractionManager() { + return MinecraftClient.getInstance().interactionManager; + } + public static void scroll(PlayerInventory inv, int rowDelta) { tryStartSwap(); final int col = inv.selectedSlot; @@ -69,16 +79,60 @@ public static void scroll(PlayerInventory inv, int rowDelta) { } } + private static void swapSlots(PlayerInventory inv, int slotA, int slotB) { + + // clickSlot has a weird indexing: + // first slot arg is slot index, what is kinda random + // https://videa.hu/videok/film-animacio/laputa-az-egi-palota-124-perc-1986-KZZvhnBm2KnCxTNx?start=1920.560579 + + // second item is normal slot index + + final int slotAIndex = slotA < 9 ? slotA + PlayerInventory.MAIN_SIZE : slotA; + getInteractionManager().clickSlot(0, slotAIndex, slotB, SlotActionType.SWAP, MinecraftClient.getInstance().player); + } + + public static void tryDoSwap(PlayerInventory inv) { if (!active) return; active = false; if (currentRow == 0) return; // Hotbar selected - final int slot = rowColToSlot(currentRow, inv.selectedSlot); - MinecraftClient.getInstance().interactionManager.pickFromInventory(slot); + switch (CONFIG.swapMode) { + case COMPATIBLE -> { + final int slot = rowColToSlot(currentRow, inv.selectedSlot); + getInteractionManager().pickFromInventory(slot); + } + case SWAP -> { + final int slotA = rowColToSlot(currentRow, inv.selectedSlot); + final int slotB = rowColToSlot(0, inv.selectedSlot); + swapSlots(inv, slotA, slotB); + } + case SHIFT -> { + final int column = inv.selectedSlot; + final int distance = currentRow; + + for (int cycleStart = 0, nMoved = 0; nMoved != ROW_COUNT; cycleStart++) { + int i = cycleStart; + int displaced = i; + do { + i += distance; + if (i >= ROW_COUNT) + i -= ROW_COUNT; + swapSlots(inv, rowColToSlot(displaced, column), rowColToSlot(i, column)); + displaced = i; + nMoved++; + } while ((i + distance) % ROW_COUNT != cycleStart); + nMoved++; + } + } + } } @Override public void onInitializeClient() { + + AutoConfig.register(SwapConfig.class, JanksonConfigSerializer::new); + CONFIG = AutoConfig.getConfigHolder(SwapConfig.class).get(); + selectSlotKey = KeyBindingHelper.registerKeyBinding(new KeyBinding( "key.slotswap.swap", InputUtil.Type.KEYSYM, From a75e2076210b91699bbc0234d78277217a2b6ee8 Mon Sep 17 00:00:00 2001 From: KosmX Date: Sat, 15 Jul 2023 18:29:14 +0200 Subject: [PATCH 3/5] Add translations and description --- src/main/resources/assets/slotswap/lang/en_US.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/resources/assets/slotswap/lang/en_US.json b/src/main/resources/assets/slotswap/lang/en_US.json index 9a730ea..141229e 100644 --- a/src/main/resources/assets/slotswap/lang/en_US.json +++ b/src/main/resources/assets/slotswap/lang/en_US.json @@ -1,3 +1,5 @@ { - "key.slotswap.swap": "Slot swap" + "key.slotswap.swap": "Slot swap", + "text.autoconfig.slotswap.option.swapMode": "Swap mode", + "text.autoconfig.slotswap.option.swapMode.@Tooltip": "COMPATIBLE: Item swap with item pick packet, it may swap items randomly but is unlikely to trigger anti-cheat\nSWAP: Simply swap the item with the selected\nSHIFT: Shift the whole column up/down when swapping items" } \ No newline at end of file From c2198ad8a564d55a2173afdf59cd745eb9990ac3 Mon Sep 17 00:00:00 2001 From: KosmX Date: Sat, 15 Jul 2023 18:29:25 +0200 Subject: [PATCH 4/5] Make the config entry user-friendly --- src/main/java/com/turtlearmymc/slotswap/config/SwapConfig.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/turtlearmymc/slotswap/config/SwapConfig.java b/src/main/java/com/turtlearmymc/slotswap/config/SwapConfig.java index 871c34a..92c8830 100644 --- a/src/main/java/com/turtlearmymc/slotswap/config/SwapConfig.java +++ b/src/main/java/com/turtlearmymc/slotswap/config/SwapConfig.java @@ -2,10 +2,13 @@ import me.shedaniel.autoconfig.ConfigData; import me.shedaniel.autoconfig.annotation.Config; +import me.shedaniel.autoconfig.annotation.ConfigEntry; @Config(name = "slotswap") public class SwapConfig implements ConfigData { + @ConfigEntry.Gui.Tooltip + @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON) public SwapMode swapMode = SwapMode.COMPATIBLE; public enum SwapMode { From bd3b5fbcdcbce3f030bb06061a2d0c8119215c51 Mon Sep 17 00:00:00 2001 From: KosmX Date: Sat, 15 Jul 2023 20:04:59 +0200 Subject: [PATCH 5/5] oops --- .../resources/assets/slotswap/lang/{en_US.json => en_us.json} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/main/resources/assets/slotswap/lang/{en_US.json => en_us.json} (100%) diff --git a/src/main/resources/assets/slotswap/lang/en_US.json b/src/main/resources/assets/slotswap/lang/en_us.json similarity index 100% rename from src/main/resources/assets/slotswap/lang/en_US.json rename to src/main/resources/assets/slotswap/lang/en_us.json