From 2e68b1426eb93f63c1e59f857ba22ac82dd2aa3b Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Tue, 1 Oct 2024 11:24:18 +0800 Subject: [PATCH 01/13] build: 2.1.1 --- client/changelog.md | 35 +---------------------------------- gradle.properties | 2 +- proxy/changelog.md | 16 +--------------- server/changelog.md | 23 +---------------------- 4 files changed, 4 insertions(+), 72 deletions(-) diff --git a/client/changelog.md b/client/changelog.md index d1b8e6b6..64ef86ff 100644 --- a/client/changelog.md +++ b/client/changelog.md @@ -5,37 +5,4 @@ If you encounter any issues, please report them on Discord: https://discord.gg/u Versions 2.0.x and 2.1.x are protocol-compatible, so there’s no need to worry if the server hasn't been updated to 2.1.x. -### Main Changes -- Backports to 1.18.2, 1.17.1, and 1.16.5. -- New open source [Opus](https://github.com/plasmoapp/opus-jni-rust) and [RNNoise](https://github.com/plasmoapp/rnnoise-jni-rust) binaries, related to [#319](https://github.com/plasmoapp/plasmo-voice/issues/319) [#375](https://github.com/plasmoapp/plasmo-voice/issues/375) [#382](https://github.com/plasmoapp/plasmo-voice/issues/382). -- NeoForge support for 1.21+. -- Forge support for 1.20.4+. -- Client now sends server ip and server port in the first ping packet, which is used for a connection establishment. This is useful for building reverse proxies. You can find an example here: https://github.com/Apehum/pv-reverse-proxy. -- Server now sends a request info packet to any player joining the server. This was introduced due to differences in how various mod loaders handle the mod channel list, and I just can't figure out how to make it work on Forge/NeoForge 1.20.2+. -- Server now checks if a player has voice disabled or microphone muted before sending or receiving the audio. -- "Open to LAN" now restarts the UDP server with the published port if `host.port` is set to 0. -- Fixed "GUI Icon remains visible when GUI is hidden with F1" ([#407](https://github.com/plasmoapp/plasmo-voice/issues/407)). -- Push-To-Talk is now disabled in chat and sign menus ([#414](https://github.com/plasmoapp/plasmo-voice/pull/414)). -- Fade-in/fade-out effects before and after an audio stream, fixing glitches that occurred when the audio source starts or stops playing audio. -- Languages now support [MiniMessage format](https://docs.advntr.dev/minimessage/index.html). -- Network jitter buffer. -- ...and many more internal changes and fixes. - -### Breaking API Changes -There have been breaking changes to the API, meaning you'll need to update your addons: -#### Client Addons -- [pv-addon-soundphysics](https://modrinth.com/mod/pv-addon-soundphysics/version/1.1.0) -- [pv-addon-replaymod 1.16.5-1.21](https://modrinth.com/mod/pv-addon-replaymod/version/1.16.5-2.1.0) -- [pv-addon-replaymod 1.21+](https://modrinth.com/mod/pv-addon-replaymod/version/1.21-2.1.0) -### Server Addons -- [pv-addon-groups](https://modrinth.com/plugin/pv-addon-groups/version/1.1.0) -- [pv-addon-sculk](https://modrinth.com/plugin/pv-addon-sculk/version/1.1.0) -- [pv-addon-broadcast](https://modrinth.com/plugin/pv-addon-broadcast/version/1.1.0) -- [pv-addon-spectator](https://modrinth.com/plugin/pv-addon-spectator/version/1.1.0) -- [pv-addon-whisper](https://modrinth.com/plugin/pv-addon-whisper/version/1.1.0) -- [pv-addon-priority](https://modrinth.com/plugin/pv-addon-priority/version/1.1.0) - -The API documentation is now available: https://plasmovoice.com/docs/api. -It's still a work in progress, so feedback is appreciated. -You can provide feedback on our Discord: https://discord.gg/uueEqzwCJJ. - +### Changes in 2.1.1 diff --git a/gradle.properties b/gradle.properties index 9b198866..859b048b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ # Version targetJavaVersion=8 group=su.plo.voice -version=2.1.0 +version=2.1.1 # Gradle args org.gradle.jvmargs=-Xmx4G -Dkotlin.daemon.jvm.options=-Xmx512M diff --git a/proxy/changelog.md b/proxy/changelog.md index 73904018..e0a8907e 100644 --- a/proxy/changelog.md +++ b/proxy/changelog.md @@ -5,18 +5,4 @@ If you encounter any issues, please report them on Discord: https://discord.gg/u Versions 2.0.x and 2.1.x are protocol-compatible, so there’s no need to worry if the server hasn't been updated to 2.1.x. -### Main Changes -- Backports to 1.18.2, 1.17.1, and 1.16.5. -- New open source [Opus](https://github.com/plasmoapp/opus-jni-rust) and [RNNoise](https://github.com/plasmoapp/rnnoise-jni-rust) binaries, related to [#319](https://github.com/plasmoapp/plasmo-voice/issues/319) [#375](https://github.com/plasmoapp/plasmo-voice/issues/375) [#382](https://github.com/plasmoapp/plasmo-voice/issues/382). -- Languages now support [MiniMessage format](https://docs.advntr.dev/minimessage/index.html). -- Fixed [#376](https://github.com/plasmoapp/plasmo-voice/issues/376) "IP address not updates after recreate minecraft's server docker container" -- ...and many more internal changes and fixes. - -### Breaking API Changes -There have been breaking changes to the API, meaning you'll need to update your addons: -- [pv-addon-groups](https://modrinth.com/plugin/pv-addon-groups/version/1.1.0) -- [pv-addon-broadcast](https://modrinth.com/plugin/pv-addon-broadcast/version/1.1.0) - -The API documentation is now available: https://plasmovoice.com/docs/api. -It's still a work in progress, so feedback is appreciated. -You can provide feedback on our Discord: https://discord.gg/uueEqzwCJJ. +### Changes in 2.1.1 \ No newline at end of file diff --git a/server/changelog.md b/server/changelog.md index 4d8e2698..e0a8907e 100644 --- a/server/changelog.md +++ b/server/changelog.md @@ -5,25 +5,4 @@ If you encounter any issues, please report them on Discord: https://discord.gg/u Versions 2.0.x and 2.1.x are protocol-compatible, so there’s no need to worry if the server hasn't been updated to 2.1.x. -### Main Changes -- Backports to 1.18.2, 1.17.1, and 1.16.5. -- New open source [Opus](https://github.com/plasmoapp/opus-jni-rust) and [RNNoise](https://github.com/plasmoapp/rnnoise-jni-rust) binaries, related to [#319](https://github.com/plasmoapp/plasmo-voice/issues/319) [#375](https://github.com/plasmoapp/plasmo-voice/issues/375) [#382](https://github.com/plasmoapp/plasmo-voice/issues/382). -- Server now sends a request info packet to any player joining the server. This was introduced due to differences in how various mod loaders handle the mod channel list, and I just can't figure out how to make it work on Forge/NeoForge 1.20.2+. -- Server now checks if a player has voice disabled or microphone muted before sending or receiving the audio. -- Languages now support [MiniMessage format](https://docs.advntr.dev/minimessage/index.html). -- ...and many more internal changes and fixes. - -### Breaking API Changes -There have been breaking changes to the API, meaning you'll need to update your addons: -- [pv-addon-groups](https://modrinth.com/plugin/pv-addon-groups/version/1.1.0) -- [pv-addon-sculk](https://modrinth.com/plugin/pv-addon-sculk/version/1.1.0) -- [pv-addon-broadcast](https://modrinth.com/plugin/pv-addon-broadcast/version/1.1.0) -- [pv-addon-spectator](https://modrinth.com/plugin/pv-addon-spectator/version/1.1.0) -- [pv-addon-whisper](https://modrinth.com/plugin/pv-addon-whisper/version/1.1.0) -- [pv-addon-priority](https://modrinth.com/plugin/pv-addon-priority/version/1.1.0) -- [pv-addon-lavaplayer-lib](https://modrinth.com/plugin/pv-addon-lavaplayer-lib/version/1.1.0) -- [pv-addon-discs](https://modrinth.com/plugin/pv-addon-discs/version/1.1.0) - -The API documentation is now available: https://plasmovoice.com/docs/api. -It's still a work in progress, so feedback is appreciated. -You can provide feedback on our Discord: https://discord.gg/uueEqzwCJJ. +### Changes in 2.1.1 \ No newline at end of file From 281eaac748942bbd9e7e19fa0e4f46b528d14c9b Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Tue, 1 Oct 2024 11:26:24 +0800 Subject: [PATCH 02/13] build(client): add 1.19.3 and soften some version bounds --- client/1.19.3-fabric/.gitkeep | 0 client/1.19.3-forge/.gitkeep | 0 client/build.gradle.kts | 1 + client/changelog.md | 4 ++++ client/root.gradle.kts | 10 ++++++++-- client/versions.toml | 10 +++++++--- 6 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 client/1.19.3-fabric/.gitkeep create mode 100644 client/1.19.3-forge/.gitkeep diff --git a/client/1.19.3-fabric/.gitkeep b/client/1.19.3-fabric/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/client/1.19.3-forge/.gitkeep b/client/1.19.3-forge/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/client/build.gradle.kts b/client/build.gradle.kts index 78769691..35242b5d 100644 --- a/client/build.gradle.kts +++ b/client/build.gradle.kts @@ -82,6 +82,7 @@ dependencies { 11701 -> "0.46.1+1.17" 11802 -> "0.76.0+1.18.2" 11902 -> "0.73.2+1.19.2" + 11903 -> "0.76.1+1.19.3" 11904 -> "0.87.1+1.19.4" 12001 -> "0.84.0+1.20.1" 12004 -> "0.95.4+1.20.4" diff --git a/client/changelog.md b/client/changelog.md index 64ef86ff..b4de3d61 100644 --- a/client/changelog.md +++ b/client/changelog.md @@ -6,3 +6,7 @@ Versions 2.0.x and 2.1.x are protocol-compatible, so there’s no need to worry if the server hasn't been updated to 2.1.x. ### Changes in 2.1.1 +- Reintroduce build for 1.19.3 +- Soften Minecraft version bounds on some versions: + - 1.20.4 now allows 1.20.2, 1.20.3 and 1.20.4 + - 1.19.2 now allows 1.19, 1.19.1 and 1.19.2 diff --git a/client/root.gradle.kts b/client/root.gradle.kts index ac63f1b8..96c0aac4 100644 --- a/client/root.gradle.kts +++ b/client/root.gradle.kts @@ -19,6 +19,9 @@ preprocess { val forge11904 = createNode("1.19.4-forge", 11904, "official") val fabric11904 = createNode("1.19.4-fabric", 11904, "official") + val forge11903 = createNode("1.19.3-forge", 11903, "official") + val fabric11903 = createNode("1.19.3-fabric", 11903, "official") + val forge11902 = createNode("1.19.2-forge", 11902, "official") val fabric11902 = createNode("1.19.2-fabric", 11902, "official") @@ -44,8 +47,11 @@ preprocess { // fabric 1.19.4 main project forge11904.link(fabric11904) - fabric11902.link(fabric11904, file("1.19.2-1.19.3.txt")) - forge11902.link(forge11904, file("1.19.2-1.19.3.txt")) + fabric11903.link(fabric11904) + forge11903.link(forge11904) + + fabric11902.link(fabric11903, file("1.19.2-1.19.3.txt")) + forge11902.link(forge11903, file("1.19.2-1.19.3.txt")) fabric11802.link(fabric11902) forge11802.link(forge11902, file("1.18.2-1.19.2.txt")) diff --git a/client/versions.toml b/client/versions.toml index 7ee3799c..42e0860b 100644 --- a/client/versions.toml +++ b/client/versions.toml @@ -5,7 +5,7 @@ neoForgeVersion = "[20,)" [12004] forgeVersion = "[49,)" -mcVersions = ["1.20.3", "1.20.4"] +mcVersions = ["1.20.2", "1.20.3", "1.20.4"] [12001] forgeVersion = "[46,)" @@ -15,9 +15,13 @@ mcVersions = ["1.20", "1.20.1"] forgeVersion = "[45,)" mcVersions = ["1.19.4"] +[11903] +forgeVersion = "[44,)" +mcVersions = ["1.19.3"] + [11902] -forgeVersion = "[43,)" -mcVersions = ["1.19.2"] +forgeVersion = "[41,)" +mcVersions = [">=1.19 <1.19.3"] [11802] forgeVersion = "[40,)" From d1dff7110a474c426c770c32415fc7ef0315bb90 Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Tue, 1 Oct 2024 11:44:00 +0800 Subject: [PATCH 03/13] ci: update changelog --- client/changelog.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/changelog.md b/client/changelog.md index b4de3d61..d8bdbaa5 100644 --- a/client/changelog.md +++ b/client/changelog.md @@ -6,7 +6,8 @@ Versions 2.0.x and 2.1.x are protocol-compatible, so there’s no need to worry if the server hasn't been updated to 2.1.x. ### Changes in 2.1.1 -- Reintroduce build for 1.19.3 -- Soften Minecraft version bounds on some versions: +- Build for 1.19.3 was reintroduced. +- Soften Minecraft version bounds: - 1.20.4 now allows 1.20.2, 1.20.3 and 1.20.4 - 1.19.2 now allows 1.19, 1.19.1 and 1.19.2 +- Updated [slib](https://github.com/plasmoapp/mc-slib) to fix crash with EssentialAddons on world join. \ No newline at end of file From 099745d37e8c18e8f7b88becaefba2b4e663469a Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Tue, 1 Oct 2024 15:11:52 +0800 Subject: [PATCH 04/13] ci: don't generate github changelog [ci skip] --- .github/workflows/prerelease-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prerelease-publish.yml b/.github/workflows/prerelease-publish.yml index 27c9b4ac..13d6514c 100644 --- a/.github/workflows/prerelease-publish.yml +++ b/.github/workflows/prerelease-publish.yml @@ -43,7 +43,7 @@ jobs: uses: Apehum/mc-publish@v1.1 with: github-token: ${{ secrets.GITHUB_TOKEN }} - github-generate-changelog: true + github-generate-changelog: false github-prerelease: true - name: Build dokka From 3993993a2573291d3903ae6426578cede7c9f639 Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Fri, 4 Oct 2024 22:17:26 +0800 Subject: [PATCH 05/13] fix(client): close devices on DeviceManager#clear --- .../su/plo/voice/api/client/audio/device/DeviceManager.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/client/src/main/java/su/plo/voice/api/client/audio/device/DeviceManager.java b/api/client/src/main/java/su/plo/voice/api/client/audio/device/DeviceManager.java index 34a646a0..91ddacc4 100644 --- a/api/client/src/main/java/su/plo/voice/api/client/audio/device/DeviceManager.java +++ b/api/client/src/main/java/su/plo/voice/api/client/audio/device/DeviceManager.java @@ -45,10 +45,12 @@ public interface DeviceManager { void setInputDevice(@Nullable InputDevice device); /** - * Removes the output and input devices. + * Closes and removes the output and input devices. */ default void clear() { + getOutputDevice().ifPresent(OutputDevice::close); setOutputDevice(null); + getInputDevice().ifPresent(InputDevice::close); setInputDevice(null); } From b0b91dd2dea2e6eb8a14657c8fd63bcb33a328eb Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Wed, 9 Oct 2024 18:56:21 +0800 Subject: [PATCH 06/13] fix(client): set delay to 5ms if packet is null in audio source job probably fixes #421 --- .../su/plo/voice/client/audio/source/BaseClientAudioSource.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/main/kotlin/su/plo/voice/client/audio/source/BaseClientAudioSource.kt b/client/src/main/kotlin/su/plo/voice/client/audio/source/BaseClientAudioSource.kt index 719e6b50..96cc5670 100644 --- a/client/src/main/kotlin/su/plo/voice/client/audio/source/BaseClientAudioSource.kt +++ b/client/src/main/kotlin/su/plo/voice/client/audio/source/BaseClientAudioSource.kt @@ -253,7 +253,7 @@ abstract class BaseClientAudioSource( while (isActive) { val wrappedPacket = buffer.poll() if (wrappedPacket == null) { - delay(0L) + delay(5L) continue } From 375e9d944dd45b6730e86c867170675a2498071f Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Wed, 9 Oct 2024 19:19:40 +0800 Subject: [PATCH 07/13] feat(client): 1.21.2-pre1 fabric --- client/1.21.2-fabric/gradle.properties | 1 + client/build.gradle.kts | 9 +- client/root.gradle.kts | 4 + .../lib/mod/client/chat/ClientChatUtil.java | 4 +- .../plo/lib/mod/client/render/RenderUtil.java | 28 ++++- .../su/plo/voice/client/ModVoiceClient.java | 6 +- .../voice/client/audio/SoundOcclusion.java | 4 +- .../event/render/EntityRenderEvent.java | 37 ------ .../event/render/PlayerRenderEvent.java | 41 ------ .../voice/client/gui/PlayerVolumeAction.java | 5 +- .../mixin/MixinEntityRenderDispatcher.java | 94 ++++++++++++++ .../client/mixin/MixinEntityRenderer.java | 35 ------ .../accessor/EntityRendererAccessor.java | 18 +++ .../client/render/ModEntityRenderer.java | 60 --------- .../render/voice/SourceIconRenderer.java | 117 +++++++++++------- .../essential/universal/shader/BlendState.kt | 37 +----- .../gg/essential/universal/shader/MCShader.kt | 36 ++++++ .../client/event/LivingEntityRenderEvent.kt | 24 ++++ .../main/resources/plasmovoice.mixins.json | 6 +- client/versions.toml | 9 +- 20 files changed, 303 insertions(+), 272 deletions(-) create mode 100644 client/1.21.2-fabric/gradle.properties delete mode 100644 client/src/main/java/su/plo/voice/client/event/render/EntityRenderEvent.java delete mode 100644 client/src/main/java/su/plo/voice/client/event/render/PlayerRenderEvent.java create mode 100644 client/src/main/java/su/plo/voice/client/mixin/MixinEntityRenderDispatcher.java delete mode 100644 client/src/main/java/su/plo/voice/client/mixin/MixinEntityRenderer.java create mode 100644 client/src/main/java/su/plo/voice/client/mixin/accessor/EntityRendererAccessor.java delete mode 100644 client/src/main/java/su/plo/voice/client/render/ModEntityRenderer.java create mode 100644 client/src/main/kotlin/su/plo/voice/client/event/LivingEntityRenderEvent.kt diff --git a/client/1.21.2-fabric/gradle.properties b/client/1.21.2-fabric/gradle.properties new file mode 100644 index 00000000..2b00f5db --- /dev/null +++ b/client/1.21.2-fabric/gradle.properties @@ -0,0 +1 @@ +essential.defaults.loom.minecraft=com.mojang:minecraft:1.21.2-pre1 diff --git a/client/build.gradle.kts b/client/build.gradle.kts index 35242b5d..c7211f2d 100644 --- a/client/build.gradle.kts +++ b/client/build.gradle.kts @@ -88,11 +88,18 @@ dependencies { 12004 -> "0.95.4+1.20.4" 12006 -> "0.97.7+1.20.6" 12100 -> "0.100.4+1.21" + 12102 -> "0.105.3+1.21.2" else -> throw GradleException("Unsupported platform $platform") } modImplementation("net.fabricmc.fabric-api:fabric-api:${fabricApiVersion}") - "include"("me.lucko:fabric-permissions-api:0.2-SNAPSHOT") + + if (platform.mcVersion >= 12102) { + // https://github.com/lucko/fabric-permissions-api/pull/26 + "include"("com.github.sakura-ryoko:fabric-permissions-api:b43d33efb8") + } else { + "include"("me.lucko:fabric-permissions-api:0.2-SNAPSHOT") + } } val includedProjects = listOf( diff --git a/client/root.gradle.kts b/client/root.gradle.kts index 96c0aac4..bb9751d3 100644 --- a/client/root.gradle.kts +++ b/client/root.gradle.kts @@ -6,6 +6,8 @@ group = "$group.client-root" preprocess { + val fabric12102 = createNode("1.21.2-fabric", 12102, "official") + val neoForge12100 = createNode("1.21-neoforge", 12100, "official") val fabric12100 = createNode("1.21-fabric", 12100, "official") val forge12100 = createNode("1.21-forge", 12100, "official") @@ -34,6 +36,8 @@ preprocess { val forge11605 = createNode("1.16.5-forge", 11605, "official") val fabric11605 = createNode("1.16.5-fabric", 11605, "official") + fabric12102.link(fabric12100) + neoForge12100.link(fabric12100) fabric12100.link(fabric12004, file("1.21-1.20.6.txt")) forge12100.link(forge12004, file("1.21-1.20.6.txt")) diff --git a/client/src/main/java/su/plo/lib/mod/client/chat/ClientChatUtil.java b/client/src/main/java/su/plo/lib/mod/client/chat/ClientChatUtil.java index e92bc1eb..2a73a2b4 100644 --- a/client/src/main/java/su/plo/lib/mod/client/chat/ClientChatUtil.java +++ b/client/src/main/java/su/plo/lib/mod/client/chat/ClientChatUtil.java @@ -29,7 +29,9 @@ public static void sendChatMessage(@NonNull McTextComponent text) { public static void sendChatMessage(@NonNull Component message) { LocalPlayer player = Minecraft.getInstance().player; - //#if MC>=11900 + //#if MC>=12102 + //$$ player.displayClientMessage(message, false); + //#elseif MC>=11900 player.sendSystemMessage(message); //#elseif MC>=11602 //$$ player.sendMessage(message, null); diff --git a/client/src/main/java/su/plo/lib/mod/client/render/RenderUtil.java b/client/src/main/java/su/plo/lib/mod/client/render/RenderUtil.java index 3b7c7d9d..89cb3d9a 100644 --- a/client/src/main/java/su/plo/lib/mod/client/render/RenderUtil.java +++ b/client/src/main/java/su/plo/lib/mod/client/render/RenderUtil.java @@ -36,6 +36,11 @@ import net.minecraft.client.renderer.ShaderInstance; //#endif +//#if MC>=12102 +//$$ import net.minecraft.client.renderer.CoreShaders; +//$$ import net.minecraft.client.renderer.ShaderProgram; +//#endif + @UtilityClass public class RenderUtil { @@ -74,6 +79,18 @@ public static void disableScissor() { //#if MC>=11700 // Note: Needs to be an Identity hash map because VertexFormat's equals method is broken (compares via its // component Map but order very much matters for VertexFormat) as of 1.17 + //#if MC>=12102 + //$$ private static final Map DEFAULT_SHADERS = new IdentityHashMap<>(); + //$$ static { + //$$ + //$$ DEFAULT_SHADERS.put(DefaultVertexFormat.PARTICLE, CoreShaders.PARTICLE); + //$$ DEFAULT_SHADERS.put(DefaultVertexFormat.POSITION, CoreShaders.POSITION); + //$$ DEFAULT_SHADERS.put(DefaultVertexFormat.POSITION_COLOR, CoreShaders.POSITION_COLOR); + //$$ DEFAULT_SHADERS.put(DefaultVertexFormat.POSITION_COLOR_LIGHTMAP, CoreShaders.POSITION_COLOR_LIGHTMAP); + //$$ DEFAULT_SHADERS.put(DefaultVertexFormat.POSITION_TEX, CoreShaders.POSITION_TEX); + //$$ DEFAULT_SHADERS.put(DefaultVertexFormat.POSITION_TEX_COLOR, CoreShaders.POSITION_TEX_COLOR); + //$$ DEFAULT_SHADERS.put(DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP, CoreShaders.POSITION_COLOR_TEX_LIGHTMAP); + //#else private static final Map> DEFAULT_SHADERS = new IdentityHashMap<>(); static { DEFAULT_SHADERS.put(DefaultVertexFormat.PARTICLE, GameRenderer::getParticleShader); @@ -83,6 +100,7 @@ public static void disableScissor() { DEFAULT_SHADERS.put(DefaultVertexFormat.POSITION_TEX, GameRenderer::getPositionTexShader); DEFAULT_SHADERS.put(DefaultVertexFormat.POSITION_TEX_COLOR, GameRenderer::getPositionTexColorShader); DEFAULT_SHADERS.put(DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP, GameRenderer::getPositionColorTexLightmapShader); + //#endif //#if MC>=12100 //$$ // Shaders for these formats are no longer provided. //#else @@ -100,12 +118,16 @@ public static void disableScissor() { public static @NotNull BufferBuilder beginBufferWithDefaultShader(@NotNull VertexFormatMode mode, @NotNull VertexFormat format) { //#if MC>=11700 - Supplier supplier = DEFAULT_SHADERS.get(format); - if (supplier == null) { + //#if MC>=12102 + //$$ ShaderProgram shader = DEFAULT_SHADERS.get(format); + //#else + Supplier shader = DEFAULT_SHADERS.get(format); + //#endif + if (shader == null) { throw new IllegalArgumentException("No default shader for " + format + ". Bind your own and use beginBufferWithActiveShader instead."); } - RenderSystem.setShader(supplier); + RenderSystem.setShader(shader); //#endif return beginBufferWithActiveShader(mode, format); diff --git a/client/src/main/java/su/plo/voice/client/ModVoiceClient.java b/client/src/main/java/su/plo/voice/client/ModVoiceClient.java index 3dd99f93..2ba4ba77 100644 --- a/client/src/main/java/su/plo/voice/client/ModVoiceClient.java +++ b/client/src/main/java/su/plo/voice/client/ModVoiceClient.java @@ -4,7 +4,6 @@ import net.minecraft.client.Minecraft; import org.lwjgl.glfw.GLFW; import su.plo.slib.api.logging.McLoggerFactory; -import su.plo.slib.mod.channel.ModChannelManager; import su.plo.slib.mod.logging.Log4jLogger; import su.plo.voice.client.gui.settings.VoiceScreens; import lombok.Getter; @@ -19,7 +18,6 @@ import su.plo.voice.client.audio.device.JavaxInputDeviceFactory; import su.plo.voice.client.connection.ModClientChannelHandler; import su.plo.voice.client.event.key.KeyPressedEvent; -import su.plo.voice.client.render.ModEntityRenderer; import su.plo.voice.client.render.ModHudRenderer; import su.plo.voice.client.render.ModLevelRenderer; import su.plo.voice.util.version.ModrinthLoader; @@ -71,6 +69,7 @@ //#elseif NEOFORGE +//$$ import su.plo.slib.mod.channel.ModChannelManager; //$$ import su.plo.voice.server.ModVoiceServer; //$$ import net.neoforged.api.distmarker.Dist; //$$ import net.neoforged.bus.api.SubscribeEvent; @@ -108,8 +107,6 @@ public final class ModVoiceClient extends BaseVoiceClient private final ModHudRenderer hudRenderer; @Getter private final ModLevelRenderer levelRenderer; - @Getter - private final ModEntityRenderer entityRenderer; private final ModClientChannelHandler handler = new ModClientChannelHandler(this); @@ -133,7 +130,6 @@ public ModVoiceClient() { this.hudRenderer = new ModHudRenderer(this); this.levelRenderer = new ModLevelRenderer(this); - this.entityRenderer = new ModEntityRenderer(this); INSTANCE = this; RenderUtil.getTextConverter().setLanguageSupplier(createLanguageSupplier()); diff --git a/client/src/main/java/su/plo/voice/client/audio/SoundOcclusion.java b/client/src/main/java/su/plo/voice/client/audio/SoundOcclusion.java index 89d0168d..7c036e0a 100644 --- a/client/src/main/java/su/plo/voice/client/audio/SoundOcclusion.java +++ b/client/src/main/java/su/plo/voice/client/audio/SoundOcclusion.java @@ -78,7 +78,9 @@ public static double getOccludedPercent(Level world, Vec3 sound, Vec3 listener) if (i <= 1) continue; BlockState state = world.getBlockState(prevSoundPos); - //#if MC>=12000 + //#if MC>=12102 + //$$ boolean isSolid = state.isSolidRender(); + //#elseif MC>=12000 //$$ boolean isSolid = state.isSolidRender(world, prevSoundPos); //#else boolean isSolid = state.getMaterial().isSolid(); diff --git a/client/src/main/java/su/plo/voice/client/event/render/EntityRenderEvent.java b/client/src/main/java/su/plo/voice/client/event/render/EntityRenderEvent.java deleted file mode 100644 index c68d4df3..00000000 --- a/client/src/main/java/su/plo/voice/client/event/render/EntityRenderEvent.java +++ /dev/null @@ -1,37 +0,0 @@ -package su.plo.voice.client.event.render; - -import com.mojang.blaze3d.vertex.PoseStack; -import lombok.Getter; -import lombok.NonNull; -import net.minecraft.world.entity.Entity; -import su.plo.voice.api.event.Event; -import su.plo.voice.client.render.ModCamera; - -public final class EntityRenderEvent implements Event { - - @Getter - private final PoseStack stack; - @Getter - private final ModCamera camera; - @Getter - private final Entity entity; - @Getter - private final int light; - private final boolean label; - - public EntityRenderEvent(@NonNull PoseStack stack, - @NonNull ModCamera camera, - @NonNull Entity entity, - int light, - boolean label) { - this.stack = stack; - this.camera = camera; - this.light = light; - this.entity = entity; - this.label = label; - } - - public boolean hasLabel() { - return label; - } -} diff --git a/client/src/main/java/su/plo/voice/client/event/render/PlayerRenderEvent.java b/client/src/main/java/su/plo/voice/client/event/render/PlayerRenderEvent.java deleted file mode 100644 index 56136999..00000000 --- a/client/src/main/java/su/plo/voice/client/event/render/PlayerRenderEvent.java +++ /dev/null @@ -1,41 +0,0 @@ -package su.plo.voice.client.event.render; - -import com.mojang.blaze3d.vertex.PoseStack; -import lombok.Getter; -import lombok.NonNull; -import net.minecraft.world.entity.player.Player; -import su.plo.voice.api.event.Event; -import su.plo.voice.client.render.ModCamera; - -public final class PlayerRenderEvent implements Event { - - @Getter - private final PoseStack stack; - @Getter - private final ModCamera camera; - @Getter - private final Player player; - @Getter - private final int light; - private final boolean label; - @Getter - private final boolean fakePlayer; - - public PlayerRenderEvent(@NonNull PoseStack stack, - @NonNull ModCamera camera, - @NonNull Player player, - int light, - boolean label, - boolean fakePlayer) { - this.stack = stack; - this.camera = camera; - this.light = light; - this.player = player; - this.label = label; - this.fakePlayer = fakePlayer; - } - - public boolean hasLabel() { - return label; - } -} diff --git a/client/src/main/java/su/plo/voice/client/gui/PlayerVolumeAction.java b/client/src/main/java/su/plo/voice/client/gui/PlayerVolumeAction.java index dc9ae8fd..a7b7f789 100644 --- a/client/src/main/java/su/plo/voice/client/gui/PlayerVolumeAction.java +++ b/client/src/main/java/su/plo/voice/client/gui/PlayerVolumeAction.java @@ -97,7 +97,10 @@ private Optional getPlayerBySight() { (int) Math.floor(playerPos.z) ); BlockState state = level.getBlockState(blockPos); - //#if MC>=12000 + + //#if MC>=12102 + //$$ boolean isSolid = state.isSolidRender(); + //#elseif MC>=12000 //$$ boolean isSolid = state.isSolidRender(level, blockPos); //#else boolean isSolid = state.getMaterial().isSolid(); diff --git a/client/src/main/java/su/plo/voice/client/mixin/MixinEntityRenderDispatcher.java b/client/src/main/java/su/plo/voice/client/mixin/MixinEntityRenderDispatcher.java new file mode 100644 index 00000000..3fcc0367 --- /dev/null +++ b/client/src/main/java/su/plo/voice/client/mixin/MixinEntityRenderDispatcher.java @@ -0,0 +1,94 @@ +package su.plo.voice.client.mixin; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.entity.EntityRenderDispatcher; +import net.minecraft.client.renderer.entity.EntityRenderer; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import su.plo.voice.client.event.LivingEntityRenderEvent; +import su.plo.voice.client.mixin.accessor.EntityRendererAccessor; + +//#if MC>=12102 +//$$ import net.minecraft.client.Camera; +//$$ import net.minecraft.client.Minecraft; +//#else +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +//#endif + +@Mixin(EntityRenderDispatcher.class) +public class MixinEntityRenderDispatcher { + + //#if MC>=12102 + //$$ @Inject( + //$$ method = "render(Lnet/minecraft/world/entity/Entity;DDDFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;ILnet/minecraft/client/renderer/entity/EntityRenderer;)V", + //$$ at = @At( + //$$ value = "INVOKE", + //$$ shift = At.Shift.AFTER, + //$$ target = "Lnet/minecraft/client/renderer/entity/EntityRenderer;render(Lnet/minecraft/client/renderer/entity/state/EntityRenderState;Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V" + //$$ ) + //$$ ) + //$$ public void render( + //$$ Entity entity, + //$$ double d, + //$$ double e, + //$$ double f, + //$$ float g, + //$$ PoseStack poseStack, + //$$ MultiBufferSource multiBufferSource, + //$$ int light, + //$$ EntityRenderer entityRenderer, + //$$ CallbackInfo ci + //$$ ) { + //$$ if (!(entity instanceof LivingEntity)) return; + //$$ + //$$ Camera camera = Minecraft.getInstance().gameRenderer.getMainCamera(); + //$$ double distanceToCamera = camera.getPosition().distanceToSqr(entity.position()); + //$$ + //$$ EntityRendererAccessor rendererAccessor = (EntityRendererAccessor) entityRenderer; + //$$ LivingEntityRenderEvent.INSTANCE.getInvoker().onRender( + //$$ (LivingEntity) entity, + //$$ poseStack, + //$$ light, + //$$ rendererAccessor.shouldShowName(entity, distanceToCamera) + //$$ ); + //$$ } + //#else + @Inject( + method = "render", + at = @At( + value = "INVOKE", + shift = At.Shift.AFTER, + target = "Lnet/minecraft/client/renderer/entity/EntityRenderer;render(Lnet/minecraft/world/entity/Entity;FFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V" + ), + locals = LocalCapture.CAPTURE_FAILHARD + ) + public void render( + Entity entity, + double d, + double e, + double f, + float g, + float h, + PoseStack poseStack, + MultiBufferSource multiBufferSource, + int light, + CallbackInfo ci, + EntityRenderer entityRenderer + ) { + if (!(entity instanceof LivingEntity)) return; + + EntityRendererAccessor rendererAccessor = (EntityRendererAccessor) entityRenderer; + LivingEntityRenderEvent.INSTANCE.getInvoker().onRender( + (LivingEntity) entity, + poseStack, + light, + rendererAccessor.shouldShowName(entity) + ); + } + //#endif +} diff --git a/client/src/main/java/su/plo/voice/client/mixin/MixinEntityRenderer.java b/client/src/main/java/su/plo/voice/client/mixin/MixinEntityRenderer.java deleted file mode 100644 index b7e38815..00000000 --- a/client/src/main/java/su/plo/voice/client/mixin/MixinEntityRenderer.java +++ /dev/null @@ -1,35 +0,0 @@ -package su.plo.voice.client.mixin; - -import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.entity.LivingEntityRenderer; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.LivingEntity; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import su.plo.voice.client.ModVoiceClient; - -@Mixin(LivingEntityRenderer.class) -public abstract class MixinEntityRenderer { - - @Shadow protected abstract boolean shouldShowName(Entity par1); - - @Inject(method = "render", at = @At(value = "RETURN")) - public void render(LivingEntity entity, float f, float g, PoseStack poseStack, MultiBufferSource multiBufferSource, int i, CallbackInfo ci) { - if (!ModVoiceClient.INSTANCE.getServerInfo().isPresent()) return; - - ModVoiceClient.INSTANCE.getEntityRenderer().render( - poseStack, - multiBufferSource, - Minecraft.getInstance().gameRenderer.getMainCamera(), - i, - entity, - shouldShowName(entity) - ); - } -} - diff --git a/client/src/main/java/su/plo/voice/client/mixin/accessor/EntityRendererAccessor.java b/client/src/main/java/su/plo/voice/client/mixin/accessor/EntityRendererAccessor.java new file mode 100644 index 00000000..8bf4b28b --- /dev/null +++ b/client/src/main/java/su/plo/voice/client/mixin/accessor/EntityRendererAccessor.java @@ -0,0 +1,18 @@ +package su.plo.voice.client.mixin.accessor; + +import net.minecraft.client.renderer.entity.EntityRenderer; +import net.minecraft.world.entity.Entity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(EntityRenderer.class) +public interface EntityRendererAccessor { + + //#if MC>=12102 + //$$ @Invoker("shouldShowName") + //$$ boolean shouldShowName(Entity entity, double distanceToCamera); + //#else + @Invoker("shouldShowName") + boolean shouldShowName(Entity entity); + //#endif +} diff --git a/client/src/main/java/su/plo/voice/client/render/ModEntityRenderer.java b/client/src/main/java/su/plo/voice/client/render/ModEntityRenderer.java deleted file mode 100644 index 57b21af8..00000000 --- a/client/src/main/java/su/plo/voice/client/render/ModEntityRenderer.java +++ /dev/null @@ -1,60 +0,0 @@ -package su.plo.voice.client.render; - -import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.Camera; -import net.minecraft.client.Minecraft; -import net.minecraft.client.player.AbstractClientPlayer; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.world.entity.Entity; -import org.jetbrains.annotations.NotNull; -import su.plo.voice.api.client.PlasmoVoiceClient; -import su.plo.voice.client.event.render.EntityRenderEvent; -import su.plo.voice.client.event.render.PlayerRenderEvent; - -public final class ModEntityRenderer extends ModRenderer { - - public ModEntityRenderer(@NotNull PlasmoVoiceClient voiceClient) { - super(voiceClient); - } - - public void render(@NotNull PoseStack poseStack, - @NotNull MultiBufferSource multiBufferSource, - @NotNull Camera camera, - int light, - @NotNull Entity entity, - boolean hasLabel) { - if (entity instanceof AbstractClientPlayer) { - this.render(poseStack, multiBufferSource, camera, light, (AbstractClientPlayer) entity, hasLabel); - return; - } - - voiceClient.getEventBus().fire(new EntityRenderEvent( - poseStack, - new ModCamera(camera.getPosition(), camera.getXRot(), camera.getYRot()), - entity, - light, - hasLabel - )); - } - - private void render(@NotNull PoseStack poseStack, - @NotNull MultiBufferSource multiBufferSource, - @NotNull Camera camera, - int light, - @NotNull AbstractClientPlayer player, - boolean hasLabel) { - boolean isFakePlayer = false; - if (Minecraft.getInstance().player != null) { - isFakePlayer = !Minecraft.getInstance().getConnection().getOnlinePlayerIds().contains(player.getUUID()); - } - - voiceClient.getEventBus().fire(new PlayerRenderEvent( - poseStack, - new ModCamera(camera.getPosition(), camera.getXRot(), camera.getYRot()), - player, - light, - hasLabel, - isFakePlayer - )); - } -} diff --git a/client/src/main/java/su/plo/voice/client/render/voice/SourceIconRenderer.java b/client/src/main/java/su/plo/voice/client/render/voice/SourceIconRenderer.java index e14132b5..53d70098 100644 --- a/client/src/main/java/su/plo/voice/client/render/voice/SourceIconRenderer.java +++ b/client/src/main/java/su/plo/voice/client/render/voice/SourceIconRenderer.java @@ -4,12 +4,14 @@ import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.PoseStack; import lombok.NonNull; +import net.minecraft.client.Camera; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.renderer.RenderType; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.Vec3; import net.minecraft.world.scores.Objective; @@ -28,9 +30,8 @@ import su.plo.voice.api.event.EventSubscribe; import su.plo.voice.client.audio.source.ClientStaticSource; import su.plo.voice.client.config.VoiceClientConfig; -import su.plo.voice.client.event.render.EntityRenderEvent; +import su.plo.voice.client.event.LivingEntityRenderEvent; import su.plo.voice.client.event.render.LevelRenderEvent; -import su.plo.voice.client.event.render.PlayerRenderEvent; import su.plo.voice.client.gui.PlayerVolumeAction; import su.plo.voice.client.render.ModCamera; import su.plo.voice.proto.data.audio.source.EntitySourceInfo; @@ -59,6 +60,8 @@ public SourceIconRenderer( this.voiceClient = voiceClient; this.config = config; this.volumeAction = volumeAction; + + LivingEntityRenderEvent.INSTANCE.registerListener(this::onLivingEntityRender); } @EventSubscribe @@ -91,19 +94,36 @@ public void onLevelRender(@NotNull LevelRenderEvent event) { } } - @EventSubscribe - public void onPlayerRender(@NotNull PlayerRenderEvent event) { + private void onLivingEntityRender( + @NotNull LivingEntity entity, + @NotNull PoseStack stack, + int light, + boolean shouldShowName + ) { + if (entity instanceof Player) { + renderPlayer((Player) entity, stack, light, shouldShowName); + } else { + renderLivingEntity(entity, stack, light, shouldShowName); + } + } + + private void renderPlayer( + @NotNull Player player, + @NotNull PoseStack stack, + int light, + boolean shouldShowName + ) { Optional connection = voiceClient.getServerConnection(); if (!connection.isPresent()) return; - Player player = event.getPlayer(); - LocalPlayer clientPlayer = Minecraft.getInstance().player; if (clientPlayer == null) return; + boolean isFakePlayer = !Minecraft.getInstance().getConnection().getOnlinePlayerIds().contains(player.getUUID()); + if (isIconHidden() || player.getUUID().equals(clientPlayer.getUUID()) - || event.isFakePlayer() + || isFakePlayer || player.isInvisibleTo(clientPlayer) ) return; @@ -126,11 +146,10 @@ public void onPlayerRender(@NotNull PlayerRenderEvent event) { hasPercent = volumeAction.isShown(player); if (hasPercent) { renderPercent( - event.getStack(), - event.getCamera(), - event.getLight(), player, - event.hasLabel() + stack, + light, + shouldShowName ); } @@ -144,23 +163,24 @@ public void onPlayerRender(@NotNull PlayerRenderEvent event) { } renderEntity( - event.getStack(), - event.getCamera(), - event.getLight(), player, + stack, + light, + shouldShowName, ResourceLocation.tryParse(iconLocation), - event.hasLabel(), hasPercent ); } - @EventSubscribe - public void onEntityRender(@NotNull EntityRenderEvent event) { + private void renderLivingEntity( + @NotNull LivingEntity entity, + @NotNull PoseStack stack, + int light, + boolean shouldShowName + ) { Optional connection = voiceClient.getServerConnection(); if (!connection.isPresent()) return; - Entity entity = event.getEntity(); - LocalPlayer clientPlayer = Minecraft.getInstance().player; if (clientPlayer == null) return; @@ -173,32 +193,33 @@ public void onEntityRender(@NotNull EntityRenderEvent event) { if (highestSourceLine == null) return; renderEntity( - event.getStack(), - event.getCamera(), - event.getLight(), entity, + stack, + light, + shouldShowName, ResourceLocation.tryParse(highestSourceLine.getIcon()), - event.hasLabel(), false ); } - public void renderEntity(@NonNull PoseStack stack, - @NonNull ModCamera camera, - int light, - @NonNull Entity entity, - @NonNull ResourceLocation iconLocation, - boolean hasLabel, - boolean hasPercent) { + private void renderEntity( + @NonNull Entity entity, + @NonNull PoseStack stack, + int light, + boolean hasLabel, + @NonNull ResourceLocation iconLocation, + boolean hasPercent + ) { Vec3 position = entity.position(); - double distance = camera.position().distanceToSqr(position); + Camera camera = Minecraft.getInstance().gameRenderer.getMainCamera(); + double distance = camera.getPosition().distanceToSqr(position.x(), position.y(), position.z()); if (distance > 4096D) return; stack.pushPose(); if (hasPercent) stack.translate(0D, 0.3D, 0D); - translateEntityMatrix(stack, camera, entity, distance, hasLabel); + translateEntityMatrix(entity, camera, stack, distance, hasLabel); if (entity.isDescending()) { vertices(stack, 40, light, iconLocation, false); @@ -210,19 +231,21 @@ public void renderEntity(@NonNull PoseStack stack, stack.popPose(); } - private void renderPercent(@NonNull PoseStack stack, - @NonNull ModCamera camera, - int light, - @NotNull Entity entity, - boolean hasLabel) { + private void renderPercent( + @NotNull Entity entity, + @NonNull PoseStack stack, + int light, + boolean hasLabel + ) { Vec3 position = entity.position(); - double distance = camera.position().distanceToSqr(position); + Camera camera = Minecraft.getInstance().gameRenderer.getMainCamera(); + double distance = camera.getPosition().distanceToSqr(position.x(), position.y(), position.z()); if (distance > 4096D) return; stack.pushPose(); - translateEntityMatrix(stack, camera, entity, distance, hasLabel); + translateEntityMatrix(entity, camera, stack, distance, hasLabel); stack.translate(5D, 0D, 0D); // render percents @@ -272,11 +295,13 @@ private void renderPercent(@NonNull PoseStack stack, stack.popPose(); } - private void translateEntityMatrix(@NonNull PoseStack stack, - @NonNull ModCamera camera, - @NotNull Entity entity, - double distance, - boolean hasLabel) { + private void translateEntityMatrix( + @NotNull Entity entity, + @NonNull Camera camera, + @NonNull PoseStack stack, + double distance, + boolean hasLabel + ) { if (hasLabel) { stack.translate(0D, 0.3D, 0D); @@ -291,8 +316,8 @@ private void translateEntityMatrix(@NonNull PoseStack stack, } stack.translate(0D, entity.getBbHeight() + 0.5D, 0D); - PoseStackKt.rotate(stack, -camera.pitch(), 0.0F, 1.0F, 0.0F); - PoseStackKt.rotate(stack, camera.yaw(), 1.0F, 0.0F, 0.0F); + PoseStackKt.rotate(stack, -camera.getYRot(), 0.0F, 1.0F, 0.0F); + PoseStackKt.rotate(stack, camera.getXRot(), 1.0F, 0.0F, 0.0F); stack.scale(-0.025F, -0.025F, 0.025F); stack.translate(-5D, -1D, 0D); } diff --git a/client/src/main/kotlin/gg/essential/universal/shader/BlendState.kt b/client/src/main/kotlin/gg/essential/universal/shader/BlendState.kt index c11a4cf8..8ca7c9fb 100644 --- a/client/src/main/kotlin/gg/essential/universal/shader/BlendState.kt +++ b/client/src/main/kotlin/gg/essential/universal/shader/BlendState.kt @@ -4,10 +4,6 @@ import com.mojang.blaze3d.systems.RenderSystem import org.lwjgl.opengl.GL11 import org.lwjgl.opengl.GL14 -//#if MC>=11700 -import com.mojang.blaze3d.shaders.BlendMode -//#endif - //#if MC>=11500 import org.lwjgl.opengl.GL20 //#endif @@ -20,38 +16,7 @@ data class BlendState( val dstAlpha: Param = dstRgb, val enabled: Boolean = true, ) { - val separate = srcRgb != srcAlpha || dstRgb != dstAlpha - - //#if MC>=11700 - private inner class McBlendState : BlendMode { - constructor() : super() - constructor(srcRgb: Int, dstRgb: Int, func: Int) : super(srcRgb, dstRgb, func) - constructor(srcRgb: Int, dstRgb: Int, srcAlpha: Int, dstAlpha: Int, func: Int) : super(srcRgb, dstRgb, srcAlpha, dstAlpha, func) - - override fun apply() { - super.apply() - // MC's enable function is fundamentally broken because it is lazy in that it does not update anything - // if the previously active blend state matches this one. But that assumes that it is the only method which - // can modify the global GL state, which is just a horrible assumption and MC itself immediately violates - // it in RenderLayer. - // So, to actually get our state applied, we gotta do it ourselves. - this@BlendState.applyState() - } - } - val mc: BlendMode = if (enabled) { - if (separate) { - McBlendState(srcRgb.glId, dstRgb.glId, srcAlpha.glId, dstAlpha.glId, equation.glId) - } else { - McBlendState(srcRgb.glId, dstRgb.glId, equation.glId) - } - } else { - McBlendState() - } - - fun activate() = mc.apply() - //#else - //$$ fun activate() = applyState() - //#endif + fun activate() = applyState() private fun applyState() { if (enabled) { diff --git a/client/src/main/kotlin/gg/essential/universal/shader/MCShader.kt b/client/src/main/kotlin/gg/essential/universal/shader/MCShader.kt index 6e73ca04..02721a83 100644 --- a/client/src/main/kotlin/gg/essential/universal/shader/MCShader.kt +++ b/client/src/main/kotlin/gg/essential/universal/shader/MCShader.kt @@ -28,6 +28,12 @@ import java.util.Optional //$$ import com.mojang.blaze3d.vertex.VertexFormatElement //#endif +//#if MC>=12102 +//$$ import net.minecraft.client.Minecraft +//$$ import net.minecraft.client.renderer.ShaderDefines +//$$ import net.minecraft.client.renderer.ShaderProgram +//#endif + internal class MCShader( private val mc: ShaderInstance, private val blendState: BlendState @@ -35,7 +41,11 @@ internal class MCShader( override var usable = true override fun bind() { + //#if MC>=12102 + //$$ RenderSystem.setShader(mc) + //#else RenderSystem.setShader(::mc) + //#endif // MC's GlBlendState is fundamentally broken because it is lazy in that it does not update anything // if the previously active blend state matches this one. But that assumes that it is the only method which @@ -46,7 +56,11 @@ internal class MCShader( } override fun unbind() { + //#if MC>=12102 + //$$ RenderSystem.clearShader() + //#else RenderSystem.setShader { null } + //#endif } private fun getUniformOrNull(name: String) = mc.getUniform(name)?.let(::MCShaderUniform) @@ -145,7 +159,25 @@ internal class MCShader( val name = DigestUtils.sha1Hex(json).lowercase() + + //#if MC>=12102 + //$$ val shaderLocation = ResourceLocation.parse( + //$$ "plasmovoice:shaders/$name", + //$$ ) + //$$ + //$$ val shaderProgram = ShaderProgram( + //$$ shaderLocation, + //$$ shaderVertexFormat, + //$$ ShaderDefines.EMPTY + //$$ ) + //$$ Minecraft.getInstance().shaderManager.preloadForStartup(factory, shaderProgram) + //$$ val compiledShaderProgram = Minecraft.getInstance().shaderManager.getProgram(shaderProgram) + //$$ ?: throw IllegalStateException("Failed to compile shader") + //$$ + //$$ return MCShader(compiledShaderProgram, blendState) + //#else return MCShader(ShaderInstance(factory, name, shaderVertexFormat), blendState) + //#endif } } } @@ -171,7 +203,11 @@ internal class MCSamplerUniform(val mc: ShaderInstance, val name: String) : Samp override val location: Int = 0 override fun setValue(textureId: Int) { + //#if MC>=12102 + //$$ mc.bindSampler(name, textureId) + //#else mc.setSampler(name, textureId) + //#endif } } diff --git a/client/src/main/kotlin/su/plo/voice/client/event/LivingEntityRenderEvent.kt b/client/src/main/kotlin/su/plo/voice/client/event/LivingEntityRenderEvent.kt new file mode 100644 index 00000000..544275a3 --- /dev/null +++ b/client/src/main/kotlin/su/plo/voice/client/event/LivingEntityRenderEvent.kt @@ -0,0 +1,24 @@ +package su.plo.voice.client.event + +import com.mojang.blaze3d.vertex.PoseStack +import net.minecraft.world.entity.LivingEntity +import su.plo.slib.api.event.GlobalEvent +import su.plo.voice.client.event.LivingEntityRenderEvent.Callback + +object LivingEntityRenderEvent : GlobalEvent( + { callbacks -> + Callback { entity, stack, light, shouldRenderLabel -> + callbacks.forEach { it.onRender(entity, stack, light, shouldRenderLabel) } + } + } +) { + + fun interface Callback { + fun onRender( + entity: LivingEntity, + stack: PoseStack, + light: Int, + shouldRenderLabel: Boolean + ) + } +} \ No newline at end of file diff --git a/client/src/main/resources/plasmovoice.mixins.json b/client/src/main/resources/plasmovoice.mixins.json index d936a0c9..1b9afea5 100644 --- a/client/src/main/resources/plasmovoice.mixins.json +++ b/client/src/main/resources/plasmovoice.mixins.json @@ -3,14 +3,16 @@ "minVersion": "0.7", "package": "su.plo.voice.client.mixin", "client": [ - "MixinEntityRenderer", "MixinKeyboardHandler", "MixinLanguageManager", "MixinMouseHandler", "MixinReloadableResourceManager", "MixinSkinManager", "MixinPlayerListEntry", - "MixinIntegratedServer" + "MixinIntegratedServer", + + "MixinEntityRenderDispatcher", + "accessor.EntityRendererAccessor" ], "injectors": { "defaultRequire": 1 diff --git a/client/versions.toml b/client/versions.toml index 42e0860b..e435bfe5 100644 --- a/client/versions.toml +++ b/client/versions.toml @@ -1,15 +1,18 @@ +[12102] +mcVersions = [">1.21.1"] + [12100] -mcVersions = [">=1.21"] +mcVersions = [">=1.21 <=1.21.1"] forgeVersion = "[51,)" neoForgeVersion = "[20,)" [12004] forgeVersion = "[49,)" -mcVersions = ["1.20.2", "1.20.3", "1.20.4"] +mcVersions = [">=1.20.2 <=1.20.4"] [12001] forgeVersion = "[46,)" -mcVersions = ["1.20", "1.20.1"] +mcVersions = [">=1.20 <=1.20.1"] [11904] forgeVersion = "[45,)" From f9e884d5e4becef625580e2f163b92be95872b07 Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Wed, 9 Oct 2024 20:41:59 +0800 Subject: [PATCH 08/13] ci: update changelog --- client/changelog.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/changelog.md b/client/changelog.md index d8bdbaa5..4a6ccd79 100644 --- a/client/changelog.md +++ b/client/changelog.md @@ -10,4 +10,6 @@ so there’s no need to worry if the server hasn't been updated to 2.1.x. - Soften Minecraft version bounds: - 1.20.4 now allows 1.20.2, 1.20.3 and 1.20.4 - 1.19.2 now allows 1.19, 1.19.1 and 1.19.2 -- Updated [slib](https://github.com/plasmoapp/mc-slib) to fix crash with EssentialAddons on world join. \ No newline at end of file +- Updated to 1.21.2-pre1. +- Updated [slib](https://github.com/plasmoapp/mc-slib) to fix crash with EssentialAddons on world join. +- Fixed audio sources causing a high CPU load. [#421](https://github.com/plasmoapp/plasmo-voice/issues/421) From b79a3857ce3ea51c3c4ccc0d69857047a077f6ff Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Fri, 11 Oct 2024 23:07:54 +0800 Subject: [PATCH 09/13] build: properly convert semver to maven version range for forge/neoforge --- client/build.gradle.kts | 49 ++++++++++++++++++----- client/src/main/resources/fabric.mod.json | 2 +- client/versions.toml | 20 ++++----- 3 files changed, 51 insertions(+), 20 deletions(-) diff --git a/client/build.gradle.kts b/client/build.gradle.kts index c7211f2d..2b06b583 100644 --- a/client/build.gradle.kts +++ b/client/build.gradle.kts @@ -242,21 +242,52 @@ tasks { data class VersionInfo( val neoForgeVersion: String, val forgeVersion: String, - val mcVersions: List + val mcVersions: String ) { - // "${mcVersions}" -> "[1.20,1.20.1]" - val forgeMcVersions - get() = - if (mcVersions[0].startsWith(">=")) { - "[${mcVersions[0].substringAfter(">=")},)" + val forgeMcVersions: String + get() { + val split = mcVersions.split(" ") + + fun versionBounds(version: String): Triple? = + when { + version.startsWith(">=") -> Triple( + "[", version.substringAfter(">="), ",)" + ) + version.startsWith(">") -> Triple( + "(", version.substringAfter(">"), ",)" + ) + version.startsWith("<=") -> Triple( + "(,", version.substringAfter("<="), "]" + ) + version.startsWith("<") -> Triple( + "(,", version.substringAfter("<"), ")" + ) + else -> null + } + + if (split.size == 1) { + val version = split.first() + val bounds = versionBounds(version) + + return if (bounds == null) { + "[$version]" + } else { + "${bounds.first}${bounds.second}${bounds.third}" + } + } else if (split.size == 2) { + val bounds = split.map { versionBounds(it)!! } + val first = bounds[0] + val second = bounds[1] + + return "${first.first}${first.second},${second.second}${second.third}" } else { - "[${mcVersions.joinToString(",")}]" + throw IllegalStateException("Invalid version") } + } - // ["${mcVersions}"] -> ["1.20", "1.20.1"] val fabricMcVersions - get() = mcVersions.joinToString("\", \"") + get() = mcVersions } fun readVersionInfo(): VersionInfo = Toml() diff --git a/client/src/main/resources/fabric.mod.json b/client/src/main/resources/fabric.mod.json index 17d11cf5..59b73edb 100644 --- a/client/src/main/resources/fabric.mod.json +++ b/client/src/main/resources/fabric.mod.json @@ -30,6 +30,6 @@ "depends": { "fabric": "*", "fabricloader": "*", - "minecraft": ["${mcVersions}"] + "minecraft": "${mcVersions}" } } diff --git a/client/versions.toml b/client/versions.toml index e435bfe5..714d54b3 100644 --- a/client/versions.toml +++ b/client/versions.toml @@ -1,39 +1,39 @@ [12102] -mcVersions = [">1.21.1"] +mcVersions = ">1.21.1" [12100] -mcVersions = [">=1.21 <=1.21.1"] +mcVersions = ">=1.21.0 <=1.21.1" forgeVersion = "[51,)" neoForgeVersion = "[20,)" [12004] forgeVersion = "[49,)" -mcVersions = [">=1.20.2 <=1.20.4"] +mcVersions = ">=1.20.2 <=1.20.4" [12001] forgeVersion = "[46,)" -mcVersions = [">=1.20 <=1.20.1"] +mcVersions = ">=1.20.0 <=1.20.1" [11904] forgeVersion = "[45,)" -mcVersions = ["1.19.4"] +mcVersions = "1.19.4" [11903] forgeVersion = "[44,)" -mcVersions = ["1.19.3"] +mcVersions = "1.19.3" [11902] forgeVersion = "[41,)" -mcVersions = [">=1.19 <1.19.3"] +mcVersions = ">=1.19 <1.19.3" [11802] forgeVersion = "[40,)" -mcVersions = ["1.18.2"] +mcVersions = "1.18.2" [11701] forgeVersion = "[37,)" -mcVersions = ["1.17.1"] +mcVersions = "1.17.1" [11605] forgeVersion = "[32,)" -mcVersions = ["1.16.5"] +mcVersions = "1.16.5" From cfef1645b7247031e40f310540528ff9f18f87f2 Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Sun, 13 Oct 2024 06:30:08 +0800 Subject: [PATCH 10/13] fix: create new instance of source and player positions on each source packet send to avoid race conditions #422 --- .../voice/server/audio/source/VoiceServerEntitySource.kt | 6 ++---- .../voice/server/audio/source/VoiceServerPlayerSource.kt | 4 +--- .../voice/server/audio/source/VoiceServerProximitySource.kt | 4 ++-- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/server/common/src/main/kotlin/su/plo/voice/server/audio/source/VoiceServerEntitySource.kt b/server/common/src/main/kotlin/su/plo/voice/server/audio/source/VoiceServerEntitySource.kt index 73947c5d..0b8a6bd8 100644 --- a/server/common/src/main/kotlin/su/plo/voice/server/audio/source/VoiceServerEntitySource.kt +++ b/server/common/src/main/kotlin/su/plo/voice/server/audio/source/VoiceServerEntitySource.kt @@ -21,10 +21,8 @@ class VoiceServerEntitySource( ) : VoiceServerProximitySource(voiceServer, addon, UUID.randomUUID(), line, decoderInfo, stereo), ServerEntitySource { - override val position: ServerPos3d = entity.getServerPosition() - get() { - return entity.getServerPosition(field) - } + override val position: ServerPos3d + get() = entity.getServerPosition() override val sourceInfo: EntitySourceInfo get() = EntitySourceInfo( diff --git a/server/common/src/main/kotlin/su/plo/voice/server/audio/source/VoiceServerPlayerSource.kt b/server/common/src/main/kotlin/su/plo/voice/server/audio/source/VoiceServerPlayerSource.kt index fcffc870..098423a6 100644 --- a/server/common/src/main/kotlin/su/plo/voice/server/audio/source/VoiceServerPlayerSource.kt +++ b/server/common/src/main/kotlin/su/plo/voice/server/audio/source/VoiceServerPlayerSource.kt @@ -21,10 +21,8 @@ class VoiceServerPlayerSource( ) : VoiceServerProximitySource(voiceServer, addon, UUID.randomUUID(), line, decoderInfo, stereo), ServerPlayerSource { - private val playerPosition = ServerPos3d() - override val position: ServerPos3d - get() = player.instance.getServerPosition(playerPosition) + get() = player.instance.getServerPosition() override val sourceInfo: PlayerSourceInfo get() = PlayerSourceInfo( diff --git a/server/common/src/main/kotlin/su/plo/voice/server/audio/source/VoiceServerProximitySource.kt b/server/common/src/main/kotlin/su/plo/voice/server/audio/source/VoiceServerProximitySource.kt index c5852158..d4a769ae 100644 --- a/server/common/src/main/kotlin/su/plo/voice/server/audio/source/VoiceServerProximitySource.kt +++ b/server/common/src/main/kotlin/su/plo/voice/server/audio/source/VoiceServerProximitySource.kt @@ -27,8 +27,6 @@ abstract class VoiceServerProximitySource( stereo: Boolean ) : BaseServerAudioSource(addon, id, serverSourceLine, decoderInfo, stereo), ServerProximitySource { - private val playerPosition = ServerPos3d() - override var angle: Int = 0 get() = field set(value) { @@ -50,6 +48,7 @@ abstract class VoiceServerProximitySource( if (dirty.compareAndSet(true, false)) sendPacket(SourceInfoPacket(sourceInfo), listenersDistance.toShort()) + val playerPosition = ServerPos3d() val sourcePosition = position val distanceSquared = (listenersDistance * listenersDistance).toDouble() @@ -74,6 +73,7 @@ abstract class VoiceServerProximitySource( val listenersDistance = event.distance * DISTANCE_MULTIPLIER + val playerPosition = ServerPos3d() val sourcePosition = position val distanceSquared = (listenersDistance * listenersDistance).toDouble() From fdf1f4079a6f94412b915e7c98a8245dfd44e4b2 Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Wed, 23 Oct 2024 04:28:19 +0800 Subject: [PATCH 11/13] feat(client): 1.21.1 neoforge --- client/1.21.2-fabric/gradle.properties | 2 +- client/1.21.2-neoforge/gradle.properties | 1 + client/root.gradle.kts | 2 ++ .../plo/voice/client/mixin/MixinEntityRenderDispatcher.java | 4 ++-- .../voice/client/mixin/accessor/EntityRendererAccessor.java | 4 ++-- client/versions.toml | 1 + 6 files changed, 9 insertions(+), 5 deletions(-) create mode 100644 client/1.21.2-neoforge/gradle.properties diff --git a/client/1.21.2-fabric/gradle.properties b/client/1.21.2-fabric/gradle.properties index 2b00f5db..bbcbaaff 100644 --- a/client/1.21.2-fabric/gradle.properties +++ b/client/1.21.2-fabric/gradle.properties @@ -1 +1 @@ -essential.defaults.loom.minecraft=com.mojang:minecraft:1.21.2-pre1 +essential.defaults.loom.minecraft=com.mojang:minecraft:1.21.2 diff --git a/client/1.21.2-neoforge/gradle.properties b/client/1.21.2-neoforge/gradle.properties new file mode 100644 index 00000000..809aed51 --- /dev/null +++ b/client/1.21.2-neoforge/gradle.properties @@ -0,0 +1 @@ +essential.defaults.loom.neoForge=net.neoforged:neoforge:21.2.0-beta diff --git a/client/root.gradle.kts b/client/root.gradle.kts index bb9751d3..f9ef6974 100644 --- a/client/root.gradle.kts +++ b/client/root.gradle.kts @@ -6,6 +6,7 @@ group = "$group.client-root" preprocess { + val neoForge12102 = createNode("1.21.2-neoforge", 12102, "official") val fabric12102 = createNode("1.21.2-fabric", 12102, "official") val neoForge12100 = createNode("1.21-neoforge", 12100, "official") @@ -37,6 +38,7 @@ preprocess { val fabric11605 = createNode("1.16.5-fabric", 11605, "official") fabric12102.link(fabric12100) + neoForge12102.link(neoForge12100) neoForge12100.link(fabric12100) fabric12100.link(fabric12004, file("1.21-1.20.6.txt")) diff --git a/client/src/main/java/su/plo/voice/client/mixin/MixinEntityRenderDispatcher.java b/client/src/main/java/su/plo/voice/client/mixin/MixinEntityRenderDispatcher.java index 3fcc0367..b55db44e 100644 --- a/client/src/main/java/su/plo/voice/client/mixin/MixinEntityRenderDispatcher.java +++ b/client/src/main/java/su/plo/voice/client/mixin/MixinEntityRenderDispatcher.java @@ -54,7 +54,7 @@ public class MixinEntityRenderDispatcher { //$$ (LivingEntity) entity, //$$ poseStack, //$$ light, - //$$ rendererAccessor.shouldShowName(entity, distanceToCamera) + //$$ rendererAccessor.plasmovoice_shouldShowName(entity, distanceToCamera) //$$ ); //$$ } //#else @@ -87,7 +87,7 @@ public void render( (LivingEntity) entity, poseStack, light, - rendererAccessor.shouldShowName(entity) + rendererAccessor.plasmovoice_shouldShowName(entity) ); } //#endif diff --git a/client/src/main/java/su/plo/voice/client/mixin/accessor/EntityRendererAccessor.java b/client/src/main/java/su/plo/voice/client/mixin/accessor/EntityRendererAccessor.java index 8bf4b28b..54d8baea 100644 --- a/client/src/main/java/su/plo/voice/client/mixin/accessor/EntityRendererAccessor.java +++ b/client/src/main/java/su/plo/voice/client/mixin/accessor/EntityRendererAccessor.java @@ -10,9 +10,9 @@ public interface EntityRendererAccessor { //#if MC>=12102 //$$ @Invoker("shouldShowName") - //$$ boolean shouldShowName(Entity entity, double distanceToCamera); + //$$ boolean plasmovoice_shouldShowName(Entity entity, double distanceToCamera); //#else @Invoker("shouldShowName") - boolean shouldShowName(Entity entity); + boolean plasmovoice_shouldShowName(Entity entity); //#endif } diff --git a/client/versions.toml b/client/versions.toml index 714d54b3..2889c47f 100644 --- a/client/versions.toml +++ b/client/versions.toml @@ -1,5 +1,6 @@ [12102] mcVersions = ">1.21.1" +neoForgeVersion = "[21,)" [12100] mcVersions = ">=1.21.0 <=1.21.1" From 68b9227c815ce0b2f723e3159de6ca237401cd30 Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Wed, 23 Oct 2024 05:40:16 +0800 Subject: [PATCH 12/13] ci: changelog --- client/changelog.md | 1 + server/changelog.md | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/client/changelog.md b/client/changelog.md index 4a6ccd79..8fc5ce45 100644 --- a/client/changelog.md +++ b/client/changelog.md @@ -13,3 +13,4 @@ so there’s no need to worry if the server hasn't been updated to 2.1.x. - Updated to 1.21.2-pre1. - Updated [slib](https://github.com/plasmoapp/mc-slib) to fix crash with EssentialAddons on world join. - Fixed audio sources causing a high CPU load. [#421](https://github.com/plasmoapp/plasmo-voice/issues/421) +- Attempt to fix "Cannot measure distance between worlds" exception, see [#422](https://github.com/plasmoapp/plasmo-voice/issues/422). \ No newline at end of file diff --git a/server/changelog.md b/server/changelog.md index e0a8907e..7b905611 100644 --- a/server/changelog.md +++ b/server/changelog.md @@ -5,4 +5,5 @@ If you encounter any issues, please report them on Discord: https://discord.gg/u Versions 2.0.x and 2.1.x are protocol-compatible, so there’s no need to worry if the server hasn't been updated to 2.1.x. -### Changes in 2.1.1 \ No newline at end of file +### Changes in 2.1.1 +- Attempt to fix "Cannot measure distance between worlds" exception, see [#422](https://github.com/plasmoapp/plasmo-voice/issues/422). \ No newline at end of file From 4982c286f9066adb306a2c8970c5ca9bd1ba1015 Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Wed, 23 Oct 2024 05:49:35 +0800 Subject: [PATCH 13/13] ci: changelog --- client/changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/changelog.md b/client/changelog.md index 8fc5ce45..7a1f88cd 100644 --- a/client/changelog.md +++ b/client/changelog.md @@ -10,7 +10,7 @@ so there’s no need to worry if the server hasn't been updated to 2.1.x. - Soften Minecraft version bounds: - 1.20.4 now allows 1.20.2, 1.20.3 and 1.20.4 - 1.19.2 now allows 1.19, 1.19.1 and 1.19.2 -- Updated to 1.21.2-pre1. +- Updated to 1.21.2. - Updated [slib](https://github.com/plasmoapp/mc-slib) to fix crash with EssentialAddons on world join. - Fixed audio sources causing a high CPU load. [#421](https://github.com/plasmoapp/plasmo-voice/issues/421) - Attempt to fix "Cannot measure distance between worlds" exception, see [#422](https://github.com/plasmoapp/plasmo-voice/issues/422). \ No newline at end of file