diff --git a/.github/workflows/prerelease-publish.yml b/.github/workflows/prerelease-publish.yml index 27c9b4ac4..13d6514c9 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 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 34a646a01..91ddacc4e 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); } diff --git a/client/1.19.3-fabric/.gitkeep b/client/1.19.3-fabric/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/client/1.19.3-forge/.gitkeep b/client/1.19.3-forge/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/client/1.21.2-fabric/gradle.properties b/client/1.21.2-fabric/gradle.properties new file mode 100644 index 000000000..bbcbaaffa --- /dev/null +++ b/client/1.21.2-fabric/gradle.properties @@ -0,0 +1 @@ +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 000000000..809aed519 --- /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/build.gradle.kts b/client/build.gradle.kts index 787696916..2b06b583a 100644 --- a/client/build.gradle.kts +++ b/client/build.gradle.kts @@ -82,16 +82,24 @@ 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" 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( @@ -234,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/changelog.md b/client/changelog.md index d1b8e6b63..7a1f88cd3 100644 --- a/client/changelog.md +++ b/client/changelog.md @@ -5,37 +5,12 @@ 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 +- 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 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 diff --git a/client/root.gradle.kts b/client/root.gradle.kts index ac63f1b8f..f9ef6974c 100644 --- a/client/root.gradle.kts +++ b/client/root.gradle.kts @@ -6,6 +6,9 @@ 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") val fabric12100 = createNode("1.21-fabric", 12100, "official") val forge12100 = createNode("1.21-forge", 12100, "official") @@ -19,6 +22,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") @@ -31,6 +37,9 @@ preprocess { val forge11605 = createNode("1.16.5-forge", 11605, "official") 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")) forge12100.link(forge12004, file("1.21-1.20.6.txt")) @@ -44,8 +53,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/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 e92bc1ebb..2a73a2b48 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 3b7c7d9d4..89cb3d9a3 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 3dd99f93e..2ba4ba77e 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 89d0168d1..7c036e0ad 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 c68d4df36..000000000 --- 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 56136999f..000000000 --- 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 dc9ae8fd6..a7b7f7893 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 000000000..b55db44e8 --- /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.plasmovoice_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.plasmovoice_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 b7e388155..000000000 --- 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 000000000..54d8baea8 --- /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 plasmovoice_shouldShowName(Entity entity, double distanceToCamera); + //#else + @Invoker("shouldShowName") + boolean plasmovoice_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 57b21af8b..000000000 --- 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 e14132b5e..53d700981 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 c11a4cf80..8ca7c9fb5 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 6e73ca04f..02721a83c 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/audio/source/BaseClientAudioSource.kt b/client/src/main/kotlin/su/plo/voice/client/audio/source/BaseClientAudioSource.kt index 719e6b50b..96cc56702 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 } 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 000000000..544275a3a --- /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/fabric.mod.json b/client/src/main/resources/fabric.mod.json index 17d11cf5b..59b73edb8 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/src/main/resources/plasmovoice.mixins.json b/client/src/main/resources/plasmovoice.mixins.json index d936a0c92..1b9afea5e 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 7ee3799c9..2889c47fd 100644 --- a/client/versions.toml +++ b/client/versions.toml @@ -1,32 +1,40 @@ +[12102] +mcVersions = ">1.21.1" +neoForgeVersion = "[21,)" + [12100] -mcVersions = [">=1.21"] +mcVersions = ">=1.21.0 <=1.21.1" forgeVersion = "[51,)" neoForgeVersion = "[20,)" [12004] forgeVersion = "[49,)" -mcVersions = ["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.0 <=1.20.1" [11904] forgeVersion = "[45,)" -mcVersions = ["1.19.4"] +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,)" -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" diff --git a/gradle.properties b/gradle.properties index 9b198866e..859b048b8 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 739040185..e0a8907e8 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 4d8e26985..7b905611a 100644 --- a/server/changelog.md +++ b/server/changelog.md @@ -5,25 +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. -### 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 +- 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/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 73947c5dc..0b8a6bd88 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 fcffc870b..098423a66 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 c5852158d..d4a769aed 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()