mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-14 09:05:17 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9c5d527d71 | ||
|
|
e70dc0a4b7 | ||
|
|
e5ad486994 | ||
|
|
1085852834 | ||
|
|
4a16e75a77 | ||
|
|
084952a216 | ||
|
|
6e55ebe21b | ||
|
|
1f988d315f | ||
|
|
764b334c21 | ||
|
|
b018b8f476 | ||
|
|
fb7e264a76 | ||
|
|
f77fa169f8 |
No files matched your search
@@ -0,0 +1,28 @@
|
||||
name: Publish
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ '1.18.x' ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
uses: MinecraftForge/SharedActions/.github/workflows/gradle.yml@main
|
||||
with:
|
||||
java: 17
|
||||
gradle_setup: './gradlew setup'
|
||||
gradle_tasks: 'build publish'
|
||||
artifact_name: 'forge'
|
||||
secrets:
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
PROMOTE_ARTIFACT_WEBHOOK: ${{ secrets.PROMOTE_ARTIFACT_WEBHOOK }}
|
||||
PROMOTE_ARTIFACT_USERNAME: ${{ secrets.PROMOTE_ARTIFACT_USERNAME }}
|
||||
PROMOTE_ARTIFACT_PASSWORD: ${{ secrets.PROMOTE_ARTIFACT_PASSWORD }}
|
||||
MAVEN_USER: ${{ secrets.MAVEN_USER }}
|
||||
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
|
||||
SIGN_KEY_ALIAS: ${{ secrets.SIGN_KEY_ALIAS }}
|
||||
SIGN_KEY_PASSWORD: ${{ secrets.SIGN_KEY_PASSWORD }}
|
||||
SIGN_KEYSTORE_PASSWORD: ${{ secrets.SIGN_KEYSTORE_PASSWORD }}
|
||||
SIGN_KEYSTORE_DATA: ${{ secrets.SIGN_KEYSTORE_DATA }}
|
||||
Vendored
-104
@@ -1,104 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<project>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<name>MinecraftForge_Forge Config DSL Script</name>
|
||||
<groupId>MinecraftForge_Forge</groupId>
|
||||
<artifactId>MinecraftForge_Forge_dsl</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<parent>
|
||||
<groupId>org.jetbrains.teamcity</groupId>
|
||||
<artifactId>configs-dsl-kotlin-parent</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jetbrains-all</id>
|
||||
<url>https://download.jetbrains.com/teamcity-repository</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>teamcity-server</id>
|
||||
<url>https://teamcity.minecraftforge.net/app/dsl-plugins-repository</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>JetBrains</id>
|
||||
<url>https://download.jetbrains.com/teamcity-repository</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>${basedir}</sourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<version>${kotlin.version}</version>
|
||||
|
||||
<configuration/>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>process-sources</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<phase>process-test-sources</phase>
|
||||
<goals>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.teamcity</groupId>
|
||||
<artifactId>teamcity-configs-maven-plugin</artifactId>
|
||||
<version>${teamcity.dsl.version}</version>
|
||||
<configuration>
|
||||
<format>kotlin</format>
|
||||
<dstDir>target/generated-configs</dstDir>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.teamcity</groupId>
|
||||
<artifactId>configs-dsl-kotlin</artifactId>
|
||||
<version>${teamcity.dsl.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.teamcity</groupId>
|
||||
<artifactId>configs-dsl-kotlin-plugins</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<type>pom</type>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-script-runtime</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
Vendored
-208
@@ -1,208 +0,0 @@
|
||||
import jetbrains.buildServer.configs.kotlin.v2019_2.*
|
||||
import jetbrains.buildServer.configs.kotlin.v2019_2.projectFeatures.githubIssues
|
||||
import jetbrains.buildServer.configs.kotlin.*
|
||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
||||
|
||||
/*
|
||||
The settings script is an entry point for defining a TeamCity
|
||||
project hierarchy. The script should contain a single call to the
|
||||
project() function with a Project instance or an init function as
|
||||
an argument.
|
||||
|
||||
VcsRoots, BuildTypes, Templates, and subprojects can be
|
||||
registered inside the project using the vcsRoot(), buildType(),
|
||||
template(), and subProject() methods respectively.
|
||||
|
||||
To debug settings scripts in command-line, run the
|
||||
|
||||
mvnDebug org.jetbrains.teamcity:teamcity-configs-maven-plugin:generate
|
||||
|
||||
command and attach your debugger to the port 8000.
|
||||
|
||||
To debug in IntelliJ Idea, open the 'Maven Projects' tool window (View
|
||||
-> Tool Windows -> Maven Projects), find the generate task node
|
||||
(Plugins -> teamcity-configs -> teamcity-configs:generate), the
|
||||
'Debug' option is available in the context menu for the task.
|
||||
*/
|
||||
|
||||
version = "2021.2"
|
||||
|
||||
project {
|
||||
|
||||
buildType(Build)
|
||||
buildType(BuildSecondaryBranches)
|
||||
buildType(PullRequests)
|
||||
buildType(PullRequestChecks)
|
||||
buildType(PullRequestCompatibility)
|
||||
|
||||
params {
|
||||
text("docker_jdk_version", "17", label = "Gradle version", description = "The version of the JDK to use during execution of tasks in a JDK.", display = ParameterDisplay.HIDDEN, allowEmpty = false)
|
||||
text("docker_gradle_version", "7.4", label = "Gradle version", description = "The version of Gradle to use during execution of Gradle tasks.", display = ParameterDisplay.HIDDEN, allowEmpty = false)
|
||||
text("git_main_branch", "1.19.x", label = "Git Main Branch", description = "The git main or default branch to use in VCS operations.", display = ParameterDisplay.HIDDEN, allowEmpty = false)
|
||||
text("git_branch_spec", """
|
||||
+:refs/heads/(main*)
|
||||
+:refs/heads/(master*)
|
||||
+:refs/heads/(develop|release|staging|main|master)
|
||||
+:refs/heads/(1.*)
|
||||
""".trimIndent(), label = "The branch specification of the repository", description = "By default all main branches are build by the configuration. Modify this value to adapt the branches build.", display = ParameterDisplay.HIDDEN, allowEmpty = true)
|
||||
text("github_repository_name", "MinecraftForge", label = "The github repository name. Used to connect to it in VCS Roots.", description = "This is the repository slug on github. So for example `MinecraftForge` or `MinecraftForge`. It is interpolated into the global VCS Roots.", display = ParameterDisplay.HIDDEN, allowEmpty = false)
|
||||
text("env.PUBLISHED_JAVA_ARTIFACT_ID", "forge", label = "Published artifact id", description = "The maven coordinate artifact id that has been published by this build. Can not be empty.", allowEmpty = false)
|
||||
text("env.PUBLISHED_JAVA_FML_ARTIFACT_ID", "fmlonly", label = "Published fmlonly artifact id", description = "The maven coordinate artifact id for fml only that has been published by this build. Can not be empty.", allowEmpty = false)
|
||||
text("env.PUBLISHED_JAVA_FML_ARTIFACT_VERSION", "0.0.0-SNAPSHOT", label = "Published fmlonly artifact version", description = "The version for fml only that has been published by this build. Can not be empty.", allowEmpty = false)
|
||||
text("env.PUBLISHED_JAVA_GROUP", "net.minecraftforge", label = "Published group", description = "The maven coordinate group that has been published by this build. Can not be empty.", allowEmpty = false)
|
||||
//These are references and not actually keys
|
||||
password("env.CROWDIN_KEY", "credentialsJSON:a3102dbe-805d-4177-9f54-3d2c2eb08fd5", display = ParameterDisplay.HIDDEN)
|
||||
password("env.KEYSTORE_URL", "credentialsJSON:a7ae1c82-8058-4061-8d12-7f6bc2618d2e", display = ParameterDisplay.HIDDEN)
|
||||
password("env.KEYSTORE_PASSWORD", "credentialsJSON:d7b964e3-a1fd-47a8-b892-6f601fe47479", display = ParameterDisplay.HIDDEN)
|
||||
text("additional_publishing_gradle_parameters", "-PcrowdinKey=%env.CROWDIN_KEY% -PkeystoreKeyPass=%env.KEYSTORE_PASSWORD% -PkeystoreStorePass=%env.KEYSTORE_PASSWORD% -Pkeystore=%env.KEYSTORE_URL%", label = "Additional gradle parameters for publish", description = "Contains the additional gradle parameters used during publishing.", display = ParameterDisplay.HIDDEN, allowEmpty = true)
|
||||
|
||||
checkbox("should_execute_build", "false", label = "Should build", description = "Indicates if the build task should be executed.", display = ParameterDisplay.HIDDEN,
|
||||
checked = "true", unchecked = "false")
|
||||
checkbox("should_execute_test", "false", label = "Should build", description = "Indicates if the build task should be executed.", display = ParameterDisplay.HIDDEN,
|
||||
checked = "true", unchecked = "false")
|
||||
}
|
||||
|
||||
features {
|
||||
githubIssues {
|
||||
id = "MinecraftForge_MinecraftForge__IssueTracker"
|
||||
displayName = "MinecraftForge/MinecraftForge"
|
||||
repositoryURL = "https://github.com/MinecraftForge/MinecraftForge"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object Build : BuildType({
|
||||
templates(AbsoluteId("MinecraftForge_SetupGradleUtilsCiEnvironmen"), AbsoluteId("MinecraftForge_BuildWithDiscordNotifications"), AbsoluteId("MinecraftForge_BuildMainBranches"), AbsoluteId("MinecraftForge_SetupProjectUsingGradle"), AbsoluteId("MinecraftForge_BuildUsingGradle"), AbsoluteId("MinecraftForge_PublishProjectUsingGradle"), AbsoluteId("MinecraftForge_TriggersStaticFilesWebpageGenerator"))
|
||||
id("MinecraftForge_MinecraftForge__Build")
|
||||
name = "Build"
|
||||
description = "Builds and Publishes the main branches of the project."
|
||||
|
||||
features {
|
||||
feature {
|
||||
id = "trigger_fml_only_files_generator"
|
||||
type = "triggerBuildFeature"
|
||||
param("triggers", "MinecraftForge_FilesGenerator_GeneratePages")
|
||||
param("parameters", """
|
||||
env.PUBLISHED_JAVA_FML_ARTIFACT_ID~env.PUBLISHED_JAVA_ARTIFACT_ID
|
||||
env.PUBLISHED_JAVA_FML_ARTIFACT_VERSION~env.PUBLISHED_JAVA_ARTIFACT_VERSION
|
||||
env.PUBLISHED_JAVA_GROUP
|
||||
""".trimIndent())
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
object BuildSecondaryBranches : BuildType({
|
||||
templates(AbsoluteId("MinecraftForge_ExcludesBuildingDefaultBranch"), AbsoluteId("MinecraftForge_SetupGradleUtilsCiEnvironmen"), AbsoluteId("MinecraftForge_BuildWithDiscordNotifications"), AbsoluteId("MinecraftForge_BuildMainBranches"), AbsoluteId("MinecraftForge_SetupProjectUsingGradle"), AbsoluteId("MinecraftForge_BuildUsingGradle"))
|
||||
id("MinecraftForge_MinecraftForge__BuildSecondaryBranches")
|
||||
name = "Build - Secondary Branches"
|
||||
description = "Builds and Publishes the secondary branches of the project."
|
||||
params {
|
||||
text("git_branch_spec", """
|
||||
+:refs/heads/(*)
|
||||
-:refs/heads/noci*
|
||||
""".trimIndent(), label = "The branch specification of the repository", description = "By default all main branches are build by the configuration. Modify this value to adapt the branches build.", display = ParameterDisplay.HIDDEN, allowEmpty = true)
|
||||
}
|
||||
vcs {
|
||||
branchFilter = """
|
||||
+:*
|
||||
-:1.*
|
||||
-:<default>
|
||||
""".trimIndent()
|
||||
}
|
||||
})
|
||||
|
||||
object PullRequests : BuildType({
|
||||
templates(AbsoluteId("MinecraftForge_BuildPullRequests"), AbsoluteId("MinecraftForge_SetupGradleUtilsCiEnvironmen"), AbsoluteId("MinecraftForge_BuildWithDiscordNotifications"), AbsoluteId("MinecraftForge_SetupProjectUsingGradle"), AbsoluteId("MinecraftForge_BuildUsingGradle"))
|
||||
id("MinecraftForge_MinecraftForge__PullRequests")
|
||||
name = "Pull Requests"
|
||||
description = "Builds pull requests for the project"
|
||||
|
||||
params {
|
||||
checkbox("should_execute_build", "true", label = "Should build", description = "Indicates if the build task should be executed.", display = ParameterDisplay.HIDDEN,
|
||||
checked = "true", unchecked = "false")
|
||||
text(
|
||||
"gradle_build_task",
|
||||
"assemble",
|
||||
label = "Gradle build task to execute during build",
|
||||
description = "Determines the build task that is executed to build the project.",
|
||||
display = ParameterDisplay.HIDDEN,
|
||||
allowEmpty = false
|
||||
)
|
||||
}
|
||||
|
||||
vcs {
|
||||
branchFilter = """
|
||||
+:*
|
||||
-:1.*
|
||||
-:<default>
|
||||
""".trimIndent()
|
||||
}
|
||||
})
|
||||
|
||||
object PullRequestChecks : BuildType({
|
||||
templates(AbsoluteId("MinecraftForge_BuildPullRequests"), AbsoluteId("MinecraftForge_SetupGradleUtilsCiEnvironmen"), AbsoluteId("MinecraftForge_BuildWithDiscordNotifications"), AbsoluteId("MinecraftForge_SetupProjectUsingGradle"))
|
||||
id("MinecraftForge_MinecraftForge__PullRequestChecks")
|
||||
name = "Pull Requests (Checks)"
|
||||
description = "Checks pull requests for the project"
|
||||
|
||||
steps {
|
||||
gradle {
|
||||
name = "Check"
|
||||
id = "RUNNER_10_Check"
|
||||
|
||||
tasks = "checkAll"
|
||||
gradleParams = "--continue %gradle_custom_args%"
|
||||
enableStacktrace = true
|
||||
dockerImage = "%docker_gradle_image%"
|
||||
dockerRunParameters = """
|
||||
-v "/opt/cache/agent/gradle:/home/gradle/.gradle"
|
||||
-v "/opt/cache/shared/gradle:/home/gradle/rocache:ro"
|
||||
--network=host
|
||||
-u 1000:1000
|
||||
%docker_additional_args%
|
||||
""".trimIndent()
|
||||
}
|
||||
}
|
||||
|
||||
vcs {
|
||||
branchFilter = """
|
||||
+:*
|
||||
-:1.*
|
||||
-:<default>
|
||||
""".trimIndent()
|
||||
}
|
||||
})
|
||||
|
||||
object PullRequestCompatibility : BuildType({
|
||||
templates(AbsoluteId("MinecraftForge_BuildPullRequests"), AbsoluteId("MinecraftForge_SetupGradleUtilsCiEnvironmen"), AbsoluteId("MinecraftForge_BuildWithDiscordNotifications"), AbsoluteId("MinecraftForge_SetupProjectUsingGradle"))
|
||||
id("MinecraftForge_MinecraftForge__PullRequestCompatibility")
|
||||
name = "Pull Requests (Compatibility)"
|
||||
description = "Validates binary compatibility for pull requests made to the project"
|
||||
|
||||
steps {
|
||||
gradle {
|
||||
name = "Validate"
|
||||
id = "RUNNER_10_Compatibility"
|
||||
|
||||
tasks = "checkJarCompatibility"
|
||||
gradleParams = "--continue %gradle_custom_args%"
|
||||
enableStacktrace = true
|
||||
dockerImage = "%docker_gradle_image%"
|
||||
dockerRunParameters = """
|
||||
-v "/opt/cache/agent/gradle:/home/gradle/.gradle"
|
||||
-v "/opt/cache/shared/gradle:/home/gradle/rocache:ro"
|
||||
--network=host
|
||||
-u 1000:1000
|
||||
%docker_additional_args%
|
||||
""".trimIndent()
|
||||
}
|
||||
}
|
||||
|
||||
vcs {
|
||||
branchFilter = """
|
||||
+:*
|
||||
-:1.*
|
||||
-:<default>
|
||||
""".trimIndent()
|
||||
}
|
||||
})
|
||||
+12
-32
@@ -30,19 +30,14 @@ plugins {
|
||||
id 'de.undercouch.download' version '5.1.3'
|
||||
id 'net.minecraftforge.gradle.patcher' version '[6.0,6.2)' apply false
|
||||
id 'net.minecraftforge.gradle.mcp' version '[6.0,6.2)' apply false
|
||||
id 'net.minecraftforge.gradlejarsigner' version '1.0.4'
|
||||
}
|
||||
|
||||
Util.init() //Init all our extension methods!
|
||||
|
||||
jarSigner.autoDetect('forge')
|
||||
|
||||
ext {
|
||||
JAR_SIGNER = null
|
||||
if (project.hasProperty('keystore')) {
|
||||
JAR_SIGNER = [
|
||||
storepass: project.properties.keystoreStorePass,
|
||||
keypass: project.properties.keystoreKeyPass,
|
||||
keystore: project.properties.keystore
|
||||
]
|
||||
}
|
||||
MAPPING_CHANNEL = 'official'
|
||||
MAPPING_VERSION = '1.18.2'
|
||||
MC_VERSION = '1.18.2'
|
||||
@@ -343,27 +338,6 @@ def sharedFmlonlyForge = { Project prj ->
|
||||
changing = true
|
||||
}
|
||||
|
||||
prj.afterEvaluate {
|
||||
[prj.tasks.universalJar, prj.tasks.installerJar].each { t ->
|
||||
def signTask = prj.task([type: SignJar, dependsOn: t], "sign${t.name.capitalize()}") {
|
||||
onlyIf {
|
||||
JAR_SIGNER != null && t.state.failure == null
|
||||
}
|
||||
def jarsigner = JAR_SIGNER == null ? [:] : JAR_SIGNER
|
||||
alias = 'forge'
|
||||
storePass = jarsigner.storepass
|
||||
keyPass = jarsigner.keypass
|
||||
keyStore = jarsigner.keystore
|
||||
inputFile = t.archiveFile.get().asFile
|
||||
outputFile = t.archiveFile.get().asFile
|
||||
doFirst {
|
||||
prj.logger.lifecycle('Signing: ' + inputFile)
|
||||
}
|
||||
}
|
||||
t.finalizedBy(signTask)
|
||||
}
|
||||
}
|
||||
|
||||
prj.tasks.userdevConfig {
|
||||
def launchPrefix = prj.name == "forge" ? "forge" : "fml"
|
||||
getArtifacts(prj, prj.configurations.installer, true).each { key, lib -> libraries.add(lib.name) }
|
||||
@@ -544,6 +518,7 @@ def sharedFmlonlyForge = { Project prj ->
|
||||
//rename 'run.sh', "run_forge_${VERSION.replace('-', '_').sh"
|
||||
//rename 'run.bat', "run_forge_${VERSION.replace('-', '_').bat"
|
||||
}
|
||||
jarSigner.sign(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -658,7 +633,7 @@ project(':fmlonly') {
|
||||
}
|
||||
}
|
||||
|
||||
task installerJson(type: InstallerJson, dependsOn: 'signUniversalJar') {
|
||||
task installerJson(type: InstallerJson, dependsOn: universalJar) {
|
||||
icon = rootProject.file('icon.ico')
|
||||
packedDependencies = PACKED_DEPS
|
||||
|
||||
@@ -1310,7 +1285,7 @@ project(':forge') {
|
||||
}
|
||||
}
|
||||
|
||||
task installerJson(type: InstallerJson, dependsOn: [launcherJson, genClientBinPatches, applyClientBinPatches, applyServerBinPatches, 'signUniversalJar']) {
|
||||
task installerJson(type: InstallerJson, dependsOn: [launcherJson, genClientBinPatches, applyClientBinPatches, applyServerBinPatches, universalJar]) {
|
||||
ext {
|
||||
// remove :fatjar
|
||||
BIN_PATCHER = BINPATCH_TOOL.substring(0, BINPATCH_TOOL.length() - 1 - BINPATCH_TOOL.split(':')[3].length())
|
||||
@@ -1546,9 +1521,10 @@ project(':forge') {
|
||||
}
|
||||
}
|
||||
}
|
||||
jarSigner.sign(it)
|
||||
}
|
||||
|
||||
task installerJar(type: InstallerJar, dependsOn: [genClientBinPatches, genServerBinPatches, 'signUniversalJar', launcherJson]) {
|
||||
task installerJar(type: InstallerJar, dependsOn: [genClientBinPatches, genServerBinPatches, universalJar, launcherJson]) {
|
||||
packedDependencies = PACKED_DEPS
|
||||
from(extraTxts)
|
||||
from(rootProject.file('/forge_installer_logo.png')) {
|
||||
@@ -1609,6 +1585,10 @@ project(':forge') {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named('checkLicenseMain') {
|
||||
mustRunAfter 'extractMapped'
|
||||
}
|
||||
|
||||
reobfJar {
|
||||
tool = FART
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.minecraftforge.eventbus.api.Event;
|
||||
import net.minecraftforge.fml.config.IConfigEvent;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
import net.minecraftforge.fml.event.IModBusEvent;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
|
||||
import net.minecraftforge.forgespi.language.IModInfo;
|
||||
|
||||
import java.util.EnumMap;
|
||||
@@ -58,7 +59,8 @@ public abstract class ModContainer
|
||||
this.modInfo = info;
|
||||
this.modLoadingStage = ModLoadingStage.CONSTRUCT;
|
||||
|
||||
final String displayTestString = info.getConfig().<String>getConfigElement("displayTest").orElse("MATCH_VERSION"); // missing defaults to DEFAULT type
|
||||
final String displayTestString = info.getConfig().<String>getConfigElement("displayTest")
|
||||
.orElseGet(() -> (Boolean) info.getOwningFile().getFileProperties().getOrDefault(ModFileInfo.CLIENT_SIDE_ONLY_PROP, Boolean.FALSE) ? "IGNORE_ALL_VERSION" : "MATCH_VERSION");
|
||||
Supplier<IExtensionPoint.DisplayTest> displayTestSupplier = switch (displayTestString) {
|
||||
case "MATCH_VERSION" -> // default displaytest checks for version string match
|
||||
() -> new IExtensionPoint.DisplayTest(() -> this.modInfo.getVersion().toString(),
|
||||
|
||||
@@ -106,16 +106,17 @@ public class UniqueModListBuilder
|
||||
if (modInfoList.size() > 1) {
|
||||
LOGGER.debug("Found {} mods for first modid {}, selecting most recent based on version data", modInfoList.size(), fullList.getKey());
|
||||
modInfoList.sort(Comparator.comparing(this::getVersion).reversed());
|
||||
LOGGER.debug("Selected file {} for modid {} with version {}", modInfoList.get(0).getFileName(), fullList.getKey(), modInfoList.get(0).getModInfos().get(0).getVersion());
|
||||
LOGGER.debug("Selected file {} for modid {} with version {}", modInfoList.get(0).getFileName(), fullList.getKey(), this.getVersion(modInfoList.get(0)));
|
||||
}
|
||||
return modInfoList.get(0);
|
||||
}
|
||||
|
||||
private ArtifactVersion getVersion(final ModFile mf)
|
||||
{
|
||||
if (mf.getModFileInfo() == null) {
|
||||
if (mf.getModFileInfo() == null || mf.getModInfos() == null || mf.getModInfos().isEmpty()) {
|
||||
return mf.getJarVersion();
|
||||
}
|
||||
|
||||
return mf.getModInfos().get(0).getVersion();
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -18,4 +18,8 @@ public class InvalidModFileException extends RuntimeException
|
||||
super(String.format(Locale.ENGLISH, "%s (%s)", message, ((ModFileInfo)modFileInfo).getFile().getFileName()));
|
||||
this.modFileInfo = modFileInfo;
|
||||
}
|
||||
|
||||
public IModFileInfo getBrokenFile() {
|
||||
return this.modFileInfo;
|
||||
}
|
||||
}
|
||||
+28
-2
@@ -11,6 +11,7 @@ import cpw.mods.modlauncher.Launcher;
|
||||
import cpw.mods.modlauncher.api.IModuleLayerManager;
|
||||
import cpw.mods.modlauncher.util.ServiceLoaderUtils;
|
||||
import net.minecraftforge.fml.loading.EarlyLoadingException;
|
||||
import net.minecraftforge.fml.loading.FMLLoader;
|
||||
import net.minecraftforge.fml.loading.LogMarkers;
|
||||
import net.minecraftforge.fml.loading.UniqueModListBuilder;
|
||||
import net.minecraftforge.fml.loading.progress.StartupMessageManager;
|
||||
@@ -19,6 +20,8 @@ import net.minecraftforge.forgespi.locating.IModFile;
|
||||
import net.minecraftforge.forgespi.locating.IModLocator;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -52,17 +55,40 @@ public class ModDiscoverer {
|
||||
List<EarlyLoadingException.ExceptionData> discoveryErrorData = new ArrayList<>();
|
||||
boolean successfullyLoadedMods = true;
|
||||
|
||||
boolean distIsDedicatedServer = FMLLoader.getDist().isDedicatedServer();
|
||||
//Loop all mod locators to get the prime mods to load from.
|
||||
for (IModLocator locator : modLocatorList) {
|
||||
try {
|
||||
LOGGER.debug(LogMarkers.SCAN,"Trying locator {}", locator);
|
||||
var locatedFiles = locator.scanMods();
|
||||
|
||||
if (locatedFiles.stream().anyMatch(file -> !(file instanceof ModFile))) {
|
||||
LOGGER.error(LogMarkers.SCAN, "A mod locator returned a file which is not a ModFile instance!. They will be skipped!");
|
||||
// Backported from 1.19.2 so we don't accidentally process any bad mod files when getting client-only mods
|
||||
var badModFiles = locatedFiles.stream().filter(file -> !(file instanceof ModFile)).toList();
|
||||
if (!badModFiles.isEmpty()) {
|
||||
LOGGER.error(LogMarkers.SCAN, "Locator {} returned {} files which is are not ModFile instances! They will be skipped!", locator, badModFiles.size());
|
||||
locatedFiles.removeAll(badModFiles);
|
||||
}
|
||||
|
||||
if (distIsDedicatedServer) {
|
||||
var clientOnlyModFiles = locatedFiles.stream()
|
||||
.filter(file -> {
|
||||
// some mod files can have null infos, like javafml, mclanguage, lowcode, and fmlcore
|
||||
@Nullable var info = file.getModFileInfo();
|
||||
|
||||
return info != null && (Boolean) info.getFileProperties().getOrDefault(ModFileInfo.CLIENT_SIDE_ONLY_PROP, Boolean.FALSE);
|
||||
})
|
||||
.toList();
|
||||
if (!clientOnlyModFiles.isEmpty()) {
|
||||
LOGGER.warn(LogMarkers.SCAN, "Locator {} returned {} files which are client-side-only mods, but we're on a dedicated server. They will be skipped!", locator, clientOnlyModFiles.size());
|
||||
locatedFiles.removeAll(clientOnlyModFiles);
|
||||
}
|
||||
}
|
||||
|
||||
LOGGER.debug(LogMarkers.SCAN, "Locator {} found {} valid mod files", locator, locatedFiles.size());
|
||||
handleLocatedFiles(loadedFiles, locatedFiles);
|
||||
} catch (InvalidModFileException imfe) {
|
||||
// We don't generally expect this exception, since it should come from the candidates stream above and be handled in the Locator, but just in case.
|
||||
LOGGER.error(LogMarkers.SCAN, "Locator {} found an invalid mod file {}", locator, imfe.getBrokenFile(), imfe);
|
||||
} catch (EarlyLoadingException exception) {
|
||||
LOGGER.error(LogMarkers.SCAN, "Failed to load mods with locator {}", locator, exception);
|
||||
discoveryErrorData.addAll(exception.getAllData());
|
||||
|
||||
+18
-1
@@ -43,6 +43,10 @@ public class ModFileInfo implements IModFileInfo, IConfigurable
|
||||
private final String license;
|
||||
private final List<String> usesServices;
|
||||
|
||||
public static final String CLIENT_SIDE_ONLY_PROP = "__FORGE_clientSideOnly";
|
||||
|
||||
private static final Map<String, Object> CLIENT_SIDE_ONLY_MAP = Map.of(CLIENT_SIDE_ONLY_PROP, Boolean.TRUE);
|
||||
|
||||
ModFileInfo(final ModFile modFile, final IConfigurable config)
|
||||
{
|
||||
this.modFile = modFile;
|
||||
@@ -56,8 +60,21 @@ public class ModFileInfo implements IModFileInfo, IConfigurable
|
||||
this.license = config.<String>getConfigElement("license")
|
||||
.orElse("");
|
||||
this.showAsResourcePack = config.<Boolean>getConfigElement("showAsResourcePack").orElse(false);
|
||||
boolean clientSideOnly = config.<Boolean>getConfigElement("clientSideOnly").orElse(false);
|
||||
this.usesServices = config.<List<String>>getConfigElement("services").orElse(List.of());
|
||||
this.properties = config.<Map<String, Object>>getConfigElement("properties").orElse(Collections.emptyMap());
|
||||
|
||||
var maybeProps = config.<Map<String, Object>>getConfigElement("properties");
|
||||
if (clientSideOnly) {
|
||||
if (maybeProps.isPresent()) {
|
||||
this.properties = new HashMap<>(maybeProps.get());
|
||||
this.properties.put(CLIENT_SIDE_ONLY_PROP, Boolean.TRUE);
|
||||
} else {
|
||||
this.properties = CLIENT_SIDE_ONLY_MAP;
|
||||
}
|
||||
} else {
|
||||
this.properties = maybeProps.orElse(Collections.emptyMap());
|
||||
}
|
||||
|
||||
this.modFile.setFileProperties(this.properties);
|
||||
this.issueURL = config.<String>getConfigElement("issueTrackerURL").map(StringUtils::toURL).orElse(null);
|
||||
final List<? extends IConfigurable> modConfigs = config.getConfigList("mods");
|
||||
|
||||
@@ -45,7 +45,7 @@ public class Scanner {
|
||||
try (InputStream in = Files.newInputStream(path)){
|
||||
ModClassVisitor mcv = new ModClassVisitor();
|
||||
ClassReader cr = new ClassReader(in);
|
||||
cr.accept(mcv, 0);
|
||||
cr.accept(mcv, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
|
||||
mcv.buildData(result.getClasses(), result.getAnnotations());
|
||||
} catch (IOException | IllegalArgumentException e) {
|
||||
// mark path bad
|
||||
|
||||
@@ -12,6 +12,9 @@ loaderVersion="${loader_version_range}" #mandatory This is typically bumped ever
|
||||
license="${mod_license}"
|
||||
# A URL to refer people to when problems occur with this mod
|
||||
#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional
|
||||
# If your mod is purely client-side and has no multiplayer functionality (be it dedicated servers or Open to LAN),
|
||||
# set this to true, and Forge will set the correct displayTest for you and skip loading your mod on dedicated servers.
|
||||
#clientSideOnly=true #optional - defaults to false if absent
|
||||
# A list of mods - how many allowed here is determined by the individual mod loader
|
||||
[[mods]] #mandatory
|
||||
# The modid of the mod
|
||||
@@ -36,7 +39,7 @@ authors="${mod_authors}" #optional
|
||||
# IGNORE_ALL_VERSION means that your mod will not cause a red X if it's present on the client or the server. This is a special case and should only be used if your mod has no server component.
|
||||
# NONE means that no display test is set on your mod. You need to do this yourself, see IExtensionPoint.DisplayTest for more information. You can define any scheme you wish with this value.
|
||||
# IMPORTANT NOTE: this is NOT an instruction as to which environments (CLIENT or DEDICATED SERVER) your mod loads on. Your mod should load (and maybe do nothing!) whereever it finds itself.
|
||||
#displayTest="MATCH_VERSION" # MATCH_VERSION is the default if nothing is specified (#optional)
|
||||
#displayTest="MATCH_VERSION" # if nothing is specified, MATCH_VERSION is the default when clientSideOnly=false, otherwise IGNORE_ALL_VERSION when clientSideOnly=true (#optional)
|
||||
|
||||
# The description text for the mod (multi line!) (#mandatory)
|
||||
description='''${mod_description}'''
|
||||
|
||||
@@ -8,6 +8,14 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -266,6 +_,7 @@
|
||||
|
||||
public boolean m_108700_(boolean p_108701_) {
|
||||
ServerboundPlayerActionPacket.Action serverboundplayeractionpacket$action = p_108701_ ? ServerboundPlayerActionPacket.Action.DROP_ALL_ITEMS : ServerboundPlayerActionPacket.Action.DROP_ITEM;
|
||||
+ if (m_6117_() && m_7655_() == InteractionHand.MAIN_HAND && (p_108701_ || m_21211_().m_41613_() == 1)) m_5810_(); // Forge: fix MC-231097 on the clientside
|
||||
ItemStack itemstack = this.m_150109_().m_182403_(p_108701_);
|
||||
this.f_108617_.m_104955_(new ServerboundPlayerActionPacket(serverboundplayeractionpacket$action, BlockPos.f_121853_, Direction.DOWN));
|
||||
return !itemstack.m_41619_();
|
||||
@@ -461,6 +_,11 @@
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,26 @@
|
||||
--- a/net/minecraft/resources/ResourceLocation.java
|
||||
+++ b/net/minecraft/resources/ResourceLocation.java
|
||||
@@ -38,10 +_,12 @@
|
||||
@@ -38,14 +_,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ /** Forge: Consider using {@link #parse(String)} instead, as Mojang made this constructor private in Vanilla 1.21 */
|
||||
+ /** @deprecated Forge: Consider using {@link #parse(String)} instead, as Mojang made this constructor private in 1.21 */
|
||||
+ @Deprecated(forRemoval = true, since = "1.20.6")
|
||||
public ResourceLocation(String p_135809_) {
|
||||
this(m_135832_(p_135809_, ':'));
|
||||
}
|
||||
|
||||
+ /** Forge: Consider using {@link #fromNamespaceAndPath(String, String)} instead, as Mojang made this constructor private in Vanilla 1.21 */
|
||||
+ /** @deprecated Forge: Consider using {@link #fromNamespaceAndPath(String, String)} instead, as Mojang made this constructor private in 1.21 */
|
||||
+ @Deprecated(forRemoval = true, since = "1.20.6")
|
||||
public ResourceLocation(String p_135811_, String p_135812_) {
|
||||
this(new String[]{p_135811_, p_135812_});
|
||||
}
|
||||
|
||||
+ /** @deprecated Forge: Consider using {@link #bySeparator(String, char)} instead, as Mojang removed this method in 1.21 */
|
||||
+ @Deprecated(forRemoval = true, since = "1.20.6")
|
||||
public static ResourceLocation m_135822_(String p_135823_, char p_135824_) {
|
||||
return new ResourceLocation(m_135832_(p_135823_, p_135824_));
|
||||
}
|
||||
@@ -116,6 +_,12 @@
|
||||
return i;
|
||||
}
|
||||
@@ -26,19 +34,121 @@
|
||||
public String m_179910_() {
|
||||
return this.toString().replace('/', '_').replace(':', '_');
|
||||
}
|
||||
@@ -182,5 +_,15 @@
|
||||
@@ -182,5 +_,117 @@
|
||||
public JsonElement serialize(ResourceLocation p_135855_, Type p_135856_, JsonSerializationContext p_135857_) {
|
||||
return new JsonPrimitive(p_135855_.toString());
|
||||
}
|
||||
+ }
|
||||
+
|
||||
+ /** Forge: Backport of Vanilla 1.21 method */
|
||||
+ // FORGE: BACKPORTS FROM 1.21
|
||||
+
|
||||
+ /** Forge: This is a backported method from 1.21, and is the replacement for {@link #ResourceLocation(String, String)}. */
|
||||
+ public static ResourceLocation fromNamespaceAndPath(String namespace, String path) {
|
||||
+ return new ResourceLocation(namespace, path);
|
||||
+ }
|
||||
+
|
||||
+ /** Forge: Backport of Vanilla 1.21 method */
|
||||
+ /** Forge: This is a backported method from 1.21, and is the replacement for {@link #ResourceLocation(String)}. */
|
||||
+ public static ResourceLocation parse(String location) {
|
||||
+ return new ResourceLocation(location);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Forge: This is a backported method from 1.21, and acts as an alternative to using {@link #parse(String)}. If you
|
||||
+ * know for sure you are going to be using the {@linkplain #DEFAULT_NAMESPACE default namespace}
|
||||
+ * ({@code "minecraft"}), use this.
|
||||
+ */
|
||||
+ public static ResourceLocation withDefaultNamespace(String path) {
|
||||
+ return new ResourceLocation(f_179908_, assertValidPath(f_179908_, path), null);
|
||||
+ }
|
||||
+
|
||||
+ /** Forge: This is a backported method from 1.21, and is the replacement for {@link #of(String, char)}. */
|
||||
+ public static ResourceLocation bySeparator(String location, char separator) {
|
||||
+ return m_135822_(location, separator);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Forge: This is a backported method from 1.21, and is the same as {@link #bySeparator(String, char)} but returns
|
||||
+ * {@code null} if a resource location cannot be created.
|
||||
+ */
|
||||
+ public static @Nullable ResourceLocation tryBySeparator(String location, char separator) {
|
||||
+ int i = location.indexOf(separator);
|
||||
+ if (i >= 0) {
|
||||
+ String s = location.substring(i + 1);
|
||||
+ if (!m_135841_(s)) {
|
||||
+ return null;
|
||||
+ } else if (i != 0) {
|
||||
+ String s1 = location.substring(0, i);
|
||||
+ return m_135843_(s1) ? new ResourceLocation(s1, s, null) : null;
|
||||
+ } else {
|
||||
+ return new ResourceLocation(f_179908_, s, null);
|
||||
+ }
|
||||
+ } else {
|
||||
+ return m_135841_(location) ? new ResourceLocation(f_179908_, location, null) : null;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // FORGE: BACKPORTS FROM 1.19.3
|
||||
+
|
||||
+ /** Forge: Dummy for {@link #ResourceLocation(String, String, ForgeDummy)} */
|
||||
+ private interface ForgeDummy { }
|
||||
+
|
||||
+ /** Forge: Backported constructor from 1.19.3, which skips additional validations. */
|
||||
+ private ResourceLocation(String namespace, String path, @Nullable ForgeDummy dummy) {
|
||||
+ this.f_135804_ = namespace;
|
||||
+ this.f_135805_ = path;
|
||||
+ }
|
||||
+
|
||||
+ /** Forge: Backported method from 1.19.3 to handle path assertion without needing to use the constructor. */
|
||||
+ private static String assertValidPath(String namespace, String path) {
|
||||
+ if (!m_135841_(path)) {
|
||||
+ throw new ResourceLocationException("Non [a-z0-9/._-] character in path of location: " + namespace + ":" + path);
|
||||
+ } else {
|
||||
+ return path;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /** Forge: This is a backported method from 1.19.3, can be used to quickly create a new resource location with a different path. */
|
||||
+ public ResourceLocation withPath(String path) {
|
||||
+ return new ResourceLocation(this.f_135804_, assertValidPath(this.f_135804_, path), null);
|
||||
+ }
|
||||
+
|
||||
+ /** Forge: This is a backported method from 1.19.3, can be used to quickly create a new resource location with a modified path. */
|
||||
+ public ResourceLocation withPath(java.util.function.UnaryOperator<String> pathFunction) {
|
||||
+ return this.withPath(pathFunction.apply(this.f_135805_));
|
||||
+ }
|
||||
+
|
||||
+ /** Forge: This is a backported method from 1.19.3, can be used to quickly create a new resource location with a prefixed path. */
|
||||
+ public ResourceLocation withPrefix(String prefix) {
|
||||
+ return this.withPath(prefix + this.f_135805_);
|
||||
+ }
|
||||
+
|
||||
+ /** Forge: This is a backported method from 1.19.3, can be used to quickly create a new resource location with a suffixed path. */
|
||||
+ public ResourceLocation withSuffix(String suffix) {
|
||||
+ return this.withPath(this.f_135805_ + suffix);
|
||||
+ }
|
||||
+
|
||||
+ /** Forge: This is a backported method from 1.19.3, can be used to quickly create a language key with a prefix and a suffix. */
|
||||
+ public String toLanguageKey(String prefix, String suffix) {
|
||||
+ return this.toLanguageKey(prefix) + "." + suffix;
|
||||
+ }
|
||||
+
|
||||
+ // FORGE: BACKPORTS FROM 1.19
|
||||
+
|
||||
+ /** Forge: This is a backported method from 1.19.3, can be used to quickly create a language key. */
|
||||
+ public String toLanguageKey() {
|
||||
+ return this.f_135804_ + "." + this.f_135805_;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Forge: This is a backported method from 1.19.3, can be used to quickly create a language key, skipping the
|
||||
+ * namespace if it is {@code "minecraft"}.
|
||||
+ */
|
||||
+ public String toShortLanguageKey() {
|
||||
+ return this.f_135804_.equals("minecraft") ? this.f_135805_ : this.toLanguageKey();
|
||||
+ }
|
||||
+
|
||||
+ /** Forge: This is a backported method from 1.19.3, can be used to quickly create a language key with a prefix. */
|
||||
+ public String toLanguageKey(String prefix) {
|
||||
+ return prefix + "." + this.toLanguageKey();
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,15 @@
|
||||
--- a/net/minecraft/server/Bootstrap.java
|
||||
+++ b/net/minecraft/server/Bootstrap.java
|
||||
@@ -55,6 +_,8 @@
|
||||
@@ -55,6 +_,13 @@
|
||||
CauldronInteraction.m_175649_();
|
||||
ArgumentTypes.m_121586_();
|
||||
Registry.m_206101_();
|
||||
+ net.minecraftforge.registries.GameData.vanillaSnapshot();
|
||||
+ // Forge: Hacky fix to ensure that NetworkConstants is loaded before mods are constructed.
|
||||
+ // Many older mods use network internals that shouldn't be used, yet are exposed so they get used anyways.
|
||||
+ // This can cause class-loading issues with ForgeMod loading NetworkConstants and HandshakeResolver.
|
||||
+ // To ensure that doesn't happen, we load it here and now. This is not an issue in 1.20.2 and newer.
|
||||
+ net.minecraftforge.network.NetworkHooks.init();
|
||||
+ if (false) // skip redirectOutputToLog, Forge already redirects stdout and stderr output to log so that they print with more context
|
||||
m_135890_();
|
||||
}
|
||||
|
||||
@@ -84,6 +84,14 @@
|
||||
}
|
||||
|
||||
}
|
||||
@@ -640,6 +_,7 @@
|
||||
return Registry.f_122826_.m_7981_(p_8648_.m_6095_()).toString();
|
||||
});
|
||||
profilerfiller.m_6174_("tickNonPassenger");
|
||||
+ if (p_8648_.canUpdate())
|
||||
p_8648_.m_8119_();
|
||||
this.m_46473_().m_7238_();
|
||||
|
||||
@@ -656,9 +_,10 @@
|
||||
++p_8664_.f_19797_;
|
||||
ProfilerFiller profilerfiller = this.m_46473_();
|
||||
|
||||
@@ -240,12 +240,13 @@
|
||||
public TextFilter m_8967_() {
|
||||
return this.f_8939_;
|
||||
}
|
||||
@@ -1511,11 +_,13 @@
|
||||
@@ -1511,11 +_,14 @@
|
||||
|
||||
public boolean m_182294_(boolean p_182295_) {
|
||||
Inventory inventory = this.m_150109_();
|
||||
+ ItemStack selected = inventory.m_36056_();
|
||||
+ if (selected.m_41619_() || !selected.onDroppedByPlayer(this)) return false;
|
||||
+ if (m_6117_() && m_7655_() == InteractionHand.MAIN_HAND && (p_182295_ || selected.m_41613_() == 1)) m_5810_(); // Forge: fix MC-231097 on the serverside
|
||||
ItemStack itemstack = inventory.m_182403_(p_182295_);
|
||||
this.f_36096_.m_182417_(inventory, inventory.f_35977_).ifPresent((p_182293_) -> {
|
||||
this.f_36096_.m_150404_(p_182293_, inventory.m_36056_());
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
--- a/net/minecraft/world/entity/npc/VillagerTrades.java
|
||||
+++ b/net/minecraft/world/entity/npc/VillagerTrades.java
|
||||
@@ -151,6 +_,7 @@
|
||||
private final int f_35667_;
|
||||
|
||||
public EmeraldsForVillagerTypeItem(int p_35669_, int p_35670_, int p_35671_, Map<VillagerType, Item> p_35672_) {
|
||||
+ if (false) // FORGE: Modders can add custom villager types, so remove this validation
|
||||
Registry.f_122868_.m_123024_().filter((p_35680_) -> {
|
||||
return !p_35672_.containsKey(p_35680_);
|
||||
}).findAny().ifPresent((p_35677_) -> {
|
||||
@@ -165,7 +_,9 @@
|
||||
@Nullable
|
||||
public MerchantOffer m_5670_(Entity p_35674_, Random p_35675_) {
|
||||
if (p_35674_ instanceof VillagerDataHolder) {
|
||||
- ItemStack itemstack = new ItemStack(this.f_35664_.get(((VillagerDataHolder)p_35674_).m_7141_().m_35560_()), this.f_35665_);
|
||||
+ Item item = this.f_35664_.get(((VillagerDataHolder)p_35674_).m_7141_().m_35560_());
|
||||
+ if (item == null) return null; // FORGE: Account for modded villager types by returning null if there is no trade
|
||||
+ ItemStack itemstack = new ItemStack(item, this.f_35665_);
|
||||
return new MerchantOffer(itemstack, new ItemStack(Items.f_42616_), this.f_35666_, this.f_35667_, 0.05F);
|
||||
} else {
|
||||
return null;
|
||||
@@ -0,0 +1,12 @@
|
||||
--- a/net/minecraft/world/entity/npc/VillagerType.java
|
||||
+++ b/net/minecraft/world/entity/npc/VillagerType.java
|
||||
@@ -65,4 +_,9 @@
|
||||
public static VillagerType m_204073_(Holder<Biome> p_204074_) {
|
||||
return p_204074_.m_203543_().map(f_35827_::get).orElse(f_35821_);
|
||||
}
|
||||
+
|
||||
+ /** FORGE: Registers the VillagerType that will spawn in the given biome. This method should be called during FMLCommonSetupEvent using event.enqueueWork() */
|
||||
+ public static void registerBiomeType(ResourceKey<Biome> biomeKey, VillagerType villagerType) {
|
||||
+ f_35827_.put(biomeKey, villagerType);
|
||||
+ }
|
||||
}
|
||||
@@ -135,14 +135,23 @@
|
||||
if (!this.f_19853_.f_46443_) {
|
||||
this.m_36246_(Stats.f_12982_.m_12902_(this.f_20935_.m_41720_()));
|
||||
}
|
||||
@@ -859,6 +_,7 @@
|
||||
@@ -857,10 +_,15 @@
|
||||
if (p_36383_ >= 3.0F) {
|
||||
int i = 1 + Mth.m_14143_(p_36383_);
|
||||
InteractionHand interactionhand = this.m_7655_();
|
||||
+ // FORGE: cache this.useItem -- if this.stopUsingItem() is called, it will be set to ItemStack.EMPTY
|
||||
+ ItemStack currentItem = this.f_20935_;
|
||||
this.f_20935_.m_41622_(i, this, (p_36149_) -> {
|
||||
p_36149_.m_21190_(interactionhand);
|
||||
+ net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(this, this.f_20935_, interactionhand);
|
||||
+ if (this.f_20935_ == currentItem) this.m_5810_(); // Forge: fix MC-168573
|
||||
});
|
||||
if (this.f_20935_.m_41619_()) {
|
||||
- if (this.f_20935_.m_41619_()) {
|
||||
+ // FORGE: use cached item since this.useItem could be ItemStack.EMPTY
|
||||
+ if (currentItem.m_41619_()) {
|
||||
if (interactionhand == InteractionHand.MAIN_HAND) {
|
||||
this.m_8061_(EquipmentSlot.MAINHAND, ItemStack.f_41583_);
|
||||
} else {
|
||||
@@ -877,10 +_,13 @@
|
||||
|
||||
protected void m_6475_(DamageSource p_36312_, float p_36313_) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/world/level/block/ChorusFlowerBlock.java
|
||||
+++ b/net/minecraft/world/level/block/ChorusFlowerBlock.java
|
||||
@@ -43,7 +_,7 @@
|
||||
@@ -43,11 +_,11 @@
|
||||
BlockPos blockpos = p_51704_.m_7494_();
|
||||
if (p_51703_.m_46859_(blockpos) && blockpos.m_123342_() < p_51703_.m_151558_()) {
|
||||
int i = p_51702_.m_61143_(f_51647_);
|
||||
@@ -9,6 +9,20 @@
|
||||
boolean flag = false;
|
||||
boolean flag1 = false;
|
||||
BlockState blockstate = p_51703_.m_8055_(p_51704_.m_7495_());
|
||||
- if (blockstate.m_60713_(Blocks.f_50259_)) {
|
||||
+ if (blockstate.m_60713_(Blocks.f_50259_) || blockstate.m_204336_(net.minecraftforge.common.Tags.Blocks.CHORUS_ADDITIONALLY_GROWS_ON)) {
|
||||
flag = true;
|
||||
} else if (blockstate.m_60713_(this.f_51648_)) {
|
||||
int j = 1;
|
||||
@@ -55,7 +_,7 @@
|
||||
for(int k = 0; k < 4; ++k) {
|
||||
BlockState blockstate1 = p_51703_.m_8055_(p_51704_.m_6625_(j + 1));
|
||||
if (!blockstate1.m_60713_(this.f_51648_)) {
|
||||
- if (blockstate1.m_60713_(Blocks.f_50259_)) {
|
||||
+ if (blockstate1.m_60713_(Blocks.f_50259_) || blockstate1.m_204336_(net.minecraftforge.common.Tags.Blocks.CHORUS_ADDITIONALLY_GROWS_ON)) {
|
||||
flag1 = true;
|
||||
}
|
||||
break;
|
||||
@@ -99,7 +_,7 @@
|
||||
} else {
|
||||
this.m_51658_(p_51703_, p_51704_);
|
||||
@@ -18,3 +32,12 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,7 +_,7 @@
|
||||
|
||||
public boolean m_7898_(BlockState p_51683_, LevelReader p_51684_, BlockPos p_51685_) {
|
||||
BlockState blockstate = p_51684_.m_8055_(p_51685_.m_7495_());
|
||||
- if (!blockstate.m_60713_(this.f_51648_) && !blockstate.m_60713_(Blocks.f_50259_)) {
|
||||
+ if (!blockstate.m_60713_(this.f_51648_) && !blockstate.m_60713_(Blocks.f_50259_) && !blockstate.m_204336_(net.minecraftforge.common.Tags.Blocks.CHORUS_ADDITIONALLY_GROWS_ON)) {
|
||||
if (!blockstate.m_60795_()) {
|
||||
return false;
|
||||
} else {
|
||||
@@ -0,0 +1,36 @@
|
||||
--- a/net/minecraft/world/level/block/ChorusPlantBlock.java
|
||||
+++ b/net/minecraft/world/level/block/ChorusPlantBlock.java
|
||||
@@ -30,7 +_,7 @@
|
||||
BlockState blockstate3 = p_51711_.m_8055_(p_51712_.m_142126_());
|
||||
BlockState blockstate4 = p_51711_.m_8055_(p_51712_.m_142128_());
|
||||
BlockState blockstate5 = p_51711_.m_8055_(p_51712_.m_142125_());
|
||||
- return this.m_49966_().m_61124_(f_55153_, Boolean.valueOf(blockstate.m_60713_(this) || blockstate.m_60713_(Blocks.f_50491_) || blockstate.m_60713_(Blocks.f_50259_))).m_61124_(f_55152_, Boolean.valueOf(blockstate1.m_60713_(this) || blockstate1.m_60713_(Blocks.f_50491_))).m_61124_(f_55148_, Boolean.valueOf(blockstate2.m_60713_(this) || blockstate2.m_60713_(Blocks.f_50491_))).m_61124_(f_55149_, Boolean.valueOf(blockstate3.m_60713_(this) || blockstate3.m_60713_(Blocks.f_50491_))).m_61124_(f_55150_, Boolean.valueOf(blockstate4.m_60713_(this) || blockstate4.m_60713_(Blocks.f_50491_))).m_61124_(f_55151_, Boolean.valueOf(blockstate5.m_60713_(this) || blockstate5.m_60713_(Blocks.f_50491_)));
|
||||
+ return this.m_49966_().m_61124_(f_55153_, Boolean.valueOf(blockstate.m_60713_(this) || blockstate.m_60713_(Blocks.f_50491_) || blockstate.m_60713_(Blocks.f_50259_) || blockstate.m_204336_(net.minecraftforge.common.Tags.Blocks.CHORUS_ADDITIONALLY_GROWS_ON))).m_61124_(f_55152_, Boolean.valueOf(blockstate1.m_60713_(this) || blockstate1.m_60713_(Blocks.f_50491_))).m_61124_(f_55148_, Boolean.valueOf(blockstate2.m_60713_(this) || blockstate2.m_60713_(Blocks.f_50491_))).m_61124_(f_55149_, Boolean.valueOf(blockstate3.m_60713_(this) || blockstate3.m_60713_(Blocks.f_50491_))).m_61124_(f_55150_, Boolean.valueOf(blockstate4.m_60713_(this) || blockstate4.m_60713_(Blocks.f_50491_))).m_61124_(f_55151_, Boolean.valueOf(blockstate5.m_60713_(this) || blockstate5.m_60713_(Blocks.f_50491_)));
|
||||
}
|
||||
|
||||
public BlockState m_7417_(BlockState p_51728_, Direction p_51729_, BlockState p_51730_, LevelAccessor p_51731_, BlockPos p_51732_, BlockPos p_51733_) {
|
||||
@@ -38,7 +_,7 @@
|
||||
p_51731_.m_186460_(p_51732_, this, 1);
|
||||
return super.m_7417_(p_51728_, p_51729_, p_51730_, p_51731_, p_51732_, p_51733_);
|
||||
} else {
|
||||
- boolean flag = p_51730_.m_60713_(this) || p_51730_.m_60713_(Blocks.f_50491_) || p_51729_ == Direction.DOWN && p_51730_.m_60713_(Blocks.f_50259_);
|
||||
+ boolean flag = p_51730_.m_60713_(this) || p_51730_.m_60713_(Blocks.f_50491_) || p_51729_ == Direction.DOWN && (p_51730_.m_60713_(Blocks.f_50259_) || p_51730_.m_204336_(net.minecraftforge.common.Tags.Blocks.CHORUS_ADDITIONALLY_GROWS_ON));
|
||||
return p_51728_.m_61124_(f_55154_.get(p_51729_), Boolean.valueOf(flag));
|
||||
}
|
||||
}
|
||||
@@ -63,13 +_,13 @@
|
||||
}
|
||||
|
||||
BlockState blockstate2 = p_51725_.m_8055_(blockpos.m_7495_());
|
||||
- if (blockstate2.m_60713_(this) || blockstate2.m_60713_(Blocks.f_50259_)) {
|
||||
+ if (blockstate2.m_60713_(this) || blockstate2.m_60713_(Blocks.f_50259_) || blockstate2.m_204336_(net.minecraftforge.common.Tags.Blocks.CHORUS_ADDITIONALLY_GROWS_ON)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- return blockstate.m_60713_(this) || blockstate.m_60713_(Blocks.f_50259_);
|
||||
+ return blockstate.m_60713_(this) || blockstate.m_60713_(Blocks.f_50259_) || blockstate.m_204336_(net.minecraftforge.common.Tags.Blocks.CHORUS_ADDITIONALLY_GROWS_ON);
|
||||
}
|
||||
|
||||
protected void m_7926_(StateDefinition.Builder<Block, BlockState> p_51735_) {
|
||||
@@ -38,12 +38,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ @Deprecated //Forge: Prefer using IForgeBlock#catchFire
|
||||
+ @Deprecated //Forge: Prefer using IForgeBlock#onCaughtFire
|
||||
public static void m_57433_(Level p_57434_, BlockPos p_57435_) {
|
||||
m_57436_(p_57434_, p_57435_, (LivingEntity)null);
|
||||
}
|
||||
|
||||
+ @Deprecated //Forge: Prefer using IForgeBlock#catchFire
|
||||
+ @Deprecated //Forge: Prefer using IForgeBlock#onCaughtFire
|
||||
private static void m_57436_(Level p_57437_, BlockPos p_57438_, @Nullable LivingEntity p_57439_) {
|
||||
if (!p_57437_.f_46443_) {
|
||||
PrimedTnt primedtnt = new PrimedTnt(p_57437_, (double)p_57438_.m_123341_() + 0.5D, (double)p_57438_.m_123342_(), (double)p_57438_.m_123343_() + 0.5D, p_57439_);
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"values": [
|
||||
"#forge:end_stones"
|
||||
]
|
||||
}
|
||||
@@ -148,7 +148,6 @@ public class ForgeMod
|
||||
return uuid.toString();
|
||||
});
|
||||
|
||||
LOGGER.debug(FORGEMOD, "Loading Network data for FML net version: {}", NetworkConstants.init());
|
||||
CrashReportCallables.registerCrashCallable("FML", ForgeVersion::getSpec);
|
||||
CrashReportCallables.registerCrashCallable("Forge", ()->ForgeVersion.getGroup()+":"+ForgeVersion.getVersion());
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ public class Tags
|
||||
public static final TagKey<Block> CHESTS_ENDER = tag("chests/ender");
|
||||
public static final TagKey<Block> CHESTS_TRAPPED = tag("chests/trapped");
|
||||
public static final TagKey<Block> CHESTS_WOODEN = tag("chests/wooden");
|
||||
public static final TagKey<Block> CHORUS_ADDITIONALLY_GROWS_ON = tag("chorus_additionally_grows_on");
|
||||
public static final TagKey<Block> COBBLESTONE = tag("cobblestone");
|
||||
public static final TagKey<Block> COBBLESTONE_NORMAL = tag("cobblestone/normal");
|
||||
public static final TagKey<Block> COBBLESTONE_INFESTED = tag("cobblestone/infested");
|
||||
|
||||
@@ -39,6 +39,7 @@ public final class ForgeBlockTagsProvider extends BlockTagsProvider
|
||||
tag(CHESTS_ENDER).add(Blocks.ENDER_CHEST);
|
||||
tag(CHESTS_TRAPPED).add(Blocks.TRAPPED_CHEST);
|
||||
tag(CHESTS_WOODEN).add(Blocks.CHEST, Blocks.TRAPPED_CHEST);
|
||||
tag(CHORUS_ADDITIONALLY_GROWS_ON).addTags(END_STONES);
|
||||
tag(COBBLESTONE).addTags(COBBLESTONE_NORMAL, COBBLESTONE_INFESTED, COBBLESTONE_MOSSY, COBBLESTONE_DEEPSLATE);
|
||||
tag(COBBLESTONE_NORMAL).add(Blocks.COBBLESTONE);
|
||||
tag(COBBLESTONE_INFESTED).add(Blocks.INFESTED_COBBLESTONE);
|
||||
|
||||
@@ -550,7 +550,7 @@ public interface IForgeBlock
|
||||
*/
|
||||
default boolean isFlammable(BlockState state, BlockGetter level, BlockPos pos, Direction direction)
|
||||
{
|
||||
return state.getFlammability(level, pos, direction) > 0;
|
||||
return state.getMaterial().isFlammable() && state.getFlammability(level, pos, direction) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -47,6 +47,11 @@ public class NetworkHooks
|
||||
{
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
public static void init()
|
||||
{
|
||||
LOGGER.debug("Loading Network data for FML net version: {}", NetworkConstants.init());
|
||||
}
|
||||
|
||||
public static String getFMLVersion(final String ip)
|
||||
{
|
||||
return ip.contains("\0") ? Objects.equals(ip.split("\0")[1], NetworkConstants.NETVERSION) ? NetworkConstants.NETVERSION : ip.split("\0")[1] : NetworkConstants.NOVERSION;
|
||||
|
||||
Reference in new issue
Block a user