diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ca100ccb0..77a8460b4 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -50,6 +50,8 @@ jobs: 1.20.3 1.20.4 1.20.5 + 1.20.6 + 1.21 modrinth-unfeature-mode: 'subset' modrinth-id: 1bZhdhsH @@ -75,6 +77,8 @@ jobs: 1.20.3 1.20.4 1.20.5 + 1.20.6 + 1.21 modrinth-unfeature-mode: 'subset' modrinth-id: 1bZhdhsH diff --git a/api/common/src/main/java/su/plo/voice/api/util/AudioUtil.java b/api/common/src/main/java/su/plo/voice/api/util/AudioUtil.java index c4c917821..9eb72461b 100644 --- a/api/common/src/main/java/su/plo/voice/api/util/AudioUtil.java +++ b/api/common/src/main/java/su/plo/voice/api/util/AudioUtil.java @@ -60,7 +60,15 @@ public static short[] floatsToShorts(float[] floats) { short[] shorts = new short[floats.length]; for(int i = 0; i < floats.length; i++) { - shorts[i] = Float.valueOf(floats[i]).shortValue(); + shorts[i] = Float.valueOf( + Math.min( // Clamp to prevent overdrive causing clipping (https://github.com/remjey/mumble/commit/f16b47c81aceaf0c8704b355d9316bf685cb3704) + Short.MAX_VALUE, + Math.max( + Short.MIN_VALUE, + floats[i] + ) + ) + ).shortValue(); } return shorts; diff --git a/client/1.21-fabric/gradle.properties b/client/1.21-fabric/gradle.properties new file mode 100644 index 000000000..cd226e39b --- /dev/null +++ b/client/1.21-fabric/gradle.properties @@ -0,0 +1 @@ +essential.defaults.loom.minecraft=com.mojang:minecraft:1.21 diff --git a/client/build.gradle.kts b/client/build.gradle.kts index 916ef9425..2fb965712 100644 --- a/client/build.gradle.kts +++ b/client/build.gradle.kts @@ -45,15 +45,6 @@ plasmoCrowdin { val shadowCommon by configurations.creating -fun uStatsVersion() = rootProject.libs.versions.ustats.map { - val minecraftVersion = when (platform.mcVersion) { - 12001, 12002, 12004, 12006 -> "1.20" - else -> platform.mcVersionStr - } - - "${minecraftVersion}-${platform.loaderStr}:$it" -}.get() - repositories { maven("https://repo.essential.gg/repository/maven-public") } @@ -71,6 +62,7 @@ dependencies { 12002 -> "0.89.1+1.20.2" 12004 -> "0.97.0+1.20.4" 12006 -> "0.97.8+1.20.6" + 12100 -> "0.100.1+1.21" else -> throw GradleException("Unsupported platform $platform") } @@ -89,15 +81,6 @@ dependencies { } } - "su.plo.ustats:${uStatsVersion()}".also { - modApi(it) { - isTransitive = false - } - shadowCommon(it) { - isTransitive = false - } - } - val includedProjects = listOf( ":api:common", ":api:client", @@ -154,8 +137,6 @@ tasks { relocate("su.plo.crowdin", "su.plo.voice.libs.crowdin") relocate("gg.essential.universal", "su.plo.voice.universal") - relocate("su.plo.ustats", "su.plo.voice.ustats") - dependencies { exclude(dependency("net.java.dev.jna:jna")) exclude(dependency("org.slf4j:slf4j-api")) diff --git a/client/changelog.md b/client/changelog.md index b1232c123..b91d96002 100644 --- a/client/changelog.md +++ b/client/changelog.md @@ -1,2 +1,3 @@ -- Fixed stacktrace spam on bad packets [#397](https://github.com/plasmoapp/plasmo-voice/issues/397) -- 1.20.5, 1.20.6 support +- Fixed distorted RNNoise output during mono capture [#400](https://github.com/plasmoapp/plasmo-voice/pull/400) +- Fixed "Failed to open device" spam in logs +- 1.21 support diff --git a/client/root.gradle.kts b/client/root.gradle.kts index 9b93bafcc..0b47e02b9 100644 --- a/client/root.gradle.kts +++ b/client/root.gradle.kts @@ -8,6 +8,8 @@ group = "$mavenGroup.client-root" preprocess { + val fabric12100 = createNode("1.21-fabric", 12100, "official") + val fabric12006 = createNode("1.20.6-fabric", 12006, "official") val fabric12004 = createNode("1.20.4-fabric", 12004, "official") @@ -22,6 +24,8 @@ preprocess { val forge11902 = createNode("1.19.2-forge", 11902, "official") val fabric11902 = createNode("1.19.2-fabric", 11902, "official") + fabric12100.link(fabric12006) + fabric12006.link(fabric12004) fabric12004.link(fabric12002) diff --git a/client/src/main/java/su/plo/lib/mod/client/gui/widget/GuiWidget.java b/client/src/main/java/su/plo/lib/mod/client/gui/widget/GuiWidget.java index fb639472f..f5a6696d2 100644 --- a/client/src/main/java/su/plo/lib/mod/client/gui/widget/GuiWidget.java +++ b/client/src/main/java/su/plo/lib/mod/client/gui/widget/GuiWidget.java @@ -7,13 +7,13 @@ public interface GuiWidget { //#if MC>=12005 - //$$ ResourceLocation MENU_LIST_BACKGROUND_LOCATION = new ResourceLocation("textures/gui/menu_list_background.png"); - //$$ ResourceLocation INWORLD_MENU_LIST_BACKGROUND_LOCATION = new ResourceLocation("textures/gui/inworld_menu_list_background.png"); + //$$ ResourceLocation MENU_LIST_BACKGROUND_LOCATION = ResourceLocation.tryParse("textures/gui/menu_list_background.png"); + //$$ ResourceLocation INWORLD_MENU_LIST_BACKGROUND_LOCATION = ResourceLocation.tryParse("textures/gui/inworld_menu_list_background.png"); //$$ - //$$ ResourceLocation FOOTER_SEPARATOR_LOCATION = new ResourceLocation("textures/gui/footer_separator.png"); - //$$ ResourceLocation INWORLD_FOOTER_SEPARATOR_LOCATION = new ResourceLocation("textures/gui/inworld_footer_separator.png"); + //$$ ResourceLocation FOOTER_SEPARATOR_LOCATION = ResourceLocation.tryParse("textures/gui/footer_separator.png"); + //$$ ResourceLocation INWORLD_FOOTER_SEPARATOR_LOCATION = ResourceLocation.tryParse("textures/gui/inworld_footer_separator.png"); //#else - ResourceLocation BACKGROUND_LOCATION = new ResourceLocation("textures/gui/options_background.png"); + ResourceLocation BACKGROUND_LOCATION = ResourceLocation.tryParse("textures/gui/options_background.png"); //#endif int getWidth(); 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 2033703a5..c3d1f9a25 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 @@ -342,7 +342,11 @@ public static int drawStringLight(UMatrixStack stack, MinecraftTextComponent tex boolean displayMode = seeThrough; //#endif + //#if MC>=12100 + //$$ MultiBufferSource.BufferSource irendertypebuffer$impl = UMinecraft.getMinecraft().renderBuffers().bufferSource(); + //#else MultiBufferSource.BufferSource irendertypebuffer$impl = MultiBufferSource.immediate(Tesselator.getInstance().getBuilder()); + //#endif UMinecraft.getFontRenderer().drawInBatch( formattedText, (float) x, diff --git a/client/src/main/java/su/plo/lib/mod/client/render/texture/ModPlayerSkins.java b/client/src/main/java/su/plo/lib/mod/client/render/texture/ModPlayerSkins.java index 0a8074c0f..2246e50e6 100644 --- a/client/src/main/java/su/plo/lib/mod/client/render/texture/ModPlayerSkins.java +++ b/client/src/main/java/su/plo/lib/mod/client/render/texture/ModPlayerSkins.java @@ -42,7 +42,7 @@ public static synchronized void loadSkin(@NotNull UUID playerId, if (skinLocation != null) return; if (fallback != null) { - ResourceLocation fallbackIdentifier = new ResourceLocation( + ResourceLocation fallbackIdentifier = ResourceLocation.tryBuild( "plasmovoice", "skins/" + Hashing.sha1().hashUnencodedChars(nick.toLowerCase()) ); @@ -72,7 +72,7 @@ public static synchronized void loadSkin(@NotNull UUID playerId, ); } else { String hash = Hashing.sha1().hashUnencodedChars(textures.get(MinecraftProfileTexture.Type.SKIN).getHash()).toString(); - ResourceLocation identifier = new ResourceLocation("skins/" + hash); + ResourceLocation identifier = ResourceLocation.tryParse("skins/" + hash); skins.put(profile.getName(), identifier); } //#endif diff --git a/client/src/main/java/su/plo/lib/mod/client/texture/ResourceCache.java b/client/src/main/java/su/plo/lib/mod/client/texture/ResourceCache.java index dd8ca0945..833847427 100644 --- a/client/src/main/java/su/plo/lib/mod/client/texture/ResourceCache.java +++ b/client/src/main/java/su/plo/lib/mod/client/texture/ResourceCache.java @@ -13,7 +13,7 @@ public final class ResourceCache { public ResourceLocation getLocation(@NotNull String resourceLocation) { return locationByString.computeIfAbsent( resourceLocation, - ResourceLocation::new + ResourceLocation::tryParse ); } } diff --git a/client/src/main/java/su/plo/lib/mod/server/world/ModServerWorld.java b/client/src/main/java/su/plo/lib/mod/server/world/ModServerWorld.java index 0d6a9683c..2c0c96107 100644 --- a/client/src/main/java/su/plo/lib/mod/server/world/ModServerWorld.java +++ b/client/src/main/java/su/plo/lib/mod/server/world/ModServerWorld.java @@ -71,15 +71,15 @@ public int hashCode() { //#if MC>=12005 //$$ private Holder.Reference parseGameEvent(@NotNull String gameEventName) { - //$$ return BuiltInRegistries.GAME_EVENT.getHolder(new ResourceLocation(gameEventName)) + //$$ return BuiltInRegistries.GAME_EVENT.getHolder(ResourceLocation.tryParse(gameEventName)) //$$ .orElseThrow(() -> new IllegalArgumentException("Invalid game event")); //$$ } //#else private GameEvent parseGameEvent(@NotNull String gameEventName) { //#if MC>=11903 - return BuiltInRegistries.GAME_EVENT.get(new ResourceLocation(gameEventName)); + return BuiltInRegistries.GAME_EVENT.get(ResourceLocation.tryParse(gameEventName)); //#else - //$$ return Registry.GAME_EVENT.get(new ResourceLocation(gameEventName)); + //$$ return Registry.GAME_EVENT.get(ResourceLocation.tryParse(gameEventName)); //#endif } //#endif 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 0294fa41f..9ee297ab0 100644 --- a/client/src/main/java/su/plo/voice/client/ModVoiceClient.java +++ b/client/src/main/java/su/plo/voice/client/ModVoiceClient.java @@ -144,7 +144,16 @@ public void onInitializeClient() { ClientLifecycleEvents.CLIENT_STOPPING.register((minecraft) -> onShutdown()); HudRenderCallback.EVENT.register(hudRenderer::render); WorldRenderEvents.LAST.register( - (context) -> levelRenderer.render(context.world(), context.matrixStack(), context.camera(), context.tickDelta()) + (context) -> levelRenderer.render( + context.world(), + context.matrixStack(), + context.camera(), + //#if MC>=12100 + //$$ context.tickCounter().getRealtimeDeltaTicks() + //#else + context.tickDelta() + //#endif + ) ); ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> onServerDisconnect()); diff --git a/client/src/main/java/su/plo/voice/client/audio/capture/VoiceClientActivationManager.java b/client/src/main/java/su/plo/voice/client/audio/capture/VoiceClientActivationManager.java index f9213556f..b7fe0cf27 100644 --- a/client/src/main/java/su/plo/voice/client/audio/capture/VoiceClientActivationManager.java +++ b/client/src/main/java/su/plo/voice/client/audio/capture/VoiceClientActivationManager.java @@ -102,7 +102,7 @@ public Optional getParentActivation() { String icon = VoiceIconUtil.INSTANCE.getIcon( serverActivation.getIcon(), - new ResourceLocation("plasmovoice:textures/addons/activations/" + serverActivation.getName()) + ResourceLocation.tryParse("plasmovoice:textures/addons/activations/" + serverActivation.getName()) ); ClientActivation activation = register(new VoiceClientActivation( diff --git a/client/src/main/java/su/plo/voice/client/audio/device/VoiceDeviceManager.java b/client/src/main/java/su/plo/voice/client/audio/device/VoiceDeviceManager.java index aa68f12c2..98a6f9fa3 100644 --- a/client/src/main/java/su/plo/voice/client/audio/device/VoiceDeviceManager.java +++ b/client/src/main/java/su/plo/voice/client/audio/device/VoiceDeviceManager.java @@ -44,6 +44,9 @@ public final class VoiceDeviceManager implements DeviceManager { private ScheduledFuture job; + private String failedOutputDevices = ""; + private String failedInputDevices = ""; + @Override public void add(@NotNull AudioDevice device) { checkNotNull(device, "device cannot be null"); @@ -248,11 +251,16 @@ private void tickJob() throws DeviceException { .orElseThrow(() -> new IllegalStateException("OpenAL input factory is not registered"));; if (outputDevices.isEmpty()) { - if (outputFactory.getDeviceNames().size() > 0) { + List deviceNames = outputFactory.getDeviceNames(); + String deviceNamesString = String.join("\n", deviceNames); + + if (deviceNames.size() > 0 && !deviceNamesString.equals(failedOutputDevices)) { try { add(voiceClient.getDeviceManager().openOutputDevice(null, Params.EMPTY)); + failedOutputDevices = ""; } catch (Exception e) { LOGGER.error("Failed to open primary OpenAL output device", e); + failedOutputDevices = deviceNamesString; } if (!voiceClient.getAudioCapture().isActive() && !inputDevices.isEmpty()) { @@ -271,11 +279,16 @@ private void tickJob() throws DeviceException { } if (inputDevices.isEmpty()) { - if (inputFactory.getDeviceNames().size() > 0 && !config.getVoice().getDisableInputDevice().value()) { + List deviceNames = inputFactory.getDeviceNames(); + String deviceNamesString = String.join("\n", deviceNames); + + if (deviceNames.size() > 0 && !deviceNamesString.equals(failedInputDevices) && !config.getVoice().getDisableInputDevice().value()) { try { replace(null, voiceClient.getDeviceManager().openInputDevice(null, Params.EMPTY)); + failedInputDevices = ""; } catch (Exception e) { LOGGER.error("Failed to open input device", e); + failedInputDevices = deviceNamesString; } if (!voiceClient.getAudioCapture().isActive()) { diff --git a/client/src/main/java/su/plo/voice/client/audio/line/VoiceClientSourceLineManager.java b/client/src/main/java/su/plo/voice/client/audio/line/VoiceClientSourceLineManager.java index 552c7734e..8f25eecc6 100644 --- a/client/src/main/java/su/plo/voice/client/audio/line/VoiceClientSourceLineManager.java +++ b/client/src/main/java/su/plo/voice/client/audio/line/VoiceClientSourceLineManager.java @@ -110,7 +110,7 @@ public void clear() { String icon = VoiceIconUtil.INSTANCE.getIcon( line.getIcon(), - new ResourceLocation("plasmovoice:textures/addons/source_lines/" + line.getName()) + ResourceLocation.tryParse("plasmovoice:textures/addons/source_lines/" + line.getName()) ); DoubleConfigEntry volumeEntry = config.getVoice() diff --git a/client/src/main/java/su/plo/voice/client/gui/settings/VoiceSettingsNavigation.java b/client/src/main/java/su/plo/voice/client/gui/settings/VoiceSettingsNavigation.java index f83df437f..11ea1ab24 100644 --- a/client/src/main/java/su/plo/voice/client/gui/settings/VoiceSettingsNavigation.java +++ b/client/src/main/java/su/plo/voice/client/gui/settings/VoiceSettingsNavigation.java @@ -114,7 +114,7 @@ public void init() { ).withStyle(MinecraftTextStyle.GRAY) )); }, - new ResourceLocation("plasmovoice:textures/icons/microphone_menu.png"), + ResourceLocation.tryParse("plasmovoice:textures/icons/microphone_menu.png"), true ); @@ -142,7 +142,7 @@ public void init() { ).withStyle(MinecraftTextStyle.GRAY) )); }, - new ResourceLocation("plasmovoice:textures/icons/microphone_menu_disabled.png"), + ResourceLocation.tryParse("plasmovoice:textures/icons/microphone_menu_disabled.png"), true ); @@ -181,7 +181,7 @@ public void init() { ).withStyle(MinecraftTextStyle.GRAY) )); }, - new ResourceLocation("plasmovoice:textures/icons/speaker_menu.png"), + ResourceLocation.tryParse("plasmovoice:textures/icons/speaker_menu.png"), true ); @@ -208,7 +208,7 @@ public void init() { ).withStyle(MinecraftTextStyle.GRAY) )); }, - new ResourceLocation("plasmovoice:textures/icons/speaker_menu_disabled.png"), + ResourceLocation.tryParse("plasmovoice:textures/icons/speaker_menu_disabled.png"), true ); diff --git a/client/src/main/java/su/plo/voice/client/gui/settings/VoiceSettingsScreen.java b/client/src/main/java/su/plo/voice/client/gui/settings/VoiceSettingsScreen.java index f046c48ee..ff383a0c0 100644 --- a/client/src/main/java/su/plo/voice/client/gui/settings/VoiceSettingsScreen.java +++ b/client/src/main/java/su/plo/voice/client/gui/settings/VoiceSettingsScreen.java @@ -78,38 +78,38 @@ public void init() { navigation.addTab( MinecraftTextComponent.translatable("gui.plasmovoice.devices"), - new ResourceLocation("plasmovoice:textures/icons/tabs/devices.png"), + ResourceLocation.tryParse("plasmovoice:textures/icons/tabs/devices.png"), new DevicesTabWidget(this, voiceClient, config, testController) ); navigation.addTab( MinecraftTextComponent.translatable("gui.plasmovoice.volume"), - new ResourceLocation("plasmovoice:textures/icons/tabs/volume.png"), + ResourceLocation.tryParse("plasmovoice:textures/icons/tabs/volume.png"), new VolumeTabWidget(this, voiceClient, config) ); navigation.addTab( MinecraftTextComponent.translatable("gui.plasmovoice.activation"), - new ResourceLocation("plasmovoice:textures/icons/tabs/activation.png"), + ResourceLocation.tryParse("plasmovoice:textures/icons/tabs/activation.png"), new ActivationTabWidget(this, voiceClient, config) ); navigation.addTab( MinecraftTextComponent.translatable("gui.plasmovoice.overlay"), - new ResourceLocation("plasmovoice:textures/icons/tabs/overlay.png"), + ResourceLocation.tryParse("plasmovoice:textures/icons/tabs/overlay.png"), new OverlayTabWidget(this, voiceClient, config) ); navigation.addTab( MinecraftTextComponent.translatable("gui.plasmovoice.advanced"), - new ResourceLocation("plasmovoice:textures/icons/tabs/advanced.png"), + ResourceLocation.tryParse("plasmovoice:textures/icons/tabs/advanced.png"), new AdvancedTabWidget(this, voiceClient, config) ); navigation.addTab( MinecraftTextComponent.translatable("gui.plasmovoice.hotkeys"), - new ResourceLocation("plasmovoice:textures/icons/tabs/hotkeys.png"), + ResourceLocation.tryParse("plasmovoice:textures/icons/tabs/hotkeys.png"), new HotKeysTabWidget(this, voiceClient, config) ); if (voiceClient.getAddonConfigs().size() > 0) { navigation.addTab( MinecraftTextComponent.translatable("gui.plasmovoice.addons"), - new ResourceLocation("plasmovoice:textures/icons/tabs/addons.png"), + ResourceLocation.tryParse("plasmovoice:textures/icons/tabs/addons.png"), new AddonsTabWidget(this, voiceClient, config) ); } diff --git a/client/src/main/java/su/plo/voice/client/gui/settings/tab/ActivationTabWidget.java b/client/src/main/java/su/plo/voice/client/gui/settings/tab/ActivationTabWidget.java index cb6b320a9..086bc7fdd 100644 --- a/client/src/main/java/su/plo/voice/client/gui/settings/tab/ActivationTabWidget.java +++ b/client/src/main/java/su/plo/voice/client/gui/settings/tab/ActivationTabWidget.java @@ -235,7 +235,7 @@ public ActivationToggleStateEntry(@NotNull MinecraftTextComponent text, ).withStyle(MinecraftTextStyle.GRAY) )); }, - new ResourceLocation("plasmovoice:textures/icons/microphone_menu.png"), + ResourceLocation.tryParse("plasmovoice:textures/icons/microphone_menu.png"), true ); IconButton enableToggleState = new IconButton( @@ -258,7 +258,7 @@ public ActivationToggleStateEntry(@NotNull MinecraftTextComponent text, ).withStyle(MinecraftTextStyle.GRAY) )); }, - new ResourceLocation("plasmovoice:textures/icons/microphone_menu_disabled.png"), + ResourceLocation.tryParse("plasmovoice:textures/icons/microphone_menu_disabled.png"), true ); diff --git a/client/src/main/java/su/plo/voice/client/gui/settings/tab/OverlayTabWidget.java b/client/src/main/java/su/plo/voice/client/gui/settings/tab/OverlayTabWidget.java index d1e0fe638..014f55fcc 100644 --- a/client/src/main/java/su/plo/voice/client/gui/settings/tab/OverlayTabWidget.java +++ b/client/src/main/java/su/plo/voice/client/gui/settings/tab/OverlayTabWidget.java @@ -109,7 +109,7 @@ private void createOverlaySource(@NotNull ClientSourceLine sourceLine) { widget, configEntry, null, - new ResourceLocation(sourceLine.getIcon()), + ResourceLocation.tryParse(sourceLine.getIcon()), null )); } else { @@ -142,7 +142,7 @@ private void createOverlaySource(@NotNull ClientSourceLine sourceLine) { widget, configEntry, null, - new ResourceLocation(sourceLine.getIcon()), + ResourceLocation.tryParse(sourceLine.getIcon()), (button, element) -> element.setText(OVERLAY_DISPLAYS.get(0)) )); } diff --git a/client/src/main/java/su/plo/voice/client/gui/settings/tab/TabWidget.java b/client/src/main/java/su/plo/voice/client/gui/settings/tab/TabWidget.java index a25cdbcbc..e6f5d53a9 100644 --- a/client/src/main/java/su/plo/voice/client/gui/settings/tab/TabWidget.java +++ b/client/src/main/java/su/plo/voice/client/gui/settings/tab/TabWidget.java @@ -340,7 +340,7 @@ public OptionEntry(@NotNull MinecraftTextComponent text, 20, this::onReset, Button.NO_TOOLTIP, - new ResourceLocation("plasmovoice:textures/icons/reset.png"), + ResourceLocation.tryParse("plasmovoice:textures/icons/reset.png"), true ); diff --git a/client/src/main/java/su/plo/voice/client/gui/settings/tab/VolumeTabWidget.java b/client/src/main/java/su/plo/voice/client/gui/settings/tab/VolumeTabWidget.java index 2d9fcef00..d6ea48e16 100644 --- a/client/src/main/java/su/plo/voice/client/gui/settings/tab/VolumeTabWidget.java +++ b/client/src/main/java/su/plo/voice/client/gui/settings/tab/VolumeTabWidget.java @@ -91,7 +91,7 @@ private void createSourceLineVolume(@NotNull ClientSourceLine sourceLine) { volumeEntry, muteEntry, null, - new ResourceLocation(sourceLine.getIcon()), + ResourceLocation.tryParse(sourceLine.getIcon()), (button, element) -> updateButtons.run() )); } @@ -228,7 +228,7 @@ private List