diff --git a/res/script.js b/res/script.js index 50b5dcd..0f894b0 100644 --- a/res/script.js +++ b/res/script.js @@ -2,7 +2,16 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -import init, { create_state, generate, is_valid_mod_id, list_all_minecraft_versions, supports_neoforge, to_mod_id, validate_mod_id } from "./templateer.js"; +import init, { + create_state, + generate, + is_valid_mod_id, + list_all_minecraft_versions, + supports_forge, + supports_neoforge, + to_mod_id, + validate_mod_id +} from "./templateer.js"; await init(); const state = create_state(); @@ -96,7 +105,7 @@ function updateState() { state.project_type = getProjectType(); state.mapping_set = getMappingSet(); state.subprojects.fabric = document.getElementById("fabric-loader-input").checked; - state.subprojects.forge = document.getElementById("forge-loader-input").checked; + state.subprojects.forge = document.getElementById("forge-loader-input").checked && isForgeAvailable(); state.subprojects.neoforge = document.getElementById("neoforge-loader-input").checked && isNeoForgeAvailable(); state.subprojects.quilt = document.getElementById("quilt-loader-input").checked; state.subprojects.fabric_likes = document.getElementById("fabric-like-input").checked && isFabricLikeAvailable(); @@ -134,17 +143,26 @@ function isNeoForgeAvailable() { return supports_neoforge(version); } +function isForgeAvailable() { + const version = mcSelect.value; + return supports_forge(version); +} + function refreshAvailablePlatforms() { - const hasNeoForge = isNeoForgeAvailable(); - const neoForgeProjectInput = document.getElementById("neoforge-project-input"); - const neoForgeLoaderInput = document.getElementById("neoforge-loader-input"); - neoForgeProjectInput.disabled = !hasNeoForge; - neoForgeLoaderInput.disabled = !hasNeoForge; - - // Change project type if Neo is not available. - if (!hasNeoForge && neoForgeProjectInput.checked) { + refreshForgeLikePlatform(isNeoForgeAvailable(), "neoforge"); + refreshForgeLikePlatform(isForgeAvailable(), "forge"); +} + +function refreshForgeLikePlatform(available, id) { + const projectInput = document.getElementById(id + "-project-input"); + const loaderInput = document.getElementById(id + "-loader-input"); + projectInput.disabled = !available; + loaderInput.disabled = !available; + + // Change project type if the platform is not available for this game version. + if (!available && projectInput.checked) { multiplatformInput.checked = true; - neoForgeProjectInput.checked = false; + projectInput.checked = false; refreshDisplayedProjectType(); } } @@ -178,5 +196,6 @@ document.getElementById("generate-button").onclick = async () => { modNameInput.value = state.mod_name; modIdInput.value = state.mod_id; refreshModIdPlaceholder(); +refreshAvailablePlatforms(); document.getElementById("package-input").value = state.package_name; document.getElementById("architectury-api-input").checked = state.dependencies.architectury_api; diff --git a/src/app/generator.rs b/src/app/generator.rs index 36fa75f..f115c86 100644 --- a/src/app/generator.rs +++ b/src/app/generator.rs @@ -44,13 +44,16 @@ pub async fn generate(app: &super::GeneratorApp) -> Result<()> { ); context.put("ARCHITECTURY_GROUP", game_version.architectury_maven_group()); context.put("ARCHITECTURY_PACKAGE", game_version.architectury_package()); - context.put("FORGE_LOADER_MAJOR", game_version.forge_major_version()); + context.maybe_put( + "FORGE_LOADER_MAJOR", + game_version.forge_major_version() + ); context.maybe_put( "NEOFORGE_LOADER_MAJOR", game_version.neoforge_loader_major(), ); context.maybe_put("NEOFORGE_MAJOR", game_version.neoforge_major()); - context.put("FORGE_PACK_FORMAT", game_version.forge_pack_version()); + context.maybe_put("FORGE_PACK_FORMAT", game_version.forge_pack_version()); if let Some((data_pack_format_key, data_pack_format)) = game_version.forge_server_pack_version() { context.put("FORGE_DATA_PACK_FORMAT_KEY", data_pack_format_key); @@ -112,22 +115,31 @@ pub async fn generate(app: &super::GeneratorApp) -> Result<()> { if app.subprojects.forge { context.define("forge"); files.push(Box::pin(forge::all_files(client.clone()))); - variables.push(Box::pin(add_key( - "FORGE_VERSION", - std::future::ready(Ok(versions.forge)), - ))); + if let Some(version) = versions.forge { + variables.push(Box::pin(add_key( + "FORGE_VERSION", + std::future::ready(Ok(version)), + ))); + } platforms.push("forge"); } if app.subprojects.neoforge { context.define("neoforge"); - files.push(Box::pin(neoforge::all_files(client.clone()))); + files.push(Box::pin(neoforge::main_files(client.clone()))); if let Some(version) = versions.neoforge { variables.push(Box::pin(add_key( "NEOFORGE_VERSION", std::future::ready(Ok(version)), ))); } + if game_version == version_resolver::minecraft::MinecraftVersion::Minecraft1_20_4 { + context.put("NEOFORGE_METADATA_FILE_NAME", "mods.toml"); + files.push(Box::pin(neoforge::mods_toml_files(client.clone()))); + } else { + context.put("NEOFORGE_METADATA_FILE_NAME", "neoforge.mods.toml"); + files.push(Box::pin(neoforge::neoforge_mods_toml_files(client.clone()))); + } platforms.push("neoforge"); } @@ -159,20 +171,29 @@ pub async fn generate(app: &super::GeneratorApp) -> Result<()> { } } ProjectType::NeoForge => { - files.push(Box::pin(neoforge_only::all_files(client.clone()))); + files.push(Box::pin(neoforge_only::main_files(client.clone()))); if let Some(version) = versions.neoforge { variables.push(Box::pin(add_key( "NEOFORGE_VERSION", std::future::ready(Ok(version)), ))); } + if game_version == version_resolver::minecraft::MinecraftVersion::Minecraft1_20_4 { + context.put("NEOFORGE_METADATA_FILE_NAME", "mods.toml"); + files.push(Box::pin(neoforge_only::mods_toml_files(client.clone()))); + } else { + context.put("NEOFORGE_METADATA_FILE_NAME", "neoforge.mods.toml"); + files.push(Box::pin(neoforge_only::neoforge_mods_toml_files(client.clone()))); + } } ProjectType::Forge => { files.push(Box::pin(forge_only::all_files(client.clone()))); - variables.push(Box::pin(add_key( - "FORGE_VERSION", - std::future::ready(Ok(versions.forge)), - ))); + if let Some(version) = versions.forge { + variables.push(Box::pin(add_key( + "FORGE_VERSION", + std::future::ready(Ok(version)), + ))); + } } } diff --git a/src/templates/neoforge/build.gradle b/src/templates/neoforge/build.gradle index 95c5c0c..f10b8cf 100644 --- a/src/templates/neoforge/build.gradle +++ b/src/templates/neoforge/build.gradle @@ -46,7 +46,7 @@ dependencies { processResources { inputs.property 'version', project.version - filesMatching('META-INF/mods.toml') { + filesMatching('META-INF/%NEOFORGE_METADATA_FILE_NAME%') { expand version: project.version } } diff --git a/src/templates/neoforge/mod.rs b/src/templates/neoforge/mod.rs index a419c02..fd1b51a 100644 --- a/src/templates/neoforge/mod.rs +++ b/src/templates/neoforge/mod.rs @@ -8,11 +8,19 @@ super::file_data!(GRADLE_PROPERTIES gradle_properties, "neoforge", true, "gradle // Code super::file_data!(MODS_TOML mods_toml, "neoforge", true, "src/main/resources/META-INF/mods.toml"); +super::file_data!(NEOFORGE_MODS_TOML neoforge_mods_toml, "neoforge", true, "src/main/resources/META-INF/neoforge.mods.toml"); super::file_data!(MOD_CLASS mod_class, "neoforge", true, "src/main/java/PACKAGE_DIR/neoforge/ExampleModNeoForge.java"); -super::file_list!(pub all_files, +super::file_list!(pub main_files, build_gradle gradle_properties - mods_toml mod_class ); + +super::file_list!(pub mods_toml_files, + mods_toml +); + +super::file_list!(pub neoforge_mods_toml_files, + neoforge_mods_toml +); diff --git a/src/templates/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/src/templates/neoforge/src/main/resources/META-INF/neoforge.mods.toml new file mode 100644 index 0000000..2fe9524 --- /dev/null +++ b/src/templates/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -0,0 +1,40 @@ +modLoader = "javafml" +loaderVersion = "[%NEOFORGE_LOADER_MAJOR%,)" +#issueTrackerURL = "" +license = "Insert License Here" + +[[mods]] +modId = "%MOD_ID%" +version = "${version}" +displayName = "%MOD_NAME%" +authors = "Me!" +description = ''' +This is an example description! Tell everyone what your mod is about! +''' +#logoFile = "" + +[[dependencies.%MOD_ID%]] +modId = "neoforge" +type = "required" +versionRange = "[%NEOFORGE_MAJOR%,)" +ordering = "NONE" +side = "BOTH" + +[[dependencies.%MOD_ID%]] +modId = "minecraft" +type = "required" +versionRange = "[%MINECRAFT_VERSION%,)" +ordering = "NONE" +side = "BOTH" +#% if architectury_api + +[[dependencies.%MOD_ID%]] +modId = "architectury" +type = "required" +versionRange = "[%ARCHITECTURY_API_VERSION%,)" +ordering = "AFTER" +side = "BOTH" +#% end + +[[mixins]] +config = "%MOD_ID%.mixins.json" diff --git a/src/templates/neoforge_only/build.gradle b/src/templates/neoforge_only/build.gradle index 4c1ec39..df5c3bc 100644 --- a/src/templates/neoforge_only/build.gradle +++ b/src/templates/neoforge_only/build.gradle @@ -38,7 +38,7 @@ dependencies { processResources { inputs.property 'version', project.version - filesMatching('META-INF/mods.toml') { + filesMatching('META-INF/%NEOFORGE_METADATA_FILE_NAME%') { expand version: project.version } } diff --git a/src/templates/neoforge_only/mod.rs b/src/templates/neoforge_only/mod.rs index c9c4b2e..40dd3d2 100644 --- a/src/templates/neoforge_only/mod.rs +++ b/src/templates/neoforge_only/mod.rs @@ -10,13 +10,21 @@ super::file_data!(SETTINGS_GRADLE settings_gradle, "neoforge_only", false, "sett // Code super::file_data!(MIXINS mixins, "neoforge_only", false, "src/main/resources/MOD_ID.mixins.json"); super::file_data!(MODS_TOML mods_toml, "neoforge_only", false, "src/main/resources/META-INF/mods.toml"); +super::file_data!(NEOFORGE_MODS_TOML neoforge_mods_toml, "neoforge_only", false, "src/main/resources/META-INF/neoforge.mods.toml"); super::file_data!(MOD_CLASS mod_class, "neoforge_only", false, "src/main/java/PACKAGE_DIR/ExampleMod.java"); -super::file_list!(pub all_files, +super::file_list!(pub main_files, build_gradle gradle_properties settings_gradle mixins - mods_toml mod_class ); + +super::file_list!(pub mods_toml_files, + mods_toml +); + +super::file_list!(pub neoforge_mods_toml_files, + neoforge_mods_toml +); diff --git a/src/templates/neoforge_only/src/main/resources/META-INF/neoforge.mods.toml b/src/templates/neoforge_only/src/main/resources/META-INF/neoforge.mods.toml new file mode 100644 index 0000000..c3678a6 --- /dev/null +++ b/src/templates/neoforge_only/src/main/resources/META-INF/neoforge.mods.toml @@ -0,0 +1,31 @@ +modLoader = "javafml" +loaderVersion = "[%NEOFORGE_LOADER_MAJOR%,)" +#issueTrackerURL = "" +license = "Insert License Here" + +[[mods]] +modId = "%MOD_ID%" +version = "${version}" +displayName = "%MOD_NAME%" +authors = "Me!" +description = ''' +This is an example description! Tell everyone what your mod is about! +''' +#logoFile = "" + +[[dependencies.%MOD_ID%]] +modId = "neoforge" +type = "required" +versionRange = "[%NEOFORGE_MAJOR%,)" +ordering = "NONE" +side = "BOTH" + +[[dependencies.%MOD_ID%]] +modId = "minecraft" +type = "required" +versionRange = "[%MINECRAFT_VERSION%,)" +ordering = "NONE" +side = "BOTH" + +[[mixins]] +config = "%MOD_ID%.mixins.json" diff --git a/src/web.rs b/src/web.rs index 2f30608..b863684 100644 --- a/src/web.rs +++ b/src/web.rs @@ -90,3 +90,9 @@ pub fn supports_neoforge(game_version: JsValue) -> Result { let game_version: version_resolver::minecraft::MinecraftVersion = serde_wasm_bindgen::from_value(game_version)?; Ok(game_version.neoforge_major().is_some()) } + +#[wasm_bindgen] +pub fn supports_forge(game_version: JsValue) -> Result { + let game_version: version_resolver::minecraft::MinecraftVersion = serde_wasm_bindgen::from_value(game_version)?; + Ok(game_version.forge_major_version().is_some()) +} diff --git a/version_resolver/src/index.rs b/version_resolver/src/index.rs index 729eeac..0f9dabb 100644 --- a/version_resolver/src/index.rs +++ b/version_resolver/src/index.rs @@ -35,7 +35,7 @@ impl VersionIndex { #[derive(Clone, Serialize, Deserialize)] pub struct Versions { pub architectury_api: String, - pub forge: String, + pub forge: Option, pub neoforge: Option, } @@ -51,18 +51,22 @@ impl Versions { ) .await?; - let forge = crate::maven::resolve_matching_version( - &client, - crate::maven::MavenLibrary::forge(), - |version| { - version.starts_with(&format!( - "{}-{}.", - game_version.version(), - game_version.forge_major_version() - )) - }, - ) - .await?; + let forge = if let Some(forge_major) = game_version.forge_major_version() { + Some(crate::maven::resolve_matching_version( + &client, + crate::maven::MavenLibrary::forge(), + |version| { + version.starts_with(&format!( + "{}-{}.", + game_version.version(), + forge_major + )) + }, + ) + .await?) + } else { + None + }; let neoforge = if let Some(major) = game_version.neoforge_major() { Some( diff --git a/version_resolver/src/minecraft.rs b/version_resolver/src/minecraft.rs index ae90353..a388fbc 100644 --- a/version_resolver/src/minecraft.rs +++ b/version_resolver/src/minecraft.rs @@ -31,6 +31,8 @@ pub enum MinecraftVersion { Minecraft1_20_2, #[serde(rename = "1.20.4")] Minecraft1_20_4, + #[serde(rename = "1.20.5")] + Minecraft1_20_5, } impl MinecraftVersion { @@ -41,26 +43,31 @@ impl MinecraftVersion { pub fn version(&self) -> &'static str { match self { - MinecraftVersion::Minecraft1_16_5 => "1.16.5", - MinecraftVersion::Minecraft1_17_1 => "1.17.1", - MinecraftVersion::Minecraft1_18_1 => "1.18.1", - MinecraftVersion::Minecraft1_18_2 => "1.18.2", - MinecraftVersion::Minecraft1_19 => "1.19", - MinecraftVersion::Minecraft1_19_1 => "1.19.1", - MinecraftVersion::Minecraft1_19_2 => "1.19.2", - MinecraftVersion::Minecraft1_19_3 => "1.19.3", - MinecraftVersion::Minecraft1_19_4 => "1.19.4", - MinecraftVersion::Minecraft1_20_1 => "1.20.1", - MinecraftVersion::Minecraft1_20_2 => "1.20.2", - MinecraftVersion::Minecraft1_20_4 => "1.20.4", + Self::Minecraft1_16_5 => "1.16.5", + Self::Minecraft1_17_1 => "1.17.1", + Self::Minecraft1_18_1 => "1.18.1", + Self::Minecraft1_18_2 => "1.18.2", + Self::Minecraft1_19 => "1.19", + Self::Minecraft1_19_1 => "1.19.1", + Self::Minecraft1_19_2 => "1.19.2", + Self::Minecraft1_19_3 => "1.19.3", + Self::Minecraft1_19_4 => "1.19.4", + Self::Minecraft1_20_1 => "1.20.1", + Self::Minecraft1_20_2 => "1.20.2", + Self::Minecraft1_20_4 => "1.20.4", + Self::Minecraft1_20_5 => "1.20.5", } } pub fn java_version(&self) -> JavaVersion { - match self { - MinecraftVersion::Minecraft1_16_5 => JavaVersion::Java8, - MinecraftVersion::Minecraft1_17_1 => JavaVersion::Java9OrNewer(16), - _ => JavaVersion::Java9OrNewer(17), + if self == &Self::Minecraft1_16_5 { + JavaVersion::Java8 + } else if self == &Self::Minecraft1_17_1 { + JavaVersion::Java9OrNewer(16) + } else if &Self::Minecraft1_18_1 <= self && self <= &Self::Minecraft1_20_4 { + JavaVersion::Java9OrNewer(17) + } else { + JavaVersion::Java9OrNewer(21) } } @@ -80,87 +87,92 @@ impl MinecraftVersion { pub fn fabric_api_branch(&self) -> &'static str { match self { - MinecraftVersion::Minecraft1_16_5 => "1.16", - MinecraftVersion::Minecraft1_17_1 => "1.17", - MinecraftVersion::Minecraft1_18_1 => "1.18", + Self::Minecraft1_16_5 => "1.16", + Self::Minecraft1_17_1 => "1.17", + Self::Minecraft1_18_1 => "1.18", _ => self.version(), } } - pub fn forge_major_version(&self) -> &'static str { + pub fn forge_major_version(&self) -> Option<&'static str> { match self { - MinecraftVersion::Minecraft1_16_5 => "36", - MinecraftVersion::Minecraft1_17_1 => "37", - MinecraftVersion::Minecraft1_18_1 => "39", - MinecraftVersion::Minecraft1_18_2 => "40", - MinecraftVersion::Minecraft1_19 => "41", - MinecraftVersion::Minecraft1_19_1 => "42", - MinecraftVersion::Minecraft1_19_2 => "43", - MinecraftVersion::Minecraft1_19_3 => "44", - MinecraftVersion::Minecraft1_19_4 => "45", - MinecraftVersion::Minecraft1_20_1 => "47", - MinecraftVersion::Minecraft1_20_2 => "48", - MinecraftVersion::Minecraft1_20_4 => "49", + Self::Minecraft1_16_5 => Some("36"), + Self::Minecraft1_17_1 => Some("37"), + Self::Minecraft1_18_1 => Some("39"), + Self::Minecraft1_18_2 => Some("40"), + Self::Minecraft1_19 => Some("41"), + Self::Minecraft1_19_1 => Some("42"), + Self::Minecraft1_19_2 => Some("43"), + Self::Minecraft1_19_3 => Some("44"), + Self::Minecraft1_19_4 => Some("45"), + Self::Minecraft1_20_1 => Some("47"), + Self::Minecraft1_20_2 => Some("48"), + Self::Minecraft1_20_4 => Some("49"), + Self::Minecraft1_20_5 => None, } } pub fn architectury_api_version(&self) -> &'static str { match self { - MinecraftVersion::Minecraft1_16_5 => "1", - MinecraftVersion::Minecraft1_17_1 => "2", - MinecraftVersion::Minecraft1_18_1 => "3", - MinecraftVersion::Minecraft1_18_2 => "4", - MinecraftVersion::Minecraft1_19 => "5", - MinecraftVersion::Minecraft1_19_1 => "6.3", - MinecraftVersion::Minecraft1_19_2 => "6", - MinecraftVersion::Minecraft1_19_3 => "7", - MinecraftVersion::Minecraft1_19_4 => "8", - MinecraftVersion::Minecraft1_20_1 => "9", - MinecraftVersion::Minecraft1_20_2 => "10", - MinecraftVersion::Minecraft1_20_4 => "11", + Self::Minecraft1_16_5 => "1", + Self::Minecraft1_17_1 => "2", + Self::Minecraft1_18_1 => "3", + Self::Minecraft1_18_2 => "4", + Self::Minecraft1_19 => "5", + Self::Minecraft1_19_1 => "6.3", + Self::Minecraft1_19_2 => "6", + Self::Minecraft1_19_3 => "7", + Self::Minecraft1_19_4 => "8", + Self::Minecraft1_20_1 => "9", + Self::Minecraft1_20_2 => "10", + Self::Minecraft1_20_4 => "11", + Self::Minecraft1_20_5 => "12", } } pub fn neoforge_loader_major(&self) -> Option<&'static str> { match self { - MinecraftVersion::Minecraft1_20_4 => Some("2"), + Self::Minecraft1_20_4 => Some("2"), + Self::Minecraft1_20_5 => Some("2"), _ => None, } } pub fn neoforge_major(&self) -> Option<&'static str> { match self { - MinecraftVersion::Minecraft1_20_4 => Some("20.4"), + Self::Minecraft1_20_4 => Some("20.4"), + Self::Minecraft1_20_5 => Some("20.5"), _ => None, } } - pub fn forge_pack_version(&self) -> &'static str { + pub fn forge_pack_version(&self) -> Option<&'static str> { match self { - MinecraftVersion::Minecraft1_16_5 => "6", - MinecraftVersion::Minecraft1_17_1 => "7", - MinecraftVersion::Minecraft1_18_1 => "8", - MinecraftVersion::Minecraft1_18_2 => "8", - MinecraftVersion::Minecraft1_19 => "9", - MinecraftVersion::Minecraft1_19_1 => "9", - MinecraftVersion::Minecraft1_19_2 => "9", - MinecraftVersion::Minecraft1_19_3 => "12", - MinecraftVersion::Minecraft1_19_4 => "13", - MinecraftVersion::Minecraft1_20_1 => "15", - MinecraftVersion::Minecraft1_20_2 => "18", - MinecraftVersion::Minecraft1_20_4 => "22", + Self::Minecraft1_16_5 => Some("6"), + Self::Minecraft1_17_1 => Some("7"), + Self::Minecraft1_18_1 => Some("8"), + Self::Minecraft1_18_2 => Some("8"), + Self::Minecraft1_19 => Some("9"), + Self::Minecraft1_19_1 => Some("9"), + Self::Minecraft1_19_2 => Some("9"), + Self::Minecraft1_19_3 => Some("12"), + Self::Minecraft1_19_4 => Some("13"), + Self::Minecraft1_20_1 => Some("15"), + Self::Minecraft1_20_2 => Some("18"), + Self::Minecraft1_20_4 => Some("22"), + Self::Minecraft1_20_5 => None, } } pub fn forge_server_pack_version(&self) -> Option<(&'static str, &'static str)> { match self { - MinecraftVersion::Minecraft1_18_2 => Some(("forge:data_pack_format", "9")), - MinecraftVersion::Minecraft1_19 => Some(("forge:data_pack_format", "10")), - MinecraftVersion::Minecraft1_19_1 => Some(("forge:data_pack_format", "10")), - MinecraftVersion::Minecraft1_19_2 => Some(("forge:data_pack_format", "10")), - MinecraftVersion::Minecraft1_19_3 => Some(("forge:data_pack_format", "10")), - MinecraftVersion::Minecraft1_19_4 => Some(("forge:server_data_pack_format", "11")), - MinecraftVersion::Minecraft1_20_1 => Some(("forge:server_data_pack_format", "15")), + Self::Minecraft1_18_2 => Some(("forge:data_pack_format", "9")), + Self::Minecraft1_19 => Some(("forge:data_pack_format", "10")), + Self::Minecraft1_19_1 => Some(("forge:data_pack_format", "10")), + Self::Minecraft1_19_2 => Some(("forge:data_pack_format", "10")), + Self::Minecraft1_19_3 => Some(("forge:data_pack_format", "10")), + Self::Minecraft1_19_4 => Some(("forge:server_data_pack_format", "11")), + Self::Minecraft1_20_1 => Some(("forge:server_data_pack_format", "15")), _ => None, } }