From 08659e641bb0b7e6c6e294772fc46b38b6f901ad Mon Sep 17 00:00:00 2001 From: KabanFriends Date: Tue, 9 Dec 2025 15:27:59 +0900 Subject: [PATCH 1/4] =?UTF-8?q?chore:=20=F0=9F=94=A7=20update=20minecraft?= =?UTF-8?q?=20to=201.21.11?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 13 ++++++++++--- gradle.properties | 16 ++++++---------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/build.gradle b/build.gradle index 8880f62..7ffd0ee 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { id "architectury-plugin" version "3.4-SNAPSHOT" - id "dev.architectury.loom" version "1.11-SNAPSHOT" apply false + id "dev.architectury.loom" version "1.13-SNAPSHOT" apply false } architectury { @@ -23,14 +23,21 @@ subprojects { maven { url "https://maven.isxander.dev/releases" } maven { url "https://maven.terraformersmc.com/" } maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } + // TODO: remove on release + maven { + name = "Maven for PR #2815" // https://github.com/neoforged/NeoForge/pull/2815 + url = uri("https://prmaven.neoforged.net/NeoForge/pr2815") + content { + includeModule("net.neoforged", "neoforge") + includeModule("net.neoforged", "testframework") + } + } } dependencies { minecraft "com.mojang:minecraft:${project.minecraft_version}" mappings loom.layered() { officialMojangMappings() - // TODO: reenable - //parchment("org.parchmentmc.data:parchment-${project.minecraft_version}:${project.parchment_version}@zip") } } } diff --git a/gradle.properties b/gradle.properties index d6db8c2..3e8654b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,21 +4,17 @@ maven_group = io.github.kabanfriends.craftgr archives_base_name = craftgr # Mod Properties -minecraft_version = 1.21.9 +minecraft_version = 1.21.11-rc3 mod_version = 1.9.7 -# Parchment Properties -# See: https://parchmentmc.org/docs/getting-started -parchment_version = 2025.06.29 - # Fabric Properties # See: https://fabricmc.net/develop/ -fabric_loader_version = 0.17.2 -fabric_api_version = 0.133.13+1.21.9 +fabric_loader_version = 0.18.0 +fabric_api_version = 0.139.4+1.21.11 # NeoForge Properties # See: https://neoforged.net/ -neoforge_version = 21.9.1-beta +neoforge_version = 21.11.0-alpha.1.21.11-rc3.20251208.212437 # Library Dependencies jlayer_version = 1.0.3 @@ -26,5 +22,5 @@ java_websocket_version = 1.5.6 math3_version = 3.6.1 # Mod Dependencies -mod_menu_version = 15.0.0 -yacl_version = 3.8.0+1.21.9 +mod_menu_version = 17.0.0-alpha.1 +yacl_version = 3.8.1+1.21.11 From fd3fc5e3d6308f4bae1e055bc9747db58fbedf68 Mon Sep 17 00:00:00 2001 From: KabanFriends Date: Wed, 10 Dec 2025 02:06:41 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20=E2=9C=A8=20various=20updates?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../github/kabanfriends/craftgr/CraftGR.java | 19 +- .../craftgr/audio/AudioPlayer.java | 2 +- .../kabanfriends/craftgr/audio/Radio.java | 31 +-- .../craftgr/config/ModConfig.java | 16 +- .../craftgr/event/ClientEvents.java | 7 +- .../craftgr/gui/RadioOptionContainer.java | 8 +- .../craftgr/keybind/Keybinds.java | 4 +- .../mixin/MixinOptionsListOptionEntry.java | 26 ++- .../craftgr/overlay/SongInfoOverlay.java | 47 ++--- .../overlay/widget/impl/ScrollingText.java | 18 +- .../craftgr/song/JsonAPISongProvider.java | 77 ++++---- .../kabanfriends/craftgr/song/Song.java | 2 +- .../craftgr/song/WebSocketSongProvider.java | 176 ++++++++++-------- .../kabanfriends/craftgr/util/Http.java | 58 ++++++ .../kabanfriends/craftgr/util/HttpUtil.java | 22 --- .../src/main/resources/craftgr.accesswidener | 1 - .../craftgr/fabric/FabricEvents.java | 4 +- 17 files changed, 275 insertions(+), 243 deletions(-) create mode 100644 common/src/main/java/io/github/kabanfriends/craftgr/util/Http.java delete mode 100644 common/src/main/java/io/github/kabanfriends/craftgr/util/HttpUtil.java diff --git a/common/src/main/java/io/github/kabanfriends/craftgr/CraftGR.java b/common/src/main/java/io/github/kabanfriends/craftgr/CraftGR.java index 72a0e87..f7b161e 100644 --- a/common/src/main/java/io/github/kabanfriends/craftgr/CraftGR.java +++ b/common/src/main/java/io/github/kabanfriends/craftgr/CraftGR.java @@ -8,12 +8,11 @@ import io.github.kabanfriends.craftgr.overlay.SongInfoOverlay; import io.github.kabanfriends.craftgr.song.FallbackSongProvider; import io.github.kabanfriends.craftgr.song.SongProvider; +import io.github.kabanfriends.craftgr.util.Http; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.FontDescription; import net.minecraft.network.chat.Style; -import net.minecraft.resources.ResourceLocation; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; +import net.minecraft.resources.Identifier; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -26,8 +25,8 @@ public class CraftGR { public static final String MOD_ID = "craftgr"; public static final String MOD_NAME = "CraftGR"; - public static final Component AUDIO_MUTED_ICON = Component.literal("M").withStyle(Style.EMPTY.withFont(new FontDescription.Resource(ResourceLocation.fromNamespaceAndPath(CraftGR.MOD_ID, "icons")))); - public static final Component RECONNECT_ICON = Component.literal("R").withStyle(Style.EMPTY.withFont(new FontDescription.Resource(ResourceLocation.fromNamespaceAndPath(CraftGR.MOD_ID, "icons")))); + public static final Component AUDIO_MUTED_ICON = Component.literal("M").withStyle(Style.EMPTY.withFont(new FontDescription.Resource(Identifier.fromNamespaceAndPath(CraftGR.MOD_ID, "icons")))); + public static final Component RECONNECT_ICON = Component.literal("R").withStyle(Style.EMPTY.withFont(new FontDescription.Resource(Identifier.fromNamespaceAndPath(CraftGR.MOD_ID, "icons")))); private static CraftGR instance; @@ -35,7 +34,6 @@ public class CraftGR { private final Logger logger; private final ModConfig config; private final ExecutorService executor; - private final CloseableHttpClient httpClient; private final ClientEvents events; private final Keybinds keybinds; private final SongInfoOverlay songInfoOverlay; @@ -50,23 +48,18 @@ public CraftGR(PlatformAdapter platformAdapter) { this.logger = LogManager.getLogger(); this.config = new ModConfig(this); this.executor = Executors.newCachedThreadPool(); - this.httpClient = HttpClients.custom() - .setUserAgent("Minecraft-CraftGR/" + platformAdapter.getModVersion()) - .build(); this.events = new ClientEvents(this); this.keybinds = new Keybinds(this); this.songInfoOverlay = new SongInfoOverlay(this); this.radio = new Radio(this); + + Http.createClient(); } public PlatformAdapter getPlatformAdapter() { return platformAdapter; } - public CloseableHttpClient getHttpClient() { - return httpClient; - } - public ExecutorService getThreadExecutor() { return executor; } diff --git a/common/src/main/java/io/github/kabanfriends/craftgr/audio/AudioPlayer.java b/common/src/main/java/io/github/kabanfriends/craftgr/audio/AudioPlayer.java index 1e2e8b0..3edf53e 100644 --- a/common/src/main/java/io/github/kabanfriends/craftgr/audio/AudioPlayer.java +++ b/common/src/main/java/io/github/kabanfriends/craftgr/audio/AudioPlayer.java @@ -4,7 +4,7 @@ import io.github.kabanfriends.craftgr.util.ExceptionUtil; import io.github.kabanfriends.craftgr.util.RingBuffer; import javazoom.jl.decoder.*; -import net.minecraft.Util; +import net.minecraft.util.Util; import org.apache.logging.log4j.Level; import org.lwjgl.BufferUtils; import org.lwjgl.openal.AL10; diff --git a/common/src/main/java/io/github/kabanfriends/craftgr/audio/Radio.java b/common/src/main/java/io/github/kabanfriends/craftgr/audio/Radio.java index 9e8d0b4..f2a3a7d 100644 --- a/common/src/main/java/io/github/kabanfriends/craftgr/audio/Radio.java +++ b/common/src/main/java/io/github/kabanfriends/craftgr/audio/Radio.java @@ -3,12 +3,13 @@ import io.github.kabanfriends.craftgr.CraftGR; import io.github.kabanfriends.craftgr.config.ModConfig; import io.github.kabanfriends.craftgr.util.*; +import io.github.kabanfriends.craftgr.util.Http; import javazoom.jl.decoder.JavaLayerException; -import org.apache.http.client.methods.*; import org.apache.logging.log4j.Level; import java.io.IOException; -import java.io.InputStream; +import java.net.URI; +import java.net.http.HttpResponse; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; @@ -23,7 +24,6 @@ public class Radio { private State state; private AudioPlayer audioPlayer; - private CloseableHttpResponse response; private Future playback; private boolean hasError; @@ -44,7 +44,6 @@ public void stop(boolean awaitReload) { audioPlayer.stop(); } if (state == State.CONNECTING || state == State.PLAYING) { - disconnect(); playback.cancel(true); } @@ -114,23 +113,13 @@ private void handlePlayback(boolean fadeIn) { } private void connect() throws IOException { - if (response != null) response.close(); - - HttpGet get = HttpUtil.get(ModConfig.get("urlStream")); - CloseableHttpResponse response = craftGR.getHttpClient().execute(get); - this.response = response; - - InputStream stream = response.getEntity().getContent(); - - audioPlayer = new AudioPlayer(craftGR, stream); - } - - private void disconnect() { - try { - response.close(); - } catch (IOException e) { - craftGR.log(Level.ERROR, "Error while closing the stream response: " + ExceptionUtil.getStackTrace(e)); - } + Http.fetch(Http.standardRequest() + .uri(URI.create(ModConfig.get("urlStream"))) + .build(), HttpResponse.BodyHandlers.ofInputStream()) + .thenAccept(response -> { + this.audioPlayer = new AudioPlayer(craftGR, response.body()); + }) + .join(); } public State getState() { diff --git a/common/src/main/java/io/github/kabanfriends/craftgr/config/ModConfig.java b/common/src/main/java/io/github/kabanfriends/craftgr/config/ModConfig.java index 8b48b78..573a4d9 100644 --- a/common/src/main/java/io/github/kabanfriends/craftgr/config/ModConfig.java +++ b/common/src/main/java/io/github/kabanfriends/craftgr/config/ModConfig.java @@ -13,6 +13,7 @@ import io.github.kabanfriends.craftgr.overlay.SongInfoOverlay; import io.github.kabanfriends.craftgr.song.SongProviderType; import io.github.kabanfriends.craftgr.util.ExceptionUtil; +import io.github.kabanfriends.craftgr.util.Http; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; import org.apache.logging.log4j.Level; @@ -37,9 +38,9 @@ public class ModConfig { new ConfigGroup(Component.translatable("text.craftgr.config.category.playback"), true, new RadioStateConfigField("playback"), new IntegerConfigField("volume", 50) - .setFormatter((value) -> Component.literal(value + "%")) + .setFormatter(value -> Component.literal(value + "%")) .setRange(0, 100) - .onApply((value) -> { + .onApply(value -> { CraftGR.getInstance().getRadio().setVolume(value); }) ), @@ -50,9 +51,9 @@ public class ModConfig { new BooleanConfigField("hideAlbumArt", false), new BooleanConfigField("openAlbum", true), new IntegerConfigField("overlayWidth", 115) - .setFormatter((value) -> Component.literal(value + "px")) + .setFormatter(value -> Component.literal(value + "px")) .setRange(35, 435) - .onApply((value) -> { + .onApply(value -> { SongInfoOverlay overlay = CraftGR.getInstance().getSongInfoOverlay(); if (overlay != null) { overlay.updateScrollWidth(); @@ -64,7 +65,7 @@ public class ModConfig { ), new ConfigGroup(Component.translatable("text.craftgr.config.category.advanced"), true, new EnumConfigField("songProvider", SongProviderType.JSON_API) - .onApply((value) -> { + .onApply(value -> { CraftGR.getInstance().setSongProvider(((SongProviderType) value).createProvider()); }), new StringConfigField("urlStream", "https://stream.gensokyoradio.net/1/"), @@ -72,9 +73,10 @@ public class ModConfig { new StringConfigField("urlAlbumArt", "https://gensokyoradio.net/images/albums/500/"), new StringConfigField("urlWebSocket", "wss://gensokyoradio.net/wss"), new IntegerConfigField("connectTimeout", 20_000) - .setFormatter((value) -> Component.literal(value + "ms")), + .setFormatter(value -> Component.literal(value + "ms")) + .onApply(value -> Http.createClient()), new IntegerConfigField("socketTimeout", 10_000) - .setFormatter((value) -> Component.literal(value + "ms")) + .setFormatter(value -> Component.literal(value + "ms")) ) }; diff --git a/common/src/main/java/io/github/kabanfriends/craftgr/event/ClientEvents.java b/common/src/main/java/io/github/kabanfriends/craftgr/event/ClientEvents.java index 79094ec..7388a4c 100644 --- a/common/src/main/java/io/github/kabanfriends/craftgr/event/ClientEvents.java +++ b/common/src/main/java/io/github/kabanfriends/craftgr/event/ClientEvents.java @@ -23,12 +23,7 @@ public void onClientStart() { public void onClientStop() { craftGR.getRadio().stop(false); - - try { - craftGR.getSongProvider().stop(); - craftGR.getHttpClient().close(); - } catch (IOException ignored) { - } + craftGR.getSongProvider().stop(); } public void onClientTick() { diff --git a/common/src/main/java/io/github/kabanfriends/craftgr/gui/RadioOptionContainer.java b/common/src/main/java/io/github/kabanfriends/craftgr/gui/RadioOptionContainer.java index 2d18327..a9545e9 100644 --- a/common/src/main/java/io/github/kabanfriends/craftgr/gui/RadioOptionContainer.java +++ b/common/src/main/java/io/github/kabanfriends/craftgr/gui/RadioOptionContainer.java @@ -10,7 +10,7 @@ import net.minecraft.client.gui.narration.NarrationElementOutput; import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -24,9 +24,9 @@ public class RadioOptionContainer extends AbstractContainerWidget { private static final Component DISABLED_TOOLTIP = Component.translatable("text.craftgr.button.config.disabled"); private static final WidgetSprites CONFIG_BUTTON_SPRITES = new WidgetSprites( - ResourceLocation.fromNamespaceAndPath(CraftGR.MOD_ID, "config"), - ResourceLocation.fromNamespaceAndPath(CraftGR.MOD_ID, "config_disabled"), - ResourceLocation.fromNamespaceAndPath(CraftGR.MOD_ID, "config_highlighted") + Identifier.fromNamespaceAndPath(CraftGR.MOD_ID, "config"), + Identifier.fromNamespaceAndPath(CraftGR.MOD_ID, "config_disabled"), + Identifier.fromNamespaceAndPath(CraftGR.MOD_ID, "config_highlighted") ); private final RadioVolumeSliderButton volumeSlider; diff --git a/common/src/main/java/io/github/kabanfriends/craftgr/keybind/Keybinds.java b/common/src/main/java/io/github/kabanfriends/craftgr/keybind/Keybinds.java index c72ba7d..95de144 100644 --- a/common/src/main/java/io/github/kabanfriends/craftgr/keybind/Keybinds.java +++ b/common/src/main/java/io/github/kabanfriends/craftgr/keybind/Keybinds.java @@ -4,7 +4,7 @@ import io.github.kabanfriends.craftgr.CraftGR; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import org.lwjgl.glfw.GLFW; public class Keybinds { @@ -15,7 +15,7 @@ public class Keybinds { "key.craftgr.toggle", InputConstants.Type.KEYSYM, GLFW.GLFW_KEY_M, - KeyMapping.Category.register(ResourceLocation.fromNamespaceAndPath("craftgr", "craftgr")) + KeyMapping.Category.register(Identifier.fromNamespaceAndPath("craftgr", "craftgr")) ), () -> CraftGR.getInstance().getRadio().toggle() ) diff --git a/common/src/main/java/io/github/kabanfriends/craftgr/mixin/MixinOptionsListOptionEntry.java b/common/src/main/java/io/github/kabanfriends/craftgr/mixin/MixinOptionsListOptionEntry.java index dab2b88..3b9a90a 100644 --- a/common/src/main/java/io/github/kabanfriends/craftgr/mixin/MixinOptionsListOptionEntry.java +++ b/common/src/main/java/io/github/kabanfriends/craftgr/mixin/MixinOptionsListOptionEntry.java @@ -1,26 +1,32 @@ package io.github.kabanfriends.craftgr.mixin; -import io.github.kabanfriends.craftgr.gui.RadioOptionContainer; import io.github.kabanfriends.craftgr.util.ThreadLocals; -import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.gui.components.OptionsList; +import org.objectweb.asm.Opcodes; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyArg; +import org.spongepowered.asm.mixin.injection.Redirect; import java.util.List; -@Mixin(OptionsList.OptionEntry.class) +@Mixin(OptionsList.Entry.class) public class MixinOptionsListOptionEntry { - @ModifyArg(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/components/OptionsList$Entry;(Ljava/util/List;Lnet/minecraft/client/gui/screens/Screen;)V")) - private static List craftgr$initOptionEntry(List list) { - Boolean value = ThreadLocals.RADIO_OPTION_CONTAINER_ADDED.get(); - if (value == null || list.size() > 1 || value) { - return list; + @Shadow @Final @Mutable + List children; + + @Redirect(method = "", at = @At(value = "FIELD", target = "Lnet/minecraft/client/gui/components/OptionsList$Entry;children:Ljava/util/List;", opcode = Opcodes.PUTFIELD)) + private void craftgr$addRadioToChildren(OptionsList.Entry instance, List value) { + Boolean added = ThreadLocals.RADIO_OPTION_CONTAINER_ADDED.get(); + if (added == null || value.size() > 1 || added) { + this.children = value; + return; } ThreadLocals.RADIO_OPTION_CONTAINER_ADDED.set(true); - return List.of(list.get(0), new RadioOptionContainer(0, 0, 150)); + this.children = List.copyOf(value); } } diff --git a/common/src/main/java/io/github/kabanfriends/craftgr/overlay/SongInfoOverlay.java b/common/src/main/java/io/github/kabanfriends/craftgr/overlay/SongInfoOverlay.java index d1c9d27..d91011e 100644 --- a/common/src/main/java/io/github/kabanfriends/craftgr/overlay/SongInfoOverlay.java +++ b/common/src/main/java/io/github/kabanfriends/craftgr/overlay/SongInfoOverlay.java @@ -10,7 +10,7 @@ import io.github.kabanfriends.craftgr.song.Song; import io.github.kabanfriends.craftgr.util.*; import io.github.kabanfriends.craftgr.util.RenderUtil; -import net.minecraft.Util; +import io.github.kabanfriends.craftgr.util.Http; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; @@ -22,11 +22,10 @@ import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.resources.sounds.SimpleSoundInstance; import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import net.minecraft.sounds.SoundEvents; +import net.minecraft.util.Util; import org.apache.commons.lang3.math.NumberUtils; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; import org.apache.logging.log4j.Level; import org.joml.Matrix3x2fStack; import org.joml.Vector2i; @@ -38,6 +37,8 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.net.URI; +import java.net.http.HttpResponse; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -72,10 +73,10 @@ public class SongInfoOverlay extends Overlay { private static final int ALBUM_ART_FETCH_TRIES = 3; private static final int ALBUM_ART_FETCH_DELAY_SECONDS = 4; - private static final ResourceLocation HIGHLIGHTED_BORDER_SPRITE = ResourceLocation.fromNamespaceAndPath(CraftGR.MOD_ID, "highlighted_border"); + private static final Identifier HIGHLIGHTED_BORDER_SPRITE = Identifier.fromNamespaceAndPath(CraftGR.MOD_ID, "highlighted_border"); - private static final ResourceLocation ALBUM_ART_PLACEHOLDER_LOCATION = ResourceLocation.fromNamespaceAndPath(CraftGR.MOD_ID, "textures/album_placeholder.png"); - private static final ResourceLocation ALBUM_ART_LOCATION = ResourceLocation.fromNamespaceAndPath(CraftGR.MOD_ID, "album"); + private static final Identifier ALBUM_ART_PLACEHOLDER_LOCATION = Identifier.fromNamespaceAndPath(CraftGR.MOD_ID, "textures/album_placeholder.png"); + private static final Identifier ALBUM_ART_LOCATION = Identifier.fromNamespaceAndPath(CraftGR.MOD_ID, "album"); private final CraftGR craftGR; private final ScrollingText songTitleText; @@ -370,18 +371,24 @@ private void downloadAlbumArtTexture(int attempt) { albumArtLoaded = false; try { - HttpGet get = HttpUtil.get(song.metadata().albumArt()); - try ( - CloseableHttpResponse response = craftGR.getHttpClient().execute(get); - InputStream stream = resizeImage(response.getEntity().getContent()) - ) { - ThreadLocals.PNG_INFO_BYPASS_VALIDATION.set(true); - NativeImage image = NativeImage.read(stream); - Minecraft.getInstance().executeBlocking(() -> { - textureManager.register(ALBUM_ART_LOCATION, new DynamicTexture(null, image)); - albumArtLoaded = true; - }); - } + Http.fetch(Http.standardRequest() + .uri(URI.create(song.metadata().albumArt())) + .build(), HttpResponse.BodyHandlers.ofInputStream()) + .thenAccept(response -> { + try { + ThreadLocals.PNG_INFO_BYPASS_VALIDATION.set(true); + NativeImage image = NativeImage.read(response.body()); + Minecraft.getInstance().executeBlocking(() -> { + textureManager.register(ALBUM_ART_LOCATION, new DynamicTexture(null, image)); + albumArtLoaded = true; + }); + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + ThreadLocals.PNG_INFO_BYPASS_VALIDATION.remove(); + } + }) + .join(); } catch (Exception e) { craftGR.log(Level.ERROR, "Error while creating album art texture (" + song.metadata().albumArt() + ")" + ( attempt < ALBUM_ART_FETCH_TRIES ? ", retrying" : "") + ": " + ExceptionUtil.getStackTrace(e)); Minecraft.getInstance().executeBlocking(() -> textureManager.release(ALBUM_ART_LOCATION)); @@ -389,8 +396,6 @@ private void downloadAlbumArtTexture(int attempt) { if (attempt < ALBUM_ART_FETCH_TRIES) { scheduler.schedule(() -> downloadAlbumArtTexture(attempt + 1), ALBUM_ART_FETCH_DELAY_SECONDS, TimeUnit.SECONDS); } - } finally { - ThreadLocals.PNG_INFO_BYPASS_VALIDATION.remove(); } } diff --git a/common/src/main/java/io/github/kabanfriends/craftgr/overlay/widget/impl/ScrollingText.java b/common/src/main/java/io/github/kabanfriends/craftgr/overlay/widget/impl/ScrollingText.java index 56f3a60..99e71aa 100644 --- a/common/src/main/java/io/github/kabanfriends/craftgr/overlay/widget/impl/ScrollingText.java +++ b/common/src/main/java/io/github/kabanfriends/craftgr/overlay/widget/impl/ScrollingText.java @@ -1,26 +1,24 @@ package io.github.kabanfriends.craftgr.overlay.widget.impl; -import io.github.kabanfriends.craftgr.config.ModConfig; import io.github.kabanfriends.craftgr.overlay.widget.UIWidget; -import net.minecraft.Util; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.network.chat.Component; +import net.minecraft.util.Util; import org.joml.Matrix3x2fStack; import java.awt.*; -//Code based on: https://github.com/MC-U-Team/U-Team-Core/blob/1.19.2/src/main/java/info/u_team/u_team_core/gui/elements/ScrollingText.java public class ScrollingText extends UIWidget { - protected int width; - protected float stepSize; - protected int waitTime; + private int width; + private float stepSize; + private int waitTime; - protected float startPos = 0; - protected float moveDifference = 0; - protected long lastTime = 0; - protected State state = State.WAITING; + private float startPos = 0; + private float moveDifference = 0; + private long lastTime = 0; + private State state = State.WAITING; private Component component; diff --git a/common/src/main/java/io/github/kabanfriends/craftgr/song/JsonAPISongProvider.java b/common/src/main/java/io/github/kabanfriends/craftgr/song/JsonAPISongProvider.java index 5acf209..d00a8a0 100644 --- a/common/src/main/java/io/github/kabanfriends/craftgr/song/JsonAPISongProvider.java +++ b/common/src/main/java/io/github/kabanfriends/craftgr/song/JsonAPISongProvider.java @@ -1,16 +1,16 @@ package io.github.kabanfriends.craftgr.song; +import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import com.google.gson.JsonParser; import io.github.kabanfriends.craftgr.CraftGR; import io.github.kabanfriends.craftgr.config.ModConfig; import io.github.kabanfriends.craftgr.util.*; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; +import io.github.kabanfriends.craftgr.util.Http; import org.apache.logging.log4j.Level; import java.io.*; -import java.nio.charset.StandardCharsets; +import java.net.URI; +import java.net.http.HttpResponse; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; @@ -85,45 +85,36 @@ private void startNewSong(Song song) { } private Song getSongFromAPI() throws IOException { - HttpGet get = HttpUtil.get(ModConfig.get("urlInfoJson")); - - try ( - CloseableHttpResponse response = CraftGR.getInstance().getHttpClient().execute(get); - InputStream stream = response.getEntity().getContent(); - BufferedReader r = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8)) - ) { - StringBuilder sb = new StringBuilder(); - String line; - while ((line = r.readLine()) != null) { - sb.append(line); - } - - JsonObject json = JsonParser.parseString(sb.toString()).getAsJsonObject(); - JsonObject songInfo = json.getAsJsonObject("SONGINFO"); - JsonObject songTimes = json.getAsJsonObject("SONGTIMES"); - JsonObject songData = json.getAsJsonObject("SONGDATA"); - JsonObject misc = json.getAsJsonObject("MISC"); - - long apiDuration = JsonUtil.getValueWithDefault(songTimes, "DURATION", 3L, long.class); - long apiPlayed = JsonUtil.getValueWithDefault(songTimes, "PLAYED", 0L, long.class); - - String albumArt = JsonUtil.getValueWithDefault(misc, "ALBUMART", null, String.class); - - return new Song( - new Song.Metadata( - TitleFixer.fixJapaneseString(JsonUtil.getValueWithDefault(songInfo, "TITLE", "", String.class)), - TitleFixer.fixJapaneseString(JsonUtil.getValueWithDefault(songInfo, "ARTIST", null, String.class)), - TitleFixer.fixJapaneseString(JsonUtil.getValueWithDefault(songInfo, "ALBUM", null, String.class)), - JsonUtil.getValueWithDefault(songInfo, "YEAR", null, String.class), - TitleFixer.fixJapaneseString(JsonUtil.getValueWithDefault(songInfo, "CIRCLE", null, String.class)), - apiDuration, - JsonUtil.getValueWithDefault(songData, "ALBUMID", 0, int.class), - albumArt == null || albumArt.isEmpty() ? null : ModConfig.get("urlAlbumArt") + albumArt, - apiPlayed > apiDuration - ), - apiPlayed - ); - } + JsonElement response = Http.fetchJson(Http.standardRequest() + .uri(URI.create(ModConfig.get("urlInfoJson"))) + .build()) + .thenApply(HttpResponse::body) + .join(); + JsonObject json = response.getAsJsonObject(); + JsonObject songInfo = json.getAsJsonObject("SONGINFO"); + JsonObject songTimes = json.getAsJsonObject("SONGTIMES"); + JsonObject songData = json.getAsJsonObject("SONGDATA"); + JsonObject misc = json.getAsJsonObject("MISC"); + + long apiDuration = JsonUtil.getValueWithDefault(songTimes, "DURATION", 3L, long.class); + long apiPlayed = JsonUtil.getValueWithDefault(songTimes, "PLAYED", 0L, long.class); + + String albumArt = JsonUtil.getValueWithDefault(misc, "ALBUMART", null, String.class); + + return new Song( + new Song.Metadata( + TitleFixer.fixJapaneseString(JsonUtil.getValueWithDefault(songInfo, "TITLE", "", String.class)), + TitleFixer.fixJapaneseString(JsonUtil.getValueWithDefault(songInfo, "ARTIST", null, String.class)), + TitleFixer.fixJapaneseString(JsonUtil.getValueWithDefault(songInfo, "ALBUM", null, String.class)), + JsonUtil.getValueWithDefault(songInfo, "YEAR", null, String.class), + TitleFixer.fixJapaneseString(JsonUtil.getValueWithDefault(songInfo, "CIRCLE", null, String.class)), + apiDuration, + JsonUtil.getValueWithDefault(songData, "ALBUMID", 0, int.class), + albumArt == null || albumArt.isEmpty() ? null : ModConfig.get("urlAlbumArt") + albumArt, + apiPlayed > apiDuration + ), + apiPlayed + ); } private static void cancelIfNotNull(ScheduledFuture task) { diff --git a/common/src/main/java/io/github/kabanfriends/craftgr/song/Song.java b/common/src/main/java/io/github/kabanfriends/craftgr/song/Song.java index 51d1d93..a0970bd 100644 --- a/common/src/main/java/io/github/kabanfriends/craftgr/song/Song.java +++ b/common/src/main/java/io/github/kabanfriends/craftgr/song/Song.java @@ -1,6 +1,6 @@ package io.github.kabanfriends.craftgr.song; -import net.minecraft.Util; +import net.minecraft.util.Util; public class Song { diff --git a/common/src/main/java/io/github/kabanfriends/craftgr/song/WebSocketSongProvider.java b/common/src/main/java/io/github/kabanfriends/craftgr/song/WebSocketSongProvider.java index 40f13b6..5889353 100644 --- a/common/src/main/java/io/github/kabanfriends/craftgr/song/WebSocketSongProvider.java +++ b/common/src/main/java/io/github/kabanfriends/craftgr/song/WebSocketSongProvider.java @@ -8,119 +8,137 @@ import io.github.kabanfriends.craftgr.util.ExceptionUtil; import io.github.kabanfriends.craftgr.util.JsonUtil; import io.github.kabanfriends.craftgr.util.TitleFixer; +import io.github.kabanfriends.craftgr.util.Http; import org.apache.logging.log4j.Level; -import org.java_websocket.client.WebSocketClient; -import org.java_websocket.handshake.ServerHandshake; import java.net.URI; +import java.net.http.WebSocket; +import java.util.concurrent.CompletionStage; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -public class WebSocketSongProvider extends WebSocketClient implements SongProvider { +public class WebSocketSongProvider implements SongProvider { private static final int RETRY_INTERVAL = 10; private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + private WebSocket client; private Song currentSong; private int clientId; public WebSocketSongProvider() { - super(URI.create(ModConfig.get("urlWebSocket"))); } @Override public void start() { - connect(); - } + WebSocket.Builder builder = Http.standardWebSocket(); + WebSocket.Listener listener = new WebSocket.Listener() { + + @Override + public void onOpen(WebSocket client) { + CraftGR.getInstance().log(Level.INFO, "WebSocket client has connected"); + JsonObject json = new JsonObject(); + json.addProperty("message", "grInitialConnection"); + + // Request the starting message, and send the initial connection + client.request(1); + send(client, json); + } - @Override - public void stop() { - close(); - scheduler.shutdownNow(); - } + @Override + public CompletionStage onText(WebSocket client, CharSequence data, boolean last) { + // Request the next message + client.request(1); + + String message = data.toString(); + try { + JsonObject json = JsonParser.parseString(message).getAsJsonObject(); + + if (json.has("message")) { // Received a message + String type = json.get("message").getAsString(); + + if (type.equals("welcome")) { // Get client ID + clientId = json.get("id").getAsInt(); + CraftGR.getInstance().log(Level.INFO, "Client ID received: " + clientId); + + } else if (type.equals("ping")) { // Response to ping requests + JsonObject response = new JsonObject(); + response.addProperty("message", "pong"); + response.addProperty("id", clientId); + send(client, response); + } + + } else if (json.has("songid")) { // Received a song information + long apiDuration = JsonUtil.getValueWithDefault(json, "duration", 3L, long.class); + long apiPlayed = JsonUtil.getValueWithDefault(json, "played", 0L, long.class); + + int year = JsonUtil.getValueWithDefault(json, "year", -1, int.class); + + currentSong = new Song( + new Song.Metadata( + TitleFixer.fixJapaneseString(JsonUtil.getValueWithDefault(json, "title", "", String.class)), + TitleFixer.fixJapaneseString(JsonUtil.getValueWithDefault(json, "artist", null, String.class)), + TitleFixer.fixJapaneseString(JsonUtil.getValueWithDefault(json, "album", null, String.class)), + year == -1 ? null : String.valueOf(year), + TitleFixer.fixJapaneseString(JsonUtil.getValueWithDefault(json, "circle", null, String.class)), + apiDuration, + JsonUtil.getValueWithDefault(json, "albumid", 0, int.class), + JsonUtil.getValueWithDefault(json, "albumart", null, String.class), + apiPlayed > apiDuration + ), + apiPlayed + ); + + CraftGR.getInstance().getSongInfoOverlay().onSongChanged(); + } else { + CraftGR.getInstance().log(Level.WARN, "Received unknown WebSocket message (" + message + "): " + json.toString()); + } + } catch (JsonParseException e) { + CraftGR.getInstance().log(Level.WARN, "Received invalid WebSocket message (" + message + "): " + ExceptionUtil.getStackTrace(e)); + } catch (Exception e) { + CraftGR.getInstance().log(Level.ERROR, "Failed to process WebSocket message: " + ExceptionUtil.getStackTrace(e)); + } + return null; + } - @Override - public Song getCurrentSong() { - return currentSong; - } + @Override + public CompletionStage onClose(WebSocket webSocket, int statusCode, String reason) { + if (statusCode == WebSocket.NORMAL_CLOSURE) { + CraftGR.getInstance().log(Level.INFO, "WebSocket client has disconnected"); + } else { + CraftGR.getInstance().log(Level.INFO, "Connection closed unexpectedly, retrying connection (code: " + statusCode + ", reason: " + reason + ")"); + scheduler.schedule(WebSocketSongProvider.this::start, RETRY_INTERVAL, TimeUnit.SECONDS); + } + return null; + } - @Override - public void verifyCurrentSong() { - } + @Override + public void onError(WebSocket client, Throwable error) { + CraftGR.getInstance().log(Level.ERROR, "WebSocket error: " + ExceptionUtil.getStackTrace(error)); + } + }; - @Override - public void onOpen(ServerHandshake handshake) { - JsonObject json = new JsonObject(); - json.addProperty("message", "grInitialConnection"); - send(json); + this.client = builder.buildAsync(URI.create(ModConfig.get("urlWebSocket")), listener).join(); } @Override - public void onMessage(String message) { - try { - JsonObject json = JsonParser.parseString(message).getAsJsonObject(); - - if (json.has("message")) { // Received a message - String type = json.get("message").getAsString(); - - if (type.equals("welcome")) { // Get client ID - clientId = json.get("id").getAsInt(); - CraftGR.getInstance().log(Level.INFO, "WebSocket client is ready!"); - - } else if (type.equals("ping")) { // Response to ping requests - JsonObject response = new JsonObject(); - response.addProperty("message", "pong"); - response.addProperty("id", clientId); - send(response); - } - - } else if (json.has("songid")) { // Received a song information - long apiDuration = JsonUtil.getValueWithDefault(json, "duration", 3L, long.class); - long apiPlayed = JsonUtil.getValueWithDefault(json, "played", 0L, long.class); - - int year = JsonUtil.getValueWithDefault(json, "year", -1, int.class); - - currentSong = new Song( - new Song.Metadata( - TitleFixer.fixJapaneseString(JsonUtil.getValueWithDefault(json, "title", "", String.class)), - TitleFixer.fixJapaneseString(JsonUtil.getValueWithDefault(json, "artist", null, String.class)), - TitleFixer.fixJapaneseString(JsonUtil.getValueWithDefault(json, "album", null, String.class)), - year == -1 ? null : String.valueOf(year), - TitleFixer.fixJapaneseString(JsonUtil.getValueWithDefault(json, "circle", null, String.class)), - apiDuration, - JsonUtil.getValueWithDefault(json, "albumid", 0, int.class), - JsonUtil.getValueWithDefault(json, "albumart", null, String.class), - apiPlayed > apiDuration - ), - apiPlayed - ); - - CraftGR.getInstance().getSongInfoOverlay().onSongChanged(); - } - } catch (JsonParseException e) { - CraftGR.getInstance().log(Level.WARN, "Received invalid WebSocket message (" + message + "): " + ExceptionUtil.getStackTrace(e)); - } catch (Exception e) { - CraftGR.getInstance().log(Level.ERROR, "Failed to process WebSocket message: " + ExceptionUtil.getStackTrace(e)); - } + public void stop() { + client.sendClose(WebSocket.NORMAL_CLOSURE, "Client closing") + .thenRun(() -> CraftGR.getInstance().log(Level.INFO, "WebSocket client has disconnected")); } @Override - public void onClose(int code, String reason, boolean remote) { - CraftGR.getInstance().log(Level.INFO, "Connection closed by " + (remote ? "remote peer, retrying connection" : "us") + " (code: " + code + ", reason: " + reason + ")"); - - if (remote) { - scheduler.schedule(this::connect, RETRY_INTERVAL, TimeUnit.SECONDS); - } + public Song getCurrentSong() { + return currentSong; } @Override - public void onError(Exception e) { - CraftGR.getInstance().log(Level.ERROR, "WebSocket error: " + ExceptionUtil.getStackTrace(e)); + public void verifyCurrentSong() { } - private void send(JsonObject json) { - send(json.toString()); + private void send(WebSocket client, JsonObject json) { + client.sendText(json.toString(), true); } } diff --git a/common/src/main/java/io/github/kabanfriends/craftgr/util/Http.java b/common/src/main/java/io/github/kabanfriends/craftgr/util/Http.java new file mode 100644 index 0000000..c7209ee --- /dev/null +++ b/common/src/main/java/io/github/kabanfriends/craftgr/util/Http.java @@ -0,0 +1,58 @@ +package io.github.kabanfriends.craftgr.util; + +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import io.github.kabanfriends.craftgr.CraftGR; +import io.github.kabanfriends.craftgr.config.ModConfig; + +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.WebSocket; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.concurrent.CompletableFuture; + +public class Http { + + private static final HttpResponse.BodyHandler JSON_BODY_HANDLER = responseInfo -> HttpResponse.BodySubscribers.mapping( + HttpResponse.BodySubscribers.ofString(StandardCharsets.UTF_8), + JsonParser::parseString + ); + + private static HttpClient httpClient; + + // Private constructor to prevent instantiation + private Http() { + } + + public static void createClient() { + httpClient = HttpClient.newBuilder() + .connectTimeout(Duration.of((long) ModConfig.get("connectTimeout"), ChronoUnit.MILLIS)) + .build(); + } + + public static CompletableFuture> fetch(HttpRequest request, HttpResponse.BodyHandler responseBodyHandler) { + return httpClient.sendAsync(request, responseBodyHandler); + } + + public static CompletableFuture> fetchString(HttpRequest request) { + return fetch(request, HttpResponse.BodyHandlers.ofString()); + } + + public static CompletableFuture> fetchJson(HttpRequest request) { + return fetch(request, JSON_BODY_HANDLER); + } + + public static HttpRequest.Builder standardRequest() { + return HttpRequest.newBuilder() + .timeout(Duration.of((long) ModConfig.get("socketTimeout"), ChronoUnit.MILLIS)) + .header("User-Agent", "Minecraft-CraftGR/" + CraftGR.getInstance().getPlatformAdapter().getModVersion()); + } + + public static WebSocket.Builder standardWebSocket() { + return httpClient.newWebSocketBuilder() + .header("User-Agent", "Minecraft-CraftGR/" + CraftGR.getInstance().getPlatformAdapter().getModVersion()); + } +} diff --git a/common/src/main/java/io/github/kabanfriends/craftgr/util/HttpUtil.java b/common/src/main/java/io/github/kabanfriends/craftgr/util/HttpUtil.java deleted file mode 100644 index b001357..0000000 --- a/common/src/main/java/io/github/kabanfriends/craftgr/util/HttpUtil.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.github.kabanfriends.craftgr.util; - -import io.github.kabanfriends.craftgr.config.ModConfig; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; - -public class HttpUtil { - - public static RequestConfig createRequestConfig() { - return RequestConfig.custom() - .setConnectTimeout(ModConfig.get("connectTimeout")) - .setConnectionRequestTimeout(ModConfig.get("connectTimeout")) - .setSocketTimeout(ModConfig.get("socketTimeout")) - .build(); - } - - public static HttpGet get(String url) { - HttpGet get = new HttpGet(url); - get.setConfig(createRequestConfig()); - return get; - } -} diff --git a/common/src/main/resources/craftgr.accesswidener b/common/src/main/resources/craftgr.accesswidener index c941a17..9ca4995 100644 --- a/common/src/main/resources/craftgr.accesswidener +++ b/common/src/main/resources/craftgr.accesswidener @@ -3,5 +3,4 @@ accessWidener v2 named extendable class net/minecraft/client/gui/navigation/ScreenRectangle accessible class net/minecraft/client/gui/components/OptionsList$Entry -accessible class net/minecraft/client/gui/components/OptionsList$OptionEntry accessible class net/minecraft/client/gui/components/AbstractSelectionList$Entry \ No newline at end of file diff --git a/fabric/src/main/java/io/github/kabanfriends/craftgr/fabric/FabricEvents.java b/fabric/src/main/java/io/github/kabanfriends/craftgr/fabric/FabricEvents.java index 801ac93..b607016 100644 --- a/fabric/src/main/java/io/github/kabanfriends/craftgr/fabric/FabricEvents.java +++ b/fabric/src/main/java/io/github/kabanfriends/craftgr/fabric/FabricEvents.java @@ -9,7 +9,7 @@ import net.fabricmc.fabric.api.client.screen.v1.ScreenMouseEvents; import net.minecraft.client.Minecraft; import net.minecraft.client.MouseHandler; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; public class FabricEvents { @@ -20,7 +20,7 @@ public static void setup() { ClientTickEvents.START_CLIENT_TICK.register(client -> CraftGR.getInstance().clientEvents().onClientTick()); - HudElementRegistry.addFirst(ResourceLocation.fromNamespaceAndPath("craftgr", "overlay"), (graphics, delta) -> { + HudElementRegistry.addFirst(Identifier.fromNamespaceAndPath("craftgr", "overlay"), (graphics, delta) -> { MouseHandler mouseHandler = Minecraft.getInstance().mouseHandler; Window window = Minecraft.getInstance().getWindow(); From 0e30b9460622f76630f2fb1d10718869fd6d5184 Mon Sep 17 00:00:00 2001 From: KabanFriends Date: Wed, 10 Dec 2025 02:11:48 +0900 Subject: [PATCH 3/4] =?UTF-8?q?chore:=20=F0=9F=94=A7=20remove=20java-webso?= =?UTF-8?q?cket=20dependency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/build.gradle | 3 --- fabric/build.gradle | 4 ---- gradle.properties | 1 - neoforge/build.gradle | 4 ---- 4 files changed, 12 deletions(-) diff --git a/common/build.gradle b/common/build.gradle index 81dec37..b6d82dc 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -7,9 +7,6 @@ dependencies { compileOnly("org.apache.commons:commons-math3:${rootProject.math3_version}") compileOnly "com.github.umjammer:jlayer:${rootProject.jlayer_version}" - compileOnly("org.java-websocket:Java-WebSocket:${rootProject.java_websocket_version}") { - exclude module: "slf4j-api" - } } loom { diff --git a/fabric/build.gradle b/fabric/build.gradle index 6d06f03..f6bc343 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -27,16 +27,12 @@ dependencies { include "org.apache.commons:commons-math3:${rootProject.math3_version}" include "com.github.umjammer:jlayer:${rootProject.jlayer_version}" - include("org.java-websocket:Java-WebSocket:${rootProject.java_websocket_version}") { - exclude module: "slf4j-api" - } //modRuntimeOnly("com.terraformersmc:modmenu:${rootProject.mod_menu_version}") { transitive(false) } //modRuntimeOnly "dev.isxander:yet-another-config-lib:${rootProject.yacl_version}-fabric" runtimeOnly "org.apache.commons:commons-math3:${rootProject.math3_version}" runtimeOnly "com.github.umjammer:jlayer:${rootProject.jlayer_version}" - runtimeOnly "org.java-websocket:Java-WebSocket:${rootProject.java_websocket_version}" } processResources { diff --git a/gradle.properties b/gradle.properties index 3e8654b..7b4ecd0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,7 +18,6 @@ neoforge_version = 21.11.0-alpha.1.21.11-rc3.20251208.212437 # Library Dependencies jlayer_version = 1.0.3 -java_websocket_version = 1.5.6 math3_version = 3.6.1 # Mod Dependencies diff --git a/neoforge/build.gradle b/neoforge/build.gradle index 954b7d4..3d63063 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -23,9 +23,6 @@ dependencies { include "org.apache.commons:commons-math3:${rootProject.math3_version}" include "com.github.umjammer:jlayer:${rootProject.jlayer_version}" - include("org.java-websocket:Java-WebSocket:${rootProject.java_websocket_version}") { - exclude module: "slf4j-api" - } // TODO: reenable /* @@ -36,7 +33,6 @@ dependencies { runtimeOnly "org.apache.commons:commons-math3:${rootProject.math3_version}" runtimeOnly "com.github.umjammer:jlayer:${rootProject.jlayer_version}" - runtimeOnly "org.java-websocket:Java-WebSocket:${rootProject.java_websocket_version}" runtimeOnly "org.quiltmc.parsers:gson:0.2.1" } From 5296bd80aa6fe9a0fe94d47c7fa8cb2be55947c4 Mon Sep 17 00:00:00 2001 From: KabanFriends Date: Wed, 10 Dec 2025 02:17:16 +0900 Subject: [PATCH 4/4] =?UTF-8?q?chore:=20=F0=9F=94=A7=20update=20mod=20meta?= =?UTF-8?q?data?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fabric/src/main/resources/fabric.mod.json | 6 +++--- neoforge/src/main/resources/META-INF/neoforge.mods.toml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index af3766c..4cdd95b 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -30,7 +30,7 @@ ], "accessWidener": "craftgr.accesswidener", "depends": { - "minecraft": ">=1.21.9-", + "minecraft": ">=1.21.11-", "fabricloader": "*", "fabric-key-binding-api-v1": "*", "fabric-lifecycle-events-v1": "*", @@ -38,10 +38,10 @@ "fabric-screen-api-v1": "*" }, "recommends": { - "yet_another_config_lib_v3": ">=3.8.0" + "yet_another_config_lib_v3": ">=3.8.1" }, "suggests": { - "modmenu": ">=15.0.0-" + "modmenu": ">=17.0.0-" }, "custom": { "modmenu:clientsideOnly": true diff --git a/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/neoforge/src/main/resources/META-INF/neoforge.mods.toml index 842eea3..1d1ee54 100644 --- a/neoforge/src/main/resources/META-INF/neoforge.mods.toml +++ b/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -21,20 +21,20 @@ file = "META-INF/accesstransformer.cfg" [[dependencies.craftgr]] modId = "minecraft" type = "required" -versionRange = "[1.21.9-,)" +versionRange = "[1.21.11-,)" ordering = "NONE" side = "CLIENT" [[dependencies.craftgr]] modId = "neoforge" type = "required" -versionRange = "[21.9.0-beta,)" +versionRange = "[21.11.0-beta,)" ordering = "NONE" side = "CLIENT" [[dependencies.craftgr]] modId = "yet_another_config_lib_v3" type = "optional" -versionRange="[3.8.0,)" +versionRange="[3.8.1,)" ordering = "NONE" side = "CLIENT"