aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--README.md1
-rw-r--r--src/main/java/eu/olli/cowlection/listener/PlayerListener.java43
-rw-r--r--src/main/java/eu/olli/cowlection/util/GsonUtils.java54
4 files changed, 96 insertions, 3 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 99ac77c..23a9ce4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [1.8.9-0.8.0] - unreleased
### Added
+- Copy inventories to clipboard as JSON with <kbd>CTRL</kbd> + <kbd>C</kbd>
- Dungeon update (part 1)
- Added Dungeon item stats tooltip cleaner
- goal: normalize stats to make comparing dungeon items much easier
diff --git a/README.md b/README.md
index e80c426..6efe063 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,7 @@ It is a collection of different features mainly focused on Hypixel SkyBlock. ðŸ
| Stalk a player (check online status, current game, ...) | `/moo stalk` |
| Toggle join/leave notifications for friends, guild members or best friends separately | `/moo toggle` |
| Copy chat component | <kbd>ALT</kbd> + <kbd>right click</kbd><br>Hold <kbd>shift</kbd> to copy full component |
+| Copy inventories to clipboard as JSON | <kbd>CTRL</kbd> + <kbd>C</kbd> |
| Tab-completable usernames for several commands (e.g. `/party`, `/invite`, ...) | `/moo config` &rarr; `Commands with Tab-completable usernames` for full list of commands |
| Auto-replace `/r` with `/w <latest username>` | `/r ` |
| Change guiScale to any value | `/moo guiscale [newValue]` |
diff --git a/src/main/java/eu/olli/cowlection/listener/PlayerListener.java b/src/main/java/eu/olli/cowlection/listener/PlayerListener.java
index af946d4..3f5ee33 100644
--- a/src/main/java/eu/olli/cowlection/listener/PlayerListener.java
+++ b/src/main/java/eu/olli/cowlection/listener/PlayerListener.java
@@ -2,15 +2,23 @@ package eu.olli.cowlection.listener;
import eu.olli.cowlection.Cowlection;
import eu.olli.cowlection.config.MooConfig;
+import eu.olli.cowlection.util.GsonUtils;
import eu.olli.cowlection.util.TickDelay;
import eu.olli.cowlection.util.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.GuiScreen;
+import net.minecraft.client.gui.inventory.GuiChest;
+import net.minecraft.client.gui.inventory.GuiInventory;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.inventory.ContainerChest;
+import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.EnumChatFormatting;
+import net.minecraftforge.client.event.GuiScreenEvent;
import net.minecraftforge.event.entity.player.ItemTooltipEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.network.FMLNetworkEvent;
@@ -135,6 +143,41 @@ public class PlayerListener {
}
@SubscribeEvent
+ public void onKeyboardInput(GuiScreenEvent.KeyboardInputEvent.Pre e) {
+ if (Keyboard.getEventKeyState() && Keyboard.getEventKey() == Keyboard.KEY_C && GuiScreen.isCtrlKeyDown()) {
+ // ctrl + C
+ IInventory inventory;
+ String inventoryName;
+ if (e.gui instanceof GuiChest) {
+ // some kind of chest
+ ContainerChest chestContainer = (ContainerChest) ((GuiChest) e.gui).inventorySlots;
+ inventory = chestContainer.getLowerChestInventory();
+ inventoryName = (inventory.hasCustomName() ? EnumChatFormatting.getTextWithoutFormattingCodes(inventory.getDisplayName().getUnformattedTextForChat()) : inventory.getName());
+ } else if (e.gui instanceof GuiInventory) {
+ // player inventory
+ inventory = Minecraft.getMinecraft().thePlayer.inventory;
+ inventoryName = "Player inventory";
+ } else {
+ // another gui, abort!
+ return;
+ }
+ NBTTagList items = new NBTTagList();
+ for (int slot = 0; slot < inventory.getSizeInventory(); slot++) {
+ ItemStack item = inventory.getStackInSlot(slot);
+ if (item != null) {
+ // slot + item
+ NBTTagCompound tag = new NBTTagCompound();
+ tag.setByte("Slot", (byte) slot);
+ item.writeToNBT(tag);
+ items.appendTag(tag);
+ }
+ }
+ GuiScreen.setClipboardString(GsonUtils.toJson(items));
+ main.getChatHelper().sendMessage(EnumChatFormatting.GREEN, "Copied " + items.tagCount() + " items from '" + inventoryName + "' to clipboard!");
+ }
+ }
+
+ @SubscribeEvent
public void onServerJoin(FMLNetworkEvent.ClientConnectedToServerEvent e) {
main.getVersionChecker().runUpdateCheck(false);
new TickDelay(() -> main.getChatHelper().sendOfflineMessages(), 6 * 20);
diff --git a/src/main/java/eu/olli/cowlection/util/GsonUtils.java b/src/main/java/eu/olli/cowlection/util/GsonUtils.java
index ece3faf..e0f1a64 100644
--- a/src/main/java/eu/olli/cowlection/util/GsonUtils.java
+++ b/src/main/java/eu/olli/cowlection/util/GsonUtils.java
@@ -1,8 +1,12 @@
package eu.olli.cowlection.util;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
+import com.google.gson.*;
import com.mojang.util.UUIDTypeAdapter;
+import net.minecraft.nbt.NBTBase;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraft.nbt.NBTTagString;
+import net.minecraftforge.common.util.Constants;
import java.io.Reader;
import java.lang.reflect.Type;
@@ -10,6 +14,7 @@ import java.util.UUID;
public final class GsonUtils {
private static final Gson gson = new GsonBuilder().registerTypeAdapter(UUID.class, new UUIDTypeAdapter()).create();
+ private static final Gson gsonPrettyPrinter = new GsonBuilder().registerTypeAdapter(UUID.class, new UUIDTypeAdapter()).setPrettyPrinting().create();
private GsonUtils() {
}
@@ -23,6 +28,49 @@ public final class GsonUtils {
}
public static String toJson(Object object) {
- return gson.toJson(object);
+ if (object instanceof NBTBase) {
+ return gsonPrettyPrinter.toJson(nbtToJson((NBTBase) object));
+ } else {
+ return gson.toJson(object);
+ }
+ }
+
+ private static JsonElement nbtToJson(NBTBase nbtElement) {
+ if (nbtElement instanceof NBTBase.NBTPrimitive) {
+ NBTBase.NBTPrimitive nbtNumber = (NBTBase.NBTPrimitive) nbtElement;
+ switch (nbtNumber.getId()) {
+ case Constants.NBT.TAG_BYTE:
+ return new JsonPrimitive(nbtNumber.getByte());
+ case Constants.NBT.TAG_SHORT:
+ return new JsonPrimitive(nbtNumber.getShort());
+ case Constants.NBT.TAG_INT:
+ return new JsonPrimitive(nbtNumber.getInt());
+ case Constants.NBT.TAG_LONG:
+ return new JsonPrimitive(nbtNumber.getLong());
+ case Constants.NBT.TAG_FLOAT:
+ return new JsonPrimitive(nbtNumber.getFloat());
+ case Constants.NBT.TAG_DOUBLE:
+ return new JsonPrimitive(nbtNumber.getDouble());
+ default:
+ return new JsonObject();
+ }
+ } else if (nbtElement instanceof NBTTagString) {
+ return new JsonPrimitive(((NBTTagString) nbtElement).getString());
+ } else if (nbtElement instanceof NBTTagList) {
+ NBTTagList nbtList = (NBTTagList) nbtElement;
+ JsonArray jsonArray = new JsonArray();
+ for (int tagId = 0; tagId < nbtList.tagCount(); tagId++) {
+ jsonArray.add(nbtToJson(nbtList.get(tagId)));
+ }
+ return jsonArray;
+ } else if (nbtElement instanceof NBTTagCompound) {
+ NBTTagCompound nbtCompound = (NBTTagCompound) nbtElement;
+ JsonObject jsonObject = new JsonObject();
+ for (String nbtEntry : nbtCompound.getKeySet()) {
+ jsonObject.add(nbtEntry, nbtToJson(nbtCompound.getTag(nbtEntry)));
+ }
+ return jsonObject;
+ }
+ return new JsonObject();
}
}