diff --git a/.github/workflows/chameleon-build.yml b/.github/workflows/chameleon-build.yml index 54c781c..f9d89b3 100644 --- a/.github/workflows/chameleon-build.yml +++ b/.github/workflows/chameleon-build.yml @@ -7,25 +7,30 @@ on: jobs: build: runs-on: ubuntu-latest - + steps: - - uses: actions/checkout@v4 - - - uses: gradle/actions/wrapper-validation@v3 - - - name: Set up JDK - uses: actions/setup-java@v4 + - name: checkout repository + uses: actions/checkout@v6 + + - name: validate gradle wrapper + uses: gradle/actions/wrapper-validation@v6 + + - name: setup jdk + uses: actions/setup-java@v5 with: - java-version: '21' - distribution: 'zulu' - - - name : Build with Gradle - run: | - export BUILD_NUMBER=${{ github.run_number }} - ./gradlew build --no-daemon --stacktrace - + java-version: '25' + distribution: 'microsoft' + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v6 + with: + cache-provider: basic + + - name: Build with Gradle + run: ./gradlew build + - name: Upload a Build Artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: Chameleon-${{ github.run_number }} path: build/libs/*.jar diff --git a/.gitignore b/.gitignore index 3c37caf..1656c12 100644 --- a/.gitignore +++ b/.gitignore @@ -115,4 +115,4 @@ gradle-app.setting run/ # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) -!gradle-wrapper.jar +!gradle-wrapper.jar \ No newline at end of file diff --git a/README.ja.md b/README.ja.md index 050ed32..bc930dd 100644 --- a/README.ja.md +++ b/README.ja.md @@ -8,30 +8,34 @@ 紹介 -------- -- このモードはMinecraft1.19以上のクライアントでmacOSのDockアイコンを変更できるようにします。 (3.2.0バージョンからWindows OSも不安定ですが、サポートします。) + +- このモードはMinecraft1.19以上のクライアントでmacOSのDockアイコンを変更できるようにします。 (3.2.0バージョンからWindows + OSも不安定ですが、サポートします。) - macOS Big Sur以上のOSをお使いになっているプレイヤーさんのため、 9つのアイコンが含まれているアイコンパックも用意されています。 ![icon packs](https://user-images.githubusercontent.com/45729082/159682087-7deeb3ec-5d9a-42b6-a0ce-c6fd502a4017.png) -- クライアントコマンド `/chameleon ` を使用するか、 [Mod Menu](https://www.curseforge.com/minecraft/mc-mods/modmenu)を使用してDockのアイコンの変更ができ、ご所望の場合 **カスタムリソースパック** を通してアイコンを追加できます。 +- クライアントコマンド `/chameleon ` + を使用するか、 [Mod Menu](https://www.curseforge.com/minecraft/mc-mods/modmenu)を使用してDockのアイコンの変更ができ、ご所望の場合 + **カスタムリソースパック** を通してアイコンを追加できます。 ![preview](https://user-images.githubusercontent.com/45729082/159741680-813d91b8-82e2-4d7a-bead-9cd1402e4710.gif) - 注意! -------- + - [fabric-api](https://www.curseforge.com/minecraft/mc-mods/fabric-api) が必要です。 - Java 17以上のみ、お使いできます。 - ビルド -------- + 1. ターミナルにて `./gradlew build` を入力します。 2. `build/libs/` ディレクトリにてMODを抽出します。 - ダウンロード -------- -- 右側のReleases欄にてダウンロードできます。 +- 右側のReleases欄にてダウンロードできます。 寄与 -------- + - オープンソース生態系の発展のため、すべてのソースコードを公開し、MODの発展のための貢献を歓迎します。 diff --git a/README.ko.md b/README.ko.md index 5d8c144..390ebd0 100644 --- a/README.ko.md +++ b/README.ko.md @@ -2,36 +2,39 @@ *다른 언어로 읽기: [English](README.md), 한국어, [日本語](README.ja.md).* -*이 프로젝트의 구버전인 Fix MC-248936 설명 읽기: [English](previous/README.md), [한국어](previous/README.ko.md), [日本語](previous/README.ja.md)* +*이 프로젝트의 구버전인 Fix MC-248936 설명 +읽기: [English](previous/README.md), [한국어](previous/README.ko.md), [日本語](previous/README.ja.md)* -------- 소개 -------- + - 이 모드는 Minecraft 1.19 이상 클라이언트에서 macOS의 Dock 아이콘을 변경할 수 있게 도와줍니다. (3.2.0 버전부터 Windows OS도 불안정하지만 지원합니다.) - macOS Big Sur 이상 OS를 사용하는 플레이어를 위한 9개의 아이콘이 포함된 아이콘 팩이 준비되어 있습니다. ![icon packs](https://user-images.githubusercontent.com/45729082/159682087-7deeb3ec-5d9a-42b6-a0ce-c6fd502a4017.png) -- 클라이언트 명령어 `/chameleon `를 사용하거나, [Mod Menu](https://www.curseforge.com/minecraft/mc-mods/modmenu)를 사용해 Dock의 아이콘을 변경할 수 있으며, 원하는 경우 **사용자 지정 리소스팩**을 사용하여 아이콘을 추가할 수도 있습니다. +- 클라이언트 명령어 `/chameleon `를 사용하거나, [Mod Menu](https://www.curseforge.com/minecraft/mc-mods/modmenu)를 사용해 Dock의 + 아이콘을 변경할 수 있으며, 원하는 경우 **사용자 지정 리소스팩**을 사용하여 아이콘을 추가할 수도 있습니다. ![preview](https://user-images.githubusercontent.com/45729082/159741680-813d91b8-82e2-4d7a-bead-9cd1402e4710.gif) - 주의! -------- + - [fabric-api](https://www.curseforge.com/minecraft/mc-mods/fabric-api) 가 필요합니다. - Java 17 이상에서만 사용 가능합니다. - 빌드 -------- + 1. 터미널에서 `./gradlew build` 를 입력합니다. 2. `build/libs/` 디렉토리에서 모드를 추출합니다. - 다운로드 -------- -- 오른쪽 릴리즈 탭에서 다운로드할 수 있습니다. +- 오른쪽 릴리즈 탭에서 다운로드할 수 있습니다. 기여 -------- + - 오픈소스 생태계의 발전을 위해 모든 소스코드를 공개하며, 모드의 발전을 위한 기여를 환영합니다. diff --git a/README.md b/README.md index e192318..df76bb0 100644 --- a/README.md +++ b/README.md @@ -2,36 +2,41 @@ *Read in other languages: English, [한국어](README.ko.md), [日本語](README.ja.md).* -*Read the description of Fix MC-248936, the old name of this project: [English](previous/README.md), [한국어](previous/README.ko.md), [日本語](previous/README.ja.md)* +*Read the description of Fix MC-248936, the old name of this +project: [English](previous/README.md), [한국어](previous/README.ko.md), [日本語](previous/README.ja.md)* -------- Introduction -------- -- This mod allows you to change the Dock icon in macOS on Minecraft 1.19 and later clients. (Starting from version 3.2.0, Windows OS is also unstable but supports it.) + +- This mod allows you to change the Dock icon in macOS on Minecraft 1.19 and later clients. (Starting from version + 3.2.0, Windows OS is also unstable but supports it.) - This mod provides icon pack containing 9 icons for players who run on macOS Big Sur or above. ![icon packs](https://user-images.githubusercontent.com/45729082/159682087-7deeb3ec-5d9a-42b6-a0ce-c6fd502a4017.png) -- You can change Dock icon using the client command `/chameleon ` or through [Mod Menu](https://www.curseforge.com/minecraft/mc-mods/modmenu). You can also add the icon using a **Custom Resource Pack** if you want. +- You can change Dock icon using the client command `/chameleon ` or + through [Mod Menu](https://www.curseforge.com/minecraft/mc-mods/modmenu). You can also add the icon using a **Custom + Resource Pack** if you want. ![preview](https://user-images.githubusercontent.com/45729082/159741680-813d91b8-82e2-4d7a-bead-9cd1402e4710.gif) - Caution! -------- + - [fabric-api](https://www.curseforge.com/minecraft/mc-mods/fabric-api) is required. - This mod is only available on Java 17 or above. - Build -------- + 1. Type `./gradlew build` in Terminal. 2. extract mod from `build/libs/` directory. - Download -------- -- You can download it from right release tab. +- You can download it from right release tab. Contribution -------- + - We open our source code to public for community development, and we appreciate contribution for mod development. diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..f0927ad --- /dev/null +++ b/build.gradle @@ -0,0 +1,79 @@ +plugins { + id 'net.fabricmc.fabric-loom' version "${loom_version}" + id 'maven-publish' +} + +version = project.mod_version +group = project.maven_group + +repositories { + // Add repositories to retrieve artifacts from in here. + // You should only use this when depending on other mods because + // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. + // See https://docs.gradle.org/current/userguide/declaring_repositories.html + // for more information about repositories. + maven { + url = uri("https://maven.terraformersmc.com/") // mod-menu + } +} + +dependencies { + // To change the versions see the gradle.properties file + minecraft "com.mojang:minecraft:${project.minecraft_version}" + implementation "net.fabricmc:fabric-loader:${project.loader_version}" + + // Fabric API. This is technically optional, but you probably want it anyway. + implementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}" + + implementation "com.terraformersmc:modmenu:${project.modmenu_version}" +} + +processResources { + def version = project.version + inputs.property "version", version + filteringCharset = "UTF-8" + + filesMatching("fabric.mod.json") { + expand "version": version + } +} + +tasks.withType(JavaCompile).configureEach { + it.options.release = 25 +} + +java { + // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task + // if it is present. + // If you remove this line, sources will not be generated. + withSourcesJar() + + sourceCompatibility = JavaVersion.VERSION_25 + targetCompatibility = JavaVersion.VERSION_25 +} + +jar { + def projectName = project.name + inputs.property "projectName", projectName + + from("LICENSE") { + rename { "${it}_$projectName" } + } +} + +// configure the maven publication +publishing { + publications { + create("mavenJava", MavenPublication) { + from components.java + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + // Notice: This block does NOT have the same function as the block in the top level. + // The repositories here will be used for publishing your artifact, not for + // retrieving dependencies. + } +} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts deleted file mode 100644 index 09337d0..0000000 --- a/build.gradle.kts +++ /dev/null @@ -1,50 +0,0 @@ -plugins { - id("fabric-loom") version "1.11-SNAPSHOT" -} - -base { - group = property("maven_group") as String - version = property("mod_version") as String - archivesName.set(property("archives_base_name") as String) -} - -java.toolchain { - languageVersion.set(JavaLanguageVersion.of(21)) -} - -repositories { - maven(url = "https://maven.parchmentmc.org/") // parchment - maven(url = "https://maven.terraformersmc.com/") // mod-menu -} - -dependencies { - minecraft("com.mojang", "minecraft", property("minecraft_version") as String) - compileOnly("ca.weblite", "java-objc-bridge", "1.1") - mappings(loom.layered { - officialMojangMappings() - parchment("org.parchmentmc.data:parchment-1.21.9:2025.10.05@zip") - }) - - modImplementation("net.fabricmc", "fabric-loader", property("loader_version") as String) - modImplementation(fabricApi.module("fabric-command-api-v2", property("fabric_version") as String)) - modImplementation(fabricApi.module("fabric-resource-loader-v0", property("fabric_version") as String)) - - modImplementation("com.terraformersmc", "modmenu", property("mod-menu_version") as String) -} - -tasks{ - processResources { - inputs.property("version", project.version) - filteringCharset = "UTF-8" - - filesMatching("fabric.mod.json") { - expand(mutableMapOf("version" to version)) - } - } - - jar { - from("LICENSE") { - rename { "${it}_${project.name}" } - } - } -} diff --git a/gradle.properties b/gradle.properties index 3baba85..90cd1eb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,17 +1,21 @@ -# Done to increase the memory available to gradle. +# Done to increase the memory available to Gradle. org.gradle.jvmargs=-Xmx1G -# Fabric Properties -# check these on https://fabricmc.net/develop/ -minecraft_version=1.21.9 -loader_version=0.17.2 - -#Fabric api -fabric_version=0.134.0+1.21.9 +org.gradle.parallel=true +# IntelliJ IDEA is not yet fully compatible with configuration cache, see: https://github.com/FabricMC/fabric-loom/issues/1349 +org.gradle.configuration-cache=false -#Mod Menu -mod-menu_version=16.0.0-rc.1 +# Fabric Properties +# check these on https://fabricmc.net/develop +minecraft_version=26.2 +loader_version=0.19.3 +loom_version=1.17-SNAPSHOT # Mod Properties -mod_version=4.7.0 +mod_version=4.8.0 maven_group=moe.caramel archives_base_name=chameleon +# Dependencies +fabric_api_version=0.154.2+26.2 +modmenu_version=20.0.0-beta.4 + + diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 1b33c55..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 002b867..df6a6ad 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,9 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip networkTimeout=10000 +retries=0 +retryBackOffMs=500 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 23d15a9..249efbb 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. @@ -20,7 +20,7 @@ ############################################################################## # -# Gradle start up script for POSIX generated by Gradle. +# gradlew start up script for POSIX generated by Gradle. # # Important for running: # @@ -29,7 +29,7 @@ # bash, then to run this script, type that shell name before the whole # command line, like: # -# ksh Gradle +# ksh gradlew # # Busybox and similar reduced shells will NOT work, because this script # requires all of these POSIX shell features: @@ -57,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/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/. @@ -114,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -172,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" ) @@ -212,7 +210,6 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" diff --git a/gradlew.bat b/gradlew.bat index 5eed7ee..8508ef6 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -19,12 +19,12 @@ @if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem -@rem Gradle startup script for Windows +@rem gradlew startup script for Windows @rem @rem ########################################################################## -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal +@rem Set local scope for the variables, and ensure extensions are enabled +setlocal EnableExtensions set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. @@ -51,7 +51,7 @@ 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 -goto fail +"%COMSPEC%" /c exit 1 :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% @@ -65,30 +65,18 @@ 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 -goto fail +"%COMSPEC%" /c exit 1 :execute @rem Setup the command line -set CLASSPATH= -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* +@rem Execute gradlew +@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 -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 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! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +:exitWithErrorLevel +@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts +"%COMSPEC%" /c exit %ERRORLEVEL% diff --git a/previous/README.ja.md b/previous/README.ja.md index fac0675..cdea6ab 100644 --- a/previous/README.ja.md +++ b/previous/README.ja.md @@ -6,31 +6,35 @@ 紹介 -------- -- このMODはMinecraft 1.13以上のクライアントをmacOSにて起動する際、 **Dockのアイコンがロードできない[問題](https://bugs.mojang.com/browse/MC-248936)** を解決します。 -- また、 Apple Siliconの機械にてMinecraft 1.18未満のクライアントを起動する際、発生する `GLFW error 65548: Cocoa: Regular windows do not have icons on macOS` エラーを解決します。 + +- このMODはMinecraft 1.13以上のクライアントをmacOSにて起動する際、 * + *Dockのアイコンがロードできない[問題](https://bugs.mojang.com/browse/MC-248936)** を解決します。 +- また、 Apple Siliconの機械にてMinecraft 1.18未満のクライアントを起動する際、発生する + `GLFW error 65548: Cocoa: Regular windows do not have icons on macOS` エラーを解決します。 - macOS Big Sur以上のOSをお使いになっているプレイヤーさんのため、 9つのアイコンが含まれているアイコンパックも用意されています。 ![icon packs](https://user-images.githubusercontent.com/45729082/159682087-7deeb3ec-5d9a-42b6-a0ce-c6fd502a4017.png) -- クライアントコマンド `/changeicon ` を使ってDockのアイコンの変更ができ、ご所望の場合 **カスタムリソースパック** を通してアイコンを追加できます。 +- クライアントコマンド `/changeicon ` を使ってDockのアイコンの変更ができ、ご所望の場合 **カスタムリソースパック + ** を通してアイコンを追加できます。 ![preview](https://user-images.githubusercontent.com/45729082/159741680-813d91b8-82e2-4d7a-bead-9cd1402e4710.gif) - 注意! -------- + - [fabric-api](https://www.curseforge.com/minecraft/mc-mods/fabric-api) が必要です。 - Java 11以上のみ、お使いできます。 - ビルド -------- + 1. ターミナルにて `./gradlew build` を入力します。 2. `build/libs/` ディレクトリにてMODを抽出します。 - ダウンロード -------- -- 右側のReleases欄にてダウンロードできます。 +- 右側のReleases欄にてダウンロードできます。 寄与 -------- + - オープンソース生態系の発展のため、すべてのソースコードを公開し、MODの発展のための貢献を歓迎します。 diff --git a/previous/README.ko.md b/previous/README.ko.md index f6e6dc3..0aeca47 100644 --- a/previous/README.ko.md +++ b/previous/README.ko.md @@ -6,31 +6,34 @@ 소개 -------- -- 이 모드는 Minecraft 1.12.2 상위 클라이언트가 macOS에서 실행될 때, **독 아이콘을 로드하지 못하는 [문제](https://bugs.mojang.com/browse/MC-248936)** 를 해결합니다. -- 또한, Apple Silicon 기기에서 Minecraft 1.18 미만 클라이언트를 실행했을 때 발생하는 `GLFW error 65548: Cocoa: Regular windows do not have icons on macOS` 오류를 해결합니다. + +- 이 모드는 Minecraft 1.12.2 상위 클라이언트가 macOS에서 실행될 때, **독 아이콘을 로드하지 못하는 [문제](https://bugs.mojang.com/browse/MC-248936)** 를 + 해결합니다. +- 또한, Apple Silicon 기기에서 Minecraft 1.18 미만 클라이언트를 실행했을 때 발생하는 + `GLFW error 65548: Cocoa: Regular windows do not have icons on macOS` 오류를 해결합니다. - macOS Big Sur 이상 OS를 사용하는 플레이어를 위한 9개의 아이콘이 포함된 아이콘 팩이 준비되어 있습니다. ![icon packs](https://user-images.githubusercontent.com/45729082/159682087-7deeb3ec-5d9a-42b6-a0ce-c6fd502a4017.png) - 클라이언트 명령어 `/changeicon `를 사용하여 Dock의 아이콘을 변경할 수 있으며, 원하는 경우 **사용자 지정 리소스팩**을 사용하여 아이콘을 추가할 수도 있습니다. ![preview](https://user-images.githubusercontent.com/45729082/159741680-813d91b8-82e2-4d7a-bead-9cd1402e4710.gif) - 주의! -------- + - [fabric-api](https://www.curseforge.com/minecraft/mc-mods/fabric-api) 가 필요합니다. - Java 11 이상에서만 사용 가능합니다. - 빌드 -------- + 1. 터미널에서 `./gradlew build` 를 입력합니다. 2. `build/libs/` 디렉토리에서 모드를 추출합니다. - 다운로드 -------- -- 오른쪽 릴리즈 탭에서 다운로드할 수 있습니다. +- 오른쪽 릴리즈 탭에서 다운로드할 수 있습니다. 기여 -------- + - 오픈소스 생태계의 발전을 위해 모든 소스코드를 공개하며, 모드의 발전을 위한 기여를 환영합니다. diff --git a/previous/README.md b/previous/README.md index a0decbd..283b1c7 100644 --- a/previous/README.md +++ b/previous/README.md @@ -6,31 +6,35 @@ Introduction -------- -- This mod fixes the [issue](https://bugs.mojang.com/browse/MC-248936) that Minecraft icon does not appear while running in macOS Dock on Minecraft 1.13 client or above. -- Also, this mod fixes the `GLFW error 65548: Cocoa: Regular windows do not have icons on macOS` error when you run Minecraft 1.17.1 client or lower on Apple Silicon devices. + +- This mod fixes the [issue](https://bugs.mojang.com/browse/MC-248936) that Minecraft icon does not appear while running + in macOS Dock on Minecraft 1.13 client or above. +- Also, this mod fixes the `GLFW error 65548: Cocoa: Regular windows do not have icons on macOS` error when you run + Minecraft 1.17.1 client or lower on Apple Silicon devices. - This mod provides icon pack containing 9 icons for players who run on macOS Big Sur or above. ![icon packs](https://user-images.githubusercontent.com/45729082/159682087-7deeb3ec-5d9a-42b6-a0ce-c6fd502a4017.png) -- You can change Dock icon using client command `/changeicon ` or add icon using **Custom Resource Pack**, if you want. +- You can change Dock icon using client command `/changeicon ` or add icon using **Custom Resource Pack**, if + you want. ![preview](https://user-images.githubusercontent.com/45729082/159741680-813d91b8-82e2-4d7a-bead-9cd1402e4710.gif) - Caution! -------- + - [fabric-api](https://www.curseforge.com/minecraft/mc-mods/fabric-api) is required. - This mod is only available on Java 11 or above. - Build -------- + 1. Type `./gradlew build` in Terminal. 2. extract mod from `build/libs/` directory. - Download -------- -- You can download it from right release tab. +- You can download it from right release tab. Contribution -------- + - We open our source code to public for community development, and we appreciate contribution for mod development. diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..b02216b --- /dev/null +++ b/settings.gradle @@ -0,0 +1,10 @@ +pluginManagement { + repositories { + maven { + name = 'Fabric' + url = 'https://maven.fabricmc.net/' + } + mavenCentral() + gradlePluginPortal() + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts deleted file mode 100644 index 552a3d1..0000000 --- a/settings.gradle.kts +++ /dev/null @@ -1,6 +0,0 @@ -pluginManagement { - repositories { - maven(url = "https://maven.fabricmc.net/") // Fabric - gradlePluginPortal() - } -} diff --git a/src/main/java/moe/caramel/chameleon/Main.java b/src/main/java/moe/caramel/chameleon/Main.java index 86804f5..2707c52 100644 --- a/src/main/java/moe/caramel/chameleon/Main.java +++ b/src/main/java/moe/caramel/chameleon/Main.java @@ -6,50 +6,55 @@ import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.fabricmc.fabric.api.resource.ResourceManagerHelper; -import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener; -import net.minecraft.Util; +import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener; // TODO this is deprecated import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.toasts.Toast; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import net.minecraft.server.packs.PackType; import net.minecraft.server.packs.resources.ResourceManager; -import java.util.Queue; - -public final class Main implements ModInitializer { - - /** - * Toast Message Queue - */ - public static final Queue INIT_TOAST_QUEUE = Queues.newArrayDeque(); - - /** - * {@code true} if Minecraft is running on macOS. - */ - public static final boolean ON_OSX = Util.getPlatform() == Util.OS.OSX; +import net.minecraft.util.Util; - @Override - public void onInitialize() { - /* Load Config */ - ModConfig.getInstance(); - - /* Register Command */ - ClientCommandRegistrationCallback.EVENT.register((dispatcher, context) -> { - ChameleonCommand.register(dispatcher); - }); - - /* Watch Reload Resources */ - ResourceManagerHelper.get(PackType.CLIENT_RESOURCES).registerReloadListener(new SimpleSynchronousResourceReloadListener() { - @Override - public ResourceLocation getFabricId() { - return ResourceLocation.fromNamespaceAndPath("caramel", "chameleon-dock"); - } +import java.util.Queue; - @Override - public void onResourceManagerReload(final ResourceManager manager) { - while (!INIT_TOAST_QUEUE.isEmpty()) { - Minecraft.getInstance().getToastManager().addToast(INIT_TOAST_QUEUE.poll()); - } - } - }); - } +/** + The type Main. + */ +public final class Main implements ModInitializer{ + + /** + Toast Message Queue + */ + public static final Queue INIT_TOAST_QUEUE = Queues.newArrayDeque(); + + /** + {@code true} if Minecraft is running on macOS. + */ + public static final boolean ON_OSX = Util.getPlatform() == Util.OS.OSX; + + @Override + public void onInitialize(){ + /* Load Config */ + ModConfig.getInstance(); + + /* Register Command */ + ClientCommandRegistrationCallback.EVENT.register((dispatcher, context) -> { + ChameleonCommand.register(dispatcher); + }); + + /* Watch Reload Resources */ + ResourceManagerHelper.get(PackType.CLIENT_RESOURCES).registerReloadListener(new SimpleSynchronousResourceReloadListener(){ + @Override + public Identifier getFabricId(){ + return Identifier.fromNamespaceAndPath("caramel", "chameleon-dock"); + } + + @Override + public void onResourceManagerReload(final ResourceManager manager){ + while (!INIT_TOAST_QUEUE.isEmpty()){ + //Minecraft.getInstance().getToastManager().addToast(INIT_TOAST_QUEUE.poll()); + Minecraft.getInstance().gui.toastManager().addToast(INIT_TOAST_QUEUE.poll()); + } + } + }); + } } diff --git a/src/main/java/moe/caramel/chameleon/command/ChameleonCommand.java b/src/main/java/moe/caramel/chameleon/command/ChameleonCommand.java index 1b6f17e..1d9b1ba 100644 --- a/src/main/java/moe/caramel/chameleon/command/ChameleonCommand.java +++ b/src/main/java/moe/caramel/chameleon/command/ChameleonCommand.java @@ -1,41 +1,49 @@ package moe.caramel.chameleon.command; -import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument; -import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; +import static net.fabricmc.fabric.api.client.command.v2.ClientCommands.argument; +import static net.fabricmc.fabric.api.client.command.v2.ClientCommands.literal; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.suggestion.SuggestionProvider; import moe.caramel.chameleon.gui.ChangeDockIconScreen; import moe.caramel.chameleon.util.ModConfig; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.minecraft.client.Minecraft; -import net.minecraft.commands.arguments.ResourceLocationArgument; +//import net.minecraft.commands.arguments.ResourceLocationArgument; +import net.minecraft.commands.arguments.IdentifierArgument; import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.util.NoSuchElementException; +/* + * The type Chameleon command. + */ public final class ChameleonCommand { private static final String ICON_NAME = "icon name"; private static final SuggestionProvider SUGGEST = (context, builder) -> { final Minecraft client = Minecraft.getInstance(); - for (final ResourceLocation resource : ModConfig.GET_ICON_SET.apply(client)) { + for (final Identifier resource : ModConfig.GET_ICON_SET.apply(client)){ builder.suggest(resource.toString()); } return builder.buildFuture(); }; - - public static void register(final @NotNull CommandDispatcher dispatcher) { + + /** + Register. + + @param dispatcher the dispatcher + */ + public static void register(final @NotNull CommandDispatcher dispatcher){ dispatcher.register(literal("chameleon").executes(context -> { final Minecraft client = Minecraft.getInstance(); - client.doRunTask(() -> client.setScreen(new ChangeDockIconScreen(null))); - return 0; - }).then( - argument(ICON_NAME, ResourceLocationArgument.id()).suggests(SUGGEST).executes(context -> { + client.wrapRunnable(() -> client.setScreenAndShow(new ChangeDockIconScreen(null))); + return 0; + }).then(argument(ICON_NAME, IdentifierArgument.id()).suggests(SUGGEST).executes(context -> { final Minecraft client = Minecraft.getInstance(); final FabricClientCommandSource source = context.getSource(); - final ResourceLocation resource = context.getArgument(ICON_NAME, ResourceLocation.class); + final Identifier resource = context.getArgument(ICON_NAME, Identifier.class); try { ModConfig.changeIcon(client, resource); @@ -52,4 +60,4 @@ public static void register(final @NotNull CommandDispatcher { - final IconSelectionList.Entry entry = this.iconSelectionList.getSelected(); - if (entry != null && !ModConfig.getInstance().iconLocation.get().equals(entry.icon)) { - try { - ModConfig.changeIcon(this.minecraft, entry.icon); - } catch (final IOException exception) { - exception.printStackTrace(); - this.minecraft.getToastManager().addToast(new SystemToast( - SystemToast.SystemToastId.PACK_LOAD_FAILURE, - Component.translatable("caramel.chameleon.change.exception.title"), - Component.translatable("caramel.chameleon.change.exception") - )); - } - } - this.minecraft.setScreen(this.lastScreen); - }).bounds(this.width / 2 - 100, this.height - 30, 200, 20).build()); - } - - @Override - public void render(final GuiGraphics graphics, final int mouseX, final int mouseY, final float delta) { - super.render(graphics, mouseX, mouseY, delta); - this.iconSelectionList.render(graphics, mouseX, mouseY, delta); - graphics.drawCenteredString(this.font, this.getTitle(), this.width / 2, 12, COLOR_WHITE); - } - - - /** - * Icon Selection list - */ - private final class IconSelectionList extends ObjectSelectionList { - - public IconSelectionList(final Minecraft client) { - super(client, ChangeDockIconScreen.this.width, ChangeDockIconScreen.this.height - 70, 32, 20); - - for (final ResourceLocation resource : ModConfig.GET_ICON_SET.apply(client)) { - if (!Main.ON_OSX && resource.getPath().endsWith(".icns")) { - continue; - } - final Entry entry = new Entry(resource); - this.addEntry(entry); - if (ModConfig.getInstance().iconLocation.get().equals(resource)) { - this.setSelected(entry); - } - } - - if (this.getSelected() != null) { - this.centerScrollOn(this.getSelected()); - } - } - - @Override - public int getRowWidth() { - return super.getRowWidth() + 50; - } - - @Override - public boolean isFocused() { - return ChangeDockIconScreen.this.getFocused() == this; - } - - - /** - * Icon Selection list Entry - */ - public class Entry extends ObjectSelectionList.Entry { - - private final ResourceLocation icon; - - public Entry(final ResourceLocation icon) { - this.icon = icon; - } - - @Override - public void renderContent(final GuiGraphics graphics, int mouseX, int mouseY, boolean hover, float delta) { - final String iconLocation = this.icon.toString(); - graphics.drawString( - ChangeDockIconScreen.this.font, - iconLocation, - IconSelectionList.this.width / 2 - ChangeDockIconScreen.this.font.width(iconLocation) / 2, - this.getY() + 6, - COLOR_WHITE, - false - ); - } - - @Override - public boolean mouseClicked(final MouseButtonEvent event, final boolean doubleClick) { - if (event.input() != 0) { - return false; - } else { - IconSelectionList.this.setSelected(this); - return true; - } - } +import java.io.IOException; - @Override - public @NotNull Component getNarration() { - return Component.literal(this.icon.toString()); - } - } - } +/** + The type Change dock icon screen. + */ +public final class ChangeDockIconScreen extends Screen{ + + private static final int COLOR_WHITE = 0xFFFFFFFF; + + private final Screen lastScreen; + private IconSelectionList iconSelectionList; + + /** + Instantiates a new Change dock icon screen. + + @param parent the parent + */ + public ChangeDockIconScreen(final Screen parent){ + super(Component.translatable("caramel.chameleon.modmenu.title")); + this.lastScreen = parent; + } + + /** + Render. + + @param graphics the graphics + @param mouseX the mouse x + @param mouseY the mouse y + @param delta the delta + */ + @Override + public void extractRenderState(final GuiGraphicsExtractor graphics, final int mouseX, final int mouseY, final float delta){ + super.extractRenderState(graphics, mouseX, mouseY, delta); + this.iconSelectionList.extractRenderState(graphics, mouseX, mouseY, delta); + graphics.centeredText(this.font, this.getTitle(), this.width / 2, 12, COLOR_WHITE); + } + + @Override + protected void init(){ + this.iconSelectionList = new IconSelectionList(this.minecraft); + this.addWidget(this.iconSelectionList); + this.addRenderableWidget(Button.builder(CommonComponents.GUI_DONE, (button) -> { + final IconSelectionList.Entry entry = this.iconSelectionList.getSelected(); + if (entry != null && !ModConfig.getInstance().iconLocation.get().equals(entry.icon)){ + try{ + ModConfig.changeIcon(this.minecraft, entry.icon); + } catch (final IOException exception){ + exception.printStackTrace(); + this.minecraft.gui.toastManager().addToast(new SystemToast(SystemToast.SystemToastId.PACK_LOAD_FAILURE, Component.translatable("caramel.chameleon.change.exception.title"), Component.translatable("caramel.chameleon.change.exception"))); + } + } + this.minecraft.setScreenAndShow(this.lastScreen); + }).bounds(this.width / 2 - 100, this.height - 30, 200, 20).build()); + } + + /** + Icon Selection list + */ + private final class IconSelectionList extends ObjectSelectionList{ + + /** + Instantiates a new Icon selection list. + + @param client the client + */ + public IconSelectionList(final Minecraft client){ + super(client, ChangeDockIconScreen.this.width, ChangeDockIconScreen.this.height - 70, 32, 20); + + for (final Identifier resource : ModConfig.GET_ICON_SET.apply(client)){ + if (!Main.ON_OSX && resource.getPath().endsWith(".icns")){ + continue; + } + + final Entry entry = new Entry(resource); + this.addEntry(entry); + if (ModConfig.getInstance().iconLocation.get().equals(resource)){ + this.setSelected(entry); + } + } + + if (this.getSelected() != null){ + this.centerScrollOn(this.getSelected()); + } + } + + @Override + public int getRowWidth(){ + return super.getRowWidth() + 50; + } + + @Override + public boolean isFocused(){ + return ChangeDockIconScreen.this.getFocused() == this; + } + + + /** + Icon Selection list Entry + */ + public class Entry extends ObjectSelectionList.Entry{ + + private final Identifier icon; + + /** + Instantiates a new Entry. + + @param icon the icon + */ + public Entry(final Identifier icon){ + this.icon = icon; + } + + /** + Render content. + + @param graphics the graphics + @param mouseX the mouse x + @param mouseY the mouse y + @param hover the hover + @param delta the delta + */ + @Override + public void extractContent(final GuiGraphicsExtractor graphics, int mouseX, int mouseY, boolean hover, float delta){ + final String iconLocation = this.icon.toString(); + graphics.text(ChangeDockIconScreen.this.font, iconLocation, IconSelectionList.this.width / 2 - ChangeDockIconScreen.this.font.width(iconLocation) / 2, this.getY() + 6, COLOR_WHITE, false); + } + + @Override + public @NotNull Component getNarration(){ + return Component.literal(this.icon.toString()); + } + + @Override + public boolean mouseClicked(final MouseButtonEvent event, final boolean doubleClick){ + if (event.input() != 0){ + return false; + } else{ + IconSelectionList.this.setSelected(this); + return true; + } + } + } + } } diff --git a/src/main/java/moe/caramel/chameleon/mixin/MixinChatComponent.java b/src/main/java/moe/caramel/chameleon/mixin/MixinChatComponent.java index 6e2b41c..bb9da2a 100644 --- a/src/main/java/moe/caramel/chameleon/mixin/MixinChatComponent.java +++ b/src/main/java/moe/caramel/chameleon/mixin/MixinChatComponent.java @@ -2,7 +2,7 @@ import moe.caramel.chameleon.Main; import moe.caramel.chameleon.util.MacosUtil; -import net.minecraft.client.GuiMessage; +import net.minecraft.client.multiplayer.chat.GuiMessage; import net.minecraft.client.gui.components.ChatComponent; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -11,6 +11,9 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +/* + * The type Mixin chat component. + */ @Mixin(ChatComponent.class) public final class MixinChatComponent { @@ -40,4 +43,4 @@ private void scrollChat(CallbackInfo ci) { MacosUtil.setBadgeLabel(null); } } -} +} \ No newline at end of file diff --git a/src/main/java/moe/caramel/chameleon/mixin/MixinMinecraft.java b/src/main/java/moe/caramel/chameleon/mixin/MixinMinecraft.java index 3744b13..f94e541 100644 --- a/src/main/java/moe/caramel/chameleon/mixin/MixinMinecraft.java +++ b/src/main/java/moe/caramel/chameleon/mixin/MixinMinecraft.java @@ -1,6 +1,7 @@ package moe.caramel.chameleon.mixin; import static moe.caramel.chameleon.util.ModConfig.*; + import com.mojang.blaze3d.platform.IconSet; import com.mojang.blaze3d.platform.Window; import moe.caramel.chameleon.Main; @@ -11,7 +12,7 @@ import net.minecraft.client.gui.components.toasts.SystemToast; import net.minecraft.client.main.GameConfig; import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import net.minecraft.server.packs.PackResources; import net.minecraft.server.packs.VanillaPackResources; import net.minecraft.server.packs.resources.IoSupplier; @@ -24,55 +25,67 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + import java.io.InputStream; import java.util.Objects; import java.util.Optional; import java.io.IOException; +/** + The type Mixin minecraft. + */ @Mixin(Minecraft.class) -public abstract class MixinMinecraft { - - @Shadow public abstract ResourceManager getResourceManager(); - @Shadow @Final private VanillaPackResources vanillaPackResources; - - @Redirect( - method = "", at = @At( - value = "INVOKE", - target = "Lcom/mojang/blaze3d/platform/Window;setIcon(Lnet/minecraft/server/packs/PackResources;Lcom/mojang/blaze3d/platform/IconSet;)V" - ) - ) - private void ignoreInit(final Window window, final PackResources resources, final IconSet iconSet) { } - - // Run after all resources are loaded - @Inject(method = "", at = @At(value = "TAIL")) - public void loadMinecraftIcon(final GameConfig gameConfig, final CallbackInfo ci) throws IOException { - final ModConfig config = ModConfig.getInstance(); - - final ResourceLocation location = config.iconLocation.get(); - final String[] vanillaPath = ModConfig.VANILLA_ICON_SET.get(location); - - final IoSupplier iconSupplier; - if (vanillaPath != null) { - iconSupplier = Objects.requireNonNull(vanillaPackResources.getRootResource(vanillaPath)); - } else { - Optional resource = this.getResourceManager().getResource(location); - if (resource.isEmpty()) { - Main.INIT_TOAST_QUEUE.add(new SystemToast( - SystemToast.SystemToastId.PACK_LOAD_FAILURE, - Component.translatable("caramel.chameleon.resetToast.title"), - Component.translatable("caramel.chameleon.resetToast.desc") - )); - final ResourceLocation icon = (Main.ON_OSX ? ORIGINAL_MAC_ICON : ORIGINAL_WIN_ICON); - config.iconLocation.update(null, icon); - resource = this.getResourceManager().getResource(icon); - } - iconSupplier = ResourceIo.create(resource.get()); - } - - if (Main.ON_OSX) { - MacosUtil.loadIcon(iconSupplier); - } else { - ModConfig.setWindowsIcon(Minecraft.getInstance(), iconSupplier); - } - } +public abstract class MixinMinecraft{ + + @Shadow + @Final + private VanillaPackResources vanillaPackResources; + + /** + Gets resource manager. + + @return the resource manager + */ + @Shadow + public abstract ResourceManager getResourceManager(); + + @Redirect(method = "", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/Window;setIcon(Lnet/minecraft/server/packs/PackResources;Lcom/mojang/blaze3d/platform/IconSet;)V")) + private void ignoreInit(final Window window, final PackResources resources, final IconSet iconSet){} + + /** + Load minecraft icon. + + @param gameConfig the game config + @param ci the ci + + @throws IOException the io exception + */ + // Run after all resources are loaded + @Inject(method = "", at = @At(value = "TAIL")) + public void loadMinecraftIcon(final GameConfig gameConfig, final CallbackInfo ci) throws IOException{ + final ModConfig config = ModConfig.getInstance(); + + final Identifier location = config.iconLocation.get(); + final String[] vanillaPath = ModConfig.VANILLA_ICON_SET.get(location); + + final IoSupplier iconSupplier; + if (vanillaPath != null){ + iconSupplier = Objects.requireNonNull(vanillaPackResources.getRootResource(vanillaPath)); + } else{ + Optional resource = this.getResourceManager().getResource(location); + if (resource.isEmpty()){ + Main.INIT_TOAST_QUEUE.add(new SystemToast(SystemToast.SystemToastId.PACK_LOAD_FAILURE, Component.translatable("caramel.chameleon.resetToast.title"), Component.translatable("caramel.chameleon.resetToast.desc"))); + final Identifier icon = (Main.ON_OSX ? ORIGINAL_MAC_ICON : ORIGINAL_WIN_ICON); + config.iconLocation.update(null, icon); + resource = this.getResourceManager().getResource(icon); + } + iconSupplier = ResourceIo.create(resource.get()); + } + + if (Main.ON_OSX){ + MacosUtil.loadIcon(iconSupplier); + } else{ + ModConfig.setWindowsIcon(Minecraft.getInstance(), iconSupplier); + } + } } diff --git a/src/main/java/moe/caramel/chameleon/util/MacosUtil.java b/src/main/java/moe/caramel/chameleon/util/MacosUtil.java index 0492d98..d11a627 100644 --- a/src/main/java/moe/caramel/chameleon/util/MacosUtil.java +++ b/src/main/java/moe/caramel/chameleon/util/MacosUtil.java @@ -5,18 +5,18 @@ import org.jetbrains.annotations.Nullable; /** - * macOS Utilities. + macOS Utilities. */ -public final class MacosUtil extends com.mojang.blaze3d.platform.MacosUtil { - - /** - * Sets the badge label for the dock. - * - * @param label badge label - */ - public static void setBadgeLabel(final @Nullable String label) { - final Client client = Client.getInstance(); - final Proxy dockTile = client.sendProxy("NSApplication", "sharedApplication").sendProxy("dockTile"); - dockTile.send("setBadgeLabel:", label); - } +public final class MacosUtil extends com.mojang.blaze3d.platform.MacosUtil{ + + /** + Sets the badge label for the dock. + + @param label badge label + */ + public static void setBadgeLabel(final @Nullable String label){ + final Client client = Client.getInstance(); + final Proxy dockTile = client.sendProxy("NSApplication", "sharedApplication").sendProxy("dockTile"); + dockTile.send("setBadgeLabel:", label); + } } diff --git a/src/main/java/moe/caramel/chameleon/util/ModConfig.java b/src/main/java/moe/caramel/chameleon/util/ModConfig.java index a19cc12..44b3ba6 100644 --- a/src/main/java/moe/caramel/chameleon/util/ModConfig.java +++ b/src/main/java/moe/caramel/chameleon/util/ModConfig.java @@ -1,13 +1,15 @@ package moe.caramel.chameleon.util; import static java.util.Map.entry; -import static net.minecraft.resources.ResourceLocation.withDefaultNamespace; +//import static net.minecraft.resources.ResourceLocation.withDefaultNamespace; +import static net.minecraft.resources.Identifier.withDefaultNamespace; import com.mojang.blaze3d.platform.NativeImage; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import moe.caramel.chameleon.Main; import net.minecraft.client.Minecraft; import net.minecraft.core.RegistryAccess; -import net.minecraft.resources.ResourceLocation; +//import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import net.minecraft.server.dedicated.Settings; import net.minecraft.server.packs.resources.IoSupplier; import org.jetbrains.annotations.NotNull; @@ -15,6 +17,7 @@ import org.lwjgl.glfw.GLFWImage; import org.lwjgl.system.MemoryStack; import org.lwjgl.system.MemoryUtil; + import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -26,123 +29,137 @@ import java.util.Set; import java.util.function.Function; -public final class ModConfig extends Settings { - - private static final Path MOD_CONFIG = new File("./config/caramel.chameleon.properties").toPath(); - private static final int CURRENT_CONFIG_VERSION = 1; - - // - public static final ResourceLocation ORIGINAL_MAC_ICON = withDefaultNamespace("icons/minecraft.icns"); - public static final ResourceLocation ORIGINAL_WIN_ICON = withDefaultNamespace("icons/icon_128x128.png"); - public static final Map VANILLA_ICON_SET = Map.ofEntries( - entry(ORIGINAL_MAC_ICON, new String[]{"icons", "minecraft.icns"}), - entry(withDefaultNamespace("icons/icon_16x16.png"), new String[]{ "icons", "icon_16x16.png" }), - entry(withDefaultNamespace("icons/icon_32x32.png"), new String[]{ "icons", "icon_32x32.png" }), - entry(withDefaultNamespace("icons/icon_48x48.png"), new String[]{ "icons", "icon_48x48.png" }), - entry(ORIGINAL_WIN_ICON, new String[]{ "icons", "icon_128x128.png" }), - entry(withDefaultNamespace("icons/icon_256x256.png"), new String[]{ "icons", "icon_256x256.png" }), - entry(withDefaultNamespace("snapshot/icons/icon_16x16.png"), new String[]{ "icons", "snapshot", "icon_16x16.png" }), - entry(withDefaultNamespace("snapshot/icons/icon_32x32.png"), new String[]{ "icons", "snapshot", "icon_32x32.png" }), - entry(withDefaultNamespace("snapshot/icons/icon_48x48.png"), new String[]{ "icons", "snapshot", "icon_48x48.png" }), - entry(withDefaultNamespace("snapshot/icons/icon_128x128.png"), new String[]{ "icons", "snapshot", "icon_128x128.png" }), - entry(withDefaultNamespace("snapshot/icons/icon_256x256.png"), new String[]{ "icons", "snapshot", "icon_256x256.png" }) - ); - - public static final Function> GET_ICON_SET = (client) -> { - final Set iconSet = new ObjectOpenHashSet<>(); - client.getResourceManager().listResources("icons", resource -> { - if (resource != null) { - iconSet.add(resource); - return true; - } - return false; - }); - iconSet.addAll(VANILLA_ICON_SET.keySet()); - return iconSet; - }; - // - - // - private static ModConfig instance; - - public static ModConfig getInstance() { - if (instance == null) { - instance = new ModConfig(); - } - - return instance; - } - // - - // - public final Settings.MutableValue configVersion; - public final Settings.MutableValue iconLocation; - - private ModConfig() { - this(Settings.loadFromFile(MOD_CONFIG)); - } - - private ModConfig(final Properties properties) { - super(properties); - this.configVersion = this.getMutable( - "config-version", - s -> (s == null) ? 0 : Integer.parseInt(s), - ModConfig.CURRENT_CONFIG_VERSION - ); - this.iconLocation = this.getMutable( - "icon-location", - ResourceLocation::tryParse, - (Main.ON_OSX ? ORIGINAL_MAC_ICON : ORIGINAL_WIN_ICON) - ); - } - - @Override - protected @NotNull ModConfig reload(final RegistryAccess registryAccess, final Properties properties) { - instance = new ModConfig(properties); - instance.store(MOD_CONFIG); - return getInstance(); - } - // - - // - public static void changeIcon(final Minecraft client, final ResourceLocation icon) throws IOException { - final String[] vanillaPath = ModConfig.VANILLA_ICON_SET.get(icon); - final IoSupplier iconSupplier; - if (vanillaPath != null) { - iconSupplier = Objects.requireNonNull(client.getVanillaPackResources().getRootResource(vanillaPath)); - } else { - iconSupplier = ResourceIo.create(client.getResourceManager().getResource(icon).get()); - } - if (Main.ON_OSX) { - MacosUtil.loadIcon(iconSupplier); - } else { - ModConfig.setWindowsIcon(client, iconSupplier); - } - ModConfig.getInstance().iconLocation.update(null, icon); - } - - public static void setWindowsIcon(final Minecraft client, final IoSupplier icon) throws IOException { - ByteBuffer value = null; - - try ( - final MemoryStack stack = MemoryStack.stackPush(); - final NativeImage image = NativeImage.read(icon.get()); - ) { - final GLFWImage.Buffer images = GLFWImage.malloc(1, stack); - - value = MemoryUtil.memAlloc(image.getWidth() * image.getHeight() * 4); - value.asIntBuffer().put(image.getPixelsABGR()); - images.position(0); - images.width(image.getWidth()); - images.height(image.getHeight()); - images.pixels(value); - - GLFW.glfwSetWindowIcon(client.getWindow().handle(), images.position(0)); - } finally { - if (value != null) { - MemoryUtil.memFree(value); - } - } - } - // +/** + The type Mod config. + */ +public final class ModConfig extends Settings{ + + /** + The constant ORIGINAL_MAC_ICON. + */ + // + public static final Identifier ORIGINAL_MAC_ICON = withDefaultNamespace("icons/minecraft.icns"); + /** + The constant ORIGINAL_WIN_ICON. + */ + public static final Identifier ORIGINAL_WIN_ICON = withDefaultNamespace("icons/icon_128x128.png"); + /** + The constant VANILLA_ICON_SET. + */ + public static final Map VANILLA_ICON_SET = Map.ofEntries(entry(ORIGINAL_MAC_ICON, new String[]{"icons", "minecraft.icns"}), entry(withDefaultNamespace("icons/icon_16x16.png"), new String[]{"icons", "icon_16x16.png"}), entry(withDefaultNamespace("icons/icon_32x32.png"), new String[]{"icons", "icon_32x32.png"}), entry(withDefaultNamespace("icons/icon_48x48.png"), new String[]{"icons", "icon_48x48.png"}), entry(ORIGINAL_WIN_ICON, new String[]{"icons", "icon_128x128.png"}), entry(withDefaultNamespace("icons/icon_256x256.png"), new String[]{"icons", "icon_256x256.png"}), entry(withDefaultNamespace("snapshot/icons/icon_16x16.png"), new String[]{"icons", "snapshot", "icon_16x16.png"}), entry(withDefaultNamespace("snapshot/icons/icon_32x32.png"), new String[]{"icons", "snapshot", "icon_32x32.png"}), entry(withDefaultNamespace("snapshot/icons/icon_48x48.png"), new String[]{"icons", "snapshot", "icon_48x48.png"}), entry(withDefaultNamespace("snapshot/icons/icon_128x128.png"), new String[]{"icons", "snapshot", "icon_128x128.png"}), entry(withDefaultNamespace("snapshot/icons/icon_256x256.png"), new String[]{"icons", "snapshot", "icon_256x256.png"})); + /** + The constant GET_ICON_SET. + */ + public static final Function> GET_ICON_SET = (client) -> { + final Set iconSet = new ObjectOpenHashSet<>(); + client.getResourceManager().listResources("icons", resource -> { + if (resource != null){ + iconSet.add(resource); + return true; + } + return false; + }); + iconSet.addAll(VANILLA_ICON_SET.keySet()); + return iconSet; + }; + private static final Path MOD_CONFIG = new File("./config/caramel.chameleon.properties").toPath(); + private static final int CURRENT_CONFIG_VERSION = 1; + // + // + private static ModConfig instance; + /** + The Config version. + */ + // + public final Settings.MutableValue configVersion; + // + /** + The Icon location. + */ + public final Settings.MutableValue iconLocation; + private ModConfig(){ + this(Settings.loadFromFile(MOD_CONFIG)); + } + + private ModConfig(final Properties properties){ + super(properties); + this.configVersion = this.getMutable("config-version", s -> (s == null) ? 0 : Integer.parseInt(s), ModConfig.CURRENT_CONFIG_VERSION); + this.iconLocation = this.getMutable("icon-location", Identifier::tryParse, (Main.ON_OSX ? ORIGINAL_MAC_ICON : ORIGINAL_WIN_ICON)); + } + + /** + Gets instance. + + @return the instance + */ + public static ModConfig getInstance(){ + if (instance == null){ + instance = new ModConfig(); + } + + return instance; + } + + /** + Change icon. + + @param client the client + @param icon the icon + + @throws IOException the io exception + */ + // + public static void changeIcon(final Minecraft client, final Identifier icon) throws IOException{ + final String[] vanillaPath = ModConfig.VANILLA_ICON_SET.get(icon); + final IoSupplier iconSupplier; + if (vanillaPath != null){ + iconSupplier = Objects.requireNonNull(client.getVanillaPackResources().getRootResource(vanillaPath)); + } else{ + iconSupplier = ResourceIo.create(client.getResourceManager().getResource(icon).get()); + } + if (Main.ON_OSX){ + MacosUtil.loadIcon(iconSupplier); + } else{ + ModConfig.setWindowsIcon(client, iconSupplier); + } + ModConfig.getInstance().iconLocation.update(null, icon); + } + // + + /** + Sets windows icon. + + @param client the client + @param icon the icon + + @throws IOException the io exception + */ + public static void setWindowsIcon(final Minecraft client, final IoSupplier icon) throws IOException{ + ByteBuffer value = null; + + try (final MemoryStack stack = MemoryStack.stackPush(); final NativeImage image = NativeImage.read(icon.get());){ + final GLFWImage.Buffer images = GLFWImage.malloc(1, stack); + + value = MemoryUtil.memAlloc(image.getWidth() * image.getHeight() * 4); + value.asIntBuffer().put(image.getPixelsABGR()); + images.position(0); + images.width(image.getWidth()); + images.height(image.getHeight()); + images.pixels(value); + + GLFW.glfwSetWindowIcon(client.getWindow().handle(), images.position(0)); + } finally{ + if (value != null){ + MemoryUtil.memFree(value); + } + } + } + + @Override + protected @NotNull ModConfig reload(final RegistryAccess registryAccess, final Properties properties){ + instance = new ModConfig(properties); + instance.store(MOD_CONFIG); + return getInstance(); + } + // } diff --git a/src/main/java/moe/caramel/chameleon/util/ModMenuImpl.java b/src/main/java/moe/caramel/chameleon/util/ModMenuImpl.java index c096276..0729df5 100644 --- a/src/main/java/moe/caramel/chameleon/util/ModMenuImpl.java +++ b/src/main/java/moe/caramel/chameleon/util/ModMenuImpl.java @@ -5,10 +5,13 @@ import moe.caramel.chameleon.gui.ChangeDockIconScreen; import net.minecraft.client.gui.screens.Screen; -public final class ModMenuImpl implements ModMenuApi { - - @Override - public ConfigScreenFactory getModConfigScreenFactory() { - return ChangeDockIconScreen::new; - } +/** + The type Mod menu. + */ +public final class ModMenuImpl implements ModMenuApi{ + + @Override + public ConfigScreenFactory getModConfigScreenFactory(){ + return ChangeDockIconScreen::new; + } } diff --git a/src/main/java/moe/caramel/chameleon/util/ResourceIo.java b/src/main/java/moe/caramel/chameleon/util/ResourceIo.java index b1a75b2..c1b4011 100644 --- a/src/main/java/moe/caramel/chameleon/util/ResourceIo.java +++ b/src/main/java/moe/caramel/chameleon/util/ResourceIo.java @@ -2,11 +2,22 @@ import net.minecraft.server.packs.resources.IoSupplier; import net.minecraft.server.packs.resources.Resource; -import java.io.InputStream; -public interface ResourceIo extends IoSupplier { +import java.io.InputStream; - static IoSupplier create(final Resource resource) { - return resource::open; - } +/** + The interface Resource io. + */ +public interface ResourceIo extends IoSupplier{ + + /** + Create io supplier. + + @param resource the resource + + @return the io supplier + */ + static IoSupplier create(final Resource resource){ + return resource::open; + } } diff --git a/src/main/resources/assets/caramel/lang/en_us.json b/src/main/resources/assets/caramel/lang/en_us.json index 34f1564..ee04ec9 100644 --- a/src/main/resources/assets/caramel/lang/en_us.json +++ b/src/main/resources/assets/caramel/lang/en_us.json @@ -1,10 +1,8 @@ { "modmenu.descriptionTranslation.chameleon-dock": "Changes the Minecraft icon displayed in the dock.", "caramel.chameleon.modmenu.title": "Chameleon Setting", - "caramel.chameleon.resetToast.title": "Chameleon settings was reset", "caramel.chameleon.resetToast.desc": "Changed to default icon due to an error.", - "caramel.chameleon.change.done": "Successfully changed the icon to \"%s\".", "caramel.chameleon.change.404": "Icon named \"%s\" does not exist.", "caramel.chameleon.change.exception.title": "Error!", diff --git a/src/main/resources/assets/caramel/lang/ja_jp.json b/src/main/resources/assets/caramel/lang/ja_jp.json index 9c22927..df252d5 100644 --- a/src/main/resources/assets/caramel/lang/ja_jp.json +++ b/src/main/resources/assets/caramel/lang/ja_jp.json @@ -1,10 +1,8 @@ { "modmenu.descriptionTranslation.chameleon-dock": "ドックに表示されるMinecraftアイコンを変更します。", "caramel.chameleon.modmenu.title": "Chameleon 設定", - "caramel.chameleon.resetToast.title": "Chameleon設定が初期化された", "caramel.chameleon.resetToast.desc": "エラーにより基本アイコンに変更されました。", - "caramel.chameleon.change.done": "アイコンを \"%s\"に変更しました。", "caramel.chameleon.change.404": "\"%s\"という名前のアイコンが見つかりません。", "caramel.chameleon.change.exception.title": "エラー!", diff --git a/src/main/resources/assets/caramel/lang/ko_kr.json b/src/main/resources/assets/caramel/lang/ko_kr.json index ac28ebf..821758b 100644 --- a/src/main/resources/assets/caramel/lang/ko_kr.json +++ b/src/main/resources/assets/caramel/lang/ko_kr.json @@ -1,10 +1,8 @@ { "modmenu.descriptionTranslation.chameleon-dock": "독에 표시되는 Minecraft 아이콘을 변경합니다.", "caramel.chameleon.modmenu.title": "Chameleon 설정", - "caramel.chameleon.resetToast.title": "Chameleon 설정이 초기화됨", "caramel.chameleon.resetToast.desc": "오류로 인해 기본 아이콘으로 변경되었습니다.", - "caramel.chameleon.change.done": "성공적으로 아이콘을 \"%s\"(으)로 변경하였습니다.", "caramel.chameleon.change.404": "\"%s\"이라는 이름의 아이콘은 존재하지 않습니다.", "caramel.chameleon.change.exception.title": "오류!", diff --git a/src/main/resources/assets/icon.png b/src/main/resources/assets/icon.png new file mode 100644 index 0000000..ad9984d Binary files /dev/null and b/src/main/resources/assets/icon.png differ diff --git a/src/main/resources/chameleon-dock.mixins.json b/src/main/resources/chameleon-dock.mixins.json index e3b8e70..e186dd7 100644 --- a/src/main/resources/chameleon-dock.mixins.json +++ b/src/main/resources/chameleon-dock.mixins.json @@ -2,7 +2,7 @@ "required": true, "minVersion": "0.8", "package": "moe.caramel.chameleon.mixin", - "compatibilityLevel": "JAVA_21", + "compatibilityLevel": "JAVA_25", "client": [ "MixinChatComponent", "MixinMinecraft" diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 5947b2f..fc14f09 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -4,9 +4,12 @@ "version": "${version}", "name": "Chameleon", "description": "Change Minecraft's Dock Icon on macOS", - "authors": [ "LemonCaramel" ], + "authors": [ + "LemonCaramel" + ], "contributors": [ - "t3rminus" + "t3rminus", + "Avakining" ], "contact": { "email": "admin@caramel.moe", @@ -18,23 +21,23 @@ "license": "MIT", "environment": "client", "entrypoints": { - "main": [ "moe.caramel.chameleon.Main" ], - "modmenu": [ "moe.caramel.chameleon.util.ModMenuImpl" ] + "main": [ + "moe.caramel.chameleon.Main" + ], + "modmenu": [ + "moe.caramel.chameleon.util.ModMenuImpl" + ] }, - "mixins": [ "chameleon-dock.mixins.json" ], + "mixins": [ + "chameleon-dock.mixins.json" + ], "depends": { - "fabric-command-api-v2": "*", - "fabric-resource-loader-v0": "*", - "fabricloader": ">=0.17.2", - "minecraft": ">=1.21.9", - "java": ">=21" + "fabricloader": ">=0.19.3", + "minecraft": "~26.2", + "java": ">=25", + "fabric-api": "*" }, "custom": { - "modupdater": { - "strategy": "curseforge", - "projectID": 597393, - "strict": false - }, "modmenu": { "update_checker": true }