├── .build ├── deploy.sh ├── eliorona-sign.asc.gpg └── usrgradle.properties.gpg ├── .github └── workflows │ └── publish.yml ├── .gitignore ├── LICENSE ├── README.md ├── build.gradle ├── common ├── build.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── oroarmor │ │ │ └── config │ │ │ ├── ArrayConfigItem.java │ │ │ ├── BooleanConfigItem.java │ │ │ ├── Config.java │ │ │ ├── ConfigItem.java │ │ │ ├── ConfigItemGroup.java │ │ │ ├── DoubleConfigItem.java │ │ │ ├── EnumConfigItem.java │ │ │ ├── IntegerConfigItem.java │ │ │ ├── StringConfigItem.java │ │ │ ├── command │ │ │ ├── ClientConfigCommand.java │ │ │ ├── ConfigCommand.java │ │ │ └── ConfigItemCommands.java │ │ │ └── screen │ │ │ ├── ConfigScreen.java │ │ │ └── ConfigScreenBuilders.java │ └── resources │ │ └── oro-config_icon.jpg │ └── test │ └── java │ └── com │ └── oroarmor │ └── config │ ├── ConfigItemTest.java │ ├── ConfigTest.java │ ├── EnumTest.java │ └── TestConfig.java ├── fabric-testmod ├── build.gradle └── src │ └── main │ ├── java │ └── com │ │ └── oroarmor │ │ └── config │ │ └── testmod │ │ ├── ColorConfigItem.java │ │ ├── EnumTest.java │ │ ├── ModMenuIntegration.java │ │ ├── OroConfigTestMod.java │ │ ├── OroConfigTestModClient.java │ │ ├── TestConfig.java │ │ └── TestConfigClient.java │ └── resources │ └── fabric.mod.json ├── fabric ├── build.gradle └── src │ └── main │ ├── java │ └── com │ │ └── oroarmor │ │ └── config │ │ ├── command │ │ └── ClientCommandHelper.java │ │ └── screen │ │ └── ModMenuConfigScreen.java │ └── resources │ └── fabric.mod.json ├── forge-testmod ├── build.gradle ├── gradle.properties └── src │ └── main │ ├── java │ └── com │ │ └── oroarmor │ │ └── config │ │ └── testmod │ │ ├── EnumTest.java │ │ ├── OroConfigTestMod.java │ │ └── TestConfig.java │ └── resources │ ├── META-INF │ └── mods.toml │ └── pack.mcmeta ├── forge ├── build.gradle ├── gradle.properties └── src │ └── main │ ├── java │ └── com │ │ └── oroarmor │ │ └── config │ │ └── screen │ │ └── ForgeConfigScreen.java │ └── resources │ └── META-INF │ └── mods.toml ├── gradle.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.build/deploy.sh: -------------------------------------------------------------------------------- 1 | set -euo pipefail 2 | IFS=$'\n\t' 3 | 4 | function cleanup { 5 | echo "🧹 Cleanup..." 6 | rm -f ~/.gradle/gradle.properties eliorona-sign.asc 7 | } 8 | 9 | trap cleanup SIGINT SIGTERM ERR EXIT 10 | 11 | echo "🚀 Preparing to deploy..." 12 | 13 | echo "🔑 Decrypting files..." 14 | 15 | gpg --quiet --batch --yes --decrypt --passphrase="${GPG_SECRET}" \ 16 | --output eliorona-sign.asc .build/eliorona-sign.asc.gpg 17 | 18 | mkdir ~/.gradle 19 | 20 | gpg --quiet --batch --yes --decrypt --passphrase="${GPG_SECRET}" \ 21 | --output ~/.gradle/gradle.properties .build/usrgradle.properties.gpg 22 | 23 | gpg --fast-import --no-tty --batch --yes eliorona-sign.asc 24 | 25 | echo "📦 Publishing..." 26 | 27 | ./gradlew build 28 | ./gradlew uploadArchives -Psign 29 | 30 | echo "✅ Done!" 31 | -------------------------------------------------------------------------------- /.build/eliorona-sign.asc.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OroArmorModding/Oro-Config/3b764d8f266eaeafd41731e11bf4227f7611f3b1/.build/eliorona-sign.asc.gpg -------------------------------------------------------------------------------- /.build/usrgradle.properties.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OroArmorModding/Oro-Config/3b764d8f266eaeafd41731e11bf4227f7611f3b1/.build/usrgradle.properties.gpg -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish to Maven Central 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | publish: 8 | 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v2 13 | - name: Set up JDK 1.8 14 | uses: actions/setup-java@v1 15 | with: 16 | java-version: 1.8 17 | - name: Grant execute permission for gradlew 18 | run: chmod +x gradlew 19 | - name: Grant execute permission for deploy script 20 | run: chmod +x .build/deploy.sh 21 | - name: Deploy with Gradle 22 | run: ./.build/deploy.sh 23 | env: 24 | GPG_SECRET: ${{ secrets.GPG_SECRET }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # gradle 2 | 3 | .gradle/ 4 | build/ 5 | out/ 6 | classes/ 7 | 8 | # eclipse 9 | 10 | *.launch 11 | 12 | # idea 13 | 14 | .idea/ 15 | *.iml 16 | *.ipr 17 | *.iws 18 | 19 | # vscode 20 | 21 | .settings/ 22 | .vscode/ 23 | bin/ 24 | .classpath 25 | .project 26 | 27 | # fabric 28 | 29 | run/ 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 OroArmor (Eli Orona) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Oro-Config 2 | A simple mod config with ModMenu and command integration 3 | 4 | 5 | ## Goal 6 | My goal in creating this library was to make an light-weight config library that feels like the json that you save your code to. Along the way I addded support for commands and ModMenu/ClothConfig screens. 7 | 8 | 9 | ## How to include 10 | Include my library in your mod by adding it to your `build.gradle` file. 11 | 12 | Make sure maven central is included in your repositiories section: 13 | ``` 14 | repositories { 15 | mavenCentral() 16 | } 17 | ``` 18 | 19 | The current version is: ![](https://img.shields.io/github/v/tag/oroarmor/oro-config.svg) 20 | 21 | ### Fabric 22 | 23 | Then in your dependencies section add my library to the classpath and jar-in-jar it so that users don't have to download an extra file: 24 | 25 | ``` 26 | dependencies { 27 | modImplementation 'com.oroarmor:oro-config-fabric:${version}' 28 | include 'com.oroarmor:oro-config-fabric:${version}' 29 | } 30 | ``` 31 | 32 | ### Forge 33 | 34 | Then in your dependencies section add my library to the classpath and shadow it so that users don't have to download an extra file: 35 | 36 | ``` 37 | dependencies { 38 | implementation fg.deobf('com.oroarmor:oro-config-forge:${version}') 39 | shadow 'com.oroarmor:oro-config-forge:${version}' 40 | } 41 | ``` 42 | 43 | ### Outside of minecraft 44 | 45 | Then in your dependencies section add my library to the classpath and shadow it so that users don't have to download an extra file: 46 | 47 | ``` 48 | dependencies { 49 | implemenation 'com.oroarmor:oro-config-common:${version}' 50 | shadow 'com.oroarmor:oro-config-common:${version}' 51 | } 52 | ``` 53 | 54 | ## How to use 55 | The best way to use my config is to extend `com.oroarmor.config.Config` with your own class. Inside this class, you should include other classes that extend `com.oroarmor.config.ConfigItemGroup` for your config groups. See the [example](#example) for a way to use the library. 56 | 57 | ### Config Item 58 | `ConfigItem`s are the main storage of the different values that make up your config. There are two constructors for `ConfigItem`s: 59 | ```java 60 | ConfigItem(String name, T defaultValue, String details) 61 | ``` 62 | and 63 | ```java 64 | ConfigItem(String name, T defaultValue, String details, Consumer> onChange) 65 | ``` 66 | T is the type of data that you are storing in this `ConfigItem`, being one of the supported types. 67 | 68 | The name is for the name of this `ConfigItem`, which is used in the json to identify what the values are used for. 69 | The default value is the value that is normal for the config to use, but is overriden when the config file is read. 70 | The details are a string representing a language key that can be used in your lang file as it is used in both commands and in the Cloth Config support. 71 | 72 | The second constructor has an `onChange` parameter, which is a Consumer that is run every time this config is changed, which can be used to send data to clients on servers or trigger other events. 73 | 74 | You can get the value from a `ConfigItem` with the `getValue` method. 75 | 76 | The library provides `ConfigItem`s for the types `String`, `Double`, `Integer`, `Boolean`, and any `Enum`. `ConfigItem` can be extended for custom value types. Registering an `EntryBuilder` and a `CommandBuilder` in `ConfigScreenBuilders` and `ConfigItemCommands` respectively add them to the config screen and command. 77 | 78 | #### Array Config Items 79 | 80 | `ArrayConfigItem`s are exactly the same as normal config items, but have a couple useful methods to get values based on their index. You cannot nest `ArrayConfigItem`s inside other `ArrayConfigItem`s. The only supported types are `String`, `Double`, `Integer`, `Boolean`, and any `Enum` 81 | 82 | ### Config Item Groups 83 | `ConfigItemGroup`s are a way to store multiple `ConfigItem`s into one group. `ConfigItemGroup`s can be nested in each other for sub groups. There is one constructor: 84 | ```java 85 | ConfigItemGroup(List> configs, String name) 86 | ``` 87 | Configs is for a list of `ConfigItem`s, not needing any type. 88 | Name is for the name of the `ConfigItemGroup`, and is used in the same way as name for `ConfigItem`. 89 | 90 | ### Config 91 | `Config` is the root for your mod config and can read and save to files with just one method. Currently `Config`s only store a list of `ConfigItemGroup`s and a single `ConfigItem` cannot be be stored. Because the file for a config can be defined, there can be configs for the entire mod, per world, and even per dimension (Commands and ClothConfig have only been tested with entire mod examples). `Config`s will auto-initialize themselves and should always be read and then written to (If the config file does not exist when trying to read, it will not crash and will create the file in the write method). This ensures that any user data is read and not overwritten. There is one constructor: 92 | ```java 93 | Config(List configs, File configFile, String id) 94 | ``` 95 | Configs is for the list of `ConfigItemGroup`s 96 | File is for the file to save the config into. 97 | Id is for the ID of the config which is used in commands and modmenu. 98 | 99 | ### Command 100 | `ConfigCommand` is a simple class that just requires a `Config` in its constructor. It does not handle its own registering, and must be registered through Fabric API 101 | 102 | The command is currently broken for forge 103 | 104 | ### Cloth Config 105 | `ModMenuConfigScreen` is an abstract class that requires you to extend it, passing in your config into a super constructor. Because this is used as an entry point, your constructor ***must*** have no parameters. 106 | 107 | ### Forge Config Screen 108 | Currently broken 109 | 110 | ### Example: 111 | These are pulled from the testmod, and are part of this repository. [Test Mod](https://github.com/OroArmor/oro-config/tree/master/fabric-testmod/src/main) 112 | 113 | Config Class: 114 | ```java 115 | public class TestConfig extends Config { 116 | public static final ConfigItemGroup mainGroup = new ConfigGroupLevel1(); 117 | 118 | public static final List configs = of(mainGroup); 119 | 120 | public TestConfig() { 121 | super(configs, new File(FabricLoader.getInstance().getConfigDir().toFile(), "oroarmor_config_testmod.json"), "oroarmor_config_testmod"); 122 | } 123 | 124 | public static class ConfigGroupLevel1 extends ConfigItemGroup { 125 | public static final EnumConfigItem testEnum = new EnumConfigItem<>("test_enum", EnumTest.A, "test_enum"); 126 | public static final BooleanConfigItem testItem = new BooleanConfigItem("test_boolean", true, "test_boolean"); 127 | 128 | public static final ArrayConfigItem testArray = new ArrayConfigItem<>("test_array", new Integer[]{1, 2, 3}, "test_array"); 129 | 130 | public ConfigGroupLevel1() { 131 | super(of(new NestedGroup(), testItem, testEnum, testArray), "group"); 132 | } 133 | 134 | public static class NestedGroup extends ConfigItemGroup { 135 | public static final IntegerConfigItem nestedItem = new IntegerConfigItem("test_int", 0, "test_integer"); 136 | 137 | public NestedGroup() { 138 | super(of(nestedItem, new TripleNested()), "nested"); 139 | } 140 | 141 | public static class TripleNested extends ConfigItemGroup { 142 | public static final StringConfigItem testString = new StringConfigItem("test_string", "Default", "test_string"); 143 | 144 | public TripleNested() { 145 | super(of(testString), "triple"); 146 | } 147 | } 148 | } 149 | } 150 | } 151 | ``` 152 | This then creates a config file called `oroarmor_config_testmod.json` in the `/config/` directory wherever Minecraft is run: 153 | ```json 154 | { 155 | "group": { 156 | "nested": { 157 | "test_int": 0, 158 | "triple": { 159 | "test_string": "Default" 160 | } 161 | }, 162 | "test_boolean": true, 163 | "test_enum": "A", 164 | "test_array": [ 165 | 1, 166 | 2, 167 | 3 168 | ] 169 | } 170 | } 171 | ``` 172 | 173 | Fabric Command Registration: 174 | ```java 175 | CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) -> new ConfigCommand(YOUR_CONFIG).register(dispatcher, p -> p.hasPermissionLevel(2))); 176 | ``` 177 | 178 | Mod Menu Integration: 179 | ```java 180 | public class ModMenuIntegration extends ModMenuConfigScreen { 181 | public ModMenuIntegration() { 182 | super(OroConfigTestMod.CONFIG); 183 | } 184 | } 185 | ``` 186 | 187 | Entry point: 188 | ```json 189 | "entrypoints": { 190 | "main": ["com.oroarmor.config.testmod.OroConfigTestMod"], 191 | "modmenu": ["com.oroarmor.config.testmod.ModMenuIntegration"] 192 | } 193 | ``` 194 | 195 | 196 | 197 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "java" 3 | id "architectury-plugin" version "3.4-SNAPSHOT" 4 | id "dev.architectury.loom" version "1.1-SNAPSHOT" apply false 5 | } 6 | 7 | architectury { 8 | minecraft = rootProject.minecraft_version 9 | } 10 | 11 | subprojects { 12 | apply plugin: "dev.architectury.loom" 13 | 14 | loom { 15 | silentMojangMappingsLicense() 16 | } 17 | 18 | dependencies { 19 | minecraft "com.mojang:minecraft:${rootProject.minecraft_version}" 20 | mappings "net.fabricmc:yarn:1.20.1+build.8:v2" 21 | } 22 | 23 | } 24 | 25 | allprojects { 26 | apply plugin: "java" 27 | apply plugin: "architectury-plugin" 28 | 29 | archivesBaseName = rootProject.archives_base_name 30 | version = rootProject.mod_version 31 | group = rootProject.maven_group 32 | 33 | repositories { 34 | maven { 35 | url "https://maven.fabricmc.net/" 36 | } 37 | } 38 | tasks.withType(JavaCompile) { 39 | options.encoding = "UTF-8" 40 | options.release = 17 41 | } 42 | 43 | java { 44 | withSourcesJar() 45 | } 46 | } -------------------------------------------------------------------------------- /common/build.gradle: -------------------------------------------------------------------------------- 1 | repositories { 2 | maven { url 'https://maven.kosmx.dev/' } 3 | maven { url 'https://maven.shedaniel.me/' } 4 | maven { url 'https://maven.fabricmc.net/' } 5 | maven { url 'https://jitpack.io' } 6 | maven { url 'https://maven.terraformersmc.com/' } 7 | maven { url 'https://www.cursemaven.com' } 8 | maven { 9 | name = 'Modrinth' 10 | url = 'https://api.modrinth.com/maven' 11 | content { 12 | includeGroup 'maven.modrinth' 13 | } 14 | } 15 | 16 | } 17 | 18 | loom { 19 | } 20 | 21 | dependencies { 22 | modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" 23 | testImplementation 'junit:junit:4.13.1' 24 | modApi "dev.architectury:architectury:${rootProject.architectury_version}" 25 | 26 | modApi("me.shedaniel.cloth:cloth-config-fabric:${rootProject.cloth_config_version}") { 27 | exclude(group: "net.fabricmc.fabric-api") 28 | } 29 | } 30 | 31 | architectury { 32 | common() 33 | } 34 | 35 | archivesBaseName = rootProject.archives_base_name + "-common" 36 | version = rootProject.mod_version 37 | group = rootProject.maven_group 38 | 39 | /* 40 | publishing { 41 | publications { 42 | mavenCommon(MavenPublication) { 43 | artifactId = rootProject.archives_base_name + "-" + project.name 44 | // add all the jars that should be included when publishing to maven 45 | artifact(jar) { 46 | classifier null 47 | } 48 | artifact(sourcesJar) { 49 | builtBy remapSourcesJar 50 | } 51 | artifact(javadocJar) { 52 | builtBy javadocJar 53 | } 54 | } 55 | } 56 | 57 | // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. 58 | repositories { 59 | // Add repositories to publish to here. 60 | } 61 | } 62 | 63 | */ 64 | -------------------------------------------------------------------------------- /common/src/main/java/com/oroarmor/config/ArrayConfigItem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config; 26 | 27 | import java.util.Arrays; 28 | import java.util.function.Consumer; 29 | import java.util.stream.Collectors; 30 | 31 | import com.google.gson.JsonArray; 32 | import com.google.gson.JsonElement; 33 | import com.google.gson.JsonObject; 34 | import com.google.gson.JsonPrimitive; 35 | import org.jetbrains.annotations.Nullable; 36 | 37 | 38 | /** 39 | * {@link ArrayConfigItem} stores an array of the supported types
40 | * The current supported types are booleans, integers, doubles, strings, and 41 | * {@link ConfigItemGroup} 42 | * 43 | * @param 44 | * @author Eli Orona 45 | */ 46 | public class ArrayConfigItem extends ConfigItem { 47 | 48 | /** 49 | * Creates a new config with the name, defaultValue, and details 50 | * 51 | * @param name The name for the config item 52 | * @param defaultValue The default value in case of a corrupted/missing config 53 | * @param details A translatable string for readability in multiple 54 | * languages 55 | */ 56 | public ArrayConfigItem(String name, T[] defaultValue, String details) { 57 | this(name, defaultValue, details, null); 58 | } 59 | 60 | /** 61 | * Creates a new config with the name, defaultValue, details, and an onChange 62 | * consumer 63 | * 64 | * @param name The name for the config item 65 | * @param defaultValue The default value in case of a corrupted/missing config 66 | * @param details A translatable string for readability in multiple 67 | * languages 68 | * @param onChange A {@link Consumer} that is run every time the config item 69 | * is modified 70 | */ 71 | public ArrayConfigItem(String name, T[] defaultValue, String details, @Nullable Consumer> onChange) { 72 | super(name, defaultValue, details, onChange); 73 | if (defaultValue[0] instanceof ArrayConfigItem) { 74 | throw new UnsupportedOperationException("ArrayConfigItems cannot be nested"); 75 | } 76 | this.value = Arrays.copyOf(defaultValue, defaultValue.length); 77 | } 78 | 79 | @SuppressWarnings("unchecked") 80 | public void fromJson(JsonElement element) { 81 | for (int i = 0; i < element.getAsJsonArray().size(); i++) { 82 | T newValue; 83 | JsonElement arrayElement = element.getAsJsonArray().get(i); 84 | switch (defaultValue[0].getClass().isEnum() ? "ENUM" : defaultValue[0].getClass().getSimpleName().toUpperCase()) { 85 | case "BOOLEAN": 86 | newValue = (T) (Object) arrayElement.getAsBoolean(); 87 | break; 88 | 89 | case "INTEGER": 90 | newValue = (T) (Object) arrayElement.getAsInt(); 91 | break; 92 | 93 | case "DOUBLE": 94 | newValue = (T) (Object) arrayElement.getAsDouble(); 95 | break; 96 | 97 | case "STRING": 98 | newValue = (T) arrayElement.getAsString(); 99 | break; 100 | 101 | case "ENUM": 102 | newValue = (T) Arrays.stream(((T) defaultValue[i]).getClass().getEnumConstants()).filter(val -> val.toString().equals(arrayElement.getAsString())).findFirst().get(); 103 | break; 104 | 105 | default: 106 | return; 107 | } 108 | value[i] = newValue; 109 | } 110 | if (value != null) { 111 | setValue(value); 112 | } 113 | } 114 | 115 | @Override 116 | public void toJson(JsonObject object) { 117 | JsonArray array = new JsonArray(); 118 | for (T t : value) { 119 | JsonElement element; 120 | switch (defaultValue[0].getClass().isEnum() ? "ENUM" : defaultValue[0].getClass().getSimpleName().toUpperCase()) { 121 | case "BOOLEAN": 122 | element = new JsonPrimitive((Boolean) t); 123 | break; 124 | 125 | case "INTEGER": 126 | case "DOUBLE": 127 | element = new JsonPrimitive((Number) t); 128 | break; 129 | 130 | case "STRING": 131 | element = new JsonPrimitive((String) t); 132 | break; 133 | 134 | case "ENUM": 135 | element = new JsonPrimitive(t.toString()); 136 | break; 137 | 138 | default: 139 | return; 140 | } 141 | 142 | array.add(element); 143 | } 144 | 145 | object.add(this.name, array); 146 | } 147 | 148 | @Override 149 | public boolean atDefaultValue() { 150 | return Arrays.equals(defaultValue, value); 151 | } 152 | 153 | @Override 154 | public boolean isValidType(Class clazz) { 155 | return clazz == defaultValue[0].getClass(); 156 | } 157 | 158 | @Override 159 | public String getCommandValue() { 160 | return Arrays.stream(this.value).map(Object::toString).collect(Collectors.joining(",")); 161 | } 162 | 163 | @Override 164 | public String getCommandDefaultValue() { 165 | return Arrays.stream(this.defaultValue).map(Object::toString).collect(Collectors.joining(",")); 166 | } 167 | 168 | /** 169 | * @param position The position in the array for the value 170 | * @return The default value of the {@link ConfigItem} 171 | */ 172 | public T getDefaultValue(int position) { 173 | return this.defaultValue[position]; 174 | } 175 | 176 | /** 177 | * @param position The position in the array for the value 178 | * @return The current value of the {@link ConfigItem} 179 | */ 180 | public T getValue(int position) { 181 | return this.value[position]; 182 | } 183 | 184 | /** 185 | * Sets the value in {@code position} the {@link ArrayConfigItem} 186 | * 187 | * @param value The value to set 188 | * @param position The position in the array for the value 189 | */ 190 | public void setValue(T value, int position) { 191 | this.value[position] = value; 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /common/src/main/java/com/oroarmor/config/BooleanConfigItem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config; 26 | 27 | import java.util.function.Consumer; 28 | 29 | import com.google.gson.JsonElement; 30 | import com.google.gson.JsonObject; 31 | import org.jetbrains.annotations.Nullable; 32 | 33 | /** 34 | * A Config item for booleans 35 | */ 36 | public class BooleanConfigItem extends ConfigItem { 37 | public BooleanConfigItem(String name, Boolean defaultValue, String details) { 38 | super(name, defaultValue, details); 39 | } 40 | 41 | public BooleanConfigItem(String name, Boolean defaultValue, String details, @Nullable Consumer> onChange) { 42 | super(name, defaultValue, details, onChange); 43 | } 44 | 45 | @Override 46 | public void fromJson(JsonElement element) { 47 | this.value = element.getAsBoolean(); 48 | } 49 | 50 | @Override 51 | public void toJson(JsonObject object) { 52 | object.addProperty(this.name, this.value); 53 | } 54 | 55 | @Override 56 | public boolean isValidType(Class clazz) { 57 | return clazz == Boolean.class; 58 | } 59 | 60 | @Override 61 | public String getCommandValue() { 62 | return this.value.toString(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /common/src/main/java/com/oroarmor/config/Config.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config; 26 | 27 | import java.io.File; 28 | import java.io.FileInputStream; 29 | import java.io.FileNotFoundException; 30 | import java.io.FileOutputStream; 31 | import java.util.Arrays; 32 | import java.util.LinkedList; 33 | import java.util.List; 34 | import java.util.NoSuchElementException; 35 | import java.util.stream.Collectors; 36 | 37 | import com.google.gson.Gson; 38 | import com.google.gson.GsonBuilder; 39 | import com.google.gson.JsonObject; 40 | import com.google.gson.JsonParser; 41 | 42 | /** 43 | * Config is a holder class for a list of {@link ConfigItemGroup}. It's main 44 | * feature is to save and read from a file. 45 | * 46 | * @author Eli Orona 47 | */ 48 | public class Config { 49 | /** 50 | * The GSON formatter for the Config 51 | */ 52 | private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); 53 | 54 | /** 55 | * The list of ConfigItemGroups for the config 56 | */ 57 | private final List configs; 58 | 59 | /** 60 | * The file to save and read the config from 61 | */ 62 | private final File configFile; 63 | 64 | /** 65 | * The ID (often the mod id) for the config 66 | */ 67 | private final String id; 68 | 69 | /** 70 | * Creates a new config 71 | * 72 | * @param configs The list of {@link ConfigItemGroup} for the config 73 | * @param configFile The file to read and save from 74 | * @param id The id of the config, should be the mod id 75 | */ 76 | public Config(List configs, File configFile, String id) { 77 | this.configs = configs; 78 | this.configFile = configFile; 79 | this.id = id; 80 | } 81 | 82 | /** 83 | * @return The list of {@link ConfigItemGroup} for this config 84 | */ 85 | public List getConfigs() { 86 | return configs; 87 | } 88 | 89 | /** 90 | * Reads the config from the file. If any changes are made and not saved this 91 | * will overwrite them. 92 | */ 93 | public void readConfigFromFile() { 94 | try (FileInputStream stream = new FileInputStream(configFile)) { 95 | byte[] bytes = new byte[stream.available()]; 96 | stream.read(bytes); 97 | String file = new String(bytes); 98 | JsonObject parsed = new JsonParser().parse(file).getAsJsonObject(); 99 | for (ConfigItemGroup cig : configs) { 100 | cig.fromJson(parsed.get(cig.getName())); 101 | } 102 | } catch (FileNotFoundException e) { 103 | saveConfigToFile(); 104 | } catch (Exception e) { 105 | e.printStackTrace(); 106 | } 107 | 108 | } 109 | 110 | /** 111 | * Gets a the value at path 112 | * 113 | * @param path The path to search 114 | * @param clazz The class of the type to get 115 | * @param The type to get 116 | * @return The value if it exists 117 | */ 118 | @SuppressWarnings("unchecked") 119 | public T getValue(String path, Class clazz) { 120 | String[] splitPath = path.split("\\."); 121 | 122 | ConfigItem selectedItem = getConfigs().stream().filter(cig -> cig.name.equals(splitPath[0])).findFirst().get(); 123 | try { 124 | LinkedList paths = new LinkedList<>(Arrays.asList(splitPath)); 125 | while (selectedItem instanceof ConfigItemGroup) { 126 | paths.removeFirst(); 127 | selectedItem = ((ConfigItemGroup) selectedItem).getConfigs().stream().filter(ci -> ci.name.equals(paths.getFirst())).findFirst().get(); 128 | } 129 | } catch (NoSuchElementException e) { 130 | System.err.printf("Path: %s does not exist\n", path); 131 | return null; 132 | } 133 | 134 | if (!selectedItem.isValidType(clazz)) { 135 | throw new IllegalArgumentException("Incorrect type " + clazz.getName() + " for " + path + ". Correct class is " + selectedItem.getValue().getClass().getSimpleName()); 136 | } 137 | 138 | return ((ConfigItem) selectedItem).getValue(); 139 | } 140 | 141 | /** 142 | * Saves the current config to the file. 143 | */ 144 | public void saveConfigToFile() { 145 | JsonObject object = new JsonObject(); 146 | for (ConfigItemGroup c : configs) { 147 | c.toJson(object); 148 | } 149 | 150 | try (FileOutputStream stream = new FileOutputStream(configFile)) { 151 | stream.write(GSON.toJson(object).getBytes()); 152 | } catch (Exception e) { 153 | e.printStackTrace(); 154 | } 155 | } 156 | 157 | /** 158 | * Returns a string representation of the config and all the sub configs 159 | */ 160 | @Override 161 | public String toString() { 162 | return configFile.getName() + ": [" + configs.stream().map(Object::toString).collect(Collectors.joining(", ")) + "]"; 163 | } 164 | 165 | /** 166 | * @return The id of the config 167 | */ 168 | public String getID() { 169 | return id; 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /common/src/main/java/com/oroarmor/config/ConfigItem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config; 26 | 27 | import java.util.function.Consumer; 28 | 29 | import com.google.gson.JsonElement; 30 | import com.google.gson.JsonObject; 31 | import org.jetbrains.annotations.Nullable; 32 | 33 | /** 34 | * {@link ConfigItem} often stores a name and a value for saving data into a 35 | * config.
36 | * The current supported types are booleans, integers, doubles, strings, and 37 | * {@link ConfigItemGroup} 38 | * 39 | * @param 40 | * @author Eli Orona 41 | */ 42 | public abstract class ConfigItem { 43 | protected final String name; 44 | protected final String details; 45 | protected final T defaultValue; 46 | @Nullable 47 | protected final Consumer> onChange; 48 | protected T value; 49 | 50 | /** 51 | * Creates a new config with the name, defaultValue, and details 52 | * 53 | * @param name The name for the config item 54 | * @param defaultValue The default value in case of a corrupted/missing config 55 | * @param details A translatable string for readability in multiple 56 | * languages 57 | */ 58 | public ConfigItem(String name, T defaultValue, String details) { 59 | this(name, defaultValue, details, null); 60 | } 61 | 62 | /** 63 | * Creates a new config with the name, defaultValue, details, and an onChange 64 | * consumer 65 | * 66 | * @param name The name for the config item 67 | * @param defaultValue The default value in case of a corrupted/missing config 68 | * @param details A translatable string for readability in multiple 69 | * languages 70 | * @param onChange A {@link Consumer} that is run every time the config item 71 | * is modified 72 | */ 73 | public ConfigItem(String name, T defaultValue, String details, @Nullable Consumer> onChange) { 74 | this.name = name; 75 | this.details = details; 76 | this.defaultValue = defaultValue; 77 | this.value = defaultValue; 78 | this.onChange = onChange; 79 | } 80 | 81 | /** 82 | * Reads and sets the {@link ConfigItem} from a JSON Element. Will throw an 83 | * error if the type does not match the type of the {@link ConfigItem} 84 | * 85 | * @param element The JSON Element 86 | */ 87 | public abstract void fromJson(JsonElement element); 88 | 89 | /** 90 | * Writes self to the json object 91 | * 92 | * @param object The object to write to 93 | */ 94 | public abstract void toJson(JsonObject object); 95 | 96 | /** 97 | * @return The default value of the {@link ConfigItem} 98 | */ 99 | public T getDefaultValue() { 100 | return defaultValue; 101 | } 102 | 103 | /** 104 | * @return The detail string of the {@link ConfigItem} 105 | */ 106 | public String getDetails() { 107 | return details; 108 | } 109 | 110 | /** 111 | * @return the name of the {@link ConfigItem} 112 | */ 113 | public String getName() { 114 | return name; 115 | } 116 | 117 | /** 118 | * @return The current value of the {@link ConfigItem} 119 | */ 120 | public T getValue() { 121 | return value; 122 | } 123 | 124 | /** 125 | * Sets the value of the {@link ConfigItem} 126 | * 127 | * @param value The value to set 128 | */ 129 | public void setValue(T value) { 130 | this.value = value; 131 | if (this.onChange != null) { 132 | this.onChange.accept(this); 133 | } 134 | } 135 | 136 | @Override 137 | public String toString() { 138 | return name + ":" + value; 139 | } 140 | 141 | /** 142 | * Returns true if the the class is validd 143 | * 144 | * @param clazz The class to check 145 | * @param 146 | * @return True if the type is validd 147 | */ 148 | public abstract boolean isValidType(Class clazz); 149 | 150 | /** 151 | * A string value to show in commands 152 | * 153 | * @return 154 | */ 155 | public String getCommandValue() { 156 | return this.value.toString(); 157 | } 158 | 159 | /** 160 | * @return True if the config item is at its default value 161 | */ 162 | public boolean atDefaultValue() { 163 | return this.value.equals(this.defaultValue); 164 | } 165 | 166 | /** 167 | * A string value for the default value to show in commands 168 | * 169 | * @return 170 | */ 171 | public String getCommandDefaultValue() { 172 | return this.defaultValue.toString(); 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /common/src/main/java/com/oroarmor/config/ConfigItemGroup.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config; 26 | 27 | import java.util.ArrayList; 28 | import java.util.List; 29 | import java.util.Map.Entry; 30 | import java.util.StringJoiner; 31 | 32 | import com.google.gson.JsonElement; 33 | import com.google.gson.JsonObject; 34 | 35 | /** 36 | * Extending {@link ConfigItem}, {@link ConfigItemGroup} can store multiple 37 | * {@link ConfigItem}s 38 | * 39 | * @author Eli Orona 40 | */ 41 | public class ConfigItemGroup extends ConfigItem> { 42 | 43 | /** 44 | * The list of {@link ConfigItem} 45 | */ 46 | private final List> configs; 47 | 48 | /** 49 | * BAD CONSTRUCTOR ONLY FOR DEFAULT VALUE. DO NOT USE 50 | */ 51 | private ConfigItemGroup() { 52 | super(null, null, null); 53 | configs = new ArrayList<>(); 54 | } 55 | 56 | /** 57 | * Creates a new {@link ConfigItemGroup} with the list of configs and the name 58 | * 59 | * @param configs The list of configs 60 | * @param name The name of this group 61 | */ 62 | public ConfigItemGroup(List> configs, String name) { 63 | super(name, new ConfigItemGroup(), ""); 64 | this.configs = configs; 65 | } 66 | 67 | @Override 68 | public void fromJson(JsonElement jsonConfigs) { 69 | JsonObject object = jsonConfigs.getAsJsonObject(); 70 | for (Entry entry : object.entrySet()) { 71 | for (ConfigItem c : configs) { 72 | if (c.getName().equals(entry.getKey())) { 73 | c.fromJson(entry.getValue()); 74 | } 75 | } 76 | } 77 | } 78 | 79 | /** 80 | * @return The configs for this group 81 | */ 82 | public List> getConfigs() { 83 | return configs; 84 | } 85 | 86 | /** 87 | * Converts the config items into json 88 | */ 89 | @Override 90 | public void toJson(JsonObject superObject) { 91 | JsonObject object = new JsonObject(); 92 | 93 | for (ConfigItem c : configs) { 94 | c.toJson(object); 95 | } 96 | 97 | superObject.add(this.getName(), object); 98 | } 99 | 100 | @Override 101 | public String toString() { 102 | String string = getName() + ": ["; 103 | StringJoiner joiner = new StringJoiner(", "); 104 | for (ConfigItem config : configs) { 105 | String toString = config.toString(); 106 | joiner.add(toString); 107 | } 108 | string += joiner.toString(); 109 | return string + "]"; 110 | } 111 | 112 | @Override 113 | public boolean isValidType(Class clazz) { 114 | return clazz == this.getClass(); 115 | } 116 | 117 | @Override 118 | public String getCommandValue() { 119 | return null; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /common/src/main/java/com/oroarmor/config/DoubleConfigItem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config; 26 | 27 | import java.util.function.Consumer; 28 | 29 | import com.google.gson.JsonElement; 30 | import com.google.gson.JsonObject; 31 | import org.jetbrains.annotations.Nullable; 32 | 33 | /** 34 | * A Config item for doubles 35 | */ 36 | public class DoubleConfigItem extends ConfigItem { 37 | protected double min = Double.MIN_VALUE; 38 | protected double max = Double.MAX_VALUE; 39 | 40 | public DoubleConfigItem(String name, Double defaultValue, String details) { 41 | super(name, defaultValue, details); 42 | } 43 | 44 | public DoubleConfigItem(String name, Double defaultValue, String details, @Nullable Consumer> onChange) { 45 | super(name, defaultValue, details, onChange); 46 | } 47 | 48 | public DoubleConfigItem(String name, Double defaultValue, String details, @Nullable Consumer> onChange, double max) { 49 | super(name, defaultValue, details, onChange); 50 | this.max = max; 51 | } 52 | 53 | public DoubleConfigItem(String name, Double defaultValue, String details, @Nullable Consumer> onChange, double min, double max) { 54 | super(name, defaultValue, details, onChange); 55 | this.min = min; 56 | this.max = max; 57 | } 58 | 59 | @Override 60 | public void fromJson(JsonElement element) { 61 | this.value = element.getAsDouble(); 62 | } 63 | 64 | @Override 65 | public void toJson(JsonObject object) { 66 | object.addProperty(this.name, this.value); 67 | } 68 | 69 | @Override 70 | public boolean isValidType(Class clazz) { 71 | return clazz == Double.class; 72 | } 73 | 74 | @Override 75 | public void setValue(Double value) { 76 | super.setValue(Double.max(Double.min(value, max), min)); 77 | } 78 | 79 | @Override 80 | public String getCommandValue() { 81 | return this.value.toString(); 82 | } 83 | 84 | /** 85 | * The max value for the config 86 | * 87 | * @return max 88 | */ 89 | public double getMin() { 90 | return min; 91 | } 92 | 93 | /** 94 | * The min value for the config 95 | * 96 | * @return min 97 | */ 98 | public double getMax() { 99 | return max; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /common/src/main/java/com/oroarmor/config/EnumConfigItem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config; 26 | 27 | import java.util.Arrays; 28 | import java.util.function.Consumer; 29 | 30 | import com.google.gson.JsonElement; 31 | import com.google.gson.JsonObject; 32 | import org.jetbrains.annotations.Nullable; 33 | 34 | /** 35 | * A Config item for enums 36 | */ 37 | public class EnumConfigItem> extends ConfigItem { 38 | public EnumConfigItem(String name, T defaultValue, String details) { 39 | super(name, defaultValue, details); 40 | } 41 | 42 | public EnumConfigItem(String name, T defaultValue, String details, @Nullable Consumer> onChange) { 43 | super(name, defaultValue, details, onChange); 44 | } 45 | 46 | @Override 47 | @SuppressWarnings("unchecked") 48 | public void fromJson(JsonElement element) { 49 | this.value = (T) Arrays.stream(((T) defaultValue).getClass().getEnumConstants()).filter(val -> val.toString().equals(element.getAsString())).findFirst().get(); 50 | } 51 | 52 | @Override 53 | public void toJson(JsonObject object) { 54 | object.addProperty(this.name, this.value.toString()); 55 | } 56 | 57 | @Override 58 | public boolean isValidType(Class clazz) { 59 | return clazz == defaultValue.getClass(); 60 | } 61 | 62 | @Override 63 | public String getCommandValue() { 64 | return this.value.toString(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /common/src/main/java/com/oroarmor/config/IntegerConfigItem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config; 26 | 27 | import java.util.function.Consumer; 28 | 29 | import com.google.gson.JsonElement; 30 | import com.google.gson.JsonObject; 31 | import org.jetbrains.annotations.Nullable; 32 | 33 | /** 34 | * A Config item for integers 35 | */ 36 | public class IntegerConfigItem extends ConfigItem { 37 | protected int min = Integer.MIN_VALUE; 38 | protected int max = Integer.MAX_VALUE; 39 | 40 | public IntegerConfigItem(String name, Integer defaultValue, String details) { 41 | super(name, defaultValue, details); 42 | } 43 | 44 | public IntegerConfigItem(String name, Integer defaultValue, String details, @Nullable Consumer> onChange) { 45 | super(name, defaultValue, details, onChange); 46 | } 47 | 48 | public IntegerConfigItem(String name, Integer defaultValue, String details, @Nullable Consumer> onChange, int max) { 49 | super(name, defaultValue, details, onChange); 50 | this.max = max; 51 | } 52 | 53 | public IntegerConfigItem(String name, Integer defaultValue, String details, @Nullable Consumer> onChange, int min, int max) { 54 | super(name, defaultValue, details, onChange); 55 | this.min = min; 56 | this.max = max; 57 | } 58 | 59 | @Override 60 | public void fromJson(JsonElement element) { 61 | this.value = element.getAsInt(); 62 | } 63 | 64 | @Override 65 | public void toJson(JsonObject object) { 66 | object.addProperty(this.name, this.value); 67 | } 68 | 69 | @Override 70 | public boolean isValidType(Class clazz) { 71 | return clazz == Integer.class; 72 | } 73 | 74 | @Override 75 | public void setValue(Integer value) { 76 | super.setValue(Integer.max(Integer.min(value, max), min)); 77 | } 78 | 79 | @Override 80 | public String getCommandValue() { 81 | return this.value.toString(); 82 | } 83 | 84 | /** 85 | * The min value for the config 86 | * 87 | * @return min 88 | */ 89 | public int getMin() { 90 | return min; 91 | } 92 | 93 | /** 94 | * The max value for the config 95 | * 96 | * @return max 97 | */ 98 | public int getMax() { 99 | return max; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /common/src/main/java/com/oroarmor/config/StringConfigItem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config; 26 | 27 | import java.util.function.Consumer; 28 | 29 | import com.google.gson.JsonElement; 30 | import com.google.gson.JsonObject; 31 | import org.jetbrains.annotations.Nullable; 32 | 33 | /** 34 | * A Config item for strings 35 | */ 36 | public class StringConfigItem extends ConfigItem { 37 | public StringConfigItem(String name, String defaultValue, String details) { 38 | super(name, defaultValue, details); 39 | } 40 | 41 | public StringConfigItem(String name, String defaultValue, String details, @Nullable Consumer> onChange) { 42 | super(name, defaultValue, details, onChange); 43 | } 44 | 45 | @Override 46 | public void fromJson(JsonElement element) { 47 | this.value = element.getAsString(); 48 | } 49 | 50 | @Override 51 | public void toJson(JsonObject object) { 52 | object.addProperty(this.name, this.value); 53 | } 54 | 55 | @Override 56 | public boolean isValidType(Class clazz) { 57 | return clazz == String.class; 58 | } 59 | 60 | @Override 61 | public String getCommandValue() { 62 | return this.value; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /common/src/main/java/com/oroarmor/config/command/ClientConfigCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config.command; 26 | 27 | import java.util.function.Predicate; 28 | 29 | import com.mojang.brigadier.CommandDispatcher; 30 | import com.mojang.brigadier.builder.LiteralArgumentBuilder; 31 | import com.oroarmor.config.Config; 32 | import com.oroarmor.config.ConfigItemGroup; 33 | 34 | import com.oroarmor.config.screen.ConfigScreen; 35 | import dev.architectury.platform.Platform; 36 | import net.minecraft.client.MinecraftClient; 37 | import net.minecraft.client.gui.screen.Screen; 38 | import net.minecraft.command.CommandSource; 39 | 40 | /** 41 | * A way to add client only commands for your config 42 | * 43 | * @param A client command source 44 | */ 45 | public class ClientConfigCommand extends ConfigCommand { 46 | public static Screen openScreen; 47 | 48 | /** 49 | * Creates a new ConfigCommand with the config 50 | * 51 | * @param config The config 52 | */ 53 | public ClientConfigCommand(Config config) { 54 | super(config); 55 | 56 | } 57 | 58 | @Override 59 | public void register(CommandDispatcher dispatcher, Predicate usable) { 60 | LiteralArgumentBuilder literalArgumentBuilder = LiteralArgumentBuilder.literal(config.getID()).requires(usable).executes(this::listConfigGroups); 61 | 62 | for (ConfigItemGroup group : config.getConfigs()) { 63 | parseConfigItemGroupCommand(literalArgumentBuilder, group); 64 | } 65 | 66 | literalArgumentBuilder.then(LiteralArgumentBuilder.literal("gui").executes(context -> { 67 | if(Platform.isModLoaded("cloth-config")){ 68 | openScreen = new ConfigScreen(config) { 69 | }.createScreen(MinecraftClient.getInstance().currentScreen); 70 | return 1; 71 | } 72 | return 0; 73 | })); 74 | 75 | dispatcher.register(literalArgumentBuilder); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /common/src/main/java/com/oroarmor/config/command/ConfigCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config.command; 26 | 27 | import java.util.function.Predicate; 28 | 29 | import com.mojang.brigadier.CommandDispatcher; 30 | import com.mojang.brigadier.builder.ArgumentBuilder; 31 | import com.mojang.brigadier.builder.LiteralArgumentBuilder; 32 | import com.mojang.brigadier.context.CommandContext; 33 | import com.mojang.brigadier.exceptions.CommandSyntaxException; 34 | import com.oroarmor.config.Config; 35 | import com.oroarmor.config.ConfigItem; 36 | import com.oroarmor.config.ConfigItemGroup; 37 | 38 | import net.minecraft.client.MinecraftClient; 39 | import net.minecraft.client.resource.language.I18n; 40 | import net.minecraft.command.CommandSource; 41 | import net.minecraft.network.message.MessageType; 42 | import net.minecraft.server.command.ServerCommandSource; 43 | import net.minecraft.text.HoverEvent; 44 | import net.minecraft.text.HoverEvent.Action; 45 | import net.minecraft.text.MutableText; 46 | import net.minecraft.text.Text; 47 | import net.minecraft.util.Formatting; 48 | import net.minecraft.util.Util; 49 | 50 | /** 51 | * Creates a com.oroarmor.config.command register callback that is based of of a config.
52 | *
53 | * Register with: 54 | * CommandRegistrationCallback.EVENT.register(new ConfigCommand(yourConfigInstance)); 55 | * 56 | * @author Eli Orona 57 | */ 58 | public class ConfigCommand { 59 | 60 | /** 61 | * The config 62 | */ 63 | protected final Config config; 64 | 65 | /** 66 | * Creates a new ConfigCommand with the config 67 | * 68 | * @param config The config 69 | */ 70 | public ConfigCommand(Config config) { 71 | this.config = config; 72 | } 73 | 74 | protected MutableText createItemText(ConfigItem item) { 75 | MutableText configListText = Text.literal(""); 76 | configListText.append(Text.literal("[" + I18n.translate(item.getDetails()) + "]")); 77 | configListText.append(" : "); 78 | configListText.append(Text.literal("[" + item.getCommandValue() + "]") 79 | .formatted(item.atDefaultValue() ? Formatting.GREEN : Formatting.DARK_GREEN) 80 | .styled(s -> s.withHoverEvent(new HoverEvent(Action.SHOW_TEXT, Text.literal((item.atDefaultValue() ? "At Default " : "") + "Value: " + (item.atDefaultValue() ? item.getCommandDefaultValue() : item.getCommandValue())))))); 81 | return configListText; 82 | } 83 | 84 | protected int listConfigGroup(CommandContext c, ConfigItemGroup group) { 85 | MutableText configList = Text.literal(""); 86 | 87 | configList.append(Text.literal(group.getName() + "\n").formatted(Formatting.BOLD)); 88 | for (ConfigItem item : group.getConfigs()) 89 | parseConfigItemText(configList, item, " "); 90 | 91 | configList.append("/"); 92 | 93 | try { 94 | sendFeedback(c, configList); 95 | } catch (CommandSyntaxException e) { 96 | e.printStackTrace(); 97 | } 98 | 99 | return 1; 100 | } 101 | 102 | protected int listConfigGroups(CommandContext c) { 103 | MutableText configList = Text.literal(""); 104 | 105 | for (ConfigItemGroup group : config.getConfigs()) { 106 | configList.append(Text.literal(group.getName() + "\n").formatted(Formatting.BOLD)); 107 | for (ConfigItem item : group.getConfigs()) { 108 | parseConfigItemText(configList, item, " "); 109 | } 110 | configList.append("/"); 111 | } 112 | 113 | try { 114 | sendFeedback(c, configList); 115 | } catch (CommandSyntaxException e) { 116 | e.printStackTrace(); 117 | } 118 | 119 | return 1; 120 | } 121 | 122 | protected void parseConfigItemText(MutableText configList, ConfigItem item, String padding) { 123 | configList.append(padding); 124 | configList.append("|--> "); 125 | if (item instanceof ConfigItemGroup) { 126 | configList.append(Text.literal(item.getName() + "\n").formatted(Formatting.BOLD)); 127 | for (ConfigItem item2 : ((ConfigItemGroup) item).getConfigs()) { 128 | parseConfigItemText(configList, item2, padding + "| "); 129 | } 130 | configList.append(padding + "/\n"); 131 | } else { 132 | configList.append(createItemText(item)); 133 | configList.append("\n"); 134 | } 135 | } 136 | 137 | protected int listItem(CommandContext c, ConfigItem item) { 138 | try { 139 | Text text = createItemText(item); 140 | sendFeedback(c, text); 141 | } catch (CommandSyntaxException e) { 142 | e.printStackTrace(); 143 | } 144 | 145 | return 1; 146 | } 147 | 148 | private void sendFeedback(CommandContext c, Text text) throws CommandSyntaxException { 149 | if (c.getSource() instanceof ServerCommandSource) { 150 | ((ServerCommandSource) c.getSource()).getPlayer().sendMessage(text, false); 151 | } else if (c.getSource().getClass().getSimpleName().toLowerCase().contains("client")) { 152 | MinecraftClient.getInstance().player.sendMessage(text, false); 153 | } 154 | } 155 | 156 | /** 157 | * Registers the command to the dispatcher 158 | * 159 | * @param dispatcher The dispatcher 160 | * @param usable A predicate to say if the command is usable 161 | */ 162 | public void register(CommandDispatcher dispatcher, Predicate usable) { 163 | LiteralArgumentBuilder literalArgumentBuilder = LiteralArgumentBuilder.literal(config.getID()).requires(usable).executes(this::listConfigGroups); 164 | 165 | for (ConfigItemGroup group : config.getConfigs()) { 166 | parseConfigItemGroupCommand(literalArgumentBuilder, group); 167 | } 168 | 169 | dispatcher.register(literalArgumentBuilder); 170 | } 171 | 172 | protected void parseConfigItemGroupCommand(LiteralArgumentBuilder literalArgumentBuilder, ConfigItemGroup group) { 173 | LiteralArgumentBuilder configGroupCommand = LiteralArgumentBuilder.literal(group.getName()).executes((c) -> listConfigGroup(c, group)); 174 | for (ConfigItem item : group.getConfigs()) { 175 | if (item instanceof ConfigItemGroup) { 176 | parseConfigItemGroupCommand(configGroupCommand, (ConfigItemGroup) item); 177 | } else { 178 | LiteralArgumentBuilder configItemCommand = LiteralArgumentBuilder.literal(item.getName()).executes((c) -> listItem(c, item)); 179 | configItemCommand.then(getCommand(item, group, config)); 180 | configGroupCommand.then(configItemCommand); 181 | } 182 | } 183 | literalArgumentBuilder.then(configGroupCommand); 184 | } 185 | 186 | private ArgumentBuilder getCommand(ConfigItem configItem, ConfigItemGroup group, Config config) { 187 | return ConfigItemCommands.getCommandBuilder(configItem).getCommand(configItem, group, config); 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /common/src/main/java/com/oroarmor/config/command/ConfigItemCommands.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config.command; 26 | 27 | import java.util.HashMap; 28 | import java.util.Map; 29 | 30 | import com.mojang.brigadier.arguments.BoolArgumentType; 31 | import com.mojang.brigadier.arguments.DoubleArgumentType; 32 | import com.mojang.brigadier.arguments.IntegerArgumentType; 33 | import com.mojang.brigadier.arguments.StringArgumentType; 34 | import com.mojang.brigadier.builder.ArgumentBuilder; 35 | import com.mojang.brigadier.builder.LiteralArgumentBuilder; 36 | import com.mojang.brigadier.builder.RequiredArgumentBuilder; 37 | import com.oroarmor.config.*; 38 | 39 | import net.minecraft.command.CommandSource; 40 | 41 | import static com.mojang.brigadier.builder.LiteralArgumentBuilder.literal; 42 | 43 | /** 44 | * Storage and registration for the commands to set config items 45 | */ 46 | public final class ConfigItemCommands { 47 | private static final Map>, CommandBuilder> COMMANDS = new HashMap<>(); 48 | 49 | static { 50 | register(BooleanConfigItem.class, new CommandBuilder() { 51 | @Override 52 | public ArgumentBuilder getCommand(ConfigItem configItem, ConfigItemGroup group, Config config) { 53 | return RequiredArgumentBuilder.argument("boolean", BoolArgumentType.bool()).executes(c -> { 54 | boolean result = BoolArgumentType.getBool(c, "boolean"); 55 | configItem.setValue(result); 56 | config.saveConfigToFile(); 57 | return 1; 58 | }); 59 | } 60 | }); 61 | register(DoubleConfigItem.class, new CommandBuilder() { 62 | @Override 63 | public ArgumentBuilder getCommand(ConfigItem configItem, ConfigItemGroup group, Config config) { 64 | DoubleConfigItem doubleConfigItem = (DoubleConfigItem) configItem; 65 | return RequiredArgumentBuilder.argument("double", DoubleArgumentType.doubleArg(doubleConfigItem.getMin(), doubleConfigItem.getMax())).executes(c -> { 66 | double result = DoubleArgumentType.getDouble(c, "double"); 67 | doubleConfigItem.setValue(result); 68 | config.saveConfigToFile(); 69 | return 1; 70 | }); 71 | } 72 | }); 73 | register(IntegerConfigItem.class, new CommandBuilder() { 74 | @Override 75 | public ArgumentBuilder getCommand(ConfigItem configItem, ConfigItemGroup group, Config config) { 76 | IntegerConfigItem integerConfigItem = (IntegerConfigItem) configItem; 77 | return RequiredArgumentBuilder.argument("int", IntegerArgumentType.integer(integerConfigItem.getMin(), integerConfigItem.getMax())).executes(c -> { 78 | int result = IntegerArgumentType.getInteger(c, "int"); 79 | integerConfigItem.setValue(result); 80 | config.saveConfigToFile(); 81 | return 1; 82 | }); 83 | } 84 | }); 85 | register(EnumConfigItem.class, new EnumCommandBuilder<>()); 86 | register(StringConfigItem.class, new CommandBuilder() { 87 | @Override 88 | public ArgumentBuilder getCommand(ConfigItem configItem, ConfigItemGroup group, Config config) { 89 | return RequiredArgumentBuilder.argument("string", StringArgumentType.string()).executes(c -> { 90 | String result = StringArgumentType.getString(c, "string"); 91 | configItem.setValue(result); 92 | config.saveConfigToFile(); 93 | return 1; 94 | }); 95 | } 96 | }); 97 | register(ArrayConfigItem.class, new ArrayCommandBuilder<>()); 98 | } 99 | 100 | /** 101 | * Registers a new command builder for the config item 102 | * 103 | * @param configItemClass The class for the config item 104 | * @param builder The builder to use 105 | * @param A config item type 106 | */ 107 | public static > void register(Class configItemClass, CommandBuilder builder) { 108 | if (COMMANDS.containsKey(configItemClass)) { 109 | throw new IllegalArgumentException("Duplicate entries for " + configItemClass.getSimpleName()); 110 | } 111 | 112 | COMMANDS.put(configItemClass, builder); 113 | } 114 | 115 | /** 116 | * Gets the config builder for the config item 117 | * 118 | * @param configItem The config item to get the builder for 119 | * @param The type of the config item's value 120 | * @param The type for the config item 121 | * @return 122 | */ 123 | @SuppressWarnings("unchecked") 124 | public static > CommandBuilder getCommandBuilder(C configItem) { 125 | return (CommandBuilder) COMMANDS.getOrDefault(configItem.getClass(), new CommandBuilder() { 126 | @Override 127 | public ArgumentBuilder getCommand(ConfigItem configItem, ConfigItemGroup group, Config config) { 128 | throw new IllegalArgumentException("Unknown Config Type"); 129 | } 130 | }); 131 | } 132 | 133 | /** 134 | * An interface to build new commands 135 | * 136 | * @param The type for the config item the command builder is for 137 | */ 138 | public interface CommandBuilder { 139 | /** 140 | * Gets the command for the config item 141 | * 142 | * @param configItem The config item 143 | * @param group The group for the item 144 | * @param config The config for the item 145 | * @param The command source type 146 | * @return A command for the config item 147 | */ 148 | ArgumentBuilder getCommand(ConfigItem configItem, ConfigItemGroup group, Config config); 149 | } 150 | 151 | private static class ArrayCommandBuilder implements CommandBuilder { 152 | @SuppressWarnings("unchecked") 153 | @Override 154 | public ArgumentBuilder getCommand(ConfigItem configItem, ConfigItemGroup group, Config config) { 155 | ArgumentBuilder setCommand; 156 | ArrayConfigItem arrayConfigItem = (ArrayConfigItem) configItem; 157 | switch (arrayConfigItem.getDefaultValue()[0].getClass().isEnum() ? "ENUM" : arrayConfigItem.getDefaultValue()[0].getClass().getSimpleName().toUpperCase()) { 158 | case "BOOLEAN": 159 | setCommand = RequiredArgumentBuilder.argument("boolean", BoolArgumentType.bool()).executes(c -> { 160 | boolean result = BoolArgumentType.getBool(c, "boolean"); 161 | int index = IntegerArgumentType.getInteger(c, "index"); 162 | arrayConfigItem.setValue((T) (Object) result, index); 163 | config.saveConfigToFile(); 164 | return 1; 165 | }); 166 | break; 167 | 168 | case "INTEGER": 169 | setCommand = RequiredArgumentBuilder.argument("int", IntegerArgumentType.integer()).executes(c -> { 170 | int result = IntegerArgumentType.getInteger(c, "int"); 171 | int index = IntegerArgumentType.getInteger(c, "index"); 172 | arrayConfigItem.setValue((T) (Object) result, index); 173 | config.saveConfigToFile(); 174 | return 1; 175 | }); 176 | break; 177 | case "DOUBLE": 178 | setCommand = RequiredArgumentBuilder.argument("double", DoubleArgumentType.doubleArg()).executes(c -> { 179 | double result = DoubleArgumentType.getDouble(c, "double"); 180 | int index = IntegerArgumentType.getInteger(c, "index"); 181 | arrayConfigItem.setValue((T) (Object) result, index); 182 | config.saveConfigToFile(); 183 | return 1; 184 | }); 185 | break; 186 | 187 | case "STRING": 188 | setCommand = RequiredArgumentBuilder.argument("string", StringArgumentType.greedyString()).executes(c -> { 189 | String result = StringArgumentType.getString(c, "string"); 190 | int index = IntegerArgumentType.getInteger(c, "index"); 191 | arrayConfigItem.setValue((T) result, index); 192 | config.saveConfigToFile(); 193 | return 1; 194 | }); 195 | break; 196 | 197 | case "ENUM": 198 | setCommand = literal("set"); 199 | Enum[] enums = ((Enum) arrayConfigItem.getValue()[0]).getClass().getEnumConstants(); 200 | for (Enum _enum : enums) { 201 | setCommand.then(LiteralArgumentBuilder.literal(_enum.toString()).executes(c -> { 202 | int index = IntegerArgumentType.getInteger(c, "index"); 203 | arrayConfigItem.setValue((T) _enum, index); 204 | config.saveConfigToFile(); 205 | return 1; 206 | })); 207 | } 208 | break; 209 | 210 | default: 211 | throw new IllegalStateException("Class " + arrayConfigItem.getDefaultValue()[0].getClass().getSimpleName() + " is an unsupported type"); 212 | } 213 | return RequiredArgumentBuilder.argument("index", IntegerArgumentType.integer(0, arrayConfigItem.getValue().length)).then(setCommand); 214 | } 215 | } 216 | 217 | private static class EnumCommandBuilder> implements CommandBuilder { 218 | @SuppressWarnings("unchecked") 219 | @Override 220 | public ArgumentBuilder getCommand(ConfigItem configItem, ConfigItemGroup group, Config config) { 221 | LiteralArgumentBuilder builder = LiteralArgumentBuilder.literal("set"); 222 | Enum[] enums = ((Enum) configItem.getValue()).getClass().getEnumConstants(); 223 | for (Enum _enum : enums) { 224 | builder.then(LiteralArgumentBuilder.literal(_enum.toString()).executes(c -> { 225 | configItem.setValue((T) _enum); 226 | config.saveConfigToFile(); 227 | return 1; 228 | })); 229 | } 230 | return builder; 231 | } 232 | } 233 | } 234 | -------------------------------------------------------------------------------- /common/src/main/java/com/oroarmor/config/screen/ConfigScreen.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config.screen; 26 | 27 | import java.util.List; 28 | import java.util.stream.Collectors; 29 | 30 | import com.oroarmor.config.Config; 31 | import com.oroarmor.config.ConfigItem; 32 | import com.oroarmor.config.ConfigItemGroup; 33 | import me.shedaniel.clothconfig2.api.AbstractConfigListEntry; 34 | import me.shedaniel.clothconfig2.api.ConfigBuilder; 35 | import me.shedaniel.clothconfig2.api.ConfigCategory; 36 | import me.shedaniel.clothconfig2.api.ConfigEntryBuilder; 37 | import me.shedaniel.clothconfig2.impl.builders.SubCategoryBuilder; 38 | 39 | import net.minecraft.client.gui.screen.Screen; 40 | import net.minecraft.text.Text; 41 | 42 | /** 43 | * This class allows for the easy addition of a Mod Menu config screen to your 44 | * mod. The abstract modifier is so that your {@link ConfigScreen} can be 45 | * used as a entry point for modmenu, as you need to set the config in the 46 | * constructor for this to work.
47 | *
48 | * Add this to your entrypoint list in {@code fabric.mod.json}:
49 | * 50 | * "modmenu" : [
51 | *  "your.package.structure.YourModMenuConfigScreen"
52 | * ] 53 | *
54 | * 55 | * @author Eli Orona 56 | */ 57 | public abstract class ConfigScreen { 58 | 59 | /** 60 | * The config for the screen 61 | */ 62 | protected final Config config; 63 | 64 | /** 65 | * Creates a new {@link ConfigScreen} 66 | * 67 | * @param config The config 68 | */ 69 | public ConfigScreen(Config config) { 70 | this.config = config; 71 | } 72 | 73 | protected ConfigCategory createCategory(ConfigBuilder builder, String categoryName) { 74 | return builder.getOrCreateCategory(Text.translatable(categoryName)); 75 | } 76 | 77 | @SuppressWarnings({"unchecked", "rawtypes"}) 78 | protected AbstractConfigListEntry createConfigItem(ConfigItem ci, ConfigEntryBuilder entryBuilder, String superGroupName) { 79 | if (ci instanceof ConfigItemGroup) { 80 | List subItems = ((ConfigItemGroup) ci).getConfigs().stream().map(configItem -> createConfigItem(configItem, entryBuilder, superGroupName + "." + ci.getName())).collect(Collectors.toList()); 81 | SubCategoryBuilder groupCategory = entryBuilder.startSubCategory(Text.translatable(superGroupName + "." + ci.getName()), subItems); 82 | return groupCategory.build(); 83 | } 84 | return ConfigScreenBuilders.getEntryBuilder(ci).getConfigEntry((ConfigItem) ci, entryBuilder, config); 85 | } 86 | 87 | /** 88 | * Creates a config screen 89 | * 90 | * @param parent The parent screen 91 | * @return A new screen 92 | */ 93 | @SuppressWarnings("rawtypes") 94 | public Screen createScreen(Screen parent) { 95 | ConfigBuilder builder = ConfigBuilder.create().setParentScreen(parent).setTitle(Text.translatable("config." + config.getID())); 96 | builder.setSavingRunnable(config::saveConfigToFile); 97 | 98 | ConfigEntryBuilder entryBuilder = ConfigEntryBuilder.create(); 99 | 100 | config.getConfigs().forEach(group -> { 101 | ConfigCategory groupCategory = createCategory(builder, "config." + config.getID() + "." + group.getName()); 102 | group.getConfigs().forEach(configItem -> { 103 | AbstractConfigListEntry entry = createConfigItem(configItem, entryBuilder, group.getName()); 104 | groupCategory.addEntry(entry); 105 | }); 106 | }); 107 | 108 | return builder.build(); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /common/src/main/java/com/oroarmor/config/screen/ConfigScreenBuilders.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config.screen; 26 | 27 | import java.util.ArrayList; 28 | import java.util.HashMap; 29 | import java.util.List; 30 | import java.util.Map; 31 | 32 | import com.oroarmor.config.*; 33 | import me.shedaniel.clothconfig2.api.AbstractConfigListEntry; 34 | import me.shedaniel.clothconfig2.api.ConfigEntryBuilder; 35 | import net.minecraft.text.Text; 36 | import org.jetbrains.annotations.NotNull; 37 | 38 | /** 39 | * Storage and registration for the config entries to set config items 40 | */ 41 | public class ConfigScreenBuilders { 42 | private static final Map>, EntryBuilder> COMMANDS = new HashMap<>(); 43 | 44 | static { 45 | register(BooleanConfigItem.class, (EntryBuilder) (configItem, entryBuilder, config) -> entryBuilder.startBooleanToggle(Text.translatable(configItem.getDetails()), configItem.getValue()).setSaveConsumer(configItem::setValue).setDefaultValue(configItem::getDefaultValue).build()); 46 | register(DoubleConfigItem.class, (EntryBuilder) (configItem, entryBuilder, config) -> { 47 | DoubleConfigItem doubleConfigItem = (DoubleConfigItem) configItem; 48 | return entryBuilder.startDoubleField(Text.translatable(doubleConfigItem.getDetails()), doubleConfigItem.getValue()).setSaveConsumer(doubleConfigItem::setValue).setDefaultValue(doubleConfigItem::getDefaultValue).setMin(doubleConfigItem.getMin()).setMax(doubleConfigItem.getMax()).build(); 49 | }); 50 | register(IntegerConfigItem.class, (EntryBuilder) (configItem, entryBuilder, config) -> { 51 | IntegerConfigItem integerConfigItem = (IntegerConfigItem) configItem; 52 | return entryBuilder.startIntField(Text.translatable(integerConfigItem.getDetails()), integerConfigItem.getValue()).setSaveConsumer(integerConfigItem::setValue).setDefaultValue(integerConfigItem::getDefaultValue).setMin(integerConfigItem.getMin()).setMax(integerConfigItem.getMax()).build(); 53 | }); 54 | register(StringConfigItem.class, (EntryBuilder) (configItem, entryBuilder, config) -> entryBuilder.startStrField(Text.translatable(configItem.getDetails()), configItem.getValue()).setSaveConsumer(configItem::setValue).setDefaultValue(configItem::getDefaultValue).build()); 55 | register(EnumConfigItem.class, new EnumEntryBuilder<>()); 56 | register(ArrayConfigItem.class, new ArrayEntryBuilder<>()); 57 | } 58 | 59 | /** 60 | * Registers a new entry builder for the config item 61 | * 62 | * @param configItemClass The class for the config item 63 | * @param builder The entry builder for the item 64 | * @param The config item type 65 | */ 66 | public static > void register(Class configItemClass, EntryBuilder builder) { 67 | if (COMMANDS.containsKey(configItemClass)) { 68 | throw new IllegalArgumentException("Duplicate entries for " + configItemClass.getSimpleName()); 69 | } 70 | 71 | COMMANDS.put(configItemClass, builder); 72 | } 73 | 74 | /** 75 | * Gets the entry builder for the config item 76 | * 77 | * @param configItem The config item 78 | * @param The storage type for the config item 79 | * @param The type of the config item 80 | * @return The entry builder 81 | */ 82 | @SuppressWarnings("unchecked") 83 | public static > EntryBuilder getEntryBuilder(C configItem) { 84 | return (EntryBuilder) COMMANDS.getOrDefault(configItem.getClass(), (EntryBuilder) (configItem1, entryBuilder, config) -> { 85 | throw new IllegalArgumentException("Unknown Config Type"); 86 | }); 87 | } 88 | 89 | /** 90 | * An interface to create new entries for the config screen 91 | * 92 | * @param The storage type of the config item 93 | */ 94 | public interface EntryBuilder { 95 | /** 96 | * Gets the entry for the config item 97 | * 98 | * @param configItem The config item 99 | * @param entryBuilder The cloth config entry builder 100 | * @param config The config 101 | * @return A new entry for the config screen 102 | */ 103 | AbstractConfigListEntry getConfigEntry(ConfigItem configItem, ConfigEntryBuilder entryBuilder, Config config); 104 | } 105 | 106 | @SuppressWarnings("all") 107 | private static class ArrayEntryBuilder implements EntryBuilder { 108 | @Override 109 | public AbstractConfigListEntry getConfigEntry(ConfigItem configItem, ConfigEntryBuilder entryBuilder, Config config) { 110 | ArrayConfigItem arrayConfigItem = (ArrayConfigItem) configItem; 111 | switch (arrayConfigItem.getDefaultValue()[0].getClass().isEnum() ? "ENUM" : arrayConfigItem.getDefaultValue()[0].getClass().getSimpleName().toUpperCase()) { 112 | case "BOOLEAN": 113 | List bconfigs = new ArrayList<>(); 114 | for (int i = 0; i < arrayConfigItem.getValue().length; i++) { 115 | int finalI = i; 116 | AbstractConfigListEntry entry = entryBuilder.startBooleanToggle(Text.translatable(arrayConfigItem.getDetails()).append(": " + i), (Boolean) arrayConfigItem.getValue(i)).setSaveConsumer(val -> arrayConfigItem.setValue((T) val, finalI)).setDefaultValue(() -> (Boolean) arrayConfigItem.getDefaultValue(finalI)).build(); 117 | bconfigs.add(entry); 118 | } 119 | return entryBuilder.startSubCategory(Text.translatable(configItem.getDetails()), bconfigs).build(); 120 | 121 | case "INTEGER": 122 | List iconfigs = new ArrayList<>(); 123 | for (int i = 0; i < arrayConfigItem.getValue().length; i++) { 124 | int finalI = i; 125 | AbstractConfigListEntry entry = entryBuilder.startIntField(Text.translatable(arrayConfigItem.getDetails()).append(": " + i), (Integer) arrayConfigItem.getValue(i)).setSaveConsumer(val -> arrayConfigItem.setValue((T) val, finalI)).setDefaultValue(() -> (Integer) arrayConfigItem.getDefaultValue(finalI)).build(); 126 | iconfigs.add(entry); 127 | } 128 | return entryBuilder.startSubCategory(Text.translatable(configItem.getDetails()), iconfigs).build(); 129 | case "DOUBLE": 130 | List dconfigs = new ArrayList<>(); 131 | for (int i = 0; i < arrayConfigItem.getValue().length; i++) { 132 | int finalI = i; 133 | AbstractConfigListEntry entry = entryBuilder.startDoubleField(Text.translatable(arrayConfigItem.getDetails()).append(": " + i), (Double) arrayConfigItem.getValue(i)).setSaveConsumer(val -> arrayConfigItem.setValue((T) val, finalI)).setDefaultValue(() -> (Double) arrayConfigItem.getDefaultValue(finalI)).build(); 134 | dconfigs.add(entry); 135 | } 136 | return entryBuilder.startSubCategory(Text.translatable(configItem.getDetails()), dconfigs).build(); 137 | 138 | case "STRING": 139 | List sconfigs = new ArrayList<>(); 140 | for (int i = 0; i < arrayConfigItem.getValue().length; i++) { 141 | int finalI = i; 142 | AbstractConfigListEntry entry = entryBuilder.startStrField(Text.translatable(arrayConfigItem.getDetails()).append(": " + i), (String) arrayConfigItem.getValue(i)).setSaveConsumer(val -> arrayConfigItem.setValue((T) val, finalI)).setDefaultValue(() -> (String) arrayConfigItem.getDefaultValue(finalI)).build(); 143 | sconfigs.add(entry); 144 | } 145 | return entryBuilder.startSubCategory(Text.translatable(arrayConfigItem.getDetails()), sconfigs).build(); 146 | 147 | case "ENUM": 148 | return getEnumArrayEntry(entryBuilder, (ArrayConfigItem) arrayConfigItem); 149 | 150 | default: 151 | throw new IllegalStateException("Class " + arrayConfigItem.getDefaultValue()[0].getClass().getSimpleName() + " is an unsupported type"); 152 | } 153 | } 154 | 155 | @NotNull 156 | private > AbstractConfigListEntry getEnumArrayEntry(ConfigEntryBuilder entryBuilder, ArrayConfigItem arrayConfigItem) { 157 | List configs = new ArrayList<>(); 158 | for (int i = 0; i < arrayConfigItem.getValue().length; i++) { 159 | int finalI = i; 160 | AbstractConfigListEntry entry = entryBuilder.startEnumSelector(Text.translatable(arrayConfigItem.getDetails()).append(": " + i), (Class) ((Enum) arrayConfigItem.getValue(i)).getClass().getEnumConstants()[0].getClass(), arrayConfigItem.getValue(i)) 161 | .setSaveConsumer(val -> arrayConfigItem.setValue((S) val, finalI)) 162 | .setDefaultValue(() -> (S) arrayConfigItem.getDefaultValue(finalI)).build(); 163 | configs.add(entry); 164 | } 165 | 166 | return entryBuilder.startSubCategory(Text.translatable(arrayConfigItem.getDetails()), configs).build(); 167 | } 168 | } 169 | 170 | private static class EnumEntryBuilder> implements EntryBuilder { 171 | @SuppressWarnings("unchecked") 172 | @Override 173 | public AbstractConfigListEntry getConfigEntry(ConfigItem configItem, ConfigEntryBuilder entryBuilder, Config config) { 174 | return entryBuilder.startEnumSelector(Text.translatable(configItem.getDetails()), (Class) ((Enum) configItem.getValue()).getClass().getEnumConstants()[0].getClass(), configItem.getValue()) 175 | .setSaveConsumer(configItem::setValue) 176 | .setDefaultValue(configItem::getValue).build(); 177 | } 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /common/src/main/resources/oro-config_icon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OroArmorModding/Oro-Config/3b764d8f266eaeafd41731e11bf4227f7611f3b1/common/src/main/resources/oro-config_icon.jpg -------------------------------------------------------------------------------- /common/src/test/java/com/oroarmor/config/ConfigItemTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config; 26 | 27 | import com.google.gson.JsonPrimitive; 28 | import org.junit.Test; 29 | 30 | import static org.junit.Assert.assertEquals; 31 | 32 | public class ConfigItemTest { 33 | @Test 34 | public void gettersAreCorrect() { 35 | Integer defaultValue = 10; 36 | String name = "name"; 37 | String details = "details"; 38 | IntegerConfigItem configItem = new IntegerConfigItem(name, defaultValue, details); 39 | 40 | assertEquals("Default Value", defaultValue, configItem.getDefaultValue()); 41 | assertEquals("Name", name, configItem.getName()); 42 | assertEquals("Details", details, configItem.getDetails()); 43 | assertEquals("To String", name + ":" + defaultValue, configItem.toString()); 44 | } 45 | 46 | @Test 47 | public void settingValue() { 48 | Integer defaultValue = 10; 49 | String name = "name"; 50 | String details = "details"; 51 | IntegerConfigItem configItem = new IntegerConfigItem(name, defaultValue, details, (ci) -> ci.value = (ci.getValue() / 2)); 52 | configItem.setValue(2 * defaultValue); 53 | 54 | assertEquals("Correct value after setting and with consumer", defaultValue, configItem.getValue()); 55 | } 56 | 57 | @Test 58 | public void readFromJSON() { 59 | IntegerConfigItem test = new IntegerConfigItem("name", 0, "details"); 60 | test.fromJson(new JsonPrimitive(10)); 61 | assertEquals("Correct value from json", (Integer) 10, test.getValue()); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /common/src/test/java/com/oroarmor/config/ConfigTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config; 26 | 27 | import org.junit.Test; 28 | 29 | import static org.junit.Assert.assertEquals; 30 | 31 | public class ConfigTest { 32 | @Test 33 | public void getValue() { 34 | Config testConfig = new TestConfig(); 35 | assertEquals("Get value gets correct value", TestConfig.ConfigGroupLevel1.testItem.getDefaultValue(), testConfig.getValue("group.test_boolean", Boolean.class)); 36 | assertEquals("Get value gets correct value", TestConfig.ConfigGroupLevel1.NestedGroup.nestedItem.getDefaultValue(), testConfig.getValue("group.nested.test_int", Integer.class)); 37 | assertEquals("Get value gets correct enum value", TestConfig.ConfigGroupLevel1.testEnum.getDefaultValue(), testConfig.getValue("group.test_enum", EnumTest.class)); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /common/src/test/java/com/oroarmor/config/EnumTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config; 26 | 27 | public enum EnumTest { 28 | A, B, C 29 | } 30 | -------------------------------------------------------------------------------- /common/src/test/java/com/oroarmor/config/TestConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config; 26 | 27 | import java.util.List; 28 | 29 | import static com.google.common.collect.ImmutableList.of; 30 | 31 | public class TestConfig extends Config { 32 | public static final ConfigItemGroup mainGroup = new ConfigGroupLevel1(); 33 | 34 | public static final List configs = of(mainGroup); 35 | 36 | public TestConfig() { 37 | super(configs, null, "oroarmor_config_testmod"); 38 | } 39 | 40 | public static class ConfigGroupLevel1 extends ConfigItemGroup { 41 | public static final EnumConfigItem testEnum = new EnumConfigItem<>("test_enum", EnumTest.A, "test_enum"); 42 | public static final BooleanConfigItem testItem = new BooleanConfigItem("test_boolean", true, "test_boolean"); 43 | 44 | public static final ArrayConfigItem testArray = new ArrayConfigItem<>("test_array", new Integer[]{1, 2, 3}, "test_array"); 45 | 46 | public ConfigGroupLevel1() { 47 | super(of(new NestedGroup(), testItem, testEnum, testArray), "group"); 48 | } 49 | 50 | public static class NestedGroup extends ConfigItemGroup { 51 | public static final IntegerConfigItem nestedItem = new IntegerConfigItem("test_int", 0, "test_integer"); 52 | 53 | public NestedGroup() { 54 | super(of(nestedItem, new TripleNested()), "nested"); 55 | } 56 | 57 | public static class TripleNested extends ConfigItemGroup { 58 | public static final StringConfigItem testString = new StringConfigItem("test_string", "Default", "test_string"); 59 | 60 | public TripleNested() { 61 | super(of(testString), "triple"); 62 | } 63 | } 64 | } 65 | } 66 | } 67 | 68 | -------------------------------------------------------------------------------- /fabric-testmod/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.github.johnrengelman.shadow" version "5.0.0" 3 | id "forgified-fabric-loom" 4 | } 5 | 6 | repositories { 7 | maven { 8 | url = "https://maven.terraformersmc.com/releases/" 9 | } 10 | } 11 | 12 | configurations { 13 | shadowCommonTestmod 14 | } 15 | 16 | 17 | architectury { 18 | platformSetupLoomIde() 19 | fabric() 20 | } 21 | 22 | dependencies { 23 | modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" 24 | // Remove the next line if you don't want to depend on the API 25 | compileOnly(project(path: ":common")) { 26 | transitive = false 27 | } 28 | runtimeOnly(project(path: ":common")) { 29 | transitive = false 30 | } 31 | 32 | implementation(project(":fabric")) 33 | 34 | modRuntime("com.terraformersmc:modmenu:1.16.8") 35 | modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}" 36 | } 37 | 38 | processResources { 39 | inputs.property "version", project.version 40 | 41 | filesMatching("fabric.mod.json") { 42 | expand "version": project.version 43 | } 44 | } 45 | 46 | shadowJar { 47 | configurations = [project.configurations.shadowCommonTestmod] 48 | classifier "dev-shadow" 49 | } 50 | 51 | remapJar { 52 | input.set shadowJar.archiveFile 53 | dependsOn shadowJar 54 | classifier "fabric-testmod" 55 | } 56 | 57 | jar { 58 | classifier "dev" 59 | } 60 | 61 | java { 62 | withSourcesJar() 63 | } 64 | 65 | sourcesJar { 66 | def commonSources = project(":common").remapSourcesJar 67 | dependsOn commonSources 68 | from zipTree(commonSources.output) 69 | } -------------------------------------------------------------------------------- /fabric-testmod/src/main/java/com/oroarmor/config/testmod/ColorConfigItem.java: -------------------------------------------------------------------------------- 1 | package com.oroarmor.config.testmod; 2 | 3 | import java.util.function.Consumer; 4 | 5 | import com.google.gson.JsonElement; 6 | import com.google.gson.JsonObject; 7 | import com.mojang.brigadier.arguments.IntegerArgumentType; 8 | import com.mojang.brigadier.builder.ArgumentBuilder; 9 | import com.mojang.brigadier.builder.LiteralArgumentBuilder; 10 | import com.mojang.brigadier.builder.RequiredArgumentBuilder; 11 | import com.oroarmor.config.Config; 12 | import com.oroarmor.config.ConfigItem; 13 | import com.oroarmor.config.ConfigItemGroup; 14 | import com.oroarmor.config.command.ConfigItemCommands; 15 | import com.oroarmor.config.screen.ConfigScreenBuilders; 16 | import me.shedaniel.math.Color; 17 | import org.jetbrains.annotations.Nullable; 18 | 19 | import net.minecraft.command.CommandSource; 20 | import net.minecraft.text.TranslatableText; 21 | 22 | public class ColorConfigItem extends ConfigItem { 23 | public ColorConfigItem(String name, Color defaultValue, String details) { 24 | super(name, defaultValue, details); 25 | } 26 | 27 | public ColorConfigItem(String name, Color defaultValue, String details, @Nullable Consumer> onChange) { 28 | super(name, defaultValue, details, onChange); 29 | } 30 | 31 | @Override 32 | public void fromJson(JsonElement element) { 33 | JsonObject colorObject = element.getAsJsonObject(); 34 | int r = colorObject.get("r").getAsInt(); 35 | int g = colorObject.get("g").getAsInt(); 36 | int b = colorObject.get("b").getAsInt(); 37 | int a = colorObject.get("a").getAsInt(); 38 | this.value = Color.ofRGBA(r, g, b, a); 39 | } 40 | 41 | @Override 42 | public void toJson(JsonObject object) { 43 | JsonObject colorObject = new JsonObject(); 44 | colorObject.addProperty("r", this.value.getRed()); 45 | colorObject.addProperty("g", this.value.getGreen()); 46 | colorObject.addProperty("b", this.value.getBlue()); 47 | colorObject.addProperty("a", this.value.getAlpha()); 48 | object.add(this.name, colorObject); 49 | } 50 | 51 | @Override 52 | public boolean isValidType(Class clazz) { 53 | return clazz == Color.class; 54 | } 55 | 56 | @Override 57 | public String getCommandValue() { 58 | return this.value.toString(); 59 | } 60 | 61 | @Override 62 | public String getCommandDefaultValue() { 63 | return this.defaultValue.toString(); 64 | } 65 | 66 | static { 67 | ConfigItemCommands.register(ColorConfigItem.class, new ConfigItemCommands.CommandBuilder() { 68 | @Override 69 | public ArgumentBuilder getCommand(ConfigItem configItem, ConfigItemGroup group, Config config) { 70 | LiteralArgumentBuilder set = LiteralArgumentBuilder.literal("set"); 71 | set.then(LiteralArgumentBuilder.literal("r") 72 | .then(RequiredArgumentBuilder.argument("val", IntegerArgumentType.integer(0, 255)) 73 | .executes(context -> { 74 | configItem.setValue(Color.ofTransparent(configItem.getValue().getColor() & 0xFF00FFFF | (IntegerArgumentType.getInteger(context, "val") << 16))); 75 | return 1; 76 | }) 77 | )); 78 | set.then(LiteralArgumentBuilder.literal("g") 79 | .then(RequiredArgumentBuilder.argument("val", IntegerArgumentType.integer(0, 255)) 80 | .executes(context -> { 81 | configItem.setValue(Color.ofTransparent(configItem.getValue().getColor() & 0xFFFF00FF | (IntegerArgumentType.getInteger(context, "val") << 8))); 82 | return 1; 83 | }) 84 | )); 85 | set.then(LiteralArgumentBuilder.literal("b") 86 | .then(RequiredArgumentBuilder.argument("val", IntegerArgumentType.integer(0, 255)) 87 | .executes(context -> { 88 | configItem.setValue(Color.ofTransparent(configItem.getValue().getColor() & 0xFFFFFF00 | (IntegerArgumentType.getInteger(context, "val") << 0))); 89 | return 1; 90 | }) 91 | )); 92 | set.then(LiteralArgumentBuilder.literal("a") 93 | .then(RequiredArgumentBuilder.argument("val", IntegerArgumentType.integer(0, 255)) 94 | .executes(context -> { 95 | configItem.setValue(Color.ofTransparent(configItem.getValue().getColor() & 0x00FFFFFF | (IntegerArgumentType.getInteger(context, "val") << 24))); 96 | return 1; 97 | }) 98 | )); 99 | return set; 100 | } 101 | }); 102 | 103 | ConfigScreenBuilders.register(ColorConfigItem.class, (ConfigScreenBuilders.EntryBuilder) (configItem, entryBuilder, config) -> entryBuilder.startColorField(new TranslatableText(configItem.getName()), configItem.getValue()).setDefaultValue2(configItem::getDefaultValue).setSaveConsumer2(configItem::setValue).setAlphaMode(true).build()); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /fabric-testmod/src/main/java/com/oroarmor/config/testmod/EnumTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config.testmod; 26 | 27 | public enum EnumTest { 28 | A, B, C 29 | } 30 | -------------------------------------------------------------------------------- /fabric-testmod/src/main/java/com/oroarmor/config/testmod/ModMenuIntegration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config.testmod; 26 | 27 | import com.oroarmor.config.screen.ModMenuConfigScreen; 28 | 29 | public class ModMenuIntegration extends ModMenuConfigScreen { 30 | public ModMenuIntegration() { 31 | super(OroConfigTestMod.CONFIG); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /fabric-testmod/src/main/java/com/oroarmor/config/testmod/OroConfigTestMod.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config.testmod; 26 | 27 | import com.oroarmor.config.Config; 28 | import com.oroarmor.config.command.ConfigCommand; 29 | 30 | import net.minecraft.server.command.ServerCommandSource; 31 | 32 | import net.fabricmc.api.ModInitializer; 33 | import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback; 34 | import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; 35 | 36 | public class OroConfigTestMod implements ModInitializer { 37 | public static Config CONFIG = new TestConfig(); 38 | 39 | @Override 40 | public void onInitialize() { 41 | CONFIG.readConfigFromFile(); 42 | CONFIG.saveConfigToFile(); 43 | ServerLifecycleEvents.SERVER_STOPPED.register(instance -> CONFIG.saveConfigToFile()); 44 | CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) -> new ConfigCommand(CONFIG).register(dispatcher, p -> p.hasPermissionLevel(2))); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /fabric-testmod/src/main/java/com/oroarmor/config/testmod/OroConfigTestModClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config.testmod; 26 | 27 | import com.oroarmor.config.Config; 28 | import com.oroarmor.config.command.ClientConfigCommand; 29 | 30 | import net.fabricmc.api.ClientModInitializer; 31 | import net.fabricmc.fabric.api.client.command.v1.ClientCommandManager; 32 | import net.fabricmc.fabric.api.client.command.v1.FabricClientCommandSource; 33 | import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; 34 | 35 | public class OroConfigTestModClient implements ClientModInitializer { 36 | public static Config CONFIG = new TestConfigClient(); 37 | 38 | @Override 39 | public void onInitializeClient() { 40 | CONFIG.readConfigFromFile(); 41 | CONFIG.saveConfigToFile(); 42 | ClientLifecycleEvents.CLIENT_STOPPING.register(instance -> CONFIG.saveConfigToFile()); 43 | new ClientConfigCommand(CONFIG).register(ClientCommandManager.DISPATCHER, p -> true); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /fabric-testmod/src/main/java/com/oroarmor/config/testmod/TestConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config.testmod; 26 | 27 | import java.io.File; 28 | import java.util.List; 29 | 30 | import com.oroarmor.config.*; 31 | 32 | import net.fabricmc.loader.api.FabricLoader; 33 | import static com.google.common.collect.ImmutableList.of; 34 | 35 | public class TestConfig extends Config { 36 | public static final ConfigItemGroup mainGroup = new ConfigGroupLevel1(); 37 | 38 | public static final List configs = of(mainGroup); 39 | 40 | public TestConfig() { 41 | super(configs, new File(FabricLoader.getInstance().getConfigDir().toFile(), "oroarmor_config_testmod.json"), "oroarmor_config_testmod"); 42 | } 43 | 44 | public static class ConfigGroupLevel1 extends ConfigItemGroup { 45 | public static final EnumConfigItem testEnum = new EnumConfigItem<>("test_enum", EnumTest.A, "test_enum"); 46 | public static final BooleanConfigItem testItem = new BooleanConfigItem("test_boolean", true, "test_boolean"); 47 | 48 | public static final ArrayConfigItem testArray = new ArrayConfigItem<>("test_array", new Integer[]{1, 2, 3}, "test_array"); 49 | 50 | public ConfigGroupLevel1() { 51 | super(of(new NestedGroup(), testItem, testEnum, testArray), "group"); 52 | } 53 | 54 | public static class NestedGroup extends ConfigItemGroup { 55 | public static final IntegerConfigItem nestedItem = new IntegerConfigItem("test_int", 0, "test_integer"); 56 | 57 | public NestedGroup() { 58 | super(of(nestedItem, new TripleNested()), "nested"); 59 | } 60 | 61 | public static class TripleNested extends ConfigItemGroup { 62 | public static final StringConfigItem testString = new StringConfigItem("test_string", "Default", "test_string"); 63 | 64 | public TripleNested() { 65 | super(of(testString), "triple"); 66 | } 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /fabric-testmod/src/main/java/com/oroarmor/config/testmod/TestConfigClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config.testmod; 26 | 27 | import java.io.File; 28 | import java.util.List; 29 | 30 | import com.oroarmor.config.Config; 31 | import com.oroarmor.config.ConfigItemGroup; 32 | import com.oroarmor.config.DoubleConfigItem; 33 | import me.shedaniel.math.Color; 34 | 35 | import net.fabricmc.loader.api.FabricLoader; 36 | import static com.google.common.collect.ImmutableList.of; 37 | 38 | public class TestConfigClient extends Config { 39 | public static final ConfigItemGroup mainGroup = new ConfigGroupLevel1(); 40 | 41 | public static final List configs = of(mainGroup); 42 | 43 | public TestConfigClient() { 44 | super(configs, new File(FabricLoader.getInstance().getConfigDir().toFile(), "oroarmor_config_testmod_client.json"), "oroarmor_config_testmod_client"); 45 | } 46 | 47 | public static class ConfigGroupLevel1 extends ConfigItemGroup { 48 | public static final DoubleConfigItem testDouble = new DoubleConfigItem("test_double", 0d, "test_double", null, -1, 1); 49 | 50 | public static final ColorConfigItem testColor = new ColorConfigItem("test_color", Color.ofTransparent(0x00FF0000), "test_color"); 51 | 52 | public ConfigGroupLevel1() { 53 | super(of(testDouble, testColor), "group"); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /fabric-testmod/src/main/resources/fabric.mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 1, 3 | "id": "oro_config_testmod", 4 | "version": "${version}", 5 | "name": "OroArmor Config Test Mod", 6 | "description": "Testmod for the config library", 7 | "authors": [ 8 | "OroArmor" 9 | ], 10 | "license": "MIT", 11 | "icon": "oro-config_icon.jpg", 12 | "environment": "*", 13 | "entrypoints": { 14 | "main": [ 15 | "com.oroarmor.config.testmod.OroConfigTestMod" 16 | ], 17 | "modmenu": [ 18 | "com.oroarmor.config.testmod.ModMenuIntegration" 19 | ], 20 | "client": [ 21 | "com.oroarmor.config.testmod.OroConfigTestModClient" 22 | ] 23 | }, 24 | "depends": { 25 | "fabricloader": ">=0.7.4" 26 | }, 27 | "suggests": { 28 | "flamingo": "*" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /fabric/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.github.johnrengelman.shadow" version "7.1.2" 3 | } 4 | 5 | repositories { 6 | maven { 7 | url = "https://maven.terraformersmc.com/releases/" 8 | } 9 | } 10 | 11 | architectury { 12 | platformSetupLoomIde() 13 | fabric() 14 | } 15 | 16 | configurations { 17 | shadowCommon 18 | } 19 | 20 | archivesBaseName = rootProject.archives_base_name + "-fabric" 21 | version = rootProject.mod_version 22 | group = rootProject.maven_group 23 | 24 | dependencies { 25 | modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" 26 | 27 | implementation(project(path: ":common")) { 28 | transitive = false 29 | } 30 | developmentFabric(project(path: ":common")) { 31 | transitive = false 32 | } 33 | shadowCommon(project(path: ":common", configuration: "transformProductionFabric")) { 34 | transitive = false 35 | } 36 | 37 | modImplementation "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}" 38 | 39 | /* 40 | modApi("com.terraformersmc:modmenu:1.16.8") { 41 | exclude(module: "fabric-api") 42 | } 43 | */ 44 | include(modApi("me.shedaniel.cloth:cloth-config-fabric:${rootProject.cloth_config_version}")) { 45 | exclude(group: "net.fabricmc.fabric-api") 46 | } 47 | } 48 | 49 | processResources { 50 | inputs.property "version", project.version 51 | 52 | filesMatching("fabric.mod.json") { 53 | expand "version": project.version 54 | } 55 | } 56 | 57 | shadowJar { 58 | configurations = [project.configurations.shadowCommon] 59 | //classifier "dev-shadow" 60 | } 61 | 62 | remapJar { 63 | input.set shadowJar.archiveFile 64 | dependsOn shadowJar 65 | } 66 | 67 | jar { 68 | //classifier "dev" 69 | } 70 | 71 | java { 72 | withSourcesJar() 73 | } 74 | 75 | sourcesJar { 76 | def commonSources = project(":common").remapSourcesJar 77 | dependsOn commonSources 78 | //from zipTree(commonSources.output) 79 | } 80 | 81 | /* 82 | publishing { 83 | publications { 84 | mavenFabric(MavenPublication) { 85 | // add all the jars that should be included when publishing to maven 86 | artifact(remapJar) { 87 | classifier null 88 | } 89 | artifact(sourcesJar) { 90 | builtBy remapSourcesJar 91 | } 92 | artifact(javadocJar) { 93 | builtBy javadocJar 94 | } 95 | } 96 | } 97 | 98 | // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. 99 | repositories { 100 | // Add repositories to publish to here. 101 | } 102 | } 103 | */ -------------------------------------------------------------------------------- /fabric/src/main/java/com/oroarmor/config/command/ClientCommandHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config.command; 26 | 27 | import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; 28 | 29 | public class ClientCommandHelper { 30 | public void registerOpenScreen() { 31 | ClientTickEvents.START_CLIENT_TICK.register(client -> { 32 | if (ClientConfigCommand.openScreen != null) { 33 | client.openScreen(ClientConfigCommand.openScreen); 34 | ClientConfigCommand.openScreen = null; 35 | } 36 | }); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /fabric/src/main/java/com/oroarmor/config/screen/ModMenuConfigScreen.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config.screen; 26 | 27 | 28 | import com.oroarmor.config.Config; 29 | import com.terraformersmc.modmenu.api.ConfigScreenFactory; 30 | import com.terraformersmc.modmenu.api.ModMenuApi; 31 | 32 | /** 33 | * This class allows for the easy addition of a Mod Menu config screen to your 34 | * mod. The abstract modifier is so that your {@link ModMenuConfigScreen} can be 35 | * used as a entry point for modmenu, as you need to set the config in the 36 | * constructor for this to work.
37 | *
38 | * Add this to your entrypoint list in {@code fabric.mod.json}:
39 | * 40 | * "modmenu" : [
41 | *  "your.package.structure.YourModMenuConfigScreen"
42 | * ] 43 | *
44 | * 45 | * @author Eli Orona 46 | */ 47 | public abstract class ModMenuConfigScreen extends ConfigScreen implements ModMenuApi { 48 | 49 | /** 50 | * Creates a new {@link ModMenuConfigScreen} 51 | * 52 | * @param config The config 53 | */ 54 | public ModMenuConfigScreen(Config config) { 55 | super(config); 56 | } 57 | 58 | 59 | @Override 60 | public ConfigScreenFactory getModConfigScreenFactory() { 61 | return this::createScreen; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /fabric/src/main/resources/fabric.mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 1, 3 | "id": "oro_config", 4 | "version": "${version}", 5 | "name": "OroArmor Config", 6 | "description": "This library adds simple configs to your mod", 7 | "authors": [ 8 | "OroArmor" 9 | ], 10 | "contact": { 11 | }, 12 | "license": "MIT", 13 | "icon": "oro-config_icon.jpg", 14 | "environment": "*", 15 | "entrypoints": { 16 | "client": [ 17 | "com.oroarmor.config.command.ClientCommandHelper::registerOpenScreen" 18 | ] 19 | }, 20 | "depends": { 21 | "fabricloader": ">=0.7.4" 22 | }, 23 | "suggests": { 24 | "flamingo": "*" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /forge-testmod/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.github.johnrengelman.shadow" version "5.0.0" 3 | } 4 | 5 | configurations { 6 | shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this. 7 | } 8 | 9 | architectury { 10 | platformSetupLoomIde() 11 | forge() 12 | } 13 | 14 | loom { 15 | useFabricMixin = true 16 | } 17 | 18 | dependencies { 19 | forge "net.minecraftforge:forge:${rootProject.minecraft_version}-${rootProject.forge_version}" 20 | // Remove the next line if you don't want to depend on the API 21 | 22 | implementation(project(path: ":common")) { 23 | transitive = false 24 | } 25 | developmentForge(project(path: ":common")) { 26 | transitive = false 27 | } 28 | 29 | modImplementation(project(path: ":forge", configuration: "dev")) { 30 | transitive(false) 31 | } 32 | 33 | modImplementation("me.shedaniel.cloth:cloth-config-forge:4.11.14") 34 | } 35 | 36 | processResources { 37 | inputs.property "version", project.version 38 | 39 | filesMatching("META-INF/mods.toml") { 40 | expand "version": project.version 41 | } 42 | } 43 | 44 | shadowJar { 45 | exclude "fabric.mod.json" 46 | classifier "dev-shadow" 47 | } 48 | 49 | remapJar { 50 | input.set shadowJar.archiveFile 51 | dependsOn shadowJar 52 | classifier "forge-testmod" 53 | } 54 | 55 | runClient { 56 | inputs.with { 57 | shadowJar.archiveFile 58 | } 59 | } 60 | 61 | jar { 62 | classifier "dev" 63 | } 64 | 65 | java { 66 | withSourcesJar() 67 | } 68 | 69 | sourcesJar { 70 | def commonSources = project(":common").remapSourcesJar 71 | dependsOn commonSources 72 | from zipTree(commonSources.output) 73 | } 74 | -------------------------------------------------------------------------------- /forge-testmod/gradle.properties: -------------------------------------------------------------------------------- 1 | loom.forge=true -------------------------------------------------------------------------------- /forge-testmod/src/main/java/com/oroarmor/config/testmod/EnumTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config.testmod; 26 | 27 | public enum EnumTest { 28 | A, B, C 29 | } 30 | -------------------------------------------------------------------------------- /forge-testmod/src/main/java/com/oroarmor/config/testmod/OroConfigTestMod.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config.testmod; 26 | 27 | import com.oroarmor.config.Config; 28 | import com.oroarmor.config.command.ConfigCommand; 29 | import com.oroarmor.config.screen.ForgeConfigScreen; 30 | import net.minecraftforge.common.MinecraftForge; 31 | import net.minecraftforge.event.RegisterCommandsEvent; 32 | import net.minecraftforge.fml.ExtensionPoint; 33 | import net.minecraftforge.fml.ModLoadingContext; 34 | import net.minecraftforge.fml.common.Mod; 35 | import net.minecraftforge.fml.event.server.FMLServerStoppedEvent; 36 | 37 | import net.minecraft.server.command.ServerCommandSource; 38 | 39 | @Mod("oroconfig-testmod") 40 | public class OroConfigTestMod { 41 | public static final Config CONFIG = new TestConfig(); 42 | 43 | public OroConfigTestMod() { 44 | CONFIG.readConfigFromFile(); 45 | MinecraftForge.EVENT_BUS.addListener(OroConfigTestMod::serverStoppedEvent); 46 | MinecraftForge.EVENT_BUS.addListener(OroConfigTestMod::registerCommandEvent); 47 | ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.CONFIGGUIFACTORY, () -> new ForgeConfigScreen(CONFIG)); 48 | } 49 | 50 | public static void serverStoppedEvent(FMLServerStoppedEvent event) { 51 | CONFIG.saveConfigToFile(); 52 | } 53 | 54 | public static void registerCommandEvent(RegisterCommandsEvent event) { 55 | new ConfigCommand(CONFIG).register(event.getDispatcher(), c -> c.hasPermissionLevel(2)); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /forge-testmod/src/main/java/com/oroarmor/config/testmod/TestConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config.testmod; 26 | 27 | import java.io.File; 28 | import java.util.List; 29 | 30 | import com.oroarmor.config.*; 31 | import net.minecraftforge.fml.loading.FMLLoader; 32 | 33 | import static com.google.common.collect.ImmutableList.of; 34 | 35 | public class TestConfig extends Config { 36 | public static final ConfigItemGroup mainGroup = new ConfigGroupLevel1(); 37 | 38 | public static final List configs = of(mainGroup); 39 | 40 | public TestConfig() { 41 | super(configs, new File(FMLLoader.getGamePath().resolve("config").toFile(), "oroarmor_config_testmod.json"), "oroarmor_config_testmod"); 42 | } 43 | 44 | public static class ConfigGroupLevel1 extends ConfigItemGroup { 45 | public static final EnumConfigItem testEnum = new EnumConfigItem<>("test_enum", EnumTest.A, "test_enum"); 46 | public static final BooleanConfigItem testItem = new BooleanConfigItem("test_boolean", true, "test_boolean"); 47 | 48 | public static final ArrayConfigItem testArray = new ArrayConfigItem<>("test_array", new Integer[]{1, 2, 3}, "test_array"); 49 | 50 | public ConfigGroupLevel1() { 51 | super(of(new NestedGroup(), testItem, testEnum, testArray), "group"); 52 | } 53 | 54 | public static class NestedGroup extends ConfigItemGroup { 55 | public static final IntegerConfigItem nestedItem = new IntegerConfigItem("test_int", 0, "test_integer"); 56 | 57 | public NestedGroup() { 58 | super(of(nestedItem, new TripleNested()), "nested"); 59 | } 60 | 61 | public static class TripleNested extends ConfigItemGroup { 62 | public static final StringConfigItem testString = new StringConfigItem("test_string", "Default", "test_string"); 63 | 64 | public TripleNested() { 65 | super(of(testString), "triple"); 66 | } 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /forge-testmod/src/main/resources/META-INF/mods.toml: -------------------------------------------------------------------------------- 1 | modLoader = "javafml" 2 | loaderVersion = "[35,)" 3 | #issueTrackerURL = "" 4 | license = "MIT" 5 | 6 | [[mods]] 7 | modId = "oroconfig-testmod" 8 | version = "${version}" 9 | displayName = "Oro Config" 10 | authors = "OroArmor" 11 | description = ''' 12 | This library adds simple configs to your mod 13 | ''' 14 | logoFile = "oro-config.png" 15 | 16 | [[dependencies.oroconfig-testmod]] 17 | modId = "forge" 18 | mandatory = true 19 | versionRange = "[35,)" 20 | ordering = "NONE" 21 | side = "BOTH" 22 | 23 | [[dependencies.oroconfig-testmod]] 24 | modId = "cloth-config" 25 | mandatory = true 26 | versionRange = "[4.11.14,)" 27 | ordering = "AFTER" 28 | side = "CLIENT" -------------------------------------------------------------------------------- /forge-testmod/src/main/resources/pack.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "pack": { 3 | "description": "Example Mod", 4 | "pack_format": 6 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /forge/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.github.johnrengelman.shadow" version "7.1.2" 3 | } 4 | 5 | configurations { 6 | shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this. 7 | dev 8 | } 9 | 10 | architectury { 11 | platformSetupLoomIde() 12 | forge() 13 | } 14 | 15 | artifacts { 16 | dev(jar) 17 | } 18 | 19 | archivesBaseName = rootProject.archives_base_name + "-forge" 20 | version = rootProject.mod_version 21 | group = rootProject.maven_group 22 | 23 | repositories { 24 | maven { url 'https://jitpack.io' } 25 | maven { url 'https://maven.theillusivec4.top/' } 26 | } 27 | 28 | dependencies { 29 | forge "net.minecraftforge:forge:${rootProject.forge_version}" 30 | // Remove the next line if you don't want to depend on the API 31 | modApi "dev.architectury:architectury-forge:${rootProject.architectury_version}" 32 | 33 | modImplementation("me.shedaniel.cloth:cloth-config-forge:${rootProject.cloth_config_version}") 34 | } 35 | 36 | shadowJar { 37 | exclude "fabric.mod.json" 38 | 39 | configurations = [project.configurations.shadowCommon] 40 | //classifier "dev-shadow" 41 | } 42 | 43 | remapJar { 44 | input.set shadowJar.archiveFile 45 | dependsOn shadowJar 46 | 47 | manifest { 48 | getAttributes()["FMLModType"] = "LIBRARY" 49 | } 50 | } 51 | 52 | jar { 53 | //classifier "dev" 54 | 55 | manifest { 56 | getAttributes()["FMLModType"] = "LIBRARY" 57 | } 58 | } 59 | 60 | java { 61 | withSourcesJar() 62 | } 63 | 64 | sourcesJar { 65 | def commonSources = project(":common").remapSourcesJar 66 | dependsOn commonSources 67 | //from zipTree(commonSources.output) 68 | } 69 | 70 | /* 71 | publishing { 72 | publications { 73 | mavenForge(MavenPublication) { 74 | artifactId = "oro-config-forge" 75 | // add all the jars that should be included when publishing to maven 76 | artifact(remapJar) { 77 | classifier null 78 | } 79 | artifact(sourcesJar) { 80 | builtBy remapSourcesJar 81 | } 82 | artifact(javadocJar) { 83 | builtBy javadocJar 84 | } 85 | } 86 | } 87 | 88 | // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. 89 | repositories { 90 | // Add repositories to publish to here. 91 | } 92 | } 93 | 94 | */ 95 | -------------------------------------------------------------------------------- /forge/gradle.properties: -------------------------------------------------------------------------------- 1 | loom.forge=true -------------------------------------------------------------------------------- /forge/src/main/java/com/oroarmor/config/screen/ForgeConfigScreen.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 OroArmor (Eli Orona) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.oroarmor.config.screen; 26 | 27 | import java.util.function.BiFunction; 28 | 29 | import com.oroarmor.config.Config; 30 | 31 | import net.minecraft.client.MinecraftClient; 32 | import net.minecraft.client.gui.screen.Screen; 33 | 34 | public class ForgeConfigScreen extends ConfigScreen implements BiFunction { 35 | public ForgeConfigScreen(Config config) { 36 | super(config); 37 | } 38 | 39 | @Override 40 | public Screen apply(MinecraftClient minecraftClient, Screen screen) { 41 | return createScreen(screen); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /forge/src/main/resources/META-INF/mods.toml: -------------------------------------------------------------------------------- 1 | modLoader = "javafml" 2 | loaderVersion = "[35,)" 3 | #issueTrackerURL = "" 4 | license = "MIT" 5 | 6 | [[mods]] 7 | modId = "oro-config" 8 | version = "${version}" 9 | displayName = "Oro Config" 10 | authors = "OroArmor" 11 | description = ''' 12 | This library adds simple configs to your mod 13 | ''' 14 | logoFile = "oro-config.png" -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx2048M 2 | minecraft_version=1.20.1 3 | archives_base_name=oro-config 4 | mod_version=4.1.0 5 | maven_group=com.oroarmor 6 | 7 | architectury_version=9.0.8 8 | cloth_config_version=11.1.106 9 | 10 | fabric_loader_version=0.14.21 11 | fabric_api_version=0.86.0+1.20.1 12 | 13 | forge_version=1.20.1-47.0.19 -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | # This is normally unused 84 | # shellcheck disable=SC2034 85 | APP_BASE_NAME=${0##*/} 86 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 87 | 88 | # Use the maximum available, or set MAX_FD != -1 to use that value. 89 | MAX_FD=maximum 90 | 91 | warn () { 92 | echo "$*" 93 | } >&2 94 | 95 | die () { 96 | echo 97 | echo "$*" 98 | echo 99 | exit 1 100 | } >&2 101 | 102 | # OS specific support (must be 'true' or 'false'). 103 | cygwin=false 104 | msys=false 105 | darwin=false 106 | nonstop=false 107 | case "$( uname )" in #( 108 | CYGWIN* ) cygwin=true ;; #( 109 | Darwin* ) darwin=true ;; #( 110 | MSYS* | MINGW* ) msys=true ;; #( 111 | NONSTOP* ) nonstop=true ;; 112 | esac 113 | 114 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 115 | 116 | 117 | # Determine the Java command to use to start the JVM. 118 | if [ -n "$JAVA_HOME" ] ; then 119 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 120 | # IBM's JDK on AIX uses strange locations for the executables 121 | JAVACMD=$JAVA_HOME/jre/sh/java 122 | else 123 | JAVACMD=$JAVA_HOME/bin/java 124 | fi 125 | if [ ! -x "$JAVACMD" ] ; then 126 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 127 | 128 | Please set the JAVA_HOME variable in your environment to match the 129 | location of your Java installation." 130 | fi 131 | else 132 | JAVACMD=java 133 | if ! command -v java >/dev/null 2>&1 134 | then 135 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 136 | 137 | Please set the JAVA_HOME variable in your environment to match the 138 | location of your Java installation." 139 | fi 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. 147 | # shellcheck disable=SC3045 148 | MAX_FD=$( ulimit -H -n ) || 149 | warn "Could not query maximum file descriptor limit" 150 | esac 151 | case $MAX_FD in #( 152 | '' | soft) :;; #( 153 | *) 154 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. 155 | # shellcheck disable=SC3045 156 | ulimit -n "$MAX_FD" || 157 | warn "Could not set maximum file descriptor limit to $MAX_FD" 158 | esac 159 | fi 160 | 161 | # Collect all arguments for the java command, stacking in reverse order: 162 | # * args from the command line 163 | # * the main class name 164 | # * -classpath 165 | # * -D...appname settings 166 | # * --module-path (only if needed) 167 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 168 | 169 | # For Cygwin or MSYS, switch paths to Windows format before running java 170 | if "$cygwin" || "$msys" ; then 171 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 172 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 173 | 174 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 175 | 176 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 177 | for arg do 178 | if 179 | case $arg in #( 180 | -*) false ;; # don't mess with options #( 181 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 182 | [ -e "$t" ] ;; #( 183 | *) false ;; 184 | esac 185 | then 186 | arg=$( cygpath --path --ignore --mixed "$arg" ) 187 | fi 188 | # Roll the args list around exactly as many times as the number of 189 | # args, so each arg winds up back in the position where it started, but 190 | # possibly modified. 191 | # 192 | # NB: a `for` loop captures its iteration list before it begins, so 193 | # changing the positional parameters here affects neither the number of 194 | # iterations, nor the values presented in `arg`. 195 | shift # remove old arg 196 | set -- "$@" "$arg" # push replacement arg 197 | done 198 | fi 199 | 200 | 201 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 202 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 203 | 204 | # Collect all arguments for the java command; 205 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 206 | # shell script including quotes and variable substitutions, so put them in 207 | # double quotes to make sure that they get re-expanded; and 208 | # * put everything else in single quotes, so that it's not re-expanded. 209 | 210 | set -- \ 211 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 212 | -classpath "$CLASSPATH" \ 213 | org.gradle.wrapper.GradleWrapperMain \ 214 | "$@" 215 | 216 | # Stop when "xargs" is not available. 217 | if ! command -v xargs >/dev/null 2>&1 218 | then 219 | die "xargs is not available" 220 | fi 221 | 222 | # Use "xargs" to parse quoted args. 223 | # 224 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 225 | # 226 | # In Bash we could simply go: 227 | # 228 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 229 | # set -- "${ARGS[@]}" "$@" 230 | # 231 | # but POSIX shell has neither arrays nor command substitution, so instead we 232 | # post-process each arg (as a line of input to sed) to backslash-escape any 233 | # character that might be a shell metacharacter, then use eval to reverse 234 | # that process (while maintaining the separation between arguments), and wrap 235 | # the whole thing up as a single "set" statement. 236 | # 237 | # This will of course break if any of these variables contains a newline or 238 | # an unmatched quote. 239 | # 240 | 241 | eval "set -- $( 242 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 243 | xargs -n1 | 244 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 245 | tr '\n' ' ' 246 | )" '"$@"' 247 | 248 | exec "$JAVACMD" "$@" 249 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url "https://maven.fabricmc.net/" } 4 | maven { url "https://maven.shedaniel.me/" } 5 | maven { url "https://files.minecraftforge.net/maven/" } 6 | gradlePluginPortal() 7 | } 8 | } 9 | 10 | include("common") 11 | include("fabric") 12 | include("forge") 13 | 14 | //include("fabric-testmod") 15 | //include("forge-testmod") 16 | 17 | rootProject.name = "oro-config" 18 | --------------------------------------------------------------------------------