Compare commits

..
Author SHA1 Message Date
big-duckie da2ffa19ff Add actions support.
release / build (21) (push) Successful in 12m1s
2025-01-01 14:27:06 -07:00
big-duckie 412ab2c1d0 Fix up some issues. 2025-01-01 14:25:39 -07:00
frqnny 8b2f1db5e9 let's see if this fixes things? 2024-06-17 14:19:40 -04:00
Draylar 5f19348fdc 1.20.1 update without Omega Config GUI 2023-07-01 16:30:59 -05:00
Draylar 505d3e70f8 1.19.2 update with maven publishing and README polishing 2023-03-01 21:16:38 -06:00
DraylarandGitHub 239ec7c3bc 1.2.3 version bump 2022-01-18 11:14:38 -06:00
DraylarandGitHub 0f0abe558e Merge pull request #12 from Luligabi1/1.18
Better config screen title
2022-01-18 11:14:04 -06:00
Luligabi1 5bdce25e29 OmegaConfigGui's generated config screen now has a TranslatableText for its title rather than a LiteralText.q 2021-12-28 15:07:41 -03:00
frqnny 9d7aa7581d Automated fabric mod json version
Closes #11
2021-12-28 10:58:42 -05:00
Draylar 8611edb92c update README 2021-12-20 18:38:58 -06:00
Draylar 58c420d35f add null check for modid when registering modmenu screens 2021-12-20 17:52:54 -06:00
Draylar 270db37dba fix omega config class loading too early in static block, make modmenu dep transitive 2021-12-20 17:41:14 -06:00
Draylar 2968111445 Move ModMenu dependency to the GUI module 2021-12-20 17:20:50 -06:00
Draylar 136cfe6a9a fix classloading for mod menu by moving registration methods to OmegaConfigGui class, fix versioning 2021-12-20 17:16:02 -06:00
Draylar 3f7c461689 Add mod icons, finish GUI support through Cloth Config Lite 2021-12-20 16:40:03 -06:00
Draylar 36ce7bc924 🦀 proguard is dead, clean up build.gradle 2021-12-20 15:23:52 -06:00
DraylarandGitHub a3cde2c8e7 JDK17 for JitPack.yml on 1.18 2021-12-13 20:39:14 -06:00
DraylarandGitHub 6fa8e58665 Merge pull request #7 from Luligabi1/1.17
Updates to 1.18.1
2021-12-13 20:37:46 -06:00
Luligabi1 ed4e9f6c19 Updates to 1.18.1 2021-12-11 15:09:18 -03:00
DraylarandGitHub 24c0d9a039 Version bump to 1.1.0 2021-12-09 00:13:32 -06:00
DraylarandGitHub 6db4f12eed Merge pull request #6 from RDKRACZ/patch-1
Add "library" badge for ModMenu; Add contact tags to the fabric.mod.json file.
2021-12-09 00:13:04 -06:00
DraylarandGitHub 6ed97d4e00 Merge pull request #4 from alkyaly/fix/comments-in-nested-classes
Fixes comments not applying when inside nested classes.
2021-12-09 00:11:55 -06:00
DraylarandGitHub 3ecbae5593 Merge pull request #5 from alkyaly/fix/multiline
Fixes multi-line comments breaking
2021-12-09 00:11:44 -06:00
K0RRandGitHub d15fcd0732 Update gradle.properties 2021-09-09 12:42:47 +02:00
K0RRandGitHub bd2cc57eb9 Update fabric.mod.json 2021-08-18 13:20:55 +02:00
K0RRandGitHub 539d3ee1af Update gradle-wrapper.properties 2021-08-18 13:18:37 +02:00
adrianoy ebfaac9fb9 Add multiline comments more sensibly... 2021-08-10 01:21:53 -03:00
K0RRandGitHub fbc0a2b354 Add "library" badge for ModMenu; Add contact tags to the fabric.mod.json file.
>It aims to achieve the following goals:
Be lightweight (<10 KB) for JIJ usage

