diff --git a/build.gradle b/build.gradle index eed9d9b..ed3bc8e 100644 --- a/build.gradle +++ b/build.gradle @@ -1,106 +1,152 @@ plugins { - id 'fabric-loom' version '1.3-SNAPSHOT' id 'maven-publish' -} - -version = project.mod_version -group = project.maven_group - -base { - archivesName = project.archives_base_name -} - -repositories { - // Add repositories to retrieve artifacts from in here. - // You should only use this when depending on other mods because - // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. - // See https://docs.gradle.org/current/userguide/declaring_repositories.html - // for more information about repositories. - maven { - url "https://cursemaven.com" - content { - includeGroup "curse.maven" - } - } + id 'fabric-loom' version '1.5-SNAPSHOT' apply false - maven { - name("Modrinth Maven") - url("https://api.modrinth.com/maven") + // https://github.com/ReplayMod/preprocessor + // https://github.com/Fallen-Breath/preprocessor + id 'com.replaymod.preprocess' version 'ce1aeb2b' - content { - includeGroup("maven.modrinth") - } - } - - mavenCentral() + // https://github.com/Fallen-Breath/yamlang + id 'me.fallenbreath.yamlang' version '1.3.1' apply false } -dependencies { - // To change the versions see the gradle.properties file - minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - - // Fabric API. This is technically optional, but you probably want it anyway. - // modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" +preprocess { + def mc117 = createNode('1.17.1', 1_17_01, '') + def mc118 = createNode('1.18.2', 1_18_02, '') + def mc119 = createNode('1.19.4', 1_19_04, '') + def mc120 = createNode('1.20.4', 1_20_04, '') - // Uncomment the following line to enable the deprecated Fabric API modules. - // These are included in the Fabric API production distribution and allow you to update your mod to the latest modules at a later more convenient time. - modImplementation "net.fabricmc.fabric-api:fabric-api-deprecated:${project.fabric_version}" - - modImplementation "curse.maven:malilib-303119:${project.malilib_file_id}" - modImplementation "curse.maven:item-scroller-242064:${project.item_scroller_file_id}" - modImplementation("top.hendrixshen.magiclib:magiclib-${project.minecraft_version.replace(".", "_")}:${project.magiclib_version}") { - exclude(group: "carpet", module: "fabric-carpet") - } + mc120.link(mc119, null) + mc119.link(mc118, file("versions/mapping-1.19.4-1.18.2.txt")) + mc118.link(mc117, null) } -processResources { - inputs.property "version", project.version - inputs.property "minecraft_dependency", project.minecraft_dependency - - filesMatching("fabric.mod.json") { - def valueMap = [ - "version" : project.version, - "minecraft_dependency": project.minecraft_dependency - ] - expand valueMap +tasks.register('buildAndGather') { + subprojects { + dependsOn project.tasks.named('build').get() } -} - -tasks.withType(JavaCompile).configureEach { - it.options.release = 17 -} - -java { - // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task - // if it is present. - // If you remove this line, sources will not be generated. - withSourcesJar() - - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 -} - -jar { - from("LICENSE") { - rename { "${it}_${project.base.archivesName.get()}" } + doFirst { + println 'Gathering builds' + def buildLibs = { + p -> p.buildDir.toPath().resolve('libs') + } + delete fileTree(buildLibs(rootProject)) { + include '*' + } + subprojects { + copy { + from(buildLibs(project)) { + include '*.jar' + exclude '*-dev.jar', '*-sources.jar', '*-shadow.jar' + } + into buildLibs(rootProject) + duplicatesStrategy DuplicatesStrategy.INCLUDE + } + } } } -// configure the maven publication -publishing { - publications { - mavenJava(MavenPublication) { - from components.java - } - } - // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. - 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. - } -} \ No newline at end of file +// +// +//version = project.mod_version +//group = project.maven_group +// +//base { +// archivesName = project.archives_base_name +//} +// +//repositories { +// // Add repositories to retrieve artifacts from in here. +// // You should only use this when depending on other mods because +// // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. +// // See https://docs.gradle.org/current/userguide/declaring_repositories.html +// // for more information about repositories. +// maven { +// url "https://cursemaven.com" +// content { +// includeGroup "curse.maven" +// } +// } +// +// maven { +// name("Modrinth Maven") +// url("https://api.modrinth.com/maven") +// +// content { +// includeGroup("maven.modrinth") +// } +// } +// +// mavenCentral() +//} +// +//dependencies { +// // To change the versions see the gradle.properties file +// minecraft "com.mojang:minecraft:${project.minecraft_version}" +// mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" +// modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" +// +// // Fabric API. This is technically optional, but you probably want it anyway. +// // modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" +// +// // Uncomment the following line to enable the deprecated Fabric API modules. +// // These are included in the Fabric API production distribution and allow you to update your mod to the latest modules at a later more convenient time. +// modImplementation "net.fabricmc.fabric-api:fabric-api-deprecated:${project.fabric_version}" +// +// modImplementation "curse.maven:malilib-303119:${project.malilib_file_id}" +// modImplementation "curse.maven:item-scroller-242064:${project.item_scroller_file_id}" +// modImplementation("top.hendrixshen.magiclib:magiclib-${project.minecraft_version.replace(".", "_")}:${project.magiclib_version}") { +// exclude(group: "carpet", module: "fabric-carpet") +// } +//} +// +//processResources { +// inputs.property "version", project.version +// inputs.property "minecraft_dependency", project.minecraft_dependency +// +// filesMatching("fabric.mod.json") { +// def valueMap = [ +// "version" : project.version, +// "minecraft_dependency": project.minecraft_dependency +// ] +// expand valueMap +// } +//} +// +//tasks.withType(JavaCompile).configureEach { +// it.options.release = 17 +//} +// +//java { +// // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task +// // if it is present. +// // If you remove this line, sources will not be generated. +// withSourcesJar() +// +// sourceCompatibility = JavaVersion.VERSION_17 +// targetCompatibility = JavaVersion.VERSION_17 +//} +// +//jar { +// from("LICENSE") { +// rename { "${it}_${project.base.archivesName.get()}" } +// } +//} +// +//// configure the maven publication +//publishing { +// publications { +// mavenJava(MavenPublication) { +// from components.java +// } +// } +// +// // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. +// 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. +// } +//} \ No newline at end of file diff --git a/common.gradle b/common.gradle new file mode 100644 index 0000000..22a6bd9 --- /dev/null +++ b/common.gradle @@ -0,0 +1,219 @@ +apply plugin: 'maven-publish' +apply plugin: 'fabric-loom' +apply plugin: 'com.replaymod.preprocess' +apply plugin: 'me.fallenbreath.yamlang' + +int mcVersion = project.mcVersion + +preprocess { + tabIndentation = true +} + +repositories { + maven { + url 'https://jitpack.io' + } + + maven { + url "https://maven.terraformersmc.com/releases/" + } + + maven { + url "https://cursemaven.com" + content { + includeGroup "curse.maven" + } + } + + maven { + name("Modrinth Maven") + url("https://api.modrinth.com/maven") + + content { + includeGroup("maven.modrinth") + } + } +} + +// https://github.com/FabricMC/fabric-loader/issues/783 +configurations { + modRuntimeOnly.exclude group: 'net.fabricmc', module: 'fabric-loader' +} + +dependencies { + // loom + minecraft "com.mojang:minecraft:${project.minecraft_version}" + mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" + modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" + + // runtime mods + // modRuntimeOnly "com.github.gnembon:fabric-carpet:${project.carpet_version}" + + // dependencies + include modImplementation("net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}") + include modImplementation("curse.maven:malilib-303119:${project.malilib_file_id}") + include modImplementation("curse.maven:item-scroller-242064:${project.item_scroller_file_id}") + + include modImplementation("com.terraformersmc:modmenu:${project.modmenu_version}") +} + +String MIXIN_CONFIG_PATH = 'unlimitedtrademod.mixins.json' +String LANG_DIR = 'assets/unlimitedtrade/lang' +JavaVersion JAVA_COMPATIBILITY +if (mcVersion >= 11800) { + JAVA_COMPATIBILITY = JavaVersion.VERSION_17 +} else if (mcVersion >= 11700) { + JAVA_COMPATIBILITY = JavaVersion.VERSION_16 +} + +loom { + runConfigs.configureEach { + // to make sure it generates all "Minecraft Client (:subproject_name)" applications + ideConfigGenerated = true + runDir '../../run' + vmArgs '-Dmixin.debug.export=true' + } +// // [FEATURE] MIXIN_AUDITOR +// runs { +// serverMixinAudit { +// server() +// vmArgs '-DmixinAuditor.audit=true' +// ideConfigGenerated false +// } +// } +} + +remapJar { + remapperIsolation = true +} + +String versionSuffix = '' +// detect github action environment variables +// https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables +if (System.getenv("BUILD_RELEASE") != "true") { + String buildNumber = System.getenv("BUILD_ID") + versionSuffix += buildNumber != null ? ('+build.' + buildNumber) : '-SNAPSHOT' +} +String fullModVersion = project.mod_version + versionSuffix + +group = project.maven_group +if (System.getenv("JITPACK") == "true") { + // move mc version into archivesBaseName, so jitpack will be able to organize archives from multiple subprojects correctly + base.archivesName = project.archives_base_name + '-mc' + project.minecraft_version + version = 'v' + fullModVersion +} else { + base.archivesName = project.archives_base_name + version = 'mc' + project.minecraft_version + '-v' + fullModVersion +} + +// See https://youtrack.jetbrains.com/issue/IDEA-296490 +// if IDEA complains about "Cannot resolve resource filtering of MatchingCopyAction" and you want to know why +processResources { + inputs.property "version", fullModVersion + inputs.property "minecraft_dependency", project.minecraft_dependency + + filesMatching("fabric.mod.json") { + def valueMap = [ + "version" : fullModVersion, + "minecraft_dependency": project.minecraft_dependency, + ] + expand valueMap + } + + filesMatching(MIXIN_CONFIG_PATH) { + filter { s -> s.replace('{{COMPATIBILITY_LEVEL}}', "JAVA_${JAVA_COMPATIBILITY.ordinal() + 1}") } + } +} + +// https://github.com/Fallen-Breath/yamlang +yamlang { + targetSourceSets = [sourceSets.main] + inputDir = LANG_DIR +} + +// ensure that the encoding is set to UTF-8, no matter what the system default is +// this fixes some edge cases with special characters not displaying correctly +// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html +tasks.withType(JavaCompile).configureEach { + options.encoding = "UTF-8" + options.compilerArgs << "-Xlint:deprecation" << "-Xlint:unchecked" +} + +java { + sourceCompatibility = JAVA_COMPATIBILITY + targetCompatibility = JAVA_COMPATIBILITY + + // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task + // if it is present. + // If you remove this line, sources will not be generated. + withSourcesJar() +} + +jar { + from(rootProject.file('LICENSE')) { + rename { "${it}_${project.archives_base_name}" } + } +} + +// https://github.com/hierynomus/license-gradle-plugin +//license { +// // use "gradle licenseFormat" to apply license headers +// header = rootProject.file('HEADER.txt') +// include '**/*.java' +// skipExistingHeaders = true +// +// headerDefinitions { +// // ref: https://github.com/mathieucarbou/license-maven-plugin/blob/4c42374bb737378f5022a3a36849d5e23ac326ea/license-maven-plugin/src/main/java/com/mycila/maven/plugin/license/header/HeaderType.java#L48 +// // modification: add a newline at the end +// SLASHSTAR_STYLE_NEWLINE { +// firstLine = "/*" +// beforeEachLine = " * " +// endLine = " */" + System.lineSeparator() +// afterEachLine = "" +// skipLinePattern = null +// firstLineDetectionPattern = "(\\s|\\t)*/\\*.*\$" +// lastLineDetectionPattern = ".*\\*/(\\s|\\t)*\$" +// allowBlankLines = false +// isMultiline = true +// padLines = false +// } +// } +// mapping { +// java = 'SLASHSTAR_STYLE_NEWLINE' +// } +// ext { +// name = project.mod_name +// author = 'Fallen_Breath' +// year = Calendar.getInstance().get(Calendar.YEAR).toString() +// } +//} +//classes.dependsOn licenseFormatMain +//testClasses.dependsOn licenseFormatTest + +// configure the maven publication +publishing { + publications { + mavenJava(MavenPublication) { + artifactId base.archivesName.get() + + from components.java + } + } + + // select the repositories you want to publish to + repositories { + // mavenLocal() + +// // [FEATURE] FALLENS_MAVEN +// maven { +// url = version.endsWith("SNAPSHOT") ? "https://maven.fallenbreath.me/snapshots" : "https://maven.fallenbreath.me/releases" +// credentials(PasswordCredentials) { +// username = 'fallen' +// password = System.getenv("FALLENS_MAVEN_TOKEN") +// } +// authentication { +// basic(BasicAuthentication) +// } +// } + } +} diff --git a/gradle.properties b/gradle.properties index ef592a2..9d3bd96 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,21 +1,13 @@ # Done to increase the memory available to gradle. org.gradle.jvmargs=-Xmx1G org.gradle.parallel=true -# Fabric Properties -# check these on https://fabricmc.net/develop -minecraft_dependency=1.20.x -minecraft_version=1.20.1 -yarn_mappings=1.20.1+build.10 -loader_version=0.14.22 +# Fabric Base Properties +# https://fabricmc.net/versions.html +loader_version=0.15.1 # Mod Properties mod_version=1.0.0 maven_group=monkey.unlimitedtrade archives_base_name=unlimitedtrade -# Dependencies -fabric_version=0.86.1+1.20.1 -## https://www.curseforge.com/minecraft/mc-mods/malilib -malilib_file_id=4623483 -## https://www.curseforge.com/minecraft/mc-mods/item-scroller -item_scroller_file_id=4593079 -## https://www.curseforge.com/minecraft/mc-mods/magiclib -magiclib_version=0.7.364 +# Global Dependencies +modmenu_version=9.0.0-pre.1 +carpet_version=1.4.128 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 033e24c..7f93135 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 9f4197d..1af9e09 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index fcb6fca..0adc8e1 100644 --- a/gradlew +++ b/gradlew @@ -83,7 +83,8 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/settings.gradle b/settings.gradle index b02216b..da4582b 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,10 +1,40 @@ +import groovy.json.JsonSlurper + pluginManagement { repositories { maven { name = 'Fabric' url = 'https://maven.fabricmc.net/' } + + maven { + url "https://maven.terraformersmc.com/releases/" + } + + maven { + name = 'Jitpack' + url = 'https://jitpack.io' + } mavenCentral() gradlePluginPortal() } + resolutionStrategy { + eachPlugin { + switch (requested.id.id) { + case "com.replaymod.preprocess": { + useModule("com.github.Fallen-Breath:preprocessor:${requested.version}") + break + } + } + } + } +} + +def settings = new JsonSlurper().parseText(file('settings.json').text) +for (String version : settings.versions) { + include(":$version") + + def proj = project(":$version") + proj.projectDir = file("versions/$version") + proj.buildFileName = "../../common.gradle" } diff --git a/settings.json b/settings.json new file mode 100644 index 0000000..989ea55 --- /dev/null +++ b/settings.json @@ -0,0 +1,8 @@ +{ + "versions": [ + "1.17.1", + "1.18.2", + "1.19.4", + "1.20.4" + ] +} \ No newline at end of file diff --git a/src/main/java/monkey/unlimitedtrade/AutoTradModClient.java b/src/main/java/monkey/unlimitedtrade/AutoTradeModClient.java similarity index 62% rename from src/main/java/monkey/unlimitedtrade/AutoTradModClient.java rename to src/main/java/monkey/unlimitedtrade/AutoTradeModClient.java index f4b3c71..c9f9f8a 100644 --- a/src/main/java/monkey/unlimitedtrade/AutoTradModClient.java +++ b/src/main/java/monkey/unlimitedtrade/AutoTradeModClient.java @@ -6,7 +6,9 @@ import it.unimi.dsi.fastutil.ints.IntArrayList; import monkey.unlimitedtrade.config.Configs; import monkey.unlimitedtrade.config.types.AfterTradeActions; -import monkey.unlimitedtrade.utils.chunkdebug.ChunkdebugApi; +import monkey.unlimitedtrade.utils.chunkdebug.BaseChunkDebug; +import monkey.unlimitedtrade.utils.chunkdebug.ChunkDebugAPI; +import monkey.unlimitedtrade.utils.chunkdebug.essential.EssentialChunkDebugAPI; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.MinecraftClient; @@ -24,63 +26,37 @@ import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import top.hendrixshen.magiclib.malilib.impl.ConfigHandler; -import top.hendrixshen.magiclib.malilib.impl.ConfigManager; import static net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents.START_CLIENT_TICK; -public class AutoTradModClient implements ClientModInitializer { +public class AutoTradeModClient implements ClientModInitializer { public static final String MOD_ID = "unlimitedtrade"; public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); public static String VERSION = "unknown"; - public static ChunkdebugApi CHUNK_DEBUG = new ChunkdebugApi(); + public static BaseChunkDebug CHUNK_DEBUG_API; public static int remainingUseRetries = 0; @Nullable public static MerchantEntity tradeEntity; - @Override - public void onInitializeClient() { - VERSION = FabricLoader.getInstance().getModContainer(MOD_ID).orElseThrow(RuntimeException::new).getMetadata().getVersion().getFriendlyString(); - - ConfigManager cm = ConfigManager.get(MOD_ID); - cm.parseConfigClass(Configs.class); - ConfigHandler configHandler = new ConfigHandler(MOD_ID, cm, Configs.VERSION); - ConfigHandler.register(configHandler); - Configs.init(cm); - - START_CLIENT_TICK.register(client -> { - if (!Configs.startTrade) { - remainingUseRetries = 0; - return; - } - - if (remainingUseRetries > 0) tryInteractBlock(client); - else if (client.crosshairTarget instanceof EntityHitResult hitResult) { - if (hitResult.getEntity() instanceof MerchantEntity merchantEntity) { - tradeEntity = merchantEntity; - Identifier world = tradeEntity.getWorld().getRegistryKey().getValue(); - - if (client.interactionManager != null && client.player != null && GuiUtils.getCurrentScreen() == null) { - if (client.player.getPos().isInRange(tradeEntity.getPos(), 2)) { - client.interactionManager.interactEntity(client.player, tradeEntity, Hand.MAIN_HAND); - } - } - - // if in listening world != villageOldWorld re-listen - if (CHUNK_DEBUG.getCurrentWorld() == null || !CHUNK_DEBUG.getCurrentWorld().equals(world)) { - CHUNK_DEBUG.requestChunkData(world); - } - } - } else if (tradeEntity != null && GuiUtils.getCurrentScreen() instanceof MerchantScreen merchantScreen) { - if (client.player == null || client.player.isSneaking()) return; - if (!Configs.waitChunkDebug || CHUNK_DEBUG.worldChunks.get(tradeEntity.getChunkPos()).levelType() == ChunkLevelType.INACCESSIBLE) { - this.startTrade(client, merchantScreen); + /** + * try to interact block + * + * @param client Minecraft Client + */ + public static void tryInteractBlock(MinecraftClient client) { + if (Configs.afterTradeActions.getOptionListValue() == AfterTradeActions.USE || + Configs.afterTradeActions.getOptionListValue() == AfterTradeActions.USE_AND_DROP) { + if (client.crosshairTarget instanceof BlockHitResult hitResult && client.interactionManager != null) { + if (client.interactionManager.interactBlock(client.player, Hand.MAIN_HAND, hitResult) != ActionResult.PASS) { + remainingUseRetries--; + return; } } - }); + } + remainingUseRetries = 0; } - public void startTrade(MinecraftClient client, MerchantScreen merchantScreen) { + public static void startTrade(MinecraftClient client, MerchantScreen merchantScreen) { MerchantScreenHandler handler = merchantScreen.getScreenHandler(); IntArrayList favorites = VillagerDataStorage.getInstance().getFavoritesForCurrentVillager(handler).favorites; @@ -89,12 +65,11 @@ public void startTrade(MinecraftClient client, MerchantScreen merchantScreen) { InventoryUtils.villagerTradeEverythingPossibleWithAllFavoritedTrades(); // drop all sell item - if (Configs.afterTradeActions == AfterTradeActions.USE_AND_DROP) { + if (Configs.afterTradeActions.getOptionListValue() == AfterTradeActions.USE_AND_DROP) { for (int index = 0; index < favorites.size(); ++index) { Item sellItem = handler.getRecipes().get(index).getSellItem().getItem(); - LOGGER.info(sellItem.getName().toString()); - if (Configs.dropBlockList.contains(sellItem.getName().toString())) { + if (Configs.dropBlockList.getStrings().contains(sellItem.getName().toString())) { continue; } @@ -108,24 +83,62 @@ public void startTrade(MinecraftClient client, MerchantScreen merchantScreen) { merchantScreen.close(); - remainingUseRetries = Configs.maxUseRetries; + remainingUseRetries = 20; tryInteractBlock(client); } - /** - * try interact block - * - * @param client Minecraft Client - */ - private void tryInteractBlock(MinecraftClient client) { - if (Configs.afterTradeActions == AfterTradeActions.USE || Configs.afterTradeActions == AfterTradeActions.USE_AND_DROP) { - if (client.crosshairTarget instanceof BlockHitResult hitResult && client.interactionManager != null) { - if (client.interactionManager.interactBlock(client.player, Hand.MAIN_HAND, hitResult) != ActionResult.PASS) { - remainingUseRetries--; - return; + @Override + public void onInitializeClient() { + VERSION = FabricLoader.getInstance().getModContainer(MOD_ID).orElseThrow(RuntimeException::new).getMetadata().getVersion().getFriendlyString(); + + Configs.init(); + + if (FabricLoader.getInstance().isModLoaded("essential-client")) { + LOGGER.info("essential-client is install, use essential-client chunk debug"); + CHUNK_DEBUG_API = new EssentialChunkDebugAPI(); + } else { + LOGGER.info("essential-client is not install, use current chunk debug"); + CHUNK_DEBUG_API = new ChunkDebugAPI(); + } + + START_CLIENT_TICK.register(client -> { +// if (client.player != null) { +// LOGGER.info(String.valueOf(CHUNK_DEBUG_API.getChunkData(client.player.getChunkPos()))); +// +// Identifier world = client.player.getWorld().getRegistryKey().getValue(); +// if (!world.equals(CHUNK_DEBUG_API.getCurrentWorld())) CHUNK_DEBUG_API.requestChunkData(world); +// } + + if (!Configs.startTrade.getBooleanValue()) { + AutoTradeModClient.remainingUseRetries = 0; + return; + } + + if (AutoTradeModClient.remainingUseRetries > 0) AutoTradeModClient.tryInteractBlock(client); + else if (client.crosshairTarget instanceof EntityHitResult hitResult) { + if (hitResult.getEntity() instanceof MerchantEntity merchantEntity) { + tradeEntity = merchantEntity; + Identifier world = tradeEntity.getWorld().getRegistryKey().getValue(); + + if (client.interactionManager != null && client.player != null && GuiUtils.getCurrentScreen() == null) { + if (client.player.getPos().isInRange(tradeEntity.getPos(), 2)) { + client.interactionManager.interactEntity(client.player, tradeEntity, Hand.MAIN_HAND); + } + } + + // if in listening world != villageOldWorld re-listen + if (CHUNK_DEBUG_API != null && CHUNK_DEBUG_API.getCurrentWorld() != null && !CHUNK_DEBUG_API.getCurrentWorld().equals(world)) { + CHUNK_DEBUG_API.requestChunkData(world); + } + } + } else if (tradeEntity != null && GuiUtils.getCurrentScreen() instanceof MerchantScreen merchantScreen) { + if (client.player != null && client.player.isSneaking()) return; + + if (!Configs.waitChunkDebug.getBooleanValue() || CHUNK_DEBUG_API != null && + CHUNK_DEBUG_API.getChunkData(tradeEntity.getChunkPos()).levelType() == ChunkLevelType.INACCESSIBLE) { + AutoTradeModClient.startTrade(client, merchantScreen); } } - } - remainingUseRetries = 0; + }); } -} \ No newline at end of file +} diff --git a/src/main/java/monkey/unlimitedtrade/config/AutoTradeConfigOption.java b/src/main/java/monkey/unlimitedtrade/config/AutoTradeConfigOption.java new file mode 100644 index 0000000..8956538 --- /dev/null +++ b/src/main/java/monkey/unlimitedtrade/config/AutoTradeConfigOption.java @@ -0,0 +1,10 @@ +package monkey.unlimitedtrade.config; + +import monkey.unlimitedtrade.config.options.AutoTradeIConfigBase; + +public record AutoTradeConfigOption(Config annotation, AutoTradeIConfigBase config) { + + public Config.Category getCategory() { + return this.annotation.category(); + } +} diff --git a/src/main/java/monkey/unlimitedtrade/config/AutoTradeConfigStorage.java b/src/main/java/monkey/unlimitedtrade/config/AutoTradeConfigStorage.java new file mode 100644 index 0000000..04058d7 --- /dev/null +++ b/src/main/java/monkey/unlimitedtrade/config/AutoTradeConfigStorage.java @@ -0,0 +1,62 @@ +package monkey.unlimitedtrade.config; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import fi.dy.masa.malilib.config.ConfigUtils; +import fi.dy.masa.malilib.config.IConfigHandler; +import fi.dy.masa.malilib.util.JsonUtils; +import monkey.unlimitedtrade.AutoTradeModClient; +import monkey.unlimitedtrade.config.options.AutoTradeIConfigBase; +import net.fabricmc.loader.api.FabricLoader; + +import java.io.File; +import java.util.List; +import java.util.stream.Collectors; + +import static monkey.unlimitedtrade.config.Configs.CATEGORY_TO_OPTION; + +public class AutoTradeConfigStorage implements IConfigHandler { + public static final String CONFIG_FILE_NAME = AutoTradeModClient.MOD_ID + ".json"; + private static final AutoTradeConfigStorage INSTANCE = new AutoTradeConfigStorage(); + private JsonObject jsonObject = new JsonObject(); + + public static File getConfigFile() { + return FabricLoader.getInstance().getConfigDir().resolve(CONFIG_FILE_NAME).toFile(); + } + + public static AutoTradeConfigStorage getInstance() { + return INSTANCE; + } + + @Override + public void load() { + loadFromFile(getConfigFile()); + } + + public void loadFromFile(File configFile) { + JsonElement element = JsonUtils.parseJsonFile(configFile); + + AutoTradeModClient.LOGGER.info(String.valueOf(element)); + if (element != null && element.isJsonObject()) { + this.jsonObject = element.getAsJsonObject(); + + for (Config.Category category : Config.Category.values()) { + List configs = CATEGORY_TO_OPTION.get(category).stream() + .map(AutoTradeConfigOption::config).collect(Collectors.toList()); + ConfigUtils.readConfigBase(jsonObject, category.name(), configs); + } + } else save(); + } + + @Override + public void save() { + for (Config.Category category : Config.Category.values()) { + List configs = CATEGORY_TO_OPTION.get(category).stream() + .map(AutoTradeConfigOption::config).collect(Collectors.toList()); + ConfigUtils.writeConfigBase(jsonObject, category.name(), configs); + } + + File configFile = getConfigFile(); + JsonUtils.writeJsonToFile(jsonObject, configFile); + } +} diff --git a/src/main/java/monkey/unlimitedtrade/config/Config.java b/src/main/java/monkey/unlimitedtrade/config/Config.java new file mode 100644 index 0000000..cb754f6 --- /dev/null +++ b/src/main/java/monkey/unlimitedtrade/config/Config.java @@ -0,0 +1,27 @@ +package monkey.unlimitedtrade.config; + + +import fi.dy.masa.malilib.util.StringUtils; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Config { + Category category(); + + enum Category { + SETTING; + + public String getDisplayName() { + return StringUtils.translate(String.format("unlimitedtrade.config.%s.name", this.name().toLowerCase())); + } + + public String getDescription() { + return StringUtils.translate(String.format("unlimitedtrade.config.%s.comment", this.name().toLowerCase())); + } + } +} diff --git a/src/main/java/monkey/unlimitedtrade/config/Configs.java b/src/main/java/monkey/unlimitedtrade/config/Configs.java index c92259d..fb914a1 100644 --- a/src/main/java/monkey/unlimitedtrade/config/Configs.java +++ b/src/main/java/monkey/unlimitedtrade/config/Configs.java @@ -1,58 +1,83 @@ package monkey.unlimitedtrade.config; -import fi.dy.masa.malilib.config.options.ConfigHotkey; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import fi.dy.masa.malilib.config.ConfigManager; +import fi.dy.masa.malilib.event.InitializationHandler; +import fi.dy.masa.malilib.event.InputEventHandler; +import monkey.unlimitedtrade.AutoTradeModClient; +import monkey.unlimitedtrade.config.options.*; import monkey.unlimitedtrade.config.types.AfterTradeActions; -import monkey.unlimitedtrade.gui.ConfigScreen; -import net.minecraft.client.MinecraftClient; -import top.hendrixshen.magiclib.malilib.api.annotation.Config; -import top.hendrixshen.magiclib.malilib.api.annotation.Hotkey; -import top.hendrixshen.magiclib.malilib.api.annotation.Numeric; -import top.hendrixshen.magiclib.malilib.impl.ConfigManager; +import monkey.unlimitedtrade.gui.AutoTradGuiConfigsBase; +import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.List; +import java.util.Map; public class Configs { public static final int VERSION = 1; + public static final List OPTIONS = new ArrayList<>(); + public static final Map> CATEGORY_TO_OPTION = Maps.newLinkedHashMap(); /* ------------------------------ */ /* ----------- Hot Key ---------- */ /* ------------------------------ */ - @Hotkey(hotkey = "V,B") - @Config(category = Category.SETTING) - public static ConfigHotkey openConfigGui; - - @Hotkey(hotkey = "C,V") - @Config(category = Category.SETTING) - public static boolean startTrade; +// @Hotkey(hotkey = "V,B") + @Config(category = Config.Category.SETTING) + public static AutoTradeHotKeyed openConfigGui = new AutoTradeHotKeyed("openConfigGui", "V,B"); /* ------------------------------ */ /* ----------- setting ---------- */ /* ------------------------------ */ + @Config(category = Config.Category.SETTING) + public static AutoTradeBooleanHotKeyed startTrade = new AutoTradeBooleanHotKeyed("startTrade", "C,V"); + @Config(category = Config.Category.SETTING) + public static AutoTradeBooleanHotKeyed waitChunkDebug = new AutoTradeBooleanHotKeyed("waitChunkDebug", ""); + @Config(category = Config.Category.SETTING) + public static AutoTradeStringList dropBlockList = new AutoTradeStringList( + "dropBlockList", + ImmutableList.copyOf(new ArrayList<>())); + @Config(category = Config.Category.SETTING) + public static AutoTradeOptionList afterTradeActions = new AutoTradeOptionList( + "afterTradeActions", + AfterTradeActions.USE_AND_DROP); - @Config(category = Category.SETTING) - public static boolean waitChunkDebug = true; - - @Config(category = Category.SETTING) - public static ArrayList dropBlockList = new ArrayList<>(); + static { + for (Field field : Configs.class.getDeclaredFields()) { + Config annotation = field.getAnnotation(Config.class); + if (annotation != null) { + try { + Object config = field.get(null); + if (!(config instanceof AutoTradeIConfigBase)) { + AutoTradeModClient.LOGGER.warn("{} is not subclass of AutoTradeIConfigBase", config); + continue; + } - @Config(category = Category.SETTING) - public static AfterTradeActions afterTradeActions = AfterTradeActions.USE_AND_DROP; + AutoTradeConfigOption option = new AutoTradeConfigOption(annotation, (AutoTradeIConfigBase) config); + OPTIONS.add(option); + CATEGORY_TO_OPTION.computeIfAbsent(option.getCategory(), k -> Lists.newArrayList()).add(option); + } catch (IllegalAccessException e) { + //noinspection CallToPrintStackTrace + e.printStackTrace(); + } - @Numeric(minValue = 0, maxValue = 100, useSlider = true) - @Config(category = Category.SETTING) - public static int maxUseRetries = 20; + } + } + } - public static void init(ConfigManager cm) { - openConfigGui.getKeybind().setCallback(((keyAction, iKeybind) -> { - ConfigScreen screen = ConfigScreen.instance; + public static void init() { + InitializationHandler.getInstance().registerInitializationHandler(() -> { + ConfigManager.getInstance().registerConfigHandler(AutoTradeModClient.MOD_ID, AutoTradeConfigStorage.getInstance()); - MinecraftClient.getInstance().setScreen(screen); + InputEventHandler.getKeybindManager().registerKeybindProvider(new KeybindProvider()); - return true; - })); - } + openConfigGui.getKeybind().setCallback(((keyAction, iKeybind) -> { + AutoTradGuiConfigsBase.openGui(); - public static class Category { - public static final String SETTING = "setting"; + return true; + })); + }); } } diff --git a/src/main/java/monkey/unlimitedtrade/config/KeybindProvider.java b/src/main/java/monkey/unlimitedtrade/config/KeybindProvider.java new file mode 100644 index 0000000..3d6eb9e --- /dev/null +++ b/src/main/java/monkey/unlimitedtrade/config/KeybindProvider.java @@ -0,0 +1,23 @@ +package monkey.unlimitedtrade.config; + +import fi.dy.masa.malilib.hotkeys.IHotkey; +import fi.dy.masa.malilib.hotkeys.IKeybindManager; +import fi.dy.masa.malilib.hotkeys.IKeybindProvider; +import monkey.unlimitedtrade.AutoTradeModClient; + +import java.util.List; + +public class KeybindProvider implements IKeybindProvider { + private static final List ALL_CUSTOM_HOTKEYS = Configs.OPTIONS.stream().map(AutoTradeConfigOption::config) + .filter(option -> option instanceof IHotkey).map(option -> (IHotkey) option).toList(); + + @Override + public void addKeysToMap(IKeybindManager iKeybindManager) { + ALL_CUSTOM_HOTKEYS.forEach(iHotkey -> iKeybindManager.addKeybindToMap(iHotkey.getKeybind())); + } + + @Override + public void addHotkeys(IKeybindManager iKeybindManager) { + iKeybindManager.addHotkeysForCategory(AutoTradeModClient.MOD_ID, "tweakermore.hotkeys.category.main", ALL_CUSTOM_HOTKEYS); + } +} diff --git a/src/main/java/monkey/unlimitedtrade/config/options/AutoTradeBooleanHotKeyed.java b/src/main/java/monkey/unlimitedtrade/config/options/AutoTradeBooleanHotKeyed.java new file mode 100644 index 0000000..b205271 --- /dev/null +++ b/src/main/java/monkey/unlimitedtrade/config/options/AutoTradeBooleanHotKeyed.java @@ -0,0 +1,44 @@ +/* + * This file is part of the TweakerMore project, licensed under the + * GNU Lesser General Public License v3.0 + * + * Copyright (C) 2023 Fallen_Breath and contributors + * + * TweakerMore is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * TweakerMore is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with TweakerMore. If not, see . + */ + +package monkey.unlimitedtrade.config.options; + +import fi.dy.masa.malilib.config.options.ConfigBooleanHotkeyed; + +public class AutoTradeBooleanHotKeyed extends ConfigBooleanHotkeyed implements AutoTradeIConfigBase { + public AutoTradeBooleanHotKeyed(String name) { + this(name, false); + } + + public AutoTradeBooleanHotKeyed(String name, String defaultHotkey) { + this(name, false, defaultHotkey); + } + + public AutoTradeBooleanHotKeyed(String name, boolean defaultValue) { + this(name, defaultValue, ""); + } + + public AutoTradeBooleanHotKeyed(String name, boolean defaultValue, String defaultHotkey) { + super(name, defaultValue, defaultHotkey, + AUTOTRADE_NAMESPACE_PREFIX + name + COMMENT_SUFFIX, + AUTOTRADE_NAMESPACE_PREFIX + name + PRETTY_NAME_SUFFIX + ); + } +} diff --git a/src/main/java/monkey/unlimitedtrade/config/options/AutoTradeHotKeyed.java b/src/main/java/monkey/unlimitedtrade/config/options/AutoTradeHotKeyed.java new file mode 100644 index 0000000..445d860 --- /dev/null +++ b/src/main/java/monkey/unlimitedtrade/config/options/AutoTradeHotKeyed.java @@ -0,0 +1,34 @@ +/* + * This file is part of the TweakerMore project, licensed under the + * GNU Lesser General Public License v3.0 + * + * Copyright (C) 2023 Fallen_Breath and contributors + * + * TweakerMore is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * TweakerMore is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with TweakerMore. If not, see . + */ + +package monkey.unlimitedtrade.config.options; + +import fi.dy.masa.malilib.config.options.ConfigHotkey; +import fi.dy.masa.malilib.hotkeys.KeybindSettings; + +public class AutoTradeHotKeyed extends ConfigHotkey implements AutoTradeIConfigBase { + public AutoTradeHotKeyed(String name, String defaultHotkey) { + super(name, defaultHotkey, AUTOTRADE_NAMESPACE_PREFIX + name + COMMENT_SUFFIX); + } + + public AutoTradeHotKeyed(String name, String defaultStorageString, KeybindSettings settings) { + super(name, defaultStorageString, settings, AUTOTRADE_NAMESPACE_PREFIX + name + COMMENT_SUFFIX); + } +} diff --git a/src/main/java/monkey/unlimitedtrade/config/options/AutoTradeIConfigBase.java b/src/main/java/monkey/unlimitedtrade/config/options/AutoTradeIConfigBase.java new file mode 100644 index 0000000..b0f8745 --- /dev/null +++ b/src/main/java/monkey/unlimitedtrade/config/options/AutoTradeIConfigBase.java @@ -0,0 +1,29 @@ +package monkey.unlimitedtrade.config.options; + +import fi.dy.masa.malilib.config.IConfigBase; +import fi.dy.masa.malilib.util.StringUtils; +import monkey.unlimitedtrade.AutoTradeModClient; + +public interface AutoTradeIConfigBase extends IConfigBase { + String AUTOTRADE_NAMESPACE_PREFIX = AutoTradeModClient.MOD_ID + ".config."; + String COMMENT_SUFFIX = ".comment"; + String PRETTY_NAME_SUFFIX = ".pretty_name"; + + @Override + default String getComment() { + return StringUtils.getTranslatedOrFallback(AUTOTRADE_NAMESPACE_PREFIX + this.getName() + COMMENT_SUFFIX, + this.getName()); + } + + @Override + default String getPrettyName() { + return StringUtils.getTranslatedOrFallback(AUTOTRADE_NAMESPACE_PREFIX + this.getName() + PRETTY_NAME_SUFFIX, + this.getConfigGuiDisplayName()); + } + + @Override + default String getConfigGuiDisplayName() { + return StringUtils.getTranslatedOrFallback(AUTOTRADE_NAMESPACE_PREFIX + this.getName() + ".name", + this.getName()); + } +} diff --git a/src/main/java/monkey/unlimitedtrade/config/options/AutoTradeOptionList.java b/src/main/java/monkey/unlimitedtrade/config/options/AutoTradeOptionList.java new file mode 100644 index 0000000..00cf262 --- /dev/null +++ b/src/main/java/monkey/unlimitedtrade/config/options/AutoTradeOptionList.java @@ -0,0 +1,13 @@ +package monkey.unlimitedtrade.config.options; + +import fi.dy.masa.malilib.config.IConfigOptionListEntry; +import fi.dy.masa.malilib.config.options.ConfigOptionList; + +public class AutoTradeOptionList extends ConfigOptionList implements AutoTradeIConfigBase { + + public AutoTradeOptionList(String name, IConfigOptionListEntry defaultValue) { + super(name, defaultValue, + AUTOTRADE_NAMESPACE_PREFIX + name + COMMENT_SUFFIX, + AUTOTRADE_NAMESPACE_PREFIX + name + PRETTY_NAME_SUFFIX); + } +} diff --git a/src/main/java/monkey/unlimitedtrade/config/options/AutoTradeStringList.java b/src/main/java/monkey/unlimitedtrade/config/options/AutoTradeStringList.java new file mode 100644 index 0000000..61d85f5 --- /dev/null +++ b/src/main/java/monkey/unlimitedtrade/config/options/AutoTradeStringList.java @@ -0,0 +1,10 @@ +package monkey.unlimitedtrade.config.options; + +import com.google.common.collect.ImmutableList; +import fi.dy.masa.malilib.config.options.ConfigStringList; + +public class AutoTradeStringList extends ConfigStringList implements AutoTradeIConfigBase { + public AutoTradeStringList(String name, ImmutableList defaultValue) { + super(name, defaultValue, AUTOTRADE_NAMESPACE_PREFIX + name + COMMENT_SUFFIX); + } +} diff --git a/src/main/java/monkey/unlimitedtrade/gui/AutoTradGuiConfigsBase.java b/src/main/java/monkey/unlimitedtrade/gui/AutoTradGuiConfigsBase.java new file mode 100644 index 0000000..898e491 --- /dev/null +++ b/src/main/java/monkey/unlimitedtrade/gui/AutoTradGuiConfigsBase.java @@ -0,0 +1,43 @@ +package monkey.unlimitedtrade.gui; + +import com.google.common.collect.Lists; +import fi.dy.masa.malilib.config.IConfigBase; +import fi.dy.masa.malilib.gui.GuiBase; +import fi.dy.masa.malilib.gui.GuiConfigsBase; +import monkey.unlimitedtrade.AutoTradeModClient; +import monkey.unlimitedtrade.config.AutoTradeConfigOption; +import monkey.unlimitedtrade.config.Config; +import monkey.unlimitedtrade.config.Configs; + +import java.util.List; + +public class AutoTradGuiConfigsBase extends GuiConfigsBase { + private final String tab; + + public AutoTradGuiConfigsBase() { + this(Config.Category.SETTING.name()); + } + + public AutoTradGuiConfigsBase(String defaultTab) { + super(10, 50, AutoTradeModClient.MOD_ID, null, "unlimitedtrade.gui.title", AutoTradeModClient.VERSION); + + tab = defaultTab; + } + + public static void openGui() { + GuiBase.openGui(new AutoTradGuiConfigsBase()); + AutoTradeModClient.LOGGER.info("open ui test"); + } + + @Override + public List getConfigs() { + + List configs = Lists.newArrayList(); + for (AutoTradeConfigOption option : Configs.CATEGORY_TO_OPTION.get(Config.Category.valueOf(tab))) { + configs.add(option.config()); + } + + configs.sort((a, b) -> a.getName().compareToIgnoreCase(b.getName())); + return ConfigOptionWrapper.createFor(configs); + } +} diff --git a/src/main/java/monkey/unlimitedtrade/gui/ConfigScreen.java b/src/main/java/monkey/unlimitedtrade/gui/ConfigScreen.java deleted file mode 100644 index 686ebd9..0000000 --- a/src/main/java/monkey/unlimitedtrade/gui/ConfigScreen.java +++ /dev/null @@ -1,20 +0,0 @@ -package monkey.unlimitedtrade.gui; - - -import fi.dy.masa.malilib.util.StringUtils; -import monkey.unlimitedtrade.AutoTradModClient; -import monkey.unlimitedtrade.config.Configs; -import top.hendrixshen.magiclib.malilib.impl.ConfigManager; -import top.hendrixshen.magiclib.malilib.impl.gui.ConfigGui; - -public class ConfigScreen extends ConfigGui { - public static final ConfigScreen instance = new ConfigScreen( - AutoTradModClient.MOD_ID, - Configs.Category.SETTING, - ConfigManager.get(AutoTradModClient.MOD_ID) - ); - - private ConfigScreen(String identifier, String defaultTab, ConfigManager configManager) { - super(identifier, defaultTab, configManager, () -> StringUtils.translate("unlimitedtrade.gui.title", AutoTradModClient.VERSION)); - } -} diff --git a/src/main/java/monkey/unlimitedtrade/gui/modmenu/ModMenuApiImpl.java b/src/main/java/monkey/unlimitedtrade/gui/modmenu/ModMenuApiImpl.java deleted file mode 100644 index efa1c15..0000000 --- a/src/main/java/monkey/unlimitedtrade/gui/modmenu/ModMenuApiImpl.java +++ /dev/null @@ -1,23 +0,0 @@ -package monkey.unlimitedtrade.gui.modmenu; - -import monkey.unlimitedtrade.AutoTradModClient; -import monkey.unlimitedtrade.gui.ConfigScreen; -import top.hendrixshen.magiclib.compat.modmenu.ModMenuCompatApi; - -public class ModMenuApiImpl implements ModMenuCompatApi { - @Override - public ConfigScreenFactoryCompat getConfigScreenFactoryCompat() { - return screen -> { - ConfigScreen configScreen = ConfigScreen.instance; - - configScreen.setParent(screen); - - return configScreen; - }; - } - - @Override - public String getModIdCompat() { - return AutoTradModClient.MOD_ID; - } -} diff --git a/src/main/java/monkey/unlimitedtrade/gui/modmenu/ModMenuImpl.java b/src/main/java/monkey/unlimitedtrade/gui/modmenu/ModMenuImpl.java new file mode 100644 index 0000000..90bb033 --- /dev/null +++ b/src/main/java/monkey/unlimitedtrade/gui/modmenu/ModMenuImpl.java @@ -0,0 +1,16 @@ +package monkey.unlimitedtrade.gui.modmenu; + +import com.terraformersmc.modmenu.api.ConfigScreenFactory; +import com.terraformersmc.modmenu.api.ModMenuApi; +import monkey.unlimitedtrade.gui.AutoTradGuiConfigsBase; + +public class ModMenuImpl implements ModMenuApi { + @Override + public ConfigScreenFactory getModConfigScreenFactory() { + return (screen) -> { + AutoTradGuiConfigsBase gui = new AutoTradGuiConfigsBase(); + gui.setParent(screen); + return gui; + }; + } +} diff --git a/src/main/java/monkey/unlimitedtrade/mixin/AutoTradeMixin.java b/src/main/java/monkey/unlimitedtrade/mixin/TradeMixin.java similarity index 50% rename from src/main/java/monkey/unlimitedtrade/mixin/AutoTradeMixin.java rename to src/main/java/monkey/unlimitedtrade/mixin/TradeMixin.java index d2c1f61..8114557 100644 --- a/src/main/java/monkey/unlimitedtrade/mixin/AutoTradeMixin.java +++ b/src/main/java/monkey/unlimitedtrade/mixin/TradeMixin.java @@ -1,6 +1,6 @@ package monkey.unlimitedtrade.mixin; -import monkey.unlimitedtrade.AutoTradModClient; +import monkey.unlimitedtrade.AutoTradeModClient; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.MerchantScreen; @@ -9,15 +9,15 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import static monkey.unlimitedtrade.AutoTradModClient.CHUNK_DEBUG; +import static monkey.unlimitedtrade.AutoTradeModClient.CHUNK_DEBUG_API; @Mixin(MinecraftClient.class) -public class AutoTradeMixin { - @Inject(method = "setScreen(Lnet/minecraft/client/gui/screen/Screen;)V", at = @At("HEAD")) - private void run(Screen screen, CallbackInfo ci) { - if (!(screen instanceof MerchantScreen)) { - AutoTradModClient.tradeEntity = null; - CHUNK_DEBUG.requestChunkData(); +public class TradeMixin { + @Inject(method = "setScreen", at = @At("HEAD")) + public void setScreen(Screen screen, CallbackInfo ci) { + if (!(screen instanceof MerchantScreen) && CHUNK_DEBUG_API != null) { + AutoTradeModClient.tradeEntity = null; + CHUNK_DEBUG_API.requestChunkData(); } } } diff --git a/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/BaseChunkDebug.java b/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/BaseChunkDebug.java new file mode 100644 index 0000000..9228e33 --- /dev/null +++ b/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/BaseChunkDebug.java @@ -0,0 +1,44 @@ +package monkey.unlimitedtrade.utils.chunkdebug; + +import net.minecraft.registry.RegistryKey; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; + +public abstract class BaseChunkDebug { + public static final Identifier DUMMY_WORLD = new Identifier("minecraft:dummy"); + + @Nullable + private Identifier currentWorld; + + public void requestChunkData() { + this.requestChunkData(DUMMY_WORLD); + } + + public void requestChunkData(String world) { + this.requestChunkData(new Identifier(world)); + } + + public void requestChunkData(Identifier world) { + this.setCurrentWorld(world.equals(DUMMY_WORLD) ? null : world); + } + + public abstract void clearChunkData(); + + public abstract ChunkData getChunkData(ChunkPos chunkPos); + + public @Nullable Identifier getCurrentWorld() { + return this.currentWorld; + } + + public void setCurrentWorld(Identifier world) { + this.currentWorld = world; + this.clearChunkData(); + } + + public void setCurrentWorld(RegistryKey world) { + this.currentWorld = world != null ? world.getRegistry() : null; + this.clearChunkData(); + } +} diff --git a/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/ChunkData.java b/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/ChunkData.java index a84c862..485a0c6 100644 --- a/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/ChunkData.java +++ b/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/ChunkData.java @@ -15,3 +15,9 @@ public static ChunkData deserialize(Identifier world, long chunkPosition, byte l return new ChunkData(new ChunkPos(chunkPosition), ChunkLevelType.values()[levelType], statusType, ticketType, world); } } + + +//public ChunkPos(long pos) { +// this.x = (int)pos; +// this.z = (int)(pos >> 32); +//} \ No newline at end of file diff --git a/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/ChunkdebugApi.java b/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/ChunkDebugAPI.java similarity index 74% rename from src/main/java/monkey/unlimitedtrade/utils/chunkdebug/ChunkdebugApi.java rename to src/main/java/monkey/unlimitedtrade/utils/chunkdebug/ChunkDebugAPI.java index c8ce954..b5409e2 100644 --- a/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/ChunkdebugApi.java +++ b/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/ChunkDebugAPI.java @@ -1,12 +1,13 @@ package monkey.unlimitedtrade.utils.chunkdebug; import io.netty.buffer.Unpooled; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.network.PacketByteBuf; -import net.minecraft.network.packet.c2s.play.CustomPayloadC2SPacket; +import net.minecraft.network.packet.c2s.common.CustomPayloadC2SPacket; import net.minecraft.registry.RegistryKey; import net.minecraft.registry.RegistryKeys; import net.minecraft.util.Identifier; @@ -17,9 +18,9 @@ import java.util.HashMap; import java.util.Map; -import static monkey.unlimitedtrade.AutoTradModClient.LOGGER; +import static monkey.unlimitedtrade.AutoTradeModClient.LOGGER; -public class ChunkdebugApi { +public class ChunkDebugAPI extends BaseChunkDebug { public static final Identifier PACKET_ID = new Identifier("essentialclient", "chunkdebug"); public static final int HELLO = 0, DATA = 16, @@ -29,14 +30,16 @@ public class ChunkdebugApi { Update.class, callbacks -> (world, chunkData) -> Arrays.stream(callbacks).forEach(callback -> callback.onUpdate(world, chunkData)) ); - public final Map worldChunks = new HashMap<>(); + private final Map worldChunks = new HashMap<>(); + @Nullable public ClientPlayNetworkHandler networkHandler; @Nullable private Identifier currentWorld; - public ChunkdebugApi() { - ClientPlayNetworking.registerGlobalReceiver(PACKET_ID, ((client, handler, buf, responseSender) -> this.handlePacket(buf, handler))); + public ChunkDebugAPI() { + ClientPlayNetworking.registerGlobalReceiver(PACKET_ID, (client, handler, buf, responseSender) -> this.handlePacket(buf, handler)); + ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> setCurrentWorld(DUMMY_WORLD)); } private void handlePacket(PacketByteBuf buf, ClientPlayNetworkHandler handler) { @@ -57,9 +60,10 @@ private void onHello(PacketByteBuf buf, ClientPlayNetworkHandler handler) { this.networkHandler = handler; LOGGER.info("Connected to ChunkDebug server"); - handler.sendPacket(new CustomPayloadC2SPacket( - PACKET_ID, - new PacketByteBuf(Unpooled.buffer()).writeVarInt(HELLO).writeString("v0.1.0").writeVarInt(VERSION) + handler.sendPacket(new CustomPayloadC2SPacket(new PacketByteBuf(Unpooled.buffer()) + .writeVarInt(HELLO) + .writeString("v0.1.0") + .writeVarInt(VERSION) )); } @@ -89,34 +93,29 @@ private void onData(PacketByteBuf buf) { this.UPDATE_EVENT.invoker().onUpdate(worldIdentify, worldChunks); } - public void requestChunkData() { - this.requestChunkData("minecraft:dummy"); + @Override + public ChunkData getChunkData(ChunkPos chunkPos) { + return this.worldChunks.get(chunkPos); } - public void requestChunkData(String world) { - this.requestChunkData(new Identifier(world)); + @Override + public void clearChunkData() { + this.worldChunks.clear(); } + @Override public void requestChunkData(Identifier world) { if (this.networkHandler == null) { + LOGGER.error("run requestChunkData but networkHandler is null"); return; } - this.setCurrentWorld(world.equals(new Identifier("minecraft:dummy")) ? null : world); - - this.networkHandler.sendPacket(new CustomPayloadC2SPacket( - PACKET_ID, - new PacketByteBuf(Unpooled.buffer()).writeVarInt(DATA).writeIdentifier(world) + this.networkHandler.sendPacket(new CustomPayloadC2SPacket(new PacketByteBuf(Unpooled.buffer()) + .writeVarInt(DATA) + .writeIdentifier(world) )); - } - public @Nullable Identifier getCurrentWorld() { - return this.currentWorld; - } - - private void setCurrentWorld(Identifier world) { - this.currentWorld = world; - this.worldChunks.clear(); + super.requestChunkData(); } @FunctionalInterface diff --git a/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/essential/EssentialChunkDebugAPI.java b/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/essential/EssentialChunkDebugAPI.java new file mode 100644 index 0000000..d4c2c4c --- /dev/null +++ b/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/essential/EssentialChunkDebugAPI.java @@ -0,0 +1,139 @@ +package monkey.unlimitedtrade.utils.chunkdebug.essential; + +import monkey.unlimitedtrade.AutoTradeModClient; +import monkey.unlimitedtrade.utils.chunkdebug.BaseChunkDebug; +import monkey.unlimitedtrade.utils.chunkdebug.ChunkData; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.server.world.ChunkLevelType; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.ChunkPos; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +public class EssentialChunkDebugAPI extends BaseChunkDebug { + @Nullable Class essentialClientClass; + @Nullable Class chunkHandlerClass; + + @Nullable Method clearAllChunksMethod; + @Nullable Method getChunksMethod; + + @Nullable Object chunkClientNetworkHandler; + @Nullable Class chunkClientNetworkHandlerCls; + @Nullable Method removeChunkDataMethod; + @Nullable Method requestChunkDataMethod; + + public EssentialChunkDebugAPI() { + try { + essentialClientClass = Class.forName("me.senseiwells.essentialclient.EssentialClient"); + //noinspection unchecked + chunkHandlerClass = (Class) Class.forName("me.senseiwells.essentialclient.feature.chunkdebug.ChunkHandler"); + + clearAllChunksMethod = chunkHandlerClass.getMethod("clearAllChunks"); + getChunksMethod = chunkHandlerClass.getMethod("getChunks", RegistryKey.class); + + Field field = essentialClientClass.getDeclaredField("CHUNK_NET_HANDLER"); + chunkClientNetworkHandler = field.get(null); + //noinspection unchecked + chunkClientNetworkHandlerCls = (Class) chunkClientNetworkHandler.getClass(); + removeChunkDataMethod = chunkClientNetworkHandlerCls.getMethod("removeChunkData"); + requestChunkDataMethod = chunkClientNetworkHandlerCls.getMethod("requestChunkData", RegistryKey.class); + } catch (ReflectiveOperationException e) { + AutoTradeModClient.LOGGER.warn("essentialclient chunkdebug class not found"); + } + } + + public void clearAllChunks() { + if (clearAllChunksMethod == null) return; + + try { + clearAllChunksMethod.invoke(chunkHandlerClass); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + public List objectToChunkData(Identifier world, Object[] chunkData) { + List result = new ArrayList<>(); + + for (Object data : chunkData) { + try { + //noinspection unchecked + Class chunkDataCls = (Class) data.getClass(); + + int x = (int) chunkDataCls.getMethod("getPosX").invoke(data); + int y = (int) chunkDataCls.getMethod("getPosZ").invoke(data); + + result.add(new ChunkData( + new ChunkPos(x, y), + ChunkLevelType.INACCESSIBLE, + (byte) 0, + (byte) 0, + world)); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + return result; + } + + public List getChunks() { + if (getChunksMethod == null) return null; + + try { + return objectToChunkData(getCurrentWorld(), (Object[]) getChunksMethod.invoke(chunkHandlerClass, RegistryKey.of(RegistryKeys.WORLD, getCurrentWorld()))); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + @Override + public void clearChunkData() { + this.clearAllChunks(); + } + + @Override + public ChunkData getChunkData(ChunkPos chunkPos) { + List chunkData = getChunks(); + + for (ChunkData chunk : chunkData) { + if (chunkPos.equals(chunk.chunkPos())) { + return chunk; + } + } + + return null; + } + + @Override + public void requestChunkData(Identifier world) { + if (this.chunkClientNetworkHandler == null) { + AutoTradeModClient.LOGGER.error("run EssentialChunkDebug but chunkClientNetworkHandlerClass is null"); + return; + } + + // if world equals DUMMY_WORLD stop + try { + if (world.equals(DUMMY_WORLD)) { + if (this.removeChunkDataMethod == null) { + AutoTradeModClient.LOGGER.error("run EssentialChunkDebug but removeChunkDataMethod is null"); + } else { + this.removeChunkDataMethod.invoke(chunkClientNetworkHandler); + } + } else if (this.requestChunkDataMethod != null) { + this.requestChunkDataMethod.invoke(chunkClientNetworkHandler, RegistryKey.of(RegistryKeys.WORLD, world)); + } else { + AutoTradeModClient.LOGGER.error("run EssentialChunkDebug but requestChunkDataMethod is null"); + } + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + + super.requestChunkData(world); + } +} diff --git a/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/essential/IChunkClientNetworkHandler.java b/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/essential/IChunkClientNetworkHandler.java new file mode 100644 index 0000000..379e8f4 --- /dev/null +++ b/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/essential/IChunkClientNetworkHandler.java @@ -0,0 +1,12 @@ +package monkey.unlimitedtrade.utils.chunkdebug.essential; + +import net.minecraft.registry.RegistryKey; +import net.minecraft.world.World; + +public interface IChunkClientNetworkHandler { + int getVersion(); + + void removeChunkData(); + + void requestChunkData(RegistryKey world); +} diff --git a/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/essential/IChunkData.java b/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/essential/IChunkData.java new file mode 100644 index 0000000..87d61f4 --- /dev/null +++ b/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/essential/IChunkData.java @@ -0,0 +1,7 @@ +package monkey.unlimitedtrade.utils.chunkdebug.essential; + +public interface IChunkData { + int getPosX(); + + int getPosZ(); +} diff --git a/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/essential/IChunkHandler.java b/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/essential/IChunkHandler.java new file mode 100644 index 0000000..fa28f81 --- /dev/null +++ b/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/essential/IChunkHandler.java @@ -0,0 +1,11 @@ +package monkey.unlimitedtrade.utils.chunkdebug.essential; + +import monkey.unlimitedtrade.utils.chunkdebug.ChunkData; +import net.minecraft.registry.RegistryKey; +import net.minecraft.world.World; + +public interface IChunkHandler { + ChunkData[] getChunks(RegistryKey world); + + void clearAllChunks(); +} diff --git a/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/essential/IChunkType.java b/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/essential/IChunkType.java new file mode 100644 index 0000000..085207b --- /dev/null +++ b/src/main/java/monkey/unlimitedtrade/utils/chunkdebug/essential/IChunkType.java @@ -0,0 +1,7 @@ +package monkey.unlimitedtrade.utils.chunkdebug.essential; + +import net.minecraft.text.Text; + +public interface IChunkType { + Text getName(); +} diff --git a/src/main/resources/assets/unlimitedtrade/lang/en_us.json b/src/main/resources/assets/unlimitedtrade/lang/en_us.json index c116354..532ac64 100644 --- a/src/main/resources/assets/unlimitedtrade/lang/en_us.json +++ b/src/main/resources/assets/unlimitedtrade/lang/en_us.json @@ -1,19 +1,19 @@ { "unlimitedtrade.gui.title": "Unlimited Trade Mod - %s", "unlimitedtrade.gui.button.tab.setting": "setting", - "unlimitedtrade.config.setting.openConfigGui.name": "open Config Gui", - "unlimitedtrade.config.setting.openConfigGui.comment": "Set the shortcut key to open the setting interface", - "unlimitedtrade.config.setting.startTrade.pretty_name": "startTrade", - "unlimitedtrade.config.setting.startTrade.name": "startTrade", - "unlimitedtrade.config.setting.startTrade.comment": "Open unlimited transactions", - "unlimitedtrade.config.setting.afterTradeActions.name": "afterTradeActions", - "unlimitedtrade.config.setting.afterTradeActions.comment": "Set up post-trade actions", - "unlimitedtrade.config.setting.waitChunkDebug.name": "wait Chunk Debug", - "unlimitedtrade.config.setting.waitChunkDebug.comment": "If you need a more stable transaction, please install the ChunkDebug module on the server\n to prevent the transaction from being loaded and causing the transaction to be invalid", - "unlimitedtrade.config.setting.dropBlockList.name": "drop Block List", - "unlimitedtrade.config.setting.dropBlockList.comment": "Limit the type of items that are automatically thrown", - "unlimitedtrade.config.setting.maxUseRetries.name": "Maximum number of post-transaction retries", - "unlimitedtrade.config.setting.maxUseRetries.comment": "Set max post-trade action max attempts", + "unlimitedtrade.config.openConfigGui.name": "open Config Gui", + "unlimitedtrade.config.openConfigGui.comment": "Set the shortcut key to open the setting interface", + "unlimitedtrade.config.startTrade.pretty_name": "startTrade", + "unlimitedtrade.config.startTrade.name": "startTrade", + "unlimitedtrade.config.startTrade.comment": "Open unlimited transactions", + "unlimitedtrade.config.afterTradeActions.name": "afterTradeActions", + "unlimitedtrade.config.afterTradeActions.comment": "Set up post-trade actions", + "unlimitedtrade.config.waitChunkDebug.name": "wait Chunk Debug", + "unlimitedtrade.config.waitChunkDebug.comment": "If you need a more stable transaction, please install the ChunkDebug module on the server\n to prevent the transaction from being loaded and causing the transaction to be invalid", + "unlimitedtrade.config.dropBlockList.name": "drop Block List", + "unlimitedtrade.config.dropBlockList.comment": "Limit the type of items that are automatically thrown", + "unlimitedtrade.config.maxUseRetries.name": "Maximum number of post-transaction retries", + "unlimitedtrade.config.maxUseRetries.comment": "Set max post-trade action max attempts", "unlimitedtrade.label.afterTradeActions.off": "§4off§r", "unlimitedtrade.label.afterTradeActions.use": "Interact/use blocks", "unlimitedtrade.label.afterTradeActions.use_and_drop": "Interact/use blocks and drop items" diff --git a/src/main/resources/assets/unlimitedtrade/lang/zh_cn.json b/src/main/resources/assets/unlimitedtrade/lang/zh_cn.json index 75c7fe6..ad32736 100644 --- a/src/main/resources/assets/unlimitedtrade/lang/zh_cn.json +++ b/src/main/resources/assets/unlimitedtrade/lang/zh_cn.json @@ -1,19 +1,19 @@ { "unlimitedtrade.gui.title": "Unlimited Trade 无限交易模组 - %s", "unlimitedtrade.gui.button.tab.setting": "设定", - "unlimitedtrade.config.setting.openConfigGui.name": "openConfigGui | 开启设定介面", - "unlimitedtrade.config.setting.openConfigGui.comment": "设定开启设定介面快捷键", - "unlimitedtrade.config.setting.startTrade.pretty_name": "startTrade | 无限交易", - "unlimitedtrade.config.setting.startTrade.name": "startTrade | 无限交易", - "unlimitedtrade.config.setting.startTrade.comment": "开启无限交易", - "unlimitedtrade.config.setting.afterTradeActions.name": "afterTradeActions | 交易后动作", - "unlimitedtrade.config.setting.afterTradeActions.comment": "设定交易后动作", - "unlimitedtrade.config.setting.waitChunkDebug.name": "waitChunkDebug | 等待 Chunk Debug", - "unlimitedtrade.config.setting.waitChunkDebug.comment": "若须更稳定的交易,请于伺服器安装 ChunkDebug 模组\n用于防止交易所加载而造成交易无效", - "unlimitedtrade.config.setting.dropBlockList.name": "dropBlockList | 自动抛出黑名单", - "unlimitedtrade.config.setting.dropBlockList.comment": "限制自动抛出的物品类型", - "unlimitedtrade.config.setting.maxUseRetries.name": "maxUseRetries | 最大交易后动作重试次数", - "unlimitedtrade.config.setting.maxUseRetries.comment": "设定最大交易后动作最大尝试次数", + "unlimitedtrade.config.openConfigGui.name": "openConfigGui | 开启设定介面", + "unlimitedtrade.config.openConfigGui.comment": "设定开启设定介面快捷键", + "unlimitedtrade.config.startTrade.pretty_name": "startTrade | 无限交易", + "unlimitedtrade.config.startTrade.name": "startTrade | 无限交易", + "unlimitedtrade.config.startTrade.comment": "开启无限交易", + "unlimitedtrade.config.afterTradeActions.name": "afterTradeActions | 交易后动作", + "unlimitedtrade.config.afterTradeActions.comment": "设定交易后动作", + "unlimitedtrade.config.waitChunkDebug.name": "waitChunkDebug | 等待 Chunk Debug", + "unlimitedtrade.config.waitChunkDebug.comment": "若须更稳定的交易,请于伺服器安装 ChunkDebug 模组\n用于防止交易所加载而造成交易无效", + "unlimitedtrade.config.dropBlockList.name": "dropBlockList | 自动抛出黑名单", + "unlimitedtrade.config.dropBlockList.comment": "限制自动抛出的物品类型", + "unlimitedtrade.config.maxUseRetries.name": "maxUseRetries | 最大交易后动作重试次数", + "unlimitedtrade.config.maxUseRetries.comment": "设定最大交易后动作最大尝试次数", "unlimitedtrade.label.afterTradeActions.off": "§4关闭§r", "unlimitedtrade.label.afterTradeActions.use": "对方块交互/使用", "unlimitedtrade.label.afterTradeActions.use_and_drop": "对方块交互/使用 并抛出购买物" diff --git a/src/main/resources/assets/unlimitedtrade/lang/zh_tw.json b/src/main/resources/assets/unlimitedtrade/lang/zh_tw.json index 34af97c..1a9c6fc 100644 --- a/src/main/resources/assets/unlimitedtrade/lang/zh_tw.json +++ b/src/main/resources/assets/unlimitedtrade/lang/zh_tw.json @@ -1,19 +1,19 @@ { "unlimitedtrade.gui.title": "Unlimited Trade 無限交易模組 - %s", "unlimitedtrade.gui.button.tab.setting": "設定", - "unlimitedtrade.config.setting.openConfigGui.name": "openConfigGui | 開啟設定介面", - "unlimitedtrade.config.setting.openConfigGui.comment": "設定開啟設定介面快捷鍵", - "unlimitedtrade.config.setting.startTrade.pretty_name": "startTrade | 無限交易", - "unlimitedtrade.config.setting.startTrade.name": "startTrade | 無限交易", - "unlimitedtrade.config.setting.startTrade.comment": "開啟無限交易", - "unlimitedtrade.config.setting.afterTradeActions.name": "afterTradeActions | 交易後動作", - "unlimitedtrade.config.setting.afterTradeActions.comment": "設定交易後動作", - "unlimitedtrade.config.setting.waitChunkDebug.name": "waitChunkDebug | 等待 Chunk Debug", - "unlimitedtrade.config.setting.waitChunkDebug.comment": "若須更穩定的交易,請於伺服器安裝 ChunkDebug 模組\n用於防止交易所加載而造成交易無效", - "unlimitedtrade.config.setting.dropBlockList.name": "dropBlockList | 自動拋出黑名單", - "unlimitedtrade.config.setting.dropBlockList.comment": "限制自動拋出的物品類型", - "unlimitedtrade.config.setting.maxUseRetries.name": "maxUseRetries | 最大交易後動作重試次數", - "unlimitedtrade.config.setting.maxUseRetries.comment": "設定最大交易後動作最大嘗試次數", + "unlimitedtrade.config.openConfigGui.name": "openConfigGui | 開啟設定介面", + "unlimitedtrade.config.openConfigGui.comment": "設定開啟設定介面快捷鍵", + "unlimitedtrade.config.startTrade.pretty_name": "startTrade | 無限交易", + "unlimitedtrade.config.startTrade.name": "startTrade | 無限交易", + "unlimitedtrade.config.startTrade.comment": "開啟無限交易", + "unlimitedtrade.config.afterTradeActions.name": "afterTradeActions | 交易後動作", + "unlimitedtrade.config.afterTradeActions.comment": "設定交易後動作", + "unlimitedtrade.config.waitChunkDebug.name": "waitChunkDebug | 等待 Chunk Debug", + "unlimitedtrade.config.waitChunkDebug.comment": "若須更穩定的交易,請於伺服器安裝 ChunkDebug 模組\n用於防止交易所加載而造成交易無效", + "unlimitedtrade.config.dropBlockList.name": "dropBlockList | 自動拋出黑名單", + "unlimitedtrade.config.dropBlockList.comment": "限制自動拋出的物品類型", + "unlimitedtrade.config.maxUseRetries.name": "maxUseRetries | 最大交易後動作重試次數", + "unlimitedtrade.config.maxUseRetries.comment": "設定最大交易後動作最大嘗試次數", "unlimitedtrade.label.afterTradeActions.off": "§4關閉§r", "unlimitedtrade.label.afterTradeActions.use": "對方塊交互/使用", "unlimitedtrade.label.afterTradeActions.use_and_drop": "對方塊交互/使用 並拋出購買物" diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 891dd78..ce3a4ec 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -16,23 +16,20 @@ "environment": "client", "entrypoints": { "client": [ - "monkey.unlimitedtrade.AutoTradModClient" + "monkey.unlimitedtrade.AutoTradeModClient" ], "modmenu": [ - "monkey.unlimitedtrade.gui.modmenu.ModMenuApiImpl" + "monkey.unlimitedtrade.gui.modmenu.ModMenuImpl" ] }, "mixins": [ "unlimitedtrademod.mixins.json" ], "depends": { - "fabricloader": ">=0.12.0", + "fabricloader": ">=0.15.1", "minecraft": "${minecraft_dependency}", - "malilib": "*", - "itemscroller": "*", - "fabric-api": "*", - "magiclib": ">=0.7.0", - "java": ">=17" + "malilib": ">=0.10", + "itemscroller": "*" }, "suggests": { "another-mod": "*" diff --git a/src/main/resources/unlimitedtrademod.mixins.json b/src/main/resources/unlimitedtrademod.mixins.json index a28c439..88e4011 100644 --- a/src/main/resources/unlimitedtrademod.mixins.json +++ b/src/main/resources/unlimitedtrademod.mixins.json @@ -1,11 +1,11 @@ { "required": true, "package": "monkey.unlimitedtrade.mixin", - "compatibilityLevel": "JAVA_17", - "mixins": [ - "AutoTradeMixin" - ], + "compatibilityLevel": "{{COMPATIBILITY_LEVEL}}", "injectors": { "defaultRequire": 1 - } + }, + "client": [ + "TradeMixin" + ] } diff --git a/versions/1.17.1/gradle.properties b/versions/1.17.1/gradle.properties new file mode 100644 index 0000000..ee74bf6 --- /dev/null +++ b/versions/1.17.1/gradle.properties @@ -0,0 +1,17 @@ +# Fabric Properties +# check these on https://fallen-breath.github.io/fabric-versions/?&version=1.17.1 +minecraft_version=1.17.1 +yarn_mappings=1.17.1+build.65 +# Fabric Mod Metadata +minecraft_dependency=1.17.x +# Build Information +# The target mc versions for the mod during mod publishing, separated with \n +game_versions=1.17.1 +# Dependencies +fabric_api_version=0.46.1+1.17 +## https://www.curseforge.com/minecraft/mc-mods/malilib +malilib_file_id=3498871 +## https://www.curseforge.com/minecraft/mc-mods/item-scroller +item_scroller_file_id=3542814 +## https://mvnrepository.com/artifact/top.hendrixshen.magiclib +magiclib_version=0.7.364 diff --git a/versions/1.18.2/gradle.properties b/versions/1.18.2/gradle.properties new file mode 100644 index 0000000..9dc45de --- /dev/null +++ b/versions/1.18.2/gradle.properties @@ -0,0 +1,17 @@ +# Fabric Properties +# check these on https://fallen-breath.github.io/fabric-versions/?&version=1.18.2 +minecraft_version=1.18.2 +yarn_mappings=1.18.2+build.4 +# Fabric Mod Metadata +minecraft_dependency=1.18.x +# Build Information +# The target mc versions for the mod during mod publishing, separated with \n +game_versions=1.18.2 +# Dependencies +fabric_api_version=0.76.0+1.18.2 +## https://www.curseforge.com/minecraft/mc-mods/malilib +malilib_file_id=3692220 +## https://www.curseforge.com/minecraft/mc-mods/item-scroller +item_scroller_file_id=3879911 +## https://mvnrepository.com/artifact/top.hendrixshen.magiclib +magiclib_version=0.7.364 diff --git a/versions/1.19.4/gradle.properties b/versions/1.19.4/gradle.properties new file mode 100644 index 0000000..7efb443 --- /dev/null +++ b/versions/1.19.4/gradle.properties @@ -0,0 +1,17 @@ +# Fabric Properties +# check these on https://fallen-breath.github.io/fabric-versions/?&version=1.19.4 +minecraft_version=1.19.4 +yarn_mappings=1.19.4+build.2 +# Fabric Mod Metadata +minecraft_dependency=1.19.x +# Build Information +# The target mc versions for the mod during mod publishing, separated with \n +game_versions=1.19.4 +# Dependencies +fabric_api_version=0.87.2+1.19.4 +## https://www.curseforge.com/minecraft/mc-mods/malilib +malilib_file_id=4519977 +## https://www.curseforge.com/minecraft/mc-mods/item-scroller +item_scroller_file_id=4444342 +## https://mvnrepository.com/artifact/top.hendrixshen.magiclib +magiclib_version=0.7.364 diff --git a/versions/1.20.4/gradle.properties b/versions/1.20.4/gradle.properties new file mode 100644 index 0000000..ccf61e0 --- /dev/null +++ b/versions/1.20.4/gradle.properties @@ -0,0 +1,17 @@ +# Fabric Properties +# check these on https://fallen-breath.github.io/fabric-versions/?&version=1.20.4 +minecraft_version=1.20.4 +yarn_mappings=1.20.4+build.3 +# Fabric Mod Metadata +minecraft_dependency=1.20.x +# Build Information +# The target mc versions for the mod during mod publishing, separated with \n +game_versions=1.20.4 +# Dependencies +fabric_api_version=0.96.1+1.20.4 +## https://www.curseforge.com/minecraft/mc-mods/malilib +malilib_file_id=5096807 +## https://www.curseforge.com/minecraft/mc-mods/item-scroller +item_scroller_file_id=4946332 +## https://mvnrepository.com/artifact/top.hendrixshen.magiclib +magiclib_version=0.7.398 diff --git a/versions/mainProject b/versions/mainProject new file mode 100644 index 0000000..0bd54ef --- /dev/null +++ b/versions/mainProject @@ -0,0 +1 @@ +1.20.4 diff --git a/versions/mapping-1.19.4-1.18.2.txt b/versions/mapping-1.19.4-1.18.2.txt new file mode 100644 index 0000000..55aa9d1 --- /dev/null +++ b/versions/mapping-1.19.4-1.18.2.txt @@ -0,0 +1 @@ +net.minecraft.network.packet.Packet net.minecraft.network.Packet