From 42a996ea247cdc7a64d6c0b21bfdb33313d6ea0b Mon Sep 17 00:00:00 2001 From: Xujiayao Date: Thu, 31 Jul 2025 21:16:54 +0800 Subject: [PATCH] Fabric NeoForge setup --- fabric/build.gradle | 50 ++++++++ fabric/gradle.properties | 4 + .../discord_mc_chat/fabric/DiscordMCChat.java | 24 ++++ .../fabric/mixin/ExampleMixin.java | 18 +++ .../resources/assets/discord_mc_chat/icon.png | Bin 0 -> 2953 bytes .../resources/discord_mc_chat.mixins.json | 14 +++ fabric/src/main/resources/fabric.mod.json | 33 +++++ gradle.properties | 10 ++ neoforge/build.gradle | 64 ++++++++++ neoforge/gradle.properties | 8 ++ .../discord_mc_chat/neoforge/Config.java | 36 ++++++ .../neoforge/DiscordMCChat.java | 116 ++++++++++++++++++ .../neoforge/DiscordMCChatClient.java | 31 +++++ .../neoforge/mixin/ExampleMixin.java | 18 +++ .../resources/META-INF/neoforge.mods.toml | 81 ++++++++++++ .../resources/discord_mc_chat.mixins.json | 14 +++ settings.gradle | 15 +++ 17 files changed, 536 insertions(+) create mode 100644 fabric/build.gradle create mode 100644 fabric/gradle.properties create mode 100644 fabric/src/main/java/com/xujiayao/discord_mc_chat/fabric/DiscordMCChat.java create mode 100644 fabric/src/main/java/com/xujiayao/discord_mc_chat/fabric/mixin/ExampleMixin.java create mode 100644 fabric/src/main/resources/assets/discord_mc_chat/icon.png create mode 100644 fabric/src/main/resources/discord_mc_chat.mixins.json create mode 100644 fabric/src/main/resources/fabric.mod.json create mode 100644 gradle.properties create mode 100644 neoforge/build.gradle create mode 100644 neoforge/gradle.properties create mode 100644 neoforge/src/main/java/com/xujiayao/discord_mc_chat/neoforge/Config.java create mode 100644 neoforge/src/main/java/com/xujiayao/discord_mc_chat/neoforge/DiscordMCChat.java create mode 100644 neoforge/src/main/java/com/xujiayao/discord_mc_chat/neoforge/DiscordMCChatClient.java create mode 100644 neoforge/src/main/java/com/xujiayao/discord_mc_chat/neoforge/mixin/ExampleMixin.java create mode 100644 neoforge/src/main/resources/META-INF/neoforge.mods.toml create mode 100644 neoforge/src/main/resources/discord_mc_chat.mixins.json create mode 100644 settings.gradle diff --git a/fabric/build.gradle b/fabric/build.gradle new file mode 100644 index 00000000..1fcc7dba --- /dev/null +++ b/fabric/build.gradle @@ -0,0 +1,50 @@ +plugins { + id "fabric-loom" version "${loom_version}" +} + +version = mod_version + +base { + archivesName = mod_name +} + +repositories { + // Add repositories to retrieve artifacts from in here. + // You should only use this when depending on other mods because + // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. + // See https://docs.gradle.org/current/userguide/declaring_repositories.html + // for more information about repositories. +} + +dependencies { + // To change the versions see the gradle.properties file + minecraft "com.mojang:minecraft:${minecraft_version}" + mappings loom.officialMojangMappings() + modImplementation "net.fabricmc:fabric-loader:${loader_version}" +} + +processResources { + inputs.property "version", version + + filesMatching("fabric.mod.json") { + expand "version": inputs.properties.version + } +} + +tasks.withType(JavaCompile).configureEach { + options.release = 21 + options.encoding = "UTF-8" +} + +java { + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 +} + +jar { + inputs.property "archivesName", base.archivesName + + from("LICENSE") { + rename { "${it}_${inputs.properties.archivesName}"} + } +} diff --git a/fabric/gradle.properties b/fabric/gradle.properties new file mode 100644 index 00000000..74635a35 --- /dev/null +++ b/fabric/gradle.properties @@ -0,0 +1,4 @@ +# Fabric Properties +# check these on https://fabricmc.net/develop +loader_version=0.16.14 +loom_version=1.11-SNAPSHOT diff --git a/fabric/src/main/java/com/xujiayao/discord_mc_chat/fabric/DiscordMCChat.java b/fabric/src/main/java/com/xujiayao/discord_mc_chat/fabric/DiscordMCChat.java new file mode 100644 index 00000000..c3fb33e3 --- /dev/null +++ b/fabric/src/main/java/com/xujiayao/discord_mc_chat/fabric/DiscordMCChat.java @@ -0,0 +1,24 @@ +package com.xujiayao.discord_mc_chat.fabric; + +import net.fabricmc.api.ModInitializer; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DiscordMCChat implements ModInitializer { + public static final String MOD_ID = "discord-mc-chat"; + + // This logger is used to write text to the console and the log file. + // It is considered best practice to use your mod id as the logger's name. + // That way, it's clear which mod wrote info, warnings, and errors. + public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); + + @Override + public void onInitialize() { + // This code runs as soon as Minecraft is in a mod-load-ready state. + // However, some things (like resources) may still be uninitialized. + // Proceed with mild caution. + + LOGGER.info("Hello Fabric world!"); + } +} \ No newline at end of file diff --git a/fabric/src/main/java/com/xujiayao/discord_mc_chat/fabric/mixin/ExampleMixin.java b/fabric/src/main/java/com/xujiayao/discord_mc_chat/fabric/mixin/ExampleMixin.java new file mode 100644 index 00000000..2a13a00b --- /dev/null +++ b/fabric/src/main/java/com/xujiayao/discord_mc_chat/fabric/mixin/ExampleMixin.java @@ -0,0 +1,18 @@ +package com.xujiayao.discord_mc_chat.fabric.mixin; + +import net.minecraft.server.MinecraftServer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import static com.xujiayao.discord_mc_chat.fabric.DiscordMCChat.LOGGER; + +@Mixin(MinecraftServer.class) +public class ExampleMixin { + @Inject(at = @At("HEAD"), method = "loadLevel") + private void init(CallbackInfo info) { + // This code is injected into the start of MinecraftServer.loadLevel()V + LOGGER.info("This line is printed by an example mod mixin!"); + } +} \ No newline at end of file diff --git a/fabric/src/main/resources/assets/discord_mc_chat/icon.png b/fabric/src/main/resources/assets/discord_mc_chat/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..7d0772cd341b35b3fd662d25f3edc31e3884fa4d GIT binary patch literal 2953 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 literal 0 HcmV?d00001 diff --git a/fabric/src/main/resources/discord_mc_chat.mixins.json b/fabric/src/main/resources/discord_mc_chat.mixins.json new file mode 100644 index 00000000..8787b30c --- /dev/null +++ b/fabric/src/main/resources/discord_mc_chat.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "package": "com.xujiayao.discord_mc_chat.fabric.mixin", + "compatibilityLevel": "JAVA_21", + "mixins": [ + "ExampleMixin" + ], + "injectors": { + "defaultRequire": 1 + }, + "overwrites": { + "requireAnnotations": true + } +} \ No newline at end of file diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json new file mode 100644 index 00000000..9b135662 --- /dev/null +++ b/fabric/src/main/resources/fabric.mod.json @@ -0,0 +1,33 @@ +{ + "schemaVersion": 1, + "id": "discord_mc_chat", + "version": "${version}", + "name": "Discord-MC-Chat", + "description": "Discord-MC-Chat (DMCC), formerly known as MC-Discord-Chat and MCDiscordChat (MCDC), is a practical and powerful Fabric and Quilt Minecraft <> Discord chat bridge inspired by BRForgers/DisFabric", + "authors": [ + "Me!" + ], + "contact": { + "homepage": "https://fabricmc.net/", + "sources": "https://github.com/FabricMC/fabric-example-mod" + }, + "license": "MIT", + "icon": "assets/discord_mc_chat/icon.png", + "environment": "*", + "entrypoints": { + "main": [ + "com.xujiayao.discord_mc_chat.fabric.DiscordMCChat" + ] + }, + "mixins": [ + "discord_mc_chat.mixins.json" + ], + "depends": { + "fabricloader": ">=0.16.14", + "minecraft": "~1.21.8", + "java": ">=21" + }, + "suggests": { + "another-mod": "*" + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000..15022cc9 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,10 @@ +# Done to increase the memory available to gradle. +org.gradle.jvmargs=-Xmx4G +org.gradle.parallel=true + +# Minecraft Properties +minecraft_version=1.21.8 + +# Mod Properties +mod_name=Discord-MC-Chat +mod_version=3.0.0-beta.1 diff --git a/neoforge/build.gradle b/neoforge/build.gradle new file mode 100644 index 00000000..7e6e56c7 --- /dev/null +++ b/neoforge/build.gradle @@ -0,0 +1,64 @@ +plugins { + id 'net.neoforged.moddev' version '2.0.105' +} + +version = mod_version + +repositories { + // Add here additional repositories if required by some of the dependencies below. +} + +base { + archivesName = mod_name +} + +// Mojang ships Java 21 to end users in 1.21.8, so mods should target Java 21. +java.toolchain.languageVersion = JavaLanguageVersion.of(21) + +neoForge { + // Specify the version of NeoForge to use. + version = neo_version +} + +dependencies { + // Example optional mod dependency with JEI + // The JEI API is declared for compile time use, while the full JEI artifact is used at runtime + // compileOnly "mezz.jei:jei-${mc_version}-common-api:${jei_version}" + // compileOnly "mezz.jei:jei-${mc_version}-neoforge-api:${jei_version}" + // We add the full version to localRuntime, not runtimeOnly, so that we do not publish a dependency on it + // localRuntime "mezz.jei:jei-${mc_version}-neoforge:${jei_version}" + + // Example mod dependency using a mod jar from ./libs with a flat dir repository + // This maps to ./libs/coolmod-${mc_version}-${coolmod_version}.jar + // The group id is ignored when searching -- in this case, it is "blank" + // implementation "blank:coolmod-${mc_version}:${coolmod_version}" + + // Example mod dependency using a file as dependency + // implementation files("libs/coolmod-${mc_version}-${coolmod_version}.jar") + + // Example project dependency using a sister or child project: + // implementation project(":myproject") + + // For more info: + // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html + // http://www.gradle.org/docs/current/userguide/dependency_management.html +} + +processResources { + var replaceProperties = [ + minecraft_version : minecraft_version, + minecraft_version_range: minecraft_version_range, + neo_version : neo_version, + mod_name : mod_name, + mod_version : mod_version + ] + inputs.properties replaceProperties + filesMatching("META-INF/neoforge.mods.toml") { + expand replaceProperties + } +} + +tasks.withType(JavaCompile).configureEach { + options.release = 21 + options.encoding = "UTF-8" +} diff --git a/neoforge/gradle.properties b/neoforge/gradle.properties new file mode 100644 index 00000000..fe04b84a --- /dev/null +++ b/neoforge/gradle.properties @@ -0,0 +1,8 @@ +# Environment Properties +# You can find the latest versions here: https://projects.neoforged.net/neoforged/neoforge +# The Minecraft version range can use any release version of Minecraft as bounds. +# Snapshots, pre-releases, and release candidates are not guaranteed to sort properly +# as they do not follow standard versioning conventions. +minecraft_version_range=[1.21.8] +# The Neo version must agree with the Minecraft version to get a valid artifact +neo_version=21.8.23 diff --git a/neoforge/src/main/java/com/xujiayao/discord_mc_chat/neoforge/Config.java b/neoforge/src/main/java/com/xujiayao/discord_mc_chat/neoforge/Config.java new file mode 100644 index 00000000..87c0da81 --- /dev/null +++ b/neoforge/src/main/java/com/xujiayao/discord_mc_chat/neoforge/Config.java @@ -0,0 +1,36 @@ +package com.xujiayao.discord_mc_chat.neoforge; + +import java.util.List; + +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.ResourceLocation; +import net.neoforged.neoforge.common.ModConfigSpec; + +// An example config class. This is not required, but it's a good idea to have one to keep your config organized. +// Demonstrates how to use Neo's config APIs +public class Config { + private static final ModConfigSpec.Builder BUILDER = new ModConfigSpec.Builder(); + + public static final ModConfigSpec.BooleanValue LOG_DIRT_BLOCK = BUILDER + .comment("Whether to log the dirt block on common setup") + .define("logDirtBlock", true); + + public static final ModConfigSpec.IntValue MAGIC_NUMBER = BUILDER + .comment("A magic number") + .defineInRange("magicNumber", 42, 0, Integer.MAX_VALUE); + + public static final ModConfigSpec.ConfigValue MAGIC_NUMBER_INTRODUCTION = BUILDER + .comment("What you want the introduction message to be for the magic number") + .define("magicNumberIntroduction", "The magic number is... "); + + // a list of strings that are treated as resource locations for items + public static final ModConfigSpec.ConfigValue> ITEM_STRINGS = BUILDER + .comment("A list of items to log on common setup.") + .defineListAllowEmpty("items", List.of("minecraft:iron_ingot"), () -> "", Config::validateItemName); + + static final ModConfigSpec SPEC = BUILDER.build(); + + private static boolean validateItemName(final Object obj) { + return obj instanceof String itemName && BuiltInRegistries.ITEM.containsKey(ResourceLocation.parse(itemName)); + } +} diff --git a/neoforge/src/main/java/com/xujiayao/discord_mc_chat/neoforge/DiscordMCChat.java b/neoforge/src/main/java/com/xujiayao/discord_mc_chat/neoforge/DiscordMCChat.java new file mode 100644 index 00000000..7066339d --- /dev/null +++ b/neoforge/src/main/java/com/xujiayao/discord_mc_chat/neoforge/DiscordMCChat.java @@ -0,0 +1,116 @@ +package com.xujiayao.discord_mc_chat.neoforge; + +import org.slf4j.Logger; + +import com.mojang.logging.LogUtils; + +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.chat.Component; +import net.minecraft.world.food.FoodProperties; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.CreativeModeTabs; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.material.MapColor; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.Mod; +import net.neoforged.fml.config.ModConfig; +import net.neoforged.fml.ModContainer; +import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; +import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent; +import net.neoforged.neoforge.event.server.ServerStartingEvent; +import net.neoforged.neoforge.registries.DeferredBlock; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredItem; +import net.neoforged.neoforge.registries.DeferredRegister; + +// The value here should match an entry in the META-INF/neoforge.mods.toml file +@Mod(DiscordMCChat.MODID) +public class DiscordMCChat { + // Define mod id in a common place for everything to reference + public static final String MODID = "discord_mc_chat"; + // Directly reference a slf4j logger + public static final Logger LOGGER = LogUtils.getLogger(); + // Create a Deferred Register to hold Blocks which will all be registered under the "discord_mc_chat" namespace + public static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks(MODID); + // Create a Deferred Register to hold Items which will all be registered under the "discord_mc_chat" namespace + public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(MODID); + // Create a Deferred Register to hold CreativeModeTabs which will all be registered under the "discord_mc_chat" namespace + public static final DeferredRegister CREATIVE_MODE_TABS = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, MODID); + + // Creates a new Block with the id "discord_mc_chat:example_block", combining the namespace and path + public static final DeferredBlock EXAMPLE_BLOCK = BLOCKS.registerSimpleBlock("example_block", BlockBehaviour.Properties.of().mapColor(MapColor.STONE)); + // Creates a new BlockItem with the id "discord_mc_chat:example_block", combining the namespace and path + public static final DeferredItem EXAMPLE_BLOCK_ITEM = ITEMS.registerSimpleBlockItem("example_block", EXAMPLE_BLOCK); + + // Creates a new food item with the id "discord_mc_chat:example_id", nutrition 1 and saturation 2 + public static final DeferredItem EXAMPLE_ITEM = ITEMS.registerSimpleItem("example_item", new Item.Properties().food(new FoodProperties.Builder() + .alwaysEdible().nutrition(1).saturationModifier(2f).build())); + + // Creates a creative tab with the id "discord_mc_chat:example_tab" for the example item, that is placed after the combat tab + public static final DeferredHolder EXAMPLE_TAB = CREATIVE_MODE_TABS.register("example_tab", () -> CreativeModeTab.builder() + .title(Component.translatable("itemGroup.discord_mc_chat")) //The language key for the title of your CreativeModeTab + .withTabsBefore(CreativeModeTabs.COMBAT) + .icon(() -> EXAMPLE_ITEM.get().getDefaultInstance()) + .displayItems((parameters, output) -> { + output.accept(EXAMPLE_ITEM.get()); // Add the example item to the tab. For your own tabs, this method is preferred over the event + }).build()); + + // The constructor for the mod class is the first code that is run when your mod is loaded. + // FML will recognize some parameter types like IEventBus or ModContainer and pass them in automatically. + public DiscordMCChat(IEventBus modEventBus, ModContainer modContainer) { + // Register the commonSetup method for modloading + modEventBus.addListener(this::commonSetup); + + // Register the Deferred Register to the mod event bus so blocks get registered + BLOCKS.register(modEventBus); + // Register the Deferred Register to the mod event bus so items get registered + ITEMS.register(modEventBus); + // Register the Deferred Register to the mod event bus so tabs get registered + CREATIVE_MODE_TABS.register(modEventBus); + + // Register ourselves for server and other game events we are interested in. + // Note that this is necessary if and only if we want *this* class (DiscordMCChat) to respond directly to events. + // Do not add this line if there are no @SubscribeEvent-annotated functions in this class, like onServerStarting() below. + NeoForge.EVENT_BUS.register(this); + + // Register the item to a creative tab + modEventBus.addListener(this::addCreative); + + // Register our mod's ModConfigSpec so that FML can create and load the config file for us + modContainer.registerConfig(ModConfig.Type.COMMON, Config.SPEC); + } + + private void commonSetup(FMLCommonSetupEvent event) { + // Some common setup code + LOGGER.info("HELLO FROM COMMON SETUP"); + + if (Config.LOG_DIRT_BLOCK.getAsBoolean()) { + LOGGER.info("DIRT BLOCK >> {}", BuiltInRegistries.BLOCK.getKey(Blocks.DIRT)); + } + + LOGGER.info("{}{}", Config.MAGIC_NUMBER_INTRODUCTION.get(), Config.MAGIC_NUMBER.getAsInt()); + + Config.ITEM_STRINGS.get().forEach((item) -> LOGGER.info("ITEM >> {}", item)); + } + + // Add the example block item to the building blocks tab + private void addCreative(BuildCreativeModeTabContentsEvent event) { + if (event.getTabKey() == CreativeModeTabs.BUILDING_BLOCKS) { + event.accept(EXAMPLE_BLOCK_ITEM); + } + } + + // You can use SubscribeEvent and let the Event Bus discover methods to call + @SubscribeEvent + public void onServerStarting(ServerStartingEvent event) { + // Do something when the server starts + LOGGER.info("HELLO from server starting"); + } +} diff --git a/neoforge/src/main/java/com/xujiayao/discord_mc_chat/neoforge/DiscordMCChatClient.java b/neoforge/src/main/java/com/xujiayao/discord_mc_chat/neoforge/DiscordMCChatClient.java new file mode 100644 index 00000000..a0ca74b4 --- /dev/null +++ b/neoforge/src/main/java/com/xujiayao/discord_mc_chat/neoforge/DiscordMCChatClient.java @@ -0,0 +1,31 @@ +package com.xujiayao.discord_mc_chat.neoforge; + +import net.minecraft.client.Minecraft; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.ModContainer; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.fml.common.Mod; +import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; +import net.neoforged.neoforge.client.gui.ConfigurationScreen; +import net.neoforged.neoforge.client.gui.IConfigScreenFactory; + +// This class will not load on dedicated servers. Accessing client side code from here is safe. +@Mod(value = DiscordMCChat.MODID, dist = Dist.CLIENT) +// You can use EventBusSubscriber to automatically register all static methods in the class annotated with @SubscribeEvent +@EventBusSubscriber(modid = DiscordMCChat.MODID, value = Dist.CLIENT) +public class DiscordMCChatClient { + public DiscordMCChatClient(ModContainer container) { + // Allows NeoForge to create a config screen for this mod's configs. + // The config screen is accessed by going to the Mods screen > clicking on your mod > clicking on config. + // Do not forget to add translations for your config options to the en_us.json file. + container.registerExtensionPoint(IConfigScreenFactory.class, ConfigurationScreen::new); + } + + @SubscribeEvent + static void onClientSetup(FMLClientSetupEvent event) { + // Some client setup code + DiscordMCChat.LOGGER.info("HELLO FROM CLIENT SETUP"); + DiscordMCChat.LOGGER.info("MINECRAFT NAME >> {}", Minecraft.getInstance().getUser().getName()); + } +} diff --git a/neoforge/src/main/java/com/xujiayao/discord_mc_chat/neoforge/mixin/ExampleMixin.java b/neoforge/src/main/java/com/xujiayao/discord_mc_chat/neoforge/mixin/ExampleMixin.java new file mode 100644 index 00000000..b00d6e1f --- /dev/null +++ b/neoforge/src/main/java/com/xujiayao/discord_mc_chat/neoforge/mixin/ExampleMixin.java @@ -0,0 +1,18 @@ +package com.xujiayao.discord_mc_chat.neoforge.mixin; + +import net.minecraft.server.MinecraftServer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import static com.xujiayao.discord_mc_chat.neoforge.DiscordMCChat.LOGGER; + +@Mixin(MinecraftServer.class) +public class ExampleMixin { + @Inject(at = @At("HEAD"), method = "loadLevel") + private void init(CallbackInfo info) { + // This code is injected into the start of MinecraftServer.loadLevel()V + LOGGER.info("This line is printed by an example mod mixin!"); + } +} \ No newline at end of file diff --git a/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/neoforge/src/main/resources/META-INF/neoforge.mods.toml new file mode 100644 index 00000000..6ed01c1c --- /dev/null +++ b/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -0,0 +1,81 @@ +# This is an example neoforge.mods.toml file. It contains the data relating to the loading mods. +# There are several mandatory fields (#mandatory), and many more that are optional (#optional). +# The overall format is standard TOML format, v0.5.0. +# Note that there are a couple of TOML lists in this file. +# Find more information on toml format here: https://github.com/toml-lang/toml + +# The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties. +# Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here. +license="MIT" + +# A URL to refer people to when problems occur with this mod +#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional + +# A list of mods - how many allowed here is determined by the individual mod loader +[[mods]] #mandatory + +# The modid of the mod +modId="discord_mc_chat" #mandatory + +# The version number of the mod +version="${mod_version}" #mandatory + +# A display name for the mod +displayName="${mod_name}" #mandatory + +# A URL to query for updates for this mod. See the JSON update specification https://docs.neoforged.net/docs/misc/updatechecker/ +#updateJSONURL="https://change.me.example.invalid/updates.json" #optional + +# A URL for the "homepage" for this mod, displayed in the mod UI +#displayURL="https://change.me.to.your.mods.homepage.example.invalid/" #optional + +# A file name (in the root of the mod JAR) containing a logo for display +#logoFile="examplemod.png" #optional + +# A text field displayed in the mod UI +#credits="" #optional + +# A text field displayed in the mod UI +authors="Xujiayao" #optional + +# The description text for the mod (multi line!) (#mandatory) +description='''Discord-MC-Chat (DMCC), formerly known as MC-Discord-Chat and MCDiscordChat (MCDC), is a practical and powerful Fabric and Quilt Minecraft <> Discord chat bridge inspired by BRForgers/DisFabric''' + +# The [[mixins]] block allows you to declare your mixin config to FML so that it gets loaded. +[[mixins]] +config="discord_mc_chat.mixins.json" + +# The [[accessTransformers]] block allows you to declare where your AT file is. +# If this block is omitted, a fallback attempt will be made to load an AT from META-INF/accesstransformer.cfg +#[[accessTransformers]] +#file="META-INF/accesstransformer.cfg" + +# The coremods config file path is not configurable and is always loaded from META-INF/coremods.json + +# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. +[[dependencies.discord_mc_chat]] #optional + # the modid of the dependency + modId="neoforge" #mandatory + # The type of the dependency. Can be one of "required", "optional", "incompatible" or "discouraged" (case insensitive). + # 'required' requires the mod to exist, 'optional' does not + # 'incompatible' will prevent the game from loading when the mod exists, and 'discouraged' will show a warning + type="required" #mandatory + # Optional field describing why the dependency is required or why it is incompatible + # reason="..." + # The version range of the dependency + versionRange="[${neo_version},)" #mandatory + # An ordering relationship for the dependency. + # BEFORE - This mod is loaded BEFORE the dependency + # AFTER - This mod is loaded AFTER the dependency + ordering="NONE" + # Side this dependency is applied on - BOTH, CLIENT, or SERVER + side="BOTH" + +# Here's another dependency +[[dependencies.discord_mc_chat]] + modId="minecraft" + type="required" + # This version range declares a minimum of the current minecraft version up to but not including the next major version + versionRange="${minecraft_version_range}" + ordering="NONE" + side="BOTH" diff --git a/neoforge/src/main/resources/discord_mc_chat.mixins.json b/neoforge/src/main/resources/discord_mc_chat.mixins.json new file mode 100644 index 00000000..8aaa3a1b --- /dev/null +++ b/neoforge/src/main/resources/discord_mc_chat.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "package": "com.xujiayao.discord_mc_chat.neoforge.mixin", + "compatibilityLevel": "JAVA_21", + "mixins": [ + "ExampleMixin" + ], + "injectors": { + "defaultRequire": 1 + }, + "overwrites": { + "requireAnnotations": true + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 00000000..a06a84fe --- /dev/null +++ b/settings.gradle @@ -0,0 +1,15 @@ +pluginManagement { + repositories { + maven { + name = "Fabric" + url = "https://maven.fabricmc.net/" + } + mavenCentral() + gradlePluginPortal() + } +} + +include(":common") + +include(":fabric") +include(":neoforge")