diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a70de66..9fef6a6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -97,6 +97,9 @@ jobs: matrix: mod-loader: ['fabric', 'forge'] mc-version: ['1.17.1', '1.18.2', '1.19.4'] + include: + - mod-loader: 'forge' + mc-version: '1.20.1' #exclude: # - mod-loader: 'forge' # mc-version: '1.17' @@ -155,11 +158,8 @@ jobs: strategy: fail-fast: false matrix: - mod-loader: ['fabric', 'forge'] + mod-loader: ['fabric', 'neoforge'] mc-version: ["1.20.6", "1.21", "1.21.3", "1.21.4"] - #exclude: - # - mod-loader: 'forge' - # mc-version: '1.17' steps: # Checks-out the repository under $GITHUB_WORKSPACE, so the job can access it diff --git a/MinecraftMod/forge/1.20.1/build.gradle b/MinecraftMod/forge/1.20.1/build.gradle index ed03cba..7e50c18 100644 --- a/MinecraftMod/forge/1.20.1/build.gradle +++ b/MinecraftMod/forge/1.20.1/build.gradle @@ -2,14 +2,14 @@ plugins { id 'eclipse' id 'idea' id 'maven-publish' - id 'net.neoforged.gradle' version '[6.0.18,6.2)' + id 'net.minecraftforge.gradle' version '[6.0,6.2)' } version = mod_version group = mod_group_id base { - archivesName = "effectmc-neoforge-${minecraft_version}" + archivesName = "effectmc-forge-${minecraft_version}" } // Enable Jar in Jar @@ -118,7 +118,7 @@ dependencies { // The "userdev" classifier will be requested and setup by ForgeGradle. // If the group id is "net.minecraft" and the artifact id is one of ["client", "server", "joined"], // then special handling is done to allow a setup of a vanilla dependency without the use of an external repository. - minecraft "net.neoforged:forge:${minecraft_version}-${forge_version}" + minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" implementation "com.mosadie.effectmc:core:${effectmc_core_version}" jarJar("com.mosadie.effectmc:core:${effectmc_core_version_range}") diff --git a/MinecraftMod/forge/1.20.1/gradle.properties b/MinecraftMod/forge/1.20.1/gradle.properties index 9bcd0c1..cb10db9 100644 --- a/MinecraftMod/forge/1.20.1/gradle.properties +++ b/MinecraftMod/forge/1.20.1/gradle.properties @@ -5,9 +5,9 @@ org.gradle.daemon=false # EffectMC Properties -effectmc_core_version=2.3 -effectmc_core_version_range=[2.2,3.0) -mod_version=2.3.0 +effectmc_core_version=3.1.0 +effectmc_core_version_range=[3.1.0,4.0.0) +mod_version=3.1.0 mod_id=effectmc mod_name=EffectMC @@ -27,7 +27,7 @@ minecraft_version=1.20.1 minecraft_version_range=[1.20.1,1.21) # The Forge version must agree with the Minecraft version to get a valid artifact -forge_version=47.1.81 +forge_version=47.0.50 # The Forge version range can use any version of Forge as bounds or match the loader version range forge_version_range=[47,) diff --git a/MinecraftMod/forge/1.20.1/settings.gradle b/MinecraftMod/forge/1.20.1/settings.gradle index 1b215ad..f32ea8b 100644 --- a/MinecraftMod/forge/1.20.1/settings.gradle +++ b/MinecraftMod/forge/1.20.1/settings.gradle @@ -2,7 +2,7 @@ pluginManagement { repositories { gradlePluginPortal() maven { - url = uri("https://maven.neoforged.net/releases") + url = uri("https://maven.minecraftforge.net/") } } } \ No newline at end of file diff --git a/MinecraftMod/forge/1.20.1/src/main/java/com/mosadie/effectmc/EffectMC.java b/MinecraftMod/forge/1.20.1/src/main/java/com/mosadie/effectmc/EffectMC.java index c140602..a7c5d82 100644 --- a/MinecraftMod/forge/1.20.1/src/main/java/com/mosadie/effectmc/EffectMC.java +++ b/MinecraftMod/forge/1.20.1/src/main/java/com/mosadie/effectmc/EffectMC.java @@ -2,11 +2,15 @@ import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; +import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.text2speech.Narrator; import com.mosadie.effectmc.core.EffectExecutor; import com.mosadie.effectmc.core.EffectMCCore; import com.mosadie.effectmc.core.WorldState; +import com.mosadie.effectmc.core.effect.*; +import com.mosadie.effectmc.core.effect.internal.Effect; +import com.mosadie.effectmc.core.effect.internal.EffectRequest; import com.mosadie.effectmc.core.handler.*; import net.minecraft.client.CameraType; import net.minecraft.client.Minecraft; @@ -28,6 +32,7 @@ import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.TagParser; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.contents.TranslatableContents; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.WorldStem; import net.minecraft.server.packs.repository.PackRepository; @@ -40,6 +45,7 @@ import net.minecraft.world.item.WrittenBookItem; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraftforge.client.event.ClientChatEvent; +import net.minecraftforge.client.event.ClientChatReceivedEvent; import net.minecraftforge.client.event.RegisterClientCommandsEvent; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.SubscribeEvent; @@ -107,6 +113,7 @@ public EffectMC() throws IOException { LOGGER.info("Server start result: " + result); MinecraftForge.EVENT_BUS.addListener(this::registerClientCommand); + MinecraftForge.EVENT_BUS.addListener(this::listenForTranslation); Header authHeader = new BasicHeader("Authorization", "Bearer " + Minecraft.getInstance().getUser().getAccessToken()); List
headers = new ArrayList<>(); @@ -118,7 +125,7 @@ public void registerClientCommand(RegisterClientCommandsEvent event) { LOGGER.info("Registering effectmc command."); event.getDispatcher().register(Commands.literal("effectmc") .then(Commands.literal("trust").executes((context -> { - Minecraft.getInstance().execute(core::setTrustNextRequest); + Minecraft.getInstance().execute(core::setTrustFlag); receiveChatMessage("[EffectMC] Now prompting to trust the next request sent."); return 0; }))) @@ -161,13 +168,72 @@ public void registerClientCommand(RegisterClientCommandsEvent event) { showItemToast(NbtUtils.prettyPrint(tag), "Exported", Minecraft.getInstance().player.getMainHandItem().getDisplayName().getString()); receiveChatMessage("[EffectMC] Exported held item data to log file!"); return 0; - }))).executes((context -> { - receiveChatMessage("[EffectMC] Available subcommands: exportbook, exportitem, trust"); + }))).then(Commands.literal("exporteffect").executes((context -> { + core.setExportFlag(); + receiveChatMessage("[EffectMC] Will export the next triggered effect as JSON to the current log file."); + return 0; + }))).then(Commands.literal("trigger").then(Commands.argument("json", StringArgumentType.greedyString()).executes((context -> { + String json = StringArgumentType.getString(context, "json"); + EffectRequest request = core.requestFromJson(json); + + if (request == null) { + receiveChatMessage("[EffectMC] Invalid JSON for effect request!"); + return 0; + } + + String worldId = getWorldState() == WorldState.SINGLEPLAYER ? getSPWorldName() : getServerIP(); + + Device device = new Device(worldId, getWorldState() == WorldState.SINGLEPLAYER ? DeviceType.WORLD : DeviceType.SERVER); + + Effect.EffectResult result = core.triggerEffect(device, request); + switch (result.result) { + case SUCCESS -> receiveChatMessage("[EffectMC] Effect \"" + request.getEffectId() + "\" triggered successfully: " + result.message); + case ERROR -> receiveChatMessage("[EffectMC] Error triggering effect: " + result.message); + case UNAUTHORIZED -> receiveChatMessage("[EffectMC] World/Server not trusted. Use /effectmc trust to trust the current world/server."); + case UNKNOWN -> receiveChatMessage("[EffectMC] Unknown effect."); + case SKIPPED -> receiveChatMessage("[EffectMC] Effect skipped: " + result.message); + case UNSUPPORTED -> receiveChatMessage("[EffectMC] Effect unsupported: " + result.message); + } + + return 0; + })))).executes((context -> { + receiveChatMessage("[EffectMC] Available subcommands: exportbook, exportitem, exporteffect, trigger, trust"); return 0; }))); LOGGER.info("Registered effectmc command."); } + public void listenForTranslation(ClientChatReceivedEvent event) { + Component component = event.getMessage(); + + if (component.getContents() instanceof TranslatableContents translationTextComponent) { + + if (translationTextComponent.getKey().equals(EffectMCCore.TRANSLATION_TRIGGER_KEY)) { + event.setCanceled(true); + + if (translationTextComponent.getArgs().length != 1) { + log("Invalid length of args for translation trigger!"); + return; + } + + String data = String.valueOf(translationTextComponent.getArgs()[0]); + + EffectRequest request = core.requestFromJson(data); + + if (request == null) { + log("Invalid request json for translation trigger!"); + return; + } + + String worldId = getWorldState() == WorldState.SINGLEPLAYER ? getSPWorldName() : getServerIP(); + + Device device = new Device(worldId, getWorldState() == WorldState.SINGLEPLAYER ? DeviceType.WORLD : DeviceType.SERVER); + + core.triggerEffect(device, request); + } + } + } + @Override public void log(String message) { LOGGER.info(message); @@ -206,7 +272,7 @@ public boolean joinServer(String serverIp) { } @Override - public boolean setSkinLayer(SkinLayerHandler.SKIN_SECTION section, boolean visibility) { + public boolean setSkinLayer(SkinLayerEffect.SKIN_SECTION section, boolean visibility) { Options options = Minecraft.getInstance().options; switch (section) { @@ -249,7 +315,7 @@ public boolean setSkinLayer(SkinLayerHandler.SKIN_SECTION section, boolean visib } @Override - public boolean toggleSkinLayer(SkinLayerHandler.SKIN_SECTION section) { + public boolean toggleSkinLayer(SkinLayerEffect.SKIN_SECTION section) { Options options = Minecraft.getInstance().options; switch (section) { @@ -338,7 +404,7 @@ public boolean showActionMessage(String message) { } @Override - public boolean triggerDisconnect(DisconnectHandler.NEXT_SCREEN nextScreenType, String title, String message) { + public boolean triggerDisconnect(DisconnectEffect.NEXT_SCREEN nextScreenType, String title, String message) { Minecraft.getInstance().execute(() -> { if (Minecraft.getInstance().level != null) { LOGGER.info("Disconnecting from world..."); @@ -407,9 +473,9 @@ public boolean playSound(String soundID, String categoryName, float volume, floa } @Override - public void showTrustPrompt(String device) { + public void showTrustPrompt(Device device) { Minecraft.getInstance().execute(() -> { - ConfirmScreen screen = new ConfirmScreen(new EffectMCCore.TrustBooleanConsumer(device, core), Component.literal("EffectMC - Trust Prompt"), Component.literal("Do you want to trust this device? (" + device + ")")); + ConfirmScreen screen = new ConfirmScreen(new EffectMCCore.TrustBooleanConsumer(device, core), Component.literal("EffectMC - Trust Prompt"), Component.literal("Do you want to trust this device?\n(Type: " + device.getType() + (device.getType() == DeviceType.OTHER ? " Device Id:" + device.getId() : "") + ")")); Minecraft.getInstance().setScreen(screen); }); } @@ -512,7 +578,7 @@ public boolean loadWorld(String worldName) { } @Override - public boolean setSkin(URL skinUrl, SetSkinHandler.SKIN_TYPE skinType) { + public boolean setSkin(URL skinUrl, SetSkinEffect.SKIN_TYPE skinType) { if (skinUrl == null) { LOGGER.warn("Skin URL is null!"); return false; @@ -557,7 +623,7 @@ public void leaveIfNeeded() { } @Override - public boolean openScreen(OpenScreenHandler.SCREEN screen) { + public boolean openScreen(OpenScreenEffect.SCREEN screen) { Minecraft.getInstance().execute(() -> { leaveIfNeeded(); @@ -591,7 +657,7 @@ public boolean setFOV(int fov) { } @Override - public boolean setPOV(SetPovHandler.POV pov) { + public boolean setPOV(SetPovEffect.POV pov) { CameraType mcPov; switch (pov) { @@ -637,7 +703,7 @@ public boolean setGamma(double gamma) { } @Override - public boolean setChatVisibility(ChatVisibilityHandler.VISIBILITY visibility) { + public boolean setChatVisibility(ChatVisibilityEffect.VISIBILITY visibility) { ChatVisiblity result; switch (visibility) { case SHOW: @@ -697,6 +763,53 @@ public String getSPWorldName() { return null; } + @Override + public void setVolume(SetVolumeEffect.VOLUME_CATEGORIES category, int volume) { + Minecraft.getInstance().execute(() -> { + + SoundSource mcSoundSource; + + switch (category) { + case MASTER: + mcSoundSource = SoundSource.MASTER; + break; + case MUSIC: + mcSoundSource = SoundSource.MUSIC; + break; + case RECORDS: + mcSoundSource = SoundSource.RECORDS; + break; + case WEATHER: + mcSoundSource = SoundSource.WEATHER; + break; + case BLOCKS: + mcSoundSource = SoundSource.BLOCKS; + break; + case HOSTILE: + mcSoundSource = SoundSource.HOSTILE; + break; + case NEUTRAL: + mcSoundSource = SoundSource.NEUTRAL; + break; + case PLAYERS: + mcSoundSource = SoundSource.PLAYERS; + break; + case AMBIENT: + mcSoundSource = SoundSource.AMBIENT; + break; + case VOICE: + mcSoundSource = SoundSource.VOICE; + break; + default: + LOGGER.error("Unknown volume category!"); + return; + } + + Minecraft.getInstance().options.getSoundSourceOptionInstance(mcSoundSource).set(volume / 100.0d); + Minecraft.getInstance().options.save(); + }); + } + @Override public String getServerIP() { if (getWorldState() != WorldState.MULTIPLAYER) { diff --git a/MinecraftMod/forge/update.json b/MinecraftMod/forge/update.json index 98db81d..b96516f 100644 --- a/MinecraftMod/forge/update.json +++ b/MinecraftMod/forge/update.json @@ -1,33 +1,7 @@ { "homepage": "https://github.com/MoSadie/EffectMC", - "1.21.4": { - "3.1.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v3.1.0" - }, - "1.21.3": { - "3.1.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v3.1.0", - "3.0.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v3.0.0" - }, - "1.21.1": { - "3.1.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v3.1.0", - "3.0.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v3.0.0" - }, - "1.21": { - "3.1.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v3.1.0", - "3.0.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v3.0.0", - "2.3.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v2.3.0" - }, - "1.20.6": { - "3.1.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v3.1.0", - "3.0.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v3.0.0", - "2.3.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v2.3.0" - }, - "1.20.4": { - "2.3.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v2.3.0" - }, - "1.20.2": { - "2.3.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v2.3.0" - }, "1.20.1": { + "3.1.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v3.1.0", "2.3.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v2.3.0", "2.2.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v2.2.0" }, @@ -98,22 +72,8 @@ "1.0.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v1.0.0" }, "promos": { - "1.21.4-latest": "3.1.0", - "1.21.4-recommended": "3.1.0", - "1.21.3-latest": "3.1.0", - "1.21.3-recommended": "3.1.0", - "1.21.1-latest": "3.1.0", - "1.21.1-recommended": "3.1.0", - "1.21-latest": "3.1.0", - "1.21-recommended": "3.1.0", - "1.20.6-latest": "3.1.0", - "1.20.6-recommended": "3.1.0", - "1.20.4-latest": "2.3.0", - "1.20.4-recommended": "2.3.0", - "1.20.2-latest": "2.3.0", - "1.20.2-recommended": "2.3.0", - "1.20.1-latest": "2.3.0", - "1.20.1-recommended": "2.3.0", + "1.20.1-latest": "3.1.0", + "1.20.1-recommended": "3.1.0", "1.19.4-latest": "3.1.0", "1.19.4-recommended": "3.1.0", "1.19.3-latest": "2.3.0", diff --git a/MinecraftMod/forge/1.20.2/.gitattributes b/MinecraftMod/neoforge/1.20.1/.gitattributes similarity index 100% rename from MinecraftMod/forge/1.20.2/.gitattributes rename to MinecraftMod/neoforge/1.20.1/.gitattributes diff --git a/MinecraftMod/neoforge/1.20.1/.gitignore b/MinecraftMod/neoforge/1.20.1/.gitignore new file mode 100644 index 0000000..12f8644 --- /dev/null +++ b/MinecraftMod/neoforge/1.20.1/.gitignore @@ -0,0 +1,25 @@ +# eclipse +bin +*.launch +.settings +.metadata +.classpath +.project + +# idea +out +*.ipr +*.iws +*.iml +.idea + +# gradle +build +.gradle + +# other +eclipse +run + +# Files from Forge MDK +forge*changelog.txt diff --git a/MinecraftMod/neoforge/1.20.1/build.gradle b/MinecraftMod/neoforge/1.20.1/build.gradle new file mode 100644 index 0000000..ed03cba --- /dev/null +++ b/MinecraftMod/neoforge/1.20.1/build.gradle @@ -0,0 +1,186 @@ +plugins { + id 'eclipse' + id 'idea' + id 'maven-publish' + id 'net.neoforged.gradle' version '[6.0.18,6.2)' +} + +version = mod_version +group = mod_group_id + +base { + archivesName = "effectmc-neoforge-${minecraft_version}" +} + +// Enable Jar in Jar +jarJar.enable(); + +// Mojang ships Java 17 to end users in 1.18+, so your mod should target Java 17. +java.toolchain.languageVersion = JavaLanguageVersion.of(17) + +println "Java: ${System.getProperty 'java.version'}, JVM: ${System.getProperty 'java.vm.version'} (${System.getProperty 'java.vendor'}), Arch: ${System.getProperty 'os.arch'}" +minecraft { + // The mappings can be changed at any time and must be in the following format. + // Channel: Version: + // official MCVersion Official field/method names from Mojang mapping files + // parchment YYYY.MM.DD-MCVersion Open community-sourced parameter names and javadocs layered on top of official + // + // You must be aware of the Mojang license when using the 'official' or 'parchment' mappings. + // See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md + // + // Parchment is an unofficial project maintained by ParchmentMC, separate from MinecraftForge + // Additional setup is needed to use their mappings: https://github.com/ParchmentMC/Parchment/wiki/Getting-Started + // + // Use non-default mappings at your own risk. They may not always work. + // Simply re-run your setup task after changing the mappings to update your workspace. + mappings channel: mapping_channel, version: mapping_version + + // When true, this property will have all Eclipse/IntelliJ IDEA run configurations run the "prepareX" task for the given run configuration before launching the game. + // In most cases, it is not necessary to enable. + // enableEclipsePrepareRuns = true + // enableIdeaPrepareRuns = true + + // This property allows configuring Gradle's ProcessResources task(s) to run on IDE output locations before launching the game. + // It is REQUIRED to be set to true for this template to function. + // See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html + copyIdeResources = true + + // When true, this property will add the folder name of all declared run configurations to generated IDE run configurations. + // The folder name can be set on a run configuration using the "folderName" property. + // By default, the folder name of a run configuration is the name of the Gradle project containing it. + // generateRunFolders = true + + // accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') // Currently, this location cannot be changed from the default. + + // Default run configurations. + // These can be tweaked, removed, or duplicated as needed. + runs { + // applies to all the run configs below + configureEach { + workingDirectory project.file('run') + + // Recommended logging data for a userdev environment + // The markers can be added/remove as needed separated by commas. + // "SCAN": For mods scan. + // "REGISTRIES": For firing of registry events. + // "REGISTRYDUMP": For getting the contents of all registries. + property 'forge.logging.markers', 'REGISTRIES' + + // Recommended logging level for the console + // You can set various levels here. + // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels + property 'forge.logging.console.level', 'debug' + + mods { + "${mod_id}" { + source sourceSets.main + } + } + } + + client { + // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. + property 'forge.enabledGameTestNamespaces', mod_id + } + + server { + property 'forge.enabledGameTestNamespaces', mod_id + args '--nogui' + } + + // This run config launches GameTestServer and runs all registered gametests, then exits. + // By default, the server will crash when no gametests are provided. + // The gametest system is also enabled by default for other run configs under the /test command. + gameTestServer { + property 'forge.enabledGameTestNamespaces', mod_id + } + + data { + // example of overriding the workingDirectory set in configureEach above + workingDirectory project.file('run-data') + + // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. + args '--mod', mod_id, '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/') + } + } +} + +// Include resources generated by data generators. +sourceSets.main.resources { srcDir 'src/generated/resources' } + +repositories { + mavenLocal(); +} + +dependencies { + // Specify the version of Minecraft to use. + // Any artifact can be supplied so long as it has a "userdev" classifier artifact and is a compatible patcher artifact. + // The "userdev" classifier will be requested and setup by ForgeGradle. + // If the group id is "net.minecraft" and the artifact id is one of ["client", "server", "joined"], + // then special handling is done to allow a setup of a vanilla dependency without the use of an external repository. + minecraft "net.neoforged:forge:${minecraft_version}-${forge_version}" + + implementation "com.mosadie.effectmc:core:${effectmc_core_version}" + jarJar("com.mosadie.effectmc:core:${effectmc_core_version_range}") +} + +// This block of code expands all declared replace properties in the specified resource targets. +// A missing property will result in an error. Properties are expanded using ${} Groovy notation. +// When "copyIdeResources" is enabled, this will also run before the game launches in IDE environments. +// See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html +tasks.named('processResources', ProcessResources).configure { + var replaceProperties = [ + minecraft_version: minecraft_version, minecraft_version_range: minecraft_version_range, + forge_version: forge_version, forge_version_range: forge_version_range, + loader_version_range: loader_version_range, + mod_id: mod_id, mod_name: mod_name, mod_license: mod_license, mod_version: mod_version, + mod_authors: mod_authors, mod_description: mod_description, + ] + inputs.properties replaceProperties + + filesMatching(['META-INF/mods.toml', 'pack.mcmeta']) { + expand replaceProperties + [project: project] + } +} + +// Example for how to get properties into the manifest for reading at runtime. +jar { + manifest { + attributes([ + "Specification-Title" : mod_id, + "Specification-Vendor" : mod_authors, + "Specification-Version" : "1", // We are version 1 of ourselves + "Implementation-Title" : project.name, + "Implementation-Version" : project.jar.archiveVersion, + "Implementation-Vendor" : mod_authors, + "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") + ]) + } + + // This is the preferred method to reobfuscate your jar file + finalizedBy 'reobfJar' +} + +// However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing: +// tasks.named('publish').configure { +// dependsOn 'reobfJar' +// } + +// Example configuration to allow publishing using the maven-publish plugin + +//publishing { +// publications { +// mavenJava(MavenPublication) { +// artifact jar +// } +// } +// repositories { +// maven { +// url "file://${project.projectDir}/mcmodsrepo" +// } +// } +//} + +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation +} \ No newline at end of file diff --git a/MinecraftMod/neoforge/1.20.1/gradle.properties b/MinecraftMod/neoforge/1.20.1/gradle.properties new file mode 100644 index 0000000..9bcd0c1 --- /dev/null +++ b/MinecraftMod/neoforge/1.20.1/gradle.properties @@ -0,0 +1,54 @@ +# Sets default memory used for gradle commands. Can be overridden by user or command line properties. +# This is required to provide enough memory for the Minecraft decompilation process. +org.gradle.jvmargs=-Xmx3G +org.gradle.daemon=false + +# EffectMC Properties + +effectmc_core_version=2.3 +effectmc_core_version_range=[2.2,3.0) +mod_version=2.3.0 + +mod_id=effectmc +mod_name=EffectMC +mod_license=GNU LGPL v3 +mod_group_id=com.mosadie.effectmc +mod_authors=MoSadie +mod_description=Various vanilla-themed live special effects for you to control! + +# Forge/Minecraft Properties + +# The Minecraft version must agree with the Forge version to get a valid artifact +minecraft_version=1.20.1 + +# 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.20.1,1.21) + +# The Forge version must agree with the Minecraft version to get a valid artifact +forge_version=47.1.81 + +# The Forge version range can use any version of Forge as bounds or match the loader version range +forge_version_range=[47,) +# The loader version range can only use the major version of Forge/FML as bounds +loader_version_range=[47,) + +# The mapping channel to use for mappings. +# The default set of supported mapping channels are ["official", "snapshot", "snapshot_nodoc", "stable", "stable_nodoc"]. +# Additional mapping channels can be registered through the "channelProviders" extension in a Gradle plugin. +# +# | Channel | Version | | +# |-----------|----------------------|--------------------------------------------------------------------------------| +# | official | MCVersion | Official field/method names from Mojang mapping files | +# | parchment | YYYY.MM.DD-MCVersion | Open community-sourced parameter names and javadocs layered on top of official | +# +# You must be aware of the Mojang license when using the 'official' or 'parchment' mappings. +# See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md +# +# Parchment is an unofficial project maintained by ParchmentMC, separate from Minecraft Forge. +# Additional setup is needed to use their mappings, see https://parchmentmc.org/docs/getting-started +mapping_channel=official +# The mapping version to query from the mapping channel. +# This must match the format required by the mapping channel. +mapping_version=1.20.1 \ No newline at end of file diff --git a/MinecraftMod/neoforge/1.20.1/gradle/wrapper/gradle-wrapper.jar b/MinecraftMod/neoforge/1.20.1/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..c1962a7 Binary files /dev/null and b/MinecraftMod/neoforge/1.20.1/gradle/wrapper/gradle-wrapper.jar differ diff --git a/MinecraftMod/neoforge/1.20.1/gradle/wrapper/gradle-wrapper.properties b/MinecraftMod/neoforge/1.20.1/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..e90ad8f --- /dev/null +++ b/MinecraftMod/neoforge/1.20.1/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Wed Oct 23 12:52:33 PDT 2024 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/MinecraftMod/neoforge/1.20.1/gradlew b/MinecraftMod/neoforge/1.20.1/gradlew new file mode 100755 index 0000000..aeb74cb --- /dev/null +++ b/MinecraftMod/neoforge/1.20.1/gradlew @@ -0,0 +1,245 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/MinecraftMod/forge/1.20.2/gradlew.bat b/MinecraftMod/neoforge/1.20.1/gradlew.bat similarity index 100% rename from MinecraftMod/forge/1.20.2/gradlew.bat rename to MinecraftMod/neoforge/1.20.1/gradlew.bat diff --git a/MinecraftMod/neoforge/1.20.1/settings.gradle b/MinecraftMod/neoforge/1.20.1/settings.gradle new file mode 100644 index 0000000..1b215ad --- /dev/null +++ b/MinecraftMod/neoforge/1.20.1/settings.gradle @@ -0,0 +1,8 @@ +pluginManagement { + repositories { + gradlePluginPortal() + maven { + url = uri("https://maven.neoforged.net/releases") + } + } +} \ No newline at end of file diff --git a/MinecraftMod/forge/1.20.4/src/main/java/com/mosadie/effectmc/EffectMC.java b/MinecraftMod/neoforge/1.20.1/src/main/java/com/mosadie/effectmc/EffectMC.java similarity index 87% rename from MinecraftMod/forge/1.20.4/src/main/java/com/mosadie/effectmc/EffectMC.java rename to MinecraftMod/neoforge/1.20.1/src/main/java/com/mosadie/effectmc/EffectMC.java index e250c2a..c140602 100644 --- a/MinecraftMod/forge/1.20.4/src/main/java/com/mosadie/effectmc/EffectMC.java +++ b/MinecraftMod/neoforge/1.20.1/src/main/java/com/mosadie/effectmc/EffectMC.java @@ -7,10 +7,7 @@ import com.mosadie.effectmc.core.EffectExecutor; import com.mosadie.effectmc.core.EffectMCCore; import com.mosadie.effectmc.core.WorldState; -import com.mosadie.effectmc.core.effect.*; -import com.mosadie.effectmc.core.effect.internal.EffectRequest; -import com.mosadie.effectmc.core.handler.Device; -import com.mosadie.effectmc.core.handler.DeviceType; +import com.mosadie.effectmc.core.handler.*; import net.minecraft.client.CameraType; import net.minecraft.client.Minecraft; import net.minecraft.client.Options; @@ -20,6 +17,7 @@ import net.minecraft.client.gui.screens.multiplayer.JoinMultiplayerScreen; import net.minecraft.client.gui.screens.worldselection.CreateWorldScreen; import net.minecraft.client.gui.screens.worldselection.SelectWorldScreen; +import net.minecraft.client.gui.screens.worldselection.WorldOpenFlows; import net.minecraft.client.multiplayer.ServerData; import net.minecraft.client.multiplayer.resolver.ServerAddress; import net.minecraft.client.resources.sounds.SimpleSoundInstance; @@ -30,9 +28,9 @@ import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.TagParser; import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.ComponentContents; -import net.minecraft.network.chat.contents.TranslatableContents; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.WorldStem; +import net.minecraft.server.packs.repository.PackRepository; import net.minecraft.sounds.SoundSource; import net.minecraft.util.RandomSource; import net.minecraft.world.entity.player.ChatVisiblity; @@ -40,11 +38,13 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.item.WrittenBookItem; -import net.neoforged.fml.ModList; -import net.neoforged.fml.common.Mod; -import net.neoforged.neoforge.client.event.ClientChatReceivedEvent; -import net.neoforged.neoforge.client.event.RegisterClientCommandsEvent; -import net.neoforged.neoforge.common.NeoForge; +import net.minecraft.world.level.storage.LevelStorageSource; +import net.minecraftforge.client.event.ClientChatEvent; +import net.minecraftforge.client.event.RegisterClientCommandsEvent; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.ModList; +import net.minecraftforge.fml.common.Mod; import org.apache.commons.io.IOUtils; import org.apache.http.Header; import org.apache.http.HttpResponse; @@ -75,7 +75,7 @@ public class EffectMC implements EffectExecutor { private static Narrator narrator = Narrator.getNarrator(); private static RandomSource randomSource = RandomSource.create(); - private static ServerData serverData = new ServerData("", "", ServerData.Type.OTHER); // Used to hold data during Open Screen + private static ServerData serverData = new ServerData("", "", false); // Used to hold data during Open Screen private final HttpClient authedClient; @@ -106,8 +106,7 @@ public EffectMC() throws IOException { } LOGGER.info("Server start result: " + result); - NeoForge.EVENT_BUS.addListener(this::registerClientCommand); - NeoForge.EVENT_BUS.addListener(this::listenForTranslation); + MinecraftForge.EVENT_BUS.addListener(this::registerClientCommand); Header authHeader = new BasicHeader("Authorization", "Bearer " + Minecraft.getInstance().getUser().getAccessToken()); List
headers = new ArrayList<>(); @@ -119,7 +118,7 @@ public void registerClientCommand(RegisterClientCommandsEvent event) { LOGGER.info("Registering effectmc command."); event.getDispatcher().register(Commands.literal("effectmc") .then(Commands.literal("trust").executes((context -> { - Minecraft.getInstance().execute(core::setTrustFlag); + Minecraft.getInstance().execute(core::setTrustNextRequest); receiveChatMessage("[EffectMC] Now prompting to trust the next request sent."); return 0; }))) @@ -162,47 +161,13 @@ public void registerClientCommand(RegisterClientCommandsEvent event) { showItemToast(NbtUtils.prettyPrint(tag), "Exported", Minecraft.getInstance().player.getMainHandItem().getDisplayName().getString()); receiveChatMessage("[EffectMC] Exported held item data to log file!"); return 0; - }))).then(Commands.literal("exporteffect").executes(context -> { - core.setExportFlag(); - receiveChatMessage("[EffectMC] Will export the next triggered effect as JSON to the current log file."); - return 0; - })).executes((context -> { + }))).executes((context -> { receiveChatMessage("[EffectMC] Available subcommands: exportbook, exportitem, trust"); return 0; }))); LOGGER.info("Registered effectmc command."); } - - private void listenForTranslation(ClientChatReceivedEvent event) { - Component component = event.getMessage(); - - ComponentContents contents = component.getContents(); - if (contents instanceof TranslatableContents translatableContents && translatableContents.getKey().equals(EffectMCCore.TRANSLATION_TRIGGER_KEY)) { - event.setCanceled(true); - - if (translatableContents.getArgs().length != 1) { - log("Invalid length of args for translation trigger!"); - return; - } - - String data = String.valueOf(translatableContents.getArgs()[0]); - - EffectRequest request = core.requestFromJson(data); - - if (request == null) { - log("Invalid request json for translation trigger!"); - return; - } - - String worldId = getWorldState() == WorldState.SINGLEPLAYER ? getSPWorldName() : getServerIP(); - - Device device = new Device(worldId, getWorldState() == WorldState.SINGLEPLAYER ? DeviceType.WORLD : DeviceType.SERVER); - - core.triggerEffect(device, request); - } - } - @Override public void log(String message) { LOGGER.info(message); @@ -211,7 +176,12 @@ public void log(String message) { @Override public boolean joinServer(String serverIp) { Minecraft.getInstance().execute(() -> { - leaveIfNeeded(); + if (Minecraft.getInstance().level != null) { + LOGGER.info("Disconnecting from world..."); + + Minecraft.getInstance().level.disconnect(); + Minecraft.getInstance().clearLevel(); + } // Create ServerAddress if (!ServerAddress.isValidAddress(serverIp)) { @@ -224,7 +194,7 @@ public boolean joinServer(String serverIp) { } ServerAddress serverAddress = ServerAddress.parseString(serverIp); - ServerData serverData = new ServerData("EffectMC", serverIp, ServerData.Type.OTHER); + ServerData serverData = new ServerData("EffectMC", serverIp, false); LOGGER.info("Connecting to " + serverAddress.getHost()); @@ -236,7 +206,7 @@ public boolean joinServer(String serverIp) { } @Override - public boolean setSkinLayer(SkinLayerEffect.SKIN_SECTION section, boolean visibility) { + public boolean setSkinLayer(SkinLayerHandler.SKIN_SECTION section, boolean visibility) { Options options = Minecraft.getInstance().options; switch (section) { @@ -279,7 +249,7 @@ public boolean setSkinLayer(SkinLayerEffect.SKIN_SECTION section, boolean visibi } @Override - public boolean toggleSkinLayer(SkinLayerEffect.SKIN_SECTION section) { + public boolean toggleSkinLayer(SkinLayerHandler.SKIN_SECTION section) { Options options = Minecraft.getInstance().options; switch (section) { @@ -368,9 +338,14 @@ public boolean showActionMessage(String message) { } @Override - public boolean triggerDisconnect(DisconnectEffect.NEXT_SCREEN nextScreenType, String title, String message) { + public boolean triggerDisconnect(DisconnectHandler.NEXT_SCREEN nextScreenType, String title, String message) { Minecraft.getInstance().execute(() -> { - leaveIfNeeded(); + if (Minecraft.getInstance().level != null) { + LOGGER.info("Disconnecting from world..."); + + Minecraft.getInstance().level.disconnect(); + Minecraft.getInstance().clearLevel(); + } Screen nextScreen; @@ -432,9 +407,9 @@ public boolean playSound(String soundID, String categoryName, float volume, floa } @Override - public void showTrustPrompt(Device device) { + public void showTrustPrompt(String device) { Minecraft.getInstance().execute(() -> { - ConfirmScreen screen = new ConfirmScreen(new EffectMCCore.TrustBooleanConsumer(device, core), Component.literal("EffectMC - Trust Prompt"), Component.literal("Do you want to trust this device?\n(Type: " + device.getType() + (device.getType() == DeviceType.OTHER ? " Device Id:" + device.getId() : "") + ")")); + ConfirmScreen screen = new ConfirmScreen(new EffectMCCore.TrustBooleanConsumer(device, core), Component.literal("EffectMC - Trust Prompt"), Component.literal("Do you want to trust this device? (" + device + ")")); Minecraft.getInstance().setScreen(screen); }); } @@ -464,7 +439,7 @@ public boolean stopSound(String sound, String categoryName) { @Override public boolean showToast(String title, String subtitle) { - Minecraft.getInstance().execute(() -> Minecraft.getInstance().getToasts().addToast(new SystemToast(SystemToast.SystemToastId.NARRATOR_TOGGLE, Component.literal(title), Component.literal(subtitle)))); + Minecraft.getInstance().execute(() -> Minecraft.getInstance().getToasts().addToast(new SystemToast(SystemToast.SystemToastIds.NARRATOR_TOGGLE, Component.literal(title), Component.literal(subtitle)))); return true; } @@ -519,13 +494,15 @@ public boolean narrate(String message, boolean interrupt) { public boolean loadWorld(String worldName) { Minecraft.getInstance().execute(() -> { if (Minecraft.getInstance().getLevelSource().levelExists(worldName)) { - leaveIfNeeded(); + if (Minecraft.getInstance().level != null) { + LOGGER.info("Disconnecting from world..."); + + Minecraft.getInstance().level.disconnect(); + Minecraft.getInstance().clearLevel(); + } LOGGER.info("Loading world..."); - Minecraft.getInstance().createWorldOpenFlows().checkForBackupAndLoad(worldName, () -> { - LOGGER.info("World load cancelled!"); - Minecraft.getInstance().setScreen(new TitleScreen()); - }); + Minecraft.getInstance().createWorldOpenFlows().loadLevel(new TitleScreen(), worldName); } else { LOGGER.warn("World " + worldName + " does not exist!"); } @@ -535,7 +512,7 @@ public boolean loadWorld(String worldName) { } @Override - public boolean setSkin(URL skinUrl, SetSkinEffect.SKIN_TYPE skinType) { + public boolean setSkin(URL skinUrl, SetSkinHandler.SKIN_TYPE skinType) { if (skinUrl == null) { LOGGER.warn("Skin URL is null!"); return false; @@ -575,13 +552,12 @@ public void leaveIfNeeded() { LOGGER.info("Disconnecting from world..."); Minecraft.getInstance().level.disconnect(); - Minecraft.getInstance().disconnect(); -// Minecraft.getInstance().clearClientLevel(new ProgressScreen(true)); + Minecraft.getInstance().clearLevel(); } } @Override - public boolean openScreen(OpenScreenEffect.SCREEN screen) { + public boolean openScreen(OpenScreenHandler.SCREEN screen) { Minecraft.getInstance().execute(() -> { leaveIfNeeded(); @@ -615,7 +591,7 @@ public boolean setFOV(int fov) { } @Override - public boolean setPOV(SetPovEffect.POV pov) { + public boolean setPOV(SetPovHandler.POV pov) { CameraType mcPov; switch (pov) { @@ -661,7 +637,7 @@ public boolean setGamma(double gamma) { } @Override - public boolean setChatVisibility(ChatVisibilityEffect.VISIBILITY visibility) { + public boolean setChatVisibility(ChatVisibilityHandler.VISIBILITY visibility) { ChatVisiblity result; switch (visibility) { case SHOW: diff --git a/MinecraftMod/neoforge/1.20.1/src/main/java/com/mosadie/effectmc/ItemToast.java b/MinecraftMod/neoforge/1.20.1/src/main/java/com/mosadie/effectmc/ItemToast.java new file mode 100644 index 0000000..075e783 --- /dev/null +++ b/MinecraftMod/neoforge/1.20.1/src/main/java/com/mosadie/effectmc/ItemToast.java @@ -0,0 +1,44 @@ +package com.mosadie.effectmc; + +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.toasts.Toast; +import net.minecraft.client.gui.components.toasts.ToastComponent; +import net.minecraft.nbt.TagParser; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; + +public class ItemToast implements Toast { + private ItemStack item; + private Component title; + private Component body; + + private long lastChanged; + private boolean changed = true; + + public ItemToast(String itemData, Component title, Component body) { + try { + this.item = ItemStack.of(TagParser.parseTag(itemData)); + } catch (CommandSyntaxException e) { + EffectMC.LOGGER.error("Invalid Item Data for Item Toast", e); + this.item = new ItemStack(Items.AIR, 1, null); + } + this.title = title; + this.body = body; + } + @Override + public Visibility render(GuiGraphics guiGraphics, ToastComponent toastComponent, long time) { + if (changed) { + lastChanged = time; + changed = false; + } + + + guiGraphics.blit(TEXTURE, 0, 0, 0, 32, this.width(), this.height()); + guiGraphics.drawString(toastComponent.getMinecraft().font, title, 30, 7, -16777216, false); + guiGraphics.drawString(toastComponent.getMinecraft().font, body, 30, 18, -16777216, false); + guiGraphics.renderFakeItem(item, 8, 8); + return (double)(time - this.lastChanged) >= 5000.0D * toastComponent.getNotificationDisplayTimeMultiplier() ? Visibility.HIDE : Visibility.SHOW; + } +} diff --git a/MinecraftMod/neoforge/1.20.1/src/main/resources/META-INF/mods.toml b/MinecraftMod/neoforge/1.20.1/src/main/resources/META-INF/mods.toml new file mode 100644 index 0000000..c3902c2 --- /dev/null +++ b/MinecraftMod/neoforge/1.20.1/src/main/resources/META-INF/mods.toml @@ -0,0 +1,26 @@ +modLoader="javafml" +loaderVersion="${loader_version_range}" +issueTrackerURL="https://github.com/MoSadie/EffectMC/issues" +license="${mod_license}" +[[mods]] +modId="${mod_id}" +version="${mod_version}" +displayName="${mod_name}" +updateJSONURL="https://raw.githubusercontent.com/MoSadie/EffectMC/main/MinecraftMod/forge/update.json" +displayURL="https://github.com/MoSadie/EffectMC" +authors="${mod_authors}" +displayTest="IGNORE_ALL_VERSION" +description='''${mod_description}''' +[[dependencies.${mod_id}]] + modId="forge" + mandatory=true + versionRange="${forge_version_range}" + ordering="NONE" + side="BOTH" + +[[dependencies.${mod_id}]] + modId="minecraft" + mandatory=true + versionRange="${minecraft_version_range}" + ordering="NONE" + side="BOTH" diff --git a/MinecraftMod/neoforge/1.20.1/src/main/resources/pack.mcmeta b/MinecraftMod/neoforge/1.20.1/src/main/resources/pack.mcmeta new file mode 100644 index 0000000..eca79ae --- /dev/null +++ b/MinecraftMod/neoforge/1.20.1/src/main/resources/pack.mcmeta @@ -0,0 +1,8 @@ +{ + "pack": { + "description": { + "text": "${mod_id} resources" + }, + "pack_format": 15 + } +} \ No newline at end of file diff --git a/MinecraftMod/forge/1.20.4/.gitattributes b/MinecraftMod/neoforge/1.20.2/.gitattributes similarity index 100% rename from MinecraftMod/forge/1.20.4/.gitattributes rename to MinecraftMod/neoforge/1.20.2/.gitattributes diff --git a/MinecraftMod/forge/1.20.2/.gitignore b/MinecraftMod/neoforge/1.20.2/.gitignore similarity index 100% rename from MinecraftMod/forge/1.20.2/.gitignore rename to MinecraftMod/neoforge/1.20.2/.gitignore diff --git a/MinecraftMod/forge/1.20.2/build.gradle b/MinecraftMod/neoforge/1.20.2/build.gradle similarity index 100% rename from MinecraftMod/forge/1.20.2/build.gradle rename to MinecraftMod/neoforge/1.20.2/build.gradle diff --git a/MinecraftMod/forge/1.20.2/gradle.properties b/MinecraftMod/neoforge/1.20.2/gradle.properties similarity index 100% rename from MinecraftMod/forge/1.20.2/gradle.properties rename to MinecraftMod/neoforge/1.20.2/gradle.properties diff --git a/MinecraftMod/forge/1.20.2/gradle/wrapper/gradle-wrapper.jar b/MinecraftMod/neoforge/1.20.2/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from MinecraftMod/forge/1.20.2/gradle/wrapper/gradle-wrapper.jar rename to MinecraftMod/neoforge/1.20.2/gradle/wrapper/gradle-wrapper.jar diff --git a/MinecraftMod/forge/1.20.2/gradle/wrapper/gradle-wrapper.properties b/MinecraftMod/neoforge/1.20.2/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from MinecraftMod/forge/1.20.2/gradle/wrapper/gradle-wrapper.properties rename to MinecraftMod/neoforge/1.20.2/gradle/wrapper/gradle-wrapper.properties diff --git a/MinecraftMod/forge/1.20.2/gradlew b/MinecraftMod/neoforge/1.20.2/gradlew similarity index 100% rename from MinecraftMod/forge/1.20.2/gradlew rename to MinecraftMod/neoforge/1.20.2/gradlew diff --git a/MinecraftMod/forge/1.20.4/gradlew.bat b/MinecraftMod/neoforge/1.20.2/gradlew.bat similarity index 100% rename from MinecraftMod/forge/1.20.4/gradlew.bat rename to MinecraftMod/neoforge/1.20.2/gradlew.bat diff --git a/MinecraftMod/forge/1.20.2/settings.gradle b/MinecraftMod/neoforge/1.20.2/settings.gradle similarity index 100% rename from MinecraftMod/forge/1.20.2/settings.gradle rename to MinecraftMod/neoforge/1.20.2/settings.gradle diff --git a/MinecraftMod/forge/1.20.2/src/main/java/com/mosadie/effectmc/EffectMC.java b/MinecraftMod/neoforge/1.20.2/src/main/java/com/mosadie/effectmc/EffectMC.java similarity index 100% rename from MinecraftMod/forge/1.20.2/src/main/java/com/mosadie/effectmc/EffectMC.java rename to MinecraftMod/neoforge/1.20.2/src/main/java/com/mosadie/effectmc/EffectMC.java diff --git a/MinecraftMod/forge/1.20.2/src/main/java/com/mosadie/effectmc/ItemToast.java b/MinecraftMod/neoforge/1.20.2/src/main/java/com/mosadie/effectmc/ItemToast.java similarity index 100% rename from MinecraftMod/forge/1.20.2/src/main/java/com/mosadie/effectmc/ItemToast.java rename to MinecraftMod/neoforge/1.20.2/src/main/java/com/mosadie/effectmc/ItemToast.java diff --git a/MinecraftMod/forge/1.20.2/src/main/resources/META-INF/mods.toml b/MinecraftMod/neoforge/1.20.2/src/main/resources/META-INF/mods.toml similarity index 100% rename from MinecraftMod/forge/1.20.2/src/main/resources/META-INF/mods.toml rename to MinecraftMod/neoforge/1.20.2/src/main/resources/META-INF/mods.toml diff --git a/MinecraftMod/forge/1.20.2/src/main/resources/pack.mcmeta b/MinecraftMod/neoforge/1.20.2/src/main/resources/pack.mcmeta similarity index 100% rename from MinecraftMod/forge/1.20.2/src/main/resources/pack.mcmeta rename to MinecraftMod/neoforge/1.20.2/src/main/resources/pack.mcmeta diff --git a/MinecraftMod/forge/1.20.6/.gitattributes b/MinecraftMod/neoforge/1.20.4/.gitattributes similarity index 100% rename from MinecraftMod/forge/1.20.6/.gitattributes rename to MinecraftMod/neoforge/1.20.4/.gitattributes diff --git a/MinecraftMod/forge/1.20.4/.gitignore b/MinecraftMod/neoforge/1.20.4/.gitignore similarity index 100% rename from MinecraftMod/forge/1.20.4/.gitignore rename to MinecraftMod/neoforge/1.20.4/.gitignore diff --git a/MinecraftMod/forge/1.20.4/build.gradle b/MinecraftMod/neoforge/1.20.4/build.gradle similarity index 100% rename from MinecraftMod/forge/1.20.4/build.gradle rename to MinecraftMod/neoforge/1.20.4/build.gradle diff --git a/MinecraftMod/forge/1.20.4/gradle.properties b/MinecraftMod/neoforge/1.20.4/gradle.properties similarity index 97% rename from MinecraftMod/forge/1.20.4/gradle.properties rename to MinecraftMod/neoforge/1.20.4/gradle.properties index 40f85b9..7bb3044 100644 --- a/MinecraftMod/forge/1.20.4/gradle.properties +++ b/MinecraftMod/neoforge/1.20.4/gradle.properties @@ -19,7 +19,7 @@ neo_version_range=[20.4,) loader_version_range=[2,) # The version of the EffectMC Core to use -effectmc_core_version=3.0 +effectmc_core_version=3.1.0 effectmc_core_version_range=[3.0,4.0) ## Mod Properties @@ -32,7 +32,7 @@ mod_name=EffectMC # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. mod_license=GNU LGPL v3 # The mod version. See https://semver.org/ -mod_version=3.0.0 +mod_version=3.1.0 # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # This should match the base package used for the mod sources. # See https://maven.apache.org/guides/mini/guide-naming-conventions.html diff --git a/MinecraftMod/forge/1.20.4/gradle/wrapper/gradle-wrapper.jar b/MinecraftMod/neoforge/1.20.4/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from MinecraftMod/forge/1.20.4/gradle/wrapper/gradle-wrapper.jar rename to MinecraftMod/neoforge/1.20.4/gradle/wrapper/gradle-wrapper.jar diff --git a/MinecraftMod/forge/1.20.4/gradle/wrapper/gradle-wrapper.properties b/MinecraftMod/neoforge/1.20.4/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from MinecraftMod/forge/1.20.4/gradle/wrapper/gradle-wrapper.properties rename to MinecraftMod/neoforge/1.20.4/gradle/wrapper/gradle-wrapper.properties diff --git a/MinecraftMod/forge/1.20.4/gradlew b/MinecraftMod/neoforge/1.20.4/gradlew similarity index 100% rename from MinecraftMod/forge/1.20.4/gradlew rename to MinecraftMod/neoforge/1.20.4/gradlew diff --git a/MinecraftMod/forge/1.20.6/gradlew.bat b/MinecraftMod/neoforge/1.20.4/gradlew.bat similarity index 100% rename from MinecraftMod/forge/1.20.6/gradlew.bat rename to MinecraftMod/neoforge/1.20.4/gradlew.bat diff --git a/MinecraftMod/neoforge/1.20.4/logs/latest.log b/MinecraftMod/neoforge/1.20.4/logs/latest.log new file mode 100644 index 0000000..e69de29 diff --git a/MinecraftMod/forge/1.20.4/settings.gradle b/MinecraftMod/neoforge/1.20.4/settings.gradle similarity index 100% rename from MinecraftMod/forge/1.20.4/settings.gradle rename to MinecraftMod/neoforge/1.20.4/settings.gradle diff --git a/MinecraftMod/neoforge/1.20.4/src/main/java/com/mosadie/effectmc/EffectMC.java b/MinecraftMod/neoforge/1.20.4/src/main/java/com/mosadie/effectmc/EffectMC.java new file mode 100644 index 0000000..a4d6366 --- /dev/null +++ b/MinecraftMod/neoforge/1.20.4/src/main/java/com/mosadie/effectmc/EffectMC.java @@ -0,0 +1,820 @@ +package com.mosadie.effectmc; + +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.text2speech.Narrator; +import com.mosadie.effectmc.core.EffectExecutor; +import com.mosadie.effectmc.core.EffectMCCore; +import com.mosadie.effectmc.core.WorldState; +import com.mosadie.effectmc.core.effect.*; +import com.mosadie.effectmc.core.effect.internal.Effect; +import com.mosadie.effectmc.core.effect.internal.EffectRequest; +import com.mosadie.effectmc.core.handler.Device; +import com.mosadie.effectmc.core.handler.DeviceType; +import net.minecraft.client.CameraType; +import net.minecraft.client.Minecraft; +import net.minecraft.client.Options; +import net.minecraft.client.gui.components.toasts.SystemToast; +import net.minecraft.client.gui.screens.*; +import net.minecraft.client.gui.screens.inventory.BookViewScreen; +import net.minecraft.client.gui.screens.multiplayer.JoinMultiplayerScreen; +import net.minecraft.client.gui.screens.worldselection.CreateWorldScreen; +import net.minecraft.client.gui.screens.worldselection.SelectWorldScreen; +import net.minecraft.client.multiplayer.ServerData; +import net.minecraft.client.multiplayer.resolver.ServerAddress; +import net.minecraft.client.resources.sounds.SimpleSoundInstance; +import net.minecraft.client.resources.sounds.SoundInstance; +import net.minecraft.client.server.IntegratedServer; +import net.minecraft.commands.Commands; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.nbt.TagParser; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.ComponentContents; +import net.minecraft.network.chat.contents.TranslatableContents; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.sounds.SoundSource; +import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.player.ChatVisiblity; +import net.minecraft.world.entity.player.PlayerModelPart; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.WrittenBookItem; +import net.neoforged.fml.ModList; +import net.neoforged.fml.common.Mod; +import net.neoforged.neoforge.client.event.ClientChatReceivedEvent; +import net.neoforged.neoforge.client.event.RegisterClientCommandsEvent; +import net.neoforged.neoforge.common.NeoForge; +import org.apache.commons.io.IOUtils; +import org.apache.http.Header; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.message.BasicHeader; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +@Mod(EffectMC.MODID) +public class EffectMC implements EffectExecutor { + public final static String MODID = "effectmc"; + + private final EffectMCCore core; + + public static Logger LOGGER = LogManager.getLogger(); + + private static Narrator narrator = Narrator.getNarrator(); + private static RandomSource randomSource = RandomSource.create(); + private static ServerData serverData = new ServerData("", "", ServerData.Type.OTHER); // Used to hold data during Open Screen + + private final HttpClient authedClient; + + public EffectMC() throws IOException { + File configDir = ModList.get().getModFileById(MODID).getFile().getFilePath().resolve("../" + MODID + "/").toFile(); + if (!configDir.exists()) { + if (!configDir.mkdirs()) { + LOGGER.error("Something went wrong creating the config directory!"); + throw new IOException("Failed to create config directory!"); + } + } + File trustFile = configDir.toPath().resolve("trust.json").toFile(); + File configFile = configDir.toPath().resolve("config.json").toFile(); + + + + LOGGER.info("Starting Core"); + core = new EffectMCCore(configFile, trustFile,this); + LOGGER.info("Core Started"); + + LOGGER.info("Starting Server"); + boolean result; + try { + result = core.initServer(); + } catch (URISyntaxException e) { + LOGGER.error("Failed to initialize server due to internal error, please report this!", e); + result = false; + } + LOGGER.info("Server start result: " + result); + + NeoForge.EVENT_BUS.addListener(this::registerClientCommand); + NeoForge.EVENT_BUS.addListener(this::listenForTranslation); + + Header authHeader = new BasicHeader("Authorization", "Bearer " + Minecraft.getInstance().getUser().getAccessToken()); + List
headers = new ArrayList<>(); + headers.add(authHeader); + authedClient = HttpClientBuilder.create().setDefaultHeaders(headers).build(); + } + + public void registerClientCommand(RegisterClientCommandsEvent event) { + LOGGER.info("Registering effectmc command."); + event.getDispatcher().register(Commands.literal("effectmc") + .then(Commands.literal("trust").executes((context -> { + Minecraft.getInstance().execute(core::setTrustFlag); + receiveChatMessage("[EffectMC] Now prompting to trust the next request sent."); + return 0; + }))) + .then(Commands.literal("exportbook").executes((context -> { + if (Minecraft.getInstance().player == null) { + return 0; + } + + ItemStack mainHand = Minecraft.getInstance().player.getMainHandItem(); + ItemStack offHand = Minecraft.getInstance().player.getOffhandItem(); + + ItemStack bookStack = null; + if (mainHand.getItem().equals(Items.WRITTEN_BOOK)) { + bookStack = mainHand; + } else if (offHand.getItem().equals(Items.WRITTEN_BOOK)) { + bookStack = offHand; + } + + if (bookStack == null) { + receiveChatMessage("[EffectMC] Failed to export book: Not holding a book!"); + return 0; + } + + if (bookStack.getTag() == null) { + receiveChatMessage("[EffectMC] Failed to export book: Missing tag."); + return 0; + } + + LOGGER.info("Exported Book JSON: " + bookStack.getTag()); + receiveChatMessage("[EffectMC] Exported the held book to the current log file."); + return 0; + }))).then(Commands.literal("exportitem").executes((context -> { + if (Minecraft.getInstance().player == null) { + LOGGER.info("Null player running exportitem, this shouldn't happen!"); + return 0; + } + CompoundTag tag = new CompoundTag(); + Minecraft.getInstance().player.getMainHandItem().save(tag); + LOGGER.info("Held Item Tag: " + NbtUtils.prettyPrint(tag)); + showItemToast(NbtUtils.prettyPrint(tag), "Exported", Minecraft.getInstance().player.getMainHandItem().getDisplayName().getString()); + receiveChatMessage("[EffectMC] Exported held item data to log file!"); + return 0; + }))).then(Commands.literal("exporteffect").executes(context -> { + core.setExportFlag(); + receiveChatMessage("[EffectMC] Will export the next triggered effect as JSON to the current log file."); + return 0; + })).then(Commands.literal("trigger").then(Commands.argument("json", StringArgumentType.greedyString()).executes((context -> { + String json = StringArgumentType.getString(context, "json"); + EffectRequest request = core.requestFromJson(json); + + if (request == null) { + receiveChatMessage("[EffectMC] Invalid JSON for effect request!"); + return 0; + } + + String worldId = getWorldState() == WorldState.SINGLEPLAYER ? getSPWorldName() : getServerIP(); + + Device device = new Device(worldId, getWorldState() == WorldState.SINGLEPLAYER ? DeviceType.WORLD : DeviceType.SERVER); + + Effect.EffectResult result = core.triggerEffect(device, request); + switch (result.result) { + case SUCCESS -> receiveChatMessage("[EffectMC] Effect \"" + request.getEffectId() + "\" triggered successfully: " + result.message); + case ERROR -> receiveChatMessage("[EffectMC] Error triggering effect: " + result.message); + case UNAUTHORIZED -> receiveChatMessage("[EffectMC] World/Server not trusted. Use /effectmc trust to trust the current world/server."); + case UNKNOWN -> receiveChatMessage("[EffectMC] Unknown effect."); + case SKIPPED -> receiveChatMessage("[EffectMC] Effect skipped: " + result.message); + case UNSUPPORTED -> receiveChatMessage("[EffectMC] Effect unsupported: " + result.message); + } + + return 0; + })))).executes((context -> { + receiveChatMessage("[EffectMC] Available subcommands: exportbook, exportitem, exporteffect, trigger, trust"); + return 0; + }))); + LOGGER.info("Registered effectmc command."); + } + + + private void listenForTranslation(ClientChatReceivedEvent event) { + Component component = event.getMessage(); + + if (component.getContents() instanceof TranslatableContents translationTextComponent) { + + if (translationTextComponent.getKey().equals(EffectMCCore.TRANSLATION_TRIGGER_KEY)) { + event.setCanceled(true); + + if (translationTextComponent.getArgs().length != 1) { + log("Invalid length of args for translation trigger!"); + return; + } + + String data = String.valueOf(translationTextComponent.getArgs()[0]); + + EffectRequest request = core.requestFromJson(data); + + if (request == null) { + log("Invalid request json for translation trigger!"); + return; + } + + String worldId = getWorldState() == WorldState.SINGLEPLAYER ? getSPWorldName() : getServerIP(); + + Device device = new Device(worldId, getWorldState() == WorldState.SINGLEPLAYER ? DeviceType.WORLD : DeviceType.SERVER); + + core.triggerEffect(device, request); + } + } + } + + @Override + public void log(String message) { + LOGGER.info(message); + } + + @Override + public boolean joinServer(String serverIp) { + Minecraft.getInstance().execute(() -> { + leaveIfNeeded(); + + // Create ServerAddress + if (!ServerAddress.isValidAddress(serverIp)) { + LOGGER.error("Invalid server IP!"); + + DisconnectedScreen errorScreen = new DisconnectedScreen(new JoinMultiplayerScreen(new TitleScreen()), Component.literal("Failed to join server!"), Component.literal("Invalid server IP!")); + Minecraft.getInstance().setScreen(errorScreen); + + return; + } + + ServerAddress serverAddress = ServerAddress.parseString(serverIp); + ServerData serverData = new ServerData("EffectMC", serverIp, ServerData.Type.OTHER); + + + LOGGER.info("Connecting to " + serverAddress.getHost()); + // Connect to server + + ConnectScreen.startConnecting(new TitleScreen(), Minecraft.getInstance(), serverAddress, serverData, false); + }); + return true; + } + + @Override + public boolean setSkinLayer(SkinLayerEffect.SKIN_SECTION section, boolean visibility) { + Options options = Minecraft.getInstance().options; + + switch (section) { + + case ALL: + options.toggleModelPart(PlayerModelPart.CAPE, visibility); + // Fall to ALL_BODY + case ALL_BODY: + options.toggleModelPart(PlayerModelPart.HAT, visibility); + options.toggleModelPart(PlayerModelPart.JACKET, visibility); + options.toggleModelPart(PlayerModelPart.LEFT_SLEEVE, visibility); + options.toggleModelPart(PlayerModelPart.LEFT_PANTS_LEG, visibility); + options.toggleModelPart(PlayerModelPart.RIGHT_SLEEVE, visibility); + options.toggleModelPart(PlayerModelPart.RIGHT_PANTS_LEG, visibility); + break; + case CAPE: + options.toggleModelPart(PlayerModelPart.CAPE, visibility); + break; + case JACKET: + options.toggleModelPart(PlayerModelPart.JACKET, visibility); + break; + case LEFT_SLEEVE: + options.toggleModelPart(PlayerModelPart.LEFT_SLEEVE, visibility); + break; + case RIGHT_SLEEVE: + options.toggleModelPart(PlayerModelPart.RIGHT_SLEEVE, visibility); + break; + case LEFT_PANTS_LEG: + options.toggleModelPart(PlayerModelPart.LEFT_PANTS_LEG, visibility); + break; + case RIGHT_PANTS_LEG: + options.toggleModelPart(PlayerModelPart.RIGHT_PANTS_LEG, visibility); + break; + case HAT: + options.toggleModelPart(PlayerModelPart.HAT, visibility); + break; + } + + return true; + } + + @Override + public boolean toggleSkinLayer(SkinLayerEffect.SKIN_SECTION section) { + Options options = Minecraft.getInstance().options; + switch (section) { + + case ALL: + options.toggleModelPart(PlayerModelPart.CAPE, !options.isModelPartEnabled(PlayerModelPart.CAPE)); + // Fall to ALL_BODY + case ALL_BODY: + options.toggleModelPart(PlayerModelPart.HAT, !options.isModelPartEnabled(PlayerModelPart.HAT)); + options.toggleModelPart(PlayerModelPart.JACKET, !options.isModelPartEnabled(PlayerModelPart.JACKET)); + options.toggleModelPart(PlayerModelPart.LEFT_SLEEVE, !options.isModelPartEnabled(PlayerModelPart.LEFT_SLEEVE)); + options.toggleModelPart(PlayerModelPart.LEFT_PANTS_LEG, !options.isModelPartEnabled(PlayerModelPart.LEFT_PANTS_LEG)); + options.toggleModelPart(PlayerModelPart.RIGHT_SLEEVE, !options.isModelPartEnabled(PlayerModelPart.RIGHT_SLEEVE)); + options.toggleModelPart(PlayerModelPart.RIGHT_PANTS_LEG, !options.isModelPartEnabled(PlayerModelPart.RIGHT_PANTS_LEG)); + break; + case CAPE: + options.toggleModelPart(PlayerModelPart.CAPE, !options.isModelPartEnabled(PlayerModelPart.CAPE)); + break; + case JACKET: + options.toggleModelPart(PlayerModelPart.JACKET, !options.isModelPartEnabled(PlayerModelPart.JACKET)); + break; + case LEFT_SLEEVE: + options.toggleModelPart(PlayerModelPart.LEFT_SLEEVE, !options.isModelPartEnabled(PlayerModelPart.LEFT_SLEEVE)); + break; + case RIGHT_SLEEVE: + options.toggleModelPart(PlayerModelPart.RIGHT_SLEEVE, !options.isModelPartEnabled(PlayerModelPart.RIGHT_SLEEVE)); + break; + case LEFT_PANTS_LEG: + options.toggleModelPart(PlayerModelPart.LEFT_PANTS_LEG, !options.isModelPartEnabled(PlayerModelPart.LEFT_PANTS_LEG)); + break; + case RIGHT_PANTS_LEG: + options.toggleModelPart(PlayerModelPart.RIGHT_PANTS_LEG, !options.isModelPartEnabled(PlayerModelPart.RIGHT_PANTS_LEG)); + break; + case HAT: + options.toggleModelPart(PlayerModelPart.HAT, !options.isModelPartEnabled(PlayerModelPart.HAT)); + break; + } + + return true; + } + + @Override + public boolean sendChatMessage(String message) { + if (Minecraft.getInstance().player != null) { + if (message.startsWith("/")) { + LOGGER.info("Sending command message: " + message); + Minecraft.getInstance().player.connection.sendCommand(message.substring(1)); + } else { + LOGGER.info("Sending chat message: " + message); + Minecraft.getInstance().player.connection.sendChat(message); + } + + return true; + } + + return false; + } + + @Override + public boolean receiveChatMessage(String message) { + if (Minecraft.getInstance().player != null) { + LOGGER.info("Showing chat message: " + message); + Minecraft.getInstance().player.displayClientMessage(Component.literal(message), false);//.sendMessage(Component.literal(message), Minecraft.getInstance().player.getUUID()); + + return true; + } + + return false; + } + + @Override + public boolean showTitle(String title, String subtitle) { + LOGGER.info("Showing Title: " + title + " Subtitle: " + subtitle); + Minecraft.getInstance().gui.resetTitleTimes(); + Minecraft.getInstance().gui.setSubtitle(Component.literal(subtitle)); + Minecraft.getInstance().gui.setTitle(Component.literal(title)); + + return true; + } + + @Override + public boolean showActionMessage(String message) { + LOGGER.info("Showing ActionBar message: " + message); + Minecraft.getInstance().gui.setOverlayMessage(Component.literal(message), false); + + return true; + } + + @Override + public boolean triggerDisconnect(DisconnectEffect.NEXT_SCREEN nextScreenType, String title, String message) { + Minecraft.getInstance().execute(() -> { + leaveIfNeeded(); + + Screen nextScreen; + + switch (nextScreenType) { + default: + case MAIN_MENU: + nextScreen = new TitleScreen(); + break; + + case SERVER_SELECT: + nextScreen = new JoinMultiplayerScreen(new TitleScreen()); + break; + + case WORLD_SELECT: + nextScreen = new SelectWorldScreen(new TitleScreen()); + break; + } + + DisconnectedScreen screen = new DisconnectedScreen(nextScreen, Component.literal(title), Component.literal(message)); + Minecraft.getInstance().setScreen(screen); + }); + + return true; + } + + @Override + public boolean playSound(String soundID, String categoryName, float volume, float pitch, boolean repeat, int repeatDelay, String attenuationType, double x, double y, double z, boolean relative, boolean global) { + Minecraft.getInstance().execute(() -> { + ResourceLocation sound = new ResourceLocation(soundID); + + SoundSource category; + try { + category = SoundSource.valueOf(categoryName.toUpperCase()); + } catch (IllegalArgumentException e) { + category = SoundSource.MASTER; + } + + SoundInstance.Attenuation attenuation; + try { + attenuation = SoundInstance.Attenuation.valueOf(attenuationType.toUpperCase()); + } catch (IllegalArgumentException e) { + attenuation = SoundInstance.Attenuation.NONE; + } + + double trueX = x; + double trueY = y; + double trueZ = z; + + if (relative && Minecraft.getInstance().level != null && Minecraft.getInstance().player != null) { + trueX += Minecraft.getInstance().player.getX(); + trueY += Minecraft.getInstance().player.getY(); + trueZ += Minecraft.getInstance().player.getZ(); + } + + Minecraft.getInstance().getSoundManager().play(new SimpleSoundInstance(sound, category, volume, pitch, randomSource, repeat, repeatDelay, attenuation, trueX, trueY, trueZ, global)); + }); + + return true; + } + + @Override + public void showTrustPrompt(Device device) { + Minecraft.getInstance().execute(() -> { + ConfirmScreen screen = new ConfirmScreen(new EffectMCCore.TrustBooleanConsumer(device, core), Component.literal("EffectMC - Trust Prompt"), Component.literal("Do you want to trust this device?\n(Type: " + device.getType() + (device.getType() == DeviceType.OTHER ? " Device Id:" + device.getId() : "") + ")")); + Minecraft.getInstance().setScreen(screen); + }); + } + + @Override + public void resetScreen() { + Minecraft.getInstance().execute(() -> Minecraft.getInstance().setScreen(null)); + } + + @Override + public boolean stopSound(String sound, String categoryName) { + Minecraft.getInstance().execute(() -> { + ResourceLocation location = sound == null ? null : ResourceLocation.tryParse(sound); + SoundSource category = null; + + try { + category = SoundSource.valueOf(categoryName); + } catch (IllegalArgumentException | NullPointerException e) { + // Do nothing, if soundId is non-null Minecraft will auto-search, otherwise Minecraft stops all sounds. + } + + Minecraft.getInstance().getSoundManager().stop(location, category); + }); + + return true; + } + + @Override + public boolean showToast(String title, String subtitle) { + Minecraft.getInstance().execute(() -> Minecraft.getInstance().getToasts().addToast(new SystemToast(SystemToast.SystemToastId.NARRATOR_TOGGLE, Component.literal(title), Component.literal(subtitle)))); + + return true; + } + + @Override + public boolean showItemToast(String itemData, String title, String subtitle) { + Minecraft.getInstance().execute(() -> Minecraft.getInstance().getToasts().addToast(new ItemToast(itemData, Component.literal(title), Component.literal(subtitle)))); + + return true; + } + + @Override + public boolean openBook(JsonObject bookJSON) { + Minecraft.getInstance().execute(() -> { + CompoundTag tag; + try { + tag = TagParser.parseTag(bookJSON.toString()); + } catch (CommandSyntaxException e) { + LOGGER.error("Invalid JSON"); + return; + } + + if (!WrittenBookItem.makeSureTagIsValid(tag)) { + LOGGER.error("Invalid Book JSON"); + return; + } + + ItemStack bookStack = new ItemStack(Items.WRITTEN_BOOK); + bookStack.setTag(tag); + + BookViewScreen.BookAccess bookInfo = BookViewScreen.BookAccess.fromItem(bookStack); + + BookViewScreen screen = new BookViewScreen(bookInfo); + + Minecraft.getInstance().setScreen(screen); + }); + + return true; + } + + @Override + public boolean narrate(String message, boolean interrupt) { + if (narrator.active()) { + Minecraft.getInstance().execute(() -> narrator.say(message, interrupt)); + return true; + } + LOGGER.error("Narrator is unavailable!"); + return false; + } + + @Override + public boolean loadWorld(String worldName) { + Minecraft.getInstance().execute(() -> { + if (Minecraft.getInstance().getLevelSource().levelExists(worldName)) { + leaveIfNeeded(); + + LOGGER.info("Loading world..."); + Minecraft.getInstance().createWorldOpenFlows().checkForBackupAndLoad(worldName, () -> { + LOGGER.info("World load cancelled!"); + Minecraft.getInstance().setScreen(new TitleScreen()); + }); + } else { + LOGGER.warn("World " + worldName + " does not exist!"); + } + }); + + return true; + } + + @Override + public boolean setSkin(URL skinUrl, SetSkinEffect.SKIN_TYPE skinType) { + if (skinUrl == null) { + LOGGER.warn("Skin URL is null!"); + return false; + } + + try { + JsonObject payload = new JsonObject(); + + payload.add("variant", new JsonPrimitive(skinType.getValue())); + payload.add("url", new JsonPrimitive(skinUrl.toString())); + + HttpPost request = new HttpPost("https://api.minecraftservices.com/minecraft/profile/skins"); + request.setEntity(new StringEntity(payload.toString(), ContentType.APPLICATION_JSON)); + + HttpResponse response = authedClient.execute(request); + + if (response.getEntity() != null && response.getEntity().getContentLength() > 0) { + JsonObject responseJSON = core.fromJson(IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8)); + if (responseJSON.has("errorMessage")) { + LOGGER.warn("Failed to update skin! " + responseJSON); + return false; + } + + LOGGER.debug("Skin Update Response: " + responseJSON); + } + + LOGGER.info("Skin updated!"); + return true; + } catch (IOException e) { + LOGGER.warn("Failed to update skin!", e); + return false; + } + } + + public void leaveIfNeeded() { + if (Minecraft.getInstance().level != null) { + LOGGER.info("Disconnecting from world..."); + + Minecraft.getInstance().level.disconnect(); + Minecraft.getInstance().disconnect(); +// Minecraft.getInstance().clearClientLevel(new ProgressScreen(true)); + } + } + + @Override + public boolean openScreen(OpenScreenEffect.SCREEN screen) { + Minecraft.getInstance().execute(() -> { + leaveIfNeeded(); + + switch (screen) { + case MAIN_MENU: + Minecraft.getInstance().setScreen(new TitleScreen()); + break; + case SERVER_SELECT: + Minecraft.getInstance().setScreen(new JoinMultiplayerScreen(new TitleScreen())); + break; + case SERVER_DIRECT_CONNECT: + Minecraft.getInstance().setScreen(new DirectJoinServerScreen(new JoinMultiplayerScreen(new TitleScreen()), this::connectIfTrue, serverData)); + break; + case WORLD_SELECT: + Minecraft.getInstance().setScreen(new SelectWorldScreen(new TitleScreen())); + break; + case WORLD_CREATE: + CreateWorldScreen.openFresh(Minecraft.getInstance(), new SelectWorldScreen(new TitleScreen())); + break; + default: + LOGGER.error("Unknown screen."); + } + }); + return true; + } + + @Override + public boolean setFOV(int fov) { + Minecraft.getInstance().execute(() -> Minecraft.getInstance().options.fov().set(fov)); + return true; + } + + @Override + public boolean setPOV(SetPovEffect.POV pov) { + CameraType mcPov; + + switch (pov) { + default: + case FIRST_PERSON: + mcPov = CameraType.FIRST_PERSON; + break; + + case THIRD_PERSON_BACK: + mcPov = CameraType.THIRD_PERSON_BACK; + break; + + case THIRD_PERSON_FRONT: + mcPov = CameraType.THIRD_PERSON_FRONT; + break; + } + + Minecraft.getInstance().execute(() -> Minecraft.getInstance().options.setCameraType(mcPov)); + return true; + } + + @Override + public boolean setGuiScale(int scale) { + if (Minecraft.getInstance().options.guiScale().get().equals(scale)) { + return true; + } + + Minecraft.getInstance().execute(() -> { + Minecraft.getInstance().options.guiScale().set(scale); + Minecraft.getInstance().options.save(); + Minecraft.getInstance().resizeDisplay(); + }); + return true; + } + + @Override + public boolean setGamma(double gamma) { + Minecraft.getInstance().execute(() -> { + Minecraft.getInstance().options.gamma().set(gamma); + Minecraft.getInstance().options.save(); + }); + return true; + } + + @Override + public boolean setChatVisibility(ChatVisibilityEffect.VISIBILITY visibility) { + ChatVisiblity result; + switch (visibility) { + case SHOW: + result = ChatVisiblity.FULL; + break; + + case COMMANDS_ONLY: + result = ChatVisiblity.SYSTEM; + break; + + case HIDE: + result = ChatVisiblity.HIDDEN; + break; + + default: + return false; + } + + Minecraft.getInstance().execute(() -> { + Minecraft.getInstance().options.chatVisibility().set(result); + Minecraft.getInstance().options.save(); + }); + return true; + } + + @Override + public boolean setRenderDistance(int chunks) { + Minecraft.getInstance().execute(() -> { + Minecraft.getInstance().options.renderDistance().set(chunks); + Minecraft.getInstance().options.save(); + }); + return true; + } + + @Override + public WorldState getWorldState() { + if (Minecraft.getInstance().level == null) { + return WorldState.OTHER; + } + + return Minecraft.getInstance().isLocalServer() ? WorldState.SINGLEPLAYER : WorldState.MULTIPLAYER; + } + + @Override + public String getSPWorldName() { + if (getWorldState() != WorldState.SINGLEPLAYER) { + return null; + } + + IntegratedServer server = Minecraft.getInstance().getSingleplayerServer(); + + if (server != null) { + return server.getWorldData().getLevelName(); + } + + LOGGER.info("Attempted to get SP World Name, but no integrated server was found!"); + return null; + } + + @Override + public String getServerIP() { + if (getWorldState() != WorldState.MULTIPLAYER) { + return null; + } + + if (Minecraft.getInstance().getCurrentServer() != null) { + return Minecraft.getInstance().getCurrentServer().ip; + } + + LOGGER.info("Failed to get Server IP!"); + return null; + } + + @Override + public void setVolume(SetVolumeEffect.VOLUME_CATEGORIES category, int volume) { + Minecraft.getInstance().execute(() -> { + + SoundSource mcSoundSource; + + switch (category) { + case MASTER: + mcSoundSource = SoundSource.MASTER; + break; + case MUSIC: + mcSoundSource = SoundSource.MUSIC; + break; + case RECORDS: + mcSoundSource = SoundSource.RECORDS; + break; + case WEATHER: + mcSoundSource = SoundSource.WEATHER; + break; + case BLOCKS: + mcSoundSource = SoundSource.BLOCKS; + break; + case HOSTILE: + mcSoundSource = SoundSource.HOSTILE; + break; + case NEUTRAL: + mcSoundSource = SoundSource.NEUTRAL; + break; + case PLAYERS: + mcSoundSource = SoundSource.PLAYERS; + break; + case AMBIENT: + mcSoundSource = SoundSource.AMBIENT; + break; + case VOICE: + mcSoundSource = SoundSource.VOICE; + break; + default: + LOGGER.error("Unknown volume category!"); + return; + } + + Minecraft.getInstance().options.getSoundSourceOptionInstance(mcSoundSource).set(volume / 100.0d); + Minecraft.getInstance().options.save(); + }); + } + + private void connectIfTrue(boolean connect) { + if (connect) { + joinServer(serverData.ip); + } else { + Minecraft.getInstance().setScreen(new JoinMultiplayerScreen(new TitleScreen())); + } + } +} diff --git a/MinecraftMod/forge/1.20.4/src/main/java/com/mosadie/effectmc/ItemToast.java b/MinecraftMod/neoforge/1.20.4/src/main/java/com/mosadie/effectmc/ItemToast.java similarity index 100% rename from MinecraftMod/forge/1.20.4/src/main/java/com/mosadie/effectmc/ItemToast.java rename to MinecraftMod/neoforge/1.20.4/src/main/java/com/mosadie/effectmc/ItemToast.java diff --git a/MinecraftMod/forge/1.20.4/src/main/resources/META-INF/mods.toml b/MinecraftMod/neoforge/1.20.4/src/main/resources/META-INF/mods.toml similarity index 100% rename from MinecraftMod/forge/1.20.4/src/main/resources/META-INF/mods.toml rename to MinecraftMod/neoforge/1.20.4/src/main/resources/META-INF/mods.toml diff --git a/MinecraftMod/forge/1.20.4/src/main/resources/pack.mcmeta b/MinecraftMod/neoforge/1.20.4/src/main/resources/pack.mcmeta similarity index 100% rename from MinecraftMod/forge/1.20.4/src/main/resources/pack.mcmeta rename to MinecraftMod/neoforge/1.20.4/src/main/resources/pack.mcmeta diff --git a/MinecraftMod/forge/1.21.3/.gitattributes b/MinecraftMod/neoforge/1.20.6/.gitattributes similarity index 100% rename from MinecraftMod/forge/1.21.3/.gitattributes rename to MinecraftMod/neoforge/1.20.6/.gitattributes diff --git a/MinecraftMod/forge/1.20.6/.gitignore b/MinecraftMod/neoforge/1.20.6/.gitignore similarity index 100% rename from MinecraftMod/forge/1.20.6/.gitignore rename to MinecraftMod/neoforge/1.20.6/.gitignore diff --git a/MinecraftMod/forge/1.20.6/build.gradle b/MinecraftMod/neoforge/1.20.6/build.gradle similarity index 100% rename from MinecraftMod/forge/1.20.6/build.gradle rename to MinecraftMod/neoforge/1.20.6/build.gradle diff --git a/MinecraftMod/forge/1.20.6/gradle.properties b/MinecraftMod/neoforge/1.20.6/gradle.properties similarity index 100% rename from MinecraftMod/forge/1.20.6/gradle.properties rename to MinecraftMod/neoforge/1.20.6/gradle.properties diff --git a/MinecraftMod/forge/1.20.6/gradle/wrapper/gradle-wrapper.jar b/MinecraftMod/neoforge/1.20.6/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from MinecraftMod/forge/1.20.6/gradle/wrapper/gradle-wrapper.jar rename to MinecraftMod/neoforge/1.20.6/gradle/wrapper/gradle-wrapper.jar diff --git a/MinecraftMod/forge/1.20.6/gradle/wrapper/gradle-wrapper.properties b/MinecraftMod/neoforge/1.20.6/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from MinecraftMod/forge/1.20.6/gradle/wrapper/gradle-wrapper.properties rename to MinecraftMod/neoforge/1.20.6/gradle/wrapper/gradle-wrapper.properties diff --git a/MinecraftMod/forge/1.20.6/gradlew b/MinecraftMod/neoforge/1.20.6/gradlew similarity index 100% rename from MinecraftMod/forge/1.20.6/gradlew rename to MinecraftMod/neoforge/1.20.6/gradlew diff --git a/MinecraftMod/forge/1.21/gradlew.bat b/MinecraftMod/neoforge/1.20.6/gradlew.bat similarity index 100% rename from MinecraftMod/forge/1.21/gradlew.bat rename to MinecraftMod/neoforge/1.20.6/gradlew.bat diff --git a/MinecraftMod/forge/1.20.6/settings.gradle b/MinecraftMod/neoforge/1.20.6/settings.gradle similarity index 100% rename from MinecraftMod/forge/1.20.6/settings.gradle rename to MinecraftMod/neoforge/1.20.6/settings.gradle diff --git a/MinecraftMod/forge/1.20.6/src/main/java/com/mosadie/effectmc/EffectMC.java b/MinecraftMod/neoforge/1.20.6/src/main/java/com/mosadie/effectmc/EffectMC.java similarity index 100% rename from MinecraftMod/forge/1.20.6/src/main/java/com/mosadie/effectmc/EffectMC.java rename to MinecraftMod/neoforge/1.20.6/src/main/java/com/mosadie/effectmc/EffectMC.java diff --git a/MinecraftMod/forge/1.20.6/src/main/java/com/mosadie/effectmc/ItemToast.java b/MinecraftMod/neoforge/1.20.6/src/main/java/com/mosadie/effectmc/ItemToast.java similarity index 100% rename from MinecraftMod/forge/1.20.6/src/main/java/com/mosadie/effectmc/ItemToast.java rename to MinecraftMod/neoforge/1.20.6/src/main/java/com/mosadie/effectmc/ItemToast.java diff --git a/MinecraftMod/forge/1.20.6/src/main/resources/META-INF/neoforge.mods.toml b/MinecraftMod/neoforge/1.20.6/src/main/resources/META-INF/neoforge.mods.toml similarity index 100% rename from MinecraftMod/forge/1.20.6/src/main/resources/META-INF/neoforge.mods.toml rename to MinecraftMod/neoforge/1.20.6/src/main/resources/META-INF/neoforge.mods.toml diff --git a/MinecraftMod/forge/1.20.6/src/main/resources/pack.mcmeta b/MinecraftMod/neoforge/1.20.6/src/main/resources/pack.mcmeta similarity index 100% rename from MinecraftMod/forge/1.20.6/src/main/resources/pack.mcmeta rename to MinecraftMod/neoforge/1.20.6/src/main/resources/pack.mcmeta diff --git a/MinecraftMod/forge/1.21.4/.gitattributes b/MinecraftMod/neoforge/1.21.3/.gitattributes similarity index 100% rename from MinecraftMod/forge/1.21.4/.gitattributes rename to MinecraftMod/neoforge/1.21.3/.gitattributes diff --git a/MinecraftMod/forge/1.21.3/.gitignore b/MinecraftMod/neoforge/1.21.3/.gitignore similarity index 100% rename from MinecraftMod/forge/1.21.3/.gitignore rename to MinecraftMod/neoforge/1.21.3/.gitignore diff --git a/MinecraftMod/forge/1.21.3/build.gradle b/MinecraftMod/neoforge/1.21.3/build.gradle similarity index 100% rename from MinecraftMod/forge/1.21.3/build.gradle rename to MinecraftMod/neoforge/1.21.3/build.gradle diff --git a/MinecraftMod/forge/1.21.3/gradle.properties b/MinecraftMod/neoforge/1.21.3/gradle.properties similarity index 100% rename from MinecraftMod/forge/1.21.3/gradle.properties rename to MinecraftMod/neoforge/1.21.3/gradle.properties diff --git a/MinecraftMod/forge/1.21.3/gradle/wrapper/gradle-wrapper.jar b/MinecraftMod/neoforge/1.21.3/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from MinecraftMod/forge/1.21.3/gradle/wrapper/gradle-wrapper.jar rename to MinecraftMod/neoforge/1.21.3/gradle/wrapper/gradle-wrapper.jar diff --git a/MinecraftMod/forge/1.21.3/gradle/wrapper/gradle-wrapper.properties b/MinecraftMod/neoforge/1.21.3/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from MinecraftMod/forge/1.21.3/gradle/wrapper/gradle-wrapper.properties rename to MinecraftMod/neoforge/1.21.3/gradle/wrapper/gradle-wrapper.properties diff --git a/MinecraftMod/forge/1.21.3/gradlew b/MinecraftMod/neoforge/1.21.3/gradlew similarity index 100% rename from MinecraftMod/forge/1.21.3/gradlew rename to MinecraftMod/neoforge/1.21.3/gradlew diff --git a/MinecraftMod/forge/1.21.3/gradlew.bat b/MinecraftMod/neoforge/1.21.3/gradlew.bat similarity index 100% rename from MinecraftMod/forge/1.21.3/gradlew.bat rename to MinecraftMod/neoforge/1.21.3/gradlew.bat diff --git a/MinecraftMod/forge/1.21.3/settings.gradle b/MinecraftMod/neoforge/1.21.3/settings.gradle similarity index 100% rename from MinecraftMod/forge/1.21.3/settings.gradle rename to MinecraftMod/neoforge/1.21.3/settings.gradle diff --git a/MinecraftMod/forge/1.21.3/src/main/java/com/mosadie/effectmc/EffectMC.java b/MinecraftMod/neoforge/1.21.3/src/main/java/com/mosadie/effectmc/EffectMC.java similarity index 100% rename from MinecraftMod/forge/1.21.3/src/main/java/com/mosadie/effectmc/EffectMC.java rename to MinecraftMod/neoforge/1.21.3/src/main/java/com/mosadie/effectmc/EffectMC.java diff --git a/MinecraftMod/forge/1.21.3/src/main/java/com/mosadie/effectmc/ItemToast.java b/MinecraftMod/neoforge/1.21.3/src/main/java/com/mosadie/effectmc/ItemToast.java similarity index 100% rename from MinecraftMod/forge/1.21.3/src/main/java/com/mosadie/effectmc/ItemToast.java rename to MinecraftMod/neoforge/1.21.3/src/main/java/com/mosadie/effectmc/ItemToast.java diff --git a/MinecraftMod/forge/1.21.3/src/main/resources/META-INF/neoforge.mods.toml b/MinecraftMod/neoforge/1.21.3/src/main/resources/META-INF/neoforge.mods.toml similarity index 100% rename from MinecraftMod/forge/1.21.3/src/main/resources/META-INF/neoforge.mods.toml rename to MinecraftMod/neoforge/1.21.3/src/main/resources/META-INF/neoforge.mods.toml diff --git a/MinecraftMod/forge/1.21/.gitattributes b/MinecraftMod/neoforge/1.21.4/.gitattributes similarity index 100% rename from MinecraftMod/forge/1.21/.gitattributes rename to MinecraftMod/neoforge/1.21.4/.gitattributes diff --git a/MinecraftMod/forge/1.21.4/.gitignore b/MinecraftMod/neoforge/1.21.4/.gitignore similarity index 100% rename from MinecraftMod/forge/1.21.4/.gitignore rename to MinecraftMod/neoforge/1.21.4/.gitignore diff --git a/MinecraftMod/forge/1.21.4/build.gradle b/MinecraftMod/neoforge/1.21.4/build.gradle similarity index 100% rename from MinecraftMod/forge/1.21.4/build.gradle rename to MinecraftMod/neoforge/1.21.4/build.gradle diff --git a/MinecraftMod/forge/1.21.4/gradle.properties b/MinecraftMod/neoforge/1.21.4/gradle.properties similarity index 100% rename from MinecraftMod/forge/1.21.4/gradle.properties rename to MinecraftMod/neoforge/1.21.4/gradle.properties diff --git a/MinecraftMod/forge/1.21.4/gradle/wrapper/gradle-wrapper.jar b/MinecraftMod/neoforge/1.21.4/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from MinecraftMod/forge/1.21.4/gradle/wrapper/gradle-wrapper.jar rename to MinecraftMod/neoforge/1.21.4/gradle/wrapper/gradle-wrapper.jar diff --git a/MinecraftMod/forge/1.21.4/gradle/wrapper/gradle-wrapper.properties b/MinecraftMod/neoforge/1.21.4/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from MinecraftMod/forge/1.21.4/gradle/wrapper/gradle-wrapper.properties rename to MinecraftMod/neoforge/1.21.4/gradle/wrapper/gradle-wrapper.properties diff --git a/MinecraftMod/forge/1.21.4/gradlew b/MinecraftMod/neoforge/1.21.4/gradlew similarity index 100% rename from MinecraftMod/forge/1.21.4/gradlew rename to MinecraftMod/neoforge/1.21.4/gradlew diff --git a/MinecraftMod/forge/1.21.4/gradlew.bat b/MinecraftMod/neoforge/1.21.4/gradlew.bat similarity index 100% rename from MinecraftMod/forge/1.21.4/gradlew.bat rename to MinecraftMod/neoforge/1.21.4/gradlew.bat diff --git a/MinecraftMod/forge/1.21.4/settings.gradle b/MinecraftMod/neoforge/1.21.4/settings.gradle similarity index 100% rename from MinecraftMod/forge/1.21.4/settings.gradle rename to MinecraftMod/neoforge/1.21.4/settings.gradle diff --git a/MinecraftMod/forge/1.21.4/src/main/java/com/mosadie/effectmc/EffectMC.java b/MinecraftMod/neoforge/1.21.4/src/main/java/com/mosadie/effectmc/EffectMC.java similarity index 100% rename from MinecraftMod/forge/1.21.4/src/main/java/com/mosadie/effectmc/EffectMC.java rename to MinecraftMod/neoforge/1.21.4/src/main/java/com/mosadie/effectmc/EffectMC.java diff --git a/MinecraftMod/forge/1.21.4/src/main/java/com/mosadie/effectmc/ItemToast.java b/MinecraftMod/neoforge/1.21.4/src/main/java/com/mosadie/effectmc/ItemToast.java similarity index 100% rename from MinecraftMod/forge/1.21.4/src/main/java/com/mosadie/effectmc/ItemToast.java rename to MinecraftMod/neoforge/1.21.4/src/main/java/com/mosadie/effectmc/ItemToast.java diff --git a/MinecraftMod/forge/1.21.4/src/main/resources/META-INF/neoforge.mods.toml b/MinecraftMod/neoforge/1.21.4/src/main/resources/META-INF/neoforge.mods.toml similarity index 100% rename from MinecraftMod/forge/1.21.4/src/main/resources/META-INF/neoforge.mods.toml rename to MinecraftMod/neoforge/1.21.4/src/main/resources/META-INF/neoforge.mods.toml diff --git a/MinecraftMod/neoforge/1.21/.gitattributes b/MinecraftMod/neoforge/1.21/.gitattributes new file mode 100644 index 0000000..f811f6a --- /dev/null +++ b/MinecraftMod/neoforge/1.21/.gitattributes @@ -0,0 +1,5 @@ +# Disable autocrlf on generated files, they always generate with LF +# Add any extra files or paths here to make git stop saying they +# are changed when only line endings change. +src/generated/**/.cache/cache text eol=lf +src/generated/**/*.json text eol=lf diff --git a/MinecraftMod/forge/1.21/.gitignore b/MinecraftMod/neoforge/1.21/.gitignore similarity index 100% rename from MinecraftMod/forge/1.21/.gitignore rename to MinecraftMod/neoforge/1.21/.gitignore diff --git a/MinecraftMod/forge/1.21/build.gradle b/MinecraftMod/neoforge/1.21/build.gradle similarity index 100% rename from MinecraftMod/forge/1.21/build.gradle rename to MinecraftMod/neoforge/1.21/build.gradle diff --git a/MinecraftMod/forge/1.21/gradle.properties b/MinecraftMod/neoforge/1.21/gradle.properties similarity index 100% rename from MinecraftMod/forge/1.21/gradle.properties rename to MinecraftMod/neoforge/1.21/gradle.properties diff --git a/MinecraftMod/forge/1.21/gradle/wrapper/gradle-wrapper.jar b/MinecraftMod/neoforge/1.21/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from MinecraftMod/forge/1.21/gradle/wrapper/gradle-wrapper.jar rename to MinecraftMod/neoforge/1.21/gradle/wrapper/gradle-wrapper.jar diff --git a/MinecraftMod/forge/1.21/gradle/wrapper/gradle-wrapper.properties b/MinecraftMod/neoforge/1.21/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from MinecraftMod/forge/1.21/gradle/wrapper/gradle-wrapper.properties rename to MinecraftMod/neoforge/1.21/gradle/wrapper/gradle-wrapper.properties diff --git a/MinecraftMod/forge/1.21/gradlew b/MinecraftMod/neoforge/1.21/gradlew similarity index 100% rename from MinecraftMod/forge/1.21/gradlew rename to MinecraftMod/neoforge/1.21/gradlew diff --git a/MinecraftMod/neoforge/1.21/gradlew.bat b/MinecraftMod/neoforge/1.21/gradlew.bat new file mode 100644 index 0000000..93e3f59 --- /dev/null +++ b/MinecraftMod/neoforge/1.21/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/MinecraftMod/forge/1.21/settings.gradle b/MinecraftMod/neoforge/1.21/settings.gradle similarity index 100% rename from MinecraftMod/forge/1.21/settings.gradle rename to MinecraftMod/neoforge/1.21/settings.gradle diff --git a/MinecraftMod/forge/1.21/src/main/java/com/mosadie/effectmc/EffectMC.java b/MinecraftMod/neoforge/1.21/src/main/java/com/mosadie/effectmc/EffectMC.java similarity index 100% rename from MinecraftMod/forge/1.21/src/main/java/com/mosadie/effectmc/EffectMC.java rename to MinecraftMod/neoforge/1.21/src/main/java/com/mosadie/effectmc/EffectMC.java diff --git a/MinecraftMod/forge/1.21/src/main/java/com/mosadie/effectmc/ItemToast.java b/MinecraftMod/neoforge/1.21/src/main/java/com/mosadie/effectmc/ItemToast.java similarity index 100% rename from MinecraftMod/forge/1.21/src/main/java/com/mosadie/effectmc/ItemToast.java rename to MinecraftMod/neoforge/1.21/src/main/java/com/mosadie/effectmc/ItemToast.java diff --git a/MinecraftMod/forge/1.21/src/main/resources/META-INF/neoforge.mods.toml b/MinecraftMod/neoforge/1.21/src/main/resources/META-INF/neoforge.mods.toml similarity index 100% rename from MinecraftMod/forge/1.21/src/main/resources/META-INF/neoforge.mods.toml rename to MinecraftMod/neoforge/1.21/src/main/resources/META-INF/neoforge.mods.toml diff --git a/MinecraftMod/forge/1.21/src/main/resources/pack.mcmeta b/MinecraftMod/neoforge/1.21/src/main/resources/pack.mcmeta similarity index 100% rename from MinecraftMod/forge/1.21/src/main/resources/pack.mcmeta rename to MinecraftMod/neoforge/1.21/src/main/resources/pack.mcmeta diff --git a/MinecraftMod/neoforge/update.json b/MinecraftMod/neoforge/update.json new file mode 100644 index 0000000..1078c66 --- /dev/null +++ b/MinecraftMod/neoforge/update.json @@ -0,0 +1,53 @@ +{ + "homepage": "https://github.com/MoSadie/EffectMC", + "1.21.4": { + "3.1.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v3.1.0" + }, + "1.21.3": { + "3.1.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v3.1.0", + "3.0.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v3.0.0" + }, + "1.21.1": { + "3.1.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v3.1.0", + "3.0.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v3.0.0" + }, + "1.21": { + "3.1.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v3.1.0", + "3.0.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v3.0.0", + "2.3.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v2.3.0" + }, + "1.20.6": { + "3.1.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v3.1.0", + "3.0.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v3.0.0", + "2.3.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v2.3.0" + }, + "1.20.4": { + "3.1.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v3.1.0", + "2.3.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v2.3.0" + }, + "1.20.2": { + "2.3.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v2.3.0" + }, + "1.20.1": { + "2.3.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v2.3.0", + "2.2.0": "See https://github.com/MoSadie/EffectMC/releases/tag/v2.2.0" + }, + "promos": { + "1.21.4-latest": "3.1.0", + "1.21.4-recommended": "3.1.0", + "1.21.3-latest": "3.1.0", + "1.21.3-recommended": "3.1.0", + "1.21.1-latest": "3.1.0", + "1.21.1-recommended": "3.1.0", + "1.21-latest": "3.1.0", + "1.21-recommended": "3.1.0", + "1.20.6-latest": "3.1.0", + "1.20.6-recommended": "3.1.0", + "1.20.4-latest": "3.1.0", + "1.20.4-recommended": "3.1.0", + "1.20.2-latest": "2.3.0", + "1.20.2-recommended": "2.3.0", + "1.20.1-latest": "2.3.0", + "1.20.1-recommended": "2.3.0" + } +}