diff --git a/.gitignore b/.gitignore index 99bbf7f..954fe97 100644 --- a/.gitignore +++ b/.gitignore @@ -80,4 +80,9 @@ nb-configuration.xml ############################## ## OS X ############################## -.DS_Store \ No newline at end of file +.DS_Store + +############################## +## Dev +############################## +release/ \ No newline at end of file diff --git a/build.gradle b/build.gradle index 4bcf89e..8bdcfdb 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ subprojects { apply plugin: 'maven-publish' group = 'net.foxmcloud.clientresetpacket' - version = '0.3.1' + version = '0.4.1' java.toolchain.languageVersion = JavaLanguageVersion.of(17) diff --git a/forge/src/main/java/gg/chaldea/client/reset/packet/ClientReset.java b/forge/src/main/java/gg/chaldea/client/reset/packet/ClientReset.java index a843060..890a9a9 100644 --- a/forge/src/main/java/gg/chaldea/client/reset/packet/ClientReset.java +++ b/forge/src/main/java/gg/chaldea/client/reset/packet/ClientReset.java @@ -97,6 +97,7 @@ public static void handleReset(HandshakeHandler handler, S2CReset msg, Supplier< } logger.info(RESETMARKER, "Received reset packet from server."); + VoiceChatReset.disconnect(); if (!handleClear(context)) { return; diff --git a/forge/src/main/java/gg/chaldea/client/reset/packet/VoiceChatReset.java b/forge/src/main/java/gg/chaldea/client/reset/packet/VoiceChatReset.java new file mode 100644 index 0000000..e4317a9 --- /dev/null +++ b/forge/src/main/java/gg/chaldea/client/reset/packet/VoiceChatReset.java @@ -0,0 +1,55 @@ +package gg.chaldea.client.reset.packet; + +import java.lang.reflect.Method; +import java.util.concurrent.atomic.AtomicBoolean; + +final class VoiceChatReset { + private static final String CLIENT_MANAGER = "de.maxhenkel.voicechat.voice.client.ClientManager"; + private static final String CLIENT_VOICECHAT = "de.maxhenkel.voicechat.voice.client.ClientVoicechat"; + private static final AtomicBoolean RESETTING = new AtomicBoolean(); + + private VoiceChatReset() { + } + + static void disconnect() { + if (!RESETTING.compareAndSet(false, true)) { + return; + } + try { + Class managerType = Class.forName(CLIENT_MANAGER); + Object manager = managerType.getMethod("instance").invoke(null); + Method onDisconnect = managerType.getDeclaredMethod("onDisconnect"); + onDisconnect.setAccessible(true); + onDisconnect.invoke(manager); + } catch (ClassNotFoundException ignored) { + // Simple Voice Chat is optional. + } catch (ReflectiveOperationException | RuntimeException exception) { + // Older SVC builds may not expose ClientManager.onDisconnect(). + closeLegacyClient(); + } catch (LinkageError error) { + // A different/incompatible SVC build must never crash the client reset. + ClientReset.logger.debug(ClientReset.RESETMARKER, "Simple Voice Chat client reset is incompatible", error); + } finally { + // The SVC client has been fully detached. The next Minecraft PLAY + // connection will create a fresh client through its normal join hook. + RESETTING.set(false); + } + } + + private static void closeLegacyClient() { + try { + Class type = Class.forName(CLIENT_VOICECHAT); + Method getClient = type.getMethod("getInstance"); + Object instance = getClient.invoke(null); + if (instance != null) { + type.getMethod("disconnect").invoke(instance); + } + } catch (ClassNotFoundException ignored) { + // Simple Voice Chat is optional. + } catch (ReflectiveOperationException | RuntimeException exception) { + ClientReset.logger.debug(ClientReset.RESETMARKER, "Simple Voice Chat client reset was not available", exception); + } catch (LinkageError error) { + ClientReset.logger.debug(ClientReset.RESETMARKER, "Simple Voice Chat client reset is incompatible", error); + } + } +} diff --git a/forge/src/main/java/gg/chaldea/client/reset/packet/mixin/VanillaPacketFilterAccessor.java b/forge/src/main/java/gg/chaldea/client/reset/packet/mixin/VanillaPacketFilterAccessor.java index e9cccde..b310b01 100644 --- a/forge/src/main/java/gg/chaldea/client/reset/packet/mixin/VanillaPacketFilterAccessor.java +++ b/forge/src/main/java/gg/chaldea/client/reset/packet/mixin/VanillaPacketFilterAccessor.java @@ -8,6 +8,6 @@ @Mixin(VanillaPacketFilter.class) public interface VanillaPacketFilterAccessor { - @Invoker("isNecessary") + @Invoker(value = "isNecessary", remap = false) boolean invokeIsNecessary(Connection manager); } diff --git a/forge/src/main/resources/META-INF/mods.toml b/forge/src/main/resources/META-INF/mods.toml index f361869..e028f42 100644 --- a/forge/src/main/resources/META-INF/mods.toml +++ b/forge/src/main/resources/META-INF/mods.toml @@ -5,7 +5,7 @@ issueTrackerURL="https://github.com/Just-Chaldea/Forge-Client-Reset-Packet/issue [[mods]] modId="clientresetpacket" -version="0.0.6" +version="0.4.1" displayName="Client Reset Packet" displayURL="https://github.com/Just-Chaldea/Forge-Client-Reset-Packet" credits="https://github.com/Just-Chaldea/Forge-Client-Reset-Packet"