diff --git a/.gitattributes b/.gitattributes index f811f6a..4c3684e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,16 @@ -# Disable autocrlf on generated files, they always generate with LF -# Add any extra files or paths here to make git stop saying they -# are changed when only line endings change. -src/generated/**/.cache/cache text eol=lf -src/generated/**/*.json text eol=lf +* text eol=lf +*.bat text eol=crlf +*.patch text eol=lf +*.java text eol=lf +*.gradle text eol=crlf +*.png binary +*.gif binary +*.exe binary +*.dll binary +*.jar binary +*.lzma binary +*.zip binary +*.pyd binary +*.cfg text eol=lf +*.jks binary +*.ogg binary \ No newline at end of file diff --git a/.github/scripts/generate-publish-matrix.sh b/.github/scripts/generate-publish-matrix.sh new file mode 100755 index 0000000..691ec8d --- /dev/null +++ b/.github/scripts/generate-publish-matrix.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# Stolen from Faboslav +# https://github.com/Faboslav/friends-and-foes/blob/master/.github/scripts/generate-publish-matrix.sh + +matrix_content="{\"include\":[" +enabled_platforms=$(awk -F= '/stonecutter_enabled_platforms/{print $2}' gradle.properties | tr -d ' ') + +for platform in $(echo $enabled_platforms | tr ',' ' '); do + versions=$(awk -F= '/stonecutter_enabled_'$platform'_versions/{print $2}' gradle.properties | tr -d ' ') + for version in $(echo $versions | tr ',' ' '); do + if [[ "$platform" == "fabric" ]]; then + supported_loaders="\"fabric\",\"quilt\"" + else + supported_loaders="\"$platform\"" + fi + + matrix_entry="{\"loader\":\"$platform\",\"version\":\"$version\",\"supported_loaders\":[$supported_loaders]}," + matrix_content+="$matrix_entry" + done +done + +matrix_content="${matrix_content%,}]}" +echo "Generated matrix: $matrix_content" +echo "matrix=$matrix_content" >> $GITHUB_OUTPUT \ No newline at end of file diff --git a/.github/scripts/parse-gradle-properties.sh b/.github/scripts/parse-gradle-properties.sh new file mode 100755 index 0000000..e94dec4 --- /dev/null +++ b/.github/scripts/parse-gradle-properties.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# Stolen from Faboslav +# https://github.com/Faboslav/friends-and-foes/blob/master/.github/scripts/parse-gradle-properties.sh + +version=${1:-} + +parse_properties_file() { + local file=$1 + while IFS='=' read -r key value || [[ -n "$key" ]]; do + key=$(echo "$key" | awk '{$1=$1;print}') + value=$(echo "$value" | awk '{$1=$1;print}') + + if [[ -z "$key" || "$key" =~ ^# || "$key" == "org.gradle.jvmargs" ]]; then + continue + fi + + key=$(echo "$key" | tr '[:lower:]' '[:upper:]' | tr -c '[:alnum:]' '_') + key=$(echo "$key" | sed 's/_$//') + + echo "${key}=${value}" + echo "${key}=${value}" >> "$GITHUB_OUTPUT" + done < "$file" +} + +parse_properties_file gradle.properties + +if [[ -n "$version" ]]; then + parse_properties_file "versions/${version}/gradle.properties" +fi \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..649e7f9 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,51 @@ +name: Build + +on: + push: + branches: + - multiloader-stonecutter + pull_request: + workflow_call: + +concurrency: + group: build-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + name: Build Everything + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + fetch-depth: 1 + + - name: Set up JDK + uses: actions/setup-java@v3 + with: + java-version: 25 + distribution: temurin + cache: gradle + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v6 + with: + cache-read-only: false + gradle-version: wrapper + add-job-summary: 'on-failure' + + - name: Make gradlew executable + run: chmod +x ./gradlew + shell: bash + + - name: Build with Gradle + run: ./gradlew build + shell: bash + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: mod-artifacts + path: ./**/versions/**/build/libs diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..0a765a5 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,65 @@ +name: Publish + +on: + release: + types: [published] + +concurrency: + group: publish-${{ github.ref }} + cancel-in-progress: false + +jobs: + generate-publish-matrix: + runs-on: ubuntu-latest + name: Generate Publish Matrix + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 1 + + - id: set-matrix + run: bash ./.github/scripts/generate-publish-matrix.sh + + build: + uses: ./.github/workflows/build.yml + + publish: + needs: [generate-publish-matrix, build] + runs-on: ubuntu-latest + name: Publish ${{ matrix.loader }} ${{ matrix.version }} + strategy: + max-parallel: 3 + fail-fast: false + matrix: ${{ fromJSON(needs.generate-publish-matrix.outputs.matrix) }} + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 1 + + - uses: actions/download-artifact@v4 + with: + name: mod-artifacts + + - name: "Parse gradle properties" + id: gradle-properties + run: bash ./.github/scripts/parse-gradle-properties.sh ${{ matrix.version }} + + - uses: Kir-Antipov/mc-publish@v3.3 + with: + modrinth-id: ${{ vars.MODRINTH_PUB && vars.MODRINTH_ID }} + modrinth-token: ${{ vars.MODRINTH_PUB && secrets.MODRINTH_TOKEN }} + curseforge-id: ${{ vars.CURSEFORGE_PUB && vars.CURSEFORGE_ID }} + curseforge-token: ${{ vars.CURSEFORGE_PUB && secrets.CURSEFORGE_TOKEN }} + files: | + ${{ matrix.loader }}/versions/${{ matrix.version }}/build/libs/*.jar + loaders: ${{ join(matrix.supported_loaders, ' ') }} + game-versions: | + >=${{ steps.gradle-properties.outputs.MIN_MINECRAFT_VERSION }} <=${{ steps.gradle-properties.outputs.MINECRAFT_VERSION }} + version: ${{ steps.gradle-properties.outputs.MOD_VERSION }}-${{ matrix.version }}-${{ matrix.loader }} + name: ${{ steps.gradle-properties.outputs.MOD_NAME }} ${{ steps.gradle-properties.outputs.MOD_VERSION }} (${{ matrix.version }}-${{ matrix.loader }}) + version-type: ${{ github.event.release.prerelease && 'beta' || 'release' }} + changelog: ${{ github.event.release.body || '' }} + retry-attempts: 6 + retry-delay: 30000 diff --git a/.gitignore b/.gitignore index d211747..d5f737e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,28 +1,119 @@ -# eclipse -bin -*.launch -.settings -.metadata -.classpath -.project - -# idea -out +# User-specific stuff +.idea/ + +*.iml *.ipr *.iws -*.iml -.idea -# gradle -build +# IntelliJ +out/ +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + .gradle +build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Cache of project +.gradletasknamecache + +**/build/ -# other -eclipse -run -runs -run-data -.vscode +# Common working directory +run/ +runs/ -# Files from Forge MDK -forge*changelog.txt +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar diff --git a/LICENSE b/LICENSE index f288702..e72bfdd 100644 --- a/LICENSE +++ b/LICENSE @@ -671,4 +671,4 @@ into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read -. +. \ No newline at end of file diff --git a/README.md b/README.md index c2b5ad6..1d0cb44 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,27 @@ -# AutoFish for Forge -Finally! An AFK fishing mod for Forge users! +# AutoFish for Everyone +Finally! An AFK fishing mod for everyone! ## Download -1. Go to the CurseForge page [here](https://www.curseforge.com/minecraft/mc-mods/autofish-for-forge) -2. Find the version of the mod you want -3. Find the Minecraft version of the mod you want -4. Download -5. Enjoy! +- [CurseForge](https://www.curseforge.com/minecraft/mc-mods/autofish-for-everyone) +- [Modrinth](https://modrinth.com/mod/autofish-for-everyone) Thanks for using the mod! -### Currently supported versions -1.21.x -(Multiple versions were too much for me. I'm sorry.) - -### Unsupported, but we have their files -1.20.x -1.19.x -1.18.x -1.17.x -1.16.x -1.15.x -1.14.4 -1.13.2 -1.12.2 -1.11.2 -1.10.2 -1.9.4 -1.8.9 +## Supported Minecraft Versions and Mod Loaders +Versions not listed here are not supported + +| Minecraft Version | Fabric | Forge | NeoForge | +|-------------------|--------|-------|----------| +| 26.2 | ✅ | ✅ | ✅ | +| 26.1.2 | ✅ | ✅ | ✅ | +| 1.21.11 | ✅ | ✅ | ✅ | +| 1.21.1 | ✅ | ✅ | ✅ | +| 1.20.1 | ✅ | ✅ | ❌ | +| 1.19.4 | ✅ | ✅ | ❌ | +| 1.19.2 | ✅ | ✅ | ❌ | +| 1.18.2 | ✅ | ✅ | ❌ | +| 1.17.1 | ✅ | ✅ | ❌ | +| 1.16.5 | ✅ | ❌ | ❌ | ## What does it do? This mod allows you to AFK fish (as long as the server allows AFK) anywhere. Can I use it in my singleplayer world? Yes! Can I use it on servers? Yes! The mod is completely client-side! You just need a Forge client on your computer, put this mod into the "mods" folder and you finished the setup! How easy it is! @@ -45,4 +39,4 @@ Programmers have probably looked at the source code already, but allow me to exp When the mod is enabled, it will look for the bobber of the player. You may think that I look for the state of the bobber but no. The state of the bobber is not public, and there is no public methods that returns the state, so it is impossible to listen for change of state. -However, I found a way simplier method to know if is catch a fish...\*drumroll\* Motion. Since, the bobber is an entity, we can track its motion. As we all know, the bobber sinks into the water when it catches a fish. By tracking the vertical motion of the bobber, we can know when it catches a fish. It is simple as that! +However, I found a way simplier method to know if is catch a fish...\*drumroll\* Motion. Since, the bobber is an entity, we can track its motion. As we all know, the bobber sinks into the water when it catches a fish. By tracking the vertical motion of the bobber, we can know when it catches a fish. It is simple as that! \ No newline at end of file diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 14aec71..0000000 --- a/build.gradle +++ /dev/null @@ -1,106 +0,0 @@ -plugins { - id 'java-library' - id 'eclipse' - id 'idea' - id 'maven-publish' - id 'net.neoforged.gradle.userdev' version '7.0.145' -} - -tasks.named('wrapper', Wrapper).configure { - distributionType = Wrapper.DistributionType.BIN -} - -version = mod_version -group = mod_group_id - -repositories { - mavenLocal() -} - -base { - archivesName = mod_id -} - -java.toolchain.languageVersion = JavaLanguageVersion.of(21) - -runs { - configureEach { - systemProperty 'forge.logging.markers', 'REGISTRIES' - systemProperty 'forge.logging.console.level', 'debug' - modSource project.sourceSets.main - } - - client { - systemProperty 'forge.enabledGameTestNamespaces', project.mod_id - } - - server { - systemProperty 'forge.enabledGameTestNamespaces', project.mod_id - programArgument '--nogui' - } - - gameTestServer { - systemProperty 'forge.enabledGameTestNamespaces', project.mod_id - } - - data { - programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath() - } -} - -sourceSets.main.resources { srcDir 'src/generated/resources' } - -dependencies { - implementation "net.neoforged:neoforge:${neo_version}" -} - -tasks.withType(ProcessResources).configureEach { - var replaceProperties = [ - minecraft_version : minecraft_version, - minecraft_version_range: minecraft_version_range, - neo_version : neo_version, - neo_version_range : neo_version_range, - loader_version_range : loader_version_range, - mod_id : mod_id, - mod_name : mod_name, - mod_license : mod_license, - mod_version : mod_version, - mod_authors : mod_authors, - mod_description : mod_description - ] - inputs.properties replaceProperties - - filesMatching(['META-INF/neoforge.mods.toml']) { - expand replaceProperties - } -} - -tasks.named('jar', Jar).configure { - manifest { - archiveClassifier = "neoforge" + minecraft_version - } -} - -publishing { - publications { - register('mavenJava', MavenPublication) { - from components.java - } - } - repositories { - maven { - url "file://${project.projectDir}/repo" - } - } -} - -tasks.withType(JavaCompile).configureEach { - options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation -} - -idea { - module { - downloadSources = true - downloadJavadoc = true - } -} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..5d0afb8 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,4 @@ +// Disable building for versions, only for branches (fabric, forge, neoforge, common). +tasks.matching { it.name == "build" || it.name.startsWith("compile") || it.name == "classes" || it.name == "jar" || it.name == "javadoc" }.configureEach { + enabled = false +} diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 0000000..05996d6 --- /dev/null +++ b/buildSrc/build.gradle.kts @@ -0,0 +1,15 @@ +plugins { + `kotlin-dsl` + kotlin("jvm") version "2.2.0" +} + +repositories { + mavenCentral() + gradlePluginPortal() + maven("https://maven.kikugie.dev/snapshots") +} + +dependencies { + fun plugin(id: String, version: String) = "$id:$id.gradle.plugin:$version" + implementation("dev.kikugie:stonecutter:0.9.5") +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/FabricLoomCompatPlugin.kt b/buildSrc/src/main/kotlin/FabricLoomCompatPlugin.kt new file mode 100644 index 0000000..ea5ea1b --- /dev/null +++ b/buildSrc/src/main/kotlin/FabricLoomCompatPlugin.kt @@ -0,0 +1,61 @@ +// Stolen from Faboslav +// https://github.com/Faboslav/friends-and-foes/blob/master/buildSrc/src/main/kotlin/FabricLoomCompatPlugin.kt + +import dev.kikugie.stonecutter.build.StonecutterBuildExtension +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.tasks.TaskProvider +import org.gradle.jvm.tasks.Jar +import org.gradle.kotlin.dsl.create +import org.gradle.kotlin.dsl.the +import org.gradle.kotlin.dsl.named + +open class FabricLoomCompatPlugin : Plugin { + override fun apply(target: Project): Unit = with(target) { + val current = the().current.parsed + + if (current > "26.0") { + setupNewLoomFacade() + } else { + setupOldLoomFacade() + } + + extensions.create("fabric", this, current > "26.0") + } + + private fun Project.setupNewLoomFacade() { + plugins.apply("net.fabricmc.fabric-loom") + + val names = listOf( + "api", "implementation", "compileOnly", "runtimeOnly", "localRuntime" + ) + + for (baseName in names) { + val loomified = "mod" + baseName.replaceFirstChar(Char::uppercaseChar) + val modConfiguration = configurations.findByName(loomified) ?: configurations.create(loomified) + + configurations.getByName(baseName).extendsFrom(modConfiguration) + } + + configurations.findByName("mappings") ?: configurations.register("mappings") { + isCanBeResolved = false + isCanBeConsumed = false + } + } + + private fun Project.setupOldLoomFacade() { + plugins.apply("net.fabricmc.fabric-loom-remap") + } + + open class FabricExtensions(val project: Project, val isNew: Boolean) { + val modJar: TaskProvider by lazy { + if (isNew) project.tasks.named("jar") + else project.tasks.named("remapJar") + } + + val modSourcesJar: TaskProvider by lazy { + if (isNew) project.tasks.named("sourcesJar") + else project.tasks.named("remapSourcesJar") + } + } +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/build-extensions.kt b/buildSrc/src/main/kotlin/build-extensions.kt new file mode 100644 index 0000000..ffff43b --- /dev/null +++ b/buildSrc/src/main/kotlin/build-extensions.kt @@ -0,0 +1,46 @@ +import dev.kikugie.stonecutter.build.StonecutterBuildExtension +import dev.kikugie.stonecutter.controller.StonecutterControllerExtension +import org.gradle.api.Project +import org.gradle.api.artifacts.dsl.RepositoryHandler +import org.gradle.kotlin.dsl.* + +val Project.mod: ModData get() = ModData(this) +fun Project.prop(key: String): String? = findProperty(key)?.toString() +fun String.upperCaseFirst() = replaceFirstChar { if (it.isLowerCase()) it.uppercaseChar() else it } + +fun RepositoryHandler.strictMaven(url: String, alias: String, vararg groups: String) = exclusiveContent { + forRepository { maven(url) { name = alias } } + filter { groups.forEach(::includeGroup) } +} + +val Project.stonecutterBuild get() = extensions.getByType() +val Project.stonecutterController get() = extensions.getByType() + +val Project.common get() = requireNotNull(stonecutterBuild.node.sibling("common")) { + "No common project for $project" +} +val Project.commonProject get() = rootProject.project(stonecutterBuild.current.project) +val Project.commonMod get() = commonProject.mod + +val Project.loader: String? get() = prop("loader") + +@JvmInline +value class ModData(private val project: Project) { + val id: String get() = modProp("id") + val name: String get() = modProp("name") + val version: String get() = modProp("version") + val group: String get() = modProp("group") + val author: String get() = modProp("author") + val description: String get() = modProp("description") + val license: String get() = modProp("license") + val github: String get() = modProp("github") + val mc: String get() = depOrNull("minecraft") ?: project.stonecutterBuild.current.version + + fun propOrNull(key: String) = project.prop(key) + fun prop(key: String) = requireNotNull(propOrNull(key)) { "Missing '$key'" } + fun modPropOrNull(key: String) = project.prop("mod.$key") + fun modProp(key: String) = requireNotNull(modPropOrNull(key)) { "Missing 'mod.$key'" } + fun depOrNull(key: String): String? = project.prop("deps.$key")?.takeIf { it.isNotEmpty() && it != "" } + fun dep(key: String) = requireNotNull(depOrNull(key)) { "Missing 'deps.$key'" } + fun modrinth(name: String, version:String) = "maven.modrinth:$name:$version" +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/multiloader-common.gradle.kts b/buildSrc/src/main/kotlin/multiloader-common.gradle.kts new file mode 100644 index 0000000..8846e26 --- /dev/null +++ b/buildSrc/src/main/kotlin/multiloader-common.gradle.kts @@ -0,0 +1,87 @@ +plugins { + id("java") + //Cid("idea") + id("java-library") +} + +version = "${commonMod.version}-${stonecutterBuild.current.version}-${loader}" + +base { + archivesName = commonMod.id +} + +java { + toolchain.languageVersion = JavaLanguageVersion.of(commonProject.prop("java.version")!!) + // withSourcesJar() + // withJavadocJar() +} + +repositories { + mavenCentral() + exclusiveContent { + forRepository { + maven("https://repo.spongepowered.org/repository/maven-public") { name = "Sponge" } + } + filter { includeGroupAndSubgroups("org.spongepowered") } + } + exclusiveContent { + forRepositories( + maven("https://maven.parchmentmc.org") { name = "ParchmentMC" }, + maven("https://maven.neoforged.net/releases") { name = "NeoForge" }, + maven("https://maven.minecraftforge.net/") { name = "MinecraftForge" } + ) + filter { includeGroup("org.parchmentmc.data") } + } + maven("https://www.cursemaven.com") + maven("https://api.modrinth.com/maven") { + name = "Modrinth" + content { + includeGroup("maven.modrinth") + } + } + maven("https://maven.terraformersmc.com/releases/") { name = "TerraformersMC" } + maven("https://maven.kikugie.dev/releases") { name = "KikuGie Releases" } + maven("https://maven.kikugie.dev/snapshots") { name = "KikuGie Snapshots" } + maven("https://thedarkcolour.github.io/KotlinForForge/") +} + +tasks { + + processResources { + val expandProps = mapOf( + "javaVersion" to commonMod.propOrNull("java.version"), + "modId" to commonMod.id, + "modName" to commonMod.name, + "modVersion" to commonMod.version, + "modGroup" to commonMod.group, + "modAuthor" to commonMod.author, + "modDescription" to commonMod.description, + "modLicense" to commonMod.license, + "modGitHub" to commonMod.github, + "minecraftVersion" to commonMod.propOrNull("minecraft_version"), + "minMinecraftVersion" to commonMod.propOrNull("min_minecraft_version"), + "fabricLoaderVersion" to commonMod.depOrNull("fabric_loader"), + "fabricApiVersion" to commonMod.depOrNull("fabric_api"), + "neoForgeVersion" to commonMod.depOrNull("neoforge"), + "forgeVersion" to commonMod.depOrNull("forge"), + // "yaclVersion" to commonMod.depOrNull("yacl"), + "modMenuVersion" to commonMod.depOrNull("modmenu") + ).filterValues { it?.isNotEmpty() == true }.mapValues { (_, v) -> v!! } + + val jsonExpandProps = expandProps.mapValues { (_, v) -> v.replace("\n", "\\\\n") } + + filesMatching(listOf("META-INF/mods.toml", "META-INF/neoforge.mods.toml")) { + expand(expandProps) + } + + filesMatching(listOf("pack.mcmeta", "fabric.mod.json")) { + expand(jsonExpandProps) + } + + inputs.properties(expandProps) + } +} + +tasks.named("processResources") { + dependsOn(":common:${commonMod.propOrNull("minecraft_version")}:stonecutterGenerate") +} diff --git a/buildSrc/src/main/kotlin/multiloader-loader.gradle.kts b/buildSrc/src/main/kotlin/multiloader-loader.gradle.kts new file mode 100644 index 0000000..b292d69 --- /dev/null +++ b/buildSrc/src/main/kotlin/multiloader-loader.gradle.kts @@ -0,0 +1,31 @@ +plugins { + id("java") + //id("idea") + id("multiloader-common") +} + +val commonJava: Configuration by configurations.creating { + isCanBeResolved = true +} +val commonResources: Configuration by configurations.creating { + isCanBeResolved = true +} + +dependencies { + val commonPath = common.hierarchy.toString() + compileOnly(project(path = commonPath)) + commonJava(project(path = commonPath, configuration = "commonJava")) + commonResources(project(path = commonPath, configuration = "commonResources")) +} + +tasks { + compileJava { + dependsOn(commonJava) + source(commonJava) + } + + processResources { + dependsOn(commonResources) + from(commonResources) + } +} \ No newline at end of file diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/fabric-loom-compat.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/fabric-loom-compat.properties new file mode 100644 index 0000000..bd727b9 --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/fabric-loom-compat.properties @@ -0,0 +1 @@ +implementation-class=FabricLoomCompatPlugin \ No newline at end of file diff --git a/common/build.gradle.kts b/common/build.gradle.kts new file mode 100644 index 0000000..b9e8636 --- /dev/null +++ b/common/build.gradle.kts @@ -0,0 +1,51 @@ +plugins { + id("multiloader-common") + id("fabric-loom-compat") + kotlin("jvm") version "2.2.0" + id("com.google.devtools.ksp") version "2.2.0-2.0.2" +} + +loom { + if (stonecutter.eval(commonMod.mc, "<=1.21.11")) { + mixin { + useLegacyMixinAp = false + } + } +} + +dependencies { + minecraft("com.mojang:minecraft:${commonMod.mc}") + + if (stonecutter.eval(commonMod.mc, "<=1.21.11")) { + mappings(loom.layered { + officialMojangMappings() + commonMod.depOrNull("parchment")?.let { parchmentVersion -> + parchment("org.parchmentmc.data:parchment-${commonMod.mc}:$parchmentVersion@zip") + } + }) + } + + modCompileOnly("net.fabricmc:fabric-loader:${commonMod.dep("fabric_loader")}") +} + +val commonJava: Configuration by configurations.creating { + isCanBeResolved = false + isCanBeConsumed = true +} + +val commonResources: Configuration by configurations.creating { + isCanBeResolved = false + isCanBeConsumed = true +} + +artifacts { + afterEvaluate { + val mainSourceSet = sourceSets.main.get() + mainSourceSet.java.sourceDirectories.files.forEach { + add(commonJava.name, it) + } + mainSourceSet.resources.sourceDirectories.files.forEach { + add(commonResources.name, it) + } + } +} \ No newline at end of file diff --git a/common/gradle.properties b/common/gradle.properties new file mode 100644 index 0000000..ed5175f --- /dev/null +++ b/common/gradle.properties @@ -0,0 +1 @@ +loader=common \ No newline at end of file diff --git a/common/src/main/java/in/northwestw/autofish/AutoFish.java b/common/src/main/java/in/northwestw/autofish/AutoFish.java new file mode 100644 index 0000000..6b98eb0 --- /dev/null +++ b/common/src/main/java/in/northwestw/autofish/AutoFish.java @@ -0,0 +1,42 @@ +package in.northwestw.autofish; + +import in.northwestw.autofish.config.Config; +import net.minecraft.network.chat.MutableComponent; +//? if >=1.21.1 { +import net.minecraft.network.chat.contents.PlainTextContents; +import net.minecraft.network.chat.contents.TranslatableContents; +//? } elif >=1.19.2 { +/*import net.minecraft.network.chat.contents.LiteralContents; +import net.minecraft.network.chat.contents.TranslatableContents; +*///? } else { +/*import net.minecraft.network.chat.TextComponent; +import net.minecraft.network.chat.TranslatableComponent; +*///? } +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class AutoFish +{ + public static final String MOD_ID = "autofish"; + public static final Logger LOGGER = LogManager.getLogger(); + + static { + Config.load(); + } + + public static MutableComponent getTranslatableComponent(String key, Object... args) { + //? if >=1.19.2 { + return MutableComponent.create(new TranslatableContents(key, null, args)); + //? } else + //return new TranslatableComponent(key, args); + } + + public static MutableComponent getLiteralComponent(String str) { + //? if >=1.21.1 { + return MutableComponent.create(new PlainTextContents.LiteralContents(str)); + //? } elif >=1.19.2 { + /*return MutableComponent.create(new LiteralContents(str)); + *///? } else + //return new TextComponent(str); + } +} diff --git a/common/src/main/java/in/northwestw/autofish/config/Config.java b/common/src/main/java/in/northwestw/autofish/config/Config.java new file mode 100644 index 0000000..7c25cc6 --- /dev/null +++ b/common/src/main/java/in/northwestw/autofish/config/Config.java @@ -0,0 +1,175 @@ +package in.northwestw.autofish.config; + +import com.google.common.collect.Lists; +import com.google.gson.*; +import in.northwestw.autofish.AutoFish; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class Config { + private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); + + public static final long[] RECAST_DELAY_RANGE = { 1L, 600L }; + public static final long[] REEL_IN_DELAY_RANGE = { 0L, 600L }; + public static final long[] THROW_DELAY_RANGE = { 5L, 600L }; + public static final long[] CHECK_INTERVAL_RANGE = { 20L, 72000L }; + + public static long recastDelay = 20, reelInDelay = 0, throwDelay = 10, checkInterval = 200; + public static boolean autoFish = true, rodProtect = true, autoReplace = true, allFilters = true; + public static List filter = Lists.newArrayList(), prioritize = Lists.newArrayList(); + + public static void save() { + try { + File file = new File("config/" + AutoFish.MOD_ID + ".json"); + JsonObject json = new JsonObject(); + json.addProperty("recast_delay", recastDelay); + json.addProperty("reel_in_delay", reelInDelay); + json.addProperty("throw_delay", throwDelay); + json.addProperty("check_interval", checkInterval); + json.addProperty("auto_fish", autoFish); + json.addProperty("rod_protect", rodProtect); + json.addProperty("auto_replace", autoReplace); + json.addProperty("all_filters", allFilters); + + JsonArray array = new JsonArray(); + filter.forEach(array::add); + json.add("filter", array); + + if (file.exists() || file.createNewFile()) { + PrintWriter writer = new PrintWriter(file); + writer.println(GSON.toJson(json)); + writer.close(); + } + } catch (IOException e) { + AutoFish.LOGGER.error(e); + } + } + public static void load() { + try { + File file = new File("config/" + AutoFish.MOD_ID + ".json"); + if (!file.exists()) { + save(); + } else { + JsonObject json = GSON.fromJson(new FileReader(file), JsonObject.class); + if (json.has("recast_delay")) + recastDelay = json.get("recast_delay").getAsLong(); + if (json.has("reel_in_delay")) + reelInDelay = json.get("reel_in_delay").getAsLong(); + if (json.has("throw_delay")) + throwDelay = json.get("throw_delay").getAsLong(); + if (json.has("check_interval")) + checkInterval = json.get("check_interval").getAsLong(); + if (json.has("auto_fish")) + autoFish = json.get("auto_fish").getAsBoolean(); + if (json.has("rod_protect")) + rodProtect = json.get("rod_protect").getAsBoolean(); + if (json.has("auto_replace")) + autoReplace = json.get("auto_replace").getAsBoolean(); + if (json.has("all_filters")) + allFilters = json.get("all_filters").getAsBoolean(); + if (json.has("filter")) { + filter = Lists.newArrayList(); + JsonArray arr = json.getAsJsonArray("filter"); + for (int ii = 0; ii < arr.size(); ii++) + filter.add(arr.get(ii).getAsString()); + } + + // validate + if (recastDelay < RECAST_DELAY_RANGE[0] || recastDelay > RECAST_DELAY_RANGE[1]) { + AutoFish.LOGGER.warn("recast_delay must be in range [1, 600]. Defaults to 20"); + recastDelay = 20; + } + if (reelInDelay < REEL_IN_DELAY_RANGE[0] || reelInDelay > REEL_IN_DELAY_RANGE[1]) { + AutoFish.LOGGER.warn("reel_in_delay must be in range [0, 600]. Defaults to 0"); + reelInDelay = 0; + } + if (throwDelay < THROW_DELAY_RANGE[0] || throwDelay > THROW_DELAY_RANGE[1]) { + AutoFish.LOGGER.warn("throw_delay must be in range [5, 600]. Defaults to 10"); + throwDelay = 10; + } + if (checkInterval < CHECK_INTERVAL_RANGE[0] || checkInterval > CHECK_INTERVAL_RANGE[1]) { + AutoFish.LOGGER.warn("check_interval must be in range [20, 72000]. Defaults to 200"); + checkInterval = 200; + } + } + } catch (IOException e) { + AutoFish.LOGGER.error(e); + } + } + + public static void setRecastDelay(long recastDelay) { + if (recastDelay < 1 || recastDelay > 600) { + AutoFish.LOGGER.warn("max_circuit_size must be in range [1, 600]. Defaults to 20"); + recastDelay = 20; + } + Config.recastDelay = recastDelay; + Config.save(); + AutoFish.LOGGER.debug("Set Recast Delay: " + recastDelay); + } + + public static void setReelInDelay(long reelInDelay) { + if (reelInDelay < 0 || reelInDelay > 600) { + AutoFish.LOGGER.warn("reel_in_delay must be in range [0, 600]. Defaults to 0"); + reelInDelay = 0; + } + Config.reelInDelay = reelInDelay; + Config.save(); + AutoFish.LOGGER.debug("Set Reel In Delay: " + reelInDelay); + } + + public static void setThrowDelay(long throwDelay) { + if (throwDelay < 5 || throwDelay > 600) { + AutoFish.LOGGER.warn("throw_delay must be in range [5, 600]. Defaults to 10"); + throwDelay = 10; + } + Config.throwDelay = throwDelay; + Config.save(); + AutoFish.LOGGER.debug("Set Throw Delay: " + throwDelay); + } + + public static void setCheckInterval(long checkInterval) { + if (checkInterval < 20 || checkInterval > 72000) { + AutoFish.LOGGER.warn("check_interval must be in range [20, 72000]. Defaults to 200"); + checkInterval = 200; + } + Config.checkInterval = checkInterval; + Config.save(); + AutoFish.LOGGER.debug("Set Check Interval: " + checkInterval); + } + + public static void setAutoFish(boolean autoFish) { + Config.autoFish = autoFish; + Config.save(); + AutoFish.LOGGER.info("Toggle AutoFish: " + autoFish); + } + + public static void setRodProtect(boolean rodProtect) { + Config.rodProtect = rodProtect; + Config.save(); + AutoFish.LOGGER.info("Toggle Rod Protect: " + rodProtect); + } + + public static void setAutoReplace(boolean autoReplace) { + Config.autoReplace = autoReplace; + Config.save(); + AutoFish.LOGGER.info("Toggle Auto Replace: " + autoReplace); + } + + public static void enableFilter(boolean filter) { + Config.allFilters = filter; + Config.save(); + AutoFish.LOGGER.info("Toggle Filter: " + filter); + } + + public static void setFilter(List list) { + Config.filter = list; + Config.save(); + AutoFish.LOGGER.info("Received new Filter"); + } +} diff --git a/common/src/main/java/in/northwestw/autofish/config/gui/FilterSelectionScreen.java b/common/src/main/java/in/northwestw/autofish/config/gui/FilterSelectionScreen.java new file mode 100644 index 0000000..21cf7c3 --- /dev/null +++ b/common/src/main/java/in/northwestw/autofish/config/gui/FilterSelectionScreen.java @@ -0,0 +1,318 @@ +package in.northwestw.autofish.config.gui; + +import com.google.common.collect.Lists; +import in.northwestw.autofish.AutoFish; +import in.northwestw.autofish.config.Config; +//? if >=26.1 { +import net.minecraft.client.gui.GuiGraphicsExtractor; +//?} elif >=1.20.1 { +//import net.minecraft.client.gui.GuiGraphics; +//? } else +//import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.screens.Screen; +//? if >=1.21.11 { +import net.minecraft.client.input.KeyEvent; +import net.minecraft.client.input.MouseButtonEvent; +//? } +//? if >=1.18.2 { +import com.mojang.datafixers.util.Pair; +import net.minecraft.core.HolderSet; +//? } else { +/*import net.minecraft.tags.ItemTags; +import net.minecraft.tags.Tag; +*///? } +//? if >=1.19.4 { +import net.minecraft.core.registries.BuiltInRegistries; +//? } else +//import net.minecraft.core.Registry; +import net.minecraft.resources.Identifier; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; + +import java.util.List; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class FilterSelectionScreen extends Screen { + private final Screen parent; + private EditBox search; + //? if >=1.19.4 { + private final Collection original = BuiltInRegistries.ITEM.stream().toList(); + //? } else + //private final Collection original = Registry.ITEM.stream().collect(Collectors.toList()); + private Collection searching; + private final Set selected = new HashSet<>(Config.filter.stream().map(string -> + //? if >=1.21.1 { + BuiltInRegistries.ITEM.getOptional(Identifier.parse(string)) + //? } elif >=1.19.4 { + //BuiltInRegistries.ITEM.getOptional(new Identifier(string)) + //? } else + //Optional.of(Registry.ITEM.get(new Identifier(string))) + ).filter(Optional::isPresent).map(Optional::get).collect(Collectors.toList())); + private int page, maxPage = (int) Math.ceil(original.size() / 300.0), max = 300; + private boolean clickProcessed = true; + private double clickX, clickY; + private Button previous, next; + int reducedHeight; + int reducedWidth; + + public FilterSelectionScreen(Screen parent) { + super(AutoFish.getTranslatableComponent("gui.filterselection")); + this.parent = parent; + } + + @Override + protected void init() { + reducedHeight = this.height - 90; + reducedWidth = this.width - 30; + max = /* (int) Math.round(300 * (reducedWidth / 550.0 + reducedHeight / 330.0) / 2.0) */ 300; + maxPage = (int) Math.ceil(original.size() / (double) max); + searching = original; + search = new EditBox(this.font, this.width / 2 - 75, 35, 150, 20, AutoFish.getTranslatableComponent("gui.superfilterscreen.search")) { + @Override + //? if >=1.21.11 { + public boolean mouseClicked(MouseButtonEvent ev, boolean p_430750_) { + if (ev.button() == ScreenHelper.MOUSE_BUTTON_LEFT) this.setValue(""); + return super.mouseClicked(ev, p_430750_); + } + //? } else { + /*public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (button == ScreenHelper.MOUSE_BUTTON_LEFT) this.setValue(""); + return super.mouseClicked(mouseX, mouseY, button); + } + *///? } + }; + search.setResponder(s -> { + String[] args = s.split("/ +/"); + List mods = Lists.newArrayList(), tags = Lists.newArrayList(), paths = Lists.newArrayList(); + for (String arg : args) { + if (arg.startsWith("@")) mods.add(arg.toLowerCase().substring(1)); + else if (arg.startsWith("#")) tags.add(arg.toLowerCase().substring(1)); + else paths.add(arg.toLowerCase()); + } + //? if >=1.21.11 { + List> itemTags = BuiltInRegistries.ITEM.getTags().filter(tag -> tags.stream().anyMatch(t -> tag.key().location().getPath().contains(t))).toList(); + //? } elif >=1.19.4 { + //List> itemTags = BuiltInRegistries.ITEM.getTags().map(Pair::getSecond).filter(tag -> tags.stream().anyMatch(t -> tag.key().location().getPath().contains(t))).toList(); + //? } elif >=1.18.2 { + /*List> itemTags = Registry.ITEM.getTags().map(Pair::getSecond).filter(tag -> tags.stream().anyMatch(t -> tag.key().location().getPath().contains(t))).toList(); + *///? } else { + /*List> itemTags = ItemTags.getAllTags().getAllTags().entrySet().stream() + .filter(entry -> tags.stream().anyMatch(t -> entry.getKey().toString().contains(t))) + .map(Map.Entry::getValue).collect(Collectors.toList()); + *///? } + searching = original.stream().filter(item -> { + //? if >=1.21.11 { + Optional> opt = BuiltInRegistries.ITEM.getResourceKey(item); + if (opt.isEmpty()) return false; + Identifier rl = opt.get().identifier(); + //? } elif >=1.19.4 { + /*Optional> opt = BuiltInRegistries.ITEM.getResourceKey(item); + if (opt.isEmpty()) return false; + Identifier rl = opt.get().location(); + *///? } else { + /*Optional> opt = Registry.ITEM.getResourceKey(item); + if (!opt.isPresent()) return false; + Identifier rl = opt.get().location(); + *///? } + boolean matchmod = mods.isEmpty(), matchtag = tags.isEmpty(), matcharg = false; + for (String mod : mods) + matchmod = matchmod || rl.getNamespace().toLowerCase().contains(mod); + //? if >=1.18.2 { + for (HolderSet.Named itemTag : itemTags) + matchtag = matchtag || itemTag.stream().anyMatch(tagItem -> tagItem.value() == item); + //? } else + //matchtag = matchtag || itemTags.stream().anyMatch(tag -> tag.contains(item)); + for (String arg : paths) + matcharg = matcharg || rl.getPath().contains(arg); + return matchmod && matchtag && matcharg; + }).collect(Collectors.toList()); + maxPage = (int) Math.ceil(searching.size() / (double) max); + if (page > maxPage - 1) page = Math.max(0, maxPage - 1); + }); + Button add = ScreenHelper.makeButton(this.width / 2 - 75, 60, 72, 20, AutoFish.getTranslatableComponent("gui.filterselection.save"), button -> { + //? if >=1.19.4 { + List items = selected.stream().map(item -> BuiltInRegistries.ITEM.getKey(item).toString()).collect(Collectors.toList()); + //? } else + //List items = selected.stream().map(item -> Registry.ITEM.getKey(item).toString()).collect(Collectors.toList()); + Config.setFilter(items); + ScreenHelper.showScreen(parent); + }); + Button done = ScreenHelper.makeButton(this.width / 2 + 3, 60, 72, 20, AutoFish.getTranslatableComponent("gui.filterselection.cancel"), button -> ScreenHelper.showScreen(parent)); + previous = ScreenHelper.makeButton(this.width / 2 - 100, 60, 20, 20, AutoFish.getLiteralComponent("<"), button -> { if (page > 0) page--; }); + previous.visible = false; + next = ScreenHelper.makeButton(this.width / 2 + 80, 60, 20, 20, AutoFish.getLiteralComponent(">"), button -> { if (page < maxPage - 1) page++; }); + next.visible = false; + //? if <=1.16.5 { + /*this.children.add(search); + addButton(add); + addButton(done); + addButton(previous); + addButton(next); + *///? } else { + addRenderableWidget(search); + addRenderableWidget(add); + addRenderableWidget(done); + addRenderableWidget(previous); + addRenderableWidget(next); + //? } + } + + @Override + //? if >=26.1 { + public void extractRenderState(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float partialTicks) { + super.extractRenderState(graphics, mouseX, mouseY, partialTicks); + graphics.centeredText(this.font, this.title, this.width / 2, 20, -1); + //?} elif >=1.20.1 { + /*public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { + super.render(graphics, mouseX, mouseY, partialTicks); + graphics.drawCenteredString(this.font, this.title, this.width / 2, 20, -1); + *///?} else { + /*public void render(PoseStack poseStack, int mouseX, int mouseY, float partialTicks) { + this.renderBackground(poseStack); + super.render(poseStack, mouseX, mouseY, partialTicks); + drawCenteredString(poseStack, this.font, this.title, this.width / 2, 20, -1); + *///? } + Collection searchingCopy = Lists.newArrayList(); + Collection prioritized = searching.stream().filter(item -> { + //? if >=1.21.11 { + Optional> opt = BuiltInRegistries.ITEM.getResourceKey(item); + if (opt.isEmpty()) return false; + Identifier rl = opt.get().identifier(); + //? } elif >=1.19.4 { + /*Optional> opt = BuiltInRegistries.ITEM.getResourceKey(item); + if (opt.isEmpty()) return false; + Identifier rl = opt.get().location(); + *///? } else { + /*Optional> opt = Registry.ITEM.getResourceKey(item); + if (!opt.isPresent()) return false; + Identifier rl = opt.get().location(); + *///? } + boolean pri = Config.prioritize.contains(rl.toString()); + if (!pri) searchingCopy.add(item); + return pri; + }).collect(Collectors.toList()); + Item[] items = Stream.concat(prioritized.stream(), searchingCopy.stream()).toArray(Item[]::new); + if (items.length > 0 && page >= 0) { + for (int i = page * max; i < Math.min((page + 1) * max, searching.size()); i++) { + Item item = items[i]; + int h = (i % max) / (max / 30); + int k = (i % max) % (max / 30); + int x = getXPos(h, reducedWidth); + int y = getYPos(k, reducedHeight); + ItemStack stack = new ItemStack(item); + if (!stack.isEmpty()) { + //? if >=26.1 { + graphics.item(stack, x, y); + //? } elif >=1.20.1 { + //graphics.renderItem(stack, x, y); + //? } elif >=1.19.4 { + //itemRenderer.renderGuiItem(poseStack, stack, x, y); + //? } else + //itemRenderer.renderGuiItem(stack, x, y); + if (!clickProcessed && isMouseInRange(clickX, clickY, x, y, x+16, y+16)) { + if (selected.contains(item)) selected.remove(item); + else selected.add(item); + clickProcessed = true; + } + //? if >=1.20.1 { + if (selected.contains(item)) graphics.fillGradient(x - 2, y - 2, x + 18, y + 18, 0xFF00FF00, 0xFF00FF00); + else if (isMouseInRange(mouseX, mouseY, x, y,x + 16, y + 16)) graphics.fillGradient(x - 2, y - 2, x + 18, y + 18, 0xFFC0C0C0, 0xFFC0C0C0); + //? } else { + /*if (selected.contains(item)) fillGradient(poseStack, x - 2, y - 2, x + 18, y + 18, 0xFF00FF00, 0xFF00FF00); + else if (isMouseInRange(mouseX, mouseY, x, y,x + 16, y + 16)) fillGradient(poseStack, x - 2, y - 2, x + 18, y + 18, 0xFFC0C0C0, 0xFFC0C0C0); + *///? } + //if (isMouseInRange(mouseX, mouseY, x, y,x + 16, y + 16)) graphics.item(this.font, stack, mouseX, mouseY); + //? if >=26.1 { + graphics.item(stack, x, y); + //? } elif >=1.20.1 { + //graphics.renderItem(stack, x, y); + //? } elif >=1.19.4 { + //itemRenderer.renderGuiItem(poseStack, stack, x, y); + //? } else + //itemRenderer.renderGuiItem(stack, x, y); + } + } + } + //? if >=26.1 { + search.extractRenderState(graphics, mouseX, mouseY, partialTicks); + //?} elif >=1.20.1 { + //search.render(graphics, mouseX, mouseY, partialTicks); + //? } else + //search.render(poseStack, mouseX, mouseY, partialTicks); + } + + private boolean isMouseInRange(double mouseX, double mouseY, int x1, int y1, int x2, int y2) { + return mouseX > x1 && mouseX < x2 && mouseY > y1 && mouseY < y2; + } + + private int getXPos(int h, int width) { + return (width * h / 30) + 15; + } + + private int getYPos(int k, int height) { + return ((height * k / (max / 30)) + 90); + } + + @Override + //? if >=1.21.11 { + public boolean keyPressed(KeyEvent ev) { + if (ev.key() == ScreenHelper.KEY_ESCAPE) { + if (!search.isFocused()) ScreenHelper.showScreen(parent); + else search.setFocused(false); + } + return super.keyPressed(ev); + } + //? } else { + /*public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + if (keyCode == ScreenHelper.KEY_ESCAPE) { + if (!search.isFocused()) ScreenHelper.showScreen(parent); + else + //? if >=1.19.4 { + search.setFocused(false); + //? } else + //search.setFocus(false); + } + return super.keyPressed(keyCode, scanCode, modifiers); + } + *///? } + + @Override + //? if >=1.21.11 { + public boolean mouseClicked(MouseButtonEvent ev, boolean flag) { + clickX = ev.x(); + clickY = ev.y(); + clickProcessed = false; + return super.mouseClicked(ev, flag); + } + //? } else { + /*public boolean mouseClicked(double mouseX, double mouseY, int button) { + clickX = mouseX; + clickY = mouseY; + clickProcessed = false; + return super.mouseClicked(mouseX, mouseY, button); + } + *///? } + + @Override + public boolean shouldCloseOnEsc() { + return false; + } + + @Override + public void tick() { + //search.tick(); + super.tick(); + previous.visible = page >= 1; + next.visible = page < maxPage - 1; + } + + @Override + public boolean isPauseScreen() { + return false; + } +} diff --git a/common/src/main/java/in/northwestw/autofish/config/gui/LongSettingScreen.java b/common/src/main/java/in/northwestw/autofish/config/gui/LongSettingScreen.java new file mode 100644 index 0000000..6ce1dff --- /dev/null +++ b/common/src/main/java/in/northwestw/autofish/config/gui/LongSettingScreen.java @@ -0,0 +1,134 @@ +package in.northwestw.autofish.config.gui; + +import in.northwestw.autofish.AutoFish; +//? if >=26.1 { +import net.minecraft.client.gui.GuiGraphicsExtractor; + //?} elif >=1.20.1 { +//import net.minecraft.client.gui.GuiGraphics; +//? } else +//import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.screens.Screen; +//? if >=1.21.11 { +import net.minecraft.client.input.KeyEvent; +import net.minecraft.client.input.MouseButtonEvent; +//? } + +import java.util.function.Consumer; +import java.util.function.Supplier; +import java.util.regex.Pattern; + +public class LongSettingScreen extends Screen { + private final Screen parent; + private final String middleTranslationKey; + private final Supplier supplier; + private final Consumer consumer; + private final long min, max; + private EditBox editBox; + + protected LongSettingScreen(Screen parent, String middleTranslationKey, Supplier supplier, Consumer consumer, long min, long max) { + super(AutoFish.getTranslatableComponent("gui." + middleTranslationKey)); + this.parent = parent; + this.middleTranslationKey = middleTranslationKey; + this.supplier = supplier; + this.consumer = consumer; + this.min = min; + this.max = max; + } + + @Override + protected void init() { + editBox = new EditBox(this.font, this.width / 2 - 75, this.height / 2 - 25, 150, 20, AutoFish.getTranslatableComponent("gui." + this.middleTranslationKey + ".throwdelay")) { + @Override + //? if >=1.21.11 { + public boolean mouseClicked(MouseButtonEvent ev, boolean p_430750_) { + if (ev.button() == ScreenHelper.MOUSE_BUTTON_LEFT) this.setValue(""); + return super.mouseClicked(ev, p_430750_); + } + //? } else { + /*public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (button == ScreenHelper.MOUSE_BUTTON_LEFT) this.setValue(""); + return super.mouseClicked(mouseX, mouseY, button); + } + *///? } + }; + editBox.setValue(Long.toString(this.supplier.get())); + Button save = ScreenHelper.makeButton(this.width / 2 - 75, this.height / 2, 150, 20, AutoFish.getTranslatableComponent("gui." + this.middleTranslationKey + ".save"), button -> { + if (!isNumeric(editBox.getValue())) editBox.setValue(Long.toString(this.supplier.get())); + else { + long delay = Long.parseLong(editBox.getValue()); + if (delay < this.min || delay > this.max) editBox.setValue(Long.toString(this.supplier.get())); + else { + this.consumer.accept(delay); + ScreenHelper.showScreen(parent); + } + } + }); + //? if <=1.16.5 { + /*this.children.add(editBox); + addButton(save); + *///? } else { + addRenderableWidget(editBox); + addRenderableWidget(save); + //? } + } + + @Override + public void tick() { + //throwDelay.tick(); + super.tick(); + } + + private static final Pattern pattern = Pattern.compile("-?\\d+(\\.\\d+)?"); + public static boolean isNumeric(String strNum) { + if (strNum == null) { + return false; + } + return pattern.matcher(strNum).matches(); + } + + @Override + //? if >=26.1 { + public void extractRenderState(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float partialTicks) { + super.extractRenderState(graphics, mouseX, mouseY, partialTicks); + graphics.centeredText(this.font, this.title, this.width / 2, 20, -1); + this.editBox.extractRenderState(graphics, mouseX, mouseY, partialTicks); + } + //? } elif >=1.20.1 { + /*public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { + super.render(graphics, mouseX, mouseY, partialTicks); + graphics.drawCenteredString(this.font, this.title, this.width / 2, 20, -1); + this.editBox.render(graphics, mouseX, mouseY, partialTicks); + } + *///? } else { + /*public void render(PoseStack poseStack, int mouseX, int mouseY, float partialTicks) { + super.render(poseStack, mouseX, mouseY, partialTicks); + drawCenteredString(poseStack, this.font, this.title, this.width / 2, 20, -1); + this.editBox.render(poseStack, mouseX, mouseY, partialTicks); + } + *///? } + + @Override + public boolean shouldCloseOnEsc() { + return false; + } + + @Override + //? if >=1.21.11 { + public boolean keyPressed(KeyEvent ev) { + if (ev.key() == ScreenHelper.KEY_ESCAPE) ScreenHelper.showScreen(parent); + return super.keyPressed(ev); + } + //? } else { + /*public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + if (keyCode == ScreenHelper.KEY_ESCAPE) ScreenHelper.showScreen(parent); + return super.keyPressed(keyCode, scanCode, modifiers); + } + *///? } + + @Override + public boolean isPauseScreen() { + return false; + } +} diff --git a/common/src/main/java/in/northwestw/autofish/config/gui/ScreenHelper.java b/common/src/main/java/in/northwestw/autofish/config/gui/ScreenHelper.java new file mode 100644 index 0000000..186777b --- /dev/null +++ b/common/src/main/java/in/northwestw/autofish/config/gui/ScreenHelper.java @@ -0,0 +1,33 @@ +package in.northwestw.autofish.config.gui; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; +//? if >=1.19.2 { +import org.lwjgl.glfw.GLFW; +//? } + +public class ScreenHelper { + //? if >=1.19.2 { + public static final int MOUSE_BUTTON_LEFT = GLFW.GLFW_MOUSE_BUTTON_2; + public static final int KEY_ESCAPE = GLFW.GLFW_KEY_ESCAPE; + //? } else { + /*public static final int MOUSE_BUTTON_LEFT = 1; + public static final int KEY_ESCAPE = 256; + *///? } + + public static void showScreen(Screen screen) { + //? if >=1.21.11 { + Minecraft.getInstance().setScreenAndShow(screen); + //? } else + //Minecraft.getInstance().setScreen(screen); + } + + public static Button makeButton(int x, int y, int width, int height, Component label, Button.OnPress onPress) { + //? if >=1.19.4 { + return new Button.Builder(label, onPress).pos(x, y).size(width, height).build(); + //? } else + //return new Button(x, y, width, height, label, onPress); + } +} diff --git a/common/src/main/java/in/northwestw/autofish/config/gui/SettingsScreen.java b/common/src/main/java/in/northwestw/autofish/config/gui/SettingsScreen.java new file mode 100644 index 0000000..eebe6ac --- /dev/null +++ b/common/src/main/java/in/northwestw/autofish/config/gui/SettingsScreen.java @@ -0,0 +1,77 @@ +package in.northwestw.autofish.config.gui; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import in.northwestw.autofish.AutoFish; +import in.northwestw.autofish.config.Config; +//? if >=26.1 { +import net.minecraft.client.gui.GuiGraphicsExtractor; + //?} elif >=1.20.1 { +//import net.minecraft.client.gui.GuiGraphics; +//? } else +//import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.List; + +public class SettingsScreen extends Screen { + private static final int WIDTH = 150, HEIGHT = 20, MARGIN = 5; + + public SettingsScreen() { + super(AutoFish.getTranslatableComponent("gui.autofish")); + } + + @Override + public boolean isPauseScreen() { + return false; + } + + @Override + protected void init() { + List> pairs = ImmutableList.of( + Pair.of(AutoFish.getTranslatableComponent("gui.autofish.recastdelay"), button -> + ScreenHelper.showScreen(new LongSettingScreen(this, "setrecastdelay", () -> Config.recastDelay, (newDelay) -> Config.recastDelay = newDelay, Config.RECAST_DELAY_RANGE[0], Config.RECAST_DELAY_RANGE[1]))), + Pair.of(AutoFish.getTranslatableComponent("gui.autofish.reelindelay"), button -> + ScreenHelper.showScreen(new LongSettingScreen(this, "setreelindelay", () -> Config.reelInDelay, (newDelay) -> Config.reelInDelay = newDelay, Config.REEL_IN_DELAY_RANGE[0], Config.REEL_IN_DELAY_RANGE[1]))), + Pair.of(AutoFish.getTranslatableComponent("gui.autofish.throwdelay"), button -> + ScreenHelper.showScreen(new LongSettingScreen(this, "setthrowdelay", () -> Config.throwDelay, (newDelay) -> Config.throwDelay = newDelay, Config.THROW_DELAY_RANGE[0], Config.THROW_DELAY_RANGE[1]))), + Pair.of(AutoFish.getTranslatableComponent("gui.autofish.checkinterval"), button -> + ScreenHelper.showScreen(new LongSettingScreen(this, "setcheckinterval", () -> Config.checkInterval, (newInterval) -> Config.checkInterval = newInterval, Config.CHECK_INTERVAL_RANGE[0], Config.CHECK_INTERVAL_RANGE[1]))), + Pair.of(AutoFish.getTranslatableComponent("gui.autofish.filter"), button -> + ScreenHelper.showScreen(new SuperFilterScreen(this))) + ); + + for (int ii = 0; ii < pairs.size(); ii++) { + Pair pair = pairs.get(ii); + Button button = ScreenHelper.makeButton(this.width / 2 - WIDTH / 2, this.height / 2 + (ii - pairs.size() / 2) * (HEIGHT + MARGIN), WIDTH, HEIGHT, pair.getLeft(), pair.getRight()); + //? if <=1.16.5 { + /*addButton(button); + *///? } else + addRenderableWidget(button); + } + + Button done = ScreenHelper.makeButton(this.width / 2 - 75, this.height - 25, 150, 20, AutoFish.getTranslatableComponent("gui.autofish.done"), button -> onClose()); + //? if <=1.16.5 { + /*addButton(done); + *///? } else + addRenderableWidget(done); + } + + @Override + //? if >=26.1 { + public void extractRenderState(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float partialTicks) { + super.extractRenderState(graphics, mouseX, mouseY, partialTicks); + graphics.centeredText(this.font, this.title, this.width / 2, 20, -1); + }//?} elif >=1.20.1 { + /*public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { + super.render(graphics, mouseX, mouseY, partialTicks); + graphics.drawCenteredString(this.font, this.title, this.width / 2, 20, -1); + }*///?} else { + /*public void render(PoseStack poseStack, int mouseX, int mouseY, float partialTicks) { + super.render(poseStack, mouseX, mouseY, partialTicks); + drawCenteredString(poseStack, this.font, this.title, this.width / 2, 20, -1); + }*///?} +} diff --git a/common/src/main/java/in/northwestw/autofish/config/gui/SuperFilterScreen.java b/common/src/main/java/in/northwestw/autofish/config/gui/SuperFilterScreen.java new file mode 100644 index 0000000..d738034 --- /dev/null +++ b/common/src/main/java/in/northwestw/autofish/config/gui/SuperFilterScreen.java @@ -0,0 +1,225 @@ +package in.northwestw.autofish.config.gui; + +import com.google.common.collect.Lists; +import com.mojang.datafixers.util.Pair; +import in.northwestw.autofish.AutoFish; +import in.northwestw.autofish.config.Config; +//? if >=26.1 { +import net.minecraft.client.gui.GuiGraphicsExtractor; +//?} elif >=1.20.1 { +//import net.minecraft.client.gui.GuiGraphics; +//? } else +//import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.screens.Screen; +//? if >=1.21.11 { +import net.minecraft.client.input.KeyEvent; +import net.minecraft.client.input.MouseButtonEvent; +//? } +//? if >=1.18.2 { +import net.minecraft.core.HolderSet; +//? } else { +/*import net.minecraft.tags.ItemTags; +import net.minecraft.tags.Tag; +*///? } +//? if >=1.19.4 { +import net.minecraft.core.registries.BuiltInRegistries; +//? } else +//import net.minecraft.core.Registry; +import net.minecraft.resources.Identifier; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; + +import java.util.List; +import java.util.*; +import java.util.stream.Collectors; + +public class SuperFilterScreen extends Screen { + private final Screen parent; + private EditBox search; + private Collection original; + private Collection searching; + private int page = 0, maxPage, max = 30; + private Button previous, next; + int reducedHeight; + int reducedWidth; + + protected SuperFilterScreen(Screen parent) { + super(AutoFish.getTranslatableComponent("gui.superfilterscreen")); + this.parent = parent; + } + + @Override + public void tick() { + //search.tick(); + previous.visible = page >= 1; + next.visible = page < maxPage - 1; + } + + @Override + protected void init() { + reducedHeight = this.height - 90; + reducedWidth = this.width - 30; + max = /* (int) Math.round(30 * (reducedWidth / 550.0 + reducedHeight / 330.0) / 2.0) */ 30; + original = Config.filter.stream().map(string -> + //? if >=1.21.1 { + BuiltInRegistries.ITEM.getOptional(Identifier.parse(string)) + //? } elif >=1.19.4 { + //BuiltInRegistries.ITEM.getOptional(new Identifier(string)) + //? } else + //Optional.of(Registry.ITEM.get(new Identifier(string))) + ).filter(Optional::isPresent).map(Optional::get).collect(Collectors.toList()); + maxPage = (int) Math.ceil(original.size() / (double) max); + searching = original; + search = new EditBox(this.font, this.width / 2 - 75, 35, 150, 20, AutoFish.getTranslatableComponent("gui.superfilterscreen.search")) { + @Override + //? if >=1.21.11 { + public boolean mouseClicked(MouseButtonEvent ev, boolean p_430750_) { + if (ev.button() == ScreenHelper.MOUSE_BUTTON_LEFT) this.setValue(""); + return super.mouseClicked(ev, p_430750_); + } + //? } else { + /*public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (button == ScreenHelper.MOUSE_BUTTON_LEFT) this.setValue(""); + return super.mouseClicked(mouseX, mouseY, button); + } + *///? } + }; + search.setResponder(s -> { + String[] args = s.split("/ +/"); + List mods = Lists.newArrayList(), tags = Lists.newArrayList(), paths = Lists.newArrayList(); + for (String arg : args) { + if (arg.startsWith("@")) mods.add(arg.toLowerCase().substring(1)); + else if (arg.startsWith("#")) tags.add(arg.toLowerCase().substring(1)); + else paths.add(arg.toLowerCase()); + } + //? if >=1.21.11 { + List> itemTags = BuiltInRegistries.ITEM.getTags().filter(tag -> tags.stream().anyMatch(t -> tag.key().location().getPath().contains(t))).toList(); + //? } elif >=1.19.4 { + //List> itemTags = BuiltInRegistries.ITEM.getTags().map(Pair::getSecond).filter(tag -> tags.stream().anyMatch(t -> tag.key().location().getPath().contains(t))).toList(); + //? } elif >=1.18.2 { + /*List> itemTags = Registry.ITEM.getTags().map(Pair::getSecond).filter(tag -> tags.stream().anyMatch(t -> tag.key().location().getPath().contains(t))).toList(); + *///? } else { + /*List> itemTags = ItemTags.getAllTags().getAllTags().entrySet().stream() + .filter(entry -> tags.stream().anyMatch(t -> entry.getKey().toString().contains(t))) + .map(Map.Entry::getValue).collect(Collectors.toList()); + *///? } + searching = original.stream().filter(item -> { + //? if >=1.21.11 { + Optional> opt = BuiltInRegistries.ITEM.getResourceKey(item); + if (opt.isEmpty()) return false; + Identifier rl = opt.get().identifier(); + //? } elif >=1.19.4 { + /*Optional> opt = BuiltInRegistries.ITEM.getResourceKey(item); + if (opt.isEmpty()) return false; + Identifier rl = opt.get().location(); + *///? } else { + /*Optional> opt = Registry.ITEM.getResourceKey(item); + if (!opt.isPresent()) return false; + Identifier rl = opt.get().location(); + *///? } + boolean matchmod = mods.isEmpty(), matchtag = tags.isEmpty(), matcharg = false; + for (String mod : mods) + matchmod = matchmod || rl.getNamespace().toLowerCase().contains(mod); + //? if >=1.18.2 { + for (HolderSet.Named itemTag : itemTags) + matchtag = matchtag || itemTag.stream().anyMatch(tagItem -> tagItem.value() == item); + //? } else + //matchtag = matchtag || itemTags.stream().anyMatch(tag -> tag.contains(item)); + for (String arg : paths) + matcharg = matcharg || rl.getPath().contains(arg); + return matchmod && matchtag && matcharg; + }).collect(Collectors.toList()); + maxPage = (int) Math.ceil(original.size() / (double) max); + if (page > maxPage - 1) page = Math.max(0, maxPage - 1); + }); + Button add = ScreenHelper.makeButton(this.width / 2 - 75, 60, 72, 20, AutoFish.getTranslatableComponent("gui.superfilterscreen.openfilter"), button -> ScreenHelper.showScreen(new FilterSelectionScreen(this))); + Button done = ScreenHelper.makeButton(this.width / 2 + 3, 60, 72, 20, AutoFish.getTranslatableComponent("gui.superfilterscreen.done"), button -> ScreenHelper.showScreen(parent)); + previous = ScreenHelper.makeButton(this.width / 2 - 100, 60, 20, 20, AutoFish.getLiteralComponent("<"), button -> { if (page > 0) page--; }); + previous.visible = false; + next = ScreenHelper.makeButton(this.width / 2 + 80, 60, 20, 20, AutoFish.getLiteralComponent(">"), button -> { if (page < maxPage - 1) page++; }); + next.visible = false; + //? if <=1.16.5 { + /*this.children.add(search); + addButton(add); + addButton(done); + addButton(previous); + addButton(next); + *///? } else { + addRenderableWidget(search); + addRenderableWidget(add); + addRenderableWidget(done); + addRenderableWidget(previous); + addRenderableWidget(next); + //? } + } + + @Override + //? if >=26.1 { + public void extractRenderState(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float partialTicks) { + super.extractRenderState(graphics, mouseX, mouseY, partialTicks); + graphics.centeredText(this.font, this.title, this.width / 2, 20, -1); + //? } elif >=1.20.1 { + /*public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { + super.render(graphics, mouseX, mouseY, partialTicks); + graphics.drawCenteredString(this.font, this.title, this.width / 2, 20, -1); + *///? } else { + /*public void render(PoseStack poseStack, int mouseX, int mouseY, float partialTicks) { + this.renderBackground(poseStack); + super.render(poseStack, mouseX, mouseY, partialTicks); + drawCenteredString(poseStack, this.font, this.title, this.width / 2, 20, -1); + *///? } + Item[] items = searching.toArray(new Item[0]); + for (int i = page * max; i < Math.min((page + 1) * max, searching.size()); i++) { + Item item = items[i]; + int h = (i % max) / (max / 3); + int k = (i % max) % (max / 3); + ItemStack stack = ItemStack.EMPTY; + if (item != null) stack = new ItemStack(item); + //? if >=26.1 { + if (!stack.isEmpty()) graphics.item(stack, (reducedWidth * h / 3) + 15, (reducedHeight * k / (max / 3)) + 90); + graphics.text(this.font, stack.getDisplayName().getString(), ((reducedWidth * h / 3) + 45), ((reducedHeight * k / (max / 3)) + 95), 0xFFFFFFFF); + //? } elif >=1.20.1 { + /*if (!stack.isEmpty()) graphics.renderItem(stack, (reducedWidth * h / 3) + 15, (reducedHeight * k / (max / 3)) + 90); + graphics.drawString(this.font, stack.getDisplayName().getString(), ((reducedWidth * h / 3) + 45), ((reducedHeight * k / (max / 3)) + 95), 0xFFFFFFFF); + *///? } elif >=1.19.4 { + /*if (!stack.isEmpty()) itemRenderer.renderGuiItem(poseStack, stack, (reducedWidth * h / 3) + 15, (reducedHeight * k / (max / 3)) + 90); + drawString(poseStack, this.font, stack.getDisplayName().getString(), ((reducedWidth * h / 3) + 45), ((reducedHeight * k / (max / 3)) + 95), 0xFFFFFFFF); + *///? } else { + /*if (!stack.isEmpty()) itemRenderer.renderGuiItem(stack, (reducedWidth * h / 3) + 15, (reducedHeight * k / (max / 3)) + 90); + drawString(poseStack, this.font, stack.getDisplayName().getString(), ((reducedWidth * h / 3) + 45), ((reducedHeight * k / (max / 3)) + 95), 0xFFFFFFFF); + *///? } + } + //? if >=26.1 { + search.extractRenderState(graphics, mouseX, mouseY, partialTicks); + //? } elif >=1.20.1 { + //search.render(graphics, mouseX, mouseY, partialTicks); + //? } else + //search.render(poseStack, mouseX, mouseY, partialTicks); + } + + @Override + public boolean shouldCloseOnEsc() { + return false; + } + + @Override + //? if >=1.21.11 { + public boolean keyPressed(KeyEvent ev) { + if (ev.key() == ScreenHelper.KEY_ESCAPE) ScreenHelper.showScreen(parent); + return super.keyPressed(ev); + } + //? } else { + /*public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + if (keyCode == ScreenHelper.KEY_ESCAPE) ScreenHelper.showScreen(parent); + return super.keyPressed(keyCode, scanCode, modifiers); + } + *///? } + + @Override + public boolean isPauseScreen() { + return false; + } +} diff --git a/common/src/main/java/in/northwestw/autofish/handler/AutoFishHandler.java b/common/src/main/java/in/northwestw/autofish/handler/AutoFishHandler.java new file mode 100644 index 0000000..1818cd7 --- /dev/null +++ b/common/src/main/java/in/northwestw/autofish/handler/AutoFishHandler.java @@ -0,0 +1,289 @@ +package in.northwestw.autofish.handler; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import in.northwestw.autofish.AutoFish; +import in.northwestw.autofish.config.Config; +import in.northwestw.autofish.config.gui.ScreenHelper; +import in.northwestw.autofish.config.gui.SettingsScreen; +import in.northwestw.autofish.keybind.KeyBinds; +import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.MultiPlayerGameMode; +import net.minecraft.client.player.LocalPlayer; +//? if >=1.19.4 { +import net.minecraft.core.registries.BuiltInRegistries; +//? } else +//import net.minecraft.core.Registry; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.Identifier; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.FishingRodItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec3; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +public class AutoFishHandler { + private static final List shouldDrop = Lists.newArrayList(); + private static boolean processingDrop, pendingReelIn, pendingRecast, lastTickFishing, afterDrop; + private static int dropCd, rodSlot; + private static long tick, checkTick; + private static final Map itemsBeforeFished = Maps.newHashMap(); + + public static void onKeyInput() { + Minecraft minecraft = Minecraft.getInstance(); + LocalPlayer player = minecraft.player; + if (KeyBinds.autofish.consumeClick()) { + Config.setAutoFish(!Config.autoFish); + if (player != null) sendOverlayMessage(player, "autofish", Config.autoFish); + } else if (KeyBinds.rodprotect.consumeClick()) { + Config.setRodProtect(!Config.rodProtect); + if (player != null) sendOverlayMessage(player, "rodprotect", Config.rodProtect); + } else if (KeyBinds.autoreplace.consumeClick()) { + Config.setAutoReplace(!Config.autoReplace); + if (player != null) sendOverlayMessage(player, "autoreplace", Config.autoReplace); + } else if (KeyBinds.itemfilter.consumeClick()) { + Config.enableFilter(!Config.allFilters); + if (player != null) sendOverlayMessage(player, "itemfilter", Config.allFilters); + } else if (KeyBinds.settings.consumeClick()) + ScreenHelper.showScreen(new SettingsScreen()); + } + + public static void onPlayerTick(final Player player) { + if (Minecraft.getInstance().player == null) return; + if (!player.getUUID().equals(Minecraft.getInstance().player.getUUID())) return; + if (checkTick > 0) checkTick--; + else { + checkTick = Config.checkInterval; + if (!pendingRecast) { + if (player.fishing == null) recast(player); + else if (player.fishing.getDeltaMovement().lengthSqr() == 0) pendingReelIn = true; + } + } + if (afterDrop) { + if (tick == 0 && rodSlot != -1) { + //? if >=1.21.11 { + player.getInventory().setSelectedSlot(rodSlot); + //? } elif >=1.17.1 { + /*player.getInventory().selected = rodSlot; + *///? } else + //player.inventory.selected = rodSlot; + rodSlot = -1; + } + tick++; + if (tick > 2) { + afterDrop = false; + tick = 0; + } + return; + } + if (pendingReelIn) { + tick++; + if (tick >= Config.reelInDelay) { + reelIn(player); + tick = 0; + pendingReelIn = false; + } + return; + } + if (processingDrop) { + if (dropCd > 0) dropCd--; + dropItem(player); + if (shouldDrop.isEmpty()) { + processingDrop = false; + afterDrop = true; + } + return; + } + if (pendingRecast) { + tick++; + if (tick >= Config.recastDelay) { + checkItem(player); + if (processingDrop) { + tick = 0; + return; + } + recast(player); + tick = 0; + pendingRecast = false; + } + return; + } + if (!Config.autoFish || player.fishing == null) return; + Vec3 vector = player.fishing.getDeltaMovement(); + double x = vector.x(); + double y = vector.y(); + double z = vector.z(); + //? if >=1.20.1 { + Level level = player.level(); + //? } else + //Level level = player.level; + if (y < -0.075 && !level.getFluidState(player.fishing.blockPosition()).isEmpty() && x == 0 && z == 0) + pendingReelIn = true; + } + + private static void reelIn(Player player) { + if (!Config.autoFish) return; + InteractionHand hand = findHandOfRod(player); + if (hand == null) return; + //? if >=1.21.11 { + List items = player.getInventory().getNonEquipmentItems(); + //? } elif >=1.17.1 { + /*List items = player.getInventory().items; + *///? } else + //List items = player.inventory.items; + items.forEach(stack -> { + //? if >=1.19.4 { + Identifier rl = BuiltInRegistries.ITEM.getKey(stack.getItem()); + //? } else + //Identifier rl = Registry.ITEM.getKey(stack.getItem()); + //? if >=26.1 { + itemsBeforeFished.put(rl.toString(), itemsBeforeFished.getOrDefault(rl, 0) + stack.count()); + //? } else + //itemsBeforeFished.put(rl.toString(), itemsBeforeFished.getOrDefault(rl.toString(), 0) + stack.getCount()); + }); + click(player, hand, Minecraft.getInstance().gameMode); + ItemStack fishingRod = player.getItemInHand(hand); + boolean needReplace = false; + if (fishingRod.getMaxDamage() - fishingRod.getDamageValue() < 2) + if (Config.autoReplace) needReplace = true; + else return; + else if (fishingRod.getMaxDamage() - fishingRod.getDamageValue() < 3 && !player.isCreative() && Config.rodProtect) + if (Config.autoReplace) needReplace = true; + else { + Config.autoFish = false; + sendOverlayMessage(player, "autofish", Config.autoFish); + return; + } + if (needReplace) { + AutoFish.LOGGER.info("Fishing rod broke. Finding replacement..."); + boolean found = false; + for (int i = 0; i < 9; i++) { + //? if >=1.21.11 { + if (i == player.getInventory().getSelectedSlot()) continue; + ItemStack stack = player.getInventory().getItem(i); + //? } elif >=1.17.1 { + /*if (i == player.getInventory().selected) continue; + ItemStack stack = player.getInventory().getItem(i); + *///? } else { + /*if (i == player.inventory.selected) continue; + ItemStack stack = player.inventory.getItem(i); + *///? } + if (stack.getItem() instanceof FishingRodItem) { + if (Config.rodProtect && stack.getMaxDamage() - stack.getDamageValue() < 2) continue; + AutoFish.LOGGER.info("Found fishing rod for replacement"); + //? if >=1.21.11 { + player.getInventory().setSelectedSlot(i); + //? } elif >=1.17.1 { + /*player.getInventory().selected = i; + *///? } else + //player.inventory.selected = i; + found = true; + break; + } + } + if (!found) return; + } + pendingRecast = true; + } + + private static void recast(Player player) { + if (!Config.autoFish) return; + InteractionHand hand = findHandOfRod(player); + if (hand == null) return; + ItemStack fishingRod = player.getItemInHand(hand); + if (fishingRod.isEmpty()) return; + click(player, hand, Minecraft.getInstance().gameMode); + } + + private static void checkItem(Player player) { + if (!itemsBeforeFished.isEmpty()) { + //? if >=1.21.11 { + List items = player.getInventory().getNonEquipmentItems(); + //? } elif >=1.17.1 { + /*List items = player.getInventory().items; + *///? } else + //List items = player.inventory.items; + for (String name : Config.filter) { + //? if >=1.21.1 { + Identifier rl = Identifier.parse(name); + //? } else + //Identifier rl = new Identifier(name); + //? if >=1.19.4 { + Optional opt = BuiltInRegistries.ITEM.getOptional(rl); + //? } else + //Optional opt = Registry.ITEM.getOptional(rl); + if (!opt.isPresent()) continue; + Item item = opt.get(); + int newCount = items.stream().filter(stack -> stack.getItem().equals(item)).mapToInt(ItemStack::getCount).reduce(Integer::sum).orElse(0); + int oldCount = itemsBeforeFished.getOrDefault(rl.toString(), 0); + int diff = newCount - oldCount; + for (int ii = 0; ii < diff; ii++) shouldDrop.add(item); + } + itemsBeforeFished.clear(); + if (!shouldDrop.isEmpty()) { + processingDrop = true; + //? if >=1.21.11 { + rodSlot = player.getInventory().getSelectedSlot(); + //? } elif >=1.17.1 { + /*rodSlot = player.getInventory().selected; + *///? } else + //rodSlot = player.inventory.selected; + } + } + } + + private static void dropItem(Player player) { + if (dropCd != 10 && dropCd != 0) return; + Item item = shouldDrop.get(0); + if (dropCd == 10) { + ((LocalPlayer) player).drop(false); + shouldDrop.remove(item); + return; + } + for (int ii = 0; ii < 9; ii++) { + //? if >=1.21.11 { + if (!player.getInventory().getItem(ii).getItem().equals(item)) continue; + player.getInventory().setSelectedSlot(ii); + //? } elif >=1.17.1 { + /*if (!player.getInventory().getItem(ii).getItem().equals(item)) continue; + player.getInventory().selected = ii; + *///? } else { + /*if (!player.inventory.getItem(ii).getItem().equals(item)) continue; + player.inventory.selected = ii; + *///? } + dropCd = 20; + return; + } + // if item cannot be found in hotbar, just ignore it + shouldDrop.remove(item); + } + + private static void click(Player player, InteractionHand hand, MultiPlayerGameMode controller) { + if (controller == null) return; + //? if >=1.19.2 { + controller.useItem(player, hand); + //? } else + //controller.useItem(player, player.level, hand); + } + + private static InteractionHand findHandOfRod(Player player) { + if (player.getMainHandItem().getItem() instanceof FishingRodItem) return InteractionHand.MAIN_HAND; + else if (player.getOffhandItem().getItem() instanceof FishingRodItem) return InteractionHand.OFF_HAND; + else return null; + } + + private static void sendOverlayMessage(Player player, String key, boolean state) { + Component component = AutoFish.getTranslatableComponent("toggle." + key, AutoFish.getTranslatableComponent("toggle.enable." + state).withStyle(state ? ChatFormatting.GREEN : ChatFormatting.RED)); + //? if >=26.1 { + player.sendOverlayMessage(component); + //? } else + //player.displayClientMessage(component, true); + } +} \ No newline at end of file diff --git a/common/src/main/java/in/northwestw/autofish/keybind/KeyBinds.java b/common/src/main/java/in/northwestw/autofish/keybind/KeyBinds.java new file mode 100644 index 0000000..55113e4 --- /dev/null +++ b/common/src/main/java/in/northwestw/autofish/keybind/KeyBinds.java @@ -0,0 +1,40 @@ +package in.northwestw.autofish.keybind; + +import in.northwestw.autofish.AutoFish; +import net.minecraft.client.KeyMapping; +//? if >=1.21.11 { +import net.minecraft.resources.Identifier; +//? } +//? if >=1.19.2 { +import org.lwjgl.glfw.GLFW; +//? } + +public class KeyBinds { + //? if >=1.19.2 { + private static final int KEY_MINUS = GLFW.GLFW_KEY_MINUS; + private static final int KEY_BACKSLASH = GLFW.GLFW_KEY_BACKSLASH; + private static final int KEY_RIGHT_BRACKET = GLFW.GLFW_KEY_RIGHT_BRACKET; + private static final int KEY_K = GLFW.GLFW_KEY_K; + private static final int KEY_APOSTROPHE = GLFW.GLFW_KEY_APOSTROPHE; + //? } else { + /*private static final int KEY_MINUS = 45; + private static final int KEY_BACKSLASH = 92; + private static final int KEY_RIGHT_BRACKET = 93; + private static final int KEY_K = 75; + private static final int KEY_APOSTROPHE = 39; + *///? } + + public static KeyMapping autofish, rodprotect, autoreplace, settings, itemfilter; + + static { + //? if >= 1.21.11 { + KeyMapping.Category cat = KeyMapping.Category.register(Identifier.fromNamespaceAndPath(AutoFish.MOD_ID, "autofish")); + //? } else + //String cat = "key.categories.autofish"; + autofish = new KeyMapping(AutoFish.getTranslatableComponent("key.autofish.autofish").getString(), KEY_MINUS, cat); + rodprotect = new KeyMapping(AutoFish.getTranslatableComponent("key.autofish.rodprotect").getString(), KEY_BACKSLASH, cat); + autoreplace = new KeyMapping(AutoFish.getTranslatableComponent("key.autofish.autoreplace").getString(), KEY_RIGHT_BRACKET, cat); + settings = new KeyMapping(AutoFish.getTranslatableComponent("key.autofish.settings").getString(), KEY_K, cat); + itemfilter = new KeyMapping(AutoFish.getTranslatableComponent("key.autofish.itemfilter").getString(), KEY_APOSTROPHE, cat); + } +} diff --git a/src/main/resources/assets/forgeautofish/lang/en_us.json b/common/src/main/resources/assets/forgeautofish/lang/en_us.json similarity index 60% rename from src/main/resources/assets/forgeautofish/lang/en_us.json rename to common/src/main/resources/assets/forgeautofish/lang/en_us.json index 22dcf47..377e926 100644 --- a/src/main/resources/assets/forgeautofish/lang/en_us.json +++ b/common/src/main/resources/assets/forgeautofish/lang/en_us.json @@ -1,51 +1,51 @@ -{ - "key.forgeautofish.autofish": "Toggle AutoFish", - "key.forgeautofish.rodprotect": "Toggle Fishing Rod Protection", - "key.forgeautofish.autoreplace": "Toggle Auto Replace", - "key.forgeautofish.settings": "Open Settings", - "key.forgeautofish.itemfilter": "Toggle Item Filter", - "key.categories.forgeautofish": "AutoFish for Forge", - - "toggle.forgeautofish": "%s AutoFish", - "toggle.rodprotect": "%s Fishing Rod Protection", - "toggle.autoreplace": "%s Auto Replace", - "toggle.itemfilter": "%s Item Filter", - - "warning.autoreplace": "Auto Replace Coming Soon", - - "gui.forgeautofish": "AutoFish Configuration", - "gui.forgeautofish.reelindelay": "Reel-In Delay", - "gui.forgeautofish.recastdelay": "Recast Delay", - "gui.forgeautofish.throwdelay": "Throw Delay", - "gui.forgeautofish.checkinterval": "Check Interval", - "gui.forgeautofish.filter": "Item Filter", - "gui.forgeautofish.done": "Done", - - "gui.setreelindelay": "Set Reel-In Delay", - "gui.setreelindelay.reelindelay": "Reel-In Delay", - "gui.setreelindelay.save": "Save Reel-In Delay", - - "gui.setrecastdelay": "Set Recast Delay", - "gui.setrecastdelay.recastdelay": "Recast Delay", - "gui.setrecastdelay.save": "Save Recast Delay", - - "gui.setthrowdelay": "Set Throw Delay", - "gui.setthrowdelay.throwdelay": "Throw Delay", - "gui.setthrowdelay.save": "Save Throw Delay", - - "gui.setcheckinterval": "Set Check Interval", - "gui.setcheckinterval.checkinterval": "Check Interval", - "gui.setcheckinterval.save": "Save Check Interval", - - "gui.superfilterscreen": "Super Item Filter", - "gui.superfilterscreen.openfilter": "Config", - "gui.superfilterscreen.search": "Search", - "gui.superfilterscreen.done": "Done", - - "gui.filterselection": "Item Filter Configuration", - "gui.filterselection.save": "Save", - "gui.filterselection.cancel": "Cancel", - - "toggle.enable.true": "Enabled", - "toggle.enable.false": "Disabled" +{ + "key.autofish.autofish": "Toggle AutoFish", + "key.autofish.rodprotect": "Toggle Fishing Rod Protection", + "key.autofish.autoreplace": "Toggle Auto Replace", + "key.autofish.settings": "Open Settings", + "key.autofish.itemfilter": "Toggle Item Filter", + "key.categories.autofish": "AutoFish for Everyone", + + "toggle.autofish": "%s AutoFish", + "toggle.rodprotect": "%s Fishing Rod Protection", + "toggle.autoreplace": "%s Auto Replace", + "toggle.itemfilter": "%s Item Filter", + + "warning.autoreplace": "Auto Replace Coming Soon", + + "gui.autofish": "AutoFish Configuration", + "gui.autofish.reelindelay": "Reel-In Delay", + "gui.autofish.recastdelay": "Recast Delay", + "gui.autofish.throwdelay": "Throw Delay", + "gui.autofish.checkinterval": "Check Interval", + "gui.autofish.filter": "Item Filter", + "gui.autofish.done": "Done", + + "gui.setreelindelay": "Set Reel-In Delay", + "gui.setreelindelay.reelindelay": "Reel-In Delay", + "gui.setreelindelay.save": "Save Reel-In Delay", + + "gui.setrecastdelay": "Set Recast Delay", + "gui.setrecastdelay.recastdelay": "Recast Delay", + "gui.setrecastdelay.save": "Save Recast Delay", + + "gui.setthrowdelay": "Set Throw Delay", + "gui.setthrowdelay.throwdelay": "Throw Delay", + "gui.setthrowdelay.save": "Save Throw Delay", + + "gui.setcheckinterval": "Set Check Interval", + "gui.setcheckinterval.checkinterval": "Check Interval", + "gui.setcheckinterval.save": "Save Check Interval", + + "gui.superfilterscreen": "Super Item Filter", + "gui.superfilterscreen.openfilter": "Config", + "gui.superfilterscreen.search": "Search", + "gui.superfilterscreen.done": "Done", + + "gui.filterselection": "Item Filter Configuration", + "gui.filterselection.save": "Save", + "gui.filterselection.cancel": "Cancel", + + "toggle.enable.true": "Enabled", + "toggle.enable.false": "Disabled" } \ No newline at end of file diff --git a/src/main/resources/assets/forgeautofish/lang/zh_tw.json b/common/src/main/resources/assets/forgeautofish/lang/zh_tw.json similarity index 58% rename from src/main/resources/assets/forgeautofish/lang/zh_tw.json rename to common/src/main/resources/assets/forgeautofish/lang/zh_tw.json index 6630290..4bd31f5 100644 --- a/src/main/resources/assets/forgeautofish/lang/zh_tw.json +++ b/common/src/main/resources/assets/forgeautofish/lang/zh_tw.json @@ -1,23 +1,23 @@ { - "key.forgeautofish.autofish": "切換 自動釣魚", - "key.forgeautofish.rodprotect": "切換 釣竿保護", - "key.forgeautofish.autoreplace": "切換 自動取代", - "key.forgeautofish.settings": "開啟設定", - "key.forgeautofish.itemfilter": "切換 物品過濾", - "key.categories.forgeautofish": "自動釣魚", - - "toggle.forgeautofish": "%s 自動釣魚", + "key.autofish.autofish": "切換 自動釣魚", + "key.autofish.rodprotect": "切換 釣竿保護", + "key.autofish.autoreplace": "切換 自動取代", + "key.autofish.settings": "開啟設定", + "key.autofish.itemfilter": "切換 物品過濾", + "key.categories.autofish": "自動釣魚", + + "toggle.autofish": "%s 自動釣魚", "toggle.rodprotect": "%s 釣竿保護", "toggle.autoreplace": "%s 自動取代", "toggle.itemfilter": "%s 物品過濾", "warning.autoreplace": "自動過濾 即將來臨", - "gui.forgeautofish": "自動釣魚設定", - "gui.forgeautofish.reelindelay": "收竿延遲", - "gui.forgeautofish.recastdelay": "投竿延遲", - "gui.forgeautofish.filter": "物品過濾", - "gui.forgeautofish.done": "完成", + "gui.autofish": "自動釣魚設定", + "gui.autofish.reelindelay": "收竿延遲", + "gui.autofish.recastdelay": "投竿延遲", + "gui.autofish.filter": "物品過濾", + "gui.autofish.done": "完成", "gui.setrecastdelay": "投竿延遲設定", "gui.setrecastdelay.recastdelay": "投竿延遲", diff --git a/src/main/resources/forgeautofish.png b/common/src/main/resources/autofish.png similarity index 100% rename from src/main/resources/forgeautofish.png rename to common/src/main/resources/autofish.png diff --git a/src/main/resources/pack.mcmeta b/common/src/main/resources/pack.mcmeta similarity index 100% rename from src/main/resources/pack.mcmeta rename to common/src/main/resources/pack.mcmeta diff --git a/fabric/build.gradle.kts b/fabric/build.gradle.kts new file mode 100644 index 0000000..78dcce7 --- /dev/null +++ b/fabric/build.gradle.kts @@ -0,0 +1,53 @@ +plugins { + id("multiloader-loader") + id("fabric-loom-compat") + kotlin("jvm") version "2.2.0" + id("com.google.devtools.ksp") version "2.2.0-2.0.2" +} + +dependencies { + minecraft("com.mojang:minecraft:${commonMod.mc}") + + if (stonecutter.eval(commonMod.mc, "<=1.21.11")) { + mappings(loom.layered { + officialMojangMappings() + commonMod.depOrNull("parchment")?.let { parchmentVersion -> + parchment("org.parchmentmc.data:parchment-${commonMod.mc}:$parchmentVersion@zip") + } + }) + } + + modImplementation("net.fabricmc:fabric-loader:${commonMod.dep("fabric_loader")}") + + // In older versions, Fabric uses the base Minecraft version for Fabric API. Specify by using {api-ver}+{mc-ver} + if (commonMod.dep("fabric_api").contains("+")) modApi("net.fabricmc.fabric-api:fabric-api:${commonMod.dep("fabric_api")}") + else modApi("net.fabricmc.fabric-api:fabric-api:${commonMod.dep("fabric_api")}+${commonMod.mc}") + + commonMod.depOrNull("modmenu")?.let { modMenuVersion -> + modImplementation("com.terraformersmc:modmenu:${modMenuVersion}") + } +} + +loom { + runs { + getByName("client") { + client() + configName = "Fabric Client" + ideConfigGenerated(true) + runDirectory = rootProject.layout.projectDirectory.dir("runs/client") + } + getByName("server") { + server() + configName = "Fabric Server" + ideConfigGenerated(true) + runDirectory = rootProject.layout.projectDirectory.dir("runs/server") + } + } + + if (stonecutter.eval(commonMod.mc, "<=1.21.11")) { + mixin { + useLegacyMixinAp = true + defaultRefmapName = "${mod.id}.refmap.json" + } + } +} \ No newline at end of file diff --git a/fabric/gradle.properties b/fabric/gradle.properties new file mode 100644 index 0000000..fcdea26 --- /dev/null +++ b/fabric/gradle.properties @@ -0,0 +1 @@ +loader=fabric \ No newline at end of file diff --git a/fabric/src/main/java/in/northwestw/autofish/AutoFishFabric.java b/fabric/src/main/java/in/northwestw/autofish/AutoFishFabric.java new file mode 100644 index 0000000..39de37e --- /dev/null +++ b/fabric/src/main/java/in/northwestw/autofish/AutoFishFabric.java @@ -0,0 +1,33 @@ +package in.northwestw.autofish; + +import in.northwestw.autofish.handler.AutoFishHandler; +import in.northwestw.autofish.keybind.KeyBinds; +import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +//? if >=26.1 { +import net.fabricmc.fabric.api.client.keymapping.v1.KeyMappingHelper; +//? } else +//import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; + +public class AutoFishFabric implements ModInitializer { + + @Override + public void onInitialize() { + //? if >=26.1 { + KeyMappingHelper.registerKeyMapping(KeyBinds.autofish); + KeyMappingHelper.registerKeyMapping(KeyBinds.rodprotect); + KeyMappingHelper.registerKeyMapping(KeyBinds.autoreplace); + KeyMappingHelper.registerKeyMapping(KeyBinds.settings); + KeyMappingHelper.registerKeyMapping(KeyBinds.itemfilter); + //? } else { + /*KeyBindingHelper.registerKeyBinding(KeyBinds.autofish); + KeyBindingHelper.registerKeyBinding(KeyBinds.rodprotect); + KeyBindingHelper.registerKeyBinding(KeyBinds.autoreplace); + KeyBindingHelper.registerKeyBinding(KeyBinds.settings); + KeyBindingHelper.registerKeyBinding(KeyBinds.itemfilter); + *///? } + + ClientTickEvents.END_CLIENT_TICK.register(client -> AutoFishHandler.onKeyInput()); + ClientTickEvents.START_CLIENT_TICK.register(client -> AutoFishHandler.onPlayerTick(client.player)); + } +} diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..fcb5f06 --- /dev/null +++ b/fabric/src/main/resources/fabric.mod.json @@ -0,0 +1,30 @@ +{ + "schemaVersion": 1, + "id": "${modId}", + "version": "${modVersion}", + "name": "${modName}", + "description": "${modDescription}", + "authors": [ + "${modAuthor}" + ], + "contact": { + "homepage": "${modGitHub}", + "sources": "${modGitHub}", + "issues": "${modGitHub}/issues" + }, + "license": "${modLicense}", + "icon": "${modId}.png", + "environment": "*", + "entrypoints": { + "main": [ + "in.northwestw.autofish.AutoFishFabric" + ] + }, + "depends": { + "fabricloader": ">=${fabricLoaderVersion}", + "fabric-api": "*", + "minecraft": ">=${minMinecraftVersion}", + "java": ">=${javaVersion}" + } +} + \ No newline at end of file diff --git a/forge/build.gradle.kts b/forge/build.gradle.kts new file mode 100644 index 0000000..743185c --- /dev/null +++ b/forge/build.gradle.kts @@ -0,0 +1,73 @@ +plugins { + id("multiloader-loader") + id("net.minecraftforge.gradle") version "[7.0.17,8)" + id("net.minecraftforge.renamer") version "1.1.2" + kotlin("jvm") version "2.2.0" + id("com.google.devtools.ksp") version "2.2.0-2.0.2" +} + +// Version will be added after renaming +if (stonecutter.eval(commonMod.mc, "<=1.20.4")) version = "${commonMod.version}-${stonecutterBuild.current.version}" + +minecraft { + if (commonMod.depOrNull("parchment") != null) mappings("parchment", "${commonMod.mc}-${commonMod.dep("parchment")}") + else mappings("official", commonMod.mc) + + val at = rootProject.file("src/${loader}/resources/META-INF/accesstransformer.cfg") + if (at.exists()) { + accessTransformer.from(at) + } + + runs { + configureEach { + systemProperty("eventbus.api.strictRuntimeChecks", "true") + systemProperty("forge.enabledGameTestNamespaces", commonMod.id) + } + + register("client") { + workingDir = rootProject.file("runs/client") + } + + register("server") { + workingDir = rootProject.file("runs/server") + args("--nogui") + } + + register("gameTestServer") { + workingDir = rootProject.file("runs/gameTestServer") + } + + register("data") { + workingDir = rootProject.file("runs/data") + args("--mod", commonMod.id, "--all", "--output", rootProject.file("src/${loader}/generated/resources"), "--existing", rootProject.file("src/${loader}/resources")) + } + } +} + +sourceSets.main { + resources.srcDir("src/generated/resources") +} + +repositories { + minecraft.mavenizer(this) // In Kotlin, it = this + maven(fg.forgeMaven) + maven(fg.minecraftLibsMaven) +} + +dependencies { + implementation(minecraft.dependency("net.minecraftforge:forge:${commonMod.mc}-${commonMod.dep("forge")}")) +} + +// The renamer plugin is required for Forge <= 1.20.4 +if (stonecutter.eval(commonMod.mc, "<=1.20.4")) { + tasks.register("deleteJar") { + description = "Deletes the JAR before renaming" + delete(layout.buildDirectory.file("libs/${commonMod.id}-${version}.jar")) + } + + renamer.classes("renameJar", tasks.named("jar")) { + map.from(minecraft.dependency.toSrgFile) + archiveClassifier = loader + finalizedBy("deleteJar") + } +} \ No newline at end of file diff --git a/forge/gradle.properties b/forge/gradle.properties new file mode 100644 index 0000000..0079a24 --- /dev/null +++ b/forge/gradle.properties @@ -0,0 +1 @@ +loader=forge \ No newline at end of file diff --git a/forge/src/main/java/in/northwestw/autofish/AutoFishForge.java b/forge/src/main/java/in/northwestw/autofish/AutoFishForge.java new file mode 100644 index 0000000..09942e2 --- /dev/null +++ b/forge/src/main/java/in/northwestw/autofish/AutoFishForge.java @@ -0,0 +1,83 @@ +package in.northwestw.autofish; + +import in.northwestw.autofish.handler.AutoFishHandler; +import in.northwestw.autofish.keybind.KeyBinds; +import net.minecraftforge.client.event.InputEvent; +//? if >=1.19.2 { +import net.minecraftforge.client.event.RegisterKeyMappingsEvent; +//? } elif >=1.18.2 { +/*import net.minecraftforge.client.ClientRegistry; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; +*///? } elif >=1.17.1 { +/*import net.minecraftforge.fmlclient.registry.ClientRegistry; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; +*///? } else { +/*import net.minecraftforge.fml.client.registry.ClientRegistry; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; +*///? } +import net.minecraftforge.event.TickEvent; +//? if >=1.21.11 { +import net.minecraftforge.eventbus.api.listener.SubscribeEvent; +//? } else +//import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.LogicalSide; +import net.minecraftforge.fml.common.Mod; + +@Mod(AutoFish.MOD_ID) +public class AutoFishForge { + + public AutoFishForge() { + } + + @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE) + public static class ForgeEvents { + //? if >=1.19.2 { + @SubscribeEvent + public static void registerKeyMappings(RegisterKeyMappingsEvent event) { + event.register(KeyBinds.autofish); + event.register(KeyBinds.rodprotect); + event.register(KeyBinds.autoreplace); + event.register(KeyBinds.settings); + event.register(KeyBinds.itemfilter); + } + //? } + + @SubscribeEvent + //? if >=1.19.2 { + public static void inputKey(InputEvent.Key event) { + //? } else + //public static void inputKey(InputEvent.KeyInputEvent event) { + AutoFishHandler.onKeyInput(); + } + + @SubscribeEvent + //? if >=1.21.1 { + public static void playerTickPre(TickEvent.PlayerTickEvent.Pre event) { + //? } else { + /*public static void playerTickPre(TickEvent.PlayerTickEvent event) { + if (event.phase != TickEvent.Phase.START) return; + *///? } + //? if >=1.21.11 { + if (event.side() != LogicalSide.CLIENT) return; + AutoFishHandler.onPlayerTick(event.player()); + //? } else { + /*if (event.side != LogicalSide.CLIENT) return; + AutoFishHandler.onPlayerTick(event.player); + *///? } + } + } + + //? if <1.19 { + /*@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) + public static class ModEvents { + @SubscribeEvent + public static void setupClient(FMLClientSetupEvent event) { + ClientRegistry.registerKeyBinding(KeyBinds.autofish); + ClientRegistry.registerKeyBinding(KeyBinds.rodprotect); + ClientRegistry.registerKeyBinding(KeyBinds.autoreplace); + ClientRegistry.registerKeyBinding(KeyBinds.settings); + ClientRegistry.registerKeyBinding(KeyBinds.itemfilter); + } + } + *///? } +} \ No newline at end of file diff --git a/forge/src/main/resources/META-INF/mods.toml b/forge/src/main/resources/META-INF/mods.toml new file mode 100644 index 0000000..8f81f49 --- /dev/null +++ b/forge/src/main/resources/META-INF/mods.toml @@ -0,0 +1,27 @@ +modLoader = "javafml" #mandatory +loaderVersion = "*" #mandatory This is typically bumped every Minecraft version by Forge. See https://files.minecraftforge.net/ for a list of versions. +license = "${modLicense}" # Review your options at https://choosealicense.com/. +#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional +#clientSideOnly=true #optional +[[mods]] #mandatory +modId = "${modId}" #mandatory +version = "${modVersion}" #mandatory +displayName = "${modName}" #mandatory +#updateJSONURL="https://change.me.example.invalid/updates.json" #optional (see https://mcforge.readthedocs.io/en/latest/gettingstarted/autoupdate/) +#displayURL="https://change.me.to.your.mods.homepage.example.invalid/" #optional (displayed in the mod UI) +logoFile = "${modId}.png" #optional +credits = "" #optional +authors = "${modAuthor}" #optional +description = '''${modDescription}''' #mandatory (Supports multiline text) +[[dependencies.${modId}]] #optional +modId = "forge" #mandatory +mandatory = true #mandatory +versionRange = "[${forgeVersion},)" #mandatory +ordering = "NONE" # The order that this dependency should load in relation to your mod, required to be either 'BEFORE' or 'AFTER' if the dependency is not mandatory +side = "BOTH" # Side this dependency is applied on - 'BOTH', 'CLIENT' or 'SERVER' +[[dependencies.${modId}]] +modId = "minecraft" +mandatory = true +versionRange = "[${minMinecraftVersion},)" +ordering = "NONE" +side = "BOTH" \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index eec1f62..511f63c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,48 +1,46 @@ -# Sets default memory used for gradle commands. Can be overridden by user or command line properties. -# This is required to provide enough memory for the Minecraft decompilation process. -org.gradle.jvmargs=-Xmx3G -org.gradle.daemon=false -org.gradle.java.home=/usr/lib/jvm/java-21-graalvm-ee - -mc_version=1.21.1 -forge_version=52.0.9 -build_mc_version=1.21.x - -#read more on this at https://github.com/neoforged/NeoGradle/blob/NG_7.0/README.md#apply-parchment-mappings -# you can also find the latest versions at: https://parchmentmc.org/docs/getting-started -neogradle.subsystems.parchment.minecraftVersion=1.21 -neogradle.subsystems.parchment.mappingsVersion=2024.07.28 -# Environment Properties -# You can find the latest versions here: https://projects.neoforged.net/neoforged/neoforge -# The Minecraft version must agree with the Neo version to get a valid artifact -minecraft_version=1.21 -# The Minecraft version range can use any release version of Minecraft as bounds. -# Snapshots, pre-releases, and release candidates are not guaranteed to sort properly -# as they do not follow standard versioning conventions. -minecraft_version_range=[1.21,1.21.1) -# The Neo version must agree with the Minecraft version to get a valid artifact -neo_version=21.0.167 -# The Neo version range can use any version of Neo as bounds -neo_version_range=[21.0.0-beta,) -# The loader version range can only use the major version of FML as bounds -loader_version_range=[4,) - -## Mod Properties - -# The unique mod identifier for the mod. Must be lowercase in English locale. Must fit the regex [a-z][a-z0-9_]{1,63} -# Must match the String constant located in the main mod class annotated with @Mod. -mod_id=forgeautofish -# The human-readable display name for the mod. -mod_name=AutoFish for NeoForge -# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. -mod_license=GPLv3 -# The mod version. See https://semver.org/ -mod_version=7.1.0 -# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. -# This should match the base package used for the mod sources. -# See https://maven.apache.org/guides/mini/guide-naming-conventions.html -mod_group_id=in.northwestw.forgeautofish -# The authors of the mod. This is a simple text string that is used for display purposes in the mod list. -mod_authors=NorthWestWind -# The description of the mod. This is a simple multiline text string that is used for display purposes in the mod list. -mod_description=I like playing survival, but fishing is a boring activity...\nTherefore, I made this mod!\nNow you can AFK Fish like no one else!\n\nNote that this is my first mod, so there might be bugs. \ No newline at end of file +# Dev +org.gradle.jvmargs=-Xmx2G + +# Mod - All field required. +mod.name=AutoFish for Everyone +mod.id=autofish +mod.group=in.northwestw.in +mod.version=8.0.1 +mod.author=NorthWestWind +mod.description=I like playing survival, but fishing is a boring activity...\nTherefore, I made this mod!\nNow you can AFK Fish like no one else! +mod.license=GPL-3.0 +mod.github=https://github.com/North-West-Wind/AutoFish + +# Stonecutter +stonecutter_enabled_platforms=fabric, neoforge, forge +stonecutter_enabled_common_versions=26.2, 26.1.2, 1.21.11, 1.21.1, 1.20.1, 1.19.4, 1.19.2, 1.18.2, 1.17.1, 1.16.5 +stonecutter_enabled_fabric_versions=26.2, 26.1.2, 1.21.11, 1.21.1, 1.20.1, 1.19.4, 1.19.2, 1.18.2, 1.17.1, 1.16.5 +stonecutter_enabled_forge_versions=26.2, 26.1.2, 1.21.11, 1.21.1, 1.20.1, 1.19.4, 1.19.2, 1.18.2, 1.17.1 +stonecutter_enabled_neoforge_versions=26.2, 26.1.2, 1.21.11, 1.21.1 + +# The below field are intentionally left blank, +# to edit, please edit gradle.properties for each versions. + +# Java +java.version= + +# Minecraft +minecraft_version= +min_minecraft_version= + +# Mappings +deps.parchment= + +# Fabric https://fabricmc.net/versions.html +deps.fabric_loader= +deps.fabric_api= + +# Forge +deps.forge= + +# NeoForge https://projects.neoforged.net/neoforged/neoforge +deps.neoforge= +deps.neoform= + +# Dependencies +deps.modmenu= \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index c1962a7..b1b8ef5 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 d951fac..b52fb7e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,9 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-bin.zip +networkTimeout=10000 +retries=0 +retryBackOffMs=500 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index c53aefa..b9bb139 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -32,10 +34,10 @@ # Busybox and similar reduced shells will NOT work, because this script # requires all of these POSIX shell features: # * functions; -# * expansions $var, ${var}, ${var:-default}, ${var+SET}, -# ${var#prefix}, ${var%suffix}, and $( cmd ); -# * compound commands having a testable exit status, especially case; -# * various built-in commands including command, set, and ulimit. +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». # # Important for patching: # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,13 +82,11 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -114,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -133,22 +132,29 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -165,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -193,18 +198,27 @@ if "$cygwin" || "$msys" ; then done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/gradlew.bat b/gradlew.bat index ac1b06f..24c62d5 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,89 +1,82 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables, and ensure extensions are enabled +setlocal EnableExtensions + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +"%COMSPEC%" /c exit 1 + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +"%COMSPEC%" /c exit 1 + +:execute +@rem Setup the command line + + + +@rem Execute Gradle +@rem endlocal doesn't take effect until after the line is parsed and variables are expanded +@rem which allows us to clear the local environment before executing the java command +endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel + +:exitWithErrorLevel +@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts +"%COMSPEC%" /c exit %ERRORLEVEL% diff --git a/neoforge/build.gradle.kts b/neoforge/build.gradle.kts new file mode 100644 index 0000000..02a0901 --- /dev/null +++ b/neoforge/build.gradle.kts @@ -0,0 +1,40 @@ +plugins { + id("multiloader-loader") + id("net.neoforged.moddev") version "2.0.141" + kotlin("jvm") version "2.2.0" + id("com.google.devtools.ksp") version "2.2.0-2.0.2" +} + +neoForge { + version = commonMod.dep("neoforge") + + runs { + register("client") { + client() + ideName = "NeoForge Client (${project.path})" + gameDirectory = rootProject.layout.projectDirectory.dir("runs/client") + } + register("server") { + server() + ideName = "NeoForge Server (${project.path})" + gameDirectory = rootProject.layout.projectDirectory.dir("runs/server") + } + } + + commonMod.depOrNull("parchment")?.let { + parchment { + mappingsVersion = it + minecraftVersion = commonMod.mc + } + } + + mods { + register(commonMod.id) { + sourceSet(sourceSets.main.get()) + } + } +} + +sourceSets.main { + resources.srcDir("src/generated/resources") +} \ No newline at end of file diff --git a/neoforge/gradle.properties b/neoforge/gradle.properties new file mode 100644 index 0000000..cb4f12e --- /dev/null +++ b/neoforge/gradle.properties @@ -0,0 +1 @@ +loader=neoforge \ No newline at end of file diff --git a/neoforge/src/main/java/in/northwestw/autofish/AutoFishNeoForge.java b/neoforge/src/main/java/in/northwestw/autofish/AutoFishNeoForge.java new file mode 100644 index 0000000..a3f59d7 --- /dev/null +++ b/neoforge/src/main/java/in/northwestw/autofish/AutoFishNeoForge.java @@ -0,0 +1,44 @@ +package in.northwestw.autofish; + +import in.northwestw.autofish.handler.AutoFishHandler; +import in.northwestw.autofish.keybind.KeyBinds; +import net.minecraft.client.player.LocalPlayer; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.LogicalSide; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.fml.common.Mod; +import net.neoforged.neoforge.client.event.InputEvent; +import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent; +import net.neoforged.neoforge.event.tick.PlayerTickEvent; + +@Mod(AutoFish.MOD_ID) +public class AutoFishNeoForge { + + public AutoFishNeoForge(IEventBus eventBus) { + } + + @EventBusSubscriber + public static class ModEvents { + @SubscribeEvent + public static void registerKeyMappings(RegisterKeyMappingsEvent event) { + event.register(KeyBinds.autofish); + event.register(KeyBinds.rodprotect); + event.register(KeyBinds.autoreplace); + event.register(KeyBinds.settings); + event.register(KeyBinds.itemfilter); + } + + @SubscribeEvent + public static void inputKey(InputEvent.Key event) { + AutoFishHandler.onKeyInput(); + } + + @SubscribeEvent + public static void playerTickPre(PlayerTickEvent.Pre event) { + if (!(event.getEntity() instanceof LocalPlayer)) return; + AutoFishHandler.onPlayerTick(event.getEntity()); + } + } +} \ No newline at end of file diff --git a/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/neoforge/src/main/resources/META-INF/neoforge.mods.toml new file mode 100644 index 0000000..3a018c3 --- /dev/null +++ b/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -0,0 +1,26 @@ +modLoader = "javafml" #mandatory +loaderVersion = "*" #mandatory +license = "${modLicense}" # Review your options at https://choosealicense.com/. +#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional +[[mods]] #mandatory +modId = "${modId}" #mandatory +version = "${modVersion}" #mandatory +displayName = "${modName}" #mandatory +#updateJSONURL="https://change.me.example.invalid/updates.json" #optional (see https://docs.neoforged.net/docs/misc/updatechecker/) +#displayURL="https://change.me.to.your.mods.homepage.example.invalid/" #optional (displayed in the mod UI) +logoFile="${modId}.png" #optional +credits="" #optional +authors = "${modAuthor}" #optional +description = '''${modDescription}''' #mandatory (Supports multiline text) +[[dependencies.${modId}]] #optional +modId = "neoforge" #mandatory +type="required" #mandatory (Can be one of "required", "optional", "incompatible" or "discouraged") +versionRange = "[${neoForgeVersion},)" #mandatory +ordering = "NONE" # The order that this dependency should load in relation to your mod, required to be either 'BEFORE' or 'AFTER' if the dependency is not mandatory +side = "BOTH" # Side this dependency is applied on - 'BOTH', 'CLIENT' or 'SERVER' +[[dependencies.${modId}]] +modId = "minecraft" +type="required" #mandatory (Can be one of "required", "optional", "incompatible" or "discouraged") +versionRange = "[${minMinecraftVersion},)" +ordering = "NONE" +side = "BOTH" diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index fd1434c..0000000 --- a/settings.gradle +++ /dev/null @@ -1,11 +0,0 @@ -pluginManagement { - repositories { - mavenLocal() - gradlePluginPortal() - maven { url = 'https://maven.neoforged.net/releases' } - } -} - -plugins { - id 'org.gradle.toolchains.foojay-resolver-convention' version '0.8.0' -} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..992d2c2 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,45 @@ +pluginManagement { + repositories { + gradlePluginPortal() + mavenCentral() + maven("https://maven.fabricmc.net/") + maven("https://maven.neoforged.net/releases/") + maven("https://maven.minecraftforge.net") + maven("https://maven.kikugie.dev/snapshots") + maven("https://maven.kikugie.dev/releases") + } +} + +plugins { + id("dev.kikugie.stonecutter") version "0.9.5" + id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0" +} + +val commonVersions = providers.gradleProperty("stonecutter_enabled_common_versions").orNull?.split(",")?.map { it.trim() } ?: emptyList() +val fabricVersions = providers.gradleProperty("stonecutter_enabled_fabric_versions").orNull?.split(",")?.map { it.trim() } ?: emptyList() +val forgeVersions = providers.gradleProperty("stonecutter_enabled_forge_versions").orNull?.split(",")?.map { it.trim() } ?: emptyList() +val neoforgeVersions = providers.gradleProperty("stonecutter_enabled_neoforge_versions").orNull?.split(",")?.map { it.trim() } ?: emptyList() +val dists = mapOf( + "common" to commonVersions, + "forge" to forgeVersions, + "fabric" to fabricVersions, + "neoforge" to neoforgeVersions +) +val uniqueVersions = dists.values.flatten().distinct() + +stonecutter { + kotlinController = true + centralScript = "build.gradle.kts" + + create(rootProject) { + versions(*uniqueVersions.toTypedArray()) + + dists.forEach { (branchName, branchVersions) -> + branch(branchName) { + versions(*branchVersions.toTypedArray()) + } + } + } +} + +rootProject.name = "autofish" \ No newline at end of file diff --git a/src/main/java/in/northwestw/forgeautofish/config/Config.java b/src/main/java/in/northwestw/forgeautofish/config/Config.java deleted file mode 100644 index c2f7816..0000000 --- a/src/main/java/in/northwestw/forgeautofish/config/Config.java +++ /dev/null @@ -1,113 +0,0 @@ -package in.northwestw.forgeautofish.config; - -import com.electronwill.nightconfig.core.file.CommentedFileConfig; -import com.electronwill.nightconfig.core.io.WritingMode; -import com.google.common.collect.Lists; -import in.northwestw.forgeautofish.AutoFish; -import in.northwestw.forgeautofish.handler.AutoFishHandler; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.EventBusSubscriber; -import net.neoforged.fml.event.config.ModConfigEvent; -import net.neoforged.neoforge.common.ModConfigSpec; - -import java.io.File; -import java.util.List; - -public class Config { - - public static final long[] RECAST_DELAY_RANGE = { 20L, 1L, 600L }; - public static final long[] REEL_IN_DELAY_RANGE = { 0L, 0L, 600L }; - public static final long[] THROW_DELAY_RANGE = { 10L, 5L, 600L }; - public static final long[] CHECK_INTERVAL_RANGE = { 200L, 20L, 72000L }; - - private static final ModConfigSpec.Builder CLIENT_BUILDER = new ModConfigSpec.Builder(); - public static final ModConfigSpec CLIENT; - - public static ModConfigSpec.LongValue RECAST_DELAY, REEL_IN_DELAY, THROW_DELAY, CHECK_INTERVAL; - public static ModConfigSpec.BooleanValue AUTO_FISH, ROD_PROTECT, AUTO_REPLACE, ALL_FILTERS; - public static ModConfigSpec.ConfigValue> FILTER, PRIORITIZE; - - static { - init(); - CLIENT = CLIENT_BUILDER.build(); - } - - public static void init() { - RECAST_DELAY = CLIENT_BUILDER.comment("Sets the delay before casting the fishing rod again (in ticks).", "Minimum is 1 tick to allow Auto Replace to take effect.").defineInRange("forgeautofish.recastdelay", RECAST_DELAY_RANGE[0], RECAST_DELAY_RANGE[1], RECAST_DELAY_RANGE[2]); - REEL_IN_DELAY = CLIENT_BUILDER.comment("Sets the delay before reeling in the fishing rod after catching a fish (in ticks).").defineInRange("forgeautofish.reelindelay", REEL_IN_DELAY_RANGE[0], REEL_IN_DELAY_RANGE[1], REEL_IN_DELAY_RANGE[2]); - THROW_DELAY = CLIENT_BUILDER.comment("Sets the delay between each item throw in filtering (in ticks).").defineInRange("forgeautofish.throwdelay", THROW_DELAY_RANGE[0], THROW_DELAY_RANGE[1], THROW_DELAY_RANGE[2]); - CHECK_INTERVAL = CLIENT_BUILDER.comment("Sets the interval for checking if the rod is thrown or stuck (in ticks).", "If not, throw/recast it.").defineInRange("forgeautofish.checkinterval", CHECK_INTERVAL_RANGE[0], CHECK_INTERVAL_RANGE[1], CHECK_INTERVAL_RANGE[2]); - AUTO_FISH = CLIENT_BUILDER.comment("Sets the default status of the Auto Fish feature").define("forgeautofish.autofish", true); - ROD_PROTECT = CLIENT_BUILDER.comment("Sets whether should the mod be turned off when the fishing rod is about to break.").define("forgeautofish.rodprotect", true); - AUTO_REPLACE = CLIENT_BUILDER.comment("Does nothing currently").define("forgeautofish.autoreplace", true); - ALL_FILTERS = CLIENT_BUILDER.comment("Toggles the entire item filter").define("forgeautofish.filter.all", true); - FILTER = CLIENT_BUILDER.comment("Sets item filter").define("forgeautofish.filter.items", Lists.newArrayList("minecraft:rotten_flesh")); - PRIORITIZE = CLIENT_BUILDER.comment("Puts these items to top of filter.").define("forgeautofish.filter.prioritize", Lists.newArrayList("minecraft:cod", "minecraft:salmon", "minecraft:tropical_fish", "minecraft:pufferfish", "minecraft:bow", "minecraft:enchanted_book", "minecraft:fishing_rod", "minecraft:name_tag", "minecraft:nautilus_shell", "minecraft:saddle", "minecraft:lily_pad", "minecraft:bowl", "minecraft:leather", "minecraft:leather_boots", "minecraft:rotten_flesh", "minecraft:stick", "minecraft:string", "minecraft:water_bottle", "minecraft:bone", "minecraft:ink_sac", "minecraft:tripwire_hook", "minecraft:bamboo", "minecraft:cocoa_beans")); - } - - public static void onLoad(final ModConfigEvent event) { - AutoFishHandler.loadSettingsFromConfig(); - } - - public static void setRecastDelay(long recastDelay) { - AutoFishHandler.recastDelay = recastDelay; - Config.RECAST_DELAY.set(recastDelay); - Config.RECAST_DELAY.save(); - AutoFish.LOGGER.info("Set Recast Delay: " + recastDelay); - } - - public static void setAutoFish(boolean autoFish) { - AutoFishHandler.autofish = autoFish; - Config.AUTO_FISH.set(autoFish); - Config.AUTO_FISH.save(); - AutoFish.LOGGER.info("Toggle AutoFish: " + autoFish); - } - - public static void setRodProtect(boolean rodProtect) { - AutoFishHandler.rodprotect = rodProtect; - Config.ROD_PROTECT.set(rodProtect); - Config.ROD_PROTECT.save(); - AutoFish.LOGGER.info("Toggle Rod Protect: " + rodProtect); - } - - public static void setAutoReplace(boolean autoReplace) { - AutoFishHandler.autoreplace = autoReplace; - Config.AUTO_REPLACE.set(autoReplace); - Config.AUTO_REPLACE.save(); - AutoFish.LOGGER.info("Toggle Auto Replace: " + autoReplace); - } - - public static void enableFilter(boolean filter) { - AutoFishHandler.itemfilter = filter; - ALL_FILTERS.set(filter); - ALL_FILTERS.save(); - AutoFish.LOGGER.info("Toggle Filter: " + filter); - } - - public static void setFILTER(List list) { - Config.FILTER.set(list); - Config.FILTER.save(); - AutoFish.LOGGER.info("Received new Filter"); - } - - public static void setReelInDelay(long reelInDelay) { - AutoFishHandler.reelInDelay = reelInDelay; - Config.REEL_IN_DELAY.set(reelInDelay); - Config.REEL_IN_DELAY.save(); - AutoFish.LOGGER.info("Set Reel In Delay: " + reelInDelay); - } - - public static void setThrowDelay(long throwDelay) { - AutoFishHandler.throwDelay = throwDelay; - Config.THROW_DELAY.set(throwDelay); - Config.THROW_DELAY.save(); - AutoFish.LOGGER.info("Set Throw Delay: " + throwDelay); - } - - public static void setCheckInterval(long checkInterval) { - AutoFishHandler.checkInterval = checkInterval; - Config.CHECK_INTERVAL.set(checkInterval); - Config.CHECK_INTERVAL.save(); - AutoFish.LOGGER.info("Set Check Interval: " + checkInterval); - } -} diff --git a/src/main/java/in/northwestw/forgeautofish/config/gui/CheckIntervalScreen.java b/src/main/java/in/northwestw/forgeautofish/config/gui/CheckIntervalScreen.java deleted file mode 100644 index be2abc2..0000000 --- a/src/main/java/in/northwestw/forgeautofish/config/gui/CheckIntervalScreen.java +++ /dev/null @@ -1,86 +0,0 @@ -package in.northwestw.forgeautofish.config.gui; - -import in.northwestw.forgeautofish.AutoFish; -import in.northwestw.forgeautofish.config.Config; -import in.northwestw.forgeautofish.handler.AutoFishHandler; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.components.Button; -import net.minecraft.client.gui.components.EditBox; -import net.minecraft.client.gui.screens.Screen; -import org.lwjgl.glfw.GLFW; - -import java.util.regex.Pattern; - -public class CheckIntervalScreen extends Screen { - private final Screen parent; - private EditBox checkInterval; - - protected CheckIntervalScreen(Screen parent) { - super(AutoFish.getTranslatableComponent("gui.setcheckinterval")); - this.parent = parent; - } - - @Override - protected void init() { - checkInterval = new EditBox(this.font, this.width / 2 - 75, this.height / 2 - 25, 150, 20, AutoFish.getTranslatableComponent("gui.setcheckinterval.checkinterval")) { - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (button == GLFW.GLFW_MOUSE_BUTTON_2) this.setValue(""); - return super.mouseClicked(mouseX, mouseY, button); - } - }; - checkInterval.setValue(Long.toString(AutoFishHandler.checkInterval)); - addRenderableWidget(checkInterval); - Button save = new Button.Builder(AutoFish.getTranslatableComponent("gui.setcheckinterval.save"), button -> { - if (!isNumeric(checkInterval.getValue())) checkInterval.setValue(Long.toString(AutoFishHandler.checkInterval)); - else { - long delay = Long.parseLong(checkInterval.getValue()); - if (delay < Config.CHECK_INTERVAL_RANGE[1] || delay > Config.CHECK_INTERVAL_RANGE[2]) checkInterval.setValue(Long.toString(AutoFishHandler.checkInterval)); - else { - Config.setCheckInterval(delay); - Minecraft.getInstance().setScreen(parent); - } - } - }).pos(this.width / 2 - 75, this.height / 2).size(150, 20).build(); - addRenderableWidget(save); - } - - @Override - public void tick() { - //checkInterval.tick(); - super.tick(); - } - - private static final Pattern pattern = Pattern.compile("-?\\d+(\\.\\d+)?"); - public static boolean isNumeric(String strNum) { - if (strNum == null) { - return false; - } - return pattern.matcher(strNum).matches(); - } - - @Override - public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { - this.renderBackground(graphics, mouseX, mouseY, partialTicks); - super.render(graphics, mouseX, mouseY, partialTicks); - graphics.drawCenteredString(this.font, this.title, this.width / 2, 20, -1); - this.checkInterval.render(graphics, mouseX, mouseY, partialTicks); - } - - @Override - public boolean shouldCloseOnEsc() { - return false; - } - - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (keyCode == GLFW.GLFW_KEY_ESCAPE) Minecraft.getInstance().setScreen(parent); - return super.keyPressed(keyCode, scanCode, modifiers); - } - - @Override - public boolean isPauseScreen() { - return false; - } -} diff --git a/src/main/java/in/northwestw/forgeautofish/config/gui/FilterSelectionScreen.java b/src/main/java/in/northwestw/forgeautofish/config/gui/FilterSelectionScreen.java deleted file mode 100644 index a6d4601..0000000 --- a/src/main/java/in/northwestw/forgeautofish/config/gui/FilterSelectionScreen.java +++ /dev/null @@ -1,180 +0,0 @@ -package in.northwestw.forgeautofish.config.gui; - -import com.google.common.collect.Lists; -import in.northwestw.forgeautofish.AutoFish; -import in.northwestw.forgeautofish.config.Config; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.components.Button; -import net.minecraft.client.gui.components.EditBox; -import net.minecraft.client.gui.screens.Screen; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.core.registries.Registries; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.TagKey; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import org.lwjgl.glfw.GLFW; - -import java.awt.*; -import java.util.List; -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -public class FilterSelectionScreen extends Screen { - private final Screen parent; - private EditBox search; - private final Collection original = BuiltInRegistries.ITEM.stream().toList(); - private Collection searching; - private final Set selected = new HashSet<>(Config.FILTER.get().stream().map(string -> BuiltInRegistries.ITEM.getOptional(ResourceLocation.parse(string))).filter(Optional::isPresent).map(Optional::get).collect(Collectors.toList())); - private int page, maxPage = (int) Math.ceil(original.size() / 300.0), max = 300; - private boolean clickProcessed = true; - private double clickX, clickY; - private Button previous, next; - int reducedHeight; - int reducedWidth; - - public FilterSelectionScreen(Screen parent) { - super(AutoFish.getTranslatableComponent("gui.filterselection")); - this.parent = parent; - } - - @Override - protected void init() { - reducedHeight = this.height - 90; - reducedWidth = this.width - 30; - max = /* (int) Math.round(300 * (reducedWidth / 550.0 + reducedHeight / 330.0) / 2.0) */ 300; - maxPage = (int) Math.ceil(original.size() / (double) max); - searching = original; - search = new EditBox(this.font, this.width / 2 - 75, 35, 150, 20, AutoFish.getTranslatableComponent("gui.superfilterscreen.search")) { - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (button == GLFW.GLFW_MOUSE_BUTTON_2) this.setValue(""); - return super.mouseClicked(mouseX, mouseY, button); - } - }; - search.setResponder(s -> { - String[] args = s.split("/ +/"); - String[] mods = Arrays.stream(args).filter(s1 -> s1.startsWith("@")).toArray(String[]::new); - String[] tags = Arrays.stream(args).filter(s1 -> s1.startsWith("#")).toArray(String[]::new); - String[] finalArgs = Arrays.stream(args).filter(s1 -> !s1.startsWith("@") && !s1.startsWith("#")).toArray(String[]::new);; - searching = original.stream().filter(item -> { - ResourceLocation rl = BuiltInRegistries.ITEM.getKey(item); - boolean matchmod = mods.length < 1, matchtag = tags.length < 1, matcharg = finalArgs.length < 1; - for (String mod : mods) { - mod = mod.toLowerCase().substring(1); - if (!rl.equals(BuiltInRegistries.ITEM.getDefaultKey())) matchmod = rl.getNamespace().toLowerCase().contains(mod); - } - for (String tag : tags) - matchtag = BuiltInRegistries.ITEM.getOrCreateTag(TagKey.create(Registries.ITEM, ResourceLocation.parse(tag.toLowerCase().substring(1)))).stream().anyMatch(it -> it == item); - for (String arg : finalArgs) { - arg = arg.toLowerCase(); - if (!rl.equals(BuiltInRegistries.ITEM.getDefaultKey())) matcharg = rl.getPath().contains(arg) || item.getDescription().getString().contains(arg); - } - return matchmod && matchtag && matcharg; - }).collect(Collectors.toList()); - maxPage = (int) Math.ceil(searching.size() / (double) max); - if (page > maxPage - 1) page = maxPage - 1; - }); - addRenderableWidget(search); - Button add = new Button.Builder(AutoFish.getTranslatableComponent("gui.filterselection.save"), button -> { - List items = selected.stream().map(item -> Objects.requireNonNullElse(BuiltInRegistries.ITEM.getKey(item), item).toString()).collect(Collectors.toList()); - Config.setFILTER(items); - Minecraft.getInstance().setScreen(parent); - }).pos(this.width / 2 - 75, 60).size(72, 20).build(); - addRenderableWidget(add); - Button done = new Button.Builder(AutoFish.getTranslatableComponent("gui.filterselection.cancel"), button -> Minecraft.getInstance().setScreen(parent)).pos(this.width / 2 + 3, 60).size(72, 20).build(); - addRenderableWidget(done); - previous = new Button.Builder(AutoFish.getLiteralComponent("<"), button -> { if (page > 0) page--; }).pos(this.width / 2 - 100, 60).size(20, 20).build(); - previous.visible = false; - addRenderableWidget(previous); - next = new Button.Builder(AutoFish.getLiteralComponent(">"), button -> { if (page < maxPage - 1) page++; }).pos(this.width / 2 + 80, 60).size(20, 20).build(); - next.visible = false; - addRenderableWidget(next); - } - - @Override - public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { - this.renderBackground(graphics, mouseX, mouseY, partialTicks); - super.render(graphics, mouseX, mouseY, partialTicks); - graphics.drawCenteredString(this.font, this.title, this.width / 2, 20, -1);Collection searchingCopy = Lists.newArrayList(); - Collection prioritized = searching.stream().filter(item -> { - ResourceLocation rl = BuiltInRegistries.ITEM.getKey(item); - if (rl.equals(BuiltInRegistries.ITEM.getDefaultKey())) return false; - boolean pri = Config.PRIORITIZE.get().contains(rl.toString()); - if (!pri) searchingCopy.add(item); - return pri; - }).toList(); - Item[] items = Stream.concat(prioritized.stream(), searchingCopy.stream()).toArray(Item[]::new); - if (items.length > 0 && page >= 0) { - for (int i = page * max; i < Math.min((page + 1) * max, searching.size()); i++) { - Item item = items[i]; - int h = (i % max) / (max / 30); - int k = (i % max) % (max / 30); - int x = getXPos(h, reducedWidth); - int y = getYPos(k, reducedHeight); - ItemStack stack = new ItemStack(item); - if (!stack.isEmpty()) { - graphics.renderItem(stack, x, y); - if (!clickProcessed && isMouseInRange(clickX, clickY, x, y, x+16, y+16)) { - if (selected.contains(item)) selected.remove(item); - else selected.add(item); - clickProcessed = true; - } - if (selected.contains(item)) graphics.fillGradient(x - 2, y - 2, x + 18, y + 18, Color.GREEN.getRGB(), Color.GREEN.getRGB()); - else if (isMouseInRange(mouseX, mouseY, x, y,x + 16, y + 16)) graphics.fillGradient(x - 2, y - 2, x + 18, y + 18, Color.LIGHT_GRAY.getRGB(), Color.LIGHT_GRAY.getRGB()); - if (isMouseInRange(mouseX, mouseY, x, y,x + 16, y + 16)) graphics.renderTooltip(this.font, stack, mouseX, mouseY); - } - } - } - search.render(graphics, mouseX, mouseY, partialTicks); - } - - private boolean isMouseInRange(double mouseX, double mouseY, int x1, int y1, int x2, int y2) { - return mouseX > x1 && mouseX < x2 && mouseY > y1 && mouseY < y2; - } - - private int getXPos(int h, int width) { - return (width * h / 30) + 15; - } - - private int getYPos(int k, int height) { - return ((height * k / (max / 30)) + 90); - } - - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (keyCode == GLFW.GLFW_KEY_ESCAPE) { - if (!search.isFocused()) Minecraft.getInstance().setScreen(parent); - else search.setFocused(false); - } - return super.keyPressed(keyCode, scanCode, modifiers); - } - - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - clickX = mouseX; - clickY = mouseY; - clickProcessed = false; - return super.mouseClicked(mouseX, mouseY, button); - } - - @Override - public boolean shouldCloseOnEsc() { - return false; - } - - @Override - public void tick() { - //search.tick(); - super.tick(); - previous.visible = page >= 1; - next.visible = page < maxPage - 1; - } - - @Override - public boolean isPauseScreen() { - return false; - } -} diff --git a/src/main/java/in/northwestw/forgeautofish/config/gui/RecastDelayScreen.java b/src/main/java/in/northwestw/forgeautofish/config/gui/RecastDelayScreen.java deleted file mode 100644 index 73d2e02..0000000 --- a/src/main/java/in/northwestw/forgeautofish/config/gui/RecastDelayScreen.java +++ /dev/null @@ -1,86 +0,0 @@ -package in.northwestw.forgeautofish.config.gui; - -import in.northwestw.forgeautofish.AutoFish; -import in.northwestw.forgeautofish.config.Config; -import in.northwestw.forgeautofish.handler.AutoFishHandler; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.components.Button; -import net.minecraft.client.gui.components.EditBox; -import net.minecraft.client.gui.screens.Screen; -import org.lwjgl.glfw.GLFW; - -import java.util.regex.Pattern; - -public class RecastDelayScreen extends Screen { - private final Screen parent; - private EditBox recastDelay; - - protected RecastDelayScreen(Screen parent) { - super(AutoFish.getTranslatableComponent("gui.setrecastdelay")); - this.parent = parent; - } - - @Override - protected void init() { - recastDelay = new EditBox(this.font, this.width / 2 - 75, this.height / 2 - 25, 150, 20, AutoFish.getTranslatableComponent("gui.setrecastdelay.recastdelay")) { - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (button == GLFW.GLFW_MOUSE_BUTTON_2) this.setValue(""); - return super.mouseClicked(mouseX, mouseY, button); - } - }; - recastDelay.setValue(Long.toString(AutoFishHandler.recastDelay)); - addRenderableWidget(recastDelay); - Button save = new Button.Builder(AutoFish.getTranslatableComponent("gui.setrecastdelay.save"), button -> { - if (!isNumeric(recastDelay.getValue())) recastDelay.setValue(Long.toString(AutoFishHandler.recastDelay)); - else { - long delay = Long.parseLong(recastDelay.getValue()); - if (delay < Config.RECAST_DELAY_RANGE[1] || delay > Config.RECAST_DELAY_RANGE[2]) recastDelay.setValue(Long.toString(AutoFishHandler.recastDelay)); - else { - Config.setRecastDelay(delay); - Minecraft.getInstance().setScreen(parent); - } - } - }).pos(this.width / 2 - 75, this.height / 2).size(150, 20).build(); - addRenderableWidget(save); - } - - @Override - public void tick() { - //recastDelay.tick(); - super.tick(); - } - - private static final Pattern pattern = Pattern.compile("-?\\d+(\\.\\d+)?"); - public static boolean isNumeric(String strNum) { - if (strNum == null) { - return false; - } - return pattern.matcher(strNum).matches(); - } - - @Override - public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { - this.renderBackground(graphics, mouseX, mouseY, partialTicks); - super.render(graphics, mouseX, mouseY, partialTicks); - graphics.drawCenteredString(this.font, this.title, this.width / 2, 20, -1); - this.recastDelay.render(graphics, mouseX, mouseY, partialTicks); - } - - @Override - public boolean shouldCloseOnEsc() { - return false; - } - - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (keyCode == GLFW.GLFW_KEY_ESCAPE) Minecraft.getInstance().setScreen(parent); - return super.keyPressed(keyCode, scanCode, modifiers); - } - - @Override - public boolean isPauseScreen() { - return false; - } -} diff --git a/src/main/java/in/northwestw/forgeautofish/config/gui/ReelInDelayScreen.java b/src/main/java/in/northwestw/forgeautofish/config/gui/ReelInDelayScreen.java deleted file mode 100644 index 470e518..0000000 --- a/src/main/java/in/northwestw/forgeautofish/config/gui/ReelInDelayScreen.java +++ /dev/null @@ -1,86 +0,0 @@ -package in.northwestw.forgeautofish.config.gui; - -import in.northwestw.forgeautofish.AutoFish; -import in.northwestw.forgeautofish.config.Config; -import in.northwestw.forgeautofish.handler.AutoFishHandler; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.components.Button; -import net.minecraft.client.gui.components.EditBox; -import net.minecraft.client.gui.screens.Screen; -import org.lwjgl.glfw.GLFW; - -import java.util.regex.Pattern; - -public class ReelInDelayScreen extends Screen { - private final Screen parent; - private EditBox reelInDelay; - - protected ReelInDelayScreen(Screen parent) { - super(AutoFish.getTranslatableComponent("gui.setreelindelay")); - this.parent = parent; - } - - @Override - protected void init() { - reelInDelay = new EditBox(this.font, this.width / 2 - 75, this.height / 2 - 25, 150, 20, AutoFish.getTranslatableComponent("gui.setreelindelay.reelindelay")) { - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (button == GLFW.GLFW_MOUSE_BUTTON_2) this.setValue(""); - return super.mouseClicked(mouseX, mouseY, button); - } - }; - reelInDelay.setValue(Long.toString(AutoFishHandler.reelInDelay)); - addRenderableWidget(reelInDelay); - Button save = new Button.Builder(AutoFish.getTranslatableComponent("gui.setreelindelay.save"), button -> { - if (!isNumeric(reelInDelay.getValue())) reelInDelay.setValue(Long.toString(AutoFishHandler.recastDelay)); - else { - long delay = Long.parseLong(reelInDelay.getValue()); - if (delay < Config.REEL_IN_DELAY_RANGE[1] || delay > Config.REEL_IN_DELAY_RANGE[2]) reelInDelay.setValue(Long.toString(AutoFishHandler.reelInDelay)); - else { - Config.setReelInDelay(delay); - Minecraft.getInstance().setScreen(parent); - } - } - }).pos(this.width / 2 - 75, this.height / 2).size(150, 20).build(); - addRenderableWidget(save); - } - - @Override - public void tick() { - //reelInDelay.tick(); - super.tick(); - } - - private static final Pattern pattern = Pattern.compile("-?\\d+(\\.\\d+)?"); - public static boolean isNumeric(String strNum) { - if (strNum == null) { - return false; - } - return pattern.matcher(strNum).matches(); - } - - @Override - public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { - this.renderBackground(graphics, mouseX, mouseY, partialTicks); - super.render(graphics, mouseX, mouseY, partialTicks); - graphics.drawCenteredString(this.font, this.title, this.width / 2, 20, -1); - this.reelInDelay.render(graphics, mouseX, mouseY, partialTicks); - } - - @Override - public boolean shouldCloseOnEsc() { - return false; - } - - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (keyCode == GLFW.GLFW_KEY_ESCAPE) Minecraft.getInstance().setScreen(parent); - return super.keyPressed(keyCode, scanCode, modifiers); - } - - @Override - public boolean isPauseScreen() { - return false; - } -} diff --git a/src/main/java/in/northwestw/forgeautofish/config/gui/SettingsScreen.java b/src/main/java/in/northwestw/forgeautofish/config/gui/SettingsScreen.java deleted file mode 100644 index 8fb729c..0000000 --- a/src/main/java/in/northwestw/forgeautofish/config/gui/SettingsScreen.java +++ /dev/null @@ -1,46 +0,0 @@ -package in.northwestw.forgeautofish.config.gui; - -import in.northwestw.forgeautofish.AutoFish; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.components.Button; -import net.minecraft.client.gui.screens.Screen; - -public class SettingsScreen extends Screen { - private static final int WIDTH = 150, HEIGHT = 20, MARGIN = 5; - - public SettingsScreen() { - super(AutoFish.getTranslatableComponent("gui.forgeautofish")); - } - - @Override - public boolean isPauseScreen() { - return false; - } - - @Override - protected void init() { - Button.Builder[] builders = { - new Button.Builder(AutoFish.getTranslatableComponent("gui.forgeautofish.recastdelay"), button -> Minecraft.getInstance().setScreen(new RecastDelayScreen(this))), - new Button.Builder(AutoFish.getTranslatableComponent("gui.forgeautofish.reelindelay"), button -> Minecraft.getInstance().setScreen(new ReelInDelayScreen(this))), - new Button.Builder(AutoFish.getTranslatableComponent("gui.forgeautofish.throwdelay"), button -> Minecraft.getInstance().setScreen(new ThrowDelayScreen(this))), - new Button.Builder(AutoFish.getTranslatableComponent("gui.forgeautofish.checkinterval"), button -> Minecraft.getInstance().setScreen(new CheckIntervalScreen(this))), - new Button.Builder(AutoFish.getTranslatableComponent("gui.forgeautofish.filter"), button -> Minecraft.getInstance().setScreen(new SuperFilterScreen(this))) - }; - - for (int ii = 0; ii < builders.length; ii++) { - Button button = builders[ii].pos(this.width / 2 - WIDTH / 2, this.height / 2 + (ii - builders.length / 2) * (HEIGHT + MARGIN)).size(WIDTH, HEIGHT).build(); - addRenderableWidget(button); - } - - Button done = new Button.Builder(AutoFish.getTranslatableComponent("gui.forgeautofish.done"), button -> onClose()).pos(this.width / 2 - 75, this.height - 25).size(150, 20).build(); - addRenderableWidget(done); - } - - @Override - public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { - this.renderBackground(graphics, mouseX, mouseY, partialTicks); - super.render(graphics, mouseX, mouseY, partialTicks); - graphics.drawCenteredString(this.font, this.title, this.width / 2, 20, -1); - } -} diff --git a/src/main/java/in/northwestw/forgeautofish/config/gui/SuperFilterScreen.java b/src/main/java/in/northwestw/forgeautofish/config/gui/SuperFilterScreen.java deleted file mode 100644 index f973c06..0000000 --- a/src/main/java/in/northwestw/forgeautofish/config/gui/SuperFilterScreen.java +++ /dev/null @@ -1,131 +0,0 @@ -package in.northwestw.forgeautofish.config.gui; - -import in.northwestw.forgeautofish.AutoFish; -import in.northwestw.forgeautofish.config.Config; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.components.Button; -import net.minecraft.client.gui.components.EditBox; -import net.minecraft.client.gui.screens.Screen; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.core.registries.Registries; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.TagKey; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import org.lwjgl.glfw.GLFW; - -import java.awt.*; -import java.util.Arrays; -import java.util.Collection; -import java.util.Optional; -import java.util.stream.Collectors; - -public class SuperFilterScreen extends Screen { - private final Screen parent; - private EditBox search; - private Collection original; - private Collection searching; - private int page = 0, maxPage, max = 30; - private Button previous, next; - int reducedHeight; - int reducedWidth; - - protected SuperFilterScreen(Screen parent) { - super(AutoFish.getTranslatableComponent("gui.superfilterscreen")); - this.parent = parent; - } - - @Override - public void tick() { - //search.tick(); - previous.visible = page >= 1; - next.visible = page < maxPage - 1; - } - - @Override - protected void init() { - reducedHeight = this.height - 90; - reducedWidth = this.width - 30; - max = /* (int) Math.round(30 * (reducedWidth / 550.0 + reducedHeight / 330.0) / 2.0) */ 30; - original = Config.FILTER.get().stream().map(string -> BuiltInRegistries.ITEM.getOptional(ResourceLocation.parse(string))).filter(Optional::isPresent).map(Optional::get).collect(Collectors.toList()); - maxPage = (int) Math.ceil(original.size() / (double) max); - searching = original; - search = new EditBox(this.font, this.width / 2 - 75, 35, 150, 20, AutoFish.getTranslatableComponent("gui.superfilterscreen.search")) { - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (button == GLFW.GLFW_MOUSE_BUTTON_2) this.setValue(""); - return super.mouseClicked(mouseX, mouseY, button); - } - }; - search.setResponder(s -> { - String[] args = s.split("/ +/"); - String[] mods = Arrays.stream(args).filter(s1 -> s1.startsWith("@")).toArray(String[]::new); - String[] tags = Arrays.stream(args).filter(s1 -> s1.startsWith("#")).toArray(String[]::new); - String[] finalArgs = Arrays.stream(args).filter(s1 -> !s1.startsWith("@") && !s1.startsWith("#")).toArray(String[]::new);; - searching = original.stream().filter(item -> { - ResourceLocation rl = BuiltInRegistries.ITEM.getKey(item); - boolean matchmod = mods.length < 1, matchtag = tags.length < 1, matcharg = finalArgs.length < 1; - for (String mod : mods) { - mod = mod.toLowerCase().substring(1); - if (!rl.equals(BuiltInRegistries.ITEM.getDefaultKey())) matchmod = rl.getNamespace().toLowerCase().contains(mod); - } - for (String tag : tags) - matchtag = BuiltInRegistries.ITEM.getOrCreateTag(TagKey.create(Registries.ITEM, ResourceLocation.parse(tag.toLowerCase().substring(1)))).stream().anyMatch(it -> it == item); - for (String arg : finalArgs) { - arg = arg.toLowerCase(); - if (!rl.equals(BuiltInRegistries.ITEM.getDefaultKey())) matcharg = rl.getPath().contains(arg) || item.getDescription().getString().contains(arg); - } - return matchmod && matchtag && matcharg; - }).collect(Collectors.toList()); - maxPage = (int) Math.ceil(original.size() / (double) max); - if (page > maxPage - 1) page = maxPage - 1; - }); - addRenderableWidget(search); - Button add = new Button.Builder(AutoFish.getTranslatableComponent("gui.superfilterscreen.openfilter"), button -> Minecraft.getInstance().setScreen(new FilterSelectionScreen(this))).pos(this.width / 2 - 75, 60).size(72, 20).build(); - addRenderableWidget(add); - Button done = new Button.Builder(AutoFish.getTranslatableComponent("gui.superfilterscreen.done"), button -> Minecraft.getInstance().setScreen(parent)).pos(this.width / 2 + 3, 60).size(72, 20).build(); - addRenderableWidget(done); - previous = new Button.Builder(AutoFish.getLiteralComponent("<"), button -> { if (page > 0) page--; }).pos(this.width / 2 - 100, 60).size(20, 20).build(); - previous.visible = false; - addRenderableWidget(previous); - next = new Button.Builder(AutoFish.getLiteralComponent(">"), button -> { if (page < maxPage - 1) page++; }).pos(this.width / 2 + 80, 60).size(20, 20).build(); - next.visible = false; - addRenderableWidget(next); - } - - @Override - public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { - this.renderBackground(graphics, mouseX, mouseY, partialTicks); - super.render(graphics, mouseX, mouseY, partialTicks); - graphics.drawCenteredString(this.font, this.title, this.width / 2, 20, -1); - Item[] items = searching.toArray(new Item[0]); - for (int i = page * max; i < Math.min((page + 1) * max, searching.size()); i++) { - Item item = items[i]; - int h = (i % max) / (max / 3); - int k = (i % max) % (max / 3); - ItemStack stack = ItemStack.EMPTY; - if (item != null) stack = new ItemStack(item); - if (!stack.isEmpty()) graphics.renderItem(stack, (reducedWidth * h / 3) + 15, (reducedHeight * k / (max / 3)) + 90); - graphics.drawString(this.font, stack.getDisplayName().getString(), ((reducedWidth * h / 3) + 45), ((reducedHeight * k / (max / 3)) + 95), Color.WHITE.getRGB()); - //this.font.draw(graphics, stack.getDisplayName().getString(), (float) ((reducedWidth * h / 3) + 45), (float) ((reducedHeight * k / (max / 3)) + 95), Color.WHITE.getRGB()); - } - search.render(graphics, mouseX, mouseY, partialTicks); - } - - @Override - public boolean shouldCloseOnEsc() { - return false; - } - - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (keyCode == GLFW.GLFW_KEY_ESCAPE) Minecraft.getInstance().setScreen(parent); - return super.keyPressed(keyCode, scanCode, modifiers); - } - - @Override - public boolean isPauseScreen() { - return false; - } -} diff --git a/src/main/java/in/northwestw/forgeautofish/config/gui/ThrowDelayScreen.java b/src/main/java/in/northwestw/forgeautofish/config/gui/ThrowDelayScreen.java deleted file mode 100644 index a0f0700..0000000 --- a/src/main/java/in/northwestw/forgeautofish/config/gui/ThrowDelayScreen.java +++ /dev/null @@ -1,86 +0,0 @@ -package in.northwestw.forgeautofish.config.gui; - -import in.northwestw.forgeautofish.AutoFish; -import in.northwestw.forgeautofish.config.Config; -import in.northwestw.forgeautofish.handler.AutoFishHandler; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.components.Button; -import net.minecraft.client.gui.components.EditBox; -import net.minecraft.client.gui.screens.Screen; -import org.lwjgl.glfw.GLFW; - -import java.util.regex.Pattern; - -public class ThrowDelayScreen extends Screen { - private final Screen parent; - private EditBox throwDelay; - - protected ThrowDelayScreen(Screen parent) { - super(AutoFish.getTranslatableComponent("gui.setthrowdelay")); - this.parent = parent; - } - - @Override - protected void init() { - throwDelay = new EditBox(this.font, this.width / 2 - 75, this.height / 2 - 25, 150, 20, AutoFish.getTranslatableComponent("gui.setthrowdelay.throwdelay")) { - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (button == GLFW.GLFW_MOUSE_BUTTON_2) this.setValue(""); - return super.mouseClicked(mouseX, mouseY, button); - } - }; - throwDelay.setValue(Long.toString(AutoFishHandler.throwDelay)); - addRenderableWidget(throwDelay); - Button save = new Button.Builder(AutoFish.getTranslatableComponent("gui.setthrowdelay.save"), button -> { - if (!isNumeric(throwDelay.getValue())) throwDelay.setValue(Long.toString(AutoFishHandler.throwDelay)); - else { - long delay = Long.parseLong(throwDelay.getValue()); - if (delay < Config.THROW_DELAY_RANGE[1] || delay > Config.THROW_DELAY_RANGE[2]) throwDelay.setValue(Long.toString(AutoFishHandler.throwDelay)); - else { - Config.setThrowDelay(delay); - Minecraft.getInstance().setScreen(parent); - } - } - }).pos(this.width / 2 - 75, this.height / 2).size(150, 20).build(); - addRenderableWidget(save); - } - - @Override - public void tick() { - //throwDelay.tick(); - super.tick(); - } - - private static final Pattern pattern = Pattern.compile("-?\\d+(\\.\\d+)?"); - public static boolean isNumeric(String strNum) { - if (strNum == null) { - return false; - } - return pattern.matcher(strNum).matches(); - } - - @Override - public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { - this.renderBackground(graphics, mouseX, mouseY, partialTicks); - super.render(graphics, mouseX, mouseY, partialTicks); - graphics.drawCenteredString(this.font, this.title, this.width / 2, 20, -1); - this.throwDelay.render(graphics, mouseX, mouseY, partialTicks); - } - - @Override - public boolean shouldCloseOnEsc() { - return false; - } - - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (keyCode == GLFW.GLFW_KEY_ESCAPE) Minecraft.getInstance().setScreen(parent); - return super.keyPressed(keyCode, scanCode, modifiers); - } - - @Override - public boolean isPauseScreen() { - return false; - } -} diff --git a/src/main/java/in/northwestw/forgeautofish/handler/AutoFishHandler.java b/src/main/java/in/northwestw/forgeautofish/handler/AutoFishHandler.java deleted file mode 100644 index d817b13..0000000 --- a/src/main/java/in/northwestw/forgeautofish/handler/AutoFishHandler.java +++ /dev/null @@ -1,243 +0,0 @@ -package in.northwestw.forgeautofish.handler; - -import com.google.common.collect.Lists; -import in.northwestw.forgeautofish.AutoFish; -import in.northwestw.forgeautofish.config.Config; -import in.northwestw.forgeautofish.config.gui.SettingsScreen; -import in.northwestw.forgeautofish.keybind.KeyBinds; -import net.minecraft.ChatFormatting; -import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.MultiPlayerGameMode; -import net.minecraft.client.player.LocalPlayer; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.FishingRodItem; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.phys.Vec3; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.EventBusSubscriber; -import net.neoforged.neoforge.client.event.InputEvent; -import net.neoforged.neoforge.event.tick.PlayerTickEvent; - -import javax.annotation.Nullable; -import java.util.List; -import java.util.Optional; - -@EventBusSubscriber(modid = AutoFish.MODID, value = Dist.CLIENT) -public class AutoFishHandler { - public static boolean autofish, rodprotect, autoreplace, itemfilter; - public static long recastDelay, reelInDelay, throwDelay, checkInterval; - private static final List shouldDrop = Lists.newArrayList(); - private static boolean processingDrop, pendingReelIn, pendingRecast, lastTickFishing, afterDrop; - private static int dropCd; - private static long tick, checkTick; - private static List itemsBeforeFished; - private static ItemStack rodStack; - - public static void loadSettingsFromConfig() { - autofish = Config.AUTO_FISH.get(); - rodprotect = Config.ROD_PROTECT.get(); - autoreplace = Config.AUTO_REPLACE.get(); - itemfilter = Config.ALL_FILTERS.get(); - - recastDelay = Config.RECAST_DELAY.get(); - reelInDelay = Config.REEL_IN_DELAY.get(); - throwDelay = Config.THROW_DELAY.get(); - checkInterval = Config.CHECK_INTERVAL.get(); - } - - @SubscribeEvent - public static void onKeyInput(InputEvent.Key e) { - Minecraft minecraft = Minecraft.getInstance(); - LocalPlayer player = minecraft.player; - if (KeyBinds.autofish.consumeClick()) { - Config.setAutoFish(!autofish); - if (player != null) player.displayClientMessage(getText("forgeautofish", autofish), true); - } else if (KeyBinds.rodprotect.consumeClick()) { - Config.setRodProtect(!rodprotect); - if (player != null) player.displayClientMessage(getText("rodprotect", rodprotect), true); - } else if (KeyBinds.autoreplace.consumeClick()) { - Config.setAutoReplace(!autoreplace); - if (player != null) player.displayClientMessage(getText("autoreplace", autoreplace), true); - } else if (KeyBinds.itemfilter.consumeClick()) { - Config.enableFilter(!itemfilter); - if (player != null) - player.displayClientMessage(getText("itemfilter", itemfilter), true); - } else if (KeyBinds.settings.consumeClick()) - minecraft.setScreen(new SettingsScreen()); - } - - @SubscribeEvent - public static void onPlayerTick(final PlayerTickEvent.Pre e) { - if (!e.getEntity().level().isClientSide) return; - Player player = e.getEntity(); - if (!player.getUUID().equals(Minecraft.getInstance().player.getUUID())) return; - if (checkTick > 0) checkTick--; - else { - checkTick = checkInterval; - if (!pendingRecast) { - if (player.fishing == null) recast(player); - else if (player.fishing.getDeltaMovement().lengthSqr() == 0) pendingReelIn = true; - } - } - if (lastTickFishing && player.fishing == null) - itemsBeforeFished = Lists.newArrayList(player.getInventory().items); - lastTickFishing = player.fishing != null; - if (afterDrop) { - if (tick == 0 && rodStack != null) { - player.getInventory().setPickedItem(rodStack); - rodStack = null; - } - tick++; - if (tick > 2) { - afterDrop = false; - tick = 0; - } - return; - } - if (pendingReelIn) { - tick++; - if (tick >= reelInDelay) { - reelIn(player); - tick = 0; - pendingReelIn = false; - } - return; - } - if (processingDrop) { - if (dropCd > 0) dropCd--; - dropItem(player); - if (shouldDrop.size() <= 0) { - processingDrop = false; - afterDrop = true; - } - return; - } - if (pendingRecast) { - tick++; - if (tick >= recastDelay) { - checkItem(player); - if (processingDrop) { - tick = 0; - return; - } - recast(player); - tick = 0; - pendingRecast = false; - } - return; - } - if (!autofish || player.fishing == null) return; - Vec3 vector = player.fishing.getDeltaMovement(); - double x = vector.x(); - double y = vector.y(); - double z = vector.z(); - if (y < -0.075 && !player.level().getFluidState(player.fishing.blockPosition()).isEmpty() && x == 0 && z == 0) - pendingReelIn = true; - } - - private static void reelIn(Player player) { - if (!autofish) return; - InteractionHand hand = findHandOfRod(player); - if (hand == null) return; - click(player, hand, Minecraft.getInstance().gameMode); - ItemStack fishingRod = player.getItemInHand(hand); - boolean needReplace = false; - if (fishingRod.getMaxDamage() - fishingRod.getDamageValue() < 2) - if (autoreplace) needReplace = true; - else return; - else if (fishingRod.getMaxDamage() - fishingRod.getDamageValue() < 3 && !player.isCreative() && rodprotect) - if (autoreplace) needReplace = true; - else { - autofish = false; - player.displayClientMessage(getText("forgeautofish", autofish), true); - return; - } - if (needReplace) { - AutoFish.LOGGER.info("Fishing rod broke. Finding replacement..."); - boolean found = false; - for (int i = 0; i < 9; i++) { - if (i == player.getInventory().selected) continue; - ItemStack stack = player.getInventory().getItem(i); - if (stack.getItem() instanceof FishingRodItem) { - if (rodprotect && stack.getMaxDamage() - stack.getDamageValue() < 2) continue; - AutoFish.LOGGER.info("Found fishing rod for replacement"); - player.getInventory().selected = i; - found = true; - break; - } - } - if (!found) return; - } - pendingRecast = true; - } - - private static void recast(Player player) { - if (!autofish) return; - InteractionHand hand = findHandOfRod(player); - if (hand == null) return; - ItemStack fishingRod = player.getItemInHand(hand); - if (fishingRod.isEmpty()) return; - click(player, hand, Minecraft.getInstance().gameMode); - } - - private static void checkItem(Player player) { - if (itemsBeforeFished != null) { - List items = player.getInventory().items; - for (String name : Config.FILTER.get()) { - ResourceLocation rl = ResourceLocation.parse(name); - Optional item = BuiltInRegistries.ITEM.getOptional(rl); - if (item.isEmpty()) continue; - int newCount = items.stream().filter(stack -> stack.getItem().equals(item.get())).mapToInt(ItemStack::getCount).reduce(Integer::sum).orElse(0); - int oldCount = itemsBeforeFished.stream().filter(stack -> stack.getItem().equals(item.get())).mapToInt(ItemStack::getCount).reduce(Integer::sum).orElse(0); - int diff = newCount - oldCount; - for (int ii = 0; ii < diff; ii++) shouldDrop.add(item.get()); - } - itemsBeforeFished = null; - if (shouldDrop.size() > 0) { - processingDrop = true; - rodStack = player.getMainHandItem(); - } - } - } - - private static void dropItem(Player player) { - if (dropCd == 4 || dropCd == 2 || dropCd == 1) return; - Item item = shouldDrop.get(0); - if (dropCd == 3) { - ((LocalPlayer) player).drop(false); - shouldDrop.remove(item); - return; - } - for (int ii = 0; ii < 9; ii++) { - final ItemStack stack = player.getInventory().items.get(ii); - if (!stack.getItem().equals(item)) continue; - player.getInventory().setPickedItem(stack); - dropCd = 5; - return; - } - // if item cannot be found in hotbar, just ignore it - shouldDrop.remove(item); - } - - private static void click(Player player, InteractionHand hand, @Nullable MultiPlayerGameMode controller) { - if (controller == null) return; - controller.useItem(player, hand); - } - - @Nullable - private static InteractionHand findHandOfRod(Player player) { - if (player.getMainHandItem().getItem() instanceof FishingRodItem) return InteractionHand.MAIN_HAND; - else if (player.getOffhandItem().getItem() instanceof FishingRodItem) return InteractionHand.OFF_HAND; - else return null; - } - - private static Component getText(String key, boolean bool) { - return AutoFish.getTranslatableComponent("toggle." + key, AutoFish.getTranslatableComponent("toggle.enable." + bool).withStyle(bool ? ChatFormatting.GREEN : ChatFormatting.RED)); - } -} \ No newline at end of file diff --git a/src/main/java/in/northwestw/forgeautofish/keybind/KeyBinds.java b/src/main/java/in/northwestw/forgeautofish/keybind/KeyBinds.java deleted file mode 100644 index 696d3c2..0000000 --- a/src/main/java/in/northwestw/forgeautofish/keybind/KeyBinds.java +++ /dev/null @@ -1,25 +0,0 @@ -package in.northwestw.forgeautofish.keybind; - -import in.northwestw.forgeautofish.AutoFish; -import net.minecraft.client.KeyMapping; -import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent; -import org.lwjgl.glfw.GLFW; - -public class KeyBinds { - - public static KeyMapping autofish, rodprotect, autoreplace, settings, itemfilter; - - public static void register(final RegisterKeyMappingsEvent event) { - autofish = new KeyMapping(AutoFish.getTranslatableComponent("key.forgeautofish.autofish").getString(), GLFW.GLFW_KEY_MINUS, "key.categories.forgeautofish"); - rodprotect = new KeyMapping(AutoFish.getTranslatableComponent("key.forgeautofish.rodprotect").getString(), GLFW.GLFW_KEY_BACKSLASH, "key.categories.forgeautofish"); - autoreplace = new KeyMapping(AutoFish.getTranslatableComponent("key.forgeautofish.autoreplace").getString(), GLFW.GLFW_KEY_RIGHT_BRACKET, "key.categories.forgeautofish"); - settings = new KeyMapping(AutoFish.getTranslatableComponent("key.forgeautofish.settings").getString(), GLFW.GLFW_KEY_K, "key.categories.forgeautofish"); - itemfilter = new KeyMapping(AutoFish.getTranslatableComponent("key.forgeautofish.itemfilter").getString(), GLFW.GLFW_KEY_APOSTROPHE, "key.categories.forgeautofish"); - - event.register(autofish); - event.register(rodprotect); - event.register(autoreplace); - event.register(settings); - event.register(itemfilter); - } -} diff --git a/stonecutter.gradle.kts b/stonecutter.gradle.kts new file mode 100644 index 0000000..f068b56 --- /dev/null +++ b/stonecutter.gradle.kts @@ -0,0 +1,19 @@ +val IS_CI = System.getenv("CI") == "true" + +plugins { + id("dev.kikugie.stonecutter") + id("net.neoforged.moddev") version "2.0.141" apply false + id("net.fabricmc.fabric-loom") version "1.17-SNAPSHOT" apply false + id("net.fabricmc.fabric-loom-remap") version "1.17-SNAPSHOT" apply false +} + +stonecutter { + parameters { + replacements.string(current.parsed < "1.21.11") { + replace("Identifier", "ResourceLocation") + } + } +} + +if (IS_CI) stonecutter active null +else stonecutter active "26.2" \ No newline at end of file diff --git a/update.json b/update.json deleted file mode 100644 index 9f0e99b..0000000 --- a/update.json +++ /dev/null @@ -1,269 +0,0 @@ -{ - "homepage": "https://github.com/North-West-Wind/forge-autofish/", - "1.21.1": { - "7.1.0": "Check Interval also checks if bobber is stuck & Fixed blurry text in config" - }, - "1.21": { - "7.0.0": "1.21 Release", - "7.1.0": "Check Interval also checks if bobber is stuck & Fixed blurry text in config" - }, - "1.20.6": { - "6.0.0": "1.20.1 Release" - }, - "1.20.5": { - "6.0.0": "1.20.1 Release" - }, - "1.20.4": { - "6.0.0": "1.20.1 Release" - }, - "1.20.3": { - "6.0.0": "1.20.1 Release" - }, - "1.20.2": { - "6.0.0": "1.20.1 Release" - }, - "1.20.1": { - "6.0.0": "1.20.1 Release" - }, - "1.19.4": { - "5.0.4": "1.19.4 Release", - "5.1.0": "Allow reeling in from any fluid" - }, - "1.19.3": { - "5.0.3": "Fixed GUI crash in 1.19.3", - "5.1.0": "Allow reeling in from any fluid" - }, - "1.19.2": { - "5.0.2": "1.19 version works for 1.19.2", - "5.1.0": "Allow reeling in from any fluid" - }, - "1.19.1": { - "5.0.2": "1.19 version works for 1.19.1", - "5.1.0": "Allow reeling in from any fluid" - }, - "1.19": { - "5.0.0": "1.19 Release", - "5.0.1": "Ignore item filter outside hotbar", - "5.0.2": "Supports for Forge 41.0.64+", - "5.1.0": "Allow reeling in from any fluid" - }, - "1.18.2": { - "4.0.2": "1.18.2 Release", - "4.1.0": "Added rod cast checker", - "4.1.1": "Ignore item filter outside hotbar", - "4.2.0": "Allow reeling in from any fluid" - }, - "1.18.1": { - "4.0.0": "1.18 Release", - "4.0.1": "Fixed item filter (Single and Multi)", - "4.1.0": "Added rod recast checker" - }, - "1.18": { - "4.0.0": "1.18 Release", - "4.0.1": "Fixed item filter (Single and Multi)", - "4.1.0": "Added rod recast checker" - }, - "1.17.1": { - "3.0.0": "1.17.1 Release", - "3.0.1": "Fixed mod tracking multiple players on server", - "3.0.2": "Fixed search bar crash + Prioritize fishable items" - }, - "1.16.5": { - "2.0.1": "1.16.5 Release", - "2.0.2": "Delay Cap in GUI + Trad. Chinese Translation", - "2.0.3": "Supports Lava Fishing from Other Mods", - "2.1.0": "Auto Replace + Major Bug Fixes", - "2.1.1": "Fixed versions", - "2.1.2": "Fixed mod tracking multiple players on server", - "2.1.3": "Fixed search bar crash + Prioritize fishable items", - "2.2.0": "Allow reeling in from any fluid" - }, - "1.16.4": { - "1.0.6": "1.16.4 Release", - "1.1.0": "Customizable Recast Delay", - "1.1.1": "Fixed Loader Version for 1.16.4", - "1.1.2": "Fixed crash while fishing", - "1.1.3": "(Properly) Fixed Loader Version for 1.16.4", - "2.0.0": "The GUI Update", - "2.0.1": "1.16.5 Release", - "2.0.2": "Delay Cap in GUI + Trad. Chinese Translation", - "2.0.3": "Supports Lava Fishing from Other Mods", - "2.1.0": "Auto Replace + Major Bug Fixes", - "2.1.1": "Fixed versions", - "2.1.2": "Fixed mod tracking multiple players on server", - "2.1.3": "Fixed search bar crash + Prioritize fishable items", - "2.2.0": "Allow reeling in from any fluid" - }, - "1.16.3": { - "1.0.5": "1.16.3 Release", - "1.1.0": "Customizable Recast Delay", - "1.1.1": "Fixed Loader Version for 1.16.4", - "1.1.2": "Fixed crash while fishing", - "1.1.3": "(Properly) Fixed Loader Version for 1.16.4", - "2.0.0": "The GUI Update", - "2.0.1": "1.16.5 Release", - "2.0.2": "Delay Cap in GUI + Trad. Chinese Translation", - "2.0.3": "Supports Lava Fishing from Other Mods", - "2.1.0": "Auto Replace + Major Bug Fixes", - "2.1.1": "Fixed versions", - "2.1.2": "Fixed mod tracking multiple players on server", - "2.1.3": "Fixed search bar crash + Prioritize fishable items", - "2.2.0": "Allow reeling in from any fluid" - }, - "1.16.2": { - "1.0.5": "1.16.2 Release", - "1.1.0": "Customizable Recast Delay", - "1.1.1": "Fixed Loader Version for 1.16.4", - "1.1.2": "Fixed crash while fishing", - "1.1.3": "(Properly) Fixed Loader Version for 1.16.4", - "2.0.0": "The GUI Update", - "2.0.1": "1.16.5 Release", - "2.0.2": "Delay Cap in GUI + Trad. Chinese Translation", - "2.0.3": "Supports Lava Fishing from Other Mods", - "2.1.0": "Auto Replace + Major Bug Fixes", - "2.1.1": "Fixed versions", - "2.1.2": "Fixed mod tracking multiple players on server", - "2.1.3": "Fixed search bar crash + Prioritize fishable items", - "2.2.0": "Allow reeling in from any fluid" - }, - "1.16.1": { - "1.0.0": "Initial Release!", - "1.0.1": "Accuracy Update", - "1.0.2": "Optimization", - "1.0.3": "Homepage Link Update", - "1.0.4": "Accuracy Update #2 + Fixed Grammatical Mistake in Description", - "1.0.5": "Offhand Support + Fishing Rod Protection", - "1.1.0": "Customizable Recast Delay", - "1.1.1": "Fixed Loader Version for 1.16.4", - "1.1.2": "Fixed crash while fishing", - "1.1.3": "(Properly) Fixed Loader Version for 1.16.4", - "2.0.0": "The GUI Update", - "2.0.1": "1.16.5 Release", - "2.0.2": "Delay Cap in GUI + Trad. Chinese Translation", - "2.0.3": "Supports Lava Fishing from Other Mods", - "2.1.0": "Auto Replace + Major Bug Fixes", - "2.1.1": "Fixed versions", - "2.1.2": "Fixed mod tracking multiple players on server", - "2.1.3": "Fixed search bar crash + Prioritize fishable items", - "2.2.0": "Allow reeling in from any fluid" - }, - "1.15.2": { - "1.0.2": "Optimization + 1.15.2 Release", - "1.0.3": "Homepage Link Update", - "1.0.4": "Accuracy Update #2 + Fixed Grammatical Mistake in Description", - "1.1.3": "Catched Up with the 1.16.4 Version", - "2.0.0": "The GUI Update", - "2.0.1": "Delay Cap in GUI + Trad. Chinese Translation" - }, - "1.15.1": { - "1.1.3": "Catched Up with the 1.16.4 Version + 1.15.1 Release", - "2.0.0": "The GUI Update", - "2.0.1": "Delay Cap in GUI + Trad. Chinese Translation" - }, - "1.15": { - "1.1.3": "Catched Up with the 1.16.4 Version + 1.15.1 Release", - "2.0.0": "The GUI Update", - "2.0.1": "Delay Cap in GUI + Trad. Chinese Translation" - }, - "1.14.4": { - "1.0.3": "1.14.4 Release", - "1.0.4": "Accuracy Update #2 + Fixed Grammatical Mistake in Description", - "2.0.0": "The GUI Update" - }, - "1.14.3": { - "2.0.0": "The GUI Update" - }, - "1.14.2": { - "2.0.0": "The GUI Update" - }, - "1.13.2": { - "1.0.3": "1.13.2 Release", - "1.0.4": "Accuracy Update #2 + Fixed Grammatical Mistake in Description" - }, - "1.12.2": { - "1.0.3": "1.12.2 Release", - "1.0.4": "Accuracy Update #2 + Fixed Grammatical Mistake in Description" - }, - "1.11.2": { - "1.0.4": "1.11.2 Release" - }, - "1.10.2": { - "1.0.4": "1.10.2 Release" - }, - "1.9.4": { - "1.0.4": "1.9.4 Release" - }, - "1.8.9": { - "1.0.4": "1.8.9 Release" - }, - "promos": { - "1.21.1-latest": "7.1.0", - "1.21.1-recommended": "7.1.0", - "1.21-latest": "7.1.0", - "1.21-recommended": "7.1.0", - "1.20.6-latest": "6.0.0", - "1.20.6-recommended": "6.0.0", - "1.20.5-latest": "6.0.0", - "1.20.5-recommended": "6.0.0", - "1.20.4-latest": "6.0.0", - "1.20.4-recommended": "6.0.0", - "1.20.3-latest": "6.0.0", - "1.20.3-recommended": "6.0.0", - "1.20.2-latest": "6.0.0", - "1.20.2-recommended": "6.0.0", - "1.20.1-latest": "6.0.0", - "1.20.1-recommended": "6.0.0", - "1.19.4-latest": "5.1.0", - "1.19.4-recommended": "5.1.0", - "1.19.3-latest": "5.1.0", - "1.19.3-recommended": "5.1.0", - "1.19.2-latest": "5.1.0", - "1.19.2-recommended": "5.1.0", - "1.19.1-latest": "5.0.2", - "1.19.1-recommended": "5.0.2", - "1.19-latest": "5.0.2", - "1.19-recommended": "5.0.2", - "1.18.2-latest": "4.2.0", - "1.18.2-recommended": "4.2.0", - "1.18.1-latest": "4.1.0", - "1.18.1-recommended": "4.1.0", - "1.18-latest": "4.1.0", - "1.18-recommended": "4.1.0", - "1.17.1-latest": "3.0.2", - "1.17.1-recommended": "3.0.2", - "1.16.5-latest": "2.2.0", - "1.16.5-recommended": "2.2.0", - "1.16.4-latest": "2.2.0", - "1.16.4-recommended": "2.2.0", - "1.16.3-latest": "2.2.0", - "1.16.3-recommended": "2.2.0", - "1.16.2-latest": "2.2.0", - "1.16.2-recommended": "2.2.0", - "1.16.1-latest": "2.2.0", - "1.16.1-recommended": "2.2.0", - "1.15.2-latest": "2.0.0", - "1.15.2-recommended": "2.0.0", - "1.15.1-latest": "2.0.0", - "1.15.1-recommended": "2.0.0", - "1.15-latest": "2.0.0", - "1.15-recommended": "2.0.0", - "1.14.4-latest": "2.0.0", - "1.14.4-recommended": "2.0.0", - "1.14.3-latest": "2.0.0", - "1.14.3-recommended": "2.0.0", - "1.14.2-latest": "2.0.0", - "1.14.2-recommended": "2.0.0", - "1.13.2-latest": "1.0.4", - "1.13.2-recommended": "1.0.4", - "1.12.2-latest": "1.0.4", - "1.12.2-recommended": "1.0.4", - "1.11.2-latest": "1.0.4", - "1.11.2-recommended": "1.0.4", - "1.10.2-latest": "1.0.4", - "1.10.2-recommended": "1.0.4", - "1.9.4-latest": "1.0.4", - "1.9.4-recommended": "1.0.4", - "1.8.9-latest": "1.0.4", - "1.8.9-recommended": "1.0.4" - } -} diff --git a/versions/1.16.5/gradle.properties b/versions/1.16.5/gradle.properties new file mode 100644 index 0000000..419e893 --- /dev/null +++ b/versions/1.16.5/gradle.properties @@ -0,0 +1,21 @@ +# Stonecutter +stonecutter_enabled_platforms=fabric + +# Java +java.version=8 + +# Minecraft +minecraft_version=1.16.5 +min_minecraft_version=1.16 + +# Mappings +deps.parchment=2022.03.06 + +# Fabric +deps.fabric_loader=0.19.3 +deps.fabric_api=0.42.0+1.16 + +deps.forge=36.2.34 + +# Dependencies +deps.modmenu= \ No newline at end of file diff --git a/versions/1.17.1/gradle.properties b/versions/1.17.1/gradle.properties new file mode 100644 index 0000000..4b06303 --- /dev/null +++ b/versions/1.17.1/gradle.properties @@ -0,0 +1,21 @@ +# Stonecutter +stonecutter_enabled_platforms=fabric, forge + +# Java +java.version=16 + +# Minecraft +minecraft_version=1.17.1 +min_minecraft_version=1.17 + +# Mappings +deps.parchment=2021.12.12 + +# Fabric +deps.fabric_loader=0.19.3 +deps.fabric_api=0.46.1+1.17 + +deps.forge=37.1.1 + +# Dependencies +deps.modmenu= \ No newline at end of file diff --git a/versions/1.18.2/gradle.properties b/versions/1.18.2/gradle.properties new file mode 100644 index 0000000..7e9a227 --- /dev/null +++ b/versions/1.18.2/gradle.properties @@ -0,0 +1,21 @@ +# Stonecutter +stonecutter_enabled_platforms=fabric, forge + +# Java +java.version=17 + +# Minecraft +minecraft_version=1.18.2 +min_minecraft_version=1.18 + +# Mappings +deps.parchment=2022.11.06 + +# Fabric +deps.fabric_loader=0.19.3 +deps.fabric_api=0.77.0 + +deps.forge=40.3.0 + +# Dependencies +deps.modmenu= \ No newline at end of file diff --git a/versions/1.19.2/gradle.properties b/versions/1.19.2/gradle.properties new file mode 100644 index 0000000..817d369 --- /dev/null +++ b/versions/1.19.2/gradle.properties @@ -0,0 +1,21 @@ +# Stonecutter +stonecutter_enabled_platforms=fabric, forge + +# Java +java.version=17 + +# Minecraft +minecraft_version=1.19.2 +min_minecraft_version=1.19 + +# Mappings +deps.parchment=2022.11.27 + +# Fabric +deps.fabric_loader=0.19.3 +deps.fabric_api=0.77.0 + +deps.forge=43.5.0 + +# Dependencies +deps.modmenu= \ No newline at end of file diff --git a/versions/1.19.4/gradle.properties b/versions/1.19.4/gradle.properties new file mode 100644 index 0000000..f06c170 --- /dev/null +++ b/versions/1.19.4/gradle.properties @@ -0,0 +1,21 @@ +# Stonecutter +stonecutter_enabled_platforms=fabric, forge + +# Java +java.version=17 + +# Minecraft +minecraft_version=1.19.4 +min_minecraft_version=1.19.3 + +# Mappings +deps.parchment=2023.06.26 + +# Fabric +deps.fabric_loader=0.19.3 +deps.fabric_api=0.87.2 + +deps.forge=45.4.0 + +# Dependencies +deps.modmenu= \ No newline at end of file diff --git a/versions/1.20.1/gradle.properties b/versions/1.20.1/gradle.properties new file mode 100644 index 0000000..9f5fb81 --- /dev/null +++ b/versions/1.20.1/gradle.properties @@ -0,0 +1,21 @@ +# Stonecutter +stonecutter_enabled_platforms=fabric, forge + +# Java +java.version=17 + +# Minecraft +minecraft_version=1.20.1 +min_minecraft_version=1.20 + +# Mappings +deps.parchment=2023.09.03 + +# Fabric +deps.fabric_loader=0.19.3 +deps.fabric_api=0.92.9 + +deps.forge=47.4.0 + +# Dependencies +deps.modmenu= \ No newline at end of file diff --git a/versions/1.21.1/gradle.properties b/versions/1.21.1/gradle.properties new file mode 100644 index 0000000..613fa41 --- /dev/null +++ b/versions/1.21.1/gradle.properties @@ -0,0 +1,25 @@ +# Stonecutter +stonecutter_enabled_platforms=fabric, forge, neoforge + +# Java +java.version=21 + +# Minecraft +minecraft_version=1.21.1 +min_minecraft_version=1.21 + +# Mappings +deps.parchment=2024.11.17 + +# Fabric +deps.fabric_loader=0.19.3 +deps.fabric_api=0.116.12 + +# NeoForge +deps.neoforge=21.1.234 +deps.neoform=1.21.1-20240808.144430 + +deps.forge=52.1.0 + +# Dependencies +deps.modmenu= \ No newline at end of file diff --git a/versions/1.21.11/gradle.properties b/versions/1.21.11/gradle.properties new file mode 100644 index 0000000..c0a8f58 --- /dev/null +++ b/versions/1.21.11/gradle.properties @@ -0,0 +1,25 @@ +# Stonecutter +stonecutter_enabled_platforms=fabric, forge, neoforge + +# Java +java.version=21 + +# Minecraft +minecraft_version=1.21.11 +min_minecraft_version=1.21.11 + +# Mappings +deps.parchment=2025.12.20 + +# Fabric +deps.fabric_loader=0.19.3 +deps.fabric_api=0.141.4 + +# NeoForge +deps.neoforge=21.11.42 +deps.neoform=1.21.11-20251209.172050 + +deps.forge=61.1.8 + +# Dependencies +deps.modmenu= \ No newline at end of file diff --git a/versions/26.1.2/gradle.properties b/versions/26.1.2/gradle.properties new file mode 100644 index 0000000..fbb8ad7 --- /dev/null +++ b/versions/26.1.2/gradle.properties @@ -0,0 +1,25 @@ +# Stonecutter +stonecutter_enabled_platforms=fabric, forge, neoforge + +# Java +java.version=25 + +# Minecraft +minecraft_version=26.1.2 +min_minecraft_version=26.1 + +# Mappings +deps.parchment= + +# Fabric +deps.fabric_loader=0.19.3 +deps.fabric_api=0.152.1 + +# NeoForge +deps.neoforge=26.1.2.0-beta +deps.neoform=26.1.2-1 + +deps.forge=64.0.10 + +# Dependencies +deps.modmenu= diff --git a/versions/26.2/gradle.properties b/versions/26.2/gradle.properties new file mode 100644 index 0000000..c5c2c2e --- /dev/null +++ b/versions/26.2/gradle.properties @@ -0,0 +1,25 @@ +# Stonecutter +stonecutter_enabled_platforms=fabric, forge, neoforge + +# Java +java.version=25 + +# Minecraft +minecraft_version=26.2 +min_minecraft_version=26.2 + +# Mappings +deps.parchment= + +# Fabric +deps.fabric_loader=0.19.3 +deps.fabric_api=0.152.1 + +# NeoForge +deps.neoforge=26.2.0.1-beta +deps.neoform=26.2-1 + +deps.forge=65.0.1 + +# Dependencies +deps.modmenu= \ No newline at end of file