From b252d8941838e15aacae232a3c759fce7c2b0587 Mon Sep 17 00:00:00 2001 From: BlazeMCworld Date: Thu, 27 Jun 2024 18:47:47 +0200 Subject: [PATCH 1/4] Add Recent Values Overlay --- .../dfonline/codeclient/config/Config.java | 12 ++ .../dfonline/codeclient/dev/RecentValues.java | 182 ++++++++++++++++++ .../mixin/entity/player/MPlayerInventory.java | 25 +++ src/main/resources/CodeClient.mixins.json | 1 + 4 files changed, 220 insertions(+) create mode 100644 src/main/java/dev/dfonline/codeclient/dev/RecentValues.java create mode 100644 src/main/java/dev/dfonline/codeclient/mixin/entity/player/MPlayerInventory.java diff --git a/src/main/java/dev/dfonline/codeclient/config/Config.java b/src/main/java/dev/dfonline/codeclient/config/Config.java index ebc77b6..ca1f32c 100644 --- a/src/main/java/dev/dfonline/codeclient/config/Config.java +++ b/src/main/java/dev/dfonline/codeclient/config/Config.java @@ -71,6 +71,7 @@ public class Config { public boolean ActionViewer = true; public boolean InvertActionViewerScroll = false; public ActionViewerAlignment ActionViewerLocation = ActionViewerAlignment.TOP; + public int RecentValues = 0; public Config() { } @@ -145,6 +146,7 @@ public void save() { object.addProperty("ActionViewer",ActionViewer); object.addProperty("InvertActionViewerScroll",InvertActionViewerScroll); object.addProperty("ActionViewerLocation",ActionViewerLocation.name()); + object.addProperty("RecentValues", RecentValues); FileManager.writeConfig(object.toString()); } catch (Exception e) { CodeClient.LOGGER.info("Couldn't save config: " + e); @@ -522,6 +524,16 @@ public YetAnotherConfigLib getLibConfig() { ) .controller(TickBoxControllerBuilder::create) .build()) + .option(Option.createBuilder(int.class) + .name(Text.literal("Recent Values")) + .description(OptionDescription.of(Text.literal("Amount of recently used values to remember."))) + .binding( + 0, + () -> RecentValues, + opt -> RecentValues = opt + ) + .controller(integerOption -> IntegerFieldControllerBuilder.create(integerOption).range(0, 100)) + .build()) .build()) // // diff --git a/src/main/java/dev/dfonline/codeclient/dev/RecentValues.java b/src/main/java/dev/dfonline/codeclient/dev/RecentValues.java new file mode 100644 index 0000000..b75820e --- /dev/null +++ b/src/main/java/dev/dfonline/codeclient/dev/RecentValues.java @@ -0,0 +1,182 @@ +package dev.dfonline.codeclient.dev; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import dev.dfonline.codeclient.CodeClient; +import dev.dfonline.codeclient.FileManager; +import dev.dfonline.codeclient.config.Config; +import dev.dfonline.codeclient.location.Dev; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; +import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; +import net.fabricmc.fabric.api.client.screen.v1.ScreenMouseEvents; +import net.minecraft.SharedConstants; +import net.minecraft.client.gui.screen.ingame.GenericContainerScreen; +import net.minecraft.client.sound.PositionedSoundInstance; +import net.minecraft.datafixer.DataFixTypes; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.StringNbtReader; +import net.minecraft.screen.slot.Slot; +import net.minecraft.screen.slot.SlotActionType; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvents; +import net.minecraft.util.math.random.Random; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +public class RecentValues { + + private static final Path file = FileManager.Path().resolve("recent_values.json"); + private static final List pinned = new ArrayList<>(); + private static final List recent = new ArrayList<>(); + private static ItemStack hoveredItem = null; + private static List hoveredOrigin = null; + + static { + try { + if (Files.exists(file)) { + JsonObject data = JsonParser.parseString(Files.readString(file)).getAsJsonObject(); + + int version = data.get("version").getAsInt(); + JsonArray pinnedJson = data.getAsJsonArray("pinned"); + JsonArray recentJson = data.getAsJsonArray("recent"); + + for (JsonElement item : pinnedJson) { + pinned.add(readItem(version, item)); + } + for (JsonElement item : recentJson) { + recent.add(readItem(version, item)); + } + } + + ClientLifecycleEvents.CLIENT_STOPPING.register(mc -> { + try { + if (!Files.exists(file.getParent())) Files.createDirectories(file.getParent()); + JsonObject data = new JsonObject(); + data.addProperty("version", SharedConstants.getGameVersion().getSaveVersion().getId()); + data.add("pinned", saveItems(pinned)); + data.add("recent", saveItems(recent)); + Files.writeString(file, data.toString()); + } catch (Exception err) { + CodeClient.LOGGER.error("Failed to save recent_values.json!"); + err.printStackTrace(); + } + }); + } catch (Exception err) { + CodeClient.LOGGER.error("Failed reading recent_values.json!"); + err.printStackTrace(); + } + + ScreenEvents.AFTER_INIT.register((client, screen, scaledWidth, scaledHeight) -> { + if (screen instanceof GenericContainerScreen container) { + if (!InsertOverlay.isCodeChest) return; + if (!(CodeClient.location instanceof Dev)) return; + + ScreenEvents.afterRender(screen).register((screen1, ctx, mouseX, mouseY, tickDelta) -> { + int y = (int) (scaledHeight * 0.25); + int xEnd = (int) (scaledWidth * 0.25); + + hoveredItem = null; + hoveredOrigin = null; + for (List group : List.of(pinned, recent)) { + int x = 10; + for (ItemStack item : group) { + ctx.drawItem(item, x, y); + ctx.drawItemInSlot(CodeClient.MC.textRenderer, item, x, y); + if (mouseX > x && mouseY > y && mouseX < x + 15 && mouseY < y + 15) { + ctx.drawItemTooltip(CodeClient.MC.textRenderer, item, mouseX, mouseY); + hoveredItem = item; + hoveredOrigin = group; + } + x += 15; + if (x > xEnd) { + x = 10; + y += 15; + } + } + if (x != 10) y += 15; + } + }); + + ScreenMouseEvents.afterMouseClick(screen).register((screen1, mouseX, mouseY, button) -> { + if (hoveredItem == null) return; + + if (button != 1) { + for (Slot slot : container.getScreenHandler().slots) { + if (slot.hasStack()) continue; + CodeClient.MC.getSoundManager().play(new PositionedSoundInstance( + SoundEvents.ENTITY_ITEM_PICKUP, + SoundCategory.PLAYERS, + 2, 0.8f, Random.create(), + CodeClient.MC.player.getBlockPos() + )); + + if (!CodeClient.MC.player.isCreative()) return; + ItemStack previous = CodeClient.MC.player.getInventory().getStack(0); + CodeClient.MC.interactionManager.clickCreativeStack(hoveredItem, 36); + CodeClient.MC.interactionManager.clickSlot( + container.getScreenHandler().syncId, + slot.id, 0, SlotActionType.SWAP, CodeClient.MC.player + ); + CodeClient.MC.interactionManager.clickCreativeStack(previous, 36); + return; + } + } else { + hoveredOrigin.remove(hoveredItem); + if (hoveredOrigin == pinned) { + CodeClient.MC.getSoundManager().play(new PositionedSoundInstance( + SoundEvents.ENTITY_ARROW_HIT, + SoundCategory.PLAYERS, + 2, 0.8f, Random.create(), + CodeClient.MC.player.getBlockPos() + )); + return; + } + CodeClient.MC.getSoundManager().play(new PositionedSoundInstance( + SoundEvents.ENTITY_SHULKER_BULLET_HIT, + SoundCategory.PLAYERS, + 2, 0.8f, Random.create(), + CodeClient.MC.player.getBlockPos() + )); + pinned.add(hoveredItem); + } + }); + } + }); + } + + private static JsonArray saveItems(List list) { + JsonArray out = new JsonArray(); + + for (ItemStack item : list) { + out.add(item.writeNbt(new NbtCompound()).asString()); + } + + return out; + } + + private static ItemStack readItem(int version, JsonElement item) throws Exception { + return ItemStack.fromNbt(DataFixTypes.HOTBAR.update(CodeClient.MC.getDataFixer(), StringNbtReader.parse(item.getAsString()), version)); + } + + public static void remember(ItemStack item) { + if (item.getNbt() == null || item.getNbt().get("PublicBukkitValues") == null || item.getSubNbt("PublicBukkitValues").get("hypercube:varitem") == null) return; + for (ItemStack it : pinned) { + if (item.getItem() == it.getItem() && item.getNbt().equals(it.getNbt())) return; + } + + ItemStack lambdaItem = item; + recent.removeIf(it -> lambdaItem.getItem() == it.getItem() && lambdaItem.getNbt().equals(it.getNbt())); + item = item.copyWithCount(1); + recent.add(0, item); + + while (recent.size() > Config.getConfig().RecentValues) { + recent.remove(recent.size() - 1); + } + } +} diff --git a/src/main/java/dev/dfonline/codeclient/mixin/entity/player/MPlayerInventory.java b/src/main/java/dev/dfonline/codeclient/mixin/entity/player/MPlayerInventory.java new file mode 100644 index 0000000..4f74d08 --- /dev/null +++ b/src/main/java/dev/dfonline/codeclient/mixin/entity/player/MPlayerInventory.java @@ -0,0 +1,25 @@ +package dev.dfonline.codeclient.mixin.entity.player; + +import dev.dfonline.codeclient.CodeClient; +import dev.dfonline.codeclient.dev.RecentValues; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.item.ItemStack; +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; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(PlayerInventory.class) +public class MPlayerInventory { + + @Shadow @Final public PlayerEntity player; + + @Inject(method = "setStack", at = @At("HEAD")) + public void onSetStack(int slot, ItemStack item, CallbackInfo ci) { + if (player == CodeClient.MC.player) RecentValues.remember(item); + } + +} diff --git a/src/main/resources/CodeClient.mixins.json b/src/main/resources/CodeClient.mixins.json index 0b7389e..9949148 100644 --- a/src/main/resources/CodeClient.mixins.json +++ b/src/main/resources/CodeClient.mixins.json @@ -13,6 +13,7 @@ "entity.player.MAbstractClientPlayerEntity", "entity.player.MClientPlayerEntity", "entity.player.MClientPlayerInteractionManager", + "entity.player.MPlayerInventory", "entity.player.MPlayerEntity", "network.MClientCommonPlayNetworkHandler", "network.MClientConnection", From 3b19336ec70e5e7da1ae4cf6eb5f0f2bdad52b44 Mon Sep 17 00:00:00 2001 From: GeorgeRNG <81434111+GeorgeRNG@users.noreply.github.com> Date: Thu, 27 Jun 2024 18:43:27 +0100 Subject: [PATCH 2/4] make a text to (& code) string function --- .../java/dev/dfonline/codeclient/Utility.java | 23 +++++++++++++++++++ .../codeclient/action/impl/GetActionDump.java | 20 ++-------------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/main/java/dev/dfonline/codeclient/Utility.java b/src/main/java/dev/dfonline/codeclient/Utility.java index aacb894..b409649 100644 --- a/src/main/java/dev/dfonline/codeclient/Utility.java +++ b/src/main/java/dev/dfonline/codeclient/Utility.java @@ -3,6 +3,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import dev.dfonline.codeclient.action.impl.GetActionDump; import dev.dfonline.codeclient.action.impl.PlaceTemplates; import dev.dfonline.codeclient.hypercube.template.Template; import dev.dfonline.codeclient.hypercube.template.TemplateBlock; @@ -353,4 +354,26 @@ public static HashMap getBlockTagLines(ItemStack item) { return options; } + + public static void textToString(Text content, StringBuilder build, GetActionDump.ColorMode colorMode) { + TextColor lastColor = null; + for (Text text : content.getSiblings()) { + TextColor color = text.getStyle().getColor(); + if (color != null && (lastColor != color) && (colorMode != GetActionDump.ColorMode.NONE)) { + lastColor = color; + if (color.getName().contains("#")) { + build.append(String.join(colorMode.text, color.getName().split("")).replace("#", colorMode.text + "x").toLowerCase()); + } else { + build.append(Formatting.valueOf(String.valueOf(color).toUpperCase()).toString().replace("§", colorMode.text)); + } + } + build.append(text.getString()); + } + } + + public static String textToString(Text content) { + var builder = new StringBuilder(); + textToString(content, builder, GetActionDump.ColorMode.SECTION); + return builder.toString(); + } } \ No newline at end of file diff --git a/src/main/java/dev/dfonline/codeclient/action/impl/GetActionDump.java b/src/main/java/dev/dfonline/codeclient/action/impl/GetActionDump.java index 96be42d..6c7f664 100644 --- a/src/main/java/dev/dfonline/codeclient/action/impl/GetActionDump.java +++ b/src/main/java/dev/dfonline/codeclient/action/impl/GetActionDump.java @@ -1,14 +1,10 @@ package dev.dfonline.codeclient.action.impl; -import dev.dfonline.codeclient.Callback; -import dev.dfonline.codeclient.CodeClient; -import dev.dfonline.codeclient.FileManager; -import dev.dfonline.codeclient.OverlayManager; +import dev.dfonline.codeclient.*; import dev.dfonline.codeclient.action.Action; import net.minecraft.network.packet.Packet; import net.minecraft.network.packet.s2c.play.GameMessageS2CPacket; import net.minecraft.text.Text; -import net.minecraft.text.TextColor; import net.minecraft.util.Formatting; import java.io.IOException; @@ -49,19 +45,7 @@ public boolean onReceivePacket(Packet packet) { return true; } - TextColor lastColor = null; - for (Text text : message.content().getSiblings()) { - TextColor color = text.getStyle().getColor(); - if (color != null && (lastColor != color) && (colorMode != ColorMode.NONE)) { - lastColor = color; - if (color.getName().contains("#")) { - capturedData.append(String.join(colorMode.text, color.getName().split("")).replace("#", colorMode.text + "x").toLowerCase()); - } else { - capturedData.append(Formatting.valueOf(String.valueOf(color).toUpperCase()).toString().replace("§", colorMode.text)); - } - } - capturedData.append(text.getString()); - } + Utility.textToString(message.content(), capturedData, colorMode); String content = message.content().getString(); capturedData.append("\n"); lines += 1; From 39476cc0c9d1d4340cbbe87851f93c093e74fa9e Mon Sep 17 00:00:00 2001 From: GeorgeRNG <81434111+GeorgeRNG@users.noreply.github.com> Date: Thu, 27 Jun 2024 19:36:37 +0100 Subject: [PATCH 3/4] make recent values more codeclient-y --- .../dfonline/codeclient/dev/RecentValues.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/main/java/dev/dfonline/codeclient/dev/RecentValues.java b/src/main/java/dev/dfonline/codeclient/dev/RecentValues.java index b75820e..9a3558a 100644 --- a/src/main/java/dev/dfonline/codeclient/dev/RecentValues.java +++ b/src/main/java/dev/dfonline/codeclient/dev/RecentValues.java @@ -22,6 +22,7 @@ import net.minecraft.screen.slot.SlotActionType; import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundEvents; +import net.minecraft.util.Identifier; import net.minecraft.util.math.random.Random; import java.nio.file.Files; @@ -78,9 +79,16 @@ public class RecentValues { if (!(CodeClient.location instanceof Dev)) return; ScreenEvents.afterRender(screen).register((screen1, ctx, mouseX, mouseY, tickDelta) -> { + if(recent.isEmpty() && pinned.isEmpty()) return; + int y = (int) (scaledHeight * 0.25); int xEnd = (int) (scaledWidth * 0.25); + ctx.drawGuiTexture(new Identifier("recipe_book/overlay_recipe"), 5, y - 5, + Math.min(Math.max(pinned.size(), recent.size()),16) * 15 + 10, + (((int) Math.ceil((double) pinned.size() / 16)) + ((int) Math.ceil((double) recent.size() / 16))) * 16 + 10 + ); + hoveredItem = null; hoveredOrigin = null; for (List group : List.of(pinned, recent)) { @@ -112,7 +120,7 @@ public class RecentValues { CodeClient.MC.getSoundManager().play(new PositionedSoundInstance( SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.PLAYERS, - 2, 0.8f, Random.create(), + 2, 1f, Random.create(), CodeClient.MC.player.getBlockPos() )); @@ -130,17 +138,17 @@ public class RecentValues { hoveredOrigin.remove(hoveredItem); if (hoveredOrigin == pinned) { CodeClient.MC.getSoundManager().play(new PositionedSoundInstance( - SoundEvents.ENTITY_ARROW_HIT, + SoundEvents.UI_BUTTON_CLICK.value(), SoundCategory.PLAYERS, - 2, 0.8f, Random.create(), + 2, 0.5f, Random.create(), CodeClient.MC.player.getBlockPos() )); return; } CodeClient.MC.getSoundManager().play(new PositionedSoundInstance( - SoundEvents.ENTITY_SHULKER_BULLET_HIT, + SoundEvents.UI_BUTTON_CLICK.value(), SoundCategory.PLAYERS, - 2, 0.8f, Random.create(), + 2, 0.6f, Random.create(), CodeClient.MC.player.getBlockPos() )); pinned.add(hoveredItem); From f6f395c89f91f7bc2f6b6cc5e88c2453d87d3990 Mon Sep 17 00:00:00 2001 From: GeorgeRNG <81434111+GeorgeRNG@users.noreply.github.com> Date: Thu, 27 Jun 2024 19:37:39 +0100 Subject: [PATCH 4/4] add contributor, increase version --- gradle.properties | 2 +- src/main/resources/fabric.mod.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index fa25158..2d1a769 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ yarn_mappings=1.20.4+build.3 loader_version=0.15.3 # Mod Properties -mod_version=1.7.0 +mod_version=1.7.1 maven_group=dev.dfonline archives_base_name=CodeClient diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 68cdac1..ca2c06e 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -15,7 +15,8 @@ }, "contributors": [ "RedVortex", - "msvae" + "msvae", + "BlazeMCworld" ], "license": "MIT", "icon": "assets/codeclient/icon.png",