Compare commits
10 Commits
2df5b3b3a0
...
a2b8d2c0bd
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a2b8d2c0bd | ||
![]() |
e562c8e3cd | ||
![]() |
d7221978d2 | ||
![]() |
6dd6ef5a0f | ||
![]() |
8565d6e5ea | ||
![]() |
b9a5edab1a | ||
![]() |
ae9bbe4337 | ||
![]() |
3851aef330 | ||
![]() |
191c6d987c | ||
![]() |
702834a6ec |
28
NOTICE.md
Normal file
28
NOTICE.md
Normal file
@ -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]
|
@ -2,7 +2,7 @@
|
||||
|
||||
Command GUI Buttons is a fabric mod for Minecraft that allows users to create custom command buttons on their clients. Users can bring up this menu in-game with the G key, type in the Name and Command they want to create a button for, and press the + to create. It will then show up as a button on their screen to use whenever they want, as the button will automatically type and execute the command they initially entered.
|
||||
|
||||

|
||||

|
||||
|
||||
Create buttons for preset chat messages, commands like '/warp home', or anything else that goes in the chat box.
|
||||
|
||||
@ -12,8 +12,7 @@ Create buttons for preset chat messages, commands like '/warp home', or anything
|
||||
- Type in the Name and Command you want to save into a button
|
||||
- Press the + button
|
||||
|
||||
Up to 20 buttons are currently supported! More are planned.
|
||||
|
||||
|
||||
### How It Works
|
||||
The list of commands are serialized into a JSON format and stored locally on the users’ systems. The mod writes any new commands into the JSON as new buttons are created, and loads the JSON at the start of the game. A local list instance exists for reading and loading the buttons each time, so that file reading is kept to a minimum.
|
||||
The list of commands are serialized into a JSON format and stored locally on the users’ systems. The mod writes any new commands into the JSON as new buttons are created, and loads the JSON at the start of the game. A local list instance exists for reading and loading the buttons each time, so that file reading is kept to a minimum.
|
||||
|
18
build.gradle
18
build.gradle
@ -1,10 +1,10 @@
|
||||
plugins {
|
||||
id 'fabric-loom' version '0.5-SNAPSHOT'
|
||||
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
|
||||
@ -28,24 +28,24 @@ dependencies {
|
||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||
|
||||
// Serialization
|
||||
compile group: 'com.alibaba', name: 'fastjson', version: '1.2.56'
|
||||
compile 'com.googlecode.json-simple:json-simple:1.1.1'
|
||||
implementation group: 'com.alibaba', name: 'fastjson', version: '1.2.56'
|
||||
implementation 'com.googlecode.json-simple:json-simple:1.1.1'
|
||||
|
||||
|
||||
implementation 'com.cedarsoftware:json-io:4.10.1'
|
||||
|
||||
compile group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1'
|
||||
implementation group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1'
|
||||
|
||||
// includes
|
||||
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:3.2.2+1.16.3"
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -3,15 +3,15 @@ org.gradle.jvmargs=-Xmx1G
|
||||
|
||||
# Fabric Properties
|
||||
# check these on https://fabricmc.net/use
|
||||
minecraft_version=1.16.4
|
||||
yarn_mappings=1.16.4+build.3
|
||||
loader_version=0.10.6+build.214
|
||||
minecraft_version=1.21.4
|
||||
yarn_mappings=1.21.4+build.8
|
||||
loader_version=0.16.10
|
||||
|
||||
# Mod Properties
|
||||
mod_version = 1.0.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.25.1+build.416-1.16
|
||||
fabric_version=0.119.3+1.21.4
|
||||
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
5
gradle/wrapper/gradle-wrapper.properties
vendored
5
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,5 @@
|
||||
#Sun Dec 20 14:49:23 CST 2020
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
2
gradlew
vendored
2
gradlew
vendored
@ -130,7 +130,7 @@ fi
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
|
21
gradlew.bat
vendored
21
gradlew.bat
vendored
@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
@ -54,7 +54,7 @@ goto fail
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
@ -64,21 +64,6 @@ echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
@ -86,7 +71,7 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
|
78
libs/LibGui-12.0.1+1.21.2.pom
Normal file
78
libs/LibGui-12.0.1+1.21.2.pom
Normal file
@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<!-- This module was also published with a richer model, Gradle metadata, -->
|
||||
<!-- which should be used instead. Do not delete the following line which -->
|
||||
<!-- is to indicate to Gradle or any Gradle module metadata file consumer -->
|
||||
<!-- that they should prefer consuming it instead. -->
|
||||
<!-- do_not_remove: published-with-gradle-metadata -->
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>io.github.cottonmc</groupId>
|
||||
<artifactId>LibGui</artifactId>
|
||||
<version>12.0.1+1.21.2</version>
|
||||
<name>LibGui</name>
|
||||
<description>Minecraft GUI Library</description>
|
||||
<url>https://github.com/CottonMC/LibGui</url>
|
||||
<licenses>
|
||||
<license>
|
||||
<name>MIT</name>
|
||||
<url>https://github.com/CottonMC/LibGui/blob/HEAD/LICENSE</url>
|
||||
</license>
|
||||
</licenses>
|
||||
<developers>
|
||||
<developer>
|
||||
<name>CottonMC</name>
|
||||
<url>https://github.com/CottonMC</url>
|
||||
</developer>
|
||||
</developers>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.github.juuxel</groupId>
|
||||
<artifactId>libninepatch</artifactId>
|
||||
<version>1.2.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.fabricmc.fabric-api</groupId>
|
||||
<artifactId>fabric-api-base</artifactId>
|
||||
<version>0.4.48+c47b9d4373</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.fabricmc.fabric-api</groupId>
|
||||
<artifactId>fabric-networking-api-v1</artifactId>
|
||||
<version>4.3.3+56ec7ac673</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.fabricmc</groupId>
|
||||
<artifactId>fabric-loader</artifactId>
|
||||
<version>0.16.7</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.fabricmc.fabric-api</groupId>
|
||||
<artifactId>fabric-lifecycle-events-v1</artifactId>
|
||||
<version>2.3.22+c47b9d4373</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.fabricmc.fabric-api</groupId>
|
||||
<artifactId>fabric-rendering-v1</artifactId>
|
||||
<version>8.0.5+c47b9d4373</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.fabricmc.fabric-api</groupId>
|
||||
<artifactId>fabric-resource-loader-v0</artifactId>
|
||||
<version>3.0.5+c47b9d4373</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.cottonmc</groupId>
|
||||
<artifactId>Jankson-Fabric</artifactId>
|
||||
<version>9.0.0+j1.2.3</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
72
remappedSrc/com/josyf/commandbuttons/CommandButtons.java
Normal file
72
remappedSrc/com/josyf/commandbuttons/CommandButtons.java
Normal file
@ -0,0 +1,72 @@
|
||||
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.option.KeyBinding;
|
||||
import net.minecraft.client.util.InputUtil;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class CommandButtons implements ModInitializer {
|
||||
|
||||
public static final String MOD_ID = "mgbuttons";
|
||||
private static ArrayList<JSONObject> masterCommList;
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
assignGuiToKey();
|
||||
initArray();
|
||||
}
|
||||
|
||||
|
||||
private void assignGuiToKey() {
|
||||
// Currently assigns to the G key
|
||||
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.
|
||||
));
|
||||
|
||||
ClientTickEvents.END_CLIENT_TICK.register(client -> {
|
||||
while (keyBinding.wasPressed()) {
|
||||
MinecraftClient.getInstance().setScreen(new ButtonGUIScreen(new ButtonGUI()));
|
||||
//client.player.closeScreen();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void runCommand(String command) {
|
||||
MinecraftClient.getInstance().player.sendChatMessage(command);
|
||||
}
|
||||
|
||||
// Assign masterCommList to JSONArray<objects> (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
|
||||
if (masterCommList == null) {
|
||||
setMasterCommList(new ArrayList<>());
|
||||
}
|
||||
}
|
||||
|
||||
public static ArrayList<JSONObject> getMasterCommList() {
|
||||
return masterCommList;
|
||||
}
|
||||
|
||||
public static void setMasterCommList(ArrayList<JSONObject> commList) {
|
||||
masterCommList = commList;
|
||||
}
|
||||
|
||||
}
|
||||
|
105
remappedSrc/com/josyf/commandbuttons/ConfigFile.java
Normal file
105
remappedSrc/com/josyf/commandbuttons/ConfigFile.java
Normal file
@ -0,0 +1,105 @@
|
||||
package com.josyf.commandbuttons;
|
||||
|
||||
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.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ConfigFile {
|
||||
|
||||
private static final JSONParser parser = new JSONParser();
|
||||
private static FileWriter fileWriter;
|
||||
|
||||
// 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 不存在。正在创建...");
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
jsonArray.add(jsonObject);
|
||||
writeToFile(jsonArray);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
// overwrites current commands.json w/ updated jsonArray
|
||||
private static void writeToFile(JSONArray jsonArray) {
|
||||
try {
|
||||
fileWriter = new FileWriter("commands.json");
|
||||
String jArrayToString = JSON.toJSONString(jsonArray);
|
||||
String formattedJson = JsonWriter.formatJson(jArrayToString);
|
||||
fileWriter.write(formattedJson);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
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<JSONObject> getArrayFromJsonFile() {
|
||||
ArrayList<JSONObject> 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;
|
||||
}
|
||||
return commandObjects;
|
||||
} catch (IOException | ParseException e) {
|
||||
System.out.println("Commands.json尚未初始化!");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void addObjectToCommList(JSONObject jsonObject) {
|
||||
ArrayList<JSONObject> commListCopy = CommandButtons.getMasterCommList();
|
||||
commListCopy.add(jsonObject);
|
||||
CommandButtons.setMasterCommList(commListCopy);
|
||||
}
|
||||
|
||||
public static void removeObject(JSONObject objToRemove) {
|
||||
// get masterCommList and remove object from list
|
||||
ArrayList<JSONObject> commListCopy = CommandButtons.getMasterCommList();
|
||||
commListCopy.remove(objToRemove);
|
||||
|
||||
// get commands.json
|
||||
// remove corresponding button from json
|
||||
removeFromFile(objToRemove);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
166
remappedSrc/com/josyf/commandbuttons/gui/ButtonGUI.java
Normal file
166
remappedSrc/com/josyf/commandbuttons/gui/ButtonGUI.java
Normal file
@ -0,0 +1,166 @@
|
||||
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 net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ButtonGUI extends LightweightGuiDescription {
|
||||
|
||||
int xValue = 0;
|
||||
int yValue = 1;
|
||||
|
||||
public ButtonGUI() {
|
||||
|
||||
// initialize root panel of GUI
|
||||
WGridPanel root = new WGridPanel();
|
||||
setupBackground(root);
|
||||
addCloseButton(root);
|
||||
|
||||
// Add delete toggle button
|
||||
WToggleButton delToggle = new WToggleButton(new TranslatableText("Delete"));
|
||||
root.add(delToggle, 0, 11, 3, 1);
|
||||
|
||||
addSavedButtons(root, delToggle);
|
||||
addCommandSection(root, delToggle);
|
||||
root.validate(this);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
});
|
||||
root.add(button, xValue, yValue, 4, 1);
|
||||
|
||||
// append the buttons to masterList for future loading
|
||||
ConfigFile.addObjectToCommList(newJsonObject);
|
||||
ConfigFile.appendToFile(newJsonObject);
|
||||
|
||||
adjustBounds();
|
||||
}
|
||||
|
||||
name.setText("");
|
||||
command.setText("");
|
||||
|
||||
root.validate(this);
|
||||
|
||||
} else {
|
||||
System.out.println("未输入名称和数值!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 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);
|
||||
} else {
|
||||
CommandButtons.runCommand(command);
|
||||
}
|
||||
|
||||
});
|
||||
root.add(button, xValue, yValue, 4, 1);
|
||||
adjustBounds();
|
||||
root.validate(this);
|
||||
} else {
|
||||
System.out.println("未输入名称和数值!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Array will contain String class types. Convert these to objects.
|
||||
private void addSavedButtons(WGridPanel root, WToggleButton toggle) {
|
||||
ArrayList<JSONObject> 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 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);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.josyf.commandbuttons.gui;
|
||||
|
||||
import io.github.cottonmc.cotton.gui.GuiDescription;
|
||||
import io.github.cottonmc.cotton.gui.client.CottonClientScreen;
|
||||
|
||||
public class ButtonGUIScreen extends CottonClientScreen {
|
||||
public ButtonGUIScreen(GuiDescription description) {
|
||||
super(description);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -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<JSONObject> 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().openScreen(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<String> 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<objects> (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<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,56 +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<JSONObject> getArrayFromJsonFile() {
|
||||
ArrayList<JSONObject> 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);
|
||||
System.out.println(i);
|
||||
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 e) {
|
||||
e.printStackTrace();
|
||||
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<JSONObject> getArrayFromJsonFile() {
|
||||
JSONArray array = getJsonArrayFromFile();
|
||||
if (array == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ArrayList<JSONObject> commandObjects = new ArrayList<>();
|
||||
for (Object obj : array) {
|
||||
if (obj instanceof JSONObject) {
|
||||
commandObjects.add((JSONObject) obj);
|
||||
}
|
||||
}
|
||||
return commandObjects;
|
||||
}
|
||||
|
||||
// 添加
|
||||
public static void addObject(JSONObject jsonObject) {
|
||||
ArrayList<JSONObject> 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<JSONObject> 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<JSONObject> 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);
|
||||
}
|
||||
}
|
||||
|
@ -5,160 +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 net.minecraft.text.TranslatableText;
|
||||
import io.github.cottonmc.cotton.gui.widget.data.HorizontalAlignment;
|
||||
import io.github.cottonmc.cotton.gui.widget.data.VerticalAlignment;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
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);
|
||||
|
||||
// Text GUI, not needed yet
|
||||
// WLabel label = new WLabel(new LiteralText("Test"), 0xFFFFFF);
|
||||
// root.add(label, 0, 4, 2, 1);
|
||||
WLabel title = new WLabel(Text.translatable("gui.commandbuttons.title"), 0xcdcdcd);
|
||||
title.setHorizontalAlignment(HorizontalAlignment.CENTER);
|
||||
root.add(title, 0, 0, 18, 1);
|
||||
|
||||
// Add delete toggle button
|
||||
WToggleButton delToggle = new WToggleButton(new TranslatableText("Delete"));
|
||||
root.add(delToggle, 17, 0, 3, 1);
|
||||
addCloseButton(root);
|
||||
|
||||
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 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);
|
||||
// 背景
|
||||
private void setupBackground(WGridPanel root) {
|
||||
root.setBackgroundPainter(BackgroundPainter.createColorful(0x4D000000));
|
||||
}
|
||||
|
||||
// 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());
|
||||
// 关闭按钮
|
||||
private void addCloseButton(WGridPanel root) {
|
||||
WButton escButton = new WButton(Text.translatable("gui.commandbuttons.close"));
|
||||
escButton.setOnClick(() -> MinecraftClient.getInstance().setScreen(this.parentScreen));
|
||||
root.add(escButton, 17, 0, 1, 1);
|
||||
}
|
||||
|
||||
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<JSONObject> 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<String> 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<JSONObject> 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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
142
src/main/java/com/josyf/commandbuttons/gui/CreateCommandGUI.java
Normal file
142
src/main/java/com/josyf/commandbuttons/gui/CreateCommandGUI.java
Normal file
@ -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<WTextField> 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<String> 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<WWidget> 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;
|
||||
}
|
||||
}
|
168
src/main/java/com/josyf/commandbuttons/gui/EditCommandGUI.java
Normal file
168
src/main/java/com/josyf/commandbuttons/gui/EditCommandGUI.java
Normal file
@ -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<WTextField> 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<String> 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<WWidget> 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;
|
||||
}
|
||||
}
|
18
src/main/resources/assets/mgbuttons/lang/en_us.json
Normal file
18
src/main/resources/assets/mgbuttons/lang/en_us.json
Normal file
@ -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"
|
||||
}
|
18
src/main/resources/assets/mgbuttons/lang/zh_cn.json
Normal file
18
src/main/resources/assets/mgbuttons/lang/zh_cn.json
Normal file
@ -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": "命令"
|
||||
}
|
@ -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.16.x",
|
||||
"minecraft": "1.21.4",
|
||||
"fabric-key-binding-api-v1": "*"
|
||||
},
|
||||
"suggests": {
|
||||
|
Loading…
x
Reference in New Issue
Block a user