It's 15 KB already :)
2021-08-04 20:18:04 +02:00
adrianoy 3da79e7860 Fixes multi-line comments breaking 2021-07-28 03:38:36 -03:00
adrianoy 228c1bb7e6 This check does nothing. 2021-07-25 23:54:52 -03:00
adrianoy e09f903332 oops. 2021-07-25 22:21:02 -03:00
adrianoy 1fe4d53565 Makes comments apply when inside nested classes of nested classes. 2021-07-25 22:20:35 -03:00
DraylarandGitHub 48f5962f57 Merge pull request #3 from frqnny/modularize
Some more important changes
2021-06-15 23:06:11 -05:00
ffrann 6099b30f3d Add new mo structures as test 2021-06-15 23:48:09 -04:00
ffrann 09658ffee6 Fix mixin compat level being set to JAVA_16
Delete NoValidConstructorException.java (waste of space smh)
2021-06-15 23:39:08 -04:00
ffrann b6b7a67866 1.0.7 update :) 2021-06-11 12:08:11 -04:00
DraylarandGitHub 73730feced Merge pull request #2 from frqnny/modularize
Port to java 16 and MC 1.17
2021-05-27 10:43:32 -05:00
ffrann f468546eea Port to java 16 and MC 1.17 2021-05-26 20:27:14 -04:00
Draylar c2d7cacdab different approach to jitpack j16 support 2021-05-26 14:52:34 -05:00
Draylar c21e5ff3ff force openjdk16 for jitpack 2021-05-26 14:43:31 -05:00
Draylar a6d2e3b1f8 1.0.5 update 2021-05-26 14:30:56 -05:00
Draylar 0ff71f0a09 add support for gradle 7 / j16 2021-05-26 14:30:32 -05:00
Draylar 1b636fa0d8 adjust class config test 2021-04-05 19:19:56 -05:00
Draylar 1e3e886346 adjust error handling to catch all errors when reading config 2021-04-03 17:23:36 -05:00
Draylar 8b42f5a9c5 refactor tests + add static class test 2021-04-03 17:14:37 -05:00
Draylar 9e9eac06fc implement custom file extensions and directories with appropriate tests, vbump to 1.0.4 2021-03-25 11:32:56 -05:00
Draylar 4e24988fa3 steal mo structures config for testing and make it workm, 1.0.3 2021-03-13 17:17:40 -06:00
Draylar e0f1ef8b5e vbump to 1.0.2 2021-03-13 16:19:27 -06:00
Draylar c6e72489cc add proguard output to gitignore 2021-03-13 16:19:16 -06:00
Draylar a2611a3302 wildcard deps for loader and mc versions 2021-03-13 16:19:06 -06:00
Draylar 3b0aec9ab5 1.0.1 version bump + probably fix modmenu dep 2021-03-13 15:30:29 -06:00
Draylar f9c9cd5745 modImplementation -> modRuntime 2021-03-13 15:27:52 -06:00
45 changed files with 644 additions and 830 deletions
+43
View File
@@ -0,0 +1,43 @@
name: release
on:
push:
tags:
- "*"
env:
VERSION: "${{github.ref_name}}"
jobs:
build:
strategy:
matrix:
java: [
21, # Current Java LTS
]
runs-on: ubuntu-22.04
steps:
- name: checkout repository
uses: actions/checkout@v4
- name: validate gradle wrapper
uses: gradle/wrapper-validation-action@v2
- name: setup jdk ${{ matrix.java }}
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java }}
distribution: "temurin"
- name: make gradle wrapper executable
run: chmod +x ./gradlew
- name: build
run: ./gradlew build
- name: publish maven
continue-on-error: true
env:
MAVEN_TOKEN: "${{secrets.MAVEN_TOKEN}}"
run: ./gradlew publish
- name: publish release
uses: akkuman/gitea-release-action@v1
with:
files: |-
build/libs/**
token: "${{secrets.GITHUB_TOKEN}}"
+2
View File
@@ -123,3 +123,5 @@ run/
/run/ /run/
/server-run/ /server-run/
/out.map /out.map
/omega-config-base/out.map
/omega-config-gui/out.map
+80 -7
View File
@@ -1,22 +1,28 @@
# ΩConfig <h1 align="center">Omega Config Ω </h1>
<p align="center">A configuration library by <a href="https://github.com/Draylar">Draylar</a></p>
--- ---
*The last config library you will ever use.* ΩConfig is a hyper-minimal config library based on [Auto Config](https://github.com/shedaniel/AutoConfig). It aims to
achieve the following goals:
ΩConfig is a hyper-minimal config library based on [Auto Config](https://github.com/shedaniel/AutoConfig). It aims to achieve - Be lightweight (<25 KB) for JIJ usage
the following goals:
- Be lightweight (<10 KB) for JIJ usage
- Exceedingly simple design & API for developers - Exceedingly simple design & API for developers
- Intuition and usability for players - Intuition and usability for players
- Bonus annotations for advanced config options (syncing values)
The following is an example of a simple ΩConfig setup: The following is an example of a simple ΩConfig setup:
```java ```java
public class TestConfig implements Config { public class TestConfig implements Config {
@Comment(value = "Hello!") @Comment(value = "Hello!")
boolean value = false; boolean value = false;
@Syncing
@Comment(value = "This value will sync to the client!")
boolean syncableValue = false;
@Override @Override
public String getFileName() { public String getFileName() {
return "test-config"; return "test-config";
@@ -24,6 +30,7 @@ public class TestConfig implements Config {
} }
``` ```
```java ```java
public class MyModInitializer { public class MyModInitializer {
@@ -35,7 +42,69 @@ public class MyModInitializer {
} }
} }
``` ```
Looking for a simple config screen? Talk about easy!
```java
public class ClientInitializer implements ClientModInitializer {
@Override
public void onInitializeClient() {
// Make sure you implement getModid in your config class!
OmegaConfigGui.registerConfigScreen(MainInitializer.CONFIG);
}
}
```
--- ---
### Pulling Omega Config into Development
To use Omega Config, you will have to add it to your build.gradle file.
What you pull in depends on whether you want GUI functionality. For basic config files using the base module (~20KB),
you can use the following gradle declarations:
```groovy
repositories {
maven { url 'https://maven.draylar.dev/releases' }
}
// 1.19.2 version: 1.3.0+1.19.2
dependencies {
modImplementation include("dev.draylar.omega-config:omega-config-base:${project.omega_config_version}")
}
```
Easy - you now have a bundled configuration library. Use the examples in the first section to implement your config.
If you want to add GUI functionality (most likely Mod Menu support), you can pull in the GUI module (~25 KB):
```groovy
repositories {
...
// Needed to retrieve Cloth Config Lite for Omega Config in development environments.
maven {
name = "Shedaniel's Maven"
url = "https://maven.shedaniel.me/"
}
// Optional dependency for Mod Menu - recommended for viewing your screen in development
maven {
name = "TerraformersMC"
url = "https://maven.terraformersmc.com/releases/"
}
}
dependencies {
... (including the base declarations)
modImplementation include("dev.draylar.omega-config:omega-config-gui:${project.omega_config_version}")
modRuntimeOnly ("com.terraformersmc:modmenu:${project.modmenu_version}") // 3.0.1 for 1.18.1
}
```
---
### Extra API Utilities ### Extra API Utilities
ΩConfig provides several utility methods for developers. ΩConfig provides several utility methods for developers.
@@ -47,7 +116,11 @@ MyModInitializer.CONFIG.value = false;
MyModInitializer.CONFIG.save(); // writes the new value to disk MyModInitializer.CONFIG.save(); // writes the new value to disk
``` ```
`@Syncing` - *configuration options marked with this annotation will automatically sync to the client when they join a server.*
--- ---
### License ### License
ΩConfig is available under Public Domain.
You are encouraged to utilize the code in this repository in any way you wish. ΩConfig is available under MIT. Omega Config will bundle the MIT license inside the jar you pull as a dependency, which means you can distribute it as a bundled dependency without any additional steps.
+74 -197
View File
@@ -1,238 +1,115 @@
import java.nio.charset.StandardCharsets
// this build.gradle is tweaked from CCA: https://github.com/OnyxStudios/Cardinal-Components-API/blob/master/build.gradle
buildscript {
repositories {
mavenLocal()
jcenter()
google()
}
dependencies {
classpath 'com.guardsquare:proguard-gradle:7.0.1'
}
}
plugins { plugins {
id "fabric-loom" version "0.7-SNAPSHOT" id 'fabric-loom' version '1.8-SNAPSHOT'
id "maven-publish" id 'maven-publish'
id "java-library"
} }
group = "draylar" if (System.getenv("VERSION")) {
archivesBaseName = "omega-config" project.mod_version = System.getenv("VERSION")
subprojects {
apply plugin: 'fabric-loom'
apply plugin: 'maven-publish'
apply plugin: 'java-library'
archivesBaseName = project.name
group = "draylar.${project.group}"
// import utility functions
apply from: "https://raw.githubusercontent.com/NerdHubMC/Gradle-Scripts/master/scripts/utilities.gradle"
repositories {
mavenCentral()
} }
compileJava { version = "${project.mod_version}"
options.encoding = StandardCharsets.UTF_8.name() group = "dev.draylar"
}
if (JavaVersion.current().isJava8Compatible()) { base {
allprojects { archivesName = "omega-config"
tasks.withType(Javadoc) {
options.addStringOption("Xdoclint:none", "-quiet")
}
}
}
jar {
from "LICENSE.md"
from "LICENSE"
manifest.mainAttributes(
"Implementation-Title": project.archivesBaseName,
"Implementation-Version": mod_version,
"Maven-Artifact": "${project.group}:${project.name}:${mod_version}".toLowerCase(Locale.ROOT),
"Built-On-Minecraft": "${project.minecraft_version}",
"Built-On-Java": "${System.getProperty("java.vm.version")} (${System.getProperty("java.vm.vendor")})"
)
}
task sourcesJar(type: Jar, dependsOn: classes) {
from sourceSets.main.allSource
classifier = "sources"
}
task javadocJar(type: Jar, dependsOn: javadoc) {
from javadoc.destinationDir
classifier = "javadoc"
}
tasks.build.dependsOn javadocJar
publishing {
publications {
mavenJava(MavenPublication) {
artifact(remapJar) {
builtBy remapJar
}
artifact(sourcesJar) {
builtBy remapSourcesJar
}
artifact(file("${project.buildDir}/libs/${archivesBaseName}-${project.mod_version}-min.jar")) {
builtBy(remapJar)
classifier = 'min'
}
pom.withXml {
def depsNode = asNode().appendNode("dependencies")
subprojects.each {
def depNode = depsNode.appendNode("dependency")
depNode.appendNode("groupId", it.group)
depNode.appendNode("artifactId", it.name)
depNode.appendNode("version", it.version)
depNode.appendNode("scope", "compile")
}
}
}
}
}
tasks.publish.dependsOn build //stupid fix for maven/loom not publishing the main artifact
task ('proguard', type: proguard.gradle.ProGuardTask) {
configuration './proguard.conf'
verbose
injars project.buildDir.toString() + '/libs/' + archivesBaseName + "-" + project.mod_version + ".jar"
outjars project.buildDir.toString() + '/libs/' + archivesBaseName + "-" + project.mod_version + "-min.jar"
printmapping 'out.map'
keepparameternames
renamesourcefileattribute 'SourceFile'
keepattributes 'Signature,Exceptions,InnerClasses,PermittedSubclasses,EnclosingMethod,Deprecated,SourceFile,LineNumberTable'
keepattributes '*Annotation*'
keep 'public class * { \
public protected *; \
}'
keepclassmembernames 'class * { \
java.lang.Class class$(java.lang.String); \
java.lang.Class class$(java.lang.String, boolean); \
}'
keepclassmembers 'class draylar.omegaconfig.mixin.* {\
<fields>;\
<init>();\
<methods>;\
}'
}
remapJar.finalizedBy proguard
} }
allprojects { allprojects {
apply plugin: "fabric-loom" apply plugin: "fabric-loom"
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_17
version = project.mod_version
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_1_8 repositories {}
version = System.getenv("TRAVIS_TAG") ?: project.mod_version
repositories {
maven {
name = "FabricMC"
url = "https://maven.fabricmc.net"
}
maven { url = "https://maven.terraformersmc.com/releases/"}
}
dependencies { dependencies {
//to change the versions see the gradle.properties file
minecraft "com.mojang:minecraft:${project.minecraft_version}" minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
modImplementation "com.terraformersmc:modmenu:1.16.8"
} }
processResources { processResources {
// this will ensure that this task is redone when there"s a change inputs.property "version", project.version
inputs.property "version", mod_version
// replace stuff in fabric.mod.json, nothing else filesMatching("fabric.mod.json") {
from(sourceSets.main.resources.srcDirs) { expand "version": project.version
include "fabric.mod.json" }
// add mod metadata
expand "version": mod_version
} }
// copy everything else, that"s not the fabric.mod.json tasks.withType(JavaCompile).configureEach {
from(sourceSets.main.resources.srcDirs) { it.options.release = 17
exclude "fabric.mod.json" javadoc.options.addStringOption('Xdoclint:none', '-quiet')
}
} }
jar { jar {
from(rootProject.file("LICENSE.md")) { from(rootProject.file("LICENSE")) {
rename { "LICENSE_${project.archivesBaseName.replace('-', '_')}" } rename { "LICENSE_${project.archivesBaseName.replace('-', '_')}" }
} }
} }
} }
subprojects {
apply plugin: 'fabric-loom'
apply plugin: 'maven-publish'
archivesBaseName = project.name
group = "dev.draylar.${project.group}"
// Only publish for submodules (not the root project) - add standard jar, + sources & development jar
publishing {
publications {
create("mavenJava", MavenPublication) {
artifactId = project.archives_base_name
version = "${project.mod_version}+${project.minecraft_version}"
from components.java
}
}
repositories {
// Add repositories to publish to here.
// Notice: This block does NOT have the same function as the block in the top level.
// The repositories here will be used for publishing your artifact, not for
// retrieving dependencies.
maven {
name = "Gitea"
url = uri("https://git.bigduckie.dev/api/packages/big-duckie/maven")
credentials(HttpHeaderCredentials) {
name = "Authorization"
value = "token ${System.getenv("MAVEN_TOKEN")}"
}
authentication {
header(HttpHeaderAuthentication)
}
}
}
}
// Add sources & javadoc artifacts
java {
withSourcesJar()
withJavadocJar()
}
}
// Main project depends on the base & gui module for testing
dependencies {
implementation project(path: ":omega-config-base", configuration: "namedElements")
afterEvaluate {
testmodImplementation sourceSets.main.output
}
}
sourceSets { sourceSets {
testmod { testmod {
compileClasspath += main.compileClasspath compileClasspath += main.compileClasspath
runtimeClasspath += main.runtimeClasspath runtimeClasspath += main.runtimeClasspath
} }
test { test {
compileClasspath += main.compileClasspath compileClasspath += main.compileClasspath
runtimeClasspath += main.runtimeClasspath runtimeClasspath += main.runtimeClasspath
} }
} }
task licenseFormatAll
subprojects { p -> licenseFormatAll.dependsOn("${p.path}:licenseFormat") }
subprojects.each { remapJar.dependsOn("${it.path}:remapJar") }
repositories {
maven {
name = "JitPack"
url = "https://jitpack.io"
}
}
dependencies {
compile project(":omega-config-base")
compile project(":omega-config-gui")
afterEvaluate {
testmodImplementation sourceSets.main.output
}
}
publishing {
publications {
mavenJava(MavenPublication) {
artifact(file("${project.buildDir}/libs/${archivesBaseName}-${project.mod_version}.jar")) {
builtBy(remapJar)
}
pom.withXml {
def depsNode = asNode().appendNode("dependencies")
subprojects.each {
def depNode = depsNode.appendNode("dependency")
depNode.appendNode("groupId", it.group)
depNode.appendNode("artifactId", it.name)
depNode.appendNode("version", it.version)
depNode.appendNode("scope", "compile")
}
}
}
}
}
tasks.publish.dependsOn build //stupid fix for maven/loom not publishing the main artifact
+10 -8
View File
@@ -1,17 +1,19 @@
# Done to increase the memory available to gradle. # Done to increase the memory available to gradle.
org.gradle.jvmargs=-Xmx1G org.gradle.jvmargs=-Xmx1G
org.gradle.parallel=true
# Fabric Properties # Fabric Properties
# check these on https://modmuss50.me/fabric.html # check these on https://fabricmc.net/versions.html
minecraft_version=1.16.5 minecraft_version=1.20.1
yarn_mappings=1.16.5+build.5 yarn_mappings=1.20.1+build.10
loader_version=0.11.2 loader_version=0.16.7
# Mod Properties # Mod Properties
mod_version=1.0.0 mod_version=1.4.1
maven_group=draylar maven_group=dev.bigduckie
archives_base_name=omega-config archives_base_name=omega-config
# Dependencies # Dependencies
# check this on https://modmuss50.me/fabric.html fabric_version=0.92.2+1.20.1
fabric_version=0.32.0+1.16
modmenu_version=7.1.0
+3 -1
View File
@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
-3
View File
@@ -1,3 +0,0 @@
-ignorewarnings
-keep class net.fabricmc.api.** { *; }
@@ -4,14 +4,14 @@ import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import draylar.omegaconfig.api.Comment; import draylar.omegaconfig.api.Comment;
import draylar.omegaconfig.api.Config; import draylar.omegaconfig.api.Config;
import draylar.omegaconfig.exception.NoValidConstructorException;
import draylar.omegaconfig.gson.SyncableExclusionStrategy; import draylar.omegaconfig.gson.SyncableExclusionStrategy;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents; import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.ListTag; import net.minecraft.nbt.NbtList;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
@@ -24,25 +24,29 @@ import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.*; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
public class OmegaConfig { public class OmegaConfig implements ModInitializer {
private static final Logger LOGGER = LogManager.getLogger();
private static final List<Config> REGISTERED_CONFIGURATIONS = new ArrayList<>();
public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
public static final Identifier CONFIG_SYNC_PACKET = new Identifier("omegaconfig", "sync"); public static final Identifier CONFIG_SYNC_PACKET = new Identifier("omegaconfig", "sync");
public static final Gson SYNC_ONLY_GSON = new GsonBuilder().addSerializationExclusionStrategy(new SyncableExclusionStrategy()).setPrettyPrinting().create(); public static final Gson SYNC_ONLY_GSON = new GsonBuilder().addSerializationExclusionStrategy(new SyncableExclusionStrategy()).setPrettyPrinting().create();
public static final Logger LOGGER = LogManager.getLogger();
private static final List<Config> REGISTERED_CONFIGURATIONS = new ArrayList<>();
static { @Override
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> { public void onInitialize() {
server.execute(() -> { ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> server.execute(() -> {
PacketByteBuf packet = new PacketByteBuf(Unpooled.buffer()); PacketByteBuf packet = new PacketByteBuf(Unpooled.buffer());
// list of configurations that are synced // list of configurations that are synced
CompoundTag root = new CompoundTag(); NbtCompound root = new NbtCompound();
ListTag configurations = new ListTag(); NbtList configurations = new NbtList();
// Iterate over each configuration. // Iterate over each configuration.
// Find values that should be synced and send the value over. // Find values that should be synced and send the value over.
@@ -54,10 +58,9 @@ public class OmegaConfig {
// save to packet and send to user // save to packet and send to user
root.put("Configurations", configurations); root.put("Configurations", configurations);
packet.writeCompoundTag(root); packet.writeNbt(root);
handler.sendPacket(ServerPlayNetworking.createS2CPacket(CONFIG_SYNC_PACKET, packet)); handler.sendPacket(ServerPlayNetworking.createS2CPacket(CONFIG_SYNC_PACKET, packet));
}); }));
});
} }
public static <T extends Config> T register(Class<T> configClass) { public static <T extends Config> T register(Class<T> configClass) {
@@ -70,7 +73,7 @@ public class OmegaConfig {
// 1. serialize to disk if the config does not already exist // 1. serialize to disk if the config does not already exist
// 2. read from disk if it does exist // 2. read from disk if it does exist
if (!configExists(config)) { if (!configExists(config)) {
writeConfig(configClass, config); config.save();
REGISTERED_CONFIGURATIONS.add(config); REGISTERED_CONFIGURATIONS.add(config);
} else { } else {
try { try {
@@ -82,18 +85,21 @@ public class OmegaConfig {
T object = GSON.fromJson(res.toString(), configClass); T object = GSON.fromJson(res.toString(), configClass);
// re-write the config to add new values // re-write the config to add new values
writeConfig(configClass, object); object.save();
REGISTERED_CONFIGURATIONS.add(object); REGISTERED_CONFIGURATIONS.add(object);
return object; return object;
} catch (IOException ioException) { } catch (Exception e) {
LOGGER.error(ioException); LOGGER.error(e);
LOGGER.info(String.format("Read error, using default values for config %s.", configClass.toString())); LOGGER.info(String.format("Encountered an error while reading %s config, falling back to default values.", config.getName()));
LOGGER.info(String.format("If this problem persists, delete the config file %s and try again.", config.getName() + "." + config.getExtension()));
} }
} }
return config; return config;
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException exception) { } catch (NoSuchMethodException | InstantiationException | IllegalAccessException |
throw new NoValidConstructorException(); InvocationTargetException e) {
e.printStackTrace();
throw new RuntimeException("No valid constructor found for: " + configClass.getName());
} }
} }
@@ -103,7 +109,7 @@ public class OmegaConfig {
// Cursed time. // Cursed time.
List<String> lines = new ArrayList<>(Arrays.asList(json.split("\n"))); List<String> lines = new ArrayList<>(Arrays.asList(json.split("\n")));
Map<Integer, String> insertions = new HashMap<>(); Map<Integer, String> insertions = new TreeMap<>();
Map<String, String> keyToComments = new HashMap<>(); Map<String, String> keyToComments = new HashMap<>();
// populate key -> comments map // populate key -> comments map
@@ -111,10 +117,9 @@ public class OmegaConfig {
addFieldComments(field, keyToComments); addFieldComments(field, keyToComments);
} }
// get inner-class fields // "flattens" all the inner classes of the Config class into a single list
// TODO: recursively get inner classes? for (Class<?> clazz : flatten(configClass.getDeclaredClasses())) {
for(Class<?> innerClass : configClass.getDeclaredClasses()) { for (Field field : clazz.getDeclaredFields()) {
for(Field field : innerClass.getDeclaredFields()) {
addFieldComments(field, keyToComments); addFieldComments(field, keyToComments);
} }
} }
@@ -122,31 +127,61 @@ public class OmegaConfig {
// Find areas we should insert comments into... // Find areas we should insert comments into...
for (int i = 0; i < lines.size(); i++) { for (int i = 0; i < lines.size(); i++) {
String at = lines.get(i); String at = lines.get(i);
String startingWhitespace = getStartingWhitespace(at);
// Check if we should insert comment
for (Map.Entry<String, String> entry : keyToComments.entrySet()) { for (Map.Entry<String, String> entry : keyToComments.entrySet()) {
String key = entry.getKey();
String comment = entry.getValue(); String comment = entry.getValue();
// Check if we should insert comment
if (at.trim().startsWith(String.format("\"%s\"", key))) { if (at.trim().startsWith(String.format("\"%s\"", entry.getKey()))) {
insertions.put(i + insertions.size(), String.format("%s//%s", getStartingWhitespace(at), comment)); if (comment.contains("\n")) {
comment = startingWhitespace + "//" + String.join(String.format("\n%s//", startingWhitespace), comment.split("\n"));
} else {
comment = String.format("%s//%s", startingWhitespace, comment);
}
insertions.put(i + insertions.size(), comment);
break; break;
} }
} }
} }
// insertions -> list // insertions -> list
insertions.forEach(lines::add); for (Map.Entry<Integer, String> entry : insertions.entrySet()) {
Integer key = entry.getKey();
String value = entry.getValue();
lines.add(key, value);
}
// list -> string // list -> string
StringBuilder res = new StringBuilder(); StringBuilder res = new StringBuilder();
lines.forEach(str -> res.append(String.format("%s%n", str))); lines.forEach(str -> res.append(String.format("%s%n", str)));
try { try {
Files.write(getConfigPath(instance), res.toString().getBytes()); Path configPath = getConfigPath(instance);
configPath.toFile().getParentFile().mkdirs();
Files.write(configPath, res.toString().getBytes());
} catch (IOException ioException) { } catch (IOException ioException) {
LOGGER.error(ioException); LOGGER.error(ioException);
LOGGER.info(String.format("Write error, using default values for config %s.", configClass.toString())); LOGGER.info(String.format("Write error, using default values for config %s.", configClass));
}
}
public static List<Class<?>> flatten(Class<?>[] array) {
List<Class<?>> list = new ArrayList<>();
for (Class<?> clazz : array) {
populateRecursively(list, clazz);
}
return list;
}
private static void populateRecursively(List<Class<?>> list, Class<?> aClass) {
list.add(aClass);
Class<?>[] classes = aClass.getDeclaredClasses();
for (Class<?> clazz : classes) {
populateRecursively(list, clazz);
} }
} }
@@ -195,7 +230,7 @@ public class OmegaConfig {
} }
public static Path getConfigPath(Config config) { public static Path getConfigPath(Config config) {
return Paths.get(FabricLoader.getInstance().getConfigDir().toString(), String.format("%s.json", config.getName())); return Paths.get(FabricLoader.getInstance().getConfigDir().toString(), config.getDirectory(), String.format("%s.%s", config.getName(), config.getExtension()));
} }
public static boolean configExists(Config config) { public static boolean configExists(Config config) {
@@ -1,7 +1,7 @@
package draylar.omegaconfig.api; package draylar.omegaconfig.api;
import draylar.omegaconfig.OmegaConfig; import draylar.omegaconfig.OmegaConfig;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtCompound;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Arrays; import java.util.Arrays;
@@ -16,8 +16,8 @@ public interface Config {
OmegaConfig.writeConfig((Class<Config>) getClass(), this); OmegaConfig.writeConfig((Class<Config>) getClass(), this);
} }
default CompoundTag writeSyncingTag() { default NbtCompound writeSyncingTag() {
CompoundTag tag = new CompoundTag(); NbtCompound tag = new NbtCompound();
tag.putString("ConfigName", getName()); tag.putString("ConfigName", getName());
// all config vs. individual fields // all config vs. individual fields
@@ -67,7 +67,7 @@ public interface Config {
* modids for configuration screen instances in their menu. * modids for configuration screen instances in their menu.
* If you are intending for this config to have a ModMenu config * If you are intending for this config to have a ModMenu config
* screen, this method should return the modid specified in your fabric.mod.json. * screen, this method should return the modid specified in your fabric.mod.json.
* * <p>
* If this method is not overridden, null will be returned, which * If this method is not overridden, null will be returned, which
* means this config is not explicitly associated with any particular mod. * means this config is not explicitly associated with any particular mod.
* *
@@ -78,7 +78,33 @@ public interface Config {
return null; return null;
} }
default boolean hasMenu() { /**
return true; * Returns the file extension of this config.
*
* <p>
* The file extension is used while serializing this config to a local file.
* The primary use-case of switching this would be supporting existing config files
* when porting from other json5 config libraries.
*
* @return the file extension of this config
*/
default String getExtension() {
return "json";
}
/**
* Returns the directory of this config, assuming the base directory is the instance config directory.
*
* <p>
* By default, a config such as 'my_config' will appear at /config/my_config.json.
* If this method specifies a directory, such as 'configurations',
* the config file will appear at /config/configurations/my_config.json.
* <p>
* Nested directories can be specified by using a string such as 'configurations/client'.
*
* @return the directory of this config
*/
default String getDirectory() {
return "";
} }
} }
@@ -1,5 +0,0 @@
package draylar.omegaconfig.exception;
public class NoValidConstructorException extends RuntimeException {
}
@@ -3,13 +3,13 @@ package draylar.omegaconfig.mixin;
import draylar.omegaconfig.OmegaConfig; import draylar.omegaconfig.OmegaConfig;
import draylar.omegaconfig.api.Config; import draylar.omegaconfig.api.Config;
import draylar.omegaconfig.api.Syncing; import draylar.omegaconfig.api.Syncing;
import net.fabricmc.fabric.api.network.ClientSidePacketRegistry; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.util.NbtType; import net.fabricmc.fabric.api.util.NbtType;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.RunArgs; import net.minecraft.client.RunArgs;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtElement;
import net.minecraft.nbt.ListTag; import net.minecraft.nbt.NbtList;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
@@ -31,15 +31,15 @@ public class ClientMixin {
method = "<init>", method = "<init>",
at = @At("RETURN")) at = @At("RETURN"))
private void onReturn(RunArgs args, CallbackInfo ci) { private void onReturn(RunArgs args, CallbackInfo ci) {
ClientSidePacketRegistry.INSTANCE.register(OmegaConfig.CONFIG_SYNC_PACKET, (context, buffer) -> { ClientPlayNetworking.registerGlobalReceiver(OmegaConfig.CONFIG_SYNC_PACKET, (client, handler, buf, responseSender) -> {
CompoundTag tag = buffer.readCompoundTag(); NbtCompound tag = buf.readNbt();
savedClientConfig.clear(); savedClientConfig.clear();
context.getTaskQueue().execute(() -> { client.execute(() -> {
if (tag != null && tag.contains("Configurations")) { if (tag != null && tag.contains("Configurations")) {
ListTag list = tag.getList("Configurations", NbtType.COMPOUND); NbtList list = tag.getList("Configurations", NbtElement.COMPOUND_TYPE);
list.forEach(compound -> { list.forEach(compound -> {
CompoundTag syncedConfiguration = (CompoundTag) compound; NbtCompound syncedConfiguration = (NbtCompound) compound;
String name = syncedConfiguration.getString("ConfigName"); String name = syncedConfiguration.getString("ConfigName");
String json = syncedConfiguration.getString("Serialized"); String json = syncedConfiguration.getString("Serialized");
boolean allSync = syncedConfiguration.getBoolean("AllSync"); boolean allSync = syncedConfiguration.getBoolean("AllSync");
@@ -79,7 +79,7 @@ public class ClientMixin {
@Inject( @Inject(
method = "disconnect(Lnet/minecraft/client/gui/screen/Screen;)V", method = "disconnect(Lnet/minecraft/client/gui/screen/Screen;)V",
at = @At("RETURN")) at = @At("RETURN"))
private void restoreConfigurations(Screen screen, CallbackInfo ci) { private void restoreConfigurations(CallbackInfo ci) {
for (Config config : savedClientConfig) { for (Config config : savedClientConfig) {
for (Config potentiallySynced : OmegaConfig.getRegisteredConfigurations()) { for (Config potentiallySynced : OmegaConfig.getRegisteredConfigurations()) {
if (config.getName().equals(potentiallySynced.getName())) { if (config.getName().equals(potentiallySynced.getName())) {
Binary file not shown.

After

Width:  |  Height:  |  Size: 225 B

@@ -5,17 +5,35 @@
"name": "OmegaConfig", "name": "OmegaConfig",
"description": "The last config solution you will ever use.", "description": "The last config solution you will ever use.",
"authors": [ "authors": [
"Draylar" "Draylar",
"Frqnny",
"Big Duckie"
], ],
"contact": {}, "entrypoints": {
"main": [
"draylar.omegaconfig.OmegaConfig"
]
},
"contact": {
"homepage": "https://github.com/Draylar/omega-config",
"sources": "https://github.com/Draylar/omega-config",
"issues": "https://github.com/Draylar/omega-config/issues"
},
"license": "MIT", "license": "MIT",
"environment": "*", "environment": "*",
"mixins": [ "mixins": [
"omega-config.mixins.json" "omega-config.mixins.json"
], ],
"depends": { "depends": {
"fabricloader": ">=0.11.2", "fabricloader": "*",
"fabric": "*", "fabric": "*",
"minecraft": "1.16.5" "minecraft": "*"
},
"custom": {
"modmenu": {
"badges": [
"library"
]
}
} }
} }
@@ -2,9 +2,8 @@
"required": true, "required": true,
"minVersion": "0.8", "minVersion": "0.8",
"package": "draylar.omegaconfig.mixin", "package": "draylar.omegaconfig.mixin",
"compatibilityLevel": "JAVA_8", "compatibilityLevel": "JAVA_16",
"mixins": [ "mixins": [
], ],
"client": [ "client": [
"ClientMixin" "ClientMixin"
-3
View File
@@ -1,3 +0,0 @@
dependencies {
compile project(":omega-config-base")
}
-3
View File
@@ -1,3 +0,0 @@
-ignorewarnings
-keep class net.fabricmc.api.** { *; }
@@ -1,23 +0,0 @@
package draylar.omegaconfiggui;
import draylar.omegaconfig.api.Config;
import draylar.omegaconfiggui.api.screen.ModMenuHelper;
import draylar.omegaconfiggui.api.screen.OmegaConfigScreen;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.loader.api.FabricLoader;
@Environment(EnvType.CLIENT)
public class OmegaConfigGui {
/**
* Registers a ModMenu configuration screen for the given {@link Config} instance.
* @param config registered config to create a ModMenu screen for
* @param <T> config type
*/
public static <T extends Config> void registerConfigScreen(T config) {
if(FabricLoader.getInstance().isModLoaded("modmenu")) {
ModMenuHelper.injectScreen(config, parent -> new OmegaConfigScreen<>(config, parent));
}
}
}
@@ -1,21 +0,0 @@
package draylar.omegaconfiggui.api.screen;
import com.google.common.collect.ImmutableMap;
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import draylar.omegaconfig.api.Config;
import draylar.omegaconfiggui.mixin.ModMenuAccessor;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class ModMenuHelper {
public static <T extends Config> void injectScreen(T config, OmegaConfigScreenSupplier<T> factory) {
// they will suspect nothing
ModMenuAccessor.setConfigScreenFactories(
new ImmutableMap.Builder<String, ConfigScreenFactory<?>>()
.putAll(ModMenuAccessor.getConfigScreenFactories())
.put(config.getModid(), factory::get)
.build());
}
}
@@ -1,141 +0,0 @@
package draylar.omegaconfiggui.api.screen;
import com.mojang.blaze3d.systems.RenderSystem;
import draylar.omegaconfig.api.Config;
import draylar.omegaconfiggui.api.screen.widget.LabelWidget;
import draylar.omegaconfiggui.api.screen.widget.TypeWidgets;
import draylar.omegaconfiggui.api.screen.widget.WidgetSupplier;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.Drawable;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.AbstractButtonWidget;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.LiteralText;
import net.minecraft.util.Identifier;
import net.minecraft.util.Pair;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class OmegaConfigScreen<T extends Config> extends Screen {
private static final List<Class<?>> validClasses = Arrays.asList(Double.class, String.class, Boolean.class);
private final T config;
private final Screen parent;
private final Map<Field, Pair<WidgetSupplier<Object, AbstractButtonWidget>, AbstractButtonWidget>> fieldWidgets = new HashMap<>();
public OmegaConfigScreen(T config, Screen parent) {
super(new LiteralText(""));
this.config = config;
this.parent = parent;
}
@Override
public void init() {
super.init();
try {
// add label & button for each config entry
// TODO: SUB-CLASS SUPPORT
List<Field> collect = Arrays.stream(config.getClass().getDeclaredFields()).filter(field -> validClasses.contains(TypeWidgets.unbox(field.getType()))).collect(Collectors.toList());
int over = 0;
for (Field field : collect) {
Class<?> unbox = TypeWidgets.unbox(field.getType());
// label
addChild(new LabelWidget(150, 15 + height / 6 + 20 * over, new LiteralText(field.getName())));
// get value
field.setAccessible(true);
Object value = field.get(config);
// button / interact
AbstractButtonWidget button;
WidgetSupplier<Object, AbstractButtonWidget> widgetSupplier = (WidgetSupplier<Object, AbstractButtonWidget>) TypeWidgets.get(unbox);
if(widgetSupplier != null) {
button = widgetSupplier.create(this,250, 5 + height / 6 + 25 * over, 100, 20, new LiteralText(field.getName()), value);
} else {
button = new TextFieldWidget(client.textRenderer, 250, 5 + height / 6 + 25 * over, 100, 20, new LiteralText(field.getName()));
}
fieldWidgets.put(field, new Pair<>(widgetSupplier, button));
addButton(button);
over++;
}
} catch (Exception e) {
e.printStackTrace();
}
// save and exit
ButtonWidget exit = new ButtonWidget(width - 60, height - 30, 50, 20, new LiteralText("Exit"), widget -> onClose());
ButtonWidget save = new ButtonWidget(10, height - 30, 50, 20, new LiteralText("Save"), widget -> {
fieldWidgets.forEach((field, pair) -> {
try {
field.set(config, pair.getLeft().get(pair.getRight()));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
});
config.save();
});
addButton(save);
addButton(exit);
}
@Override
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
renderBackground(matrices);
for (AbstractButtonWidget button : this.buttons) {
button.render(matrices, mouseX, mouseY, delta);
}
for (Element element : this.children) {
if (element instanceof Drawable && !buttons.contains(element)) {
((Drawable) element).render(matrices, mouseX, mouseY, delta);
}
}
}
@Override
public void onClose() {
client.openScreen(parent);
}
@Override
public void renderBackground(MatrixStack matrices) {
// TODO: option for transparent BG
// this.fillGradient(matrices, 0, 0, this.width, this.height, -1072689136, -804253680);
renderCustomBackgroundTexture(0, 64, 64, 64, 0, 0, this.height, this.width);
renderCustomBackgroundTexture(0, 32, 32, 32, 0, this.height / 8, this.height / 8 * 6, this.width);
textRenderer.draw(matrices, config.getName(), width / 2f - textRenderer.getWidth(config.getName()) / 2f, 10, 0xffffff);
}
public void renderCustomBackgroundTexture(int vOffset, int r, int g, int b, int x, int y, int height, int width) {
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferBuilder = tessellator.getBuffer();
this.client.getTextureManager().bindTexture(OPTIONS_BACKGROUND_TEXTURE);
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
bufferBuilder.begin(7, VertexFormats.POSITION_TEXTURE_COLOR);
bufferBuilder.vertex(x, height + y, 0.0D).texture(0.0F, (float)height / 32.0F + (float)vOffset).color(r, g, b, 255).next();
bufferBuilder.vertex(width + x, height + y, 0.0D).texture((float)width / 32.0F, (float)height / 32.0F + (float)vOffset).color(r, g, b, 255).next();
bufferBuilder.vertex(width + x, y, 0.0D).texture((float)width / 32.0F, (float)vOffset).color(r, g, b, 255).next();
bufferBuilder.vertex(x, y, 0.0D).texture(0.0F, (float)vOffset).color(r, g, b, 255).next();
tessellator.draw();
}
}
@@ -1,8 +0,0 @@
package draylar.omegaconfiggui.api.screen;
import draylar.omegaconfig.api.Config;
import net.minecraft.client.gui.screen.Screen;
public interface OmegaConfigScreenSupplier<T extends Config> {
OmegaConfigScreen<T> get(Screen parent);
}
@@ -1,30 +0,0 @@
package draylar.omegaconfiggui.api.screen.widget;
import draylar.omegaconfiggui.mixin.AbstractButtonWidgetAccessor;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.AbstractButtonWidget;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.text.Text;
public class BaseTextFieldWidget extends TextFieldWidget {
protected final Screen parent;
public BaseTextFieldWidget(Screen parent, TextRenderer textRenderer, int x, int y, int width, int height, Text text) {
super(textRenderer, x, y, width, height, text);
this.parent = parent;
}
@Override
public void setTextFieldFocused(boolean focused) {
// unfocus all others
parent.children().forEach(element -> {
if(element instanceof AbstractButtonWidget) {
((AbstractButtonWidgetAccessor) element).callSetFocused(false);
}
});
super.setFocused(focused);
}
}
@@ -1,27 +0,0 @@
package draylar.omegaconfiggui.api.screen.widget;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Text;
public class DoubleFieldWidget extends BaseTextFieldWidget {
public DoubleFieldWidget(Screen parent, TextRenderer textRenderer, int x, int y, int width, int height, Text text) {
super(parent, textRenderer, x, y, width, height, text);
}
@Override
public void write(String string) {
try {
if(string.equals(".") && !getText().contains(".")) {
super.write(string);
} else {
Double.parseDouble(string);
super.write(string);
}
} catch(NumberFormatException ignored) {
}
}
}
@@ -1,26 +0,0 @@
package draylar.omegaconfiggui.api.screen.widget;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.Drawable;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.Element;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Text;
public class LabelWidget extends DrawableHelper implements Drawable, Element {
private final int x;
private final int y;
private final Text message;
public LabelWidget(int x, int y, Text message) {
this.x = x;
this.y = y;
this.message = message;
}
@Override
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
drawTextWithShadow(matrices, MinecraftClient.getInstance().textRenderer, message, x, y, 0xffffff);
}
}
@@ -1,45 +0,0 @@
package draylar.omegaconfiggui.api.screen.widget;
import draylar.omegaconfiggui.api.screen.widget.supplier.BooleanWidgetSupplier;
import draylar.omegaconfiggui.api.screen.widget.supplier.DoubleWidgetSupplier;
import draylar.omegaconfiggui.api.screen.widget.supplier.StringWidgetSupplier;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
public class TypeWidgets {
public static final Map<Class<?>, WidgetSupplier<?, ?>> CLASS_WIDGETS = new HashMap<>();
public static final Map<Class<?>, Class<?>> PRIMITIVE_TO_BOXED = new HashMap<>();
static {
CLASS_WIDGETS.put(Double.class, new DoubleWidgetSupplier());
CLASS_WIDGETS.put(Boolean.class, new BooleanWidgetSupplier());
CLASS_WIDGETS.put(String.class, new StringWidgetSupplier());
// primitive -> boxed
PRIMITIVE_TO_BOXED.put(boolean.class, Boolean.class);
PRIMITIVE_TO_BOXED.put(byte.class, Byte.class);
PRIMITIVE_TO_BOXED.put(char.class, Character.class);
PRIMITIVE_TO_BOXED.put(double.class, Double.class);
PRIMITIVE_TO_BOXED.put(float.class, Float.class);
PRIMITIVE_TO_BOXED.put(int.class, Integer.class);
PRIMITIVE_TO_BOXED.put(long.class, Long.class);
PRIMITIVE_TO_BOXED.put(short.class, Short.class);
PRIMITIVE_TO_BOXED.put(void.class, Void.class);
}
@Nullable
public static <T> WidgetSupplier<T, ?> get(Class<T> typeClass) {
return (WidgetSupplier<T, ?>) CLASS_WIDGETS.get(unbox(typeClass));
}
public static Class<?> unbox(Class<?> c) {
return PRIMITIVE_TO_BOXED.getOrDefault(c, c);
}
private TypeWidgets() {
// NO-OP
}
}
@@ -1,10 +0,0 @@
package draylar.omegaconfiggui.api.screen.widget;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.AbstractButtonWidget;
import net.minecraft.text.LiteralText;
public interface WidgetSupplier<T, A extends AbstractButtonWidget> {
AbstractButtonWidget create(Screen parent, int x, int y, int width, int height, LiteralText prompt, T value);
T get(A widget);
}
@@ -1,19 +0,0 @@
package draylar.omegaconfiggui.api.screen.widget.supplier;
import draylar.omegaconfiggui.api.screen.widget.WidgetSupplier;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.CheckboxWidget;
import net.minecraft.text.LiteralText;
public class BooleanWidgetSupplier implements WidgetSupplier<Boolean, CheckboxWidget> {
@Override
public CheckboxWidget create(Screen parent, int x, int y, int width, int height, LiteralText prompt, Boolean value) {
return new CheckboxWidget(x, y, 20, 20, new LiteralText(""), value);
}
@Override
public Boolean get(CheckboxWidget widget) {
return widget.isChecked();
}
}
@@ -1,35 +0,0 @@
package draylar.omegaconfiggui.api.screen.widget.supplier;
import draylar.omegaconfiggui.api.screen.widget.DoubleFieldWidget;
import draylar.omegaconfiggui.api.screen.widget.WidgetSupplier;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.LiteralText;
public class DoubleWidgetSupplier implements WidgetSupplier<Double, DoubleFieldWidget> {
@Override
public DoubleFieldWidget create(Screen parent, int x, int y, int width, int height, LiteralText prompt, Double value) {
LiteralText text = new LiteralText(String.valueOf(value));
DoubleFieldWidget widget = new DoubleFieldWidget(parent, MinecraftClient.getInstance().textRenderer, x, y, width, height, text);
widget.setText(text.asString());
return widget;
}
@Override
public Double get(DoubleFieldWidget widget) {
String message = widget.getText();
// if it is just a . or empty, return 0
if(message.equals(".") || message.isEmpty()) {
return 0.0;
}
// trim potential trailing .
if(message.indexOf(".") == message.length()) {
message = message.substring(0, message.length() - 1);
}
return Double.parseDouble(message);
}
}
@@ -1,25 +0,0 @@
package draylar.omegaconfiggui.api.screen.widget.supplier;
import draylar.omegaconfiggui.api.screen.widget.BaseTextFieldWidget;
import draylar.omegaconfiggui.api.screen.widget.WidgetSupplier;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.AbstractButtonWidget;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.text.LiteralText;
public class StringWidgetSupplier implements WidgetSupplier<String, TextFieldWidget> {
@Override
public TextFieldWidget create(Screen parent, int x, int y, int width, int height, LiteralText prompt, String value) {
LiteralText text = new LiteralText(value);
TextFieldWidget textField = new BaseTextFieldWidget(parent, MinecraftClient.getInstance().textRenderer, x, y, width, height, text);
textField.setText(value);
return textField;
}
@Override
public String get(TextFieldWidget widget) {
return widget.getText();
}
}
@@ -1,11 +0,0 @@
package draylar.omegaconfiggui.mixin;
import net.minecraft.client.gui.widget.AbstractButtonWidget;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(AbstractButtonWidget.class)
public interface AbstractButtonWidgetAccessor {
@Invoker
void callSetFocused(boolean focused);
}
@@ -1,20 +0,0 @@
package draylar.omegaconfiggui.mixin;
import com.google.common.collect.ImmutableMap;
import com.terraformersmc.modmenu.ModMenu;
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(ModMenu.class)
public interface ModMenuAccessor {
@Accessor
static ImmutableMap<String, ConfigScreenFactory<?>> getConfigScreenFactories() {
throw new UnsupportedOperationException();
}
@Accessor
static void setConfigScreenFactories(ImmutableMap<String, ConfigScreenFactory<?>> configScreenFactories) {
throw new UnsupportedOperationException();
}
}
@@ -1,21 +0,0 @@
{
"schemaVersion": 1,
"id": "omega-config-gui",
"version": "${version}",
"name": "OmegaConfigGui",
"description": "GUI support for Omega Config.",
"authors": [
"Draylar"
],
"contact": {},
"license": "MIT",
"environment": "*",
"mixins": [
"omega-config-gui.mixins.json"
],
"depends": {
"fabricloader": ">=0.11.2",
"fabric": "*",
"minecraft": "1.16.5"
}
}
@@ -1,15 +0,0 @@
{
"required": true,
"minVersion": "0.8",
"package": "draylar.omegaconfiggui.mixin",
"compatibilityLevel": "JAVA_8",
"mixins": [
"AbstractButtonWidgetAccessor",
"ModMenuAccessor"
],
"client": [
],
"injectors": {
"defaultRequire": 1
}
}
-3
View File
@@ -1,3 +0,0 @@
-ignorewarnings
-keep class net.fabricmc.api.** { *; }
+1 -2
View File
@@ -1,10 +1,10 @@
pluginManagement { pluginManagement {
repositories { repositories {
jcenter()
maven { maven {
name = 'Fabric' name = 'Fabric'
url = 'https://maven.fabricmc.net/' url = 'https://maven.fabricmc.net/'
} }
mavenCentral()
gradlePluginPortal() gradlePluginPortal()
} }
} }
@@ -12,4 +12,3 @@ pluginManagement {
rootProject.name = 'omega-config' rootProject.name = 'omega-config'
include 'omega-config-base' include 'omega-config-base'
include 'omega-config-gui'
@@ -1,20 +1,19 @@
package draylar.omegatest; package draylar.omegatest;
import draylar.omegaconfiggui.OmegaConfigGui;
import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.text.LiteralText; import net.minecraft.client.font.TextRenderer;
import net.minecraft.text.Text;
public class OmegaTestClient implements ClientModInitializer { public class OmegaTestClient implements ClientModInitializer {
@Override @Override
public void onInitializeClient() { public void onInitializeClient() {
OmegaConfigGui.registerConfigScreen(OmegaTestMain.CONFIG); HudRenderCallback.EVENT.register((context, delta) -> {
TextRenderer tr = MinecraftClient.getInstance().textRenderer;
HudRenderCallback.EVENT.register((stack, delta) -> { context.drawText(tr, Text.literal(String.valueOf(OmegaTestMain.CONFIG.v)), 15, 15, 0xffffff, true);
MinecraftClient.getInstance().textRenderer.draw(stack, new LiteralText(String.valueOf(OmegaTestMain.CONFIG.v)), 15, 15, 0xffffff); context.drawText(tr, Text.literal(String.valueOf(OmegaTestMain.CONFIG.doubleTest)), 15, 25, 0xffffff, true);
MinecraftClient.getInstance().textRenderer.draw(stack, new LiteralText(String.valueOf(OmegaTestMain.CONFIG.doubleTest)), 15, 30, 0xffffff);
}); });
} }
} }
@@ -1,11 +1,20 @@
package draylar.omegatest; package draylar.omegatest;
import draylar.omegaconfig.OmegaConfig; import draylar.omegaconfig.OmegaConfig;
import draylar.omegatest.config.ClassConfigTest;
import draylar.omegatest.config.CommentedNestedClassConfig;
import draylar.omegatest.config.NestedConfigTest;
import draylar.omegatest.config.SimpleConfigTest;
import draylar.omegatest.config.StructuresConfigTest;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
public class OmegaTestMain implements ModInitializer { public class OmegaTestMain implements ModInitializer {
public static final TestConfig CONFIG = OmegaConfig.register(TestConfig.class); public static final SimpleConfigTest CONFIG = OmegaConfig.register(SimpleConfigTest.class);
public static final StructuresConfigTest MO_CONFIG = OmegaConfig.register(StructuresConfigTest.class);
public static final NestedConfigTest NESTED = OmegaConfig.register(NestedConfigTest.class);
public static final ClassConfigTest CLASS = OmegaConfig.register(ClassConfigTest.class);
public static final CommentedNestedClassConfig COMMENTED_NESTED_CLASS = OmegaConfig.register(CommentedNestedClassConfig.class);
@Override @Override
public void onInitialize() { public void onInitialize() {
@@ -0,0 +1,30 @@
package draylar.omegatest.config;
import draylar.omegaconfig.api.Config;
import java.util.Arrays;
import java.util.List;
public class ClassConfigTest implements Config {
public List<TestClass> l = Arrays.asList(
new TestClass(true, 1, "hello")
);
@Override
public String getName() {
return "class-config";
}
public static class TestClass {
public final boolean a;
public final int b;
public String c;
public TestClass(boolean a, int b, String c) {
this.a = a;
this.b = b;
this.c = c;
}
}
}
@@ -0,0 +1,73 @@
package draylar.omegatest.config;
import draylar.omegaconfig.api.Comment;
import draylar.omegaconfig.api.Config;
public class CommentedNestedClassConfig implements Config {
@Comment("Very nested test")
public First first = new First();
@Comment("True")
public boolean test = false;
@Comment("First-Level")
public VeryNested veryNested = new VeryNested();
public static class First {
@Comment("Cucumbers")
public boolean cucumbers = true;
@Comment("InnerFirst")
public InnerFirst innerFirst = new InnerFirst();
@Comment("InnerSecond")
public InnerSecond innerSecond = new InnerSecond();
public static class InnerFirst {
@Comment("Number of Tomatoes")
public int numberOfTomatoes = 10;
}
public static class InnerSecond {
@Comment("Inner Second First")
public InnerSecondFirst innerSecondFirst = new InnerSecondFirst();
public static class InnerSecondFirst {
@Comment("Olive Oil")
public String oliveOil = "oliveOil";
}
}
}
public static class VeryNested {
@Comment("Second-Level")
public Very very = new Very();
public static class Very {
@Comment("Third-Level")
public VeryVery veryVery = new VeryVery();
public static class VeryVery {
@Comment("Forth-Level")
public VeryVeryVery veryVeryVery = new VeryVeryVery();
public static class VeryVeryVery {
@Comment("Fifth-Level")
public VeryVeryVeryVery veryVeryVeryVery = new VeryVeryVeryVery();
public static class VeryVeryVeryVery {
@Comment("Sixth-Level")
public String last = "last";
}
}
}
}
}
@Override
public String getName() {
return "commented-inner-classes";
}
@Override
public String getExtension() {
return "json5";
}
}
@@ -0,0 +1,18 @@
package draylar.omegatest.config;
import draylar.omegaconfig.api.Config;
public class NestedConfigTest implements Config {
public boolean test = false;
@Override
public String getName() {
return "nested";
}
@Override
public String getDirectory() {
return "test";
}
}
@@ -1,4 +1,4 @@
package draylar.omegatest; package draylar.omegatest.config;
import draylar.omegaconfig.api.Comment; import draylar.omegaconfig.api.Comment;
import draylar.omegaconfig.api.Config; import draylar.omegaconfig.api.Config;
@@ -6,25 +6,19 @@ import draylar.omegaconfig.api.Syncing;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@Syncing @Syncing
public class TestConfig implements Config { public class SimpleConfigTest implements Config {
@Comment(value = "Hello!") @Comment(value = "Hello!")
boolean v = false; public boolean v = false;
@Comment(value = "I'm a double.") @Comment(value = "I'm a double.")
double doubleTest = 0.0; public double doubleTest = 0.0;
String stringTest = "Hello, world!"; public String stringTest = "Hello, world!";
@Comment(value = "This is an inner static class.") @Comment(value = "This is an inner static class.")
public Test test = new Test(); public Test test = new Test();
public static class Test {
@Comment(value = "This is the value inside the class!")
public boolean innerTest = false;
}
@Override @Override
public String getName() { public String getName() {
return "test-config"; return "test-config";
@@ -34,4 +28,10 @@ public class TestConfig implements Config {
public @Nullable String getModid() { public @Nullable String getModid() {
return "omega-config-test"; return "omega-config-test";
} }
public static class Test {
@Comment(value = "This is the value inside the class!")
public boolean innerTest = false;
}
} }
@@ -0,0 +1,42 @@
package draylar.omegatest.config;
import java.util.Map;
public class StructureConfigEntry {
public final boolean activated;
public final int separation;
public final int spacing;
public final int salt;
private StructureConfigEntry(int separation, int spacing, int salt) {
this.activated = true;
this.spacing = spacing;
this.separation = separation;
this.salt = salt;
}
public static StructureConfigEntry of(int separation, int spacing, int salt) {
return new StructureConfigEntry(separation, spacing, salt);
}
public static void computeConfigMap(Map<String, StructureConfigEntry> map) {
map.computeIfAbsent("abandoned_church", (id) -> of(14, 38, 66996840));
map.computeIfAbsent("barn_house", (id) -> of(8, 38, 165757306));
map.computeIfAbsent("big_pyramid", (id) -> of(5, 25, 239284294));
map.computeIfAbsent("jungle_pyramid", (id) -> of(5, 25, 312178642));
map.computeIfAbsent("the_castle_in_the_sky", (id) -> of(8, 30, 423494938));
map.computeIfAbsent("killer_bunny_castle", (id) -> of(25, 45, 48123900));
map.computeIfAbsent("villager_tower", (id) -> of(16, 34, 550292492));
map.computeIfAbsent("villager_market", (id) -> of(16, 36, 784939542));
map.computeIfAbsent("pillager_factory", (id) -> of(16, 36, 839204924));
map.computeIfAbsent("ice_tower", (id) -> of(8, 28, 964058305));
map.computeIfAbsent("tavern", (id) -> of(12, 32, 19296726));
map.computeIfAbsent("pirate_ship", (id) -> of(16, 40, 583957395));
map.computeIfAbsent("lighthouse", (id) -> of(16, 32, 29502322));
map.computeIfAbsent("volcanic_vent", (id) -> of(4, 8, 84981094));
map.computeIfAbsent("moai", (id) -> of(4, 8, 12994829));
map.computeIfAbsent("air_balloon", (id) -> of(1, 6, 29483148));
}
}
@@ -0,0 +1,58 @@
package draylar.omegatest.config;
import draylar.omegaconfig.api.Comment;
import draylar.omegaconfig.api.Config;
import net.minecraft.util.Identifier;
import java.util.HashMap;
import java.util.Map;
//taken straight out of Mo Structures
public class StructuresConfigTest implements Config {
@Comment("""
Welcome to Mo'Structures Config!
Here, you can turn off structures, change their chance, and also change their salt.
To turn off a structure, simply go to the corresponding entry and set `activated` to false.
Mo' Structures uses the vanilla structure spawning system. That is-
- Seperation is the minimum chunks between structures
- Spacing is the average chunks between structures
Salt is a special field that gives structures unique spawning positions. DO NOT TOUCH IT, ONLY ADVANCED TROUBLESHOOTING!
""")
public final Map<String, StructureConfigEntry> structureConfigEntries = new HashMap<>(17);
@Override
public String getName() {
return "mostructures-config-v2";
}
@Override
public String getExtension() {
return "json5";
}
public StructureConfigEntry get(Identifier id) {
for (Map.Entry<String, StructureConfigEntry> entry : structureConfigEntries.entrySet()) {
if (entry.getKey().equals(id.getPath())) {
return entry.getValue();
}
}
throw new NullPointerException("Tried StructureConfigEntry with id: " + id + ", but it was null!");
}
@Override
public void save() {
StructureConfigEntry.computeConfigMap(structureConfigEntries);
Config.super.save();
}
}
@@ -0,0 +1,3 @@
{
"config.omega-config-test.test-config": "Omega Config - Test Config"
}
+2 -2
View File
@@ -19,8 +19,8 @@
] ]
}, },
"depends": { "depends": {
"fabricloader": ">=0.11.2", "fabricloader": "*",
"fabric": "*", "fabric": "*",
"minecraft": "1.16.5" "minecraft": "*"
} }
} }