diff --git a/NOTICE.md b/NOTICE.md new file mode 100644 index 0000000..4fd9e53 --- /dev/null +++ b/NOTICE.md @@ -0,0 +1,28 @@ +# 项目名称:command-gui-buttons-revive +# 原始项目:[command-gui-buttons](https://github.com/joseph-garcia/command-gui-buttons) +# 许可证:GNU General Public License v3.0 (GPL-3.0) + +## 版权声明 +- 原始项目版权归 joseph-garcia 所有 (© [原项目版权年份,但是原项目的许可证也不告诉我这些信息,啥都是空的,作者都是我填的]) +- 本衍生作品的修改部分版权归 BRanulf 所有 (© 2025) + +## 修改声明 +此项目是基于 command-gui-buttons 的二次修改版本。 + +## 许可继承 +- 本项目**整体**遵循 [GNU GPL v3 许可证](LICENSE) +- 您有权利根据 GPL v3 条款: + ✓ 免费使用、修改本代码 + ✓ 重新分发源代码或编译版本 +- **义务**:若您分发修改后的版本,必须: + ✓ 公开修改后的完整源代码 + ✓ 保留此声明文件及原始许可文件 + ✓ 明确标注您的修改内容 + +## 免责声明 +本软件按“原样”提供,作者不承担任何明示或暗示的担保责任。 +使用本软件产生的风险由用户自行承担。 + +> 原始项目仓库:https://github.com/joseph-garcia/command-gui-buttons + +> 本项目仓库:[您的项目URL] diff --git a/build.gradle b/build.gradle index e4d505e..8a46c84 100644 --- a/build.gradle +++ b/build.gradle @@ -1,10 +1,10 @@ plugins { - id 'fabric-loom' version '0.9.9' + id 'fabric-loom' version '1.9.2' id 'maven-publish' } -sourceCompatibility = JavaVersion.VERSION_1_8 -targetCompatibility = JavaVersion.VERSION_1_8 +sourceCompatibility = "21" +targetCompatibility = "21" archivesBaseName = project.archives_base_name version = project.mod_version @@ -40,12 +40,12 @@ dependencies { include 'com.alibaba:fastjson:1.2.56' include 'com.googlecode.json-simple:json-simple:1.1.1' include 'com.cedarsoftware:json-io:4.10.1' - include "io.github.cottonmc:LibGui:3.2.2+1.16.3" +// include files("libs/LibGui-12.0.1+1.21.2.jar") // PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs. // You may need to force-disable transitiveness on them. - modImplementation "io.github.cottonmc:LibGui:4.1.5+1.17.1" + modImplementation files("libs/LibGui-12.0.1+1.21.2.jar") } processResources { @@ -67,7 +67,7 @@ tasks.withType(JavaCompile) { // if it is present. // If you remove this task, sources will not be generated. task sourcesJar(type: Jar, dependsOn: classes) { - classifier = "sources" + archiveClassifier = "sources" from sourceSets.main.allSource } diff --git a/gradle.properties b/gradle.properties index f783221..f1c5d84 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,15 +3,15 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://fabricmc.net/use - minecraft_version=1.17.1 - yarn_mappings=1.17.1+build.31 - loader_version=0.11.6 + minecraft_version=1.21.4 + yarn_mappings=1.21.4+build.8 + loader_version=0.16.10 # Mod Properties - mod_version = 1.2.0 + mod_version = 1.14.514.011 maven_group = com.josyf.commandbuttons - archives_base_name = command-gui-buttons + archives_base_name = command-gui-buttons-revive # Dependencies # currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api - fabric_version=0.37.1+1.17 + fabric_version=0.119.3+1.21.4 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 05679dc..260504c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/libs/LibGui-12.0.1+1.21.2.pom b/libs/LibGui-12.0.1+1.21.2.pom new file mode 100644 index 0000000..0bd6e7c --- /dev/null +++ b/libs/LibGui-12.0.1+1.21.2.pom @@ -0,0 +1,78 @@ + + + + + + + + 4.0.0 + io.github.cottonmc + LibGui + 12.0.1+1.21.2 + LibGui + Minecraft GUI Library + https://github.com/CottonMC/LibGui + + + MIT + https://github.com/CottonMC/LibGui/blob/HEAD/LICENSE + + + + + CottonMC + https://github.com/CottonMC + + + + + io.github.juuxel + libninepatch + 1.2.0 + compile + + + net.fabricmc.fabric-api + fabric-api-base + 0.4.48+c47b9d4373 + compile + + + net.fabricmc.fabric-api + fabric-networking-api-v1 + 4.3.3+56ec7ac673 + compile + + + net.fabricmc + fabric-loader + 0.16.7 + runtime + + + net.fabricmc.fabric-api + fabric-lifecycle-events-v1 + 2.3.22+c47b9d4373 + runtime + + + net.fabricmc.fabric-api + fabric-rendering-v1 + 8.0.5+c47b9d4373 + runtime + + + net.fabricmc.fabric-api + fabric-resource-loader-v0 + 3.0.5+c47b9d4373 + runtime + + + io.github.cottonmc + Jankson-Fabric + 9.0.0+j1.2.3 + runtime + + + diff --git a/remappedSrc/com/josyf/commandbuttons/ConfigFile.java b/remappedSrc/com/josyf/commandbuttons/ConfigFile.java index ac36143..6db490d 100644 --- a/remappedSrc/com/josyf/commandbuttons/ConfigFile.java +++ b/remappedSrc/com/josyf/commandbuttons/ConfigFile.java @@ -22,7 +22,7 @@ public class ConfigFile { array.add(jsonObject); writeToFile(array); } catch (IOException e) { - System.out.println("Commands.json doesn't exist. Creating one...!"); + System.out.println("Commands.json 不存在。正在创建..."); JSONArray jsonArray = new JSONArray(); jsonArray.add(jsonObject); writeToFile(jsonArray); @@ -77,7 +77,7 @@ public class ConfigFile { } return commandObjects; } catch (IOException | ParseException e) { - System.out.println("Commands.json not yet initialized!"); + System.out.println("Commands.json尚未初始化!"); } return null; } diff --git a/remappedSrc/com/josyf/commandbuttons/gui/ButtonGUI.java b/remappedSrc/com/josyf/commandbuttons/gui/ButtonGUI.java index 62d256c..27f3756 100644 --- a/remappedSrc/com/josyf/commandbuttons/gui/ButtonGUI.java +++ b/remappedSrc/com/josyf/commandbuttons/gui/ButtonGUI.java @@ -93,7 +93,7 @@ public class ButtonGUI extends LightweightGuiDescription { root.validate(this); } else { - System.out.println("No name and value entered!"); + System.out.println("未输入名称和数值!"); } } @@ -115,7 +115,7 @@ public class ButtonGUI extends LightweightGuiDescription { adjustBounds(); root.validate(this); } else { - System.out.println("No name and value entered!"); + System.out.println("未输入名称和数值!"); } } diff --git a/src/main/java/com/josyf/commandbuttons/CommandButtons.java b/src/main/java/com/josyf/commandbuttons/CommandButtons.java index a667434..44a32c7 100644 --- a/src/main/java/com/josyf/commandbuttons/CommandButtons.java +++ b/src/main/java/com/josyf/commandbuttons/CommandButtons.java @@ -1,58 +1,59 @@ package com.josyf.commandbuttons; - import com.josyf.commandbuttons.gui.ButtonGUI; import com.josyf.commandbuttons.gui.ButtonGUIScreen; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; import net.minecraft.client.MinecraftClient; -//import net.minecraft.client.options.KeyBinding; import net.minecraft.client.option.KeyBinding; import net.minecraft.client.util.InputUtil; import org.json.simple.JSONObject; import org.lwjgl.glfw.GLFW; import java.util.ArrayList; +import java.util.List; public class CommandButtons implements ModInitializer { public static final String MOD_ID = "mgbuttons"; private static ArrayList masterCommList; - public static void main(String[] args) { - - } - @Override public void onInitialize() { assignGuiToKey(); initArray(); } - private void assignGuiToKey() { - // Currently assigns to the G key + // 默认G键触发GUI KeyBinding keyBinding = KeyBindingHelper.registerKeyBinding(new KeyBinding( - "key.commandbuttons.opengui", // The translation key of the keybinding's name - InputUtil.Type.KEYSYM, // The type of the keybinding, KEYSYM for keyboard, MOUSE for mouse. - GLFW.GLFW_KEY_G, // The keycode of the key - "gui.commandbuttons.mgbuttons" // The translation key of the keybinding's category. + "key.commandbuttons.opengui", + InputUtil.Type.KEYSYM, + GLFW.GLFW_KEY_G, + "gui.commandbuttons.mgbuttons" )); ClientTickEvents.END_CLIENT_TICK.register(client -> { while (keyBinding.wasPressed()) { - MinecraftClient.getInstance().setScreen(new ButtonGUIScreen(new ButtonGUI())); - //client.player.closeScreen(); + MinecraftClient.getInstance().setScreen(new ButtonGUIScreen(new ButtonGUI())); } }); } - public static void runCommand(String command) { - MinecraftClient.getInstance().player.sendChatMessage(command); + + // 执行命令,一行一行来 + public static void runCommands(List commands) { + MinecraftClient client = MinecraftClient.getInstance(); + if (client != null && client.player != null && client.player.networkHandler != null) { + for (String command : commands) { + if (command != null && !command.trim().isEmpty()) { + client.player.networkHandler.sendChatCommand(command.trim()); + } + } + } } - // Assign masterCommList to JSONArray (from commands.json). Runs once. static void initArray() { masterCommList = ConfigFile.getArrayFromJsonFile(); // If commands.json doesn't exist yet, start a global list variable for future creation @@ -69,5 +70,10 @@ public class CommandButtons implements ModInitializer { masterCommList = commList; } + public static void refreshMasterCommList() { + masterCommList = ConfigFile.getArrayFromJsonFile(); + if (masterCommList == null) { + masterCommList = new ArrayList<>(); + } + } } - diff --git a/src/main/java/com/josyf/commandbuttons/ConfigFile.java b/src/main/java/com/josyf/commandbuttons/ConfigFile.java index 57f9a09..dfbb238 100644 --- a/src/main/java/com/josyf/commandbuttons/ConfigFile.java +++ b/src/main/java/com/josyf/commandbuttons/ConfigFile.java @@ -4,49 +4,86 @@ import com.alibaba.fastjson.JSON; import com.cedarsoftware.util.io.JsonWriter; import org.json.simple.JSONArray; import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; -import org.json.simple.parser.*; -import java.io.*; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; import java.util.ArrayList; +import java.util.List; public class ConfigFile { private static final JSONParser parser = new JSONParser(); - private static FileWriter fileWriter; + private static final String CONFIG_FILE_NAME = "commands.json"; // Read commands.json, convert it to an array, and append A JSON OBJECT public static void appendToFile(JSONObject jsonObject) { - try { - Object obj = parser.parse(new FileReader("commands.json")); - JSONArray array = (JSONArray) obj; - array.add(jsonObject); - writeToFile(array); - } catch (IOException e) { - System.out.println("Commands.json doesn't exist. Creating one...!"); - JSONArray jsonArray = new JSONArray(); - jsonArray.add(jsonObject); - writeToFile(jsonArray); - } catch (ParseException e) { - e.printStackTrace(); + JSONArray array = getJsonArrayFromFile(); + if (array == null) { + array = new JSONArray(); + } + array.add(jsonObject); + writeToFile(array); + } + + // 按名称 + public static void removeObjectByName(String name) { + JSONArray array = getJsonArrayFromFile(); + if (array == null) { + return; + } + JSONArray newArray = new JSONArray(); + boolean removed = false; + for (Object obj : array) { + if (obj instanceof JSONObject) { + JSONObject jsonObject = (JSONObject) obj; + if (jsonObject.containsKey("name") && jsonObject.get("name").equals(name)) { + removed = true; + } else { + newArray.add(jsonObject); + } + } + } + if (removed) { + writeToFile(newArray); } } - public static void removeFromFile(JSONObject jsonObject) { - try { - Object obj = parser.parse(new FileReader("commands.json")); - JSONArray array = (JSONArray) obj; - array.remove(jsonObject); - writeToFile(array); - } catch (IOException | ParseException e) { - e.printStackTrace(); + public static void updateObjectByName(String originalName, JSONObject updatedObject) { + JSONArray array = getJsonArrayFromFile(); + if (array == null) { + return; } + JSONArray newArray = new JSONArray(); + boolean updated = false; + for (Object obj : array) { + if (obj instanceof JSONObject) { + JSONObject jsonObject = (JSONObject) obj; + if (jsonObject.containsKey("name") && jsonObject.get("name").equals(originalName)) { + newArray.add(updatedObject); + updated = true; + } else { + newArray.add(jsonObject); + } + } + } + if (updated) { + writeToFile(newArray); + } else { + System.err.println("未找到名称为'" + originalName + "'的命令以进行更新。"); + } + writeToFile(newArray); } + // overwrites current commands.json w/ updated jsonArray private static void writeToFile(JSONArray jsonArray) { + FileWriter fileWriter = null; try { - fileWriter = new FileWriter("commands.json"); + fileWriter = new FileWriter(CONFIG_FILE_NAME); + // Use fastjson for writing as it handles JSONArray better with JsonWriter formatting String jArrayToString = JSON.toJSONString(jsonArray); String formattedJson = JsonWriter.formatJson(jArrayToString); fileWriter.write(formattedJson); @@ -54,53 +91,94 @@ public class ConfigFile { e.printStackTrace(); } finally { try { - fileWriter.flush(); - fileWriter.close(); + if (fileWriter != null) { + fileWriter.flush(); + fileWriter.close(); + } } catch (IOException e) { e.printStackTrace(); } } } - // parses commands.json into array, loop through array and add JSONObjects. returns array - public static ArrayList getArrayFromJsonFile() { - ArrayList commandObjects = new ArrayList<>(); - try { - // assign array to JSONArray using our commands.json as an object - Object obj = parser.parse(new FileReader("commands.json")); - JSONArray array = (JSONArray) obj; - // so "array" is now a JSONArray full of JSONObjects - // now we will iterate through the array and add COs to our local CO array - for (int i = 0; i < array.size(); i++) { - JSONObject childObject = (JSONObject)array.get(i); - commandObjects.add(childObject); - if (i >= 19) break; + // parses commands.json into JSONArray + private static JSONArray getJsonArrayFromFile() { + try (FileReader reader = new FileReader(CONFIG_FILE_NAME)) { + Object obj = parser.parse(reader); + if (obj instanceof JSONArray) { + return (JSONArray) obj; + } else if (obj instanceof JSONObject) { + + System.err.println("配置文件不是一个 JSON 数组。返回空数组。"); + return new JSONArray(); + } else { + System.err.println("配置文件包含意外的内容。返回空数组。"); + return new JSONArray(); } - return commandObjects; - } catch (IOException | ParseException e) { - System.out.println("Commands.json not yet initialized!"); + } catch (IOException e) { + System.out.println("Commands.json文件不存在或读取错误。返回null。"); + return null; + } catch (ParseException e) { + System.err.println("解析 commands.json 时出错:" + e.getMessage()); + e.printStackTrace(); + return new JSONArray(); } - return null; } - public static void addObjectToCommList(JSONObject jsonObject) { + + // parses commands.json into + public static ArrayList getArrayFromJsonFile() { + JSONArray array = getJsonArrayFromFile(); + if (array == null) { + return null; + } + + ArrayList commandObjects = new ArrayList<>(); + for (Object obj : array) { + if (obj instanceof JSONObject) { + commandObjects.add((JSONObject) obj); + } + } + return commandObjects; + } + + // 添加 + public static void addObject(JSONObject jsonObject) { ArrayList commListCopy = CommandButtons.getMasterCommList(); + if (commListCopy == null) { + commListCopy = new ArrayList<>(); + CommandButtons.setMasterCommList(commListCopy); + } commListCopy.add(jsonObject); - CommandButtons.setMasterCommList(commListCopy); + appendToFile(jsonObject); } + // 移除 public static void removeObject(JSONObject objToRemove) { - // get masterCommList and remove object from list ArrayList commListCopy = CommandButtons.getMasterCommList(); - commListCopy.remove(objToRemove); - - // get commands.json - // remove corresponding button from json - removeFromFile(objToRemove); - + if (commListCopy != null) { + commListCopy.removeIf(obj -> obj.containsKey("name") && objToRemove.containsKey("name") && obj.get("name").equals(objToRemove.get("name"))); + } + if (objToRemove.containsKey("name")) { + removeObjectByName(objToRemove.get("name").toString()); + } else { + System.err.println("无法删除没有“name”字段的对象。"); + } } - - + // 编辑 + public static void updateObject(String originalName, JSONObject updatedObject) { + ArrayList commListCopy = CommandButtons.getMasterCommList(); + if (commListCopy != null) { + for (int i = 0; i < commListCopy.size(); i++) { + JSONObject obj = commListCopy.get(i); + if (obj.containsKey("name") && obj.get("name").equals(originalName)) { + commListCopy.set(i, updatedObject); + break; + } + } + } + updateObjectByName(originalName, updatedObject); + } } diff --git a/src/main/java/com/josyf/commandbuttons/gui/ButtonGUI.java b/src/main/java/com/josyf/commandbuttons/gui/ButtonGUI.java index 62d256c..63467b1 100644 --- a/src/main/java/com/josyf/commandbuttons/gui/ButtonGUI.java +++ b/src/main/java/com/josyf/commandbuttons/gui/ButtonGUI.java @@ -5,162 +5,126 @@ import com.josyf.commandbuttons.ConfigFile; import io.github.cottonmc.cotton.gui.client.BackgroundPainter; import io.github.cottonmc.cotton.gui.client.LightweightGuiDescription; import io.github.cottonmc.cotton.gui.widget.*; +import io.github.cottonmc.cotton.gui.widget.data.HorizontalAlignment; +import io.github.cottonmc.cotton.gui.widget.data.VerticalAlignment; import net.minecraft.client.MinecraftClient; -import net.minecraft.text.TranslatableText; +import io.github.cottonmc.cotton.gui.widget.data.Insets; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.text.Text; +import org.json.simple.JSONArray; import org.json.simple.JSONObject; import java.util.ArrayList; +import java.util.List; public class ButtonGUI extends LightweightGuiDescription { - int xValue = 0; - int yValue = 1; + private final Screen parentScreen; public ButtonGUI() { - + this.parentScreen = MinecraftClient.getInstance().currentScreen; // initialize root panel of GUI WGridPanel root = new WGridPanel(); + setRootPanel(root); + root.setSize(300, 200); + + + root.setInsets(new Insets(5)); + setupBackground(root); + + WLabel title = new WLabel(Text.translatable("gui.commandbuttons.title"), 0xcdcdcd); + title.setHorizontalAlignment(HorizontalAlignment.CENTER); + root.add(title, 0, 0, 18, 1); + addCloseButton(root); - // Add delete toggle button - WToggleButton delToggle = new WToggleButton(new TranslatableText("Delete")); - root.add(delToggle, 0, 11, 3, 1); + WGridPanel commandListPanel = new WGridPanel(); + WScrollPanel scrollPanel = new WScrollPanel(commandListPanel); + root.add(scrollPanel, 0, 2, 18, 8); + + addSavedButtons(commandListPanel); + + WButton addCommandButton = new WButton(Text.translatable("gui.commandbuttons.add_command")); + addCommandButton.setOnClick(this::openCreateCommandScreen); + root.add(addCommandButton, 0, 11, 18, 1); - addSavedButtons(root, delToggle); - addCommandSection(root, delToggle); root.validate(this); } + // 背景 + private void setupBackground(WGridPanel root) { + root.setBackgroundPainter(BackgroundPainter.createColorful(0x4D000000)); + } + + // 关闭按钮 private void addCloseButton(WGridPanel root) { - WButton escButton = new WButton(new TranslatableText("x")); - escButton.setOnClick(() -> MinecraftClient.getInstance().player.closeScreen()); - root.add(escButton, 17, 1, 2, 2); + WButton escButton = new WButton(Text.translatable("gui.commandbuttons.close")); + escButton.setOnClick(() -> MinecraftClient.getInstance().setScreen(this.parentScreen)); + root.add(escButton, 17, 0, 1, 1); } - private void addCommandSection(WGridPanel root, WToggleButton toggle) { - // Add text field for command NAME entry - WTextField nameTextField = new WTextField(); - nameTextField.setMaxLength(11); - nameTextField.setSuggestion("Name"); - root.add(nameTextField, 0, 12, 6, 1); - - // Add text field for command / entry - WTextField commandTextField = new WTextField(); - commandTextField.setSuggestion("/command"); - commandTextField.setMaxLength(300); - root.add(commandTextField, 6, 12, 11, 1); - - // Add button for command entry - WButton addCmdBtn = new WButton(new TranslatableText("+")); - addCmdBtn.setOnClick(() -> addGUIButton(root, nameTextField, commandTextField, toggle)); - root.add(addCmdBtn, 18, 12, 1, 1); - } - - // Function to save newly added buttons to commands.json - private void addGUIButton(WGridPanel root, WTextField name, WTextField command, WToggleButton isDeleteToggled) { - // Only add the button if there are contents in both - if (!name.getText().equals("") && !command.getText().equals("")) { - // Create a new Json object & append to masterCommList - JSONObject newJsonObject = new JSONObject(); - newJsonObject.put("name", name.getText()); - newJsonObject.put("command", command.getText()); - - if (!isListTooLong()) { - String commandString = command.getText(); - WButton button = new WButton(new TranslatableText(name.getText())); - button.setOnClick(() -> { - if (isDeleteToggled.getToggle()) { - ConfigFile.removeObject(newJsonObject); - root.remove(button); - } else { - CommandButtons.runCommand(commandString); + // 保存的设置 + private void addSavedButtons(WGridPanel commandListPanel) { + ArrayList commListCopy = CommandButtons.getMasterCommList(); + if (commListCopy != null) { + int yOffset = 0; + for (JSONObject object : commListCopy) { + if (object.containsKey("name") && object.containsKey("commands")) { + String name = object.get("name").toString(); + JSONArray commandsArray = (JSONArray) object.get("commands"); + List commands = new ArrayList<>(); + for (Object cmdObj : commandsArray) { + if (cmdObj instanceof String) { + commands.add((String) cmdObj); + } } - }); - root.add(button, xValue, yValue, 4, 1); + WGridPanel commandEntryPanel = new WGridPanel(); + commandEntryPanel.setSize(commandListPanel.getWidth(), 20); - // append the buttons to masterList for future loading - ConfigFile.addObjectToCommList(newJsonObject); - ConfigFile.appendToFile(newJsonObject); + WButton executeButton = new WButton(Text.literal(name)); + executeButton.setOnClick(() -> { + CommandButtons.runCommands(commands); + MinecraftClient.getInstance().setScreen(this.parentScreen); + }); + commandEntryPanel.add(executeButton, 0, 0, 14, 1); - adjustBounds(); - } + WButton editButton = new WButton(Text.translatable("gui.commandbuttons.edit")); + editButton.setOnClick(() -> openEditCommandScreen(object)); + commandEntryPanel.add(editButton, 15, 0, 3, 1); - name.setText(""); - command.setText(""); - - root.validate(this); - - } else { - System.out.println("No name and value entered!"); - } - - } - - // function to load buttons from commands.json - private void addGUIButton(WGridPanel root, String name, String command, WToggleButton isDeleteToggled, JSONObject object) { - if (!name.equals("") && !command.equals("")) { - WButton button = new WButton(new TranslatableText(name)); - button.setOnClick(() -> { - if (isDeleteToggled.getToggle()) { - ConfigFile.removeObject(object); - root.remove(button); + commandListPanel.add(commandEntryPanel, 0, yOffset, 18, 1); + yOffset += 1; } else { - CommandButtons.runCommand(command); + System.err.println("在 commands.json 中跳过格式错误的命令对象:" + object.toJSONString()); } - - }); - root.add(button, xValue, yValue, 4, 1); - adjustBounds(); - root.validate(this); - } else { - System.out.println("No name and value entered!"); - } - } - - - // Array will contain String class types. Convert these to objects. - private void addSavedButtons(WGridPanel root, WToggleButton toggle) { - ArrayList commListCopy = CommandButtons.getMasterCommList(); - // Then convert the objects to buttons - if (commListCopy != null) { - for (int i = 0; i < commListCopy.size(); i++) { - JSONObject object = commListCopy.get(i); - String name = commListCopy.get(i).get("name").toString(); - String command = commListCopy.get(i).get("command").toString(); - addGUIButton(root, name, command, toggle, object); - if (i >= 19) break; } } + } + // 新建按钮 + private void openCreateCommandScreen() { + MinecraftClient.getInstance().setScreen(new ButtonGUIScreen(new CreateCommandGUI(this.parentScreen), this.parentScreen)); + } + + // 编辑按钮 + private void openEditCommandScreen(JSONObject commandObject) { + MinecraftClient.getInstance().setScreen(new ButtonGUIScreen(new EditCommandGUI(commandObject, this.parentScreen), this.parentScreen)); } - private void adjustBounds() { - if (xValue % 12 == 0 && xValue != 0) { - yValue += 2; - xValue = 0; - } else { - xValue += 4; - } - } - - private boolean isListTooLong() { - return CommandButtons.getMasterCommList().size() > 19; - } - - // Change background panel color to transparent black @Override public void addPainters() { - super.addPainters(); - this.rootPanel.setBackgroundPainter(BackgroundPainter.createColorful(0x4D000000)); } - private void setupBackground(WGridPanel root) { - setRootPanel(root); - root.setSize(350, 240); + @Override + public boolean isTitleVisible() { + return true; } - + @Override + public int getTitleColor() { + return 0x404040; + } } diff --git a/src/main/java/com/josyf/commandbuttons/gui/ButtonGUIScreen.java b/src/main/java/com/josyf/commandbuttons/gui/ButtonGUIScreen.java index 55120e1..8cc6c90 100644 --- a/src/main/java/com/josyf/commandbuttons/gui/ButtonGUIScreen.java +++ b/src/main/java/com/josyf/commandbuttons/gui/ButtonGUIScreen.java @@ -2,13 +2,25 @@ package com.josyf.commandbuttons.gui; import io.github.cottonmc.cotton.gui.GuiDescription; import io.github.cottonmc.cotton.gui.client.CottonClientScreen; +import net.minecraft.client.gui.screen.Screen; public class ButtonGUIScreen extends CottonClientScreen { + + private final Screen parent; + public ButtonGUIScreen(GuiDescription description) { - super(description); + this(description, null); } + public ButtonGUIScreen(GuiDescription description, Screen parent) { + super(description); + this.parent = parent; + } + @Override + public void close() { + if (this.client != null) { + this.client.setScreen(this.parent); + } + } } - - diff --git a/src/main/java/com/josyf/commandbuttons/gui/CreateCommandGUI.java b/src/main/java/com/josyf/commandbuttons/gui/CreateCommandGUI.java new file mode 100644 index 0000000..c288b08 --- /dev/null +++ b/src/main/java/com/josyf/commandbuttons/gui/CreateCommandGUI.java @@ -0,0 +1,142 @@ +package com.josyf.commandbuttons.gui; + +import com.josyf.commandbuttons.CommandButtons; +import com.josyf.commandbuttons.ConfigFile; +import io.github.cottonmc.cotton.gui.client.BackgroundPainter; +import io.github.cottonmc.cotton.gui.client.LightweightGuiDescription; +import io.github.cottonmc.cotton.gui.widget.*; +import io.github.cottonmc.cotton.gui.widget.data.HorizontalAlignment; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.text.Text; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import io.github.cottonmc.cotton.gui.widget.data.Insets; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class CreateCommandGUI extends LightweightGuiDescription { + + private final Screen parentScreen; + private final WGridPanel commandsPanel; + private final ArrayList commandTextFields = new ArrayList<>(); + private int nextCommandRow = 0; + + public CreateCommandGUI(Screen parentScreen) { + this.parentScreen = parentScreen; + + WGridPanel root = new WGridPanel(); + setRootPanel(root); + root.setSize(280, 220); + root.setInsets(new Insets(5)); + + root.setBackgroundPainter(BackgroundPainter.createColorful(0x4D000000)); + + WLabel title = new WLabel(Text.translatable("gui.commandbuttons.create_title"), getTitleColor()); + title.setHorizontalAlignment(HorizontalAlignment.CENTER); + root.add(title, 0, 0, 16, 1); + + WLabel nameLabel = new WLabel(Text.translatable("gui.commandbuttons.name_label")); + root.add(nameLabel, 0, 2); + WTextField nameField = new WTextField(); + nameField.setSuggestion(Text.translatable("gui.commandbuttons.commands_suggestion_name")); + root.add(nameField, 0, 3, 16, 1); + WLabel commandsLabel = new WLabel(Text.translatable("gui.commandbuttons.commands_label")); + root.add(commandsLabel, 0, 5); + + commandsPanel = new WGridPanel(); + WScrollPanel scrollPanel = new WScrollPanel(commandsPanel); + root.add(scrollPanel, 0, 6, 16, 8); + + addCommandTextField(""); + rebuildCommandsPanel(); + + WButton addCommandButton = new WButton(Text.literal("+")); + addCommandButton.setOnClick(() -> { + addCommandTextField(""); + rebuildCommandsPanel(); + }); + root.add(addCommandButton, 16, 6, 1, 1); + + WButton createButton = new WButton(Text.translatable("gui.commandbuttons.create")); + createButton.setOnClick(() -> { + String name = nameField.getText().trim(); + List commands = commandTextFields.stream() + .map(WTextField::getText) + .map(String::trim) + .filter(cmd -> !cmd.isEmpty()) + .collect(Collectors.toList()); + + if (!name.isEmpty() && !commands.isEmpty()) { + JSONObject newCommand = new JSONObject(); + newCommand.put("name", name); + + JSONArray commandsArray = new JSONArray(); + commandsArray.addAll(commands); + newCommand.put("commands", commandsArray); + + ConfigFile.addObject(newCommand); + CommandButtons.refreshMasterCommList(); + + MinecraftClient.getInstance().setScreen(this.parentScreen); + } else { + System.out.println("名称或命令字段为空!"); + } + }); + root.add(createButton, 0, 15, 8, 1); + + WButton cancelButton = new WButton(Text.translatable("gui.commandbuttons.cancel")); + cancelButton.setOnClick(() -> { + MinecraftClient.getInstance().setScreen(this.parentScreen); + }); + + root.add(cancelButton, 8, 15, 8, 1); + + root.validate(this); + } + private void addCommandTextField(String initialText) { + WTextField textField = new WTextField(); + textField.setText(initialText); + textField.setSuggestion(Text.translatable("gui.commandbuttons.commands_suggestion_command")); + commandTextFields.add(textField); + } + private void rebuildCommandsPanel() { + List currentPanelChildren = commandsPanel.streamChildren().collect(Collectors.toList()); + + for (WWidget child : currentPanelChildren) { + commandsPanel.remove(child); + } + nextCommandRow = 0; + + for (WTextField textField : commandTextFields) { + + commandsPanel.add(textField, 0, nextCommandRow, 15, 1); + WButton removeButton = new WButton(Text.literal("-")); + removeButton.setOnClick(() -> { + commandTextFields.remove(textField); + rebuildCommandsPanel(); + }); + commandsPanel.add(removeButton, 15, nextCommandRow, 1, 1); + + nextCommandRow += 1; + } + if (commandTextFields.isEmpty()) { + addCommandTextField(""); + rebuildCommandsPanel(); + return; + } + + commandsPanel.validate(this); + } + @Override + public boolean isTitleVisible() { + return false; + } + + @Override + public int getTitleColor() { + return 0x404040; + } +} diff --git a/src/main/java/com/josyf/commandbuttons/gui/EditCommandGUI.java b/src/main/java/com/josyf/commandbuttons/gui/EditCommandGUI.java new file mode 100644 index 0000000..5b828e7 --- /dev/null +++ b/src/main/java/com/josyf/commandbuttons/gui/EditCommandGUI.java @@ -0,0 +1,168 @@ +package com.josyf.commandbuttons.gui; + +import com.josyf.commandbuttons.CommandButtons; +import com.josyf.commandbuttons.ConfigFile; +import io.github.cottonmc.cotton.gui.client.BackgroundPainter; +import io.github.cottonmc.cotton.gui.client.LightweightGuiDescription; +import io.github.cottonmc.cotton.gui.widget.*; +import io.github.cottonmc.cotton.gui.widget.data.HorizontalAlignment; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.text.Text; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import io.github.cottonmc.cotton.gui.widget.data.Insets; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class EditCommandGUI extends LightweightGuiDescription { + + private final JSONObject originalCommand; + private final String originalName; + private final Screen parentScreen; + + private final WGridPanel commandsPanel; + private final ArrayList commandTextFields = new ArrayList<>(); + private int nextCommandRow = 0; + + public EditCommandGUI(JSONObject commandObject, Screen parentScreen) { + this.originalCommand = commandObject; + this.originalName = commandObject.containsKey("name") ? originalCommand.get("name").toString() : ""; + this.parentScreen = parentScreen; + + WGridPanel root = new WGridPanel(); + setRootPanel(root); + root.setSize(280, 250); + root.setInsets(new Insets(5)); + root.setBackgroundPainter(BackgroundPainter.createColorful(0x4D000000)); + WLabel title = new WLabel(Text.translatable("gui.commandbuttons.edit_title"), getTitleColor()); + title.setHorizontalAlignment(HorizontalAlignment.CENTER); + + root.add(title, 0, 0, 16, 1); + WLabel nameLabel = new WLabel(Text.translatable("gui.commandbuttons.name_label")); + + root.add(nameLabel, 0, 2); + WTextField nameField = new WTextField(); + nameField.setText(originalName); + root.add(nameField, 0, 3, 16, 1); + WLabel commandsLabel = new WLabel(Text.translatable("gui.commandbuttons.commands_label")); + + root.add(commandsLabel, 0, 5); + commandsPanel = new WGridPanel(); + WScrollPanel scrollPanel = new WScrollPanel(commandsPanel); + + root.add(scrollPanel, 0, 6, 16, 8); + loadCommandsIntoFields(); + rebuildCommandsPanel(); + WButton addCommandButton = new WButton(Text.literal("+")); + addCommandButton.setOnClick(() -> { + addCommandTextField(""); + rebuildCommandsPanel(); + }); + + root.add(addCommandButton, 16, 6, 1, 1); + WButton saveButton = new WButton(Text.translatable("gui.commandbuttons.save")); + saveButton.setOnClick(() -> { + String newName = nameField.getText().trim(); + List commands = commandTextFields.stream() + .map(WTextField::getText) + .map(String::trim) + .filter(cmd -> !cmd.isEmpty()) + .collect(Collectors.toList()); + + if (!newName.isEmpty() && !commands.isEmpty()) { + JSONObject updatedCommand = new JSONObject(); + updatedCommand.put("name", newName); + + JSONArray commandsArray = new JSONArray(); + commandsArray.addAll(commands); + updatedCommand.put("commands", commandsArray); + + ConfigFile.updateObject(originalName, updatedCommand); + CommandButtons.refreshMasterCommList(); + MinecraftClient.getInstance().setScreen(this.parentScreen); + } else { + System.out.println("名称或命令字段为空!"); + } + }); + + root.add(saveButton, 0, 15, 8, 1); + WButton deleteButton = new WButton(Text.translatable("gui.commandbuttons.delete")); + deleteButton.setOnClick(() -> { + ConfigFile.removeObject(originalCommand); + CommandButtons.refreshMasterCommList(); + MinecraftClient.getInstance().setScreen(this.parentScreen); + }); + + root.add(deleteButton, 0, 16, 8, 1); + WButton cancelButton = new WButton(Text.translatable("gui.commandbuttons.cancel")); + cancelButton.setOnClick(() -> { + + MinecraftClient.getInstance().setScreen(this.parentScreen); + }); + + root.add(cancelButton, 8, 15, 8, 1); + root.validate(this); + } + private void loadCommandsIntoFields() { + commandTextFields.clear(); + if (originalCommand.containsKey("commands") && originalCommand.get("commands") instanceof JSONArray) { + JSONArray commandsArray = (JSONArray) originalCommand.get("commands"); + for (Object cmdObj : commandsArray) { + if (cmdObj instanceof String) { + addCommandTextField((String) cmdObj); + } + } + } + if (commandTextFields.isEmpty()) { + addCommandTextField(""); + } + + } + private void addCommandTextField(String initialText) { + WTextField textField = new WTextField(); + textField.setText(initialText); + textField.setSuggestion(Text.of(Text.translatable("gui.commandbuttons.commands_suggestion_command"))); + commandTextFields.add(textField); + } + private void rebuildCommandsPanel() { + List currentPanelChildren = commandsPanel.streamChildren().collect(Collectors.toList()); + + for (WWidget child : currentPanelChildren) { + commandsPanel.remove(child); + } + nextCommandRow = 0; + + for (WTextField textField : commandTextFields) { + + commandsPanel.add(textField, 0, nextCommandRow, 15, 1); + WButton removeButton = new WButton(Text.literal("-")); + removeButton.setOnClick(() -> { + commandTextFields.remove(textField); + rebuildCommandsPanel(); + }); + commandsPanel.add(removeButton, 15, nextCommandRow, 1, 1); + + nextCommandRow += 1; + } + if (commandTextFields.isEmpty()) { + addCommandTextField(""); + rebuildCommandsPanel(); + return; + } + + commandsPanel.validate(this); + } + + @Override + public boolean isTitleVisible() { + return false; + } + + @Override + public int getTitleColor() { + return 0x404040; + } +} diff --git a/src/main/resources/assets/mgbuttons/lang/en_us.json b/src/main/resources/assets/mgbuttons/lang/en_us.json new file mode 100644 index 0000000..ce21f67 --- /dev/null +++ b/src/main/resources/assets/mgbuttons/lang/en_us.json @@ -0,0 +1,18 @@ +{ + "key.commandbuttons.opengui": "Open Command Buttons GUI", + "gui.commandbuttons.mgbuttons": "Command Buttons", + "gui.commandbuttons.title": "Command Buttons", + "gui.commandbuttons.close": "X", + "gui.commandbuttons.add_command": "Add New Command", + "gui.commandbuttons.edit": "Edit", + "gui.commandbuttons.create_title": "Create New Command", + "gui.commandbuttons.edit_title": "Edit Command", + "gui.commandbuttons.name_label": "Name:", + "gui.commandbuttons.commands_label": "Commands (one per line, no / ):", + "gui.commandbuttons.create": "Create", + "gui.commandbuttons.save": "Save", + "gui.commandbuttons.delete": "Delete", + "gui.commandbuttons.cancel": "Cancel", + "gui.commandbuttons.commands_suggestion_name": "Command buttons name", + "gui.commandbuttons.commands_suggestion_command": "Command" +} diff --git a/src/main/resources/assets/mgbuttons/lang/zh_cn.json b/src/main/resources/assets/mgbuttons/lang/zh_cn.json new file mode 100644 index 0000000..2917140 --- /dev/null +++ b/src/main/resources/assets/mgbuttons/lang/zh_cn.json @@ -0,0 +1,18 @@ +{ + "key.commandbuttons.opengui": "打开命令按钮界面", + "gui.commandbuttons.mgbuttons": "命令按钮", + "gui.commandbuttons.title": "命令按钮", + "gui.commandbuttons.close": "X", + "gui.commandbuttons.add_command": "添加新命令", + "gui.commandbuttons.edit": "编辑", + "gui.commandbuttons.create_title": "创建新命令", + "gui.commandbuttons.edit_title": "编辑命令", + "gui.commandbuttons.name_label": "名称:", + "gui.commandbuttons.commands_label": "命令(每行一条,不要斜杠):", + "gui.commandbuttons.create": "创建", + "gui.commandbuttons.save": "保存", + "gui.commandbuttons.delete": "删除", + "gui.commandbuttons.cancel": "取消", + "gui.commandbuttons.commands_suggestion_name": "命令按钮名称", + "gui.commandbuttons.commands_suggestion_command": "命令" +} \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 45bded4..fc7a508 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -1,17 +1,18 @@ { "schemaVersion": 1, - "id": "command-gui-buttons", + "id": "command-gui-buttons-revive", "version": "${version}", "name": "Command GUI Buttons", "description": "Create GUI buttons in-game to execute commands.", "authors": [ "JosephG", - "Abbanon" + "Abbanon", + "BRanulf(This version ONLY)" ], "contact": { - "homepage": "https://www.curseforge.com/minecraft/mc-mods/command-gui-buttons", - "sources": "https://github.com/joseph-garcia/command-gui-buttons" + "homepage": "https://git.branulf.top/Branulf/command-gui-buttons-revive", + "sources": "https://git.branulf.top/Branulf/command-gui-buttons-revive" }, "license": "gpl-3.0", @@ -27,9 +28,9 @@ ], "depends": { - "fabricloader": ">=0.7.4", + "fabricloader": ">=0.16.10", "fabric": "*", - "minecraft": "1.17.x", + "minecraft": "1.21.4", "fabric-key-binding-api-v1": "*" }, "suggests": {