From 1c0c8e0d08e80503bd09c9188fdf8425124f6643 Mon Sep 17 00:00:00 2001 From: Caitlyn <1423429+CaitlynMainer@users.noreply.github.com> Date: Thu, 16 Jul 2026 09:54:47 -0700 Subject: [PATCH 1/3] Mostly working 1.21.1 port with AAC support --- build.gradle | 95 +++++++++++-------- gradle.properties | 10 +- gradle/wrapper/gradle-wrapper.properties | 2 +- settings.gradle | 2 +- src/main/java/me/michiyo/openfm/OpenFM.java | 25 ++--- .../openfm/client/ClientForgeEvents.java | 13 ++- .../openfm/client/ClientModEvents.java | 18 ++-- .../michiyo/openfm/client/OpenFMClient.java | 12 +-- .../openfm/client/audio/AacDecoder.java | 74 +++++++++++++++ .../openfm/client/audio/DecoderFactory.java | 14 ++- .../client/audio/RadioStreamPlayer.java | 15 ++- .../screen/OpenFMAudioSettingsScreen.java | 12 +-- .../openfm/client/screen/RadioScreen.java | 10 +- .../openfm/compat/cc/ComputerCraftCompat.java | 63 ++---------- .../openfm/config/OpenFMClientConfig.java | 8 +- .../openfm/events/CreativeTabEvents.java | 22 ----- .../michiyo/openfm/net/C2SButtonAction.java | 50 ++++++---- .../me/michiyo/openfm/net/C2SLinkSpeaker.java | 35 ++++--- .../me/michiyo/openfm/net/C2SSetFields.java | 34 ++++--- .../michiyo/openfm/net/MemoryCardLogic.java | 20 ++-- src/main/java/me/michiyo/openfm/net/Net.java | 52 +++------- .../me/michiyo/openfm/net/S2CSyncFields.java | 37 +++++--- .../michiyo/openfm/reg/ModBlockEntities.java | 12 +-- .../java/me/michiyo/openfm/reg/ModBlocks.java | 11 +-- .../michiyo/openfm/reg/ModCreativeTabs.java | 7 +- .../java/me/michiyo/openfm/reg/ModItems.java | 15 ++- .../java/me/michiyo/openfm/reg/ModMenus.java | 14 +-- .../openfm/world/be/RadioBlockEntity.java | 27 +++--- .../openfm/world/be/SpeakerBlockEntity.java | 31 +++--- .../openfm/world/block/RadioBlock.java | 13 ++- .../openfm/world/block/SpeakerBlock.java | 7 ++ .../openfm/world/item/OpenFMTunerItem.java | 26 ++--- src/main/resources/META-INF/mods.toml | 24 ----- .../resources/META-INF/neoforge.mods.toml | 31 ++++++ .../resources/assets/openfm/lang/en_us.json | 3 +- .../openfm/models/item/memory_card.json | 6 ++ .../assets/openfm/models/item/tuner.json | 6 ++ src/main/resources/pack.mcmeta | 2 +- 38 files changed, 467 insertions(+), 391 deletions(-) create mode 100644 src/main/java/me/michiyo/openfm/client/audio/AacDecoder.java delete mode 100644 src/main/java/me/michiyo/openfm/events/CreativeTabEvents.java delete mode 100644 src/main/resources/META-INF/mods.toml create mode 100644 src/main/resources/META-INF/neoforge.mods.toml create mode 100644 src/main/resources/assets/openfm/models/item/memory_card.json create mode 100644 src/main/resources/assets/openfm/models/item/tuner.json diff --git a/build.gradle b/build.gradle index ec6d80a..ff14282 100644 --- a/build.gradle +++ b/build.gradle @@ -1,41 +1,42 @@ plugins { - id 'eclipse' + id 'java-library' + id 'idea' id 'maven-publish' - id 'net.minecraftforge.gradle' version '6.0.+' + id 'net.neoforged.gradle.userdev' version '7.1.36' } -group = project.mod_group +group = project.mod_group_id version = project.mod_version -archivesBaseName = project.mod_id -java.toolchain.languageVersion = JavaLanguageVersion.of(17) +base { + archivesName = project.mod_id +} -minecraft { - mappings channel: 'official', version: project.minecraft_version +java.toolchain.languageVersion = JavaLanguageVersion.of(21) - runs { - client { - workingDirectory project.file('run') - property 'forge.logging.console.level', 'debug' - mods { - "${project.mod_id}" { - source sourceSets.main - } - } +runs { + configureEach { + systemProperty 'forge.logging.console.level', 'debug' + workingDirectory project.layout.projectDirectory.dir('run').dir(name) + modSource project.sourceSets.main + dependencies { + runtime "javazoom:jlayer:1.0.1" + runtime "org.jcraft:jorbis:0.0.17" + runtime "com.tianscar.javasound:jaad:0.9.4" } + } - server { - workingDirectory project.file('run') - property 'forge.logging.console.level', 'debug' - mods { - "${project.mod_id}" { - source sourceSets.main - } - } - } + client {} + + server { + argument '--nogui' } } +configurations { + runtimeClasspath.extendsFrom localRuntime +} + repositories { mavenCentral() @@ -47,21 +48,41 @@ repositories { } dependencies { - minecraft "net.minecraftforge:forge:${project.minecraft_version}-${project.forge_version}" + implementation "net.neoforged:neoforge:${project.neo_version}" - // Compile-time - implementation "javazoom:jlayer:1.0.1" - implementation "org.jcraft:jorbis:0.0.17" + // Compile against and embed the stream decoder libraries in the distributable mod jar. + jarJar(implementation("javazoom:jlayer:[1.0.1]")) { + version { prefer "1.0.1" } + } + jarJar(implementation("org.jcraft:jorbis:[0.0.17]")) { + version { prefer "0.0.17" } + } + jarJar(implementation("com.tianscar.javasound:jaad:[0.9.4]")) { + version { prefer "0.9.4" } + } - // ComputerCraft (CC:Tweaked) - ForgeGradle deobf deps - // API at compile-time, full mod at runtime for dev runs. - compileOnly "cc.tweaked:cc-tweaked-1.20.1-core-api:1.117.0" - compileOnly fg.deobf("cc.tweaked:cc-tweaked-1.20.1-forge-api:1.117.0") - runtimeOnly fg.deobf("cc.tweaked:cc-tweaked-1.20.1-forge:1.117.0") + // CC:Tweaked still publishes its 1.21.1 NeoForge-compatible build under the forge classifier. + compileOnly "cc.tweaked:cc-tweaked-${project.minecraft_version}-core-api:${project.cc_tweaked_version}" + compileOnly "cc.tweaked:cc-tweaked-${project.minecraft_version}-forge-api:${project.cc_tweaked_version}" + localRuntime "cc.tweaked:cc-tweaked-${project.minecraft_version}-forge:${project.cc_tweaked_version}" - // DEV runtime: put libs on the game/launch classpath so the mod classloader can see them - minecraftLibrary "javazoom:jlayer:1.0.1" - minecraftLibrary "org.jcraft:jorbis:0.0.17" +} + +tasks.withType(ProcessResources).configureEach { + def replaceProperties = [ + minecraft_version_range: minecraft_version_range, + neo_version: neo_version, + loader_version_range: loader_version_range, + mod_id: mod_id, + mod_name: mod_name, + mod_license: mod_license, + mod_version: mod_version, + cc_tweaked_version: cc_tweaked_version + ] + inputs.properties replaceProperties + filesMatching('META-INF/neoforge.mods.toml') { + expand replaceProperties + } } tasks.withType(JavaCompile).configureEach { diff --git a/gradle.properties b/gradle.properties index 1edb7f3..21a5c62 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,9 +1,13 @@ org.gradle.jvmargs=-Xmx3G org.gradle.daemon=false -minecraft_version=1.20.1 -forge_version=47.3.0 +minecraft_version=1.21.1 +minecraft_version_range=[1.21.1] +neo_version=21.1.235 +loader_version_range=[4,) mod_id=openfm mod_name=OpenFM +mod_license=MIT mod_version=0.0.1 -mod_group=me.michiyo +mod_group_id=me.michiyo +cc_tweaked_version=1.113.1 mod_authors=Caitlyn diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2617362..aa02b02 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/settings.gradle b/settings.gradle index 5e9f853..996438a 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,7 +1,7 @@ pluginManagement { repositories { gradlePluginPortal() - maven { url = 'https://maven.minecraftforge.net' } + maven { url = 'https://maven.neoforged.net/releases' } mavenCentral() } } diff --git a/src/main/java/me/michiyo/openfm/OpenFM.java b/src/main/java/me/michiyo/openfm/OpenFM.java index 79b71db..b7742f2 100644 --- a/src/main/java/me/michiyo/openfm/OpenFM.java +++ b/src/main/java/me/michiyo/openfm/OpenFM.java @@ -8,36 +8,29 @@ import me.michiyo.openfm.reg.ModMenus; import me.michiyo.openfm.reg.ModCreativeTabs; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.fml.ModLoadingContext; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.config.ModConfig; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.fml.ModContainer; +import net.neoforged.fml.common.Mod; +import net.neoforged.fml.ModList; +import net.neoforged.fml.config.ModConfig; @Mod(OpenFM.MODID) public class OpenFM { public static final String MODID = "openfm"; - public OpenFM() { - IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus(); - + public OpenFM(IEventBus bus, ModContainer modContainer) { ModBlocks.REG.register(bus); ModItems.REG.register(bus); ModBlockEntities.REG.register(bus); ModMenus.REG.register(bus); ModCreativeTabs.REG.register(bus); - ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, OpenFMClientConfig.SPEC); + modContainer.registerConfig(ModConfig.Type.CLIENT, OpenFMClientConfig.SPEC); - Net.register(); + bus.addListener(Net::register); if (ModList.get().isLoaded("computercraft")) { - MinecraftForge.EVENT_BUS.addGenericListener(BlockEntity.class, - me.michiyo.openfm.compat.cc.ComputerCraftCompat::attachPeripherals - ); + bus.addListener(me.michiyo.openfm.compat.cc.ComputerCraftCompat::registerCapabilities); } } } diff --git a/src/main/java/me/michiyo/openfm/client/ClientForgeEvents.java b/src/main/java/me/michiyo/openfm/client/ClientForgeEvents.java index f179176..facbd32 100644 --- a/src/main/java/me/michiyo/openfm/client/ClientForgeEvents.java +++ b/src/main/java/me/michiyo/openfm/client/ClientForgeEvents.java @@ -2,17 +2,16 @@ import me.michiyo.openfm.OpenFM; import me.michiyo.openfm.client.audio.RadioStreamManager; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.event.TickEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.neoforge.client.event.ClientTickEvent; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; -@Mod.EventBusSubscriber(modid = OpenFM.MODID, value = Dist.CLIENT) // FORGE bus (default) +@EventBusSubscriber(modid = OpenFM.MODID, value = Dist.CLIENT) public final class ClientForgeEvents { @SubscribeEvent - public static void onClientTick(TickEvent.ClientTickEvent e) { - if (e.phase != TickEvent.Phase.END) return; + public static void onClientTick(ClientTickEvent.Post e) { RadioStreamManager.clientTick(); } diff --git a/src/main/java/me/michiyo/openfm/client/ClientModEvents.java b/src/main/java/me/michiyo/openfm/client/ClientModEvents.java index 886cc6e..e344fbf 100644 --- a/src/main/java/me/michiyo/openfm/client/ClientModEvents.java +++ b/src/main/java/me/michiyo/openfm/client/ClientModEvents.java @@ -6,25 +6,27 @@ import me.michiyo.openfm.reg.ModMenus; import me.michiyo.openfm.client.render.RadioBlockEntityRenderer; import net.minecraft.client.renderer.blockentity.BlockEntityRenderers; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; -import net.minecraft.client.gui.screens.MenuScreens; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; -@Mod.EventBusSubscriber(modid = OpenFM.MODID, bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) +@EventBusSubscriber(modid = OpenFM.MODID, bus = EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) public final class ClientModEvents { @SubscribeEvent public static void onClientSetup(FMLClientSetupEvent e) { e.enqueueWork(() -> { - MenuScreens.register(ModMenus.RADIO_MENU.get(), RadioScreen::new); - // Block Entity Renderer (screen text) BlockEntityRenderers.register(ModBlockEntities.RADIO_BE.get(), RadioBlockEntityRenderer::new); }); } + @SubscribeEvent + public static void registerScreens(RegisterMenuScreensEvent event) { + event.register(ModMenus.RADIO_MENU.get(), RadioScreen::new); + } private ClientModEvents() {} } diff --git a/src/main/java/me/michiyo/openfm/client/OpenFMClient.java b/src/main/java/me/michiyo/openfm/client/OpenFMClient.java index 579eab6..931606c 100644 --- a/src/main/java/me/michiyo/openfm/client/OpenFMClient.java +++ b/src/main/java/me/michiyo/openfm/client/OpenFMClient.java @@ -4,14 +4,14 @@ import me.michiyo.openfm.client.screen.OpenFMAudioSettingsScreen; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.Button; -import net.minecraft.client.gui.screens.OptionsScreen; +import net.minecraft.client.gui.screens.options.OptionsScreen; import net.minecraft.network.chat.Component; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.client.event.ScreenEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.neoforge.client.event.ScreenEvent; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; -@Mod.EventBusSubscriber(modid = OpenFM.MODID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.FORGE) +@EventBusSubscriber(modid = OpenFM.MODID, value = Dist.CLIENT) public final class OpenFMClient { @SubscribeEvent diff --git a/src/main/java/me/michiyo/openfm/client/audio/AacDecoder.java b/src/main/java/me/michiyo/openfm/client/audio/AacDecoder.java new file mode 100644 index 0000000..b987a95 --- /dev/null +++ b/src/main/java/me/michiyo/openfm/client/audio/AacDecoder.java @@ -0,0 +1,74 @@ +package me.michiyo.openfm.client.audio; + +import net.sourceforge.jaad.SampleBuffer; +import net.sourceforge.jaad.aac.Decoder; +import net.sourceforge.jaad.adts.ADTSDemultiplexer; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; + +public final class AacDecoder implements PcmDecoder { + private final InputStream in; + private final ADTSDemultiplexer demultiplexer; + private final Decoder decoder; + private final SampleBuffer sampleBuffer = new SampleBuffer(); + + private int sampleRate; + private int channels; + private byte[] pending = new byte[0]; + private int pendingOffset; + + public AacDecoder(InputStream in) throws IOException { + this.in = in; + this.demultiplexer = new ADTSDemultiplexer(in); + this.decoder = Decoder.create(demultiplexer.getDecoderInfo()); + this.sampleBuffer.setBigEndian(false); + this.sampleRate = demultiplexer.getSampleFrequency(); + this.channels = demultiplexer.getChannelCount(); + } + + @Override + public byte[] readPcmChunk(int requestedBytes) throws Exception { + byte[] out = new byte[requestedBytes]; + int written = 0; + + while (written < requestedBytes) { + if (pendingOffset < pending.length) { + int count = Math.min(pending.length - pendingOffset, requestedBytes - written); + System.arraycopy(pending, pendingOffset, out, written, count); + pendingOffset += count; + written += count; + continue; + } + + byte[] frame = demultiplexer.readNextFrame(); + if (frame == null) { + return written == 0 ? null : Arrays.copyOf(out, written); + } + + decoder.decodeFrame(frame, sampleBuffer); + sampleRate = sampleBuffer.getSampleRate(); + channels = sampleBuffer.getChannels(); + pending = sampleBuffer.getData(); + pendingOffset = 0; + } + + return out; + } + + @Override + public int getSampleRate() { + return sampleRate; + } + + @Override + public int getChannels() { + return channels; + } + + @Override + public void close() { + try { in.close(); } catch (IOException ignored) {} + } +} diff --git a/src/main/java/me/michiyo/openfm/client/audio/DecoderFactory.java b/src/main/java/me/michiyo/openfm/client/audio/DecoderFactory.java index 588ee05..8b46577 100644 --- a/src/main/java/me/michiyo/openfm/client/audio/DecoderFactory.java +++ b/src/main/java/me/michiyo/openfm/client/audio/DecoderFactory.java @@ -3,6 +3,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.PushbackInputStream; +import java.util.Locale; public final class DecoderFactory { private DecoderFactory() {} @@ -17,7 +18,7 @@ public DecoderWithStream(PcmDecoder decoder, InputStream stream) { } } - public static DecoderWithStream create(InputStream raw) throws Exception { + public static DecoderWithStream create(InputStream raw, String contentType) throws Exception { PushbackInputStream in = new PushbackInputStream(raw, 64); byte[] head = readSome(in, 64); @@ -30,6 +31,11 @@ public static DecoderWithStream create(InputStream raw) throws Exception { return new DecoderWithStream(new OggVorbisDecoder(in), in); } + String normalizedType = contentType == null ? "" : contentType.toLowerCase(Locale.ROOT); + if (normalizedType.contains("aac") || isAdts(head)) { + return new DecoderWithStream(new AacDecoder(in), in); + } + // MP3 often starts with ID3 tag if (startsWith(head, new byte[]{'I','D','3'})) { return new DecoderWithStream(new Mp3Decoder(in), in); @@ -48,6 +54,12 @@ public static DecoderWithStream create(InputStream raw) throws Exception { return new DecoderWithStream(new Mp3Decoder(in), in); } + private static boolean isAdts(byte[] head) { + return head.length >= 2 + && (head[0] & 0xFF) == 0xFF + && (head[1] & 0xF6) == 0xF0; + } + private static boolean startsWith(byte[] a, byte[] prefix) { if (a.length < prefix.length) return false; for (int i = 0; i < prefix.length; i++) { diff --git a/src/main/java/me/michiyo/openfm/client/audio/RadioStreamPlayer.java b/src/main/java/me/michiyo/openfm/client/audio/RadioStreamPlayer.java index ab8fa53..06a94cc 100644 --- a/src/main/java/me/michiyo/openfm/client/audio/RadioStreamPlayer.java +++ b/src/main/java/me/michiyo/openfm/client/audio/RadioStreamPlayer.java @@ -370,6 +370,8 @@ private void startDecoderThread() { if (resp.statusCode() < 200 || resp.statusCode() >= 300) return; int metaInt = parseIcyMetaInt(resp.headers().firstValue("icy-metaint")); + String contentType = resp.headers().firstValue("content-type").orElse(""); + log("Content-Type=" + contentType); try (InputStream raw = resp.body(); BufferedInputStream bin0 = new BufferedInputStream(raw, 64 * 1024)) { @@ -399,7 +401,7 @@ private void startDecoderThread() { audioIn = new BufferedInputStream(audioIn, 64 * 1024); } - DecoderFactory.DecoderWithStream created = DecoderFactory.create(audioIn); + DecoderFactory.DecoderWithStream created = DecoderFactory.create(audioIn, contentType); decoder = created.decoder; log("Decoder=" + decoder.getClass().getSimpleName()); @@ -452,12 +454,19 @@ private void startDecoderThread() { Thread.currentThread().interrupt(); } } catch (Throwable t) { - log("Decoder thread exception: " + t); - t.printStackTrace(); + if (stopped.get() || !running.get()) { + Thread.currentThread().interrupt(); + } else { + log("Decoder thread exception: " + t); + t.printStackTrace(); + } } finally { if (decoder != null) { try { decoder.close(); } catch (Throwable ignored) {} } + if (!stopped.get()) { + stopInternal(); + } } }, "OpenFM-Decode-" + url.hashCode()); diff --git a/src/main/java/me/michiyo/openfm/client/screen/OpenFMAudioSettingsScreen.java b/src/main/java/me/michiyo/openfm/client/screen/OpenFMAudioSettingsScreen.java index 0c47e37..4beb12e 100644 --- a/src/main/java/me/michiyo/openfm/client/screen/OpenFMAudioSettingsScreen.java +++ b/src/main/java/me/michiyo/openfm/client/screen/OpenFMAudioSettingsScreen.java @@ -5,15 +5,12 @@ import net.minecraft.client.OptionInstance; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; -import net.minecraft.client.gui.components.OptionsList; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; public class OpenFMAudioSettingsScreen extends Screen { private final Screen parent; - private OptionsList list; - // Updates continuously while dragging; written to config on mouse release / Done. private double pendingRadioVolume; @@ -42,9 +39,9 @@ public OpenFMAudioSettingsScreen(Screen parent) { @Override protected void init() { - this.list = new OptionsList(this.minecraft, this.width, this.height, 32, this.height - 32, 25); - this.list.addBig(this.radioVolumeOption); - this.addWidget(this.list); + this.addRenderableWidget(this.radioVolumeOption.createButton( + this.minecraft.options, this.width / 2 - 155, 40, 310 + )); this.addRenderableWidget(Button.builder(Component.literal("Done"), b -> onClose()) .bounds(this.width / 2 - 100, this.height - 27, 200, 20) @@ -90,9 +87,8 @@ public void onClose() { @Override public void render(GuiGraphics g, int mouseX, int mouseY, float partialTick) { - this.renderBackground(g); + this.renderBackground(g, mouseX, mouseY, partialTick); g.drawCenteredString(this.font, this.title, this.width / 2, 12, 0xFFFFFF); - this.list.render(g, mouseX, mouseY, partialTick); super.render(g, mouseX, mouseY, partialTick); } } diff --git a/src/main/java/me/michiyo/openfm/client/screen/RadioScreen.java b/src/main/java/me/michiyo/openfm/client/screen/RadioScreen.java index 0988e91..75bc48e 100644 --- a/src/main/java/me/michiyo/openfm/client/screen/RadioScreen.java +++ b/src/main/java/me/michiyo/openfm/client/screen/RadioScreen.java @@ -16,8 +16,8 @@ import net.minecraft.resources.ResourceLocation; public class RadioScreen extends AbstractContainerScreen { - private static final ResourceLocation GUI_TEX = new ResourceLocation("openfm", "textures/gui/gui_radio.png"); - private static final ResourceLocation BTN_TEX = new ResourceLocation("openfm", "textures/gui/buttons.png"); + private static final ResourceLocation GUI_TEX = ResourceLocation.fromNamespaceAndPath("openfm", "textures/gui/gui_radio.png"); + private static final ResourceLocation BTN_TEX = ResourceLocation.fromNamespaceAndPath("openfm", "textures/gui/buttons.png"); private static final int TEX_W = 256; private static final int TEX_H = 256; @@ -265,11 +265,11 @@ private void refreshLockSprite() { } private void sendButton(C2SButtonAction.Action action) { - Net.CH.sendToServer(new C2SButtonAction(menu.pos, action)); + Net.sendToServer(new C2SButtonAction(menu.pos, action)); } private void sendFieldsToServer() { - Net.CH.sendToServer(new C2SSetFields(menu.pos, urlBox.getValue(), colorBox.getValue(), textBox.getValue())); + Net.sendToServer(new C2SSetFields(menu.pos, urlBox.getValue(), colorBox.getValue(), textBox.getValue())); } public void applyServerSync(S2CSyncFields pkt) { @@ -342,7 +342,7 @@ protected void renderBg(GuiGraphics g, float partialTick, int mouseX, int mouseY @Override public void render(GuiGraphics g, int mouseX, int mouseY, float partialTick) { - this.renderBackground(g); + this.renderBackground(g, mouseX, mouseY, partialTick); super.render(g, mouseX, mouseY, partialTick); if (debugGui) { diff --git a/src/main/java/me/michiyo/openfm/compat/cc/ComputerCraftCompat.java b/src/main/java/me/michiyo/openfm/compat/cc/ComputerCraftCompat.java index 5b24dbb..5503622 100644 --- a/src/main/java/me/michiyo/openfm/compat/cc/ComputerCraftCompat.java +++ b/src/main/java/me/michiyo/openfm/compat/cc/ComputerCraftCompat.java @@ -1,62 +1,17 @@ package me.michiyo.openfm.compat.cc; -import dan200.computercraft.api.peripheral.IPeripheral; -import me.michiyo.openfm.OpenFM; -import me.michiyo.openfm.world.be.RadioBlockEntity; -import net.minecraft.core.Direction; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.common.capabilities.CapabilityManager; -import net.minecraftforge.common.capabilities.CapabilityToken; -import net.minecraftforge.common.capabilities.ICapabilityProvider; -import net.minecraftforge.common.util.LazyOptional; -import net.minecraftforge.common.util.NonNullSupplier; -import net.minecraftforge.event.AttachCapabilitiesEvent; - -import javax.annotation.Nullable; +import dan200.computercraft.api.peripheral.PeripheralCapability; +import me.michiyo.openfm.reg.ModBlockEntities; +import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent; public final class ComputerCraftCompat { private ComputerCraftCompat() {} - public static final Capability CAPABILITY_PERIPHERAL = - CapabilityManager.get(new CapabilityToken<>() {}); - - private static final ResourceLocation KEY = - new ResourceLocation(OpenFM.MODID, "computercraft_peripheral"); - - public static void attachPeripherals(AttachCapabilitiesEvent event) { - BlockEntity be = event.getObject(); - if (!(be instanceof RadioBlockEntity radio)) return; - - PeripheralProvider provider = new PeripheralProvider(() -> new OpenFMRadioPeripheral(radio)); - event.addCapability(KEY, provider); - event.addListener(provider::invalidate); - } - - private static final class PeripheralProvider implements ICapabilityProvider { - private final NonNullSupplier factory; - private @Nullable LazyOptional cached; - - private PeripheralProvider(NonNullSupplier factory) { - this.factory = factory; - } - - private void invalidate() { - if (cached != null) cached.invalidate(); - cached = null; - } - - @Override - public LazyOptional getCapability(Capability capability, @Nullable Direction side) { - if (capability != CAPABILITY_PERIPHERAL) return LazyOptional.empty(); - - LazyOptional cur = cached; - if (cur == null) { - cur = LazyOptional.of(factory); - cached = cur; - } - return cur.cast(); - } + public static void registerCapabilities(RegisterCapabilitiesEvent event) { + event.registerBlockEntity( + PeripheralCapability.get(), + ModBlockEntities.RADIO_BE.get(), + (radio, side) -> new OpenFMRadioPeripheral(radio) + ); } } diff --git a/src/main/java/me/michiyo/openfm/config/OpenFMClientConfig.java b/src/main/java/me/michiyo/openfm/config/OpenFMClientConfig.java index 211c19e..0d6600e 100644 --- a/src/main/java/me/michiyo/openfm/config/OpenFMClientConfig.java +++ b/src/main/java/me/michiyo/openfm/config/OpenFMClientConfig.java @@ -1,14 +1,14 @@ package me.michiyo.openfm.config; -import net.minecraftforge.common.ForgeConfigSpec; +import net.neoforged.neoforge.common.ModConfigSpec; public final class OpenFMClientConfig { - public static final ForgeConfigSpec SPEC; + public static final ModConfigSpec SPEC; - public static final ForgeConfigSpec.DoubleValue RADIO_VOLUME; // 0.0..1.0 + public static final ModConfigSpec.DoubleValue RADIO_VOLUME; // 0.0..1.0 static { - ForgeConfigSpec.Builder b = new ForgeConfigSpec.Builder(); + ModConfigSpec.Builder b = new ModConfigSpec.Builder(); b.push("audio"); diff --git a/src/main/java/me/michiyo/openfm/events/CreativeTabEvents.java b/src/main/java/me/michiyo/openfm/events/CreativeTabEvents.java deleted file mode 100644 index 029c943..0000000 --- a/src/main/java/me/michiyo/openfm/events/CreativeTabEvents.java +++ /dev/null @@ -1,22 +0,0 @@ -package me.michiyo.openfm.events; - -import me.michiyo.openfm.OpenFM; -import me.michiyo.openfm.reg.ModCreativeTabs; -import me.michiyo.openfm.reg.ModItems; -import net.minecraftforge.event.BuildCreativeModeTabContentsEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; - -@Mod.EventBusSubscriber(modid = OpenFM.MODID, bus = Mod.EventBusSubscriber.Bus.MOD) -public final class CreativeTabEvents { - - @SubscribeEvent - public static void onBuildTabContents(BuildCreativeModeTabContentsEvent e) { - if (e.getTab() == ModCreativeTabs.OPENFM_TAB.get()) { - e.accept(ModItems.RADIO_BLOCK_ITEM.get()); - e.accept(ModItems.MEMORY_CARD.get()); - } - } - - private CreativeTabEvents() {} -} diff --git a/src/main/java/me/michiyo/openfm/net/C2SButtonAction.java b/src/main/java/me/michiyo/openfm/net/C2SButtonAction.java index 538ed83..f520835 100644 --- a/src/main/java/me/michiyo/openfm/net/C2SButtonAction.java +++ b/src/main/java/me/michiyo/openfm/net/C2SButtonAction.java @@ -1,14 +1,22 @@ package me.michiyo.openfm.net; +import me.michiyo.openfm.OpenFM; import me.michiyo.openfm.world.be.RadioBlockEntity; import net.minecraft.core.BlockPos; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; -import net.minecraftforge.network.NetworkEvent; - -import java.util.function.Supplier; - -public class C2SButtonAction { +import net.neoforged.neoforge.network.handling.IPayloadContext; + +public class C2SButtonAction implements CustomPacketPayload { + public static final Type TYPE = new Type<>( + ResourceLocation.fromNamespaceAndPath(OpenFM.MODID, "button_action") + ); + public static final StreamCodec STREAM_CODEC = + StreamCodec.of((buf, msg) -> encode(msg, buf), C2SButtonAction::decode); public enum Action { VOL_DOWN, VOL_UP, TOGGLE_LOCK, @@ -40,15 +48,12 @@ public static C2SButtonAction decode(FriendlyByteBuf buf) { return new C2SButtonAction(pos, vals[ord]); } - public static void handle(C2SButtonAction msg, Supplier ctxSup) { - NetworkEvent.Context ctx = ctxSup.get(); - ctx.enqueueWork(() -> { - ServerPlayer player = ctx.getSender(); - if (player == null) return; + public static void handle(C2SButtonAction msg, IPayloadContext ctx) { + if (!(ctx.player() instanceof ServerPlayer player)) return; - var level = player.serverLevel(); - var be = level.getBlockEntity(msg.pos); - if (!(be instanceof RadioBlockEntity radio)) return; + var level = player.serverLevel(); + var be = level.getBlockEntity(msg.pos); + if (!(be instanceof RadioBlockEntity radio)) return; boolean hasOwner = radio.getOwnerUuid() != null; boolean isOwner = hasOwner && radio.getOwnerUuid().equals(player.getUUID()); @@ -65,13 +70,13 @@ public static void handle(C2SButtonAction msg, Supplier ct radio.setChanged(); S2CSyncFields.syncToTracking(level, msg.pos, radio); - return; - } + return; + } // For all other actions, enforce lock if (radio.isLocked() && hasOwner && !isOwner) { - return; - } + return; + } // If unowned, first editor becomes owner radio.ensureOwner(player.getUUID()); @@ -103,9 +108,12 @@ public static void handle(C2SButtonAction msg, Supplier ct default -> {} } - radio.setChanged(); - S2CSyncFields.syncToTracking(level, msg.pos, radio); - }); - ctx.setPacketHandled(true); + radio.setChanged(); + S2CSyncFields.syncToTracking(level, msg.pos, radio); + } + + @Override + public Type type() { + return TYPE; } } diff --git a/src/main/java/me/michiyo/openfm/net/C2SLinkSpeaker.java b/src/main/java/me/michiyo/openfm/net/C2SLinkSpeaker.java index f521c40..74cab1f 100644 --- a/src/main/java/me/michiyo/openfm/net/C2SLinkSpeaker.java +++ b/src/main/java/me/michiyo/openfm/net/C2SLinkSpeaker.java @@ -1,20 +1,28 @@ package me.michiyo.openfm.net; +import me.michiyo.openfm.OpenFM; import me.michiyo.openfm.world.be.RadioBlockEntity; import me.michiyo.openfm.world.be.SpeakerBlockEntity; import net.minecraft.core.BlockPos; import net.minecraft.core.registries.Registries; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.network.NetworkEvent; - -import java.util.function.Supplier; - -public class C2SLinkSpeaker { +import net.neoforged.neoforge.network.handling.IPayloadContext; + +public class C2SLinkSpeaker implements CustomPacketPayload { + public static final Type TYPE = new Type<>( + ResourceLocation.fromNamespaceAndPath(OpenFM.MODID, "link_speaker") + ); + public static final StreamCodec STREAM_CODEC = + StreamCodec.of((buf, msg) -> encode(msg, buf), C2SLinkSpeaker::decode); private final boolean unlink; private final ResourceKey speakerDim; @@ -61,13 +69,10 @@ public static C2SLinkSpeaker decode(FriendlyByteBuf buf) { return new C2SLinkSpeaker(unlink, speakerDim, speakerPos, radioDim, radioPos); } - public static void handle(C2SLinkSpeaker msg, Supplier ctxSup) { - NetworkEvent.Context ctx = ctxSup.get(); + public static void handle(C2SLinkSpeaker msg, IPayloadContext ctx) { + if (!(ctx.player() instanceof net.minecraft.server.level.ServerPlayer player)) return; - ctx.enqueueWork(() -> { - if (ctx.getSender() == null) return; - - ServerLevel speakerLevel = ctx.getSender().server.getLevel(msg.speakerDim); + ServerLevel speakerLevel = player.server.getLevel(msg.speakerDim); if (speakerLevel == null) return; if (!speakerLevel.isLoaded(msg.speakerPos)) return; @@ -80,7 +85,7 @@ public static void handle(C2SLinkSpeaker msg, Supplier ctx return; } - ServerLevel radioLevel = ctx.getSender().server.getLevel(msg.radioDim); + ServerLevel radioLevel = player.server.getLevel(msg.radioDim); if (radioLevel == null) return; if (!radioLevel.isLoaded(msg.radioPos)) return; @@ -95,9 +100,11 @@ public static void handle(C2SLinkSpeaker msg, Supplier ctx speakerBe.setLink(msg.radioDim, msg.radioPos); sendSpeakerUpdate(speakerLevel, msg.speakerPos); - }); + } - ctx.setPacketHandled(true); + @Override + public Type type() { + return TYPE; } private static void sendSpeakerUpdate(ServerLevel level, BlockPos pos) { diff --git a/src/main/java/me/michiyo/openfm/net/C2SSetFields.java b/src/main/java/me/michiyo/openfm/net/C2SSetFields.java index e9acab3..091398a 100644 --- a/src/main/java/me/michiyo/openfm/net/C2SSetFields.java +++ b/src/main/java/me/michiyo/openfm/net/C2SSetFields.java @@ -1,14 +1,22 @@ package me.michiyo.openfm.net; +import me.michiyo.openfm.OpenFM; import me.michiyo.openfm.world.be.RadioBlockEntity; import net.minecraft.core.BlockPos; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; -import net.minecraftforge.network.NetworkEvent; +import net.neoforged.neoforge.network.handling.IPayloadContext; -import java.util.function.Supplier; - -public class C2SSetFields { +public class C2SSetFields implements CustomPacketPayload { + public static final Type TYPE = new Type<>( + ResourceLocation.fromNamespaceAndPath(OpenFM.MODID, "set_fields") + ); + public static final StreamCodec STREAM_CODEC = + StreamCodec.of((buf, msg) -> encode(msg, buf), C2SSetFields::decode); public final BlockPos pos; public final String url; public final String screenColor; @@ -37,11 +45,8 @@ public static C2SSetFields decode(FriendlyByteBuf buf) { ); } - public static void handle(C2SSetFields msg, Supplier ctxSup) { - NetworkEvent.Context ctx = ctxSup.get(); - ctx.enqueueWork(() -> { - ServerPlayer player = ctx.getSender(); - if (player == null) return; + public static void handle(C2SSetFields msg, IPayloadContext ctx) { + if (!(ctx.player() instanceof ServerPlayer player)) return; var level = player.serverLevel(); var be = level.getBlockEntity(msg.pos); @@ -69,9 +74,12 @@ public static void handle(C2SSetFields msg, Supplier ctxSu radio.setScreenText(text); } - radio.setChanged(); - S2CSyncFields.syncToTracking(level, msg.pos, radio); - }); - ctx.setPacketHandled(true); + radio.setChanged(); + S2CSyncFields.syncToTracking(level, msg.pos, radio); + } + + @Override + public Type type() { + return TYPE; } } diff --git a/src/main/java/me/michiyo/openfm/net/MemoryCardLogic.java b/src/main/java/me/michiyo/openfm/net/MemoryCardLogic.java index 92c68b1..b29daa8 100644 --- a/src/main/java/me/michiyo/openfm/net/MemoryCardLogic.java +++ b/src/main/java/me/michiyo/openfm/net/MemoryCardLogic.java @@ -1,8 +1,10 @@ package me.michiyo.openfm.net; import me.michiyo.openfm.world.be.RadioBlockEntity; +import net.minecraft.core.component.DataComponents; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.component.CustomData; public final class MemoryCardLogic { private static final String ROOT = "OpenFMCard"; @@ -11,7 +13,6 @@ public static void saveToCard(RadioBlockEntity radio) { ItemStack card = radio.getInventory().getItem(0); if (card.isEmpty()) return; - CompoundTag tag = card.getOrCreateTag(); CompoundTag root = new CompoundTag(); root.putString("StreamUrl", radio.getStreamUrl()); @@ -19,17 +20,16 @@ public static void saveToCard(RadioBlockEntity radio) { root.putString("ScreenColor", radio.getScreenColor()); root.putString("ScreenText", radio.getScreenText()); - tag.put(ROOT, root); - card.setTag(tag); + CustomData.update(DataComponents.CUSTOM_DATA, card, tag -> tag.put(ROOT, root)); radio.setChanged(); } public static void loadFromCard(RadioBlockEntity radio) { ItemStack card = radio.getInventory().getItem(0); - if (card.isEmpty() || !card.hasTag()) return; + if (card.isEmpty()) return; - CompoundTag tag = card.getTag(); - if (tag == null || !tag.contains(ROOT)) return; + CompoundTag tag = card.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag(); + if (!tag.contains(ROOT)) return; CompoundTag root = tag.getCompound(ROOT); @@ -41,13 +41,9 @@ public static void loadFromCard(RadioBlockEntity radio) { public static void deleteFromCard(RadioBlockEntity radio) { ItemStack card = radio.getInventory().getItem(0); - if (card.isEmpty() || !card.hasTag()) return; - - CompoundTag tag = card.getTag(); - if (tag == null) return; + if (card.isEmpty()) return; - tag.remove(ROOT); - card.setTag(tag); + CustomData.update(DataComponents.CUSTOM_DATA, card, tag -> tag.remove(ROOT)); radio.setChanged(); } diff --git a/src/main/java/me/michiyo/openfm/net/Net.java b/src/main/java/me/michiyo/openfm/net/Net.java index 9213d61..3e6e3b5 100644 --- a/src/main/java/me/michiyo/openfm/net/Net.java +++ b/src/main/java/me/michiyo/openfm/net/Net.java @@ -1,49 +1,23 @@ package me.michiyo.openfm.net; -import me.michiyo.openfm.OpenFM; -import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.network.NetworkDirection; -import net.minecraftforge.network.NetworkRegistry; -import net.minecraftforge.network.simple.SimpleChannel; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.neoforged.neoforge.network.PacketDistributor; +import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent; +import net.neoforged.neoforge.network.registration.PayloadRegistrar; public final class Net { private static final String PROTOCOL = "1"; - public static final SimpleChannel CH = NetworkRegistry.newSimpleChannel( - new ResourceLocation(OpenFM.MODID, "main"), - () -> PROTOCOL, - PROTOCOL::equals, - PROTOCOL::equals - ); - private static int id = 0; - - public static void register() { - // C2S - CH.messageBuilder(C2SButtonAction.class, id++, NetworkDirection.PLAY_TO_SERVER) - .encoder(C2SButtonAction::encode) - .decoder(C2SButtonAction::decode) - .consumerMainThread(C2SButtonAction::handle) - .add(); - - CH.messageBuilder(C2SSetFields.class, id++, NetworkDirection.PLAY_TO_SERVER) - .encoder(C2SSetFields::encode) - .decoder(C2SSetFields::decode) - .consumerMainThread(C2SSetFields::handle) - .add(); - - // NEW: Speaker link/unlink - CH.messageBuilder(C2SLinkSpeaker.class, id++, NetworkDirection.PLAY_TO_SERVER) - .encoder(C2SLinkSpeaker::encode) - .decoder(C2SLinkSpeaker::decode) - .consumerMainThread(C2SLinkSpeaker::handle) - .add(); + public static void register(RegisterPayloadHandlersEvent event) { + PayloadRegistrar registrar = event.registrar(PROTOCOL); + registrar.playToServer(C2SButtonAction.TYPE, C2SButtonAction.STREAM_CODEC, C2SButtonAction::handle); + registrar.playToServer(C2SSetFields.TYPE, C2SSetFields.STREAM_CODEC, C2SSetFields::handle); + registrar.playToServer(C2SLinkSpeaker.TYPE, C2SLinkSpeaker.STREAM_CODEC, C2SLinkSpeaker::handle); + registrar.playToClient(S2CSyncFields.TYPE, S2CSyncFields.STREAM_CODEC, S2CSyncFields::handle); + } - // S2C (THIS is the one that makes your color/text/url sync work) - CH.messageBuilder(S2CSyncFields.class, id++, NetworkDirection.PLAY_TO_CLIENT) - .encoder(S2CSyncFields::encode) - .decoder(S2CSyncFields::decode) - .consumerMainThread(S2CSyncFields::handle) - .add(); + public static void sendToServer(CustomPacketPayload payload) { + PacketDistributor.sendToServer(payload); } private Net() {} diff --git a/src/main/java/me/michiyo/openfm/net/S2CSyncFields.java b/src/main/java/me/michiyo/openfm/net/S2CSyncFields.java index 73f9a41..f4e02ab 100644 --- a/src/main/java/me/michiyo/openfm/net/S2CSyncFields.java +++ b/src/main/java/me/michiyo/openfm/net/S2CSyncFields.java @@ -1,17 +1,25 @@ package me.michiyo.openfm.net; +import me.michiyo.openfm.OpenFM; import me.michiyo.openfm.client.screen.RadioScreen; import me.michiyo.openfm.world.be.RadioBlockEntity; import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; -import net.minecraftforge.network.NetworkEvent; -import net.minecraftforge.network.PacketDistributor; +import net.neoforged.neoforge.network.PacketDistributor; +import net.neoforged.neoforge.network.handling.IPayloadContext; -import java.util.function.Supplier; - -public class S2CSyncFields { +public class S2CSyncFields implements CustomPacketPayload { + public static final Type TYPE = new Type<>( + ResourceLocation.fromNamespaceAndPath(OpenFM.MODID, "sync_fields") + ); + public static final StreamCodec STREAM_CODEC = + StreamCodec.of((buf, msg) -> encode(msg, buf), S2CSyncFields::decode); public final BlockPos pos; public final String url; public final String screenColor; @@ -52,11 +60,9 @@ public static S2CSyncFields decode(FriendlyByteBuf buf) { ); } - public static void handle(S2CSyncFields msg, Supplier ctxSup) { - NetworkEvent.Context ctx = ctxSup.get(); - ctx.enqueueWork(() -> { - Minecraft mc = Minecraft.getInstance(); - if (mc.level == null) return; + public static void handle(S2CSyncFields msg, IPayloadContext ctx) { + Minecraft mc = Minecraft.getInstance(); + if (mc.level == null) return; var be = mc.level.getBlockEntity(msg.pos); if (be instanceof RadioBlockEntity radio) { @@ -67,10 +73,11 @@ public static void handle(S2CSyncFields msg, Supplier ctxS if (mc.screen instanceof RadioScreen screen) { screen.applyServerSync(msg); } - }); + } - //System.out.println("[OpenFM] S2C received for " + msg.pos + " color=" + msg.screenColor + " text=" + msg.screenText + " playing=" + msg.playing); - ctx.setPacketHandled(true); + @Override + public Type type() { + return TYPE; } public static void syncToTracking(ServerLevel level, BlockPos pos, RadioBlockEntity radio) { @@ -83,7 +90,7 @@ public static void syncToTracking(ServerLevel level, BlockPos pos, RadioBlockEnt radio.isLocked(), radio.isPlaying() ); - Net.CH.send(PacketDistributor.TRACKING_CHUNK.with(() -> level.getChunkAt(pos)), pkt); + PacketDistributor.sendToPlayersTrackingChunk(level, level.getChunkAt(pos).getPos(), pkt); } public static void syncToPlayer(net.minecraft.server.level.ServerPlayer player, BlockPos pos, RadioBlockEntity radio) { @@ -96,6 +103,6 @@ public static void syncToPlayer(net.minecraft.server.level.ServerPlayer player, radio.isLocked(), radio.isPlaying() ); - Net.CH.send(PacketDistributor.PLAYER.with(() -> player), pkt); + PacketDistributor.sendToPlayer(player, pkt); } } diff --git a/src/main/java/me/michiyo/openfm/reg/ModBlockEntities.java b/src/main/java/me/michiyo/openfm/reg/ModBlockEntities.java index 2be0f02..f50f9e3 100644 --- a/src/main/java/me/michiyo/openfm/reg/ModBlockEntities.java +++ b/src/main/java/me/michiyo/openfm/reg/ModBlockEntities.java @@ -3,20 +3,20 @@ import me.michiyo.openfm.OpenFM; import me.michiyo.openfm.world.be.RadioBlockEntity; import me.michiyo.openfm.world.be.SpeakerBlockEntity; +import net.minecraft.core.registries.Registries; import net.minecraft.world.level.block.entity.BlockEntityType; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; -import net.minecraftforge.registries.RegistryObject; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; public class ModBlockEntities { public static final DeferredRegister> REG = - DeferredRegister.create(ForgeRegistries.BLOCK_ENTITY_TYPES, OpenFM.MODID); + DeferredRegister.create(Registries.BLOCK_ENTITY_TYPE, OpenFM.MODID); - public static final RegistryObject> RADIO_BE = REG.register("radio_be", + public static final DeferredHolder, BlockEntityType> RADIO_BE = REG.register("radio_be", () -> BlockEntityType.Builder.of(RadioBlockEntity::new, ModBlocks.RADIO_BLOCK.get()).build(null) ); - public static final RegistryObject> SPEAKER_BE = REG.register("speaker_be", + public static final DeferredHolder, BlockEntityType> SPEAKER_BE = REG.register("speaker_be", () -> BlockEntityType.Builder.of(SpeakerBlockEntity::new, ModBlocks.SPEAKER_BLOCK.get()).build(null) ); } diff --git a/src/main/java/me/michiyo/openfm/reg/ModBlocks.java b/src/main/java/me/michiyo/openfm/reg/ModBlocks.java index 0b0bf6f..b5e9fa2 100644 --- a/src/main/java/me/michiyo/openfm/reg/ModBlocks.java +++ b/src/main/java/me/michiyo/openfm/reg/ModBlocks.java @@ -6,18 +6,17 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.material.MapColor; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; -import net.minecraftforge.registries.RegistryObject; +import net.neoforged.neoforge.registries.DeferredBlock; +import net.neoforged.neoforge.registries.DeferredRegister; public class ModBlocks { - public static final DeferredRegister REG = DeferredRegister.create(ForgeRegistries.BLOCKS, OpenFM.MODID); + public static final DeferredRegister.Blocks REG = DeferredRegister.createBlocks(OpenFM.MODID); - public static final RegistryObject RADIO_BLOCK = REG.register("radio_block", + public static final DeferredBlock RADIO_BLOCK = REG.register("radio_block", () -> new RadioBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).strength(3.0F).requiresCorrectToolForDrops()) ); - public static final RegistryObject SPEAKER_BLOCK = REG.register("speaker_block", + public static final DeferredBlock SPEAKER_BLOCK = REG.register("speaker_block", () -> new SpeakerBlock(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).strength(3.0F).requiresCorrectToolForDrops()) ); } diff --git a/src/main/java/me/michiyo/openfm/reg/ModCreativeTabs.java b/src/main/java/me/michiyo/openfm/reg/ModCreativeTabs.java index aaedc37..442b82d 100644 --- a/src/main/java/me/michiyo/openfm/reg/ModCreativeTabs.java +++ b/src/main/java/me/michiyo/openfm/reg/ModCreativeTabs.java @@ -5,20 +5,21 @@ import net.minecraft.network.chat.Component; import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.ItemStack; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.RegistryObject; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; public class ModCreativeTabs { public static final DeferredRegister REG = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, OpenFM.MODID); - public static final RegistryObject OPENFM_TAB = REG.register("openfm", () -> + public static final DeferredHolder OPENFM_TAB = REG.register("openfm", () -> CreativeModeTab.builder() .title(Component.literal("OpenFM")) .icon(() -> new ItemStack(ModItems.RADIO_BLOCK_ITEM.get())) .displayItems((params, output) -> { output.accept(ModItems.RADIO_BLOCK_ITEM.get()); output.accept(ModItems.SPEAKER_BLOCK_ITEM.get()); + output.accept(ModItems.MEMORY_CARD.get()); output.accept(ModItems.TUNER.get()); }) .build() diff --git a/src/main/java/me/michiyo/openfm/reg/ModItems.java b/src/main/java/me/michiyo/openfm/reg/ModItems.java index ab5cb03..3f91e42 100644 --- a/src/main/java/me/michiyo/openfm/reg/ModItems.java +++ b/src/main/java/me/michiyo/openfm/reg/ModItems.java @@ -4,26 +4,25 @@ import me.michiyo.openfm.world.item.OpenFMTunerItem; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.Item; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; -import net.minecraftforge.registries.RegistryObject; +import net.neoforged.neoforge.registries.DeferredItem; +import net.neoforged.neoforge.registries.DeferredRegister; public class ModItems { - public static final DeferredRegister REG = DeferredRegister.create(ForgeRegistries.ITEMS, OpenFM.MODID); + public static final DeferredRegister.Items REG = DeferredRegister.createItems(OpenFM.MODID); - public static final RegistryObject RADIO_BLOCK_ITEM = REG.register("radio_block", + public static final DeferredItem RADIO_BLOCK_ITEM = REG.register("radio_block", () -> new BlockItem(ModBlocks.RADIO_BLOCK.get(), new Item.Properties()) ); - public static final RegistryObject SPEAKER_BLOCK_ITEM = REG.register("speaker_block", + public static final DeferredItem SPEAKER_BLOCK_ITEM = REG.register("speaker_block", () -> new BlockItem(ModBlocks.SPEAKER_BLOCK.get(), new Item.Properties()) ); - public static final RegistryObject MEMORY_CARD = REG.register("memory_card", + public static final DeferredItem MEMORY_CARD = REG.register("memory_card", () -> new Item(new Item.Properties().stacksTo(1)) ); - public static final RegistryObject TUNER = REG.register("tuner", + public static final DeferredItem TUNER = REG.register("tuner", () -> new OpenFMTunerItem(new Item.Properties().stacksTo(1)) ); } diff --git a/src/main/java/me/michiyo/openfm/reg/ModMenus.java b/src/main/java/me/michiyo/openfm/reg/ModMenus.java index e36a539..59c0393 100644 --- a/src/main/java/me/michiyo/openfm/reg/ModMenus.java +++ b/src/main/java/me/michiyo/openfm/reg/ModMenus.java @@ -2,16 +2,16 @@ import me.michiyo.openfm.OpenFM; import me.michiyo.openfm.world.menu.RadioMenu; +import net.minecraft.core.registries.Registries; import net.minecraft.world.inventory.MenuType; -import net.minecraftforge.common.extensions.IForgeMenuType; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; -import net.minecraftforge.registries.RegistryObject; +import net.neoforged.neoforge.common.extensions.IMenuTypeExtension; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; public class ModMenus { public static final DeferredRegister> REG = - DeferredRegister.create(ForgeRegistries.MENU_TYPES, OpenFM.MODID); + DeferredRegister.create(Registries.MENU, OpenFM.MODID); - public static final RegistryObject> RADIO_MENU = - REG.register("radio_menu", () -> IForgeMenuType.create(RadioMenu::new)); + public static final DeferredHolder, MenuType> RADIO_MENU = + REG.register("radio_menu", () -> IMenuTypeExtension.create(RadioMenu::new)); } diff --git a/src/main/java/me/michiyo/openfm/world/be/RadioBlockEntity.java b/src/main/java/me/michiyo/openfm/world/be/RadioBlockEntity.java index 96fa5f3..72ebb51 100644 --- a/src/main/java/me/michiyo/openfm/world/be/RadioBlockEntity.java +++ b/src/main/java/me/michiyo/openfm/world/be/RadioBlockEntity.java @@ -4,6 +4,7 @@ import me.michiyo.openfm.net.S2CSyncFields; import me.michiyo.openfm.reg.ModBlockEntities; import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.Connection; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; @@ -158,8 +159,8 @@ public void setScreenText(String t) { public SimpleContainer getInventory() { return inv; } @Override - protected void saveAdditional(CompoundTag tag) { - super.saveAdditional(tag); + protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.saveAdditional(tag, registries); if (ownerUuid != null) tag.putUUID("Owner", ownerUuid); tag.putBoolean("Locked", locked); @@ -173,13 +174,13 @@ protected void saveAdditional(CompoundTag tag) { CompoundTag invTag = new CompoundTag(); ItemStack stack = inv.getItem(0); - if (!stack.isEmpty()) invTag.put("MemoryCard", stack.save(new CompoundTag())); + if (!stack.isEmpty()) invTag.put("MemoryCard", stack.save(registries)); tag.put("Inv", invTag); } @Override - public void load(CompoundTag tag) { - super.load(tag); + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.loadAdditional(tag, registries); ownerUuid = tag.hasUUID("Owner") ? tag.getUUID("Owner") : null; locked = tag.getBoolean("Locked"); @@ -195,7 +196,7 @@ public void load(CompoundTag tag) { if (tag.contains("Inv")) { CompoundTag invTag = tag.getCompound("Inv"); if (invTag.contains("MemoryCard")) { - inv.setItem(0, ItemStack.of(invTag.getCompound("MemoryCard"))); + inv.setItem(0, ItemStack.parseOptional(registries, invTag.getCompound("MemoryCard"))); } } } @@ -250,13 +251,13 @@ public void setRemoved() { // ---- BE sync plumbing ---- @Override - public CompoundTag getUpdateTag() { - return saveWithoutMetadata(); + public CompoundTag getUpdateTag(HolderLookup.Provider registries) { + return saveWithoutMetadata(registries); } @Override - public void handleUpdateTag(CompoundTag tag) { - load(tag); + public void handleUpdateTag(CompoundTag tag, HolderLookup.Provider registries) { + loadWithComponents(tag, registries); clientApplyAudioState(); } @@ -266,10 +267,10 @@ public ClientboundBlockEntityDataPacket getUpdatePacket() { } @Override - public void onDataPacket(Connection net, ClientboundBlockEntityDataPacket pkt) { + public void onDataPacket(Connection net, ClientboundBlockEntityDataPacket pkt, HolderLookup.Provider registries) { CompoundTag tag = pkt.getTag(); if (tag != null) { - load(tag); + loadWithComponents(tag, registries); clientApplyAudioState(); } } @@ -375,7 +376,7 @@ public String cc_getStreamUrl() { private void cc_event(String event, Object... args) { if (this.level == null || this.level.isClientSide) return; if (!(this.level instanceof net.minecraft.server.level.ServerLevel serverLevel)) return; - if (!net.minecraftforge.fml.ModList.get().isLoaded("computercraft")) return; + if (!net.neoforged.fml.ModList.get().isLoaded("computercraft")) return; try { Class cls = Class.forName("me.michiyo.openfm.compat.cc.CCEvents"); diff --git a/src/main/java/me/michiyo/openfm/world/be/SpeakerBlockEntity.java b/src/main/java/me/michiyo/openfm/world/be/SpeakerBlockEntity.java index fe89b56..7695e91 100644 --- a/src/main/java/me/michiyo/openfm/world/be/SpeakerBlockEntity.java +++ b/src/main/java/me/michiyo/openfm/world/be/SpeakerBlockEntity.java @@ -2,6 +2,7 @@ import me.michiyo.openfm.reg.ModBlockEntities; import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceKey; @@ -11,8 +12,8 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec3; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.fml.loading.FMLEnvironment; public class SpeakerBlockEntity extends BlockEntity { private static final String NBT_LINKED_DIM = "LinkedDim"; @@ -89,19 +90,19 @@ private void syncToClient() { // ----------------------- private static void clientRegisterEmitter(BlockPos radioPos, BlockPos speakerPos) { - DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> { + if (FMLEnvironment.dist == Dist.CLIENT) { me.michiyo.openfm.client.audio.RadioStreamManager.setEmitterForRadio( radioPos, speakerPos, Vec3.atCenterOf(speakerPos) ); - }); + } } private static void clientUnregisterEmitter(BlockPos radioPos, BlockPos speakerPos) { - DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> { + if (FMLEnvironment.dist == Dist.CLIENT) { me.michiyo.openfm.client.audio.RadioStreamManager.clearEmitterForRadio(radioPos, speakerPos); - }); + } } /** @@ -172,12 +173,12 @@ public static void serverTick(Level level, BlockPos pos, BlockState state, Speak // ----------------------- @Override - public void load(CompoundTag tag) { - super.load(tag); + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.loadAdditional(tag, registries); String dimStr = tag.getString(NBT_LINKED_DIM); if (dimStr != null && !dimStr.isEmpty()) { - this.linkedDim = ResourceKey.create(Registries.DIMENSION, new ResourceLocation(dimStr)); + this.linkedDim = ResourceKey.create(Registries.DIMENSION, ResourceLocation.parse(dimStr)); } else { this.linkedDim = null; } @@ -196,8 +197,8 @@ public void load(CompoundTag tag) { } @Override - protected void saveAdditional(CompoundTag tag) { - super.saveAdditional(tag); + protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.saveAdditional(tag, registries); tag.putString(NBT_LINKED_DIM, linkedDim == null ? "" : linkedDim.location().toString()); if (linkedRadioPos != null) { @@ -209,15 +210,15 @@ protected void saveAdditional(CompoundTag tag) { } @Override - public CompoundTag getUpdateTag() { + public CompoundTag getUpdateTag(HolderLookup.Provider registries) { CompoundTag tag = new CompoundTag(); - saveAdditional(tag); + saveAdditional(tag, registries); return tag; } @Override - public void handleUpdateTag(CompoundTag tag) { - super.handleUpdateTag(tag); + public void handleUpdateTag(CompoundTag tag, HolderLookup.Provider registries) { + super.handleUpdateTag(tag, registries); // load() is not guaranteed to be called here, so refresh using current fields clientRefreshEmitterRegistration(); } diff --git a/src/main/java/me/michiyo/openfm/world/block/RadioBlock.java b/src/main/java/me/michiyo/openfm/world/block/RadioBlock.java index 7c75f51..859290a 100644 --- a/src/main/java/me/michiyo/openfm/world/block/RadioBlock.java +++ b/src/main/java/me/michiyo/openfm/world/block/RadioBlock.java @@ -1,12 +1,12 @@ package me.michiyo.openfm.world.block; +import com.mojang.serialization.MapCodec; import me.michiyo.openfm.world.be.RadioBlockEntity; import me.michiyo.openfm.world.menu.RadioMenu; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.MenuProvider; import net.minecraft.world.SimpleMenuProvider; @@ -22,11 +22,11 @@ import net.minecraft.world.level.block.state.properties.DirectionProperty; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.phys.BlockHitResult; -import net.minecraftforge.network.NetworkHooks; import javax.annotation.Nullable; public class RadioBlock extends BaseEntityBlock { + public static final MapCodec CODEC = simpleCodec(RadioBlock::new); public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; public RadioBlock(Properties props) { @@ -34,6 +34,11 @@ public RadioBlock(Properties props) { this.registerDefaultState(this.stateDefinition.any().setValue(FACING, Direction.NORTH)); } + @Override + protected MapCodec codec() { + return CODEC; + } + @Override public RenderShape getRenderShape(BlockState state) { return RenderShape.MODEL; @@ -57,7 +62,7 @@ protected void createBlockStateDefinition(StateDefinition.Builder buf.writeBlockPos(pos)); + ((ServerPlayer) player).openMenu(provider, buf -> buf.writeBlockPos(pos)); return InteractionResult.CONSUME; } } diff --git a/src/main/java/me/michiyo/openfm/world/block/SpeakerBlock.java b/src/main/java/me/michiyo/openfm/world/block/SpeakerBlock.java index a52b1c7..2cc571c 100644 --- a/src/main/java/me/michiyo/openfm/world/block/SpeakerBlock.java +++ b/src/main/java/me/michiyo/openfm/world/block/SpeakerBlock.java @@ -1,5 +1,6 @@ package me.michiyo.openfm.world.block; +import com.mojang.serialization.MapCodec; import me.michiyo.openfm.world.be.SpeakerBlockEntity; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -19,6 +20,7 @@ import org.jetbrains.annotations.Nullable; public class SpeakerBlock extends BaseEntityBlock { + public static final MapCodec CODEC = simpleCodec(SpeakerBlock::new); public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; public SpeakerBlock(Properties props) { @@ -26,6 +28,11 @@ public SpeakerBlock(Properties props) { this.registerDefaultState(this.stateDefinition.any().setValue(FACING, Direction.NORTH)); } + @Override + protected MapCodec codec() { + return CODEC; + } + @Override public RenderShape getRenderShape(BlockState state) { return RenderShape.MODEL; diff --git a/src/main/java/me/michiyo/openfm/world/item/OpenFMTunerItem.java b/src/main/java/me/michiyo/openfm/world/item/OpenFMTunerItem.java index 25564dd..ded2159 100644 --- a/src/main/java/me/michiyo/openfm/world/item/OpenFMTunerItem.java +++ b/src/main/java/me/michiyo/openfm/world/item/OpenFMTunerItem.java @@ -8,12 +8,14 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; +import net.minecraft.core.component.DataComponents; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.InteractionResult; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.component.CustomData; import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.level.Level; @@ -37,7 +39,7 @@ public InteractionResult useOn(UseOnContext ctx) { // send packet client-side if (level.isClientSide) { ResourceKey dim = level.dimension(); - Net.CH.sendToServer(C2SLinkSpeaker.unlink(dim, clicked)); + Net.sendToServer(C2SLinkSpeaker.unlink(dim, clicked)); } clearSpeakerSelection(stack); @@ -80,7 +82,7 @@ public InteractionResult useOn(UseOnContext ctx) { // send packet client-side if (level.isClientSide) { - Net.CH.sendToServer(C2SLinkSpeaker.link(sel.dim, sel.pos, level.dimension(), clicked)); + Net.sendToServer(C2SLinkSpeaker.link(sel.dim, sel.pos, level.dimension(), clicked)); } clearSpeakerSelection(stack); @@ -99,27 +101,27 @@ public InteractionResult useOn(UseOnContext ctx) { } private static void setSpeakerSelection(ItemStack stack, ResourceKey dim, BlockPos pos) { - CompoundTag tag = stack.getOrCreateTag(); - tag.putString(NBT_SPK_DIM, dim.location().toString()); - tag.putLong(NBT_SPK_POS, pos.asLong()); + CustomData.update(DataComponents.CUSTOM_DATA, stack, tag -> { + tag.putString(NBT_SPK_DIM, dim.location().toString()); + tag.putLong(NBT_SPK_POS, pos.asLong()); + }); } private static void clearSpeakerSelection(ItemStack stack) { - CompoundTag tag = stack.getTag(); - if (tag == null) return; - tag.remove(NBT_SPK_DIM); - tag.remove(NBT_SPK_POS); + CustomData.update(DataComponents.CUSTOM_DATA, stack, tag -> { + tag.remove(NBT_SPK_DIM); + tag.remove(NBT_SPK_POS); + }); } private static SpeakerSel getSpeakerSelection(ItemStack stack) { - CompoundTag tag = stack.getTag(); - if (tag == null) return null; + CompoundTag tag = stack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag(); if (!tag.contains(NBT_SPK_DIM) || !tag.contains(NBT_SPK_POS)) return null; String dimStr = tag.getString(NBT_SPK_DIM); if (dimStr == null || dimStr.isEmpty()) return null; - ResourceKey dim = ResourceKey.create(Registries.DIMENSION, new ResourceLocation(dimStr)); + ResourceKey dim = ResourceKey.create(Registries.DIMENSION, ResourceLocation.parse(dimStr)); BlockPos pos = BlockPos.of(tag.getLong(NBT_SPK_POS)); return new SpeakerSel(dim, pos); } diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml deleted file mode 100644 index 359bd7f..0000000 --- a/src/main/resources/META-INF/mods.toml +++ /dev/null @@ -1,24 +0,0 @@ -modLoader="javafml" -loaderVersion="[47,)" -license="MIT" - -[[mods]] -modId="openfm" -version="${file.jarVersion}" -displayName="OpenFM" -authors="Caitlyn" -description="Streaming radio block + speakers." - -[[dependencies.openfm]] -modId="forge" -mandatory=true -versionRange="[47,)" -ordering="NONE" -side="BOTH" - -[[dependencies.openfm]] -modId="minecraft" -mandatory=true -versionRange="[1.20.1]" -ordering="NONE" -side="BOTH" diff --git a/src/main/resources/META-INF/neoforge.mods.toml b/src/main/resources/META-INF/neoforge.mods.toml new file mode 100644 index 0000000..7b3b7f6 --- /dev/null +++ b/src/main/resources/META-INF/neoforge.mods.toml @@ -0,0 +1,31 @@ +modLoader="javafml" +loaderVersion="${loader_version_range}" +license="${mod_license}" + +[[mods]] +modId="${mod_id}" +version="${mod_version}" +displayName="${mod_name}" +authors="Caitlyn" +description="Streaming radio block + speakers." + +[[dependencies.${mod_id}]] +modId="neoforge" +type="required" +versionRange="[${neo_version},)" +ordering="NONE" +side="BOTH" + +[[dependencies.${mod_id}]] +modId="minecraft" +type="required" +versionRange="${minecraft_version_range}" +ordering="NONE" +side="BOTH" + +[[dependencies.${mod_id}]] +modId="computercraft" +type="optional" +versionRange="[${cc_tweaked_version},)" +ordering="AFTER" +side="BOTH" diff --git a/src/main/resources/assets/openfm/lang/en_us.json b/src/main/resources/assets/openfm/lang/en_us.json index 407b542..f05c630 100644 --- a/src/main/resources/assets/openfm/lang/en_us.json +++ b/src/main/resources/assets/openfm/lang/en_us.json @@ -3,6 +3,5 @@ "item.openfm.memory_card": "Memory Card", "item.openfm.radio_block": "OpenFM Radio", "item.openfm.tuner": "Tuner", - "block.openfm.speaker_block": "Speaker", - + "block.openfm.speaker_block": "Speaker" } diff --git a/src/main/resources/assets/openfm/models/item/memory_card.json b/src/main/resources/assets/openfm/models/item/memory_card.json new file mode 100644 index 0000000..470db87 --- /dev/null +++ b/src/main/resources/assets/openfm/models/item/memory_card.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "openfm:item/memory_card" + } +} diff --git a/src/main/resources/assets/openfm/models/item/tuner.json b/src/main/resources/assets/openfm/models/item/tuner.json new file mode 100644 index 0000000..4cf7c8a --- /dev/null +++ b/src/main/resources/assets/openfm/models/item/tuner.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "openfm:item/tuner" + } +} diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta index 29d0731..76604fd 100644 --- a/src/main/resources/pack.mcmeta +++ b/src/main/resources/pack.mcmeta @@ -1,6 +1,6 @@ { "pack": { - "pack_format": 15, + "pack_format": 34, "description": "OpenFM resources" } } From df2e8f35d68ccf38f8aee11901d350249b19a653 Mon Sep 17 00:00:00 2001 From: Caitlyn <1423429+CaitlynMainer@users.noreply.github.com> Date: Thu, 16 Jul 2026 20:23:21 -0700 Subject: [PATCH 2/3] Fabric, does it work? Sorta! --- .gitignore | 1 + README.md | 41 +++++--- build.gradle | 90 +----------------- buildSrc/build.gradle | 4 + .../src/main/groovy/multiloader-common.gradle | 77 +++++++++++++++ .../src/main/groovy/multiloader-loader.gradle | 34 +++++++ common/build.gradle | 36 +++++++ .../src}/main/java/me/michiyo/openfm.zip | Bin .../main/java/me/michiyo/openfm/OpenFM.java | 27 ++++++ .../michiyo/openfm/client/ClientEvents.java | 12 +++ .../michiyo/openfm/client/OpenFMClient.java | 27 ++++++ .../openfm/client/audio/AacDecoder.java | 0 .../openfm/client/audio/DecoderFactory.java | 0 .../openfm/client/audio/Mp3Decoder.java | 0 .../openfm/client/audio/OggVorbisDecoder.java | 0 .../openfm/client/audio/PcmDecoder.java | 0 .../client/audio/RadioStreamManager.java | 0 .../client/audio/RadioStreamPlayer.java | 0 .../openfm/client/gui/TexturedButton.java | 0 .../render/RadioBlockEntityRenderer.java | 0 .../screen/OpenFMAudioSettingsScreen.java | 0 .../openfm/client/screen/RadioScreen.java | 11 ++- .../me/michiyo/openfm/compat/cc/CCEvents.java | 0 .../compat/cc/OpenFMRadioPeripheral.java | 0 .../openfm/config/OpenFMClientConfig.java | 20 ++++ .../michiyo/openfm/net/C2SButtonAction.java | 5 +- .../me/michiyo/openfm/net/C2SLinkSpeaker.java | 6 +- .../me/michiyo/openfm/net/C2SSetFields.java | 5 +- .../michiyo/openfm/net/MemoryCardLogic.java | 0 .../main/java/me/michiyo/openfm/net/Net.java | 13 +++ .../me/michiyo/openfm/net/S2CSyncFields.java | 9 +- .../openfm/platform/OpenFMPlatform.java | 28 ++++++ .../openfm/platform/OpenFMRegistrar.java | 30 ++++++ .../openfm/platform/RegistrySupplier.java | 8 ++ .../me/michiyo/openfm/platform/Services.java | 12 +++ .../michiyo/openfm/reg/ModBlockEntities.java | 19 ++++ .../java/me/michiyo/openfm/reg/ModBlocks.java | 24 +++++ .../michiyo/openfm/reg/ModCreativeTabs.java | 26 +++++ .../java/me/michiyo/openfm/reg/ModItems.java | 28 ++++++ .../java/me/michiyo/openfm/reg/ModMenus.java | 17 ++++ .../openfm/world/be/RadioBlockEntity.java | 28 +----- .../openfm/world/be/SpeakerBlockEntity.java | 20 +--- .../openfm/world/block/RadioBlock.java | 3 +- .../openfm/world/block/SpeakerBlock.java | 0 .../openfm/world/item/OpenFMTunerItem.java | 0 .../michiyo/openfm/world/menu/RadioMenu.java | 0 .../openfm/blockstates/radio_block.json | 0 .../openfm/blockstates/speaker_block.json | 0 .../resources/assets/openfm/lang/en_us.json | 0 .../openfm/models/block/radio_block.json | 0 .../openfm/models/block/speaker_block.json | 0 .../openfm/models/item/memory_card.json | 0 .../openfm/models/item/radio_block.json | 0 .../openfm/models/item/speaker_block.json | 0 .../assets/openfm/models/item/tuner.json | 0 .../openfm/textures/block/radio_front.png | Bin .../openfm/textures/block/radio_side.png | Bin .../openfm/textures/block/speaker_front.png | Bin .../openfm/textures/block/speaker_side.png | Bin .../assets/openfm/textures/gui/buttons.png | Bin .../assets/openfm/textures/gui/gui_radio.png | Bin .../openfm/textures/item/memory_card.png | Bin .../assets/openfm/textures/item/tuner.png | Bin .../src}/main/resources/pack.mcmeta | 0 fabric/build.gradle | 39 ++++++++ .../openfm/fabric/FabricClientBridge.java | 16 ++++ .../openfm/fabric/FabricClientConfig.java | 49 ++++++++++ .../openfm/fabric/FabricComputerCraft.java | 15 +++ .../michiyo/openfm/fabric/FabricNetwork.java | 33 +++++++ .../michiyo/openfm/fabric/FabricPlatform.java | 42 ++++++++ .../openfm/fabric/FabricRegistrar.java | 60 ++++++++++++ .../michiyo/openfm/fabric/OpenFMFabric.java | 18 ++++ .../openfm/fabric/OpenFMFabricClient.java | 26 +++++ .../me.michiyo.openfm.platform.OpenFMPlatform | 2 + fabric/src/main/resources/fabric.mod.json | 24 +++++ gradle.properties | 28 ++++-- gradle/wrapper/gradle-wrapper.properties | 2 +- neoforge/build.gradle | 32 +++++++ .../openfm/neoforge/NeoForgeClientConfig.java | 21 ++++ .../openfm/neoforge/NeoForgeClientEvents.java | 44 +++++++++ .../neoforge/NeoForgeComputerCraft.java | 16 ++++ .../openfm/neoforge/NeoForgeNetwork.java | 28 ++++++ .../openfm/neoforge/NeoForgePlatform.java | 31 ++++++ .../openfm/neoforge/NeoForgeRegistrar.java | 73 ++++++++++++++ .../openfm/neoforge/OpenFMNeoForge.java | 30 ++++++ .../resources/META-INF/neoforge.mods.toml | 13 +-- .../me.michiyo.openfm.platform.OpenFMPlatform | 1 + settings.gradle | 31 +++++- src/main/java/me/michiyo/openfm/OpenFM.java | 36 ------- .../openfm/client/ClientForgeEvents.java | 19 ---- .../openfm/client/ClientModEvents.java | 32 ------- .../michiyo/openfm/client/OpenFMClient.java | 33 ------- .../openfm/compat/cc/ComputerCraftCompat.java | 17 ---- .../openfm/config/OpenFMClientConfig.java | 27 ------ src/main/java/me/michiyo/openfm/net/Net.java | 24 ----- .../michiyo/openfm/reg/ModBlockEntities.java | 22 ----- .../java/me/michiyo/openfm/reg/ModBlocks.java | 22 ----- .../michiyo/openfm/reg/ModCreativeTabs.java | 27 ------ .../java/me/michiyo/openfm/reg/ModItems.java | 28 ------ .../java/me/michiyo/openfm/reg/ModMenus.java | 17 ---- 100 files changed, 1155 insertions(+), 484 deletions(-) create mode 100644 buildSrc/build.gradle create mode 100644 buildSrc/src/main/groovy/multiloader-common.gradle create mode 100644 buildSrc/src/main/groovy/multiloader-loader.gradle create mode 100644 common/build.gradle rename {src => common/src}/main/java/me/michiyo/openfm.zip (100%) create mode 100644 common/src/main/java/me/michiyo/openfm/OpenFM.java create mode 100644 common/src/main/java/me/michiyo/openfm/client/ClientEvents.java create mode 100644 common/src/main/java/me/michiyo/openfm/client/OpenFMClient.java rename {src => common/src}/main/java/me/michiyo/openfm/client/audio/AacDecoder.java (100%) rename {src => common/src}/main/java/me/michiyo/openfm/client/audio/DecoderFactory.java (100%) rename {src => common/src}/main/java/me/michiyo/openfm/client/audio/Mp3Decoder.java (100%) rename {src => common/src}/main/java/me/michiyo/openfm/client/audio/OggVorbisDecoder.java (100%) rename {src => common/src}/main/java/me/michiyo/openfm/client/audio/PcmDecoder.java (100%) rename {src => common/src}/main/java/me/michiyo/openfm/client/audio/RadioStreamManager.java (100%) rename {src => common/src}/main/java/me/michiyo/openfm/client/audio/RadioStreamPlayer.java (100%) rename {src => common/src}/main/java/me/michiyo/openfm/client/gui/TexturedButton.java (100%) rename {src => common/src}/main/java/me/michiyo/openfm/client/render/RadioBlockEntityRenderer.java (100%) rename {src => common/src}/main/java/me/michiyo/openfm/client/screen/OpenFMAudioSettingsScreen.java (100%) rename {src => common/src}/main/java/me/michiyo/openfm/client/screen/RadioScreen.java (97%) rename {src => common/src}/main/java/me/michiyo/openfm/compat/cc/CCEvents.java (100%) rename {src => common/src}/main/java/me/michiyo/openfm/compat/cc/OpenFMRadioPeripheral.java (100%) create mode 100644 common/src/main/java/me/michiyo/openfm/config/OpenFMClientConfig.java rename {src => common/src}/main/java/me/michiyo/openfm/net/C2SButtonAction.java (95%) rename {src => common/src}/main/java/me/michiyo/openfm/net/C2SLinkSpeaker.java (95%) rename {src => common/src}/main/java/me/michiyo/openfm/net/C2SSetFields.java (93%) rename {src => common/src}/main/java/me/michiyo/openfm/net/MemoryCardLogic.java (100%) create mode 100644 common/src/main/java/me/michiyo/openfm/net/Net.java rename {src => common/src}/main/java/me/michiyo/openfm/net/S2CSyncFields.java (91%) create mode 100644 common/src/main/java/me/michiyo/openfm/platform/OpenFMPlatform.java create mode 100644 common/src/main/java/me/michiyo/openfm/platform/OpenFMRegistrar.java create mode 100644 common/src/main/java/me/michiyo/openfm/platform/RegistrySupplier.java create mode 100644 common/src/main/java/me/michiyo/openfm/platform/Services.java create mode 100644 common/src/main/java/me/michiyo/openfm/reg/ModBlockEntities.java create mode 100644 common/src/main/java/me/michiyo/openfm/reg/ModBlocks.java create mode 100644 common/src/main/java/me/michiyo/openfm/reg/ModCreativeTabs.java create mode 100644 common/src/main/java/me/michiyo/openfm/reg/ModItems.java create mode 100644 common/src/main/java/me/michiyo/openfm/reg/ModMenus.java rename {src => common/src}/main/java/me/michiyo/openfm/world/be/RadioBlockEntity.java (94%) rename {src => common/src}/main/java/me/michiyo/openfm/world/be/SpeakerBlockEntity.java (92%) rename {src => common/src}/main/java/me/michiyo/openfm/world/block/RadioBlock.java (96%) rename {src => common/src}/main/java/me/michiyo/openfm/world/block/SpeakerBlock.java (100%) rename {src => common/src}/main/java/me/michiyo/openfm/world/item/OpenFMTunerItem.java (100%) rename {src => common/src}/main/java/me/michiyo/openfm/world/menu/RadioMenu.java (100%) rename {src => common/src}/main/resources/assets/openfm/blockstates/radio_block.json (100%) rename {src => common/src}/main/resources/assets/openfm/blockstates/speaker_block.json (100%) rename {src => common/src}/main/resources/assets/openfm/lang/en_us.json (100%) rename {src => common/src}/main/resources/assets/openfm/models/block/radio_block.json (100%) rename {src => common/src}/main/resources/assets/openfm/models/block/speaker_block.json (100%) rename {src => common/src}/main/resources/assets/openfm/models/item/memory_card.json (100%) rename {src => common/src}/main/resources/assets/openfm/models/item/radio_block.json (100%) rename {src => common/src}/main/resources/assets/openfm/models/item/speaker_block.json (100%) rename {src => common/src}/main/resources/assets/openfm/models/item/tuner.json (100%) rename {src => common/src}/main/resources/assets/openfm/textures/block/radio_front.png (100%) rename {src => common/src}/main/resources/assets/openfm/textures/block/radio_side.png (100%) rename {src => common/src}/main/resources/assets/openfm/textures/block/speaker_front.png (100%) rename {src => common/src}/main/resources/assets/openfm/textures/block/speaker_side.png (100%) rename {src => common/src}/main/resources/assets/openfm/textures/gui/buttons.png (100%) rename {src => common/src}/main/resources/assets/openfm/textures/gui/gui_radio.png (100%) rename {src => common/src}/main/resources/assets/openfm/textures/item/memory_card.png (100%) rename {src => common/src}/main/resources/assets/openfm/textures/item/tuner.png (100%) rename {src => common/src}/main/resources/pack.mcmeta (100%) create mode 100644 fabric/build.gradle create mode 100644 fabric/src/main/java/me/michiyo/openfm/fabric/FabricClientBridge.java create mode 100644 fabric/src/main/java/me/michiyo/openfm/fabric/FabricClientConfig.java create mode 100644 fabric/src/main/java/me/michiyo/openfm/fabric/FabricComputerCraft.java create mode 100644 fabric/src/main/java/me/michiyo/openfm/fabric/FabricNetwork.java create mode 100644 fabric/src/main/java/me/michiyo/openfm/fabric/FabricPlatform.java create mode 100644 fabric/src/main/java/me/michiyo/openfm/fabric/FabricRegistrar.java create mode 100644 fabric/src/main/java/me/michiyo/openfm/fabric/OpenFMFabric.java create mode 100644 fabric/src/main/java/me/michiyo/openfm/fabric/OpenFMFabricClient.java create mode 100644 fabric/src/main/resources/META-INF/services/me.michiyo.openfm.platform.OpenFMPlatform create mode 100644 fabric/src/main/resources/fabric.mod.json create mode 100644 neoforge/build.gradle create mode 100644 neoforge/src/main/java/me/michiyo/openfm/neoforge/NeoForgeClientConfig.java create mode 100644 neoforge/src/main/java/me/michiyo/openfm/neoforge/NeoForgeClientEvents.java create mode 100644 neoforge/src/main/java/me/michiyo/openfm/neoforge/NeoForgeComputerCraft.java create mode 100644 neoforge/src/main/java/me/michiyo/openfm/neoforge/NeoForgeNetwork.java create mode 100644 neoforge/src/main/java/me/michiyo/openfm/neoforge/NeoForgePlatform.java create mode 100644 neoforge/src/main/java/me/michiyo/openfm/neoforge/NeoForgeRegistrar.java create mode 100644 neoforge/src/main/java/me/michiyo/openfm/neoforge/OpenFMNeoForge.java rename {src => neoforge/src}/main/resources/META-INF/neoforge.mods.toml (69%) create mode 100644 neoforge/src/main/resources/META-INF/services/me.michiyo.openfm.platform.OpenFMPlatform delete mode 100644 src/main/java/me/michiyo/openfm/OpenFM.java delete mode 100644 src/main/java/me/michiyo/openfm/client/ClientForgeEvents.java delete mode 100644 src/main/java/me/michiyo/openfm/client/ClientModEvents.java delete mode 100644 src/main/java/me/michiyo/openfm/client/OpenFMClient.java delete mode 100644 src/main/java/me/michiyo/openfm/compat/cc/ComputerCraftCompat.java delete mode 100644 src/main/java/me/michiyo/openfm/config/OpenFMClientConfig.java delete mode 100644 src/main/java/me/michiyo/openfm/net/Net.java delete mode 100644 src/main/java/me/michiyo/openfm/reg/ModBlockEntities.java delete mode 100644 src/main/java/me/michiyo/openfm/reg/ModBlocks.java delete mode 100644 src/main/java/me/michiyo/openfm/reg/ModCreativeTabs.java delete mode 100644 src/main/java/me/michiyo/openfm/reg/ModItems.java delete mode 100644 src/main/java/me/michiyo/openfm/reg/ModMenus.java diff --git a/.gitignore b/.gitignore index 12f8644..9746858 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ build # other eclipse run +runs # Files from Forge MDK forge*changelog.txt diff --git a/README.md b/README.md index 09c8940..c02b03f 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,43 @@ # OpenFM -Streaming radio for Minecraft, with OpenComputers, and ComputerCraft support. +OpenFM adds streaming internet radio blocks and linked speakers to Minecraft 1.21.1, with optional CC:Tweaked peripheral support. -fm = component.openfm_radio +## Loaders -fm.setURL("http://listen.radionomy.com/DeepHouse") +OpenFM is maintained as a multi-loader project: -fm.start() +- `common` contains shared gameplay, networking payloads, UI, rendering, and streaming audio code. +- `neoforge` contains the NeoForge entrypoint and loader integrations. +- `fabric` contains the Fabric entrypoints and loader integrations. -fm.stop() +The loader modules compile the same common sources. Loader-specific behavior is kept behind the registration and platform service interfaces under `me.michiyo.openfm.platform`. -fm.volUp() +## Building -fm.volDown() +Java 21 is required. -fm.getVol() +```powershell +.\gradlew.bat :neoforge:build :fabric:build +``` -fm.setScreenColor(0xFF0000) Sets the text color to red on the display +The distributable JARs are written to: -fm.setScreenText("Text to display on radio") Text will scroll if larger than the display. +- `neoforge/build/libs/openfm-neoforge-1.21.1-.jar` +- `fabric/build/libs/openfm-fabric-1.21.1-.jar` +Both JARs embed the MP3, Ogg Vorbis, and AAC decoder libraries. The Fabric build requires Fabric API. CC:Tweaked is optional on both loaders. -Highly modified version of Dragon's Radio Mod, Dragon's Radio Mod is Licenses MIT. +## Development runs -Downloads via Curse http://www.curse.com/mc-mods/Minecraft/236839-openfm +```powershell +.\gradlew.bat :neoforge:runClient +.\gradlew.bat :neoforge:runServer +.\gradlew.bat :fabric:runClient +.\gradlew.bat :fabric:runServer +``` + +## CC:Tweaked + +When CC:Tweaked is installed, the radio is exposed as an OpenFM peripheral. Existing Lua-facing methods and events are shared between both loader builds. + +OpenFM is a heavily modified version of Dragon's Radio Mod. Both projects are licensed under the MIT License. diff --git a/build.gradle b/build.gradle index ff14282..8b2a8f6 100644 --- a/build.gradle +++ b/build.gradle @@ -1,90 +1,4 @@ plugins { - id 'java-library' - id 'idea' - id 'maven-publish' - id 'net.neoforged.gradle.userdev' version '7.1.36' -} - -group = project.mod_group_id -version = project.mod_version - -base { - archivesName = project.mod_id -} - -java.toolchain.languageVersion = JavaLanguageVersion.of(21) - -runs { - configureEach { - systemProperty 'forge.logging.console.level', 'debug' - workingDirectory project.layout.projectDirectory.dir('run').dir(name) - modSource project.sourceSets.main - dependencies { - runtime "javazoom:jlayer:1.0.1" - runtime "org.jcraft:jorbis:0.0.17" - runtime "com.tianscar.javasound:jaad:0.9.4" - } - } - - client {} - - server { - argument '--nogui' - } -} - -configurations { - runtimeClasspath.extendsFrom localRuntime -} - -repositories { - mavenCentral() - - // CC:Tweaked Maven (note: maven.squiddev.cc, NOT squiddev.cc/maven) - maven { - url "https://maven.squiddev.cc" - content { includeGroup "cc.tweaked" } - } -} - -dependencies { - implementation "net.neoforged:neoforge:${project.neo_version}" - - // Compile against and embed the stream decoder libraries in the distributable mod jar. - jarJar(implementation("javazoom:jlayer:[1.0.1]")) { - version { prefer "1.0.1" } - } - jarJar(implementation("org.jcraft:jorbis:[0.0.17]")) { - version { prefer "0.0.17" } - } - jarJar(implementation("com.tianscar.javasound:jaad:[0.9.4]")) { - version { prefer "0.9.4" } - } - - // CC:Tweaked still publishes its 1.21.1 NeoForge-compatible build under the forge classifier. - compileOnly "cc.tweaked:cc-tweaked-${project.minecraft_version}-core-api:${project.cc_tweaked_version}" - compileOnly "cc.tweaked:cc-tweaked-${project.minecraft_version}-forge-api:${project.cc_tweaked_version}" - localRuntime "cc.tweaked:cc-tweaked-${project.minecraft_version}-forge:${project.cc_tweaked_version}" - -} - -tasks.withType(ProcessResources).configureEach { - def replaceProperties = [ - minecraft_version_range: minecraft_version_range, - neo_version: neo_version, - loader_version_range: loader_version_range, - mod_id: mod_id, - mod_name: mod_name, - mod_license: mod_license, - mod_version: mod_version, - cc_tweaked_version: cc_tweaked_version - ] - inputs.properties replaceProperties - filesMatching('META-INF/neoforge.mods.toml') { - expand replaceProperties - } -} - -tasks.withType(JavaCompile).configureEach { - options.encoding = 'UTF-8' + id 'fabric-loom' version '1.8-SNAPSHOT' apply false + id 'net.neoforged.moddev' version '2.0.49-beta' apply false } diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle new file mode 100644 index 0000000..afdd0b1 --- /dev/null +++ b/buildSrc/build.gradle @@ -0,0 +1,4 @@ +plugins { + id 'groovy-gradle-plugin' +} + diff --git a/buildSrc/src/main/groovy/multiloader-common.gradle b/buildSrc/src/main/groovy/multiloader-common.gradle new file mode 100644 index 0000000..3983004 --- /dev/null +++ b/buildSrc/src/main/groovy/multiloader-common.gradle @@ -0,0 +1,77 @@ +plugins { + id 'java-library' + id 'maven-publish' +} + +base { + archivesName = "${mod_id}-${project.name}-${minecraft_version}" +} + +java { + toolchain.languageVersion = JavaLanguageVersion.of(java_version) + withSourcesJar() +} + +repositories { + mavenCentral() + maven { + name = 'CC-Tweaked' + url = 'https://maven.squiddev.cc' + content { includeGroup 'cc.tweaked' } + } + exclusiveContent { + forRepositories( + maven { + name = 'ParchmentMC' + url = 'https://maven.parchmentmc.org/' + }, + maven { + name = 'NeoForge' + url = 'https://maven.neoforged.net/releases' + } + ) + filter { includeGroup 'org.parchmentmc.data' } + } +} + +['apiElements', 'runtimeElements', 'sourcesElements'].each { variant -> + configurations."$variant".outgoing { + capability("$group:${base.archivesName.get()}:$version") + capability("$group:$mod_id-${project.name}-${minecraft_version}:$version") + capability("$group:$mod_id:$version") + } + publishing.publications.configureEach { + suppressPomMetadataWarningsFor(variant) + } +} + +tasks.withType(Jar).configureEach { + from(rootProject.file('LICENSE')) { + rename { "${it}_${mod_name}" } + } +} + +processResources { + def expandProps = [ + version: version, + minecraft_version: minecraft_version, + minecraft_version_range: minecraft_version_range, + fabric_version: fabric_version, + fabric_loader_version: fabric_loader_version, + mod_name: mod_name, + mod_author: mod_author, + mod_id: mod_id, + license: license, + description: project.description, + neoforge_version: neoforge_version, + neoforge_loader_version_range: neoforge_loader_version_range, + cc_tweaked_version: cc_tweaked_version, + credits: credits, + java_version: java_version + ] + filesMatching(['pack.mcmeta', 'fabric.mod.json', 'META-INF/neoforge.mods.toml']) { + expand expandProps + } + inputs.properties(expandProps) +} + diff --git a/buildSrc/src/main/groovy/multiloader-loader.gradle b/buildSrc/src/main/groovy/multiloader-loader.gradle new file mode 100644 index 0000000..467b08c --- /dev/null +++ b/buildSrc/src/main/groovy/multiloader-loader.gradle @@ -0,0 +1,34 @@ +plugins { + id 'multiloader-common' +} + +configurations { + commonJava { canBeResolved = true } + commonResources { canBeResolved = true } +} + +dependencies { + compileOnly(project(':common')) { + capabilities { requireCapability "$group:$mod_id" } + } + commonJava project(path: ':common', configuration: 'commonJava') + commonResources project(path: ':common', configuration: 'commonResources') +} + +tasks.named('compileJava', JavaCompile) { + dependsOn(configurations.commonJava) + source(configurations.commonJava) +} + +processResources { + dependsOn(configurations.commonResources) + from(configurations.commonResources) +} + +tasks.named('sourcesJar', Jar) { + dependsOn(configurations.commonJava) + from(configurations.commonJava) + dependsOn(configurations.commonResources) + from(configurations.commonResources) +} + diff --git a/common/build.gradle b/common/build.gradle new file mode 100644 index 0000000..3d3b4e4 --- /dev/null +++ b/common/build.gradle @@ -0,0 +1,36 @@ +plugins { + id 'multiloader-common' + id 'net.neoforged.moddev' +} + +neoForge { + neoFormVersion = neo_form_version + parchment { + minecraftVersion = parchment_minecraft + mappingsVersion = parchment_version + } +} + +dependencies { + api 'javazoom:jlayer:1.0.1' + api 'org.jcraft:jorbis:0.0.17' + api 'com.tianscar.javasound:jaad:0.9.4' + compileOnly "cc.tweaked:cc-tweaked-${minecraft_version}-core-api:${cc_tweaked_version}" +} + +configurations { + commonJava { + canBeResolved = false + canBeConsumed = true + } + commonResources { + canBeResolved = false + canBeConsumed = true + } +} + +artifacts { + commonJava sourceSets.main.java.sourceDirectories.singleFile + commonResources sourceSets.main.resources.sourceDirectories.singleFile +} + diff --git a/src/main/java/me/michiyo/openfm.zip b/common/src/main/java/me/michiyo/openfm.zip similarity index 100% rename from src/main/java/me/michiyo/openfm.zip rename to common/src/main/java/me/michiyo/openfm.zip diff --git a/common/src/main/java/me/michiyo/openfm/OpenFM.java b/common/src/main/java/me/michiyo/openfm/OpenFM.java new file mode 100644 index 0000000..87c9697 --- /dev/null +++ b/common/src/main/java/me/michiyo/openfm/OpenFM.java @@ -0,0 +1,27 @@ +package me.michiyo.openfm; + +import me.michiyo.openfm.platform.OpenFMRegistrar; +import me.michiyo.openfm.reg.ModBlockEntities; +import me.michiyo.openfm.reg.ModBlocks; +import me.michiyo.openfm.reg.ModCreativeTabs; +import me.michiyo.openfm.reg.ModItems; +import me.michiyo.openfm.reg.ModMenus; + +public final class OpenFM { + public static final String MODID = "openfm"; + private static boolean initialized; + + public static synchronized void init(OpenFMRegistrar registrar) { + if (initialized) return; + + ModBlocks.register(registrar); + ModItems.register(registrar); + ModBlockEntities.register(registrar); + ModMenus.register(registrar); + ModCreativeTabs.register(registrar); + initialized = true; + } + + private OpenFM() {} +} + diff --git a/common/src/main/java/me/michiyo/openfm/client/ClientEvents.java b/common/src/main/java/me/michiyo/openfm/client/ClientEvents.java new file mode 100644 index 0000000..521dc7e --- /dev/null +++ b/common/src/main/java/me/michiyo/openfm/client/ClientEvents.java @@ -0,0 +1,12 @@ +package me.michiyo.openfm.client; + +import me.michiyo.openfm.client.audio.RadioStreamManager; + +public final class ClientEvents { + public static void clientTick() { + RadioStreamManager.clientTick(); + } + + private ClientEvents() {} +} + diff --git a/common/src/main/java/me/michiyo/openfm/client/OpenFMClient.java b/common/src/main/java/me/michiyo/openfm/client/OpenFMClient.java new file mode 100644 index 0000000..1b2d2be --- /dev/null +++ b/common/src/main/java/me/michiyo/openfm/client/OpenFMClient.java @@ -0,0 +1,27 @@ +package me.michiyo.openfm.client; + +import me.michiyo.openfm.client.screen.OpenFMAudioSettingsScreen; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.gui.screens.options.OptionsScreen; +import net.minecraft.network.chat.Component; + +import java.util.function.Consumer; + +public final class OpenFMClient { + public static void addSettingsButton(Screen screen, Consumer