From cda366d0623c9b85876612d9f2f477f74c330737 Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Fri, 25 Oct 2024 15:53:14 +0800 Subject: [PATCH 01/17] build: v2.1.2 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 859b048b..5633cbfe 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ # Version targetJavaVersion=8 group=su.plo.voice -version=2.1.1 +version=2.1.2 # Gradle args org.gradle.jvmargs=-Xmx4G -Dkotlin.daemon.jvm.options=-Xmx512M From 42abe2870abefaa8eaa3c7995931ab380165c266 Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Mon, 28 Oct 2024 13:59:26 +0800 Subject: [PATCH 02/17] fix: set startTime when first frame received in AudioSender --- .../plo/voice/api/server/audio/source/AudioSender.kt | 8 +++++++- client/changelog.md | 11 ++--------- proxy/changelog.md | 3 ++- server/changelog.md | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/api/server-proxy-common/src/main/kotlin/su/plo/voice/api/server/audio/source/AudioSender.kt b/api/server-proxy-common/src/main/kotlin/su/plo/voice/api/server/audio/source/AudioSender.kt index 9eedfff9..7009e027 100644 --- a/api/server-proxy-common/src/main/kotlin/su/plo/voice/api/server/audio/source/AudioSender.kt +++ b/api/server-proxy-common/src/main/kotlin/su/plo/voice/api/server/audio/source/AudioSender.kt @@ -39,7 +39,7 @@ class AudioSender( val job = CoroutineScope(Dispatchers.Default).launch { var sequenceNumber = 0L - val startTime = System.nanoTime() + var startTime = 0L var endOfStream = false @@ -49,6 +49,7 @@ class AudioSender( if (!endOfStream) { endOfStream = true onEnd.invoke(sequenceNumber++) + startTime = 0L } delay(10L) @@ -61,6 +62,7 @@ class AudioSender( endOfStream = true onEnd.invoke(sequenceNumber++) + startTime = 0L continue } @@ -76,6 +78,10 @@ class AudioSender( continue } + if (startTime == 0L) { + startTime = System.nanoTime() + } + val frameTime = 20_000_000 * sequenceNumber val waitTime = startTime + frameTime - System.nanoTime() diff --git a/client/changelog.md b/client/changelog.md index 7a1f88cd..69ba0ade 100644 --- a/client/changelog.md +++ b/client/changelog.md @@ -5,12 +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 -- 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 +### Changes in 2.1.2 +- Fixed buffer overflow when using AudioSender with delayed first frame. \ No newline at end of file diff --git a/proxy/changelog.md b/proxy/changelog.md index e0a8907e..69ba0ade 100644 --- a/proxy/changelog.md +++ b/proxy/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.2 +- Fixed buffer overflow when using AudioSender with delayed first frame. \ No newline at end of file diff --git a/server/changelog.md b/server/changelog.md index 7b905611..69ba0ade 100644 --- a/server/changelog.md +++ b/server/changelog.md @@ -5,5 +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 -- 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 +### Changes in 2.1.2 +- Fixed buffer overflow when using AudioSender with delayed first frame. \ No newline at end of file From 17d3bbcae5bb25ba88b84bba7bbd65e29800080d Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Thu, 31 Oct 2024 19:01:41 +0800 Subject: [PATCH 03/17] fix(proxy): don't send packets to a client when client server is null --- proxy/changelog.md | 3 ++- .../su/plo/voice/proxy/socket/NettyPacketHandler.java | 2 ++ .../plo/voice/proxy/socket/NettyUdpProxyConnection.java | 8 +++++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/proxy/changelog.md b/proxy/changelog.md index 69ba0ade..8c44a4ac 100644 --- a/proxy/changelog.md +++ b/proxy/changelog.md @@ -6,4 +6,5 @@ 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.2 -- Fixed buffer overflow when using AudioSender with delayed first frame. \ No newline at end of file +- Fixed buffer overflow when using AudioSender with delayed first frame. +- Fixed client EncoderException on server switch caused by UDP packets sent to a client when client's server is null. \ No newline at end of file diff --git a/proxy/common/src/main/java/su/plo/voice/proxy/socket/NettyPacketHandler.java b/proxy/common/src/main/java/su/plo/voice/proxy/socket/NettyPacketHandler.java index ef091696..8a27bd41 100644 --- a/proxy/common/src/main/java/su/plo/voice/proxy/socket/NettyPacketHandler.java +++ b/proxy/common/src/main/java/su/plo/voice/proxy/socket/NettyPacketHandler.java @@ -128,6 +128,8 @@ private boolean sendPacket(ChannelHandlerContext ctx, NettyPacketUdp nettyPacket } else { receiver = connection.getRemoteAddress(); receiverSecret = connection.getSecret(); + + if (!connection.isConnected()) return true; } // rewrite to backend server diff --git a/proxy/common/src/main/java/su/plo/voice/proxy/socket/NettyUdpProxyConnection.java b/proxy/common/src/main/java/su/plo/voice/proxy/socket/NettyUdpProxyConnection.java index ae90a5b7..f483db06 100644 --- a/proxy/common/src/main/java/su/plo/voice/proxy/socket/NettyUdpProxyConnection.java +++ b/proxy/common/src/main/java/su/plo/voice/proxy/socket/NettyUdpProxyConnection.java @@ -42,7 +42,6 @@ public final class NettyUdpProxyConnection implements UdpProxyConnection, Server private InetSocketAddress remoteAddress; @Setter private RemoteServer remoteServer; - @Getter private boolean connected = true; @Override @@ -52,6 +51,8 @@ public Optional getRemoteServer() { @Override public void sendPacket(Packet packet) { + if (!isConnected()) return; + byte[] encoded = PacketUdpCodec.encode(packet, secret); if (encoded == null) return; @@ -70,6 +71,11 @@ public void disconnect() { this.connected = false; } + @Override + public boolean isConnected() { + return connected && player.getInstance().getServer() != null; + } + @Override public void handle(@NotNull PingPacket packet) { } From 672bbc3a30ad402b553383f344d9d88b61597752 Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Sun, 3 Nov 2024 03:17:22 +0800 Subject: [PATCH 04/17] fix(client): don't send packets to a server when Minecraft connection is null aka in config/login state --- client/changelog.md | 3 ++- .../su/plo/voice/client/connection/ModServerConnection.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/client/changelog.md b/client/changelog.md index 69ba0ade..da2de743 100644 --- a/client/changelog.md +++ b/client/changelog.md @@ -6,4 +6,5 @@ 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.2 -- Fixed buffer overflow when using AudioSender with delayed first frame. \ No newline at end of file +- Fixed buffer overflow when using AudioSender with delayed first frame. +- Fixed EncoderException on server switch on servers with proxy and proxy-side addons (e.g, groups addon). \ No newline at end of file diff --git a/client/src/main/java/su/plo/voice/client/connection/ModServerConnection.java b/client/src/main/java/su/plo/voice/client/connection/ModServerConnection.java index 5300b21c..9d78b88c 100644 --- a/client/src/main/java/su/plo/voice/client/connection/ModServerConnection.java +++ b/client/src/main/java/su/plo/voice/client/connection/ModServerConnection.java @@ -121,7 +121,7 @@ public ModServerConnection(@NotNull BaseVoiceClient voiceClient, @Override public void sendPacket(@NotNull Packet packet, boolean checkUdpConnection) { - if (!connection.isConnected()) return; + if (!connection.isConnected() || Minecraft.getInstance().getConnection() == null) return; if (checkUdpConnection && !voiceClient.getUdpClientManager().isConnected()) return; From ffdb0d6ec09ddbcdc6d86134d6e59ff24b4a560c Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Sun, 3 Nov 2024 18:01:25 +0800 Subject: [PATCH 05/17] ci: update changelog --- proxy/changelog.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proxy/changelog.md b/proxy/changelog.md index 8c44a4ac..d1e3bb33 100644 --- a/proxy/changelog.md +++ b/proxy/changelog.md @@ -7,4 +7,5 @@ so there’s no need to worry if the server hasn't been updated to 2.1.x. ### Changes in 2.1.2 - Fixed buffer overflow when using AudioSender with delayed first frame. -- Fixed client EncoderException on server switch caused by UDP packets sent to a client when client's server is null. \ No newline at end of file +- Fixed client EncoderException on server switch caused by UDP packets sent to a client when client's server is null. +- Fixed ArrayIndexOutOfBoundsException exception when using `/` command on Velocity. \ No newline at end of file From cebc482dcb61f3eb42ccf97db0cc385c4ad8753f Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Mon, 4 Nov 2024 16:24:27 +0800 Subject: [PATCH 06/17] fix: check wildcard permission before everything else on permission update --- client/changelog.md | 3 ++- proxy/changelog.md | 3 ++- .../server/audio/capture/VoiceServerActivationManager.kt | 6 +++--- server/changelog.md | 3 ++- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/client/changelog.md b/client/changelog.md index da2de743..ff0ecdfe 100644 --- a/client/changelog.md +++ b/client/changelog.md @@ -7,4 +7,5 @@ so there’s no need to worry if the server hasn't been updated to 2.1.x. ### Changes in 2.1.2 - Fixed buffer overflow when using AudioSender with delayed first frame. -- Fixed EncoderException on server switch on servers with proxy and proxy-side addons (e.g, groups addon). \ No newline at end of file +- Fixed EncoderException on server switch on servers with proxy and proxy-side addons (e.g, groups addon). +- Fixed `pv.activation.*` permission is not being updated on the client without reconnect. \ No newline at end of file diff --git a/proxy/changelog.md b/proxy/changelog.md index d1e3bb33..51fa8178 100644 --- a/proxy/changelog.md +++ b/proxy/changelog.md @@ -8,4 +8,5 @@ so there’s no need to worry if the server hasn't been updated to 2.1.x. ### Changes in 2.1.2 - Fixed buffer overflow when using AudioSender with delayed first frame. - Fixed client EncoderException on server switch caused by UDP packets sent to a client when client's server is null. -- Fixed ArrayIndexOutOfBoundsException exception when using `/` command on Velocity. \ No newline at end of file +- Fixed ArrayIndexOutOfBoundsException exception when using `/` command on Velocity. +- Fixed `pv.activation.*` permission is not being updated on the client without reconnect. \ No newline at end of file diff --git a/server-proxy-common/src/main/kotlin/su/plo/voice/server/audio/capture/VoiceServerActivationManager.kt b/server-proxy-common/src/main/kotlin/su/plo/voice/server/audio/capture/VoiceServerActivationManager.kt index 1991e817..890818a4 100644 --- a/server-proxy-common/src/main/kotlin/su/plo/voice/server/audio/capture/VoiceServerActivationManager.kt +++ b/server-proxy-common/src/main/kotlin/su/plo/voice/server/audio/capture/VoiceServerActivationManager.kt @@ -191,11 +191,8 @@ class VoiceServerActivationManager( val player = event.player val permission = event.permission - if (activationById.values.none { it.permissions.contains(permission) }) return - if (permission == WILDCARD_ACTIVATION_PERMISSION) { when (player.instance.getPermission(WILDCARD_ACTIVATION_PERMISSION)) { - PermissionTristate.TRUE -> activationById.values.forEach { player.sendPacket(ActivationRegisterPacket(it as VoiceActivation)) } @@ -214,6 +211,9 @@ class VoiceServerActivationManager( } return } + + if (activationById.values.none { it.permissions.contains(permission) }) return + val permissionSplit = permission.split("\\.".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() val activation = getActivationByName(permissionSplit[permissionSplit.size - 1]).orElse(null) ?: return diff --git a/server/changelog.md b/server/changelog.md index 69ba0ade..b7c5e053 100644 --- a/server/changelog.md +++ b/server/changelog.md @@ -6,4 +6,5 @@ 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.2 -- Fixed buffer overflow when using AudioSender with delayed first frame. \ No newline at end of file +- Fixed buffer overflow when using AudioSender with delayed first frame. +- Fixed `pv.activation.*` permission is not being updated on the client without reconnect. \ No newline at end of file From 5c364f619200580a13f22b5c73f63722c4425202 Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Sun, 10 Nov 2024 18:00:40 +0800 Subject: [PATCH 07/17] build: update slib --- gradle/libs.versions.toml | 2 +- server/changelog.md | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3d202fca..f3db0ef2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,7 +13,7 @@ gson = "2.10.1" netty = "4.1.77.Final" crowdin = "1.1.0-SNAPSHOT" config = "1.0.2" -slib = "1.0.0-SNAPSHOT" +slib = "1.0.1-SNAPSHOT" bstats = "3.0.2" luckperms = "5.4" papi = "2.11.6" diff --git a/server/changelog.md b/server/changelog.md index b7c5e053..3c3ece26 100644 --- a/server/changelog.md +++ b/server/changelog.md @@ -7,4 +7,5 @@ so there’s no need to worry if the server hasn't been updated to 2.1.x. ### Changes in 2.1.2 - Fixed buffer overflow when using AudioSender with delayed first frame. -- Fixed `pv.activation.*` permission is not being updated on the client without reconnect. \ No newline at end of file +- Fixed `pv.activation.*` permission is not being updated on the client without reconnect. +- Fixed server translations missing in kick messages. [#428](https://github.com/plasmoapp/plasmo-voice/issues/428) \ No newline at end of file From 7b0cdbf66bcac34452e0b7f4fb847848a6a48dca Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Thu, 14 Nov 2024 05:54:39 +0800 Subject: [PATCH 08/17] fix(client): handle charTyped in ScreenWrapper --- client/changelog.md | 3 ++- .../su/plo/lib/mod/client/gui/screen/ScreenWrapper.java | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/client/changelog.md b/client/changelog.md index ff0ecdfe..4748ef33 100644 --- a/client/changelog.md +++ b/client/changelog.md @@ -8,4 +8,5 @@ so there’s no need to worry if the server hasn't been updated to 2.1.x. ### Changes in 2.1.2 - Fixed buffer overflow when using AudioSender with delayed first frame. - Fixed EncoderException on server switch on servers with proxy and proxy-side addons (e.g, groups addon). -- Fixed `pv.activation.*` permission is not being updated on the client without reconnect. \ No newline at end of file +- Fixed `pv.activation.*` permission is not being updated on the client without reconnect. +- Fixed textfield input not being handled. \ No newline at end of file diff --git a/client/src/main/java/su/plo/lib/mod/client/gui/screen/ScreenWrapper.java b/client/src/main/java/su/plo/lib/mod/client/gui/screen/ScreenWrapper.java index 765ed03a..d38c98a1 100644 --- a/client/src/main/java/su/plo/lib/mod/client/gui/screen/ScreenWrapper.java +++ b/client/src/main/java/su/plo/lib/mod/client/gui/screen/ScreenWrapper.java @@ -186,10 +186,14 @@ public boolean mouseScrolled(double mouseX, double mouseY, double delta) { // return screen.mouseScrolled(mouseX, mouseY, delta); // } + @Override + public boolean charTyped(char typedChar, int modifiers) { + return screen.charTyped(typedChar, modifiers); + } + @Override public boolean keyPressed(int keyCode, int scanCode, int modifiers) { if (keyCode == 0) { - screen.charTyped((char) 0, modifiers); return false; } From 89df24112caaff4a328c205dd6a1af1658a4cdc9 Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Sun, 17 Nov 2024 05:01:25 +0800 Subject: [PATCH 09/17] feat(client): debug print supported data lines when capture device is not available --- .../audio/capture/VoiceAudioCapture.java | 15 +++++++--- .../audio/device/JavaxInputDeviceFactory.java | 28 ++++++++++++++++++- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/client/src/main/java/su/plo/voice/client/audio/capture/VoiceAudioCapture.java b/client/src/main/java/su/plo/voice/client/audio/capture/VoiceAudioCapture.java index 7cfaf2b2..dfa3bd7f 100644 --- a/client/src/main/java/su/plo/voice/client/audio/capture/VoiceAudioCapture.java +++ b/client/src/main/java/su/plo/voice/client/audio/capture/VoiceAudioCapture.java @@ -21,15 +21,18 @@ import su.plo.voice.api.client.audio.capture.AudioCapture; import su.plo.voice.api.client.audio.capture.ClientActivation; import su.plo.voice.api.client.audio.capture.ClientActivationManager; -import su.plo.voice.api.client.audio.device.AudioDevice; import su.plo.voice.api.client.audio.device.DeviceManager; -import su.plo.voice.api.client.audio.device.DeviceType; import su.plo.voice.api.client.audio.device.InputDevice; import su.plo.voice.api.client.connection.ServerInfo; -import su.plo.voice.api.client.event.audio.capture.*; +import su.plo.voice.api.client.event.audio.capture.AudioCaptureEvent; +import su.plo.voice.api.client.event.audio.capture.AudioCaptureInitializeEvent; +import su.plo.voice.api.client.event.audio.capture.AudioCaptureProcessedEvent; +import su.plo.voice.api.client.event.audio.capture.AudioCaptureStartEvent; +import su.plo.voice.api.client.event.audio.capture.AudioCaptureStopEvent; import su.plo.voice.api.encryption.Encryption; import su.plo.voice.api.encryption.EncryptionException; import su.plo.voice.api.util.AudioUtil; +import su.plo.voice.client.audio.device.JavaxInputDeviceFactory; import su.plo.voice.client.audio.filter.StereoToMonoFilter; import su.plo.voice.client.config.VoiceClientConfig; import su.plo.voice.client.mac.AVAuthorizationStatus; @@ -41,7 +44,10 @@ import su.plo.voice.proto.packets.udp.serverbound.PlayerAudioPacket; import javax.sound.sampled.AudioFormat; -import java.util.*; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; public final class VoiceAudioCapture implements AudioCapture { @@ -123,6 +129,7 @@ public void initialize(@NotNull ServerInfo serverInfo) { devices.setInputDevice(inputDevice); } catch (Exception e) { LOGGER.error("Failed to open input device", e); + JavaxInputDeviceFactory.printSupportedLines(); } } diff --git a/client/src/main/java/su/plo/voice/client/audio/device/JavaxInputDeviceFactory.java b/client/src/main/java/su/plo/voice/client/audio/device/JavaxInputDeviceFactory.java index de288db1..ec9d4773 100644 --- a/client/src/main/java/su/plo/voice/client/audio/device/JavaxInputDeviceFactory.java +++ b/client/src/main/java/su/plo/voice/client/audio/device/JavaxInputDeviceFactory.java @@ -4,12 +4,18 @@ import com.google.common.collect.ImmutableList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import su.plo.voice.BaseVoice; import su.plo.voice.api.client.PlasmoVoiceClient; import su.plo.voice.api.client.audio.device.AudioDevice; import su.plo.voice.api.client.audio.device.DeviceException; import su.plo.voice.api.client.audio.device.DeviceFactory; -import javax.sound.sampled.*; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.Line; +import javax.sound.sampled.Mixer; +import javax.sound.sampled.TargetDataLine; import java.util.ArrayList; import java.util.List; @@ -17,6 +23,26 @@ public final class JavaxInputDeviceFactory implements DeviceFactory { + public static void printSupportedLines() { + BaseVoice.DEBUG_LOGGER.log("Supported target data lines:"); + + Mixer.Info[] mixers = AudioSystem.getMixerInfo(); + for (Mixer.Info mixerInfo : mixers) { + Mixer mixer = AudioSystem.getMixer(mixerInfo); + Line.Info lineInfo = new Line.Info(TargetDataLine.class); + + if (mixer.isLineSupported(lineInfo)) { + for (Line.Info info : mixer.getTargetLineInfo()) { + BaseVoice.DEBUG_LOGGER.log(info.toString()); + DataLine.Info dataInfo = (DataLine.Info) info; + for (AudioFormat dataFormat : dataInfo.getFormats()) { + BaseVoice.DEBUG_LOGGER.log(dataFormat.toString()); + } + } + } + } + } + private final PlasmoVoiceClient client; public JavaxInputDeviceFactory(PlasmoVoiceClient client) { From 9359a30263b2fbee1a48dcc1915e831b7b87956b Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Sun, 17 Nov 2024 05:44:40 +0800 Subject: [PATCH 10/17] feat(client): mute player source if a direct source from the same player is active --- .../voice/api/client/config/ClientConfig.kt | 2 + client/changelog.md | 3 +- .../client/config/VoiceClientConfig.java | 3 + .../gui/settings/tab/AdvancedTabWidget.java | 5 ++ .../audio/source/BaseClientAudioSource.kt | 68 +++++++++++-------- .../client/audio/source/ClientPlayerSource.kt | 7 ++ .../assets/plasmovoice/lang/en_us.json | 4 +- 7 files changed, 61 insertions(+), 31 deletions(-) diff --git a/api/client/src/main/kotlin/su/plo/voice/api/client/config/ClientConfig.kt b/api/client/src/main/kotlin/su/plo/voice/api/client/config/ClientConfig.kt index 5e807ca1..65fcd4d3 100644 --- a/api/client/src/main/kotlin/su/plo/voice/api/client/config/ClientConfig.kt +++ b/api/client/src/main/kotlin/su/plo/voice/api/client/config/ClientConfig.kt @@ -79,6 +79,8 @@ interface ClientConfig { val panning: BooleanConfigEntry + val mutePlayerOnDirect: BooleanConfigEntry + val cameraSoundListener: BooleanConfigEntry val exponentialVolumeSlider: BooleanConfigEntry diff --git a/client/changelog.md b/client/changelog.md index 4748ef33..7ad7ee22 100644 --- a/client/changelog.md +++ b/client/changelog.md @@ -9,4 +9,5 @@ so there’s no need to worry if the server hasn't been updated to 2.1.x. - Fixed buffer overflow when using AudioSender with delayed first frame. - Fixed EncoderException on server switch on servers with proxy and proxy-side addons (e.g, groups addon). - Fixed `pv.activation.*` permission is not being updated on the client without reconnect. -- Fixed textfield input not being handled. \ No newline at end of file +- Fixed textfield input not being handled. +- Player sources are now automatically muted if the direct source from the same player becomes active. Can be disabled in menu `Advanced`/`Mute Player On Direct`. \ No newline at end of file diff --git a/client/src/main/java/su/plo/voice/client/config/VoiceClientConfig.java b/client/src/main/java/su/plo/voice/client/config/VoiceClientConfig.java index 2005ab0c..ad1ce62e 100644 --- a/client/src/main/java/su/plo/voice/client/config/VoiceClientConfig.java +++ b/client/src/main/java/su/plo/voice/client/config/VoiceClientConfig.java @@ -400,6 +400,9 @@ public static class Advanced implements ClientConfig.Advanced { @ConfigField private BooleanConfigEntry panning = new BooleanConfigEntry(true); + @ConfigField + private BooleanConfigEntry mutePlayerOnDirect = new BooleanConfigEntry(true); + @ConfigField private BooleanConfigEntry cameraSoundListener = new BooleanConfigEntry(true); diff --git a/client/src/main/java/su/plo/voice/client/gui/settings/tab/AdvancedTabWidget.java b/client/src/main/java/su/plo/voice/client/gui/settings/tab/AdvancedTabWidget.java index e4caa401..2c36715c 100644 --- a/client/src/main/java/su/plo/voice/client/gui/settings/tab/AdvancedTabWidget.java +++ b/client/src/main/java/su/plo/voice/client/gui/settings/tab/AdvancedTabWidget.java @@ -55,6 +55,11 @@ public void init() { )); addEntry(createStereoToMonoSources()); addEntry(createPanning()); + addEntry(createToggleEntry( + McTextComponent.translatable("gui.plasmovoice.advanced.mute_player_on_direct"), + McTextComponent.translatable("gui.plasmovoice.advanced.mute_player_on_direct.tooltip"), + config.getAdvanced().getMutePlayerOnDirect() + )); addEntry(new CategoryEntry(McTextComponent.translatable("gui.plasmovoice.advanced.exponential_volume"))); addEntry(createToggleEntry( 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 96cc5670..69a5e4e3 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 @@ -344,42 +344,44 @@ abstract class BaseClientAudioSource( // so we need to make sure that source is not closed rn if (closed.get()) return - // packet compensation - if (lastSequenceNumber >= 0) { - val packetsToCompensate = (packet.sequenceNumber - (lastSequenceNumber + 1)).toInt() - if (packetsToCompensate in 1..4) { - BaseVoice.DEBUG_LOGGER.warn("Compensate {} lost packets", packetsToCompensate) - for (i in 0 until packetsToCompensate) { - val compensatedSequenceNumber = lastSequenceNumber + i + 1 - - if (decoder != null && decoder is AudioDecoderPlc && !sourceInfo.isStereo) { - try { - write((decoder as AudioDecoderPlc).decodePLC(), compensatedSequenceNumber) - } catch (e: CodecException) { - LOGGER.warn("Failed to decode source audio", e) - return + if (shouldWrite()) { + // packet compensation + if (lastSequenceNumber >= 0) { + val packetsToCompensate = (packet.sequenceNumber - (lastSequenceNumber + 1)).toInt() + if (packetsToCompensate in 1..4) { + BaseVoice.DEBUG_LOGGER.warn("Compensate {} lost packets", packetsToCompensate) + for (i in 0 until packetsToCompensate) { + val compensatedSequenceNumber = lastSequenceNumber + i + 1 + + if (decoder != null && decoder is AudioDecoderPlc && !sourceInfo.isStereo) { + try { + write((decoder as AudioDecoderPlc).decodePLC(), compensatedSequenceNumber) + } catch (e: CodecException) { + LOGGER.warn("Failed to decode source audio", e) + return + } + } else { + write(ShortArray(0), compensatedSequenceNumber) } - } else { - write(ShortArray(0), compensatedSequenceNumber) } } } - } - // decrypt & decode samples - try { - val decrypted = encryption?.decrypt(packet.data) ?: packet.data - val decoded = decoder?.decode(decrypted) ?: AudioUtil.bytesToShorts(decrypted) + // decrypt & decode samples + try { + val decrypted = encryption?.decrypt(packet.data) ?: packet.data + val decoded = decoder?.decode(decrypted) ?: AudioUtil.bytesToShorts(decrypted) - if (sourceInfo.isStereo && config.advanced.stereoSourcesToMono.value()) { - write(AudioUtil.convertToMonoShorts(decoded), packet.sequenceNumber) - } else { - write(decoded, packet.sequenceNumber) + if (sourceInfo.isStereo && config.advanced.stereoSourcesToMono.value()) { + write(AudioUtil.convertToMonoShorts(decoded), packet.sequenceNumber) + } else { + write(decoded, packet.sequenceNumber) + } + } catch (e: EncryptionException) { + BaseVoice.DEBUG_LOGGER.warn("Failed to decrypt source audio", e) + } catch (e: CodecException) { + BaseVoice.DEBUG_LOGGER.warn("Failed to decode source audio", e) } - } catch (e: EncryptionException) { - BaseVoice.DEBUG_LOGGER.warn("Failed to decrypt source audio", e) - } catch (e: CodecException) { - BaseVoice.DEBUG_LOGGER.warn("Failed to decode source audio", e) } lastSequenceNumber = packet.sequenceNumber @@ -548,6 +550,14 @@ abstract class BaseClientAudioSource( return sourceInfo.isStereo && !config.advanced.stereoSourcesToMono.value() } + /** + * Determines if audio should be written to the underlying AL source. + * + * Because we don't want to disable source icons in some cases, + * we should just disable writing samples to the actual source. + */ + protected open fun shouldWrite(): Boolean = true + companion object { private val OUTER_ANGLE: Double = 180.0 private val LOGGER: Logger = LogManager.getLogger(BaseClientAudioSource::class.java) diff --git a/client/src/main/kotlin/su/plo/voice/client/audio/source/ClientPlayerSource.kt b/client/src/main/kotlin/su/plo/voice/client/audio/source/ClientPlayerSource.kt index 66e010ad..e40e64e2 100644 --- a/client/src/main/kotlin/su/plo/voice/client/audio/source/ClientPlayerSource.kt +++ b/client/src/main/kotlin/su/plo/voice/client/audio/source/ClientPlayerSource.kt @@ -41,6 +41,13 @@ class ClientPlayerSource( override fun isPanningDisabled(): Boolean = sourcePlayer == getListener() || super.isPanningDisabled() + override fun shouldWrite(): Boolean = + !voiceClient.config.advanced.mutePlayerOnDirect.value() || + voiceClient.sourceManager.sources + .filterIsInstance() + .filter { it.isActivated() } + .none { it.sourceInfo.sender?.id == sourceInfo.playerInfo.playerId } + private val sourceMute: BooleanConfigEntry get() { return config.voice diff --git a/client/src/main/resources/assets/plasmovoice/lang/en_us.json b/client/src/main/resources/assets/plasmovoice/lang/en_us.json index d4ee048c..78168afc 100644 --- a/client/src/main/resources/assets/plasmovoice/lang/en_us.json +++ b/client/src/main/resources/assets/plasmovoice/lang/en_us.json @@ -70,7 +70,9 @@ "gui.plasmovoice.advanced.directional_sources_angle.tooltip": "An angle in which you will hear the source at 100% if directional sources option is enabled.\n\n360 is like if the option is disabled.", "gui.plasmovoice.advanced.stereo_sources_to_mono": "Mono Stereo Sources", "gui.plasmovoice.advanced.stereo_sources_to_mono.tooltip": "Addons use stereo sources for better audio quality. The quality is much better, but facing doesn't affect the panning. Sound only fades out with distance.\n\nWhen this option is enabled, stereo sources are converted to the usual mono sources. Quality is worse, but they will now have panning.", - "gui.plasmovoice.advanced.panning": "Stereo positioning", + "gui.plasmovoice.advanced.panning": "Stereo Positioning", + "gui.plasmovoice.advanced.mute_player_on_direct": "Mute Player On Direct", + "gui.plasmovoice.advanced.mute_player_on_direct.tooltip": "When enabled, the player's source will be automatically muted if the direct source from the same player becomes active. Use this to avoid overlapping audio or conflicting playback from multiple sources.", "gui.plasmovoice.advanced.exponential_volume": "Exponential Volume", "gui.plasmovoice.advanced.exponential_volume.volume_slider": "Volume Slider", From 19200b676a083939b77fcbfcf3b144871cb30ea5 Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Sun, 17 Nov 2024 06:09:47 +0800 Subject: [PATCH 11/17] fix(client): update last buffer time in al source if samples write was skipped --- .../plo/voice/api/client/audio/device/source/AlSource.java | 5 +++++ .../plo/voice/client/audio/device/source/StreamAlSource.kt | 6 +++++- .../plo/voice/client/audio/source/BaseClientAudioSource.kt | 2 ++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/api/client/src/main/java/su/plo/voice/api/client/audio/device/source/AlSource.java b/api/client/src/main/java/su/plo/voice/api/client/audio/device/source/AlSource.java index f190f4c3..9e9906ca 100644 --- a/api/client/src/main/java/su/plo/voice/api/client/audio/device/source/AlSource.java +++ b/api/client/src/main/java/su/plo/voice/api/client/audio/device/source/AlSource.java @@ -157,6 +157,11 @@ public interface AlSource extends DeviceSource { */ void setCloseTimeoutMs(long timeoutMs); + /** + * Updates last buffer time to current time provided by the time supplier. + */ + void updateLastBufferTime(); + /** * Gets the OpenAL format of the source. * diff --git a/client/src/main/kotlin/su/plo/voice/client/audio/device/source/StreamAlSource.kt b/client/src/main/kotlin/su/plo/voice/client/audio/device/source/StreamAlSource.kt index 4a6ab435..21a4aaac 100644 --- a/client/src/main/kotlin/su/plo/voice/client/audio/device/source/StreamAlSource.kt +++ b/client/src/main/kotlin/su/plo/voice/client/audio/device/source/StreamAlSource.kt @@ -99,6 +99,10 @@ class StreamAlSource private constructor( this.closeTimeoutMs = timeoutMs } + override fun updateLastBufferTime() { + lastBufferTime = timeSupplier.currentTimeMillis + } + override fun write(samples: ShortArray, applyFilters: Boolean) { val processedSamples = if (applyFilters) { device.processFilters(samples) @@ -202,7 +206,7 @@ class StreamAlSource private constructor( queueWithEmptyBuffers() fillQueue() - lastBufferTime = timeSupplier.currentTimeMillis + updateLastBufferTime() availableBuffer[0] = -1 while (isStreaming.get()) { 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 69a5e4e3..07da4bcd 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 @@ -382,6 +382,8 @@ abstract class BaseClientAudioSource( } catch (e: CodecException) { BaseVoice.DEBUG_LOGGER.warn("Failed to decode source audio", e) } + } else { + source.updateLastBufferTime() } lastSequenceNumber = packet.sequenceNumber From 0c529064137ed5c8b941866c997535b190fe15de Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Wed, 20 Nov 2024 00:27:22 +0800 Subject: [PATCH 12/17] fix(server): send /vmute command usage --- .../main/java/su/plo/voice/server/command/VoiceMuteCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/common/src/main/java/su/plo/voice/server/command/VoiceMuteCommand.java b/server/common/src/main/java/su/plo/voice/server/command/VoiceMuteCommand.java index c29c1cd9..8ac3d850 100644 --- a/server/common/src/main/java/su/plo/voice/server/command/VoiceMuteCommand.java +++ b/server/common/src/main/java/su/plo/voice/server/command/VoiceMuteCommand.java @@ -33,7 +33,7 @@ public final class VoiceMuteCommand implements McCommand { @Override public void execute(@NotNull McCommandSource source, @NotNull String[] arguments) { if (arguments.length == 0) { - source.sendMessage(McTextComponent.translatable("pv.error.no_permissions")); + source.sendMessage(McTextComponent.translatable("pv.command.mute.usage")); return; } From 7d28d996acb0f191d1f8cd39a46bce68759b1907 Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Wed, 20 Nov 2024 00:30:31 +0800 Subject: [PATCH 13/17] ci: update changelog --- server/changelog.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/changelog.md b/server/changelog.md index 3c3ece26..a4400ed4 100644 --- a/server/changelog.md +++ b/server/changelog.md @@ -8,4 +8,5 @@ so there’s no need to worry if the server hasn't been updated to 2.1.x. ### Changes in 2.1.2 - Fixed buffer overflow when using AudioSender with delayed first frame. - Fixed `pv.activation.*` permission is not being updated on the client without reconnect. -- Fixed server translations missing in kick messages. [#428](https://github.com/plasmoapp/plasmo-voice/issues/428) \ No newline at end of file +- Fixed server translations missing in kick messages. [#428](https://github.com/plasmoapp/plasmo-voice/issues/428) +- `/vmute` without arguments now sends command usage instead of "no permissions" error. \ No newline at end of file From 134a574c040b661e14e4f77d2e648f101009d13a Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Thu, 21 Nov 2024 12:35:32 +0800 Subject: [PATCH 14/17] feat(client): 1.21.4-pre1 fabric --- client/1.21.4-fabric/gradle.properties | 1 + client/build.gradle.kts | 10 +++++++++- client/root.gradle.kts | 4 ++++ .../voice/client/mixin/MixinSkinManager.java | 20 +++++++++++++++++-- .../gg/essential/universal/DummyPack.kt | 13 +++++++++++- .../voice/client/crowdin/PlasmoCrowdinPack.kt | 13 ++++++++++-- .../render/cape/DeveloperCapeManager.kt | 19 +++++++++++++++++- client/versions.toml | 4 ++++ 8 files changed, 77 insertions(+), 7 deletions(-) create mode 100644 client/1.21.4-fabric/gradle.properties diff --git a/client/1.21.4-fabric/gradle.properties b/client/1.21.4-fabric/gradle.properties new file mode 100644 index 00000000..1e3bbc1d --- /dev/null +++ b/client/1.21.4-fabric/gradle.properties @@ -0,0 +1 @@ +essential.defaults.loom.minecraft=com.mojang:minecraft:1.21.4-pre1 diff --git a/client/build.gradle.kts b/client/build.gradle.kts index 2b06b583..8a4fabe5 100644 --- a/client/build.gradle.kts +++ b/client/build.gradle.kts @@ -60,6 +60,7 @@ val shadowCommon by configurations.creating fun slibArtifact(): String { val minecraftVersion = when (platform.mcVersion) { 11904 -> "1.19.3" + 12104 -> "1.21.2" else -> platform.mcVersionStr } @@ -89,10 +90,17 @@ dependencies { 12006 -> "0.97.7+1.20.6" 12100 -> "0.100.4+1.21" 12102 -> "0.105.3+1.21.2" + 12104 -> "0.109.1+1.21.4" else -> throw GradleException("Unsupported platform $platform") } - modImplementation("net.fabricmc.fabric-api:fabric-api:${fabricApiVersion}") + fun fabricApiModules(vararg module: String) { + module.forEach { + modImplementation(fabricApi.module("fabric-$it", fabricApiVersion)) + } + } + + fabricApiModules("rendering-v1", "networking-api-v1", "lifecycle-events-v1", "key-binding-api-v1") if (platform.mcVersion >= 12102) { // https://github.com/lucko/fabric-permissions-api/pull/26 diff --git a/client/root.gradle.kts b/client/root.gradle.kts index f9ef6974..d4b2db72 100644 --- a/client/root.gradle.kts +++ b/client/root.gradle.kts @@ -6,6 +6,8 @@ group = "$group.client-root" preprocess { + val fabric12104 = createNode("1.21.4-fabric", 12104, "official") + val neoForge12102 = createNode("1.21.2-neoforge", 12102, "official") val fabric12102 = createNode("1.21.2-fabric", 12102, "official") @@ -37,6 +39,8 @@ preprocess { val forge11605 = createNode("1.16.5-forge", 11605, "official") val fabric11605 = createNode("1.16.5-fabric", 11605, "official") + fabric12104.link(fabric12102) + fabric12102.link(fabric12100) neoForge12102.link(neoForge12100) diff --git a/client/src/main/java/su/plo/voice/client/mixin/MixinSkinManager.java b/client/src/main/java/su/plo/voice/client/mixin/MixinSkinManager.java index df83bf30..d8e8b163 100644 --- a/client/src/main/java/su/plo/voice/client/mixin/MixinSkinManager.java +++ b/client/src/main/java/su/plo/voice/client/mixin/MixinSkinManager.java @@ -9,7 +9,6 @@ //#if MC>=12002 //$$ import com.mojang.authlib.minecraft.MinecraftSessionService; -//$$ import net.minecraft.client.renderer.texture.TextureManager; //$$ //$$ import org.spongepowered.asm.mixin.Unique; //$$ import org.spongepowered.asm.mixin.injection.At; @@ -18,6 +17,11 @@ //$$ //$$ import java.nio.file.Path; //$$ import java.util.concurrent.Executor; + +//#if MC<12104 +//$$ import net.minecraft.client.renderer.texture.TextureManager; +//#endif + //#else import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Shadow; @@ -26,7 +30,19 @@ @Mixin(SkinManager.class) public abstract class MixinSkinManager implements SkinManagerAccessor { - //#if MC>=12002 + //#if MC>=12104 + //$$ @Unique + //$$ private static File SKINS_DIRECTORY; + //$$ @Inject(at = @At("RETURN"), method = "") + //$$ private void init(Path path, MinecraftSessionService minecraftSessionService, Executor executor, CallbackInfo ci) { + //$$ SKINS_DIRECTORY = path.toFile(); + //$$ } + //$$ @NotNull + //$$ @Override + //$$ public File getSkinsCacheFolder() { + //$$ return SKINS_DIRECTORY; + //$$ } + //#elseif MC>=12002 //$$ @Unique //$$ private static File SKINS_DIRECTORY; //$$ @Inject(at = @At("RETURN"), method = "") diff --git a/client/src/main/kotlin/gg/essential/universal/DummyPack.kt b/client/src/main/kotlin/gg/essential/universal/DummyPack.kt index 22fd61cd..453bcdc2 100644 --- a/client/src/main/kotlin/gg/essential/universal/DummyPack.kt +++ b/client/src/main/kotlin/gg/essential/universal/DummyPack.kt @@ -5,7 +5,6 @@ import gg.essential.universal.shader.MCShader import net.minecraft.resources.ResourceLocation import net.minecraft.server.packs.PackResources import net.minecraft.server.packs.PackType -import net.minecraft.server.packs.metadata.MetadataSectionSerializer import net.minecraft.server.packs.resources.IoSupplier import java.io.InputStream @@ -13,6 +12,12 @@ import java.io.InputStream //$$ import net.minecraft.server.packs.PackLocationInfo //#endif +//#if MC>=12104 +//$$ import net.minecraft.server.packs.metadata.MetadataSectionType +//#else +import net.minecraft.server.packs.metadata.MetadataSectionSerializer +//#endif + /** * A dummy resource pack for use in [MCShader], since the [Resource] constructor * on 1.19.3+ requires a [PackResources] instead of a String name. @@ -46,9 +51,15 @@ object DummyPack : PackResources { throw UnsupportedOperationException() } + //#if MC>=12104 + //$$ override fun getMetadataSection(metadataSectionType: MetadataSectionType): T? { + //$$ throw UnsupportedOperationException() + //$$ } + //#else override fun getMetadataSection(metadataSectionSerializer: MetadataSectionSerializer): T? { throw UnsupportedOperationException() } + //#endif //#if MC>=12005 //$$ override fun location(): PackLocationInfo { diff --git a/client/src/main/kotlin/su/plo/voice/client/crowdin/PlasmoCrowdinPack.kt b/client/src/main/kotlin/su/plo/voice/client/crowdin/PlasmoCrowdinPack.kt index 95158a46..6e4022e8 100644 --- a/client/src/main/kotlin/su/plo/voice/client/crowdin/PlasmoCrowdinPack.kt +++ b/client/src/main/kotlin/su/plo/voice/client/crowdin/PlasmoCrowdinPack.kt @@ -4,7 +4,6 @@ import com.google.common.collect.ImmutableSet import net.minecraft.resources.ResourceLocation import net.minecraft.server.packs.PackResources import net.minecraft.server.packs.PackType -import net.minecraft.server.packs.metadata.MetadataSectionSerializer import java.io.File import java.io.InputStream @@ -20,6 +19,12 @@ import net.minecraft.server.packs.resources.IoSupplier //$$ import java.util.function.Predicate //#endif +//#if MC>=12104 +//$$ import net.minecraft.server.packs.metadata.MetadataSectionType +//#else +import net.minecraft.server.packs.metadata.MetadataSectionSerializer +//#endif + class PlasmoCrowdinPack( private val crowdinFolder: File ) : PackResources { @@ -88,7 +93,11 @@ class PlasmoCrowdinPack( override fun getNamespaces(packType: PackType): Set = NAMESPACES - override fun getMetadataSection(metadataSectionSerializer: MetadataSectionSerializer) = null + //#if MC>=12104 + //$$ override fun getMetadataSection(metadataSectionType: MetadataSectionType): T? = null + //#else + override fun getMetadataSection(metadataSectionSerializer: MetadataSectionSerializer): T? = null + //#endif //#if MC>11902 override fun packId() = "Plasmo Crowdin resource pack" diff --git a/client/src/main/kotlin/su/plo/voice/client/render/cape/DeveloperCapeManager.kt b/client/src/main/kotlin/su/plo/voice/client/render/cape/DeveloperCapeManager.kt index 19fbf82e..331ececd 100644 --- a/client/src/main/kotlin/su/plo/voice/client/render/cape/DeveloperCapeManager.kt +++ b/client/src/main/kotlin/su/plo/voice/client/render/cape/DeveloperCapeManager.kt @@ -6,7 +6,6 @@ import com.google.common.cache.CacheBuilder import com.google.common.hash.Hashing import com.mojang.authlib.minecraft.MinecraftProfileTexture import net.minecraft.client.Minecraft -import net.minecraft.client.renderer.texture.HttpTexture import net.minecraft.resources.ResourceLocation import su.plo.lib.mod.client.ResourceLocationUtil import su.plo.lib.mod.client.render.texture.ModPlayerSkins @@ -22,6 +21,12 @@ import java.util.function.Supplier //$$ import net.minecraft.client.resources.PlayerSkin //#endif +//#if MC>=12104 +//$$ import net.minecraft.client.renderer.texture.SkinTextureDownloader +//#else +import net.minecraft.client.renderer.texture.HttpTexture +//#endif + object DeveloperCapeManager { private val loadedCapes: Cache>> = CacheBuilder.newBuilder() @@ -93,10 +98,22 @@ object DeveloperCapeManager { capeFile.delete() } + //#if MC>=12104 + //$$ try { + //$$ SkinTextureDownloader.downloadAndRegisterSkin( + //$$ capeLocation, + //$$ capeFile.toPath(), + //$$ texture.url, + //$$ false + //$$ ).get() + //$$ } catch (ignored: Exception) { + //$$ } + //#else Minecraft.getInstance().textureManager.register( capeLocation, HttpTexture(capeFile, texture.url, ModPlayerSkins.getDefaultSkin(UUID.randomUUID()), false) {} ) + //#endif capeLocation } diff --git a/client/versions.toml b/client/versions.toml index 2889c47f..1f5f85be 100644 --- a/client/versions.toml +++ b/client/versions.toml @@ -1,3 +1,7 @@ +[12104] +mcVersions = ">1.21.3" +neoForgeVersion = "[21,)" + [12102] mcVersions = ">1.21.1" neoForgeVersion = "[21,)" From 7bcb6c1b28fffe77faaa8261051fbd498f8ea887 Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Tue, 26 Nov 2024 11:57:48 +0800 Subject: [PATCH 15/17] build: update slib --- gradle/libs.versions.toml | 2 +- proxy/changelog.md | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f3db0ef2..3f30c30d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,7 +13,7 @@ gson = "2.10.1" netty = "4.1.77.Final" crowdin = "1.1.0-SNAPSHOT" config = "1.0.2" -slib = "1.0.1-SNAPSHOT" +slib = "1.0.2-SNAPSHOT" bstats = "3.0.2" luckperms = "5.4" papi = "2.11.6" diff --git a/proxy/changelog.md b/proxy/changelog.md index 51fa8178..adb58ce4 100644 --- a/proxy/changelog.md +++ b/proxy/changelog.md @@ -9,4 +9,5 @@ so there’s no need to worry if the server hasn't been updated to 2.1.x. - Fixed buffer overflow when using AudioSender with delayed first frame. - Fixed client EncoderException on server switch caused by UDP packets sent to a client when client's server is null. - Fixed ArrayIndexOutOfBoundsException exception when using `/` command on Velocity. -- Fixed `pv.activation.*` permission is not being updated on the client without reconnect. \ No newline at end of file +- Fixed `pv.activation.*` permission is not being updated on the client without reconnect. +- Fixed permission check on BungeeCord. \ No newline at end of file From 34bb3531a2f32d1049c5c5751348be947b9911a7 Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Wed, 4 Dec 2024 10:14:14 +0800 Subject: [PATCH 16/17] feat(client): 1.21.4 fabric/neoforge --- .github/workflows/alpha.yml | 4 ++++ .github/workflows/release.yml | 4 ++++ client/1.21.2-neoforge/gradle.properties | 1 - .../gradle.properties | 0 client/1.21.3-neoforge/gradle.properties | 1 + client/1.21.4-fabric/gradle.properties | 2 +- client/1.21.4-neoforge/gradle.properties | 1 + client/build.gradle.kts | 9 ++++----- client/changelog.md | 1 + client/root.gradle.kts | 12 +++++++----- client/versions.toml | 4 ++-- 11 files changed, 25 insertions(+), 14 deletions(-) delete mode 100644 client/1.21.2-neoforge/gradle.properties rename client/{1.21.2-fabric => 1.21.3-fabric}/gradle.properties (100%) create mode 100644 client/1.21.3-neoforge/gradle.properties create mode 100644 client/1.21.4-neoforge/gradle.properties diff --git a/.github/workflows/alpha.yml b/.github/workflows/alpha.yml index 6fee617d..22963e1f 100644 --- a/.github/workflows/alpha.yml +++ b/.github/workflows/alpha.yml @@ -59,6 +59,8 @@ jobs: 1.20.4 1.21 1.21.1 + 1.21.2 + 1.21.3 modrinth-unfeature-mode: 'subset' modrinth-id: 1bZhdhsH @@ -84,6 +86,8 @@ jobs: 1.20.4 1.21 1.21.1 + 1.21.2 + 1.21.3 modrinth-unfeature-mode: 'subset' modrinth-id: 1bZhdhsH diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 612f17be..ac49c768 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -58,6 +58,8 @@ jobs: 1.20.4 1.21 1.21.1 + 1.21.2 + 1.21.3 modrinth-unfeature-mode: 'subset' modrinth-id: 1bZhdhsH @@ -82,6 +84,8 @@ jobs: 1.20.4 1.21 1.21.1 + 1.21.2 + 1.21.3 modrinth-unfeature-mode: 'subset' modrinth-id: 1bZhdhsH diff --git a/client/1.21.2-neoforge/gradle.properties b/client/1.21.2-neoforge/gradle.properties deleted file mode 100644 index 809aed51..00000000 --- a/client/1.21.2-neoforge/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -essential.defaults.loom.neoForge=net.neoforged:neoforge:21.2.0-beta diff --git a/client/1.21.2-fabric/gradle.properties b/client/1.21.3-fabric/gradle.properties similarity index 100% rename from client/1.21.2-fabric/gradle.properties rename to client/1.21.3-fabric/gradle.properties diff --git a/client/1.21.3-neoforge/gradle.properties b/client/1.21.3-neoforge/gradle.properties new file mode 100644 index 00000000..bdfefe60 --- /dev/null +++ b/client/1.21.3-neoforge/gradle.properties @@ -0,0 +1 @@ +essential.defaults.loom.neoForge=net.neoforged:neoforge:21.3.57 diff --git a/client/1.21.4-fabric/gradle.properties b/client/1.21.4-fabric/gradle.properties index 1e3bbc1d..88fcece3 100644 --- a/client/1.21.4-fabric/gradle.properties +++ b/client/1.21.4-fabric/gradle.properties @@ -1 +1 @@ -essential.defaults.loom.minecraft=com.mojang:minecraft:1.21.4-pre1 +essential.defaults.loom.minecraft=com.mojang:minecraft:1.21.4 diff --git a/client/1.21.4-neoforge/gradle.properties b/client/1.21.4-neoforge/gradle.properties new file mode 100644 index 00000000..ddf38cf8 --- /dev/null +++ b/client/1.21.4-neoforge/gradle.properties @@ -0,0 +1 @@ +essential.defaults.loom.neoForge=net.neoforged:neoforge:21.4.2-beta diff --git a/client/build.gradle.kts b/client/build.gradle.kts index 8a4fabe5..841ed1f6 100644 --- a/client/build.gradle.kts +++ b/client/build.gradle.kts @@ -60,7 +60,7 @@ val shadowCommon by configurations.creating fun slibArtifact(): String { val minecraftVersion = when (platform.mcVersion) { 11904 -> "1.19.3" - 12104 -> "1.21.2" + 12103, 12104 -> "1.21.2" else -> platform.mcVersionStr } @@ -89,8 +89,8 @@ 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" - 12104 -> "0.109.1+1.21.4" + 12103 -> "0.110.0+1.21.3" + 12104 -> "0.110.5+1.21.4" else -> throw GradleException("Unsupported platform $platform") } @@ -103,8 +103,7 @@ dependencies { fabricApiModules("rendering-v1", "networking-api-v1", "lifecycle-events-v1", "key-binding-api-v1") if (platform.mcVersion >= 12102) { - // https://github.com/lucko/fabric-permissions-api/pull/26 - "include"("com.github.sakura-ryoko:fabric-permissions-api:b43d33efb8") + "include"("me.lucko:fabric-permissions-api:0.3.3") } else { "include"("me.lucko:fabric-permissions-api:0.2-SNAPSHOT") } diff --git a/client/changelog.md b/client/changelog.md index 7ad7ee22..db41edc9 100644 --- a/client/changelog.md +++ b/client/changelog.md @@ -6,6 +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.2 +- 1.21.4 fabric/neoforge. - Fixed buffer overflow when using AudioSender with delayed first frame. - Fixed EncoderException on server switch on servers with proxy and proxy-side addons (e.g, groups addon). - Fixed `pv.activation.*` permission is not being updated on the client without reconnect. diff --git a/client/root.gradle.kts b/client/root.gradle.kts index d4b2db72..61c49960 100644 --- a/client/root.gradle.kts +++ b/client/root.gradle.kts @@ -6,10 +6,11 @@ group = "$group.client-root" preprocess { + val neoForge12104 = createNode("1.21.4-neoforge", 12104, "official") val fabric12104 = createNode("1.21.4-fabric", 12104, "official") - val neoForge12102 = createNode("1.21.2-neoforge", 12102, "official") - val fabric12102 = createNode("1.21.2-fabric", 12102, "official") + val neoForge12103 = createNode("1.21.3-neoforge", 12103, "official") + val fabric12103 = createNode("1.21.3-fabric", 12103, "official") val neoForge12100 = createNode("1.21-neoforge", 12100, "official") val fabric12100 = createNode("1.21-fabric", 12100, "official") @@ -39,10 +40,11 @@ preprocess { val forge11605 = createNode("1.16.5-forge", 11605, "official") val fabric11605 = createNode("1.16.5-fabric", 11605, "official") - fabric12104.link(fabric12102) + fabric12104.link(fabric12103) + neoForge12104.link(neoForge12103) - fabric12102.link(fabric12100) - neoForge12102.link(neoForge12100) + fabric12103.link(fabric12100) + neoForge12103.link(neoForge12100) neoForge12100.link(fabric12100) fabric12100.link(fabric12004, file("1.21-1.20.6.txt")) diff --git a/client/versions.toml b/client/versions.toml index 1f5f85be..ea9b85c8 100644 --- a/client/versions.toml +++ b/client/versions.toml @@ -2,8 +2,8 @@ mcVersions = ">1.21.3" neoForgeVersion = "[21,)" -[12102] -mcVersions = ">1.21.1" +[12103] +mcVersions = ">=1.21.2 <=1.21.3" neoForgeVersion = "[21,)" [12100] From 448f82bc6046275c5a8ecaab4a6023cc2f352186 Mon Sep 17 00:00:00 2001 From: Apehum <36326454+Apehum@users.noreply.github.com> Date: Wed, 4 Dec 2024 12:18:54 +0800 Subject: [PATCH 17/17] fix(client): check if Minecraft connection is null only in 1.20.4+ --- .../su/plo/voice/client/connection/ModServerConnection.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/src/main/java/su/plo/voice/client/connection/ModServerConnection.java b/client/src/main/java/su/plo/voice/client/connection/ModServerConnection.java index 9d78b88c..652d3ef5 100644 --- a/client/src/main/java/su/plo/voice/client/connection/ModServerConnection.java +++ b/client/src/main/java/su/plo/voice/client/connection/ModServerConnection.java @@ -121,7 +121,10 @@ public ModServerConnection(@NotNull BaseVoiceClient voiceClient, @Override public void sendPacket(@NotNull Packet packet, boolean checkUdpConnection) { - if (!connection.isConnected() || Minecraft.getInstance().getConnection() == null) return; + if (!connection.isConnected()) return; + //#if MC>=12004 + //$$ if (Minecraft.getInstance().getConnection() == null) return; + //#endif if (checkUdpConnection && !voiceClient.getUdpClientManager().isConnected()) return;