Refactor into separate modules
This commit is contained in:
parent
98c736af46
commit
f939dadec6
|
@ -26,4 +26,4 @@ deploy:
|
|||
stage: deploy
|
||||
when: manual
|
||||
script:
|
||||
- gradle --build-cache publishModrinth curseforge
|
||||
- gradle --build-cache modrinth curseforge
|
||||
|
|
240
build.gradle
240
build.gradle
|
@ -1,43 +1,223 @@
|
|||
apply from: "https://gitlab.com/-/snippets/2121059/raw/master/jfbase.gradle"
|
||||
plugins {
|
||||
id "java-library"
|
||||
id "eclipse"
|
||||
id "idea"
|
||||
id "maven-publish"
|
||||
id "fabric-loom" version "0.10-SNAPSHOT" apply false
|
||||
id "com.matthewprenger.cursegradle" version "1.4.0"
|
||||
id "com.modrinth.minotaur" version "1.1.0"
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name = 'TerraformersMC'
|
||||
url = 'https://maven.terraformersmc.com/'
|
||||
version = "$project.mod_version"
|
||||
|
||||
def moduleDependencies(project, List<String> depNames) {
|
||||
def deps = depNames.iterator().collect { project.dependencies.project(path: ":$it", configuration: 'dev') }
|
||||
project.dependencies {
|
||||
deps.each {
|
||||
api it
|
||||
}
|
||||
}
|
||||
project.publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
pom.withXml {
|
||||
def depsNode = asNode().appendNode("dependencies")
|
||||
deps.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")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
testmod {
|
||||
compileClasspath += main.compileClasspath + main.output
|
||||
runtimeClasspath += main.runtimeClasspath + main.output
|
||||
allprojects {
|
||||
apply plugin: "java-library"
|
||||
apply plugin: "fabric-loom"
|
||||
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
it.options.release = 16
|
||||
}
|
||||
|
||||
group = "io.gitlab.jfronny.libjf"
|
||||
|
||||
sourceSets {
|
||||
testmod {
|
||||
compileClasspath += main.compileClasspath
|
||||
runtimeClasspath += main.runtimeClasspath
|
||||
}
|
||||
}
|
||||
|
||||
loom {
|
||||
runs {
|
||||
testmodClient {
|
||||
client()
|
||||
ideConfigGenerated project.rootProject == project
|
||||
name = "Testmod Client"
|
||||
source sourceSets.testmod
|
||||
}
|
||||
testmodServer {
|
||||
server()
|
||||
ideConfigGenerated project.rootProject == project
|
||||
name = "Testmod Server"
|
||||
source sourceSets.testmod
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||
mappings "net.fabricmc:yarn:${project.minecraft_version}+${project.yarn_mappings}:v2"
|
||||
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||
|
||||
modImplementation "com.terraformersmc:modmenu:2.0.10"
|
||||
include modImplementation(fabricApi.module("fabric-tag-extensions-v0", "0.40.1+1.17"))
|
||||
include modImplementation(fabricApi.module("fabric-resource-loader-v0", "0.40.1+1.17"))
|
||||
}
|
||||
|
||||
configurations {
|
||||
dev
|
||||
}
|
||||
|
||||
loom {
|
||||
shareRemapCaches = true
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name = 'TerraformersMC'
|
||||
url = 'https://maven.terraformersmc.com/'
|
||||
}
|
||||
}
|
||||
|
||||
jar {
|
||||
archiveClassifier = "dev"
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
remapJar {
|
||||
input = file("${project.buildDir}/libs/$archivesBaseName-${project.version}-dev.jar")
|
||||
archiveFileName = "${archivesBaseName}-${project.version}.jar"
|
||||
}
|
||||
|
||||
artifacts {
|
||||
dev file: file("${project.buildDir}/libs/$archivesBaseName-${project.version}-dev.jar"), type: "jar", builtBy: jar
|
||||
}
|
||||
|
||||
processResources {
|
||||
inputs.property "version", project.version
|
||||
|
||||
filesMatching("fabric.mod.json") {
|
||||
expand "version": project.version
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar, dependsOn: classes) {
|
||||
archiveClassifier = "sources"
|
||||
from sourceSets.main.allSource
|
||||
}
|
||||
|
||||
tasks.withType(AbstractArchiveTask) {
|
||||
preserveFileTimestamps = false
|
||||
reproducibleFileOrder = true
|
||||
}
|
||||
}
|
||||
|
||||
subprojects {
|
||||
dependencies {
|
||||
testmodImplementation sourceSets.main.output
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
afterEvaluate {
|
||||
artifact(remapJar) {
|
||||
builtBy remapJar
|
||||
}
|
||||
|
||||
artifact(sourcesJar) {
|
||||
builtBy remapSourcesJar
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
subprojects.each { remapJar.dependsOn("${it.path}:remapJar") }
|
||||
|
||||
dependencies {
|
||||
//to change the versions see the gradle.properties file
|
||||
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||
mappings "net.fabricmc:yarn:${project.minecraft_version}+${project.yarn_mappings}:v2"
|
||||
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||
afterEvaluate {
|
||||
subprojects.each {
|
||||
api project(path: ":${it.name}", configuration: "dev")
|
||||
|
||||
include modImplementation(fabricApi.module("fabric-tag-extensions-v0", "0.40.1+1.17"))
|
||||
include modImplementation(fabricApi.module("fabric-resource-loader-v0", "0.40.1+1.17"))
|
||||
modImplementation "com.terraformersmc:modmenu:2.0.10"
|
||||
}
|
||||
include project("${it.name}:")
|
||||
|
||||
loom {
|
||||
runs {
|
||||
testmodClient {
|
||||
client()
|
||||
ideConfigGenerated project.rootProject == project
|
||||
name = "Testmod Client"
|
||||
source sourceSets.testmod
|
||||
}
|
||||
testmodServer {
|
||||
server()
|
||||
ideConfigGenerated project.rootProject == project
|
||||
name = "Testmod Server"
|
||||
source sourceSets.testmod
|
||||
testmodImplementation project("${it.name}:").sourceSets.testmod.output
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task modrinth(type: com.modrinth.minotaur.TaskModrinthUpload, dependsOn: remapJar) {
|
||||
onlyIf {
|
||||
System.getenv().MODRINTH_API_TOKEN
|
||||
}
|
||||
|
||||
token = System.getenv().MODRINTH_API_TOKEN
|
||||
projectId = "WKwQAwke"
|
||||
versionNumber = version
|
||||
versionName = "[${project.minecraft_version}] ${project.mod_version}"
|
||||
uploadFile = remapJar
|
||||
addGameVersion("${project.minecraft_version}")
|
||||
addLoader('fabric')
|
||||
}
|
||||
|
||||
curseforge {
|
||||
if (System.getenv().CURSEFORGE_API_TOKEN) {
|
||||
apiKey = System.getenv().CURSEFORGE_API_TOKEN
|
||||
} else {
|
||||
println "No CURSEFORGE_API_TOKEN specified"
|
||||
}
|
||||
project {
|
||||
id = "482600"
|
||||
releaseType = 'release'
|
||||
addGameVersion "Fabric"
|
||||
addGameVersion "${project.minecraft_version}"
|
||||
changelog = ""
|
||||
mainArtifact(file("${project.buildDir}/libs/${archivesBaseName}-${version}.jar"))
|
||||
mainArtifact.displayName = "[${project.minecraft_version}] ${project.mod_version}"
|
||||
afterEvaluate {
|
||||
uploadTask.dependsOn(remapJar)
|
||||
}
|
||||
}
|
||||
options {
|
||||
forgeGradleIntegration = false
|
||||
}
|
||||
}
|
||||
|
||||
task remapMavenJar(type: net.fabricmc.loom.task.RemapJarTask, dependsOn: jar) {
|
||||
input = jar.archiveFile
|
||||
archiveFileName = "${archivesBaseName}-${project.version}-maven.jar"
|
||||
addNestedDependencies = false
|
||||
}
|
||||
build.dependsOn remapMavenJar
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
maven(MavenPublication) {
|
||||
artifact(remapMavenJar) {
|
||||
builtBy remapMavenJar
|
||||
}
|
||||
|
||||
artifact(sourcesJar) {
|
||||
builtBy remapSourcesJar
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#!/bin/bash
|
||||
|
||||
# https://github.com/jitpack/jitpack.io/issues/4355#issuecomment-744678253
|
||||
|
||||
JV=`java -version 2>&1 >/dev/null | head -1`
|
||||
echo $JV | sed -E 's/^.*version "([^".]*)\.[^"]*".*$/\1/'
|
||||
|
||||
if [ "$JV" != 16 ]; then
|
||||
case "$1" in
|
||||
install)
|
||||
echo "installing sdkman..."
|
||||
curl -s "https://get.sdkman.io" | bash
|
||||
source ~/.sdkman/bin/sdkman-init.sh
|
||||
sdk install java 16.0.1-open
|
||||
;;
|
||||
use)
|
||||
echo "must source ~/.sdkman/bin/sdkman-init.sh"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
|
@ -9,10 +9,3 @@ loader_version=0.11.6
|
|||
mod_version=1.2.3
|
||||
maven_group=io.gitlab.jfronny
|
||||
archives_base_name=libjf
|
||||
|
||||
modrinth_id=WKwQAwke
|
||||
modrinth_required_dependencies=
|
||||
modrinth_optional_dependencies=
|
||||
curseforge_id=482600
|
||||
curseforge_required_dependencies=
|
||||
curseforge_optional_dependencies=
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
jdk:
|
||||
- openjdk16
|
||||
|
||||
before_install:
|
||||
- bash ensure-jitpack-java-16 install
|
||||
|
||||
install:
|
||||
- if ! bash ensure-jitpack-java-16 use; then source ~/.sdkman/bin/sdkman-init.sh; fi
|
||||
- java -version
|
||||
- ./gradlew publishToMavenLocal
|
|
@ -0,0 +1,5 @@
|
|||
archivesBaseName = "libjf-base"
|
||||
version = "1.0"
|
||||
|
||||
dependencies {
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package io.gitlab.jfronny.libjf;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import io.gitlab.jfronny.libjf.gson.HiddenAnnotationExclusionStrategy;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
public class LibJf {
|
||||
private LibJf() {
|
||||
}
|
||||
public static final String MOD_ID = "libjf";
|
||||
public static final Logger LOGGER = LogManager.getLogger(MOD_ID);
|
||||
public static final Gson GSON = new GsonBuilder()
|
||||
.excludeFieldsWithModifiers(Modifier.TRANSIENT)
|
||||
.excludeFieldsWithModifiers(Modifier.PRIVATE)
|
||||
.addSerializationExclusionStrategy(new HiddenAnnotationExclusionStrategy())
|
||||
.setPrettyPrinting()
|
||||
.create();
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.libjf.data;
|
||||
package io.gitlab.jfronny.libjf;
|
||||
|
||||
import net.minecraft.resource.ResourceType;
|
||||
import net.minecraft.util.Identifier;
|
|
@ -4,7 +4,9 @@ import com.google.gson.ExclusionStrategy;
|
|||
import com.google.gson.FieldAttributes;
|
||||
|
||||
public class HiddenAnnotationExclusionStrategy implements ExclusionStrategy {
|
||||
public boolean shouldSkipClass(Class<?> clazz) { return false; }
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
public boolean shouldSkipField(FieldAttributes fieldAttributes) {
|
||||
return fieldAttributes.getAnnotation(GsonHidden.class) != null;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "libjf-base",
|
||||
"version": "${version}",
|
||||
"authors": [
|
||||
"JFronny"
|
||||
],
|
||||
"contact": {
|
||||
"website": "https://jfronny.gitlab.io",
|
||||
"repo": "https://gitlab.com/jfmods/libjf"
|
||||
},
|
||||
"license": "MIT",
|
||||
"environment": "*",
|
||||
"depends": {
|
||||
"fabricloader": ">=0.11.3",
|
||||
"minecraft": "*"
|
||||
},
|
||||
"custom": {
|
||||
"modmenu": {
|
||||
"parent": "libjf"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "libjf-base-testmod",
|
||||
"version": "${version}",
|
||||
"environment": "*"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
archivesBaseName = "libjf-config-v0"
|
||||
version = "1.0"
|
||||
|
||||
dependencies {
|
||||
moduleDependencies(project, ["libjf-base", "libjf-unsafe-v0"])
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package io.gitlab.jfronny.libjf.config;
|
||||
|
||||
import io.gitlab.jfronny.libjf.Libjf;
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import io.gitlab.jfronny.libjf.config.entry.Entry;
|
||||
import io.gitlab.jfronny.libjf.gson.GsonHidden;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
@ -39,22 +40,22 @@ public class Config {
|
|||
for (Field field : config.getFields()) {
|
||||
EntryInfo info = new EntryInfo();
|
||||
info.field = field;
|
||||
if (field.isAnnotationPresent(Entry.class))
|
||||
if (field.isAnnotationPresent(io.gitlab.jfronny.libjf.config.entry.Entry.class))
|
||||
try {
|
||||
info.defaultValue = field.get(null);
|
||||
} catch (IllegalAccessException ignored) {}
|
||||
entries.add(info);
|
||||
}
|
||||
try {
|
||||
Libjf.GSON.fromJson(Files.newBufferedReader(path), config); }
|
||||
LibJf.GSON.fromJson(Files.newBufferedReader(path), config); }
|
||||
catch (Exception e) { write(); }
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public void initClient(EntryInfo info) {
|
||||
if (!(info.field.isAnnotationPresent(Entry.class) || info.field.isAnnotationPresent(GsonHidden.class))) return;
|
||||
if (!(info.field.isAnnotationPresent(io.gitlab.jfronny.libjf.config.entry.Entry.class) || info.field.isAnnotationPresent(GsonHidden.class))) return;
|
||||
Class<?> type = info.field.getType();
|
||||
Entry e = info.field.getAnnotation(Entry.class);
|
||||
io.gitlab.jfronny.libjf.config.entry.Entry e = info.field.getAnnotation(Entry.class);
|
||||
info.width = e != null ? e.width() : 0;
|
||||
|
||||
if (e == null) return;
|
||||
|
@ -120,7 +121,7 @@ public class Config {
|
|||
path = FabricLoader.getInstance().getConfigDir().resolve(modid + ".json");
|
||||
try {
|
||||
if (!Files.exists(path)) Files.createFile(path);
|
||||
Files.write(path, Libjf.GSON.toJson(configClass.getDeclaredConstructor().newInstance()).getBytes());
|
||||
Files.write(path, LibJf.GSON.toJson(configClass.getDeclaredConstructor().newInstance()).getBytes());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package io.gitlab.jfronny.libjf.config;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ConfigHolder {
|
||||
private ConfigHolder() {
|
||||
}
|
||||
private static final Map<String, Config> configs = new HashMap<>();
|
||||
|
||||
public static void registerConfig(String modId, Class<?> config) {
|
||||
if (!isRegistered(config))
|
||||
configs.put(modId, new Config(modId, config));
|
||||
}
|
||||
|
||||
public static Map<String, Config> getConfigs() {
|
||||
return ImmutableMap.copyOf(configs);
|
||||
}
|
||||
|
||||
public static boolean isRegistered(Class<?> config) {
|
||||
for (Config value : configs.values()) {
|
||||
if (value.configClass.equals(config))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -2,8 +2,8 @@ package io.gitlab.jfronny.libjf.config;
|
|||
|
||||
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
|
||||
import com.terraformersmc.modmenu.api.ModMenuApi;
|
||||
import io.gitlab.jfronny.libjf.Libjf;
|
||||
import io.gitlab.jfronny.libjf.config.gui.TinyConfigScreen;
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -12,8 +12,8 @@ public class ModMenu implements ModMenuApi {
|
|||
@Override
|
||||
public Map<String, ConfigScreenFactory<?>> getProvidedConfigScreenFactories() {
|
||||
Map<String, ConfigScreenFactory<?>> factories = new HashMap<>();
|
||||
for (Map.Entry<String, Config> entry : Libjf.getConfigs().entrySet()) {
|
||||
if (!Libjf.MOD_ID.equals(entry.getKey()))
|
||||
for (Map.Entry<String, Config> entry : ConfigHolder.getConfigs().entrySet()) {
|
||||
if (!LibJf.MOD_ID.equals(entry.getKey()))
|
||||
factories.put(entry.getKey(), buildFactory(entry.getValue()));
|
||||
}
|
||||
return factories;
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.libjf.config;
|
||||
package io.gitlab.jfronny.libjf.config.entry;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
|
@ -1,17 +1,17 @@
|
|||
package io.gitlab.jfronny.libjf.entry;
|
||||
package io.gitlab.jfronny.libjf.config.entry;
|
||||
|
||||
import io.gitlab.jfronny.libjf.Libjf;
|
||||
import io.gitlab.jfronny.libjf.config.Config;
|
||||
import io.gitlab.jfronny.libjf.config.Entry;
|
||||
import io.gitlab.jfronny.libjf.config.ConfigHolder;
|
||||
import io.gitlab.jfronny.libjf.config.EntryInfo;
|
||||
import io.gitlab.jfronny.libjf.gson.GsonHidden;
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
|
||||
public class LibjfClient implements ClientModInitializer {
|
||||
public class JfConfigClient implements ClientModInitializer {
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
for (Config config : Libjf.getConfigs().values()) {
|
||||
Libjf.LOGGER.info("Registring config UI for " + config.modid);
|
||||
for (Config config : ConfigHolder.getConfigs().values()) {
|
||||
LibJf.LOGGER.info("Registring config UI for " + config.modid);
|
||||
for (EntryInfo info : config.entries) {
|
||||
if (info.field.isAnnotationPresent(Entry.class) || info.field.isAnnotationPresent(GsonHidden.class))
|
||||
try {
|
|
@ -0,0 +1,18 @@
|
|||
package io.gitlab.jfronny.libjf.config.entry;
|
||||
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import io.gitlab.jfronny.libjf.config.ConfigHolder;
|
||||
import io.gitlab.jfronny.libjf.config.JfConfig;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.fabricmc.loader.api.entrypoint.EntrypointContainer;
|
||||
import net.fabricmc.loader.api.entrypoint.PreLaunchEntrypoint;
|
||||
|
||||
public class JfConfigSafe implements PreLaunchEntrypoint {
|
||||
@Override
|
||||
public void onPreLaunch() {
|
||||
for (EntrypointContainer<JfConfig> config : FabricLoader.getInstance().getEntrypointContainers(LibJf.MOD_ID + ":config", JfConfig.class)) {
|
||||
ConfigHolder.registerConfig(config.getProvider().getMetadata().getId(), config.getEntrypoint().getClass());
|
||||
LibJf.LOGGER.info("Registering config for " + config.getProvider().getMetadata().getId());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package io.gitlab.jfronny.libjf.config.entry;
|
||||
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import io.gitlab.jfronny.libjf.config.ConfigHolder;
|
||||
import io.gitlab.jfronny.libjf.config.JfConfig;
|
||||
import io.gitlab.jfronny.libjf.unsafe.DynamicEntry;
|
||||
import io.gitlab.jfronny.libjf.unsafe.UltraEarlyInit;
|
||||
|
||||
public class JfConfigUnsafe implements UltraEarlyInit {
|
||||
@Override
|
||||
public void init() {
|
||||
DynamicEntry.execute(LibJf.MOD_ID + ":config", JfConfig.class, s -> {
|
||||
ConfigHolder.registerConfig(s.modId(), s.instance().getClass());
|
||||
LibJf.LOGGER.info("Registering config for " + s.modId());
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
package io.gitlab.jfronny.libjf.config.gui;
|
||||
|
||||
import io.gitlab.jfronny.libjf.Libjf;
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import io.gitlab.jfronny.libjf.config.Config;
|
||||
import io.gitlab.jfronny.libjf.config.Entry;
|
||||
import io.gitlab.jfronny.libjf.config.entry.Entry;
|
||||
import io.gitlab.jfronny.libjf.config.EntryInfo;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
@ -54,7 +54,7 @@ public class TinyConfigScreen extends Screen {
|
|||
|
||||
this.addDrawableChild(new ButtonWidget(this.width / 2 - 154, this.height - 28, 150, 20, ScreenTexts.CANCEL, button -> {
|
||||
try {
|
||||
Libjf.GSON.fromJson(Files.newBufferedReader(config.path), config.configClass); }
|
||||
LibJf.GSON.fromJson(Files.newBufferedReader(config.path), config.configClass); }
|
||||
catch (Exception e) { config.write(); }
|
||||
|
||||
for (EntryInfo info : config.entries) {
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "libjf-base",
|
||||
"name": "LibJF Base",
|
||||
"version": "${version}",
|
||||
"authors": [
|
||||
"JFronny"
|
||||
],
|
||||
"contact": {
|
||||
"website": "https://jfronny.gitlab.io",
|
||||
"repo": "https://gitlab.com/jfmods/libjf"
|
||||
},
|
||||
"license": "MIT",
|
||||
"environment": "*",
|
||||
"entrypoints": {
|
||||
"modmenu": [
|
||||
"io.gitlab.jfronny.libjf.config.ModMenu"
|
||||
],
|
||||
"client": [
|
||||
"io.gitlab.jfronny.libjf.config.entry.JfConfigClient"
|
||||
],
|
||||
"libjf:preEarly": [
|
||||
"io.gitlab.jfronny.libjf.config.entry.JfConfigUnsafe"
|
||||
],
|
||||
"preLaunch": [
|
||||
"io.gitlab.jfronny.libjf.config.entry.JfConfigSafe"
|
||||
]
|
||||
},
|
||||
"custom": {
|
||||
"modmenu": {
|
||||
"badges": ["library"],
|
||||
"parent": "libjf"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +1,19 @@
|
|||
package io.gitlab.jfronny.libjf.test;
|
||||
package io.gitlab.jfronny.libjf.config.test;
|
||||
|
||||
import io.gitlab.jfronny.libjf.config.Entry;
|
||||
import io.gitlab.jfronny.libjf.config.JfConfig;
|
||||
import io.gitlab.jfronny.libjf.config.entry.Entry;
|
||||
import io.gitlab.jfronny.libjf.gson.GsonHidden;
|
||||
|
||||
public class TestMod implements JfConfig {
|
||||
public class TestConfig implements JfConfig {
|
||||
@Entry public static boolean disablePacks = false;
|
||||
@Entry public static int intTest = 20;
|
||||
@Entry public static double decimalTest = 20;
|
||||
@Entry public static String dieStr = "lolz";
|
||||
@Entry @GsonHidden public static String guiOnlyStr = "lolz";
|
||||
@Entry @GsonHidden
|
||||
public static String guiOnlyStr = "lolz";
|
||||
public static String gsonOnlyStr = "lolz";
|
||||
@Entry public static Test enumTest = Test.Test;
|
||||
@Entry
|
||||
public static Test enumTest = Test.Test;
|
||||
|
||||
public enum Test {
|
||||
Test, ER
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"libjf-config-v0-testmod.jfconfig.title": "JfConfig example",
|
||||
"libjf-config-v0-testmod.jfconfig.disablePacks": "Disable resource packs",
|
||||
"libjf-config-v0-testmod.jfconfig.intTest": "Int Test",
|
||||
"libjf-config-v0-testmod.jfconfig.decimalTest": "Decimal Test",
|
||||
"libjf-config-v0-testmod.jfconfig.dieStr": "String Test",
|
||||
"libjf-config-v0-testmod.jfconfig.enumTest": "Enum Test",
|
||||
"libjf-config-v0-testmod.jfconfig.enumTest.tooltip": "Enum Test Tooltip",
|
||||
"libjf-config-v0-testmod.jfconfig.enum.Test.Test": "Test",
|
||||
"libjf-config-v0-testmod.jfconfig.enum.Test.ER": "ER"
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "libjf-config-v0-testmod",
|
||||
"version": "${version}",
|
||||
"environment": "*",
|
||||
"entrypoints": {
|
||||
"libjf:config": [
|
||||
"io.gitlab.jfronny.libjf.config.test.TestConfig"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
archivesBaseName = "libjf-data-manipulation-v0"
|
||||
version = "1.0"
|
||||
|
||||
dependencies {
|
||||
moduleDependencies(project, ["libjf-base"])
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package io.gitlab.jfronny.libjf.data;
|
||||
package io.gitlab.jfronny.libjf.data.manipulation;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
|
@ -14,8 +15,8 @@ public class RecipeUtil {
|
|||
REMOVAL_BY_ID.add(identifier);
|
||||
}
|
||||
|
||||
public static void removeRecipeFor(ItemStack product) {
|
||||
RECIPES_FOR_REMOVAL.add(product);
|
||||
public static void removeRecipeFor(Item product) {
|
||||
RECIPES_FOR_REMOVAL.add(product.getDefaultStack());
|
||||
}
|
||||
|
||||
public static boolean isIdBlocked(Identifier identifier) {
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.libjf.data;
|
||||
package io.gitlab.jfronny.libjf.data.manipulation;
|
||||
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
|
@ -1,6 +1,6 @@
|
|||
package io.gitlab.jfronny.libjf.data;
|
||||
package io.gitlab.jfronny.libjf.data.manipulation;
|
||||
|
||||
import io.gitlab.jfronny.libjf.data.impl.WrappedResourcePack;
|
||||
import io.gitlab.jfronny.libjf.data.manipulation.impl.WrappedResourcePack;
|
||||
import net.minecraft.resource.ResourcePack;
|
||||
|
||||
//This is a class for binary compatibility with mods using libjf
|
|
@ -1,8 +1,8 @@
|
|||
package io.gitlab.jfronny.libjf.data.impl;
|
||||
package io.gitlab.jfronny.libjf.data.manipulation.impl;
|
||||
|
||||
import io.gitlab.jfronny.libjf.data.ResourcePath;
|
||||
import io.gitlab.jfronny.libjf.data.UserResourceEvents;
|
||||
import io.gitlab.jfronny.libjf.data.WrappedPack;
|
||||
import io.gitlab.jfronny.libjf.ResourcePath;
|
||||
import io.gitlab.jfronny.libjf.data.manipulation.UserResourceEvents;
|
||||
import io.gitlab.jfronny.libjf.data.manipulation.WrappedPack;
|
||||
import net.minecraft.resource.ResourceType;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
package io.gitlab.jfronny.libjf.data.impl;
|
||||
package io.gitlab.jfronny.libjf.data.manipulation.impl;
|
||||
|
||||
import io.gitlab.jfronny.libjf.data.WrappedPack;
|
||||
import io.gitlab.jfronny.libjf.data.manipulation.WrappedPack;
|
||||
import net.minecraft.resource.ResourcePack;
|
||||
import net.minecraft.resource.ResourceType;
|
||||
import net.minecraft.resource.metadata.ResourceMetadataReader;
|
|
@ -1,9 +1,9 @@
|
|||
package io.gitlab.jfronny.libjf.mixin;
|
||||
package io.gitlab.jfronny.libjf.data.manipulation.mixin;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.JsonObject;
|
||||
import io.gitlab.jfronny.libjf.Libjf;
|
||||
import io.gitlab.jfronny.libjf.data.RecipeUtil;
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import io.gitlab.jfronny.libjf.data.manipulation.RecipeUtil;
|
||||
import net.minecraft.recipe.Recipe;
|
||||
import net.minecraft.recipe.RecipeManager;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
@ -26,7 +26,7 @@ public class RecipeManagerMixin {
|
|||
Identifier recipeId = cur.getKey();
|
||||
|
||||
if (RecipeUtil.isIdBlocked(recipeId)) {
|
||||
Libjf.LOGGER.info("Blocking recipe by identifier: " + recipeId);
|
||||
LibJf.LOGGER.info("Blocking recipe by identifier: " + recipeId);
|
||||
} else {
|
||||
replacement.add(cur);
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ public class RecipeManagerMixin {
|
|||
Recipe<?> recipe = (Recipe<?>) value;
|
||||
|
||||
if (RecipeUtil.isOutputBlocked(recipe.getOutput())) {
|
||||
Libjf.LOGGER.info("Blocked recipe by predicate: " + recipe.getId());
|
||||
LibJf.LOGGER.info("Blocked recipe by predicate: " + recipe.getId());
|
||||
return builder;
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
package io.gitlab.jfronny.libjf.mixin;
|
||||
package io.gitlab.jfronny.libjf.data.manipulation.mixin;
|
||||
|
||||
import io.gitlab.jfronny.libjf.data.WrappedPack;
|
||||
import io.gitlab.jfronny.libjf.data.manipulation.WrappedPack;
|
||||
import net.fabricmc.fabric.impl.resource.loader.FabricModResourcePack;
|
||||
import net.fabricmc.fabric.impl.resource.loader.ModNioResourcePack;
|
||||
import net.minecraft.resource.ReloadableResourceManagerImpl;
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "libjf-data-manipulation-v0",
|
||||
"version": "${version}",
|
||||
"authors": [
|
||||
"JFronny"
|
||||
],
|
||||
"contact": {
|
||||
"website": "https://jfronny.gitlab.io",
|
||||
"repo": "https://gitlab.com/jfmods/libjf"
|
||||
},
|
||||
"license": "MIT",
|
||||
"environment": "*",
|
||||
"mixins": ["libjf-data-manipulation-v0.mixins.json"],
|
||||
"custom": {
|
||||
"modmenu": {
|
||||
"parent": "libjf"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "io.gitlab.jfronny.libjf.data.manipulation.mixin",
|
||||
"compatibilityLevel": "JAVA_16",
|
||||
"mixins": [
|
||||
"RecipeManagerMixin",
|
||||
"ReloadableResourceManagerImplMixin"
|
||||
],
|
||||
"client": [
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package io.gitlab.jfronny.libjf.data.manipulation.test;
|
||||
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import io.gitlab.jfronny.libjf.data.manipulation.RecipeUtil;
|
||||
import io.gitlab.jfronny.libjf.data.manipulation.UserResourceEvents;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.resource.AbstractFileResourcePack;
|
||||
|
||||
public class TestEntrypoint implements ModInitializer {
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
// This should prevent resource packs from doing anything if my hooks are working and
|
||||
UserResourceEvents.OPEN.register((type, id, previous, pack) -> {
|
||||
if (pack.getUnderlying() instanceof AbstractFileResourcePack) {
|
||||
LibJf.LOGGER.info(pack.getName() + " opened " + type.name() + "/" + id.toString());
|
||||
}
|
||||
return previous;
|
||||
});
|
||||
UserResourceEvents.CONTAINS.register((type, id, previous, pack) -> {
|
||||
if (pack.getUnderlying() instanceof AbstractFileResourcePack) {
|
||||
return false;
|
||||
}
|
||||
return previous;
|
||||
});
|
||||
RecipeUtil.removeRecipeFor(Items.DIAMOND_SWORD);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "libjf-data-manipulation-v0-testmod",
|
||||
"version": "${version}",
|
||||
"environment": "*",
|
||||
"entrypoints": {
|
||||
"main": [
|
||||
"io.gitlab.jfronny.libjf.data.manipulation.test.TestEntrypoint"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
archivesBaseName = "libjf-data-v0"
|
||||
version = "1.0"
|
||||
|
||||
dependencies {
|
||||
moduleDependencies(project, ["libjf-base"])
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package io.gitlab.jfronny.libjf.data;
|
||||
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import net.fabricmc.fabric.api.tag.TagFactory;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.tag.Tag;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class Tags {
|
||||
public static final Tag<Item> SHULKER_ILLEGAL = TagFactory.ITEM.create(new Identifier(LibJf.MOD_ID, "shulker_boxes_illegal"));
|
||||
public static final Tag<Item> OVERPOWERED = TagFactory.ITEM.create(new Identifier(LibJf.MOD_ID, "overpowered"));
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.libjf.mixin;
|
||||
package io.gitlab.jfronny.libjf.data.mixin;
|
||||
|
||||
import io.gitlab.jfronny.libjf.data.Tags;
|
||||
import net.minecraft.entity.Entity;
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.libjf.mixin;
|
||||
package io.gitlab.jfronny.libjf.data.mixin;
|
||||
|
||||
import io.gitlab.jfronny.libjf.data.Tags;
|
||||
import net.minecraft.block.entity.ShulkerBoxBlockEntity;
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.libjf.mixin;
|
||||
package io.gitlab.jfronny.libjf.data.mixin;
|
||||
|
||||
import io.gitlab.jfronny.libjf.data.Tags;
|
||||
import net.minecraft.item.ItemStack;
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "libjf-data-v0",
|
||||
"version": "${version}",
|
||||
"authors": [
|
||||
"JFronny"
|
||||
],
|
||||
"contact": {
|
||||
"website": "https://jfronny.gitlab.io",
|
||||
"repo": "https://gitlab.com/jfmods/libjf"
|
||||
},
|
||||
"license": "MIT",
|
||||
"environment": "*",
|
||||
"mixins": ["libjf-data-v0.mixins.json"],
|
||||
"custom": {
|
||||
"modmenu": {
|
||||
"parent": "libjf"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +1,10 @@
|
|||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "io.gitlab.jfronny.libjf.mixin",
|
||||
"package": "io.gitlab.jfronny.libjf.data.mixin",
|
||||
"compatibilityLevel": "JAVA_16",
|
||||
"mixins": [
|
||||
"EntityMixin",
|
||||
"RecipeManagerMixin",
|
||||
"ReloadableResourceManagerImplMixin",
|
||||
"ShulkerBoxBlockEntityMixin",
|
||||
"ShulkerBoxSlotMixin"
|
||||
],
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"minecraft:netherite_helmet",
|
||||
"minecraft:netherite_chestplate",
|
||||
"minecraft:netherite_leggings",
|
||||
"minecraft:netherite_boots"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "libjf-data-v0-testmod",
|
||||
"version": "${version}",
|
||||
"environment": "*"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
archivesBaseName = "libjf-unsafe-v0"
|
||||
version = "1.0"
|
||||
|
||||
dependencies {
|
||||
moduleDependencies(project, ["libjf-base"])
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.libjf.entry;
|
||||
package io.gitlab.jfronny.libjf.unsafe;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ReferenceArrayList;
|
||||
import net.fabricmc.loader.ModContainer;
|
|
@ -0,0 +1,15 @@
|
|||
package io.gitlab.jfronny.libjf.unsafe;
|
||||
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import net.fabricmc.loader.api.LanguageAdapter;
|
||||
|
||||
public class JfLanguageAdapter implements LanguageAdapter {
|
||||
@Override
|
||||
public native <T> T create(net.fabricmc.loader.api.ModContainer mod, String value, Class<T> type);
|
||||
|
||||
static {
|
||||
DynamicEntry.execute(LibJf.MOD_ID + ":preEarly", UltraEarlyInit.class, s -> s.instance().init());
|
||||
DynamicEntry.execute(LibJf.MOD_ID + ":early", UltraEarlyInit.class, s -> s.instance().init());
|
||||
LibJf.LOGGER.info("LibJF unsafe init completed");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package io.gitlab.jfronny.libjf.unsafe;
|
||||
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import io.gitlab.jfronny.libjf.unsafe.asm.AsmConfig;
|
||||
import io.gitlab.jfronny.libjf.unsafe.asm.AsmConfigBaker;
|
||||
import io.gitlab.jfronny.libjf.unsafe.asm.AsmTransformer;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
|
||||
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
|
||||
import org.spongepowered.asm.mixin.transformer.FabricMixinTransformerProxy;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class MixinPlugin implements IMixinConfigPlugin {
|
||||
@Override
|
||||
public void onLoad(String mixinPackage) {
|
||||
try {
|
||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||
Class<?> classLoaderClass = classLoader.getClass();
|
||||
|
||||
Field delegateField = classLoaderClass.getDeclaredField("delegate");
|
||||
delegateField.setAccessible(true);
|
||||
Object delegate = delegateField.get(classLoader);
|
||||
Class<?> delegateClass = delegate.getClass();
|
||||
|
||||
Field mixinTransformerField = delegateClass.getDeclaredField("mixinTransformer");
|
||||
mixinTransformerField.setAccessible(true);
|
||||
|
||||
Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
|
||||
unsafeField.setAccessible(true);
|
||||
Unsafe unsafe = (Unsafe) unsafeField.get(null);
|
||||
|
||||
AsmTransformer mixinTransformer = (AsmTransformer) unsafe.allocateInstance(AsmTransformer.class);
|
||||
mixinTransformer.delegate = (FabricMixinTransformerProxy) mixinTransformerField.get(delegate);
|
||||
AsmConfigBaker baker = new AsmConfigBaker();
|
||||
DynamicEntry.execute(LibJf.MOD_ID + ":asm", AsmConfig.class, s -> {
|
||||
LibJf.LOGGER.info("Discovered LibJF asm plugin in " + s.modId());
|
||||
baker.add(s.instance());
|
||||
});
|
||||
mixinTransformer.asmConfig = baker.bake();
|
||||
|
||||
mixinTransformerField.set(delegate, mixinTransformer);
|
||||
} catch (NoSuchFieldException | IllegalAccessException | InstantiationException e) {
|
||||
LibJf.LOGGER.error("Could not initialize LibJF ASM", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRefMapperConfig() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMixins() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
|
||||
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.libjf.entry;
|
||||
package io.gitlab.jfronny.libjf.unsafe;
|
||||
|
||||
public interface UltraEarlyInit {
|
||||
void init();
|
|
@ -0,0 +1,10 @@
|
|||
package io.gitlab.jfronny.libjf.unsafe.asm;
|
||||
|
||||
import io.gitlab.jfronny.libjf.unsafe.asm.patch.Patch;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public interface AsmConfig {
|
||||
Set<String> skipClasses();
|
||||
Set<Patch> getPatches();
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package io.gitlab.jfronny.libjf.unsafe.asm;
|
||||
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import io.gitlab.jfronny.libjf.unsafe.asm.patch.Patch;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class AsmConfigBaker {
|
||||
private final Set<AsmConfig> configs = new LinkedHashSet<>();
|
||||
public void add(AsmConfig config) {
|
||||
configs.add(config);
|
||||
}
|
||||
|
||||
public AsmConfig bake() {
|
||||
Set<String> skipClasses = new HashSet<>();
|
||||
Set<Patch> patches = new LinkedHashSet<>();
|
||||
for (AsmConfig config : configs) {
|
||||
Set<String> skipClassesC = config.skipClasses();
|
||||
Set<Patch> patchesC = config.getPatches();
|
||||
if (skipClassesC != null) skipClasses.addAll(skipClassesC);
|
||||
if (patchesC != null) patches.addAll(patchesC);
|
||||
}
|
||||
LibJf.LOGGER.info("Applying " + patches.size() + " ASM patches");
|
||||
return new AsmConfig() {
|
||||
@Override
|
||||
public Set<String> skipClasses() {
|
||||
return skipClasses;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Patch> getPatches() {
|
||||
return patches;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package io.gitlab.jfronny.libjf.unsafe.asm;
|
||||
|
||||
import io.gitlab.jfronny.libjf.unsafe.asm.patch.Patch;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.spongepowered.asm.mixin.transformer.FabricMixinTransformerProxy;
|
||||
import org.spongepowered.asm.transformers.MixinClassWriter;
|
||||
|
||||
public class AsmTransformer extends FabricMixinTransformerProxy {
|
||||
public FabricMixinTransformerProxy delegate;
|
||||
public AsmConfig asmConfig;
|
||||
|
||||
@Override
|
||||
public byte[] transformClassBytes(String name, String transformedName, byte[] basicClass) {
|
||||
byte[] data = delegate.transformClassBytes(name, transformedName, basicClass);
|
||||
if (data == null || name == null)
|
||||
return basicClass;
|
||||
basicClass = data;
|
||||
if (name.startsWith("org.objectweb.asm")
|
||||
|| name.startsWith("net.fabricmc.loader")
|
||||
|| name.startsWith("net.minecraft")
|
||||
|| name.startsWith("io.gitlab.jfronny.libjf.unsafe.asm")
|
||||
|| name.startsWith("joptsimple")
|
||||
)
|
||||
return basicClass;
|
||||
|
||||
ClassNode klass = new ClassNode();
|
||||
ClassReader reader = new ClassReader(basicClass);
|
||||
reader.accept(klass, ClassReader.EXPAND_FRAMES);
|
||||
|
||||
for (Patch patch : asmConfig.getPatches()) {
|
||||
patch.apply(klass);
|
||||
}
|
||||
|
||||
ClassWriter writer = new MixinClassWriter(reader, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||
klass.accept(writer);
|
||||
basicClass = writer.toByteArray();
|
||||
return basicClass;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package io.gitlab.jfronny.libjf.unsafe.asm.patch;
|
||||
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.InsnList;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public abstract class InterfaceImplMethodReplacePatch implements Patch {
|
||||
private final String targetInterface;
|
||||
|
||||
protected InterfaceImplMethodReplacePatch(String targetInterface) {
|
||||
this.targetInterface = targetInterface;
|
||||
}
|
||||
|
||||
public abstract Map<String, Consumer<InsnList>> getPatches();
|
||||
|
||||
@Override
|
||||
public void apply(ClassNode klazz) {
|
||||
if (klazz.interfaces.contains(targetInterface) || targetInterface.equals(klazz.superName)) {
|
||||
LibJf.LOGGER.info("Found " + klazz.name + " implementing " + targetInterface);
|
||||
Map<String, Consumer<InsnList>> patches = getPatches();
|
||||
for (MethodNode method : klazz.methods) {
|
||||
if (patches.containsKey(method.name)) {
|
||||
LibJf.LOGGER.info("Patching " + method.name);
|
||||
method.instructions.clear();
|
||||
patches.get(method.name).accept(method.instructions);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package io.gitlab.jfronny.libjf.unsafe.asm.patch;
|
||||
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
public interface Patch {
|
||||
void apply(ClassNode klazz);
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "libjf-unsafe-v0",
|
||||
"version": "${version}",
|
||||
"authors": [
|
||||
"JFronny"
|
||||
],
|
||||
"contact": {
|
||||
"website": "https://jfronny.gitlab.io",
|
||||
"repo": "https://gitlab.com/jfmods/libjf"
|
||||
},
|
||||
"license": "MIT",
|
||||
"environment": "*",
|
||||
"languageAdapters": {
|
||||
"libjf": "io.gitlab.jfronny.libjf.unsafe.JfLanguageAdapter"
|
||||
},
|
||||
"mixins": ["libjf-unsafe-v0.mixins.json"],
|
||||
"custom": {
|
||||
"modmenu": {
|
||||
"parent": "libjf"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "io.gitlab.jfronny.libjf.data.mixin",
|
||||
"compatibilityLevel": "JAVA_16",
|
||||
"plugin": "io.gitlab.jfronny.libjf.unsafe.MixinPlugin",
|
||||
"mixins": [
|
||||
],
|
||||
"client": [
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package io.gitlab.jfronny.libjf.unsafe.test;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import io.gitlab.jfronny.libjf.unsafe.asm.AsmConfig;
|
||||
import io.gitlab.jfronny.libjf.unsafe.asm.patch.Patch;
|
||||
import net.minecraft.client.main.Main;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.tree.MethodInsnNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class AsmTest implements AsmConfig {
|
||||
@Override
|
||||
public Set<String> skipClasses() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Patch> getPatches() {
|
||||
return Set.of(klazz -> {
|
||||
if (klazz.name.equals("com/mojang/blaze3d/systems/RenderSystem")) {
|
||||
for (MethodNode method : klazz.methods) {
|
||||
if (method.name.equals("initRenderThread")) {
|
||||
method.instructions.insert(new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(AsmTest.class), "logSuccess", "()V"));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void logSuccess() {
|
||||
LibJf.LOGGER.info("Successfully ASMd into RenderSystem\n" +
|
||||
":::'###:::::'######::'##::::'##:'########:'########::'######::'########:\n" +
|
||||
"::'## ##:::'##... ##: ###::'###:... ##..:: ##.....::'##... ##:... ##..::\n" +
|
||||
":'##:. ##:: ##:::..:: ####'####:::: ##:::: ##::::::: ##:::..::::: ##::::\n" +
|
||||
"'##:::. ##:. ######:: ## ### ##:::: ##:::: ######:::. ######::::: ##::::\n" +
|
||||
" #########::..... ##: ##. #: ##:::: ##:::: ##...:::::..... ##:::: ##::::\n" +
|
||||
" ##.... ##:'##::: ##: ##:.:: ##:::: ##:::: ##:::::::'##::: ##:::: ##::::\n" +
|
||||
" ##:::: ##:. ######:: ##:::: ##:::: ##:::: ########:. ######::::: ##::::\n" +
|
||||
"..:::::..:::......:::..:::::..:::::..:::::........:::......::::::..:::::");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package io.gitlab.jfronny.libjf.unsafe.test;
|
||||
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import io.gitlab.jfronny.libjf.unsafe.UltraEarlyInit;
|
||||
|
||||
public class UnsafeEntryTest implements UltraEarlyInit {
|
||||
@Override
|
||||
public void init() {
|
||||
LibJf.LOGGER.info("Successfully executed code before that should be possible\n" +
|
||||
"'||' '|' '|| . '||''''| '|| \n" +
|
||||
" || | || .||. ... .. .... || . .... ... .. || .... ... \n" +
|
||||
" || | || || ||' '' '' .|| ||''| '' .|| ||' '' || '|. | \n" +
|
||||
" || | || || || .|' || || .|' || || || '|.| \n" +
|
||||
" '|..' .||. '|.' .||. '|..'|' .||.....| '|..'|' .||. .||. '| \n" +
|
||||
" .. | \n" +
|
||||
" '' ");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "libjf-unsafe-v0-testmod",
|
||||
"version": "${version}",
|
||||
"environment": "*",
|
||||
"entrypoints": {
|
||||
"libjf:asm": [
|
||||
"io.gitlab.jfronny.libjf.unsafe.test.AsmTest"
|
||||
],
|
||||
"libjf:early": [
|
||||
"io.gitlab.jfronny.libjf.unsafe.test.UnsafeEntryTest"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -7,3 +7,12 @@ pluginManagement {
|
|||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = "libjf"
|
||||
|
||||
include 'libjf-base'
|
||||
|
||||
include 'libjf-config-v0'
|
||||
include 'libjf-data-v0'
|
||||
include 'libjf-data-manipulation-v0'
|
||||
include 'libjf-unsafe-v0'
|
|
@ -1,41 +0,0 @@
|
|||
package io.gitlab.jfronny.libjf;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import io.gitlab.jfronny.libjf.config.Config;
|
||||
import io.gitlab.jfronny.libjf.gson.HiddenAnnotationExclusionStrategy;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Libjf {
|
||||
public static final String MOD_ID = "libjf";
|
||||
public static final Logger LOGGER = LogManager.getLogger(MOD_ID);
|
||||
public static final Gson GSON = new GsonBuilder()
|
||||
.excludeFieldsWithModifiers(Modifier.TRANSIENT)
|
||||
.excludeFieldsWithModifiers(Modifier.PRIVATE)
|
||||
.addSerializationExclusionStrategy(new HiddenAnnotationExclusionStrategy())
|
||||
.setPrettyPrinting()
|
||||
.create();
|
||||
private static final Map<String, Config> configs = new HashMap<>();
|
||||
|
||||
@Deprecated
|
||||
public static void registerConfig(String modId, Class<?> config) {
|
||||
if (!isRegistered(config))
|
||||
configs.put(modId, new Config(modId, config));
|
||||
}
|
||||
public static Map<String, Config> getConfigs() {
|
||||
return ImmutableMap.copyOf(configs);
|
||||
}
|
||||
public static boolean isRegistered(Class<?> config) {
|
||||
for (Config value : configs.values()) {
|
||||
if (value.configClass.equals(config))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
package io.gitlab.jfronny.libjf.data;
|
||||
|
||||
import net.fabricmc.fabric.api.tag.TagFactory;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.tag.Tag;
|
||||
import net.minecraft.util.Identifier;
|
||||
import io.gitlab.jfronny.libjf.Libjf;
|
||||
|
||||
public class Tags {
|
||||
public static Tag<Item> SHULKER_ILLEGAL = TagFactory.ITEM.create(new Identifier(Libjf.MOD_ID, "shulker_boxes_illegal"));
|
||||
public static Tag<Item> OVERPOWERED = TagFactory.ITEM.create(new Identifier(Libjf.MOD_ID, "overpowered"));
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
package io.gitlab.jfronny.libjf.entry;
|
||||
|
||||
import io.gitlab.jfronny.libjf.Libjf;
|
||||
import io.gitlab.jfronny.libjf.config.JfConfig;
|
||||
import net.fabricmc.loader.api.LanguageAdapter;
|
||||
|
||||
public class JfLanguageAdapter implements LanguageAdapter {
|
||||
@Override
|
||||
public native <T> T create(net.fabricmc.loader.api.ModContainer mod, String value, Class<T> type);
|
||||
|
||||
static {
|
||||
DynamicEntry.execute(Libjf.MOD_ID + ":config", JfConfig.class, s -> {
|
||||
Libjf.registerConfig(s.modId(), s.instance().getClass());
|
||||
Libjf.LOGGER.info("Registering config for " + s.modId());
|
||||
});
|
||||
DynamicEntry.execute(Libjf.MOD_ID + ":early", UltraEarlyInit.class, s -> s.instance().init());
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 4.3 KiB |
|
@ -14,20 +14,6 @@
|
|||
"license": "MIT",
|
||||
"icon": "assets/libjf/icon.png",
|
||||
"environment": "*",
|
||||
"entrypoints": {
|
||||
"client": [
|
||||
"io.gitlab.jfronny.libjf.entry.LibjfClient"
|
||||
],
|
||||
"modmenu": [
|
||||
"io.gitlab.jfronny.libjf.config.ModMenu"
|
||||
]
|
||||
},
|
||||
"languageAdapters": {
|
||||
"libjf": "io.gitlab.jfronny.libjf.entry.JfLanguageAdapter"
|
||||
},
|
||||
"mixins": [
|
||||
"libjf.mixins.json"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.11.3",
|
||||
"minecraft": "*"
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
package io.gitlab.jfronny.libjf.test;
|
||||
|
||||
import io.gitlab.jfronny.libjf.data.UserResourceEvents;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.minecraft.resource.AbstractFileResourcePack;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
|
||||
public class Entrypoint implements ModInitializer {
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
// This should prevent resource packs from doing anything if my hooks are working and
|
||||
UserResourceEvents.OPEN.register((type, id, previous, pack) -> {
|
||||
if (TestMod.disablePacks && pack.getUnderlying() instanceof AbstractFileResourcePack) {
|
||||
throw new FileNotFoundException();
|
||||
}
|
||||
return previous;
|
||||
});
|
||||
UserResourceEvents.CONTAINS.register((type, id, previous, pack) -> {
|
||||
if (TestMod.disablePacks && pack.getUnderlying() instanceof AbstractFileResourcePack) {
|
||||
return false;
|
||||
}
|
||||
return previous;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"libjf-testmod.jfconfig.title": "JfConfig example",
|
||||
"libjf-testmod.jfconfig.disablePacks": "Disable resource packs",
|
||||
"libjf-testmod.jfconfig.intTest": "Int Test",
|
||||
"libjf-testmod.jfconfig.decimalTest": "Decimal Test",
|
||||
"libjf-testmod.jfconfig.dieStr": "String Test",
|
||||
"libjf-testmod.jfconfig.enumTest": "Enum Test",
|
||||
"libjf-testmod.jfconfig.enumTest.tooltip": "Enum Test Tooltip",
|
||||
"libjf-testmod.jfconfig.enum.Test.Test": "Test",
|
||||
"libjf-testmod.jfconfig.enum.Test.ER": "ER"
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "libjf-testmod",
|
||||
"version": "${version}",
|
||||
"environment": "*",
|
||||
"entrypoints": {
|
||||
"libjf:config": [
|
||||
"io.gitlab.jfronny.libjf.test.TestMod"
|
||||
],
|
||||
"main": [
|
||||
"io.gitlab.jfronny.libjf.test.Entrypoint"
|
||||
]
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue