mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-14 01:04:24 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c1126a7b4 | ||
|
|
326e0329b9 | ||
|
|
f9d0daa91c | ||
|
|
094200e687 | ||
|
|
bb4818630c | ||
|
|
7af3155b39 | ||
|
|
d988b4a811 | ||
|
|
18f5bdb7ca | ||
|
|
f41d493552 | ||
|
|
8cd2c9c63f | ||
|
|
427b335cac | ||
|
|
2049096c6f | ||
|
|
98d4fa6dc2 | ||
|
|
5306471aec | ||
|
|
aa8818b049 | ||
|
|
2d86f17363 | ||
|
|
3a36a01913 | ||
|
|
47d70a7f31 | ||
|
|
d5b5e6f4db | ||
|
|
e76d814439 | ||
|
|
b8b40e1f54 | ||
|
|
5e8c786406 | ||
|
|
5b8224f839 | ||
|
|
cd621eb081 | ||
|
|
b1113f0363 | ||
|
|
daf5933b79 | ||
|
|
47fd2e8604 | ||
|
|
05297fd72f | ||
|
|
f20cf19f94 | ||
|
|
061cd3da53 | ||
|
|
03202a8ab4 | ||
|
|
8a67be4afd | ||
|
|
4c1ab67f33 | ||
|
|
7e06a2105f | ||
|
|
4a0c8be742 | ||
|
|
0c030ee5e1 | ||
|
|
1134fac54c | ||
|
|
ac44d72530 | ||
|
|
12468bd8d2 | ||
|
|
a98eeb9d08 | ||
|
|
b558b132cd | ||
|
|
c102633566 | ||
|
|
cce002ad29 | ||
|
|
b1ed321438 | ||
|
|
c7c2478cb0 | ||
|
|
b70d99489b | ||
|
|
57f45eaca0 | ||
|
|
52fcc4d649 | ||
|
|
959ab9abc9 | ||
|
|
c3a91872fe | ||
|
|
4d074f0a1e | ||
|
|
c2225ab1da | ||
|
|
bb03b1a7d1 | ||
|
|
be7275443f | ||
|
|
dc1c973684 | ||
|
|
06d568408c | ||
|
|
2256e88fb4 | ||
|
|
9b962c8ff0 | ||
|
|
7656b75992 | ||
|
|
58a5449c2f | ||
|
|
702abe0665 | ||
|
|
2070b77fd4 | ||
|
|
fd00822015 | ||
|
|
17565c0ea2 | ||
|
|
22668ad2c2 | ||
|
|
0dcc3d700d | ||
|
|
2ab3d9b8a3 | ||
|
|
d578d8f6df | ||
|
|
fd61016a7e | ||
|
|
7f77d24f45 | ||
|
|
3ebdcb34d1 | ||
|
|
05240fecf7 | ||
|
|
d5860d7cfa | ||
|
|
7bb97dafda | ||
|
|
ca90babc4a | ||
|
|
4b813e4319 | ||
|
|
fa84c22662 | ||
|
|
2ae640b530 | ||
|
|
4f95a20c5e | ||
|
|
915d570b17 | ||
|
|
5979636ee5 | ||
|
|
5acfc6ae3c | ||
|
|
48341120fb | ||
|
|
ff45bb4c27 | ||
|
|
eabba46595 | ||
|
|
683bf99fe4 | ||
|
|
2a05c7c01d | ||
|
|
e386229b66 | ||
|
|
59b8ec5625 | ||
|
|
50ae5db357 | ||
|
|
3aa99a1250 | ||
|
|
00c8513129 | ||
|
|
9c1404fecc | ||
|
|
c11686ab6c | ||
|
|
2818984f6c | ||
|
|
db225ed04a | ||
|
|
0ec4c34a34 | ||
|
|
597ebc3267 | ||
|
|
e16f54eebe | ||
|
|
27480c15fa | ||
|
|
df0dea59f3 | ||
|
|
d7bc564512 | ||
|
|
e6a73ef36c | ||
|
|
1ba7c6aecd | ||
|
|
7c5e95222e | ||
|
|
38df3d2a15 | ||
|
|
3beaa817f3 | ||
|
|
3ebd7ba0ef | ||
|
|
1ba9c34650 | ||
|
|
2f9e726aea | ||
|
|
ade2b8cc80 | ||
|
|
9b144f4541 | ||
|
|
0c35436217 | ||
|
|
0e66b7b217 |
No files matched your search
@@ -1,16 +0,0 @@
|
||||
# Configuration for support-requests - https://github.com/dessant/support-requests
|
||||
|
||||
# Label used to mark issues as support requests
|
||||
supportLabel: Forum
|
||||
# Comment to post on issues marked as support requests. Add a link
|
||||
# to a support page, or set to `false` to disable
|
||||
supportComment: >
|
||||
👋 We use the issue tracker exclusively for final bug reports and feature requests.
|
||||
However, this issue appears to be better suited for the
|
||||
[Forge Support Forums](http://www.minecraftforge.net/forum/forum/18-support-bug-reports/).
|
||||
Please create a new topic on the support forum with this issue, and the conversation can
|
||||
continue there.
|
||||
# Whether to close issues marked as support requests
|
||||
close: true
|
||||
# Whether to lock issues marked as support requests
|
||||
lock: true
|
||||
@@ -0,0 +1,27 @@
|
||||
name: Support Requests
|
||||
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- labeled
|
||||
- unlabeled
|
||||
- reopened
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
support:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/support-requests@v2
|
||||
with:
|
||||
support-label: Forum
|
||||
issue-comment: >
|
||||
:wave: We use the issue tracker exclusively for final bug reports and feature requests.
|
||||
However, this issue appears to be better suited for the
|
||||
[Forge Support Forums](https://forums.minecraftforge.net/) or
|
||||
[Forge Discord](https://discord.gg/UvedJ9m). Please create a new topic on the support forum
|
||||
with this issue or ask in the `#tech-support` channel in the Discord server, and the
|
||||
conversation can continue there.
|
||||
lock-issue: true
|
||||
+23
-12
@@ -20,8 +20,8 @@ plugins {
|
||||
id 'net.minecraftforge.gradleutils' version '2.+'
|
||||
id 'eclipse'
|
||||
id 'de.undercouch.download' version '4.1.2'
|
||||
id 'net.minecraftforge.gradle.patcher' version '[5.1.39,)' apply false
|
||||
id 'net.minecraftforge.gradle.mcp' version '[5.1.39,)' apply false
|
||||
id 'net.minecraftforge.gradle.patcher' version '[5.1.43,)' apply false
|
||||
id 'net.minecraftforge.gradle.mcp' version '[5.1.43,)' apply false
|
||||
}
|
||||
|
||||
Util.init() //Init all our extension methods!
|
||||
@@ -39,13 +39,13 @@ ext {
|
||||
MAPPING_VERSION = '1.19'
|
||||
MC_VERSION = '1.19'
|
||||
MCP_VERSION = '20220607.102129'
|
||||
SPI_VERSION = '4.0.10'
|
||||
SPI_VERSION = '6.0.0'
|
||||
ACCESSTRANSFORMERS_VERSION = '8.0.4'
|
||||
COREMODS_VERSION = '5.0.1'
|
||||
EVENTBUS_VERSION = '5.0.3'
|
||||
MODLAUNCHER_VERSION = '9.1.3'
|
||||
SECUREJARHANDLER_VERSION = '1.0.3'
|
||||
BOOTSTRAPLAUNCHER_VERSION = '1.0.0'
|
||||
EVENTBUS_VERSION = '6.0.0'
|
||||
MODLAUNCHER_VERSION = '10.0.8'
|
||||
SECUREJARHANDLER_VERSION = '2.1.4'
|
||||
BOOTSTRAPLAUNCHER_VERSION = '1.1.2'
|
||||
ASM_VERSION = '9.3'
|
||||
INSTALLER_VERSION = '2.1.+'
|
||||
MIXIN_VERSION = '0.8.5'
|
||||
@@ -65,6 +65,7 @@ ext {
|
||||
APACHE_COMMONS_LANG3_VERSION = '3.12.0'
|
||||
JOPT_SIMPLE_VERSION = '5.0.4'
|
||||
COMMONS_IO_VERSION = '2.11.0'
|
||||
JARJAR_VERSION = '0.3.9'
|
||||
|
||||
GIT_INFO = gradleutils.gitInfo
|
||||
VERSION = gradleutils.getFilteredMCTagOffsetBranchVersion(true, '[0-9]', MC_VERSION)
|
||||
@@ -75,7 +76,7 @@ ext {
|
||||
INSTALLER_TOOLS = 'net.minecraftforge:installertools:1.3.0'
|
||||
JAR_SPLITTER = 'net.minecraftforge:jarsplitter:1.1.4'
|
||||
FART = 'net.minecraftforge:ForgeAutoRenamingTool:0.1.22:all'
|
||||
MIN_TAG_FOR_CHANGELOG = "39.0"
|
||||
MIN_TAG_FOR_CHANGELOG = "41.0"
|
||||
}
|
||||
|
||||
println('Version: ' + VERSION +
|
||||
@@ -283,6 +284,7 @@ def sharedDeps = {
|
||||
installer "org.jline:jline-terminal:${JLINE_VERSION}" // Dep of TerminalConsoleAppender
|
||||
installer "org.spongepowered:mixin:${MIXIN_VERSION}"
|
||||
installer 'org.openjdk.nashorn:nashorn-core:15.3'
|
||||
installer "net.minecraftforge:JarJar:${JARJAR_VERSION}"
|
||||
|
||||
/*
|
||||
installer 'org.lwjgl:lwjgl:3.2.2'
|
||||
@@ -429,6 +431,8 @@ def sharedFmlonlyForge = { Project prj ->
|
||||
run.args '--fml.forgeGroup', prj.group
|
||||
run.args '--fml.mcpVersion', MCP_VERSION
|
||||
|
||||
run.jvmArgs '-Djava.net.preferIPv6Addresses=system'
|
||||
|
||||
if (run.name.contains('client')) {
|
||||
run.client true
|
||||
} else {
|
||||
@@ -449,6 +453,7 @@ def sharedFmlonlyForge = { Project prj ->
|
||||
run.jvmArgs '--add-modules', 'ALL-MODULE-PATH'
|
||||
// Additions to these JVM module args should be mirrored to server_files/args.txt and other similar blocks in the buildscript
|
||||
run.jvmArgs '--add-opens', 'java.base/java.util.jar=cpw.mods.securejarhandler'
|
||||
run.jvmArgs '--add-opens', 'java.base/java.lang.invoke=cpw.mods.securejarhandler'
|
||||
run.jvmArgs '--add-exports', 'java.base/sun.security.util=cpw.mods.securejarhandler'
|
||||
run.jvmArgs '--add-exports', 'jdk.naming.dns/com.sun.jndi.dns=java.naming'
|
||||
}
|
||||
@@ -632,13 +637,15 @@ project(':fmlonly') {
|
||||
'--fml.mcVersion', MC_VERSION,
|
||||
'--fml.forgeGroup', project.group,
|
||||
'--fml.mcpVersion', MCP_VERSION],
|
||||
jvm: ["-DignoreList=${fmlonly_client.properties.ignoreList},\${version_name}.jar",
|
||||
jvm: ['-Djava.net.preferIPv6Addresses=system',
|
||||
"-DignoreList=${fmlonly_client.properties.ignoreList},\${version_name}.jar",
|
||||
"-DmergeModules=${fmlonly_client.properties.mergeModules}",
|
||||
'-DlibraryDirectory=${library_directory}',
|
||||
'-p', Util.getArtifacts(project, configurations.moduleonly, false).values().collect{"\${library_directory}/${it.downloads.artifact.path}"}.join('${classpath_separator}'),
|
||||
'--add-modules', 'ALL-MODULE-PATH',
|
||||
// Additions to these JVM module args should be mirrored to server_files/args.txt and other similar blocks in the buildscript
|
||||
'--add-opens', 'java.base/java.util.jar=cpw.mods.securejarhandler',
|
||||
'--add-opens', 'java.base/java.lang.invoke=cpw.mods.securejarhandler',
|
||||
'--add-exports', 'java.base/sun.security.util=cpw.mods.securejarhandler',
|
||||
'--add-exports', 'jdk.naming.dns/com.sun.jndi.dns=java.naming'
|
||||
]
|
||||
@@ -1059,6 +1066,7 @@ project(':forge') {
|
||||
'--mod', 'custom_transformtype_test',
|
||||
'--mod', 'data_pack_registries_test',
|
||||
'--mod', 'biome_modifiers_test',
|
||||
'--mod', 'structure_modifiers_test',
|
||||
'--output', rootProject.file('src/generated_test/resources/'),
|
||||
'--existing', sourceSets.main.resources.srcDirs[0],
|
||||
'--existing', sourceSets.test.resources.srcDirs[0]
|
||||
@@ -1192,7 +1200,8 @@ project(':forge') {
|
||||
|
||||
def baseForgeVersion = System.getProperty("forge.compatibility_check_version")
|
||||
if (baseForgeVersion == null)
|
||||
baseForgeVersion = "${MC_VERSION}-${GIT_INFO.tag}.0"
|
||||
// FIXME: Restore commented out portion when next tagged (41.1 or 42.0), assuming that a .0 build is published
|
||||
baseForgeVersion = "1.19-41.0.1" // "${MC_VERSION}-${GIT_INFO.tag}.0"
|
||||
if (baseForgeVersion == "null")
|
||||
baseForgeVersion = null // Allow disabling from system property if not wanted
|
||||
def baseForgeUniversal = null
|
||||
@@ -1228,7 +1237,7 @@ project(':forge') {
|
||||
}.toArray(Dependency[]::new))
|
||||
|
||||
baseJar = project.tasks.applyBaseCompatibilityJarBinPatches.output
|
||||
baseLibraries.from(baseForgeUniversal)
|
||||
baseLibraries.from(project.configurations.detachedConfiguration(baseForgeUniversal))
|
||||
baseLibraries.from(project.tasks.createJoinedSRG.output)
|
||||
baseLibraries.from(fmlLibs)
|
||||
|
||||
@@ -1260,13 +1269,15 @@ project(':forge') {
|
||||
'--fml.mcVersion', MC_VERSION,
|
||||
'--fml.forgeGroup', project.group,
|
||||
'--fml.mcpVersion', MCP_VERSION],
|
||||
jvm: ["-DignoreList=${forge_client.properties.ignoreList},\${version_name}.jar",
|
||||
jvm: ['-Djava.net.preferIPv6Addresses=system',
|
||||
"-DignoreList=${forge_client.properties.ignoreList},\${version_name}.jar",
|
||||
"-DmergeModules=${forge_client.properties.mergeModules}",
|
||||
'-DlibraryDirectory=${library_directory}',
|
||||
'-p', Util.getArtifacts(project, configurations.moduleonly, false).values().collect{'${library_directory}/' + it.downloads.artifact.path}.join('${classpath_separator}'),
|
||||
'--add-modules', 'ALL-MODULE-PATH',
|
||||
// Additions to these JVM module args should be mirrored to server_files/args.txt and other similar blocks in the buildscript
|
||||
'--add-opens', 'java.base/java.util.jar=cpw.mods.securejarhandler',
|
||||
'--add-opens', 'java.base/java.lang.invoke=cpw.mods.securejarhandler',
|
||||
'--add-exports', 'java.base/sun.security.util=cpw.mods.securejarhandler',
|
||||
'--add-exports', 'jdk.naming.dns/com.sun.jndi.dns=java.naming'
|
||||
]
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
MinecraftForge
|
||||
=============
|
||||
[](https://files.minecraftforge.net)
|
||||
[](https://files.minecraftforge.net)
|
||||
[](https://files.minecraftforge.net) [](https://discord.gg/UvedJ9m) [](https://www.patreon.com/LexManos)
|
||||
|
||||
Forge is a free, open-source modding API all of your favourite mods use!
|
||||
|
||||
@@ -93,5 +93,7 @@ public interface IExtensionPoint<T extends Record>
|
||||
* @see net.minecraftforge.client.ForgeHooksClient#processForgeListPingData(net.minecraft.network.protocol.status.ServerStatus, net.minecraft.client.multiplayer.ServerData)
|
||||
*/
|
||||
@SuppressWarnings("JavadocReference") // reference to NetworkConstants, ForgeHooksClient
|
||||
record DisplayTest(Supplier<String> suppliedVersion, BiPredicate<String, Boolean> remoteVersionTest) implements IExtensionPoint<DisplayTest> {}
|
||||
record DisplayTest(Supplier<String> suppliedVersion, BiPredicate<String, Boolean> remoteVersionTest) implements IExtensionPoint<DisplayTest> {
|
||||
public static final String IGNORESERVERONLY = "OHNOES\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31\uD83D\uDE31";
|
||||
}
|
||||
}
|
||||
@@ -56,9 +56,24 @@ public abstract class ModContainer
|
||||
this.namespace = this.modId;
|
||||
this.modInfo = info;
|
||||
this.modLoadingStage = ModLoadingStage.CONSTRUCT;
|
||||
// default displaytest extension checks for version string match
|
||||
registerExtensionPoint(IExtensionPoint.DisplayTest.class, () -> new IExtensionPoint.DisplayTest(()->this.modInfo.getVersion().toString(),
|
||||
(incoming, isNetwork)->Objects.equals(incoming, this.modInfo.getVersion().toString())));
|
||||
|
||||
final String displayTestString = info.getConfig().<String>getConfigElement("displayTest").orElse("MATCH_VERSION"); // missing defaults to DEFAULT type
|
||||
Supplier<IExtensionPoint.DisplayTest> displayTestSupplier = switch (displayTestString) {
|
||||
case "MATCH_VERSION" -> // default displaytest checks for version string match
|
||||
() -> new IExtensionPoint.DisplayTest(() -> this.modInfo.getVersion().toString(),
|
||||
(incoming, isNetwork) -> Objects.equals(incoming, this.modInfo.getVersion().toString()));
|
||||
case "IGNORE_SERVER_VERSION" -> // Ignores any version information coming from the server - use for server only mods
|
||||
() -> new IExtensionPoint.DisplayTest(() -> IExtensionPoint.DisplayTest.IGNORESERVERONLY, (incoming, isNetwork) -> true);
|
||||
case "IGNORE_ALL_VERSION" -> // Ignores all information and provides no information
|
||||
() -> new IExtensionPoint.DisplayTest(() -> "", (incoming, isNetwork) -> true);
|
||||
case "NONE" -> null; // NO display test at all - use this if you're going to do your own display test
|
||||
default -> // any other value throws an exception
|
||||
throw new IllegalArgumentException("Invalid displayTest value supplied in mods.toml");
|
||||
};
|
||||
if (displayTestSupplier != null)
|
||||
registerExtensionPoint(IExtensionPoint.DisplayTest.class, displayTestSupplier);
|
||||
else
|
||||
extensionPoints.remove(IExtensionPoint.DisplayTest.class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@@ -53,6 +54,7 @@ public class ModList
|
||||
private List<ModContainer> mods;
|
||||
private Map<String, ModContainer> indexedMods;
|
||||
private List<ModFileScanData> modFileScanData;
|
||||
private List<ModContainer> sortedContainers;
|
||||
|
||||
private ModList(final List<ModFile> modFiles, final List<ModInfo> sortedList)
|
||||
{
|
||||
@@ -155,6 +157,7 @@ public class ModList
|
||||
void setLoadedMods(final List<ModContainer> modContainers)
|
||||
{
|
||||
this.mods = modContainers;
|
||||
this.sortedContainers = modContainers.stream().sorted(Comparator.comparingInt(c->sortedList.indexOf(c.getModInfo()))).toList();
|
||||
this.indexedMods = modContainers.stream().collect(Collectors.toMap(ModContainer::getModId, Function.identity()));
|
||||
}
|
||||
|
||||
@@ -218,6 +221,10 @@ public class ModList
|
||||
indexedMods.forEach(modContainerConsumer);
|
||||
}
|
||||
|
||||
public void forEachModInOrder(Consumer<ModContainer> containerConsumer) {
|
||||
this.sortedContainers.forEach(containerConsumer);
|
||||
}
|
||||
|
||||
public <T> Stream<T> applyForEachModContainer(Function<ModContainer, T> function) {
|
||||
return indexedMods.values().stream().map(function);
|
||||
}
|
||||
|
||||
@@ -8,18 +8,22 @@ package net.minecraftforge.fml;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraftforge.eventbus.api.Event;
|
||||
import net.minecraftforge.fml.event.IModBusEvent;
|
||||
import net.minecraftforge.fml.loading.FMLEnvironment;
|
||||
import net.minecraftforge.fml.loading.FMLLoader;
|
||||
import net.minecraftforge.fml.loading.LoadingModList;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.InvalidModIdentifier;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
|
||||
import net.minecraftforge.fml.loading.progress.StartupMessageManager;
|
||||
import net.minecraftforge.forgespi.language.IModInfo;
|
||||
import net.minecraftforge.forgespi.language.IModLanguageProvider;
|
||||
import net.minecraftforge.forgespi.locating.ForgeFeature;
|
||||
import net.minecraftforge.forgespi.locating.IModFile;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -28,6 +32,7 @@ import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -96,7 +101,7 @@ public class ModLoader
|
||||
.map(file -> new ModLoadingWarning(null, ModLoadingStage.VALIDATE, InvalidModIdentifier.identifyJarProblem(file.getFilePath()).orElse("fml.modloading.brokenfile"), file.getFileName()))
|
||||
.collect(Collectors.toList());
|
||||
FMLLoader.getLoadingModList().getModFiles().stream()
|
||||
.filter(ModFileInfo::missingLicense) //Search for files with missing licenses
|
||||
.filter(ModFileInfo::missingLicense)
|
||||
.filter(modFileInfo -> modFileInfo.getMods().stream().noneMatch(thisModInfo -> this.loadingExceptions.stream().map(ModLoadingException::getModInfo).anyMatch(otherInfo -> otherInfo == thisModInfo))) //Ignore files where any other mod already encountered an error
|
||||
.map(modFileInfo -> new ModLoadingException(null, ModLoadingStage.VALIDATE, "fml.modloading.missinglicense", null, modFileInfo.getFile()))
|
||||
.forEach(this.loadingExceptions::add);
|
||||
@@ -133,6 +138,7 @@ public class ModLoader
|
||||
* @param periodicTask Optional periodic task to perform on the main thread while other activities run
|
||||
*/
|
||||
public void gatherAndInitializeMods(final ModWorkManager.DrivenExecutor syncExecutor, final Executor parallelExecutor, final Runnable periodicTask) {
|
||||
ForgeFeature.registerFeature("java_version", ForgeFeature.VersionFeatureTest.forVersionString(IModInfo.DependencySide.SERVER, System.getProperty("java.version")));
|
||||
loadingStateValid = true;
|
||||
statusConsumer.ifPresent(c->c.accept("Waiting for scan to complete"));
|
||||
FMLLoader.backgroundScanHandler.waitForScanToComplete(periodicTask);
|
||||
@@ -145,6 +151,22 @@ public class ModLoader
|
||||
loadingStateValid = false;
|
||||
throw new LoadingFailedException(loadingExceptions);
|
||||
}
|
||||
statusConsumer.ifPresent(c->c.accept("Validating features"));
|
||||
List<? extends ForgeFeature.Bound> failedBounds = loadingModList.getMods().stream()
|
||||
.map(ModInfo::getForgeFeatures)
|
||||
.flatMap(Collection::stream)
|
||||
.filter(bound -> !ForgeFeature.testFeature(FMLEnvironment.dist, bound))
|
||||
.toList();
|
||||
|
||||
if (!failedBounds.isEmpty()) {
|
||||
LOGGER.fatal(CORE, "Failed to validate feature bounds for mods");
|
||||
modList.setLoadedMods(Collections.emptyList());
|
||||
loadingStateValid = false;
|
||||
throw new LoadingFailedException(failedBounds.stream()
|
||||
.map(fb -> new ModLoadingException(fb.modInfo(), ModLoadingStage.CONSTRUCT, "fml.modloading.feature.missing", null, fb.featureName(), fb.featureBound(), ForgeFeature.featureValue(fb)))
|
||||
.toList());
|
||||
}
|
||||
|
||||
statusConsumer.ifPresent(c->c.accept("Building Mod List"));
|
||||
final List<ModContainer> modContainers = loadingModList.getModFiles().stream()
|
||||
.map(ModFileInfo::getFile)
|
||||
@@ -222,7 +244,7 @@ public class ModLoader
|
||||
}
|
||||
}
|
||||
|
||||
private List<ModContainer> buildMods(final ModFile modFile)
|
||||
private List<ModContainer> buildMods(final IModFile modFile)
|
||||
{
|
||||
final Map<String, IModInfo> modInfoMap = modFile.getModFileInfo().getMods().stream().collect(Collectors.toMap(IModInfo::getModId, Function.identity()));
|
||||
|
||||
@@ -244,7 +266,7 @@ public class ModLoader
|
||||
return containers.stream().filter(mc -> mc.modLoadingStage != ModLoadingStage.ERROR).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private ModContainer buildModContainerFromTOML(final ModFile modFile, final Map<String, IModInfo> modInfoMap, final Map.Entry<String, ? extends IModLanguageProvider.IModLanguageLoader> idToProviderEntry) {
|
||||
private ModContainer buildModContainerFromTOML(final IModFile modFile, final Map<String, IModInfo> modInfoMap, final Map.Entry<String, ? extends IModLanguageProvider.IModLanguageLoader> idToProviderEntry) {
|
||||
try {
|
||||
final String modId = idToProviderEntry.getKey();
|
||||
final IModLanguageProvider.IModLanguageLoader languageLoader = idToProviderEntry.getValue();
|
||||
@@ -273,7 +295,7 @@ public class ModLoader
|
||||
LOGGER.error("Cowardly refusing to send event generator to a broken mod state");
|
||||
return;
|
||||
}
|
||||
ModList.get().forEachModContainer((id, mc) -> mc.acceptEvent(generator.apply(mc)));
|
||||
ModList.get().forEachModInOrder(mc -> mc.acceptEvent(generator.apply(mc)));
|
||||
}
|
||||
|
||||
public <T extends Event & IModBusEvent> void postEvent(T e) {
|
||||
@@ -281,7 +303,18 @@ public class ModLoader
|
||||
LOGGER.error("Cowardly refusing to send event {} to a broken mod state", e.getClass().getName());
|
||||
return;
|
||||
}
|
||||
ModList.get().forEachModContainer((id, mc) -> mc.acceptEvent(e));
|
||||
ModList.get().forEachModInOrder(mc -> mc.acceptEvent(e));
|
||||
}
|
||||
public <T extends Event & IModBusEvent> void postEventWithWrapInModOrder(T e, BiConsumer<ModContainer, T> pre, BiConsumer<ModContainer, T> post) {
|
||||
if (!loadingStateValid) {
|
||||
LOGGER.error("Cowardly refusing to send event {} to a broken mod state", e.getClass().getName());
|
||||
return;
|
||||
}
|
||||
ModList.get().forEachModInOrder(mc -> {
|
||||
pre.accept(mc, e);
|
||||
mc.acceptEvent(e);
|
||||
post.accept(mc, e);
|
||||
});
|
||||
}
|
||||
|
||||
public List<ModLoadingWarning> getWarnings()
|
||||
|
||||
@@ -117,14 +117,22 @@ public class VersionChecker
|
||||
/**
|
||||
* Returns the response body as a String for the given URL while following redirects
|
||||
*/
|
||||
private String openUrlString(URL url) throws IOException, URISyntaxException, InterruptedException {
|
||||
private String openUrlString(URL url, IModInfo mod) throws IOException, URISyntaxException, InterruptedException {
|
||||
URL currentUrl = url;
|
||||
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("Java-http-client/").append(System.getProperty("java.version")).append(' ');
|
||||
sb.append("MinecraftForge/").append(FMLLoader.versionInfo().mcAndForgeVersion()).append(' ');
|
||||
sb.append(mod.getModId()).append('/').append(mod.getVersion());
|
||||
final String userAgent = sb.toString();
|
||||
|
||||
for (int redirects = 0; redirects < MAX_HTTP_REDIRECTS; redirects++)
|
||||
{
|
||||
var request = HttpRequest.newBuilder()
|
||||
.uri(currentUrl.toURI())
|
||||
.timeout(Duration.ofSeconds(HTTP_TIMEOUT_SECS))
|
||||
.setHeader("Accept-Encoding", "gzip")
|
||||
.setHeader("User-Agent", userAgent)
|
||||
.GET()
|
||||
.build();
|
||||
|
||||
@@ -166,7 +174,7 @@ public class VersionChecker
|
||||
URL url = mod.getUpdateURL().get();
|
||||
LOGGER.info("[{}] Starting version check at {}", mod.getModId(), url.toString());
|
||||
|
||||
String data = openUrlString(url);
|
||||
String data = openUrlString(url, mod);
|
||||
|
||||
LOGGER.debug("[{}] Received version check data:\n{}", mod.getModId(), data);
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ dependencies {
|
||||
api("cpw.mods:modlauncher:${MODLAUNCHER_VERSION}")
|
||||
api("net.minecraftforge:coremods:${COREMODS_VERSION}")
|
||||
api("com.mojang:logging:${MOJANG_LOGGING_VERSION}")
|
||||
api "net.minecraftforge:JarJar:${JARJAR_VERSION}"
|
||||
|
||||
implementation("net.sf.jopt-simple:jopt-simple:${JOPT_SIMPLE_VERSION}")
|
||||
implementation("cpw.mods:securejarhandler:${SECUREJARHANDLER_VERSION}")
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) Forge Development LLC and contributors
|
||||
* SPDX-License-Identifier: LGPL-2.1-only
|
||||
*/
|
||||
|
||||
package net.minecraftforge.fml.loading;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class ClasspathLocatorUtils {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
public static Path findJarPathFor(final String resourceName, final String jarName, final URL resource) {
|
||||
try {
|
||||
Path path;
|
||||
final URI uri = resource.toURI();
|
||||
if (uri.getScheme().equals("jar") && uri.getRawSchemeSpecificPart().contains("!/")) {
|
||||
int lastExcl = uri.getRawSchemeSpecificPart().lastIndexOf("!/");
|
||||
path = Paths.get(new URI(uri.getRawSchemeSpecificPart().substring(0, lastExcl)));
|
||||
} else {
|
||||
path = Paths.get(new URI("file://"+uri.getRawSchemeSpecificPart().substring(0, uri.getRawSchemeSpecificPart().length()-resourceName.length())));
|
||||
}
|
||||
//LOGGER.debug(CORE, "Found JAR {} at path {}", jarName, path.toString());
|
||||
return path;
|
||||
} catch (NullPointerException | URISyntaxException e) {
|
||||
LOGGER.error(LogMarkers.SCAN, "Failed to find JAR for class {} - {}", resourceName, jarName);
|
||||
throw new RuntimeException("Unable to locate "+resourceName+" - "+jarName, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) Forge Development LLC and contributors
|
||||
* SPDX-License-Identifier: LGPL-2.1-only
|
||||
*/
|
||||
|
||||
package net.minecraftforge.fml.loading;
|
||||
|
||||
import cpw.mods.modlauncher.api.NamedPath;
|
||||
import cpw.mods.modlauncher.serviceapi.ITransformerDiscoveryService;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
||||
public class ClasspathTransformerDiscoverer implements ITransformerDiscoveryService {
|
||||
|
||||
private final List<Path> legacyClasspath = Arrays.stream(System.getProperty("legacyClassPath", "").split(File.pathSeparator)).map(Path::of).toList();
|
||||
|
||||
@Override
|
||||
public List<NamedPath> candidates(Path gameDirectory) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NamedPath> candidates(final Path gameDirectory, final String launchTarget) {
|
||||
if (launchTarget != null && launchTarget.contains("dev")) {
|
||||
this.scan(gameDirectory);
|
||||
}
|
||||
return List.copyOf(found);
|
||||
}
|
||||
|
||||
private final static List<NamedPath> found = new ArrayList<>();
|
||||
|
||||
public static List<Path> allExcluded() {
|
||||
return found.stream().map(np->np.paths()[0]).toList();
|
||||
}
|
||||
|
||||
private void scan(final Path gameDirectory) {
|
||||
try {
|
||||
locateTransformers("META-INF/services/cpw.mods.modlauncher.api.ITransformationService");
|
||||
locateTransformers("META-INF/services/net.minecraftforge.forgespi.locating.IModLocator");
|
||||
} catch (IOException e) {
|
||||
LogManager.getLogger().error("Error during discovery of transform services from the classpath", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void locateTransformers(String resource) throws IOException {
|
||||
final Enumeration<URL> resources = ClassLoader.getSystemClassLoader().getResources(resource);
|
||||
while (resources.hasMoreElements()) {
|
||||
URL url = resources.nextElement();
|
||||
Path path = ClasspathLocatorUtils.findJarPathFor(resource, url.toString(), url);
|
||||
if (legacyClasspath.stream().anyMatch(path::equals) || !Files.exists(path) || Files.isDirectory(path))
|
||||
continue;
|
||||
found.add(new NamedPath(path.toUri().toString(), path));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,7 @@ public class EarlyLoadingException extends RuntimeException {
|
||||
return errorMessages;
|
||||
}
|
||||
|
||||
EarlyLoadingException(final String message, final Throwable originalException, List<ExceptionData> errorMessages) {
|
||||
public EarlyLoadingException(final String message, final Throwable originalException, List<ExceptionData> errorMessages) {
|
||||
super(message, originalException);
|
||||
this.errorMessages = errorMessages;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ public class FMLConfig
|
||||
configSpec.define("maxThreads", -1);
|
||||
configSpec.define("versionCheck", Boolean.TRUE);
|
||||
configSpec.define("defaultConfigPath", "defaultconfigs");
|
||||
configSpec.define("disableOptimizedDFU", Boolean.TRUE);
|
||||
}
|
||||
|
||||
private CommentedFileConfig configData;
|
||||
@@ -88,4 +89,8 @@ public class FMLConfig
|
||||
public static String defaultConfigPath() {
|
||||
return INSTANCE.configData.<String>getOptional("defaultConfigPath").orElse("defaultconfigs");
|
||||
}
|
||||
|
||||
public static boolean isOptimizedDFUDisabled() {
|
||||
return INSTANCE.configData.<Boolean>getOptional("disableOptimizedDFU").orElse(Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
@@ -134,7 +134,7 @@ public class LanguageLoadingProvider
|
||||
}
|
||||
|
||||
public IModLanguageProvider findLanguage(ModFile mf, String modLoader, VersionRange modLoaderVersion) {
|
||||
final String languageFileName = mf.getLocator() instanceof ExplodedDirectoryLocator ? "in-development" : mf.getFileName();
|
||||
final String languageFileName = mf.getProvider() instanceof ExplodedDirectoryLocator ? "in-development" : mf.getFileName();
|
||||
final ModLanguageWrapper mlw = languageProviderMap.get(modLoader);
|
||||
if (mlw == null) {
|
||||
LOGGER.error(LOADING,"Missing language {} version {} wanted by {}", modLoader, modLoaderVersion, languageFileName);
|
||||
|
||||
@@ -10,11 +10,18 @@ import net.minecraftforge.fml.loading.moddiscovery.BackgroundScanHandler;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
|
||||
import net.minecraftforge.forgespi.locating.IModFile;
|
||||
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -28,7 +35,7 @@ public class LoadingModList
|
||||
private final List<ModInfo> sortedList;
|
||||
private final Map<String, ModFileInfo> fileById;
|
||||
private final List<EarlyLoadingException> preLoadErrors;
|
||||
private List<ModFile> brokenFiles;
|
||||
private List<IModFile> brokenFiles;
|
||||
|
||||
private LoadingModList(final List<ModFile> modFiles, final List<ModInfo> sortedList)
|
||||
{
|
||||
@@ -154,11 +161,11 @@ public class LoadingModList
|
||||
return preLoadErrors;
|
||||
}
|
||||
|
||||
public void setBrokenFiles(final List<ModFile> brokenFiles) {
|
||||
public void setBrokenFiles(final List<IModFile> brokenFiles) {
|
||||
this.brokenFiles = brokenFiles;
|
||||
}
|
||||
|
||||
public List<ModFile> getBrokenFiles() {
|
||||
public List<IModFile> getBrokenFiles() {
|
||||
return this.brokenFiles;
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,6 @@ import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
|
||||
import net.minecraftforge.fml.loading.toposort.CyclePresentException;
|
||||
import net.minecraftforge.fml.loading.toposort.TopologicalSort;
|
||||
import net.minecraftforge.forgespi.locating.IModFile;
|
||||
import org.apache.maven.artifact.versioning.ArtifactVersion;
|
||||
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
|
||||
import org.slf4j.Logger;
|
||||
@@ -36,14 +35,15 @@ import static net.minecraftforge.fml.loading.LogMarkers.LOADING;
|
||||
public class ModSorter
|
||||
{
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final UniqueModListBuilder uniqueModListBuilder;
|
||||
private List<ModFile> modFiles;
|
||||
private List<ModInfo> sortedList;
|
||||
private Map<String, ModInfo> modIdNameLookup;
|
||||
private Map<String, IModInfo> modIdNameLookup;
|
||||
private List<ModFile> systemMods;
|
||||
|
||||
private ModSorter(final List<ModFile> modFiles)
|
||||
{
|
||||
this.modFiles = modFiles;
|
||||
this.uniqueModListBuilder = new UniqueModListBuilder(modFiles);
|
||||
}
|
||||
|
||||
public static LoadingModList sort(List<ModFile> mods, final List<ExceptionData> errors)
|
||||
@@ -78,11 +78,12 @@ public class ModSorter
|
||||
// lambdas are identity based, so sorting them is impossible unless you hold reference to them
|
||||
final MutableGraph<ModFileInfo> graph = GraphBuilder.directed().build();
|
||||
AtomicInteger counter = new AtomicInteger();
|
||||
Map<IModFileInfo, Integer> infos = modFiles.stream()
|
||||
Map<ModFileInfo, Integer> infos = modFiles.stream()
|
||||
.map(ModFile::getModFileInfo)
|
||||
.filter(ModFileInfo.class::isInstance)
|
||||
.map(ModFileInfo.class::cast)
|
||||
.collect(toMap(Function.identity(), e -> counter.incrementAndGet()));
|
||||
infos.keySet().forEach(i -> graph.addNode((ModFileInfo) i));
|
||||
infos.keySet().forEach(graph::addNode);
|
||||
modFiles.stream()
|
||||
.map(ModFile::getModInfos)
|
||||
.<IModInfo>mapMulti(Iterable::forEach)
|
||||
@@ -124,10 +125,9 @@ public class ModSorter
|
||||
private void addDependency(MutableGraph<ModFileInfo> topoGraph, IModInfo.ModVersion dep)
|
||||
{
|
||||
final ModFileInfo self = (ModFileInfo)dep.getOwner().getOwningFile();
|
||||
final ModInfo targetModInfo = modIdNameLookup.get(dep.getModId());
|
||||
final IModInfo targetModInfo = modIdNameLookup.get(dep.getModId());
|
||||
// soft dep that doesn't exist. Just return. No edge required.
|
||||
if (targetModInfo == null) return;
|
||||
final ModFileInfo target = targetModInfo.getOwningFile();
|
||||
if (targetModInfo == null || !(targetModInfo.getOwningFile() instanceof final ModFileInfo target)) return;
|
||||
if (self == target)
|
||||
return; // in case a jar has two mods that have dependencies between
|
||||
switch (dep.getOrdering()) {
|
||||
@@ -138,19 +138,32 @@ public class ModSorter
|
||||
|
||||
private void buildUniqueList()
|
||||
{
|
||||
// Collect mod files by module name. This will be used for deduping purposes
|
||||
final Map<String, List<IModFile>> modFilesByFirstId = modFiles.stream()
|
||||
.collect(groupingBy(mf -> mf.getModFileInfo().moduleName()));
|
||||
final UniqueModListBuilder.UniqueModListData uniqueModListData = uniqueModListBuilder.buildUniqueList();
|
||||
|
||||
this.modFiles = uniqueModListData.modFiles();
|
||||
|
||||
detectSystemMods(uniqueModListData.modFilesByFirstId());
|
||||
|
||||
modIdNameLookup = uniqueModListData.modFilesByFirstId().entrySet().stream()
|
||||
.filter(e -> !e.getValue().get(0).getModInfos().isEmpty())
|
||||
.collect(Collectors.toMap(
|
||||
Map.Entry::getKey,
|
||||
e -> e.getValue().get(0).getModInfos().get(0)
|
||||
));
|
||||
}
|
||||
|
||||
private void detectSystemMods(final Map<String, List<ModFile>> modFilesByFirstId)
|
||||
{
|
||||
// Capture system mods (ex. MC, Forge) here, so we can keep them for later
|
||||
final Set<String> systemMods = new HashSet<>();
|
||||
// The minecraft mod is always a system mod
|
||||
systemMods.add("minecraft");
|
||||
// Find mod file from MinecraftLocator to define the system mods
|
||||
modFiles.stream()
|
||||
.filter(modFile -> modFile.getLocator().getClass() == MinecraftLocator.class)
|
||||
.filter(modFile -> modFile.getProvider().getClass() == MinecraftLocator.class)
|
||||
.map(ModFile::getSecureJar)
|
||||
.map(SecureJar::getManifest)
|
||||
.map(SecureJar::moduleDataProvider)
|
||||
.map(SecureJar.ModuleDataProvider::getManifest)
|
||||
.map(Manifest::getMainAttributes)
|
||||
.map(mf -> mf.getValue("FML-System-Mods"))
|
||||
.filter(Objects::nonNull)
|
||||
@@ -168,47 +181,6 @@ public class ModSorter
|
||||
throw new IllegalStateException("Failed to find system mod: " + systemMod);
|
||||
}
|
||||
}
|
||||
|
||||
// Select the newest by artifact version sorting of non-unique files thus identified
|
||||
this.modFiles = modFilesByFirstId.entrySet().stream()
|
||||
.map(this::selectNewestModInfo)
|
||||
.map(Map.Entry::getValue)
|
||||
.map(ModFile.class::cast)
|
||||
.collect(toList());
|
||||
|
||||
// Transform to the full mod id list
|
||||
final Map<String, List<ModInfo>> modIds = modFiles.stream()
|
||||
.map(ModFile::getModInfos)
|
||||
.flatMap(Collection::stream)
|
||||
.map(ModInfo.class::cast)
|
||||
.collect(groupingBy(IModInfo::getModId));
|
||||
|
||||
// Its theoretically possible that some mod has somehow moved an id to a secondary place, thus causing a dupe.
|
||||
// We can't handle this
|
||||
final List<ModInfo> dupedMods = modIds.values().stream()
|
||||
.filter(modInfos -> modInfos.size() > 1)
|
||||
.map(modInfos -> modInfos.get(0))
|
||||
.toList();
|
||||
|
||||
if (!dupedMods.isEmpty()) {
|
||||
final List<EarlyLoadingException.ExceptionData> duplicateModErrors = dupedMods.stream()
|
||||
.map(dm -> new EarlyLoadingException.ExceptionData("fml.modloading.dupedmod",
|
||||
dm, Objects.toString(dm))).toList();
|
||||
throw new EarlyLoadingException("Duplicate mods found", null, duplicateModErrors);
|
||||
}
|
||||
|
||||
modIdNameLookup = modIds.entrySet().stream()
|
||||
.collect(toMap(Map.Entry::getKey, e -> e.getValue().get(0)));
|
||||
}
|
||||
|
||||
private Map.Entry<String, IModFile> selectNewestModInfo(Map.Entry<String, List<IModFile>> fullList) {
|
||||
List<IModFile> modInfoList = fullList.getValue();
|
||||
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.<IModFile, ArtifactVersion>comparing(mf -> mf.getModInfos().get(0).getVersion()).reversed());
|
||||
LOGGER.debug("Selected file {} for modid {} with version {}", modInfoList.get(0).getFileName(), fullList.getKey(), modInfoList.get(0).getModInfos().get(0).getVersion());
|
||||
}
|
||||
return Map.entry(fullList.getKey(), modInfoList.get(0));
|
||||
}
|
||||
|
||||
private List<EarlyLoadingException.ExceptionData> verifyDependencyVersions()
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) Forge Development LLC and contributors
|
||||
* SPDX-License-Identifier: LGPL-2.1-only
|
||||
*/
|
||||
|
||||
package net.minecraftforge.fml.loading;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
|
||||
import net.minecraftforge.forgespi.language.IModInfo;
|
||||
import org.apache.maven.artifact.versioning.ArtifactVersion;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.stream.Collectors.*;
|
||||
|
||||
public class UniqueModListBuilder
|
||||
{
|
||||
private final static Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
private final List<ModFile> modFiles;
|
||||
|
||||
public UniqueModListBuilder(final List<ModFile> modFiles) {this.modFiles = modFiles;}
|
||||
|
||||
public UniqueModListData buildUniqueList()
|
||||
{
|
||||
List<ModFile> uniqueModList;
|
||||
List<ModFile> uniqueLibListWithVersion;
|
||||
|
||||
// Collect mod files by module name. This will be used for deduping purposes
|
||||
final Map<String, List<ModFile>> modFilesByFirstId = modFiles.stream()
|
||||
.filter(mf -> mf.getModFileInfo() != null)
|
||||
.collect(groupingBy(UniqueModListBuilder::getModId));
|
||||
|
||||
final Map<String, List<ModFile>> libFilesWithVersionByModuleName = modFiles.stream()
|
||||
.filter(mf -> mf.getModFileInfo() == null)
|
||||
.collect(groupingBy(UniqueModListBuilder::getModId));
|
||||
|
||||
// Select the newest by artifact version sorting of non-unique files thus identified
|
||||
uniqueModList = modFilesByFirstId.entrySet().stream()
|
||||
.map(this::selectNewestModInfo)
|
||||
.toList();
|
||||
|
||||
// Select the newest by artifact version sorting of non-unique files thus identified
|
||||
uniqueLibListWithVersion = libFilesWithVersionByModuleName.entrySet().stream()
|
||||
.map(this::selectNewestModInfo)
|
||||
.toList();
|
||||
|
||||
// Transform to the full mod id list
|
||||
final Map<String, List<IModInfo>> modIds = uniqueModList.stream()
|
||||
.filter(mf -> mf.getModFileInfo() != null) //Filter out non-mod files, we don't care about those for now.....
|
||||
.map(ModFile::getModInfos)
|
||||
.flatMap(Collection::stream)
|
||||
.collect(groupingBy(IModInfo::getModId));
|
||||
|
||||
// Transform to the full lib id list
|
||||
final Map<String, List<ModFile>> versionedLibIds = uniqueLibListWithVersion.stream()
|
||||
.map(UniqueModListBuilder::getModId)
|
||||
.collect(Collectors.toMap(
|
||||
Function.identity(),
|
||||
libFilesWithVersionByModuleName::get
|
||||
));
|
||||
|
||||
// Its theoretically possible that some mod has somehow moved an id to a secondary place, thus causing a dupe.
|
||||
// We can't handle this
|
||||
final List<IModInfo> dupedMods = modIds.values().stream()
|
||||
.filter(modInfos -> modInfos.size() > 1)
|
||||
.map(modInfos -> modInfos.get(0))
|
||||
.toList();
|
||||
|
||||
if (!dupedMods.isEmpty()) {
|
||||
final List<EarlyLoadingException.ExceptionData> duplicateModErrors = dupedMods.stream()
|
||||
.map(dm -> new EarlyLoadingException.ExceptionData("fml.modloading.dupedmod", dm, Objects.toString(dm)))
|
||||
.toList();
|
||||
throw new EarlyLoadingException("Duplicate mods found", null, duplicateModErrors);
|
||||
}
|
||||
|
||||
final List<ModFile> dupedLibs = versionedLibIds.values().stream()
|
||||
.filter(modFiles -> modFiles.size() > 1)
|
||||
.map(modFiles -> modFiles.get(0))
|
||||
.toList();
|
||||
|
||||
if (!dupedLibs.isEmpty()) {
|
||||
final List<EarlyLoadingException.ExceptionData> duplicateLibErrors = dupedLibs.stream()
|
||||
.map(dm -> new EarlyLoadingException.ExceptionData("fml.modloading.dupedlib.versioned", dm, Objects.toString(dm)))
|
||||
.toList();
|
||||
throw new EarlyLoadingException("Duplicate plugins or libraries found", null, duplicateLibErrors);
|
||||
}
|
||||
|
||||
// Collect unique mod files by module name. This will be used for deduping purposes
|
||||
final Map<String, List<ModFile>> uniqueModFilesByFirstId = uniqueModList.stream()
|
||||
.collect(groupingBy(UniqueModListBuilder::getModId));
|
||||
|
||||
final List<ModFile> loadedList = new ArrayList<>();
|
||||
loadedList.addAll(uniqueModList);
|
||||
loadedList.addAll(uniqueLibListWithVersion);
|
||||
|
||||
return new UniqueModListData(loadedList, uniqueModFilesByFirstId);
|
||||
}
|
||||
|
||||
private ModFile selectNewestModInfo(Map.Entry<String, List<ModFile>> fullList) {
|
||||
List<ModFile> modInfoList = fullList.getValue();
|
||||
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());
|
||||
}
|
||||
return modInfoList.get(0);
|
||||
}
|
||||
|
||||
private ArtifactVersion getVersion(final ModFile mf)
|
||||
{
|
||||
if (mf.getModFileInfo() == null) {
|
||||
return mf.getJarVersion();
|
||||
}
|
||||
return mf.getModInfos().get(0).getVersion();
|
||||
}
|
||||
|
||||
private static String getModId(ModFile modFile) {
|
||||
if (modFile.getModFileInfo() == null || modFile.getModFileInfo().getMods().isEmpty()) {
|
||||
return modFile.getSecureJar().name();
|
||||
}
|
||||
|
||||
return modFile.getModFileInfo().moduleName();
|
||||
}
|
||||
|
||||
public record UniqueModListData(List<ModFile> modFiles, Map<String, List<ModFile>> modFilesByFirstId) {}
|
||||
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) Forge Development LLC and contributors
|
||||
* SPDX-License-Identifier: LGPL-2.1-only
|
||||
*/
|
||||
|
||||
package net.minecraftforge.fml.loading.moddiscovery;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraftforge.forgespi.locating.IDependencyLocator;
|
||||
import net.minecraftforge.forgespi.locating.IModFile;
|
||||
import net.minecraftforge.forgespi.locating.ModFileLoadingException;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
|
||||
public abstract class AbstractJarFileDependencyLocator extends AbstractJarFileModProvider implements IDependencyLocator
|
||||
{
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
protected Optional<InputStream> loadResourceFromModFile(final IModFile modFile, final Path path) {
|
||||
try {
|
||||
return Optional.of(Files.newInputStream(modFile.findResource(path.toString())));
|
||||
}
|
||||
catch (final FileNotFoundException e) {
|
||||
LOGGER.debug("Failed to load resource {} from {}, it does not contain dependency information.", path, modFile.getFileName());
|
||||
return Optional.empty();
|
||||
}
|
||||
catch (final Exception e) {
|
||||
LOGGER.error("Failed to load resource {} from mod {}, cause {}", path, modFile.getFileName(), e);
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
protected Optional<IModFile> loadModFileFrom(final IModFile file, final Path path) {
|
||||
try {
|
||||
final Path pathInModFile = file.findResource(path.toString());
|
||||
return Optional.of(createMod(pathInModFile).file());
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOGGER.error("Failed to load mod file {} from {}", path, file.getFileName());
|
||||
throw new ModFileLoadingException("Failed to load mod file "+file.getFileName());
|
||||
}
|
||||
}
|
||||
|
||||
protected String identifyMod(final IModFile modFile) {
|
||||
return modFile.getFileName();
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) Forge Development LLC and contributors
|
||||
* SPDX-License-Identifier: LGPL-2.1-only
|
||||
*/
|
||||
|
||||
package net.minecraftforge.fml.loading.moddiscovery;
|
||||
|
||||
import net.minecraftforge.forgespi.locating.IModLocator;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public abstract class AbstractJarFileModLocator extends AbstractJarFileModProvider implements IModLocator
|
||||
{
|
||||
@Override
|
||||
public List<IModLocator.ModFileOrException> scanMods()
|
||||
{
|
||||
return scanCandidates().map(this::createMod).toList();
|
||||
}
|
||||
|
||||
public abstract Stream<Path> scanCandidates();
|
||||
}
|
||||
+9
-21
@@ -7,20 +7,19 @@ package net.minecraftforge.fml.loading.moddiscovery;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import cpw.mods.jarhandling.SecureJar;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import net.minecraftforge.fml.loading.LogMarkers;
|
||||
import net.minecraftforge.forgespi.locating.IModFile;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public abstract class AbstractJarFileLocator extends AbstractModLocator {
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public abstract class AbstractJarFileModProvider extends AbstractModProvider
|
||||
{
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
@Override
|
||||
@@ -34,15 +33,4 @@ public abstract class AbstractJarFileLocator extends AbstractModLocator {
|
||||
}
|
||||
LOGGER.debug(LogMarkers.SCAN,"Scan finished: {}", file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IModFile> scanMods() {
|
||||
return scanCandidates()
|
||||
.map(this::createMod)
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public abstract Stream<Path> scanCandidates();
|
||||
}
|
||||
-96
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Forge Development LLC and contributors
|
||||
* SPDX-License-Identifier: LGPL-2.1-only
|
||||
*/
|
||||
|
||||
package net.minecraftforge.fml.loading.moddiscovery;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import cpw.mods.jarhandling.JarMetadata;
|
||||
import cpw.mods.jarhandling.SecureJar;
|
||||
import net.minecraftforge.fml.loading.LogMarkers;
|
||||
import net.minecraftforge.forgespi.language.IConfigurable;
|
||||
import net.minecraftforge.forgespi.language.IModFileInfo;
|
||||
import net.minecraftforge.forgespi.language.IModInfo;
|
||||
import net.minecraftforge.forgespi.locating.IModFile;
|
||||
import net.minecraftforge.forgespi.locating.IModLocator;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
public abstract class AbstractModLocator implements IModLocator {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
protected static final String MODS_TOML = "META-INF/mods.toml";
|
||||
protected static final String MANIFEST = "META-INF/MANIFEST.MF";
|
||||
|
||||
protected Optional<IModFile> createMod(Path... path) {
|
||||
var mjm = new ModJarMetadata();
|
||||
var sj = SecureJar.from(
|
||||
Manifest::new,
|
||||
jar -> jar.findFile(MODS_TOML).isPresent() ? mjm : JarMetadata.from(jar, path),
|
||||
(root, p) -> true,
|
||||
path
|
||||
);
|
||||
|
||||
IModFile mod;
|
||||
var type = sj.getManifest().getMainAttributes().getValue(ModFile.TYPE);
|
||||
if (sj.findFile(MODS_TOML).isPresent()) {
|
||||
LOGGER.debug(LogMarkers.SCAN, "Found {} mod of type {}: {}", MODS_TOML, type, path);
|
||||
mod = new ModFile(sj, this, ModFileParser::modsTomlParser);
|
||||
} else if (type != null) {
|
||||
LOGGER.debug(LogMarkers.SCAN, "Found {} mod of type {}: {}", MANIFEST, type, path);
|
||||
mod = new ModFile(sj, this, this::manifestParser);
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
mjm.setModFile(mod);
|
||||
return Optional.of(mod);
|
||||
}
|
||||
|
||||
protected IModFileInfo manifestParser(final IModFile mod) {
|
||||
Function<String, Optional<String>> cfg = name -> Optional.ofNullable(mod.getSecureJar().getManifest().getMainAttributes().getValue(name));
|
||||
var license = cfg.apply("LICENSE").orElse("");
|
||||
var dummy = new IConfigurable() {
|
||||
@Override
|
||||
public <T> Optional<T> getConfigElement(String... key) {
|
||||
return Optional.empty();
|
||||
}
|
||||
@Override
|
||||
public List<? extends IConfigurable> getConfigList(String... key) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
};
|
||||
|
||||
return new IModFileInfo() {
|
||||
@Override public List<IModInfo> getMods() { return Collections.emptyList(); }
|
||||
@Override public List<LanguageSpec> requiredLanguageLoaders() { return Collections.emptyList(); }
|
||||
@Override public boolean showAsResourcePack() { return false; }
|
||||
@Override public Map<String, Object> getFileProperties() { return Collections.emptyMap(); }
|
||||
@Override public String getLicense() { return license; }
|
||||
@Override public IModFile getFile() { return mod; }
|
||||
@Override public IConfigurable getConfig() { return dummy; }
|
||||
|
||||
// These Should never be called as it's only called from ModJarMetadata.version and we bypass that
|
||||
@Override public String moduleName() { return mod.getSecureJar().name(); }
|
||||
@Override public String versionString() { return null; }
|
||||
@Override public List<String> usesServices() { return null; }
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IModFileInfo(" + mod.getFilePath() + ")";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(final IModFile modFile) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (c) Forge Development LLC and contributors
|
||||
* SPDX-License-Identifier: LGPL-2.1-only
|
||||
*/
|
||||
|
||||
package net.minecraftforge.fml.loading.moddiscovery;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import cpw.mods.jarhandling.JarMetadata;
|
||||
import cpw.mods.jarhandling.SecureJar;
|
||||
import net.minecraftforge.fml.loading.LogMarkers;
|
||||
import net.minecraftforge.forgespi.language.IConfigurable;
|
||||
import net.minecraftforge.forgespi.language.IModFileInfo;
|
||||
import net.minecraftforge.forgespi.language.IModInfo;
|
||||
import net.minecraftforge.forgespi.locating.IModFile;
|
||||
import net.minecraftforge.forgespi.locating.IModLocator;
|
||||
import net.minecraftforge.forgespi.locating.IModProvider;
|
||||
import net.minecraftforge.forgespi.locating.ModFileLoadingException;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
public abstract class AbstractModProvider implements IModProvider
|
||||
{
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
protected static final String MODS_TOML = "META-INF/mods.toml";
|
||||
protected static final String MANIFEST = "META-INF/MANIFEST.MF";
|
||||
|
||||
protected IModLocator.ModFileOrException createMod(Path... path) {
|
||||
var mjm = new ModJarMetadata();
|
||||
var sj = SecureJar.from(
|
||||
Manifest::new,
|
||||
jar -> jar.moduleDataProvider().findFile(MODS_TOML).isPresent() ? mjm : JarMetadata.from(jar, path),
|
||||
(root, p) -> true,
|
||||
path
|
||||
);
|
||||
|
||||
IModFile mod;
|
||||
var type = sj.moduleDataProvider().getManifest().getMainAttributes().getValue(ModFile.TYPE);
|
||||
if (type == null) {
|
||||
type = getDefaultJarModType();
|
||||
}
|
||||
if (sj.moduleDataProvider().findFile(MODS_TOML).isPresent()) {
|
||||
LOGGER.debug(LogMarkers.SCAN, "Found {} mod of type {}: {}", MODS_TOML, type, path);
|
||||
mod = new ModFile(sj, this, ModFileParser::modsTomlParser);
|
||||
} else if (type != null) {
|
||||
LOGGER.debug(LogMarkers.SCAN, "Found {} mod of type {}: {}", MANIFEST, type, path);
|
||||
mod = new ModFile(sj, this, this::manifestParser, type);
|
||||
} else {
|
||||
return new IModLocator.ModFileOrException(null, new ModFileLoadingException("Invalid mod file found "+ Arrays.toString(path)));
|
||||
}
|
||||
|
||||
mjm.setModFile(mod);
|
||||
return new IModLocator.ModFileOrException(mod, null);
|
||||
}
|
||||
|
||||
protected IModFileInfo manifestParser(final IModFile mod) {
|
||||
Function<String, Optional<String>> cfg = name -> Optional.ofNullable(mod.getSecureJar().moduleDataProvider().getManifest().getMainAttributes().getValue(name));
|
||||
var license = cfg.apply("LICENSE").orElse("");
|
||||
var dummy = new IConfigurable() {
|
||||
@Override
|
||||
public <T> Optional<T> getConfigElement(String... key) {
|
||||
return Optional.empty();
|
||||
}
|
||||
@Override
|
||||
public List<? extends IConfigurable> getConfigList(String... key) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
};
|
||||
|
||||
return new DefaultModFileInfo(mod, license, dummy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(final IModFile modFile) {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected String getDefaultJarModType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private record DefaultModFileInfo(IModFile mod, String license, IConfigurable configurable) implements IModFileInfo, IConfigurable {
|
||||
@Override
|
||||
public <T> Optional<T> getConfigElement(final String... strings)
|
||||
{
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends IConfigurable> getConfigList(final String... strings)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override public List<IModInfo> getMods() { return Collections.emptyList(); }
|
||||
@Override public List<LanguageSpec> requiredLanguageLoaders() { return Collections.emptyList(); }
|
||||
@Override public boolean showAsResourcePack() { return false; }
|
||||
@Override public Map<String, Object> getFileProperties() { return Collections.emptyMap(); }
|
||||
@Override
|
||||
public String getLicense() { return license; }
|
||||
|
||||
@Override public IModFile getFile() { return mod; }
|
||||
@Override public IConfigurable getConfig() { return configurable; }
|
||||
|
||||
// These Should never be called as it's only called from ModJarMetadata.version and we bypass that
|
||||
@Override public String moduleName() { return mod.getSecureJar().name(); }
|
||||
@Override public String versionString() { return null; }
|
||||
@Override public List<String> usesServices() { return null; }
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IModFileInfo(" + mod.getFilePath() + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-2
@@ -5,6 +5,7 @@
|
||||
|
||||
package net.minecraftforge.fml.loading.moddiscovery;
|
||||
|
||||
import net.minecraftforge.fml.loading.ClasspathLocatorUtils;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraftforge.fml.loading.LogMarkers;
|
||||
import org.slf4j.Logger;
|
||||
@@ -24,7 +25,8 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ClasspathLocator extends AbstractJarFileLocator {
|
||||
public class ClasspathLocator extends AbstractJarFileModLocator
|
||||
{
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final List<Path> legacyClasspath = Arrays.stream(System.getProperty("legacyClassPath", "").split(File.pathSeparator)).map(Path::of).toList();
|
||||
private boolean enabled = false;
|
||||
@@ -58,7 +60,7 @@ public class ClasspathLocator extends AbstractJarFileLocator {
|
||||
final Enumeration<URL> resources = ClassLoader.getSystemClassLoader().getResources(resource);
|
||||
while (resources.hasMoreElements()) {
|
||||
URL url = resources.nextElement();
|
||||
Path path = findJarPathFor(resource, resource, url);
|
||||
Path path = ClasspathLocatorUtils.findJarPathFor(resource, resource, url);
|
||||
if (claimed.stream().anyMatch(path::equals) || !Files.exists(path) || Files.isDirectory(path))
|
||||
continue;
|
||||
ret.add(path);
|
||||
|
||||
+3
-3
@@ -30,14 +30,14 @@ public class ExplodedDirectoryLocator implements IModLocator {
|
||||
private final Map<ExplodedMod, IModFile> mods = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public List<IModFile> scanMods() {
|
||||
public List<IModLocator.ModFileOrException> scanMods() {
|
||||
explodedMods.forEach(explodedMod ->
|
||||
ModJarMetadata.buildFile(this,
|
||||
jar->jar.findFile("/META-INF/mods.toml").isPresent(),
|
||||
jar->jar.moduleDataProvider().findFile("/META-INF/mods.toml").isPresent(),
|
||||
(a,b) -> true,
|
||||
explodedMod.paths().toArray(Path[]::new))
|
||||
.ifPresentOrElse(f->mods.put(explodedMod, f), () -> LOGGER.warn(LogMarkers.LOADING, "Failed to find exploded resource mods.toml in directory {}", explodedMod.paths().get(0).toString())));
|
||||
return List.copyOf(mods.values());
|
||||
return mods.values().stream().map(mf->new IModLocator.ModFileOrException(mf, null)).toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+8
-2
@@ -6,16 +6,22 @@
|
||||
package net.minecraftforge.fml.loading.moddiscovery;
|
||||
|
||||
import net.minecraftforge.forgespi.language.IModFileInfo;
|
||||
import net.minecraftforge.forgespi.locating.ModFileLoadingException;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
|
||||
public class InvalidModFileException extends RuntimeException
|
||||
public class InvalidModFileException extends ModFileLoadingException
|
||||
{
|
||||
private final IModFileInfo modFileInfo;
|
||||
|
||||
public InvalidModFileException(String message, IModFileInfo modFileInfo)
|
||||
{
|
||||
super(String.format(Locale.ENGLISH, "%s (%s)", message, ((ModFileInfo)modFileInfo).getFile().getFileName()));
|
||||
super(String.format(Locale.ROOT, "%s (%s)", message, Optional.ofNullable(modFileInfo).map(mf->mf.getFile().getFileName()).orElse("MISSING FILE NAME")));
|
||||
this.modFileInfo = modFileInfo;
|
||||
}
|
||||
|
||||
public IModFileInfo getBrokenFile() {
|
||||
return modFileInfo;
|
||||
}
|
||||
}
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (c) Forge Development LLC and contributors
|
||||
* SPDX-License-Identifier: LGPL-2.1-only
|
||||
*/
|
||||
|
||||
package net.minecraftforge.fml.loading.moddiscovery;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraftforge.fml.loading.EarlyLoadingException;
|
||||
import net.minecraftforge.forgespi.language.IModInfo;
|
||||
import net.minecraftforge.forgespi.locating.IModFile;
|
||||
import net.minecraftforge.forgespi.locating.ModFileLoadingException;
|
||||
import net.minecraftforge.jarjar.selection.JarSelector;
|
||||
import org.apache.maven.artifact.versioning.ArtifactVersion;
|
||||
import org.apache.maven.artifact.versioning.VersionRange;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class JarInJarDependencyLocator extends AbstractJarFileDependencyLocator
|
||||
{
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
@Override
|
||||
public String name()
|
||||
{
|
||||
return "JarInJar";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IModFile> scanMods(final Iterable<IModFile> loadedMods)
|
||||
{
|
||||
final List<IModFile> sources = Lists.newArrayList();
|
||||
loadedMods.forEach(sources::add);
|
||||
|
||||
|
||||
final List<IModFile> dependenciesToLoad = JarSelector.detectAndSelect(sources, this::loadResourceFromModFile, this::loadModFileFrom, this::identifyMod, this::exception);
|
||||
|
||||
if (dependenciesToLoad.isEmpty())
|
||||
{
|
||||
LOGGER.info("No dependencies to load found. Skipping!");
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
LOGGER.info("Found {} dependencies adding them to mods collection", dependenciesToLoad.size());
|
||||
return dependenciesToLoad;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initArguments(final Map<String, ?> arguments)
|
||||
{
|
||||
// NO-OP, for now
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDefaultJarModType()
|
||||
{
|
||||
return IModFile.Type.GAMELIBRARY.name();
|
||||
}
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
@Override
|
||||
protected Optional<IModFile> loadModFileFrom(final IModFile file, final Path path)
|
||||
{
|
||||
try
|
||||
{
|
||||
final Path pathInModFile = file.findResource(path.toString());
|
||||
final URI filePathUri = new URI("jij:" + (pathInModFile.toAbsolutePath().toUri().getRawSchemeSpecificPart())).normalize();
|
||||
final Map<String, ?> outerFsArgs = ImmutableMap.of("packagePath", pathInModFile);
|
||||
final FileSystem zipFS = FileSystems.newFileSystem(filePathUri, outerFsArgs);
|
||||
final Path pathInFS = zipFS.getPath("/");
|
||||
return Optional.of(createMod(pathInFS).file());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.error("Failed to load mod file {} from {}", path, file.getFileName());
|
||||
final RuntimeException exception = new ModFileLoadingException("Failed to load mod file " + file.getFileName());
|
||||
exception.initCause(e);
|
||||
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
||||
protected EarlyLoadingException exception(Collection<JarSelector.ResolutionFailureInformation<IModFile>> failedDependencies)
|
||||
{
|
||||
|
||||
final List<EarlyLoadingException.ExceptionData> errors = failedDependencies.stream()
|
||||
.filter(entry -> !entry.sources().isEmpty()) //Should never be the case, but just to be sure
|
||||
.map(this::buildExceptionData)
|
||||
.toList();
|
||||
|
||||
return new EarlyLoadingException(failedDependencies.size() + " Dependency restrictions were not met.", null, errors);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private EarlyLoadingException.ExceptionData buildExceptionData(final JarSelector.ResolutionFailureInformation<IModFile> entry)
|
||||
{
|
||||
return new EarlyLoadingException.ExceptionData(
|
||||
getErrorTranslationKey(entry),
|
||||
entry.identifier().group() + ":" + entry.identifier().artifact(),
|
||||
entry.sources()
|
||||
.stream()
|
||||
.flatMap(this::getModWithVersionRangeStream)
|
||||
.map(this::formatError)
|
||||
.collect(Collectors.joining(", "))
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String getErrorTranslationKey(final JarSelector.ResolutionFailureInformation<IModFile> entry)
|
||||
{
|
||||
return entry.failureReason() == JarSelector.FailureReason.VERSION_RESOLUTION_FAILED ?
|
||||
"fml.dependencyloading.conflictingdependencies" :
|
||||
"fml.dependencyloading.mismatchedcontaineddependencies";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Stream<ModWithVersionRange> getModWithVersionRangeStream(final JarSelector.SourceWithRequestedVersionRange<IModFile> file)
|
||||
{
|
||||
return file.sources()
|
||||
.stream()
|
||||
.map(IModFile::getModFileInfo)
|
||||
.flatMap(modFileInfo -> modFileInfo.getMods().stream())
|
||||
.map(modInfo -> new ModWithVersionRange(modInfo, file.requestedVersionRange(), file.includedVersion()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String formatError(final ModWithVersionRange modWithVersionRange)
|
||||
{
|
||||
return "\u00a7e" + modWithVersionRange.modInfo().getModId() + "\u00a7r - \u00a74" + modWithVersionRange.versionRange().toString() + "\u00a74 - \u00a72" + modWithVersionRange.artifactVersion().toString() + "\u00a72";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String identifyMod(final IModFile modFile)
|
||||
{
|
||||
if (modFile.getModFileInfo() == null || modFile.getModInfos().isEmpty())
|
||||
{
|
||||
return modFile.getFileName();
|
||||
}
|
||||
|
||||
return modFile.getModInfos().stream().map(IModInfo::getModId).collect(Collectors.joining());
|
||||
}
|
||||
|
||||
private record ModWithVersionRange(IModInfo modInfo, VersionRange versionRange, ArtifactVersion artifactVersion)
|
||||
{}
|
||||
}
|
||||
+2
-1
@@ -15,7 +15,8 @@ import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class MavenDirectoryLocator extends AbstractJarFileLocator {
|
||||
public class MavenDirectoryLocator extends AbstractJarFileModLocator
|
||||
{
|
||||
private List<Path> modCoords;
|
||||
|
||||
@Override
|
||||
|
||||
+13
-9
@@ -12,21 +12,26 @@ import net.minecraftforge.fml.loading.FMLLoader;
|
||||
import net.minecraftforge.fml.loading.LogMarkers;
|
||||
import net.minecraftforge.forgespi.language.IModFileInfo;
|
||||
import net.minecraftforge.forgespi.locating.IModFile;
|
||||
import net.minecraftforge.forgespi.locating.IModLocator;
|
||||
import net.minecraftforge.forgespi.locating.ModFileFactory;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.*;
|
||||
import java.util.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class MinecraftLocator extends AbstractModLocator {
|
||||
public class MinecraftLocator extends AbstractModProvider implements IModLocator
|
||||
{
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
@Override
|
||||
public List<IModFile> scanMods() {
|
||||
public List<IModLocator.ModFileOrException> scanMods() {
|
||||
final var launchHandler = FMLLoader.getLaunchHandler();
|
||||
var baseMC = launchHandler.getMinecraftPaths();
|
||||
var mcjar = ModJarMetadata.buildFile(j->ModFileFactory.FACTORY.build(j, this, this::buildMinecraftTOML), j->true, baseMC.minecraftFilter(), baseMC.minecraftPaths().toArray(Path[]::new)).orElseThrow();
|
||||
@@ -35,12 +40,11 @@ public class MinecraftLocator extends AbstractModLocator {
|
||||
.map(sj -> new ModFile(sj, this, ModFileParser::modsTomlParser))
|
||||
.collect(Collectors.<IModFile>toList());
|
||||
var othermods = baseMC.otherModPaths().stream()
|
||||
.map(p -> createMod(p.toArray(Path[]::new)).orElse(null))
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
.map(p -> createMod(p.toArray(Path[]::new)))
|
||||
.filter(Objects::nonNull);
|
||||
artifacts.add(mcjar);
|
||||
artifacts.addAll(othermods);
|
||||
return artifacts;
|
||||
|
||||
return Stream.concat(artifacts.stream().map(f -> new ModFileOrException(f, null)), othermods).toList();
|
||||
}
|
||||
|
||||
private IModFileInfo buildMinecraftTOML(final IModFile iModFile) {
|
||||
|
||||
+132
-27
@@ -5,13 +5,19 @@
|
||||
|
||||
package net.minecraftforge.fml.loading.moddiscovery;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.mojang.logging.LogUtils;
|
||||
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.LogMarkers;
|
||||
import net.minecraftforge.fml.loading.UniqueModListBuilder;
|
||||
import net.minecraftforge.fml.loading.progress.StartupMessageManager;
|
||||
import net.minecraftforge.forgespi.Environment;
|
||||
import net.minecraftforge.forgespi.language.IModFileInfo;
|
||||
import net.minecraftforge.forgespi.locating.IDependencyLocator;
|
||||
import net.minecraftforge.forgespi.locating.IModFile;
|
||||
import net.minecraftforge.forgespi.locating.IModLocator;
|
||||
import org.slf4j.Logger;
|
||||
@@ -19,52 +25,151 @@ import org.slf4j.Logger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ModDiscoverer {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final ServiceLoader<IModLocator> locators;
|
||||
private final List<IModLocator> locatorList;
|
||||
private final ServiceLoader<IModLocator> modLocators;
|
||||
private final ServiceLoader<IDependencyLocator> dependencyLocators;
|
||||
private final List<IModLocator> modLocatorList;
|
||||
private final List<IDependencyLocator> dependencyLocatorList;
|
||||
|
||||
public ModDiscoverer(Map<String, ?> arguments) {
|
||||
Launcher.INSTANCE.environment().computePropertyIfAbsent(Environment.Keys.MODDIRECTORYFACTORY.get(), v->ModsFolderLocator::new);
|
||||
Launcher.INSTANCE.environment().computePropertyIfAbsent(Environment.Keys.PROGRESSMESSAGE.get(), v-> StartupMessageManager.locatorConsumer().orElseGet(()-> s->{}));
|
||||
final var moduleLayerManager = Launcher.INSTANCE.environment().findModuleLayerManager().orElseThrow();
|
||||
locators = ServiceLoader.load(moduleLayerManager.getLayer(IModuleLayerManager.Layer.SERVICE).orElseThrow(), IModLocator.class);
|
||||
locatorList = ServiceLoaderUtils.streamServiceLoader(()->locators, sce->LOGGER.error("Failed to load locator list", sce)).collect(Collectors.toList());
|
||||
locatorList.forEach(l->l.initArguments(arguments));
|
||||
modLocators = ServiceLoader.load(moduleLayerManager.getLayer(IModuleLayerManager.Layer.SERVICE).orElseThrow(), IModLocator.class);
|
||||
dependencyLocators = ServiceLoader.load(moduleLayerManager.getLayer(IModuleLayerManager.Layer.SERVICE).orElseThrow(), IDependencyLocator.class);
|
||||
modLocatorList = ServiceLoaderUtils.streamServiceLoader(()-> modLocators, sce->LOGGER.error("Failed to load mod locator list", sce)).collect(Collectors.toList());
|
||||
modLocatorList.forEach(l->l.initArguments(arguments));
|
||||
dependencyLocatorList = ServiceLoaderUtils.streamServiceLoader(()-> dependencyLocators, sce->LOGGER.error("Failed to load dependency locator list", sce)).collect(Collectors.toList());
|
||||
dependencyLocatorList.forEach(l->l.initArguments(arguments));
|
||||
if (LOGGER.isDebugEnabled(LogMarkers.CORE))
|
||||
{
|
||||
LOGGER.debug(LogMarkers.CORE, "Found Mod Locators : {}", locatorList.stream()
|
||||
.map(iModLocator -> "(" + iModLocator.name() + ":" + iModLocator.getClass().getPackage().getImplementationVersion() + ")").collect(Collectors.joining(",")));
|
||||
LOGGER.debug(LogMarkers.CORE, "Found Mod Locators : {}", modLocatorList.stream()
|
||||
.map(modLocator -> "(%s:%s)".formatted(modLocator.name(),
|
||||
modLocator.getClass().getPackage().getImplementationVersion())).collect(Collectors.joining(",")));
|
||||
}
|
||||
if (LOGGER.isDebugEnabled(LogMarkers.CORE))
|
||||
{
|
||||
LOGGER.debug(LogMarkers.CORE, "Found Dependency Locators : {}", dependencyLocatorList.stream()
|
||||
.map(dependencyLocator -> "(%s:%s)".formatted(dependencyLocator.name(),
|
||||
dependencyLocator.getClass().getPackage().getImplementationVersion())).collect(Collectors.joining(",")));
|
||||
}
|
||||
}
|
||||
|
||||
ModDiscoverer(List<IModLocator> locatorList) {
|
||||
this.locatorList = locatorList;
|
||||
this.locators = null;
|
||||
}
|
||||
|
||||
public ModValidator discoverMods() {
|
||||
LOGGER.debug(LogMarkers.SCAN,"Scanning for mods and other resources to load. We know {} ways to find mods", locatorList.size());
|
||||
var loadedFiles = new ArrayList<>();
|
||||
for (IModLocator locator : locatorList) {
|
||||
LOGGER.debug(LogMarkers.SCAN,"Trying locator {}", locator);
|
||||
var modFiles = locator.scanMods();
|
||||
for (IModFile mf : modFiles) {
|
||||
LOGGER.info(LogMarkers.SCAN, "Found mod file {} of type {} with locator {}", mf.getFileName(), mf.getType(), mf.getLocator());
|
||||
StartupMessageManager.modLoaderConsumer().ifPresent(c->c.accept("Found mod file "+mf.getFileName()+" of type "+mf.getType()));
|
||||
}
|
||||
loadedFiles.addAll(modFiles);
|
||||
}
|
||||
final var modFilesMap = loadedFiles.stream()
|
||||
.map(ModFile.class::cast)
|
||||
.collect(Collectors.groupingBy(IModFile::getType));
|
||||
LOGGER.debug(LogMarkers.SCAN,"Scanning for mods and other resources to load. We know {} ways to find mods", modLocatorList.size());
|
||||
List<ModFile> loadedFiles = new ArrayList<>();
|
||||
List<EarlyLoadingException.ExceptionData> discoveryErrorData = new ArrayList<>();
|
||||
boolean successfullyLoadedMods = true;
|
||||
List<IModFileInfo> brokenFiles = new ArrayList<>();
|
||||
|
||||
var validator = new ModValidator(modFilesMap);
|
||||
//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 candidates = locator.scanMods();
|
||||
LOGGER.debug(LogMarkers.SCAN, "Locator {} found {} candidates or errors", locator, candidates.size());
|
||||
var exceptions = candidates.stream().map(IModLocator.ModFileOrException::ex).filter(Objects::nonNull).toList();
|
||||
if (!exceptions.isEmpty()) {
|
||||
LOGGER.debug(LogMarkers.SCAN, "Locator {} found {} invalid mod files", locator, exceptions.size());
|
||||
brokenFiles.addAll(exceptions.stream().map(e->e instanceof InvalidModFileException ime ? ime.getBrokenFile() : null).filter(Objects::nonNull).toList());
|
||||
}
|
||||
var locatedFiles = candidates.stream().map(IModLocator.ModFileOrException::file).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
|
||||
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());
|
||||
brokenFiles.addAll(badModFiles.stream().map(IModFile::getModFileInfo).toList());
|
||||
}
|
||||
locatedFiles.removeAll(badModFiles);
|
||||
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);
|
||||
brokenFiles.add(imfe.getBrokenFile());
|
||||
} catch (EarlyLoadingException exception) {
|
||||
LOGGER.error(LogMarkers.SCAN, "Failed to load mods with locator {}", locator, exception);
|
||||
discoveryErrorData.addAll(exception.getAllData());
|
||||
}
|
||||
}
|
||||
|
||||
//First processing run of the mod list. Any duplicates will cause resolution failure and dependency loading will be skipped.
|
||||
Map<IModFile.Type, List<ModFile>> modFilesMap = Maps.newHashMap();
|
||||
try {
|
||||
final UniqueModListBuilder modsUniqueListBuilder = new UniqueModListBuilder(loadedFiles);
|
||||
final UniqueModListBuilder.UniqueModListData uniqueModsData = modsUniqueListBuilder.buildUniqueList();
|
||||
|
||||
//Grab the temporary results.
|
||||
//This allows loading to continue to a base state, in case dependency loading fails.
|
||||
modFilesMap = uniqueModsData.modFiles().stream()
|
||||
.collect(Collectors.groupingBy(IModFile::getType));
|
||||
loadedFiles = uniqueModsData.modFiles();
|
||||
}
|
||||
catch (EarlyLoadingException exception) {
|
||||
LOGGER.error(LogMarkers.SCAN, "Failed to build unique mod list after mod discovery.", exception);
|
||||
discoveryErrorData.addAll(exception.getAllData());
|
||||
successfullyLoadedMods = false;
|
||||
}
|
||||
|
||||
//We can continue loading if prime mods loaded successfully.
|
||||
if (successfullyLoadedMods) {
|
||||
LOGGER.debug(LogMarkers.SCAN, "Successfully Loaded {} mods. Attempting to load dependencies...", loadedFiles.size());
|
||||
for (IDependencyLocator locator : dependencyLocatorList) {
|
||||
try {
|
||||
LOGGER.debug(LogMarkers.SCAN,"Trying locator {}", locator);
|
||||
final List<IModFile> locatedMods = ImmutableList.copyOf(loadedFiles);
|
||||
|
||||
var locatedFiles = locator.scanMods(locatedMods);
|
||||
if (locatedFiles.stream().anyMatch(file -> !(file instanceof ModFile))) {
|
||||
LOGGER.error(LogMarkers.SCAN, "A dependency locator returned a file which is not a ModFile instance!. They will be skipped!");
|
||||
}
|
||||
|
||||
handleLocatedFiles(loadedFiles, locatedFiles);
|
||||
}
|
||||
catch (EarlyLoadingException exception) {
|
||||
LOGGER.error(LogMarkers.SCAN, "Failed to load dependencies with locator {}", locator, exception);
|
||||
discoveryErrorData.addAll(exception.getAllData());
|
||||
}
|
||||
}
|
||||
|
||||
//Second processing run of the mod list. Any duplicates will cause resolution failure and only the mods list will be loaded.
|
||||
try {
|
||||
final UniqueModListBuilder modsAndDependenciesUniqueListBuilder = new UniqueModListBuilder(loadedFiles);
|
||||
final UniqueModListBuilder.UniqueModListData uniqueModsAndDependenciesData = modsAndDependenciesUniqueListBuilder.buildUniqueList();
|
||||
|
||||
//We now only need the mod files map, not the list.
|
||||
modFilesMap = uniqueModsAndDependenciesData.modFiles().stream()
|
||||
.collect(Collectors.groupingBy(IModFile::getType));
|
||||
} catch (EarlyLoadingException exception) {
|
||||
LOGGER.error(LogMarkers.SCAN, "Failed to build unique mod list after dependency discovery.", exception);
|
||||
discoveryErrorData.addAll(exception.getAllData());
|
||||
modFilesMap = loadedFiles.stream().collect(Collectors.groupingBy(IModFile::getType));
|
||||
}
|
||||
}
|
||||
else {
|
||||
//Failure notify the listeners.
|
||||
LOGGER.error(LogMarkers.SCAN, "Mod Discovery failed. Skipping dependency discovery.");
|
||||
}
|
||||
|
||||
//Validate the loading. With a deduplicated list, we can now successfully process the artifacts and load
|
||||
//transformer plugins.
|
||||
var validator = new ModValidator(modFilesMap, brokenFiles, discoveryErrorData);
|
||||
validator.stage1Validation();
|
||||
return validator;
|
||||
}
|
||||
|
||||
private void handleLocatedFiles(final List<ModFile> loadedFiles, final List<IModFile> locatedFiles)
|
||||
{
|
||||
var locatedModFiles = locatedFiles.stream().filter(ModFile.class::isInstance).map(ModFile.class::cast).toList();
|
||||
for (IModFile mf : locatedModFiles) {
|
||||
LOGGER.info(LogMarkers.SCAN, "Found mod file {} of type {} with provider {}", mf.getFileName(), mf.getType(), mf.getProvider());
|
||||
StartupMessageManager.modLoaderConsumer().ifPresent(c->c.accept("Found mod file "+mf.getFileName()+" of type "+mf.getType()));
|
||||
}
|
||||
loadedFiles.addAll(locatedModFiles);
|
||||
}
|
||||
}
|
||||
@@ -16,8 +16,10 @@ import net.minecraftforge.forgespi.language.IModInfo;
|
||||
import net.minecraftforge.forgespi.language.IModLanguageProvider;
|
||||
import net.minecraftforge.forgespi.language.ModFileScanData;
|
||||
import net.minecraftforge.forgespi.locating.IModFile;
|
||||
import net.minecraftforge.forgespi.locating.IModLocator;
|
||||
import net.minecraftforge.forgespi.locating.IModProvider;
|
||||
import net.minecraftforge.forgespi.locating.ModFileFactory;
|
||||
import org.apache.maven.artifact.versioning.ArtifactVersion;
|
||||
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.nio.file.Files;
|
||||
@@ -51,9 +53,9 @@ public class ModFile implements IModFile {
|
||||
private Throwable scanError;
|
||||
private final SecureJar jar;
|
||||
private final Type modFileType;
|
||||
private final Manifest manifest;
|
||||
private final IModLocator locator;
|
||||
private IModFileInfo modFileInfo;
|
||||
private final Manifest manifest;
|
||||
private final IModProvider provider;
|
||||
private IModFileInfo modFileInfo;
|
||||
private ModFileScanData fileModFileScanData;
|
||||
private CompletableFuture<ModFileScanData> futureScanResult;
|
||||
private List<CoreModFile> coreMods;
|
||||
@@ -62,15 +64,19 @@ public class ModFile implements IModFile {
|
||||
static final Attributes.Name TYPE = new Attributes.Name("FMLModType");
|
||||
private SecureJar.Status securityStatus;
|
||||
|
||||
public ModFile(final SecureJar jar, final IModLocator locator, final ModFileFactory.ModFileInfoParser parser) {
|
||||
this.locator = locator;
|
||||
public ModFile(final SecureJar jar, final IModProvider provider, final ModFileFactory.ModFileInfoParser parser) {
|
||||
this(jar, provider, parser, parseType(jar));
|
||||
}
|
||||
|
||||
public ModFile(final SecureJar jar, final IModProvider provider, final ModFileFactory.ModFileInfoParser parser, String type) {
|
||||
this.provider = provider;
|
||||
this.jar = jar;
|
||||
this.parser = parser;
|
||||
|
||||
manifest = this.jar.getManifest();
|
||||
final Optional<String> value = Optional.ofNullable(manifest.getMainAttributes().getValue(TYPE));
|
||||
modFileType = Type.valueOf(value.orElse("MOD"));
|
||||
manifest = this.jar.moduleDataProvider().getManifest();
|
||||
modFileType = Type.valueOf(type);
|
||||
jarVersion = Optional.ofNullable(manifest.getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VERSION)).orElse("0.0NONE");
|
||||
this.modFileInfo = ModFileParser.readModList(this, this.parser);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -123,7 +129,7 @@ public class ModFile implements IModFile {
|
||||
}
|
||||
|
||||
public void scanFile(Consumer<Path> pathConsumer) {
|
||||
locator.scanFile(this, pathConsumer);
|
||||
provider.scanFile(this, pathConsumer);
|
||||
}
|
||||
|
||||
public void setFutureScanResult(CompletableFuture<ModFileScanData> future) {
|
||||
@@ -188,8 +194,8 @@ public class ModFile implements IModFile {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IModLocator getLocator() {
|
||||
return locator;
|
||||
public IModProvider getProvider() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -201,4 +207,15 @@ public class ModFile implements IModFile {
|
||||
public void setSecurityStatus(final SecureJar.Status status) {
|
||||
this.securityStatus = status;
|
||||
}
|
||||
|
||||
public ArtifactVersion getJarVersion()
|
||||
{
|
||||
return new DefaultArtifactVersion(this.jarVersion);
|
||||
}
|
||||
|
||||
private static String parseType(final SecureJar jar) {
|
||||
final Manifest m = jar.moduleDataProvider().getManifest();
|
||||
final Optional<String> value = Optional.ofNullable(m.getMainAttributes().getValue(TYPE));
|
||||
return value.orElse("MOD");
|
||||
}
|
||||
}
|
||||
@@ -11,12 +11,11 @@ import net.minecraftforge.fml.loading.StringUtils;
|
||||
import net.minecraftforge.forgespi.language.IConfigurable;
|
||||
import net.minecraftforge.forgespi.language.IModInfo;
|
||||
import net.minecraftforge.forgespi.language.MavenVersionAdapter;
|
||||
import net.minecraftforge.forgespi.locating.ForgeFeature;
|
||||
import org.apache.maven.artifact.versioning.ArtifactVersion;
|
||||
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
|
||||
import org.apache.maven.artifact.versioning.VersionRange;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.Marker;
|
||||
import org.slf4j.MarkerFactory;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
@@ -32,6 +31,7 @@ public class ModInfo implements IModInfo, IConfigurable
|
||||
private static final DefaultArtifactVersion DEFAULT_VERSION = new DefaultArtifactVersion("1");
|
||||
private static final Pattern VALID_MODID = Pattern.compile("^[a-z][a-z0-9_]{1,63}$");
|
||||
private static final Pattern VALID_NAMESPACE = Pattern.compile("^[a-z][a-z0-9_.-]{1,63}$");
|
||||
private static final Pattern VALID_VERSION = Pattern.compile("^\\d+.*");
|
||||
|
||||
private final ModFileInfo owningFile;
|
||||
private final String modId;
|
||||
@@ -43,8 +43,11 @@ public class ModInfo implements IModInfo, IConfigurable
|
||||
private final boolean logoBlur;
|
||||
private final Optional<URL> updateJSONURL;
|
||||
private final List<? extends IModInfo.ModVersion> dependencies;
|
||||
|
||||
private final List<ForgeFeature.Bound> features;
|
||||
private final Map<String,Object> properties;
|
||||
private final IConfigurable config;
|
||||
private final Optional<URL> modUrl;
|
||||
|
||||
public ModInfo(final ModFileInfo owningFile, final IConfigurable config)
|
||||
{
|
||||
@@ -83,9 +86,23 @@ public class ModInfo implements IModInfo, IConfigurable
|
||||
.collect(Collectors.toList()))
|
||||
.orElse(Collections.emptyList());
|
||||
|
||||
this.features = ownFile.map(mfi -> mfi.<Map<String, String>>getConfigElement("features", this.modId)
|
||||
.stream()
|
||||
.flatMap(m->m.entrySet().stream())
|
||||
.map(e->new ForgeFeature.Bound(e.getKey(), e.getValue(), this))
|
||||
.collect(Collectors.toList())).orElse(Collections.emptyList());
|
||||
|
||||
this.properties = ownFile.map(mfi -> mfi.<Map<String, Object>>getConfigElement("modproperties", this.modId)
|
||||
.orElse(Collections.emptyMap()))
|
||||
.orElse(Collections.emptyMap());
|
||||
|
||||
this.modUrl = config.<String>getConfigElement("modUrl")
|
||||
.map(StringUtils::toURL);
|
||||
|
||||
// verify we have a valid mod version otherwise throw an exception
|
||||
if (!VALID_VERSION.matcher(this.version.toString()).matches()) {
|
||||
throw new InvalidModFileException("Illegal version number specified "+this.version, this.getOwningFile());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -152,6 +169,11 @@ public class ModInfo implements IModInfo, IConfigurable
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends ForgeFeature.Bound> getForgeFeatures() {
|
||||
return this.features;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Optional<T> getConfigElement(final String... key) {
|
||||
return this.config.getConfigElement(key);
|
||||
@@ -162,6 +184,11 @@ public class ModInfo implements IModInfo, IConfigurable
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<URL> getModURL() {
|
||||
return modUrl;
|
||||
}
|
||||
|
||||
class ModVersion implements net.minecraftforge.forgespi.language.IModInfo.ModVersion {
|
||||
private IModInfo owner;
|
||||
private final String modId;
|
||||
@@ -169,6 +196,7 @@ public class ModInfo implements IModInfo, IConfigurable
|
||||
private final boolean mandatory;
|
||||
private final Ordering ordering;
|
||||
private final DependencySide side;
|
||||
private Optional<URL> referralUrl;
|
||||
|
||||
public ModVersion(final IModInfo owner, final IConfigurable config) {
|
||||
this.owner = owner;
|
||||
@@ -185,6 +213,8 @@ public class ModInfo implements IModInfo, IConfigurable
|
||||
this.side = config.<String>getConfigElement("side")
|
||||
.map(DependencySide::valueOf)
|
||||
.orElse(DependencySide.BOTH);
|
||||
this.referralUrl = config.<String>getConfigElement("referralUrl")
|
||||
.map(StringUtils::toURL);
|
||||
}
|
||||
|
||||
|
||||
@@ -229,6 +259,11 @@ public class ModInfo implements IModInfo, IConfigurable
|
||||
{
|
||||
return owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<URL> getReferralURL() {
|
||||
return referralUrl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+23
-11
@@ -13,11 +13,16 @@ import net.minecraftforge.fml.loading.LoadingModList;
|
||||
import net.minecraftforge.fml.loading.LogMarkers;
|
||||
import net.minecraftforge.fml.loading.ModSorter;
|
||||
import net.minecraftforge.fml.loading.progress.StartupMessageManager;
|
||||
import net.minecraftforge.forgespi.language.IModFileInfo;
|
||||
import net.minecraftforge.forgespi.locating.IModFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ModValidator {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
@@ -25,14 +30,17 @@ public class ModValidator {
|
||||
private final List<ModFile> candidatePlugins;
|
||||
private final List<ModFile> candidateMods;
|
||||
private LoadingModList loadingModList;
|
||||
private List<ModFile> brokenFiles;
|
||||
private List<IModFile> brokenFiles;
|
||||
private final List<EarlyLoadingException.ExceptionData> discoveryErrorData;
|
||||
|
||||
public ModValidator(final Map<IModFile.Type, List<ModFile>> modFiles) {
|
||||
public ModValidator(final Map<IModFile.Type, List<ModFile>> modFiles, final List<IModFileInfo> brokenFiles, final List<EarlyLoadingException.ExceptionData> discoveryErrorData) {
|
||||
this.modFiles = modFiles;
|
||||
this.candidateMods = lst(modFiles.get(IModFile.Type.MOD));
|
||||
this.candidateMods.addAll(lst(modFiles.get(IModFile.Type.GAMELIBRARY)));
|
||||
this.candidatePlugins = lst(modFiles.get(IModFile.Type.LANGPROVIDER));
|
||||
this.candidatePlugins.addAll(lst(modFiles.get(IModFile.Type.LIBRARY)));
|
||||
this.discoveryErrorData = discoveryErrorData;
|
||||
this.brokenFiles = brokenFiles.stream().map(IModFileInfo::getFile).collect(Collectors.toList()); // mutable list
|
||||
}
|
||||
|
||||
private static List<ModFile> lst(List<ModFile> files) {
|
||||
@@ -40,7 +48,7 @@ public class ModValidator {
|
||||
}
|
||||
|
||||
public void stage1Validation() {
|
||||
brokenFiles = validateFiles(candidateMods);
|
||||
brokenFiles.addAll(validateFiles(candidateMods));
|
||||
if (LOGGER.isDebugEnabled(LogMarkers.SCAN)) {
|
||||
LOGGER.debug(LogMarkers.SCAN, "Found {} mod files with {} mods", candidateMods.size(), candidateMods.stream().mapToInt(mf -> mf.getModInfos().size()).sum());
|
||||
}
|
||||
@@ -52,22 +60,22 @@ public class ModValidator {
|
||||
final List<ModFile> brokenFiles = new ArrayList<>();
|
||||
for (Iterator<ModFile> iterator = mods.iterator(); iterator.hasNext(); )
|
||||
{
|
||||
ModFile mod = iterator.next();
|
||||
if (!mod.getLocator().isValid(mod) || !mod.identifyMods()) {
|
||||
LOGGER.warn(LogMarkers.SCAN, "File {} has been ignored - it is invalid", mod.getFilePath());
|
||||
ModFile modFile = iterator.next();
|
||||
if (!modFile.getProvider().isValid(modFile) || !modFile.identifyMods()) {
|
||||
LOGGER.warn(LogMarkers.SCAN, "File {} has been ignored - it is invalid", modFile.getFilePath());
|
||||
iterator.remove();
|
||||
brokenFiles.add(mod);
|
||||
brokenFiles.add(modFile);
|
||||
}
|
||||
}
|
||||
return brokenFiles;
|
||||
}
|
||||
|
||||
public ITransformationService.Resource getPluginResources() {
|
||||
return new ITransformationService.Resource(IModuleLayerManager.Layer.PLUGIN, this.candidatePlugins.stream().map(ModFile::getSecureJar).toList());
|
||||
return new ITransformationService.Resource(IModuleLayerManager.Layer.PLUGIN, this.candidatePlugins.stream().map(IModFile::getSecureJar).toList());
|
||||
}
|
||||
|
||||
public ITransformationService.Resource getModResources() {
|
||||
return new ITransformationService.Resource(IModuleLayerManager.Layer.GAME, this.candidateMods.stream().map(ModFile::getSecureJar).toList());
|
||||
return new ITransformationService.Resource(IModuleLayerManager.Layer.GAME, this.candidateMods.stream().map(IModFile::getSecureJar).toList());
|
||||
}
|
||||
|
||||
private List<EarlyLoadingException.ExceptionData> validateLanguages() {
|
||||
@@ -86,7 +94,11 @@ public class ModValidator {
|
||||
|
||||
public BackgroundScanHandler stage2Validation() {
|
||||
var errors = validateLanguages();
|
||||
loadingModList = ModSorter.sort(candidateMods, errors);
|
||||
|
||||
var allErrors = new ArrayList<>(errors);
|
||||
allErrors.addAll(this.discoveryErrorData);
|
||||
|
||||
loadingModList = ModSorter.sort(candidateMods, allErrors);
|
||||
loadingModList.addCoreMods();
|
||||
loadingModList.addAccessTransformers();
|
||||
loadingModList.setBrokenFiles(brokenFiles);
|
||||
|
||||
+2
-1
@@ -23,7 +23,8 @@ import static cpw.mods.modlauncher.api.LamdbaExceptionUtils.uncheck;
|
||||
/**
|
||||
* Support loading mods located in JAR files in the mods folder
|
||||
*/
|
||||
public class ModsFolderLocator extends AbstractJarFileLocator {
|
||||
public class ModsFolderLocator extends AbstractJarFileModLocator
|
||||
{
|
||||
private static final String SUFFIX = ".jar";
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final Path modFolder;
|
||||
|
||||
+2
-2
@@ -5,6 +5,7 @@
|
||||
|
||||
package net.minecraftforge.fml.loading.targets;
|
||||
|
||||
import cpw.mods.modlauncher.api.ServiceRunner;
|
||||
import net.minecraftforge.fml.loading.FMLLoader;
|
||||
import net.minecraftforge.fml.loading.LibraryFinder;
|
||||
import net.minecraftforge.fml.loading.VersionInfo;
|
||||
@@ -21,10 +22,9 @@ public abstract class CommonClientLaunchHandler extends CommonLaunchHandler {
|
||||
@Override public boolean isProduction() { return true; }
|
||||
|
||||
@Override
|
||||
public Callable<Void> launchService(String[] arguments, ModuleLayer layer) {
|
||||
public ServiceRunner launchService(String[] arguments, ModuleLayer layer) {
|
||||
return () -> {
|
||||
Class.forName(layer.findModule("minecraft").orElseThrow(),"net.minecraft.client.main.Main").getMethod("main", String[].class).invoke(null, (Object)arguments);
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -6,6 +6,7 @@
|
||||
package net.minecraftforge.fml.loading.targets;
|
||||
|
||||
import cpw.mods.jarhandling.SecureJar;
|
||||
import cpw.mods.modlauncher.api.ServiceRunner;
|
||||
import net.minecraftforge.fml.loading.FMLLoader;
|
||||
import net.minecraftforge.fml.loading.LibraryFinder;
|
||||
import net.minecraftforge.fml.loading.VersionInfo;
|
||||
@@ -23,10 +24,9 @@ public abstract class CommonServerLaunchHandler extends CommonLaunchHandler {
|
||||
@Override public boolean isProduction() { return true; }
|
||||
|
||||
@Override
|
||||
public Callable<Void> launchService(String[] arguments, ModuleLayer layer) {
|
||||
public ServiceRunner launchService(String[] arguments, ModuleLayer layer) {
|
||||
return () -> {
|
||||
Class.forName(layer.findModule("minecraft").orElseThrow(),"net.minecraft.server.Main").getMethod("main", String[].class).invoke(null, (Object)arguments);
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -5,6 +5,7 @@
|
||||
|
||||
package net.minecraftforge.fml.loading.targets;
|
||||
|
||||
import cpw.mods.modlauncher.api.ServiceRunner;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
@@ -13,12 +14,11 @@ public class FMLClientDevLaunchHandler extends CommonDevLaunchHandler {
|
||||
@Override public Dist getDist() { return Dist.CLIENT; }
|
||||
|
||||
@Override
|
||||
public Callable<Void> launchService(String[] arguments, ModuleLayer layer) {
|
||||
public ServiceRunner launchService(String[] arguments, ModuleLayer layer) {
|
||||
return () -> {
|
||||
var args = preLaunch(arguments, layer);
|
||||
|
||||
Class.forName(layer.findModule("minecraft").orElseThrow(), "net.minecraft.client.main.Main").getMethod("main", String[].class).invoke(null, (Object) args);
|
||||
return null;
|
||||
};
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -5,6 +5,7 @@
|
||||
|
||||
package net.minecraftforge.fml.loading.targets;
|
||||
|
||||
import cpw.mods.modlauncher.api.ServiceRunner;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
@@ -17,12 +18,11 @@ public class FMLClientUserdevLaunchHandler extends FMLUserdevLaunchHandler {
|
||||
public Dist getDist() { return Dist.CLIENT; }
|
||||
|
||||
@Override
|
||||
public Callable<Void> launchService(String[] arguments, ModuleLayer layer) {
|
||||
public ServiceRunner launchService(String[] arguments, ModuleLayer layer) {
|
||||
return () -> {
|
||||
var args = preLaunch(arguments, layer);
|
||||
|
||||
Class.forName(layer.findModule("minecraft").orElseThrow(), "net.minecraft.client.main.Main").getMethod("main", String[].class).invoke(null, (Object) args);
|
||||
return null;
|
||||
};
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -5,6 +5,7 @@
|
||||
|
||||
package net.minecraftforge.fml.loading.targets;
|
||||
|
||||
import cpw.mods.modlauncher.api.ServiceRunner;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
@@ -20,12 +21,11 @@ public class FMLDataUserdevLaunchHandler extends FMLUserdevLaunchHandler {
|
||||
public boolean isData() { return true; }
|
||||
|
||||
@Override
|
||||
public Callable<Void> launchService(String[] arguments, ModuleLayer layer) {
|
||||
public ServiceRunner launchService(String[] arguments, ModuleLayer layer) {
|
||||
return () -> {
|
||||
var args = preLaunch(arguments, layer);
|
||||
|
||||
Class.forName(layer.findModule("minecraft").orElseThrow(), "net.minecraft.data.Main").getMethod("main", String[].class).invoke(null, (Object) args);
|
||||
return null;
|
||||
};
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -5,6 +5,7 @@
|
||||
|
||||
package net.minecraftforge.fml.loading.targets;
|
||||
|
||||
import cpw.mods.modlauncher.api.ServiceRunner;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
@@ -13,12 +14,11 @@ public class FMLServerDevLaunchHandler extends CommonDevLaunchHandler {
|
||||
@Override public Dist getDist() { return Dist.DEDICATED_SERVER; }
|
||||
|
||||
@Override
|
||||
public Callable<Void> launchService(String[] arguments, ModuleLayer layer) {
|
||||
public ServiceRunner launchService(String[] arguments, ModuleLayer layer) {
|
||||
return () -> {
|
||||
var args = preLaunch(arguments, layer);
|
||||
|
||||
Class.forName(layer.findModule("minecraft").orElseThrow(),"net.minecraft.server.Main").getMethod("main", String[].class).invoke(null, (Object)args);
|
||||
return null;
|
||||
};
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -5,6 +5,7 @@
|
||||
|
||||
package net.minecraftforge.fml.loading.targets;
|
||||
|
||||
import cpw.mods.modlauncher.api.ServiceRunner;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
@@ -14,12 +15,11 @@ public class FMLServerUserdevLaunchHandler extends FMLUserdevLaunchHandler {
|
||||
@Override public Dist getDist() { return Dist.DEDICATED_SERVER; }
|
||||
|
||||
@Override
|
||||
public Callable<Void> launchService(String[] arguments, ModuleLayer layer) {
|
||||
public ServiceRunner launchService(String[] arguments, ModuleLayer layer) {
|
||||
return () -> {
|
||||
var args = preLaunch(arguments, layer);
|
||||
|
||||
Class.forName(layer.findModule("minecraft").orElseThrow(),"net.minecraft.server.Main").getMethod("main", String[].class).invoke(null, (Object)args);
|
||||
return null;
|
||||
};
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -5,6 +5,7 @@
|
||||
|
||||
package net.minecraftforge.fml.loading.targets;
|
||||
|
||||
import cpw.mods.modlauncher.api.ServiceRunner;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
@@ -13,12 +14,11 @@ public class ForgeClientDevLaunchHandler extends CommonDevLaunchHandler {
|
||||
@Override public Dist getDist() { return Dist.CLIENT; }
|
||||
|
||||
@Override
|
||||
public Callable<Void> launchService(String[] arguments, ModuleLayer layer) {
|
||||
public ServiceRunner launchService(String[] arguments, ModuleLayer layer) {
|
||||
return () -> {
|
||||
var args = preLaunch(arguments, layer);
|
||||
|
||||
Class.forName(layer.findModule("minecraft").orElseThrow(), "net.minecraft.client.main.Main").getMethod("main", String[].class).invoke(null, (Object) args);
|
||||
return null;
|
||||
};
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -5,6 +5,7 @@
|
||||
|
||||
package net.minecraftforge.fml.loading.targets;
|
||||
|
||||
import cpw.mods.modlauncher.api.ServiceRunner;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
@@ -17,12 +18,11 @@ public class ForgeClientUserdevLaunchHandler extends ForgeUserdevLaunchHandler {
|
||||
public Dist getDist() { return Dist.CLIENT; }
|
||||
|
||||
@Override
|
||||
public Callable<Void> launchService(String[] arguments, ModuleLayer layer) {
|
||||
public ServiceRunner launchService(String[] arguments, ModuleLayer layer) {
|
||||
return () -> {
|
||||
var args = preLaunch(arguments, layer);
|
||||
|
||||
Class.forName(layer.findModule("minecraft").orElseThrow(), "net.minecraft.client.main.Main").getMethod("main", String[].class).invoke(null, (Object) args);
|
||||
return null;
|
||||
};
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -5,6 +5,7 @@
|
||||
|
||||
package net.minecraftforge.fml.loading.targets;
|
||||
|
||||
import cpw.mods.modlauncher.api.ServiceRunner;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
@@ -15,12 +16,11 @@ public class ForgeDataDevLaunchHandler extends CommonDevLaunchHandler {
|
||||
@Override public boolean isData() { return true; }
|
||||
|
||||
@Override
|
||||
public Callable<Void> launchService(String[] arguments, ModuleLayer layer) {
|
||||
public ServiceRunner launchService(String[] arguments, ModuleLayer layer) {
|
||||
return () -> {
|
||||
var args = preLaunch(arguments, layer);
|
||||
|
||||
Class.forName(layer.findModule("minecraft").orElseThrow(), "net.minecraft.data.Main").getMethod("main", String[].class).invoke(null, (Object) args);
|
||||
return null;
|
||||
};
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -5,6 +5,7 @@
|
||||
|
||||
package net.minecraftforge.fml.loading.targets;
|
||||
|
||||
import cpw.mods.modlauncher.api.ServiceRunner;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
@@ -20,12 +21,11 @@ public class ForgeDataUserdevLaunchHandler extends ForgeUserdevLaunchHandler {
|
||||
public boolean isData() { return true; }
|
||||
|
||||
@Override
|
||||
public Callable<Void> launchService(String[] arguments, ModuleLayer layer) {
|
||||
public ServiceRunner launchService(String[] arguments, ModuleLayer layer) {
|
||||
return () -> {
|
||||
var args = preLaunch(arguments, layer);
|
||||
|
||||
Class.forName(layer.findModule("minecraft").orElseThrow(), "net.minecraft.data.Main").getMethod("main", String[].class).invoke(null, (Object) args);
|
||||
return null;
|
||||
};
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -5,6 +5,7 @@
|
||||
|
||||
package net.minecraftforge.fml.loading.targets;
|
||||
|
||||
import cpw.mods.modlauncher.api.ServiceRunner;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
@@ -14,12 +15,11 @@ public class ForgeGametestDevLaunchHandler extends CommonDevLaunchHandler {
|
||||
@Override public Dist getDist() { return Dist.DEDICATED_SERVER; }
|
||||
|
||||
@Override
|
||||
public Callable<Void> launchService(String[] arguments, ModuleLayer layer) {
|
||||
public ServiceRunner launchService(String[] arguments, ModuleLayer layer) {
|
||||
return () -> {
|
||||
var args = preLaunch(arguments, layer);
|
||||
|
||||
Class.forName(layer.findModule("forge").orElseThrow(), "net.minecraftforge.gametest.GameTestMain").getMethod("main", String[].class).invoke(null, (Object)args);
|
||||
return null;
|
||||
};
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -5,6 +5,7 @@
|
||||
|
||||
package net.minecraftforge.fml.loading.targets;
|
||||
|
||||
import cpw.mods.modlauncher.api.ServiceRunner;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
@@ -14,12 +15,11 @@ public class ForgeGametestUserdevLaunchHandler extends ForgeUserdevLaunchHandler
|
||||
@Override public Dist getDist() { return Dist.DEDICATED_SERVER; }
|
||||
|
||||
@Override
|
||||
public Callable<Void> launchService(String[] arguments, ModuleLayer layer) {
|
||||
public ServiceRunner launchService(String[] arguments, ModuleLayer layer) {
|
||||
return () -> {
|
||||
var args = preLaunch(arguments, layer);
|
||||
|
||||
Class.forName(layer.findModule("forge").orElseThrow(), "net.minecraftforge.gametest.GameTestMain").getMethod("main", String[].class).invoke(null, (Object)args);
|
||||
return null;
|
||||
};
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -5,6 +5,7 @@
|
||||
|
||||
package net.minecraftforge.fml.loading.targets;
|
||||
|
||||
import cpw.mods.modlauncher.api.ServiceRunner;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
@@ -13,12 +14,11 @@ public class ForgeServerDevLaunchHandler extends CommonDevLaunchHandler {
|
||||
@Override public Dist getDist() { return Dist.DEDICATED_SERVER; }
|
||||
|
||||
@Override
|
||||
public Callable<Void> launchService(String[] arguments, ModuleLayer layer) {
|
||||
public ServiceRunner launchService(String[] arguments, ModuleLayer layer) {
|
||||
return () -> {
|
||||
var args = preLaunch(arguments, layer);
|
||||
|
||||
Class.forName(layer.findModule("minecraft").orElseThrow(),"net.minecraft.server.Main").getMethod("main", String[].class).invoke(null, (Object)args);
|
||||
return null;
|
||||
};
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -5,6 +5,7 @@
|
||||
|
||||
package net.minecraftforge.fml.loading.targets;
|
||||
|
||||
import cpw.mods.modlauncher.api.ServiceRunner;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
@@ -14,12 +15,11 @@ public class ForgeServerUserdevLaunchHandler extends ForgeUserdevLaunchHandler {
|
||||
@Override public Dist getDist() { return Dist.DEDICATED_SERVER; }
|
||||
|
||||
@Override
|
||||
public Callable<Void> launchService(String[] arguments, ModuleLayer layer) {
|
||||
public ServiceRunner launchService(String[] arguments, ModuleLayer layer) {
|
||||
return () -> {
|
||||
var args = preLaunch(arguments, layer);
|
||||
|
||||
Class.forName(layer.findModule("minecraft").orElseThrow(),"net.minecraft.server.Main").getMethod("main", String[].class).invoke(null, (Object)args);
|
||||
return null;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -4,3 +4,5 @@ splashscreen = true
|
||||
maxThreads = -1
|
||||
# Enable forge global version checking
|
||||
versionCheck = true
|
||||
# Disables Optimized DFU client-side.
|
||||
disableOptimizedDFU = true
|
||||
+2
-1
@@ -1 +1,2 @@
|
||||
net.minecraftforge.fml.loading.ModDirTransformerDiscoverer
|
||||
net.minecraftforge.fml.loading.ModDirTransformerDiscoverer
|
||||
net.minecraftforge.fml.loading.ClasspathTransformerDiscoverer
|
||||
+1
@@ -0,0 +1 @@
|
||||
net.minecraftforge.fml.loading.moddiscovery.JarInJarDependencyLocator
|
||||
+2
-2
@@ -40,7 +40,7 @@ https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md
|
||||
|
||||
Additional Resources:
|
||||
=========================
|
||||
Community Documentation: http://mcforge.readthedocs.io/en/latest/gettingstarted/
|
||||
Community Documentation: https://mcforge.readthedocs.io/en/latest/gettingstarted/
|
||||
LexManos' Install Video: https://www.youtube.com/watch?v=8VEdtQLuLO0
|
||||
Forge Forum: https://forums.minecraftforge.net/
|
||||
Forge Discord: https://discord.gg/UvedJ9m
|
||||
Forge Discord: https://discord.gg/UvedJ9m
|
||||
+1
-11
@@ -1,7 +1,7 @@
|
||||
plugins {
|
||||
id 'eclipse'
|
||||
id 'maven-publish'
|
||||
id 'net.minecraftforge.gradle' version '5.+'
|
||||
id 'net.minecraftforge.gradle' version '5.1.+'
|
||||
}
|
||||
|
||||
version = '1.0'
|
||||
@@ -65,7 +65,6 @@ minecraft {
|
||||
|
||||
property 'forge.logging.console.level', 'debug'
|
||||
|
||||
// Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
|
||||
property 'forge.enabledGameTestNamespaces', 'examplemod'
|
||||
|
||||
mods {
|
||||
@@ -81,19 +80,10 @@ minecraft {
|
||||
gameTestServer {
|
||||
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'
|
||||
|
||||
// Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
|
||||
property 'forge.enabledGameTestNamespaces', 'examplemod'
|
||||
|
||||
mods {
|
||||
|
||||
@@ -1,61 +1,69 @@
|
||||
package com.example.examplemod;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.CreativeModeTab;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.material.Material;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.InterModComms;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent;
|
||||
import net.minecraftforge.event.server.ServerStartingEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import net.minecraftforge.registries.DeferredRegister;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.minecraftforge.registries.RegistryObject;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
// The value here should match an entry in the META-INF/mods.toml file
|
||||
@Mod("examplemod")
|
||||
@Mod(ExampleMod.MODID)
|
||||
public class ExampleMod
|
||||
{
|
||||
// Define mod id in a common place for everything to reference
|
||||
public static final String MODID = "examplemod";
|
||||
// Directly reference a slf4j logger
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
// Create a Deferred Register to hold Blocks which will all be registered under the "examplemod" namespace
|
||||
public static final DeferredRegister<Block> BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID);
|
||||
// Create a Deferred Register to hold Items which will all be registered under the "examplemod" namespace
|
||||
public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MODID);
|
||||
|
||||
// Creates a new Block with the id "examplemod:example_block", combining the namespace and path
|
||||
public static final RegistryObject<Block> EXAMPLE_BLOCK = BLOCKS.register("example_block", () -> new Block(BlockBehaviour.Properties.of(Material.STONE)));
|
||||
// Creates a new BlockItem with the id "examplemod:example_block", combining the namespace and path
|
||||
public static final RegistryObject<Item> EXAMPLE_BLOCK_ITEM = ITEMS.register("example_block", () -> new BlockItem(EXAMPLE_BLOCK.get(), new Item.Properties().tab(CreativeModeTab.TAB_BUILDING_BLOCKS)));
|
||||
|
||||
public ExampleMod()
|
||||
{
|
||||
// Register the setup method for modloading
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
|
||||
// Register the enqueueIMC method for modloading
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::enqueueIMC);
|
||||
// Register the processIMC method for modloading
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::processIMC);
|
||||
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||
|
||||
// Register the commonSetup method for modloading
|
||||
modEventBus.addListener(this::commonSetup);
|
||||
|
||||
// Register the Deferred Register to the mod event bus so blocks get registered
|
||||
BLOCKS.register(modEventBus);
|
||||
// Register the Deferred Register to the mod event bus so items get registered
|
||||
ITEMS.register(modEventBus);
|
||||
|
||||
// Register ourselves for server and other game events we are interested in
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
}
|
||||
|
||||
private void setup(final FMLCommonSetupEvent event)
|
||||
private void commonSetup(final FMLCommonSetupEvent event)
|
||||
{
|
||||
// some preinit code
|
||||
LOGGER.info("HELLO FROM PREINIT");
|
||||
LOGGER.info("DIRT BLOCK >> {}", Blocks.DIRT.getRegistryName());
|
||||
}
|
||||
|
||||
private void enqueueIMC(final InterModEnqueueEvent event)
|
||||
{
|
||||
// Some example code to dispatch IMC to another mod
|
||||
InterModComms.sendTo("examplemod", "helloworld", () -> { LOGGER.info("Hello world from the MDK"); return "Hello world";});
|
||||
}
|
||||
|
||||
private void processIMC(final InterModProcessEvent event)
|
||||
{
|
||||
// Some example code to receive and process InterModComms from other mods
|
||||
LOGGER.info("Got IMC {}", event.getIMCStream().
|
||||
map(m->m.messageSupplier().get()).
|
||||
collect(Collectors.toList()));
|
||||
// Some common setup code
|
||||
LOGGER.info("HELLO FROM COMMON SETUP");
|
||||
LOGGER.info("DIRT BLOCK >> {}", ForgeRegistries.BLOCKS.getKey(Blocks.DIRT));
|
||||
}
|
||||
|
||||
// You can use SubscribeEvent and let the Event Bus discover methods to call
|
||||
@@ -66,16 +74,16 @@ public class ExampleMod
|
||||
LOGGER.info("HELLO from server starting");
|
||||
}
|
||||
|
||||
// You can use EventBusSubscriber to automatically subscribe events on the contained class (this is subscribing to the MOD
|
||||
// Event bus for receiving Registry Events)
|
||||
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
|
||||
public static class RegistryEvents
|
||||
// You can use EventBusSubscriber to automatically register all static methods in the class annotated with @SubscribeEvent
|
||||
@Mod.EventBusSubscriber(modid = MODID, bus = Mod.EventBusSubscriber.Bus.MOD)
|
||||
public static class ClientModEvents
|
||||
{
|
||||
@SubscribeEvent
|
||||
public static void onBlocksRegistry(final RegistryEvent.Register<Block> blockRegistryEvent)
|
||||
public static void onClientSetup(FMLClientSetupEvent event)
|
||||
{
|
||||
// Register a new block here
|
||||
LOGGER.info("HELLO from Register Block");
|
||||
// Some client setup code
|
||||
LOGGER.info("HELLO FROM CLIENT SETUP");
|
||||
LOGGER.info("MINECRAFT NAME >> {}", Minecraft.getInstance().getUser().getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,14 @@ logoFile="examplemod.png" #optional
|
||||
credits="Thanks for this example mod goes to Java" #optional
|
||||
# A text field displayed in the mod UI
|
||||
authors="Love, Cheese and small house plants" #optional
|
||||
# Display Test controls the display for your mod in the server connection screen
|
||||
# MATCH_VERSION means that your mod will cause a red X if the versions on client and server differ. This is the default behaviour and should be what you choose if you have server and client elements to your mod.
|
||||
# IGNORE_SERVER_VERSION means that your mod will not cause a red X if it's present on the server but not on the client. This is what you should use if you're a server only mod.
|
||||
# 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)
|
||||
|
||||
# The description text for the mod (multi line!) (#mandatory)
|
||||
description='''
|
||||
This is a long form description of the mod. You can write whatever you want here
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/com/mojang/blaze3d/vertex/BufferBuilder.java
|
||||
+++ b/com/mojang/blaze3d/vertex/BufferBuilder.java
|
||||
@@ -486,4 +_,15 @@
|
||||
@@ -486,4 +_,14 @@
|
||||
this.f_166822_ = p_166829_;
|
||||
}
|
||||
}
|
||||
@@ -8,11 +8,10 @@
|
||||
+ // Forge start
|
||||
+ public void putBulkData(ByteBuffer buffer) {
|
||||
+ m_85722_(buffer.limit() + this.f_85658_.m_86020_());
|
||||
+ this.f_85648_.position(this.f_85654_ * this.f_85658_.m_86020_());
|
||||
+ this.f_85648_.position(this.f_85652_);
|
||||
+ this.f_85648_.put(buffer);
|
||||
+ this.f_85648_.position(0);
|
||||
+ this.f_85654_ += buffer.limit() / this.f_85658_.m_86020_();
|
||||
+ this.f_85652_ += buffer.limit();
|
||||
+ }
|
||||
+
|
||||
+ public VertexFormat getVertexFormat() { return this.f_85658_; }
|
||||
}
|
||||
@@ -9,7 +9,18 @@
|
||||
VertexConsumer m_5483_(double p_85945_, double p_85946_, double p_85947_);
|
||||
|
||||
VertexConsumer m_6122_(int p_85973_, int p_85974_, int p_85975_, int p_85976_);
|
||||
@@ -101,11 +_,12 @@
|
||||
@@ -64,6 +_,10 @@
|
||||
}
|
||||
|
||||
default void m_85995_(PoseStack.Pose p_85996_, BakedQuad p_85997_, float[] p_85998_, float p_85999_, float p_86000_, float p_86001_, int[] p_86002_, int p_86003_, boolean p_86004_) {
|
||||
+ putBulkData(p_85996_, p_85997_, p_85998_, p_85999_, p_86000_, p_86001_, 1, p_86002_, p_86003_, p_86004_);
|
||||
+ }
|
||||
+
|
||||
+ default void putBulkData(PoseStack.Pose p_85996_, BakedQuad p_85997_, float[] p_85998_, float p_85999_, float p_86000_, float p_86001_, float alpha, int[] p_86002_, int p_86003_, boolean p_86004_) {
|
||||
float[] afloat = new float[]{p_85998_[0], p_85998_[1], p_85998_[2], p_85998_[3]};
|
||||
int[] aint = new int[]{p_86002_[0], p_86002_[1], p_86002_[2], p_86002_[3]};
|
||||
int[] aint1 = p_85997_.m_111303_();
|
||||
@@ -101,12 +_,14 @@
|
||||
f5 = afloat[k] * p_86001_;
|
||||
}
|
||||
|
||||
@@ -19,7 +30,10 @@
|
||||
float f10 = bytebuffer.getFloat(20);
|
||||
Vector4f vector4f = new Vector4f(f, f1, f2, 1.0F);
|
||||
vector4f.m_123607_(matrix4f);
|
||||
- this.m_5954_(vector4f.m_123601_(), vector4f.m_123615_(), vector4f.m_123616_(), f3, f4, f5, 1.0F, f9, f10, p_86003_, l, vector3f.m_122239_(), vector3f.m_122260_(), vector3f.m_122269_());
|
||||
+ applyBakedNormals(vector3f, bytebuffer, p_85996_.m_85864_());
|
||||
this.m_5954_(vector4f.m_123601_(), vector4f.m_123615_(), vector4f.m_123616_(), f3, f4, f5, 1.0F, f9, f10, p_86003_, l, vector3f.m_122239_(), vector3f.m_122260_(), vector3f.m_122269_());
|
||||
+ float vertexAlpha = p_86004_ ? alpha * (float) (bytebuffer.get(15) & 255) / 255.0F : alpha;
|
||||
+ this.m_5954_(vector4f.m_123601_(), vector4f.m_123615_(), vector4f.m_123616_(), f3, f4, f5, vertexAlpha, f9, f10, p_86003_, l, vector3f.m_122239_(), vector3f.m_122260_(), vector3f.m_122269_());
|
||||
}
|
||||
} catch (Throwable throwable1) {
|
||||
if (memorystack != null) {
|
||||
@@ -9,6 +9,15 @@
|
||||
public static final ItemPredicate f_45028_ = new ItemPredicate();
|
||||
@Nullable
|
||||
private final TagKey<Item> f_45029_;
|
||||
@@ -80,7 +_,7 @@
|
||||
return false;
|
||||
} else {
|
||||
if (this.f_45033_.length > 0) {
|
||||
- Map<Enchantment, Integer> map = EnchantmentHelper.m_44882_(p_45050_.m_41785_());
|
||||
+ Map<Enchantment, Integer> map = p_45050_.getAllEnchantments();
|
||||
|
||||
for(EnchantmentPredicate enchantmentpredicate : this.f_45033_) {
|
||||
if (!enchantmentpredicate.m_30476_(map)) {
|
||||
@@ -107,6 +_,11 @@
|
||||
public static ItemPredicate m_45051_(@Nullable JsonElement p_45052_) {
|
||||
if (p_45052_ != null && !p_45052_.isJsonNull()) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
} else if (recipetype == RecipeType.f_44113_) {
|
||||
return RecipeBookCategories.SMITHING;
|
||||
} else {
|
||||
+ RecipeBookCategories categories = net.minecraftforge.client.RecipeBookRegistry.findCategories(recipetype, p_90647_);
|
||||
+ RecipeBookCategories categories = net.minecraftforge.client.RecipeBookManager.findCategories((RecipeType) recipetype, p_90647_);
|
||||
+ if (categories != null) return categories;
|
||||
f_90618_.warn("Unknown recipe category: {}/{}", LogUtils.defer(() -> {
|
||||
return Registry.f_122864_.m_7981_(p_90647_.m_6671_());
|
||||
|
||||
@@ -8,48 +8,20 @@
|
||||
+public class KeyMapping implements Comparable<KeyMapping>, net.minecraftforge.client.extensions.IForgeKeyMapping {
|
||||
private static final Map<String, KeyMapping> f_90809_ = Maps.newHashMap();
|
||||
- private static final Map<InputConstants.Key, KeyMapping> f_90810_ = Maps.newHashMap();
|
||||
+ private static final net.minecraftforge.client.settings.KeyBindingMap f_90810_ = new net.minecraftforge.client.settings.KeyBindingMap();
|
||||
+ private static final net.minecraftforge.client.settings.KeyMappingLookup f_90810_ = new net.minecraftforge.client.settings.KeyMappingLookup();
|
||||
private static final Set<String> f_90811_ = Sets.newHashSet();
|
||||
public static final String f_167805_ = "key.categories.movement";
|
||||
public static final String f_167806_ = "key.categories.misc";
|
||||
@@ -41,7 +_,7 @@
|
||||
private int f_90818_;
|
||||
|
||||
public static void m_90835_(InputConstants.Key p_90836_) {
|
||||
- KeyMapping keymapping = f_90810_.get(p_90836_);
|
||||
+ KeyMapping keymapping = f_90810_.lookupActive(p_90836_);
|
||||
if (keymapping != null) {
|
||||
++keymapping.f_90818_;
|
||||
}
|
||||
@@ -49,7 +_,7 @@
|
||||
}
|
||||
|
||||
public static void m_90837_(InputConstants.Key p_90838_, boolean p_90839_) {
|
||||
- KeyMapping keymapping = f_90810_.get(p_90838_);
|
||||
+ for (KeyMapping keymapping : f_90810_.lookupAll(p_90838_))
|
||||
+ for (KeyMapping keymapping : f_90810_.getAll(p_90838_))
|
||||
if (keymapping != null) {
|
||||
keymapping.m_7249_(p_90839_);
|
||||
}
|
||||
@@ -73,10 +_,10 @@
|
||||
}
|
||||
|
||||
public static void m_90854_() {
|
||||
- f_90810_.clear();
|
||||
+ f_90810_.clearMap();
|
||||
|
||||
for(KeyMapping keymapping : f_90809_.values()) {
|
||||
- f_90810_.put(keymapping.f_90816_, keymapping);
|
||||
+ f_90810_.addKey(keymapping.f_90816_, keymapping);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -91,12 +_,12 @@
|
||||
this.f_90814_ = this.f_90816_;
|
||||
this.f_90815_ = p_90828_;
|
||||
f_90809_.put(p_90825_, this);
|
||||
- f_90810_.put(this.f_90816_, this);
|
||||
+ f_90810_.addKey(this.f_90816_, this);
|
||||
f_90811_.add(p_90828_);
|
||||
@@ -96,7 +_,7 @@
|
||||
}
|
||||
|
||||
public boolean m_90857_() {
|
||||
@@ -154,7 +126,7 @@
|
||||
+ if (this.keyModifier.matches(keyCode))
|
||||
+ this.keyModifier = net.minecraftforge.client.settings.KeyModifier.NONE;
|
||||
+ f_90809_.put(description, this);
|
||||
+ f_90810_.addKey(keyCode, this);
|
||||
+ f_90810_.put(keyCode, this);
|
||||
+ f_90811_.add(category);
|
||||
+ }
|
||||
+
|
||||
@@ -188,9 +160,9 @@
|
||||
+ this.f_90816_ = keyCode;
|
||||
+ if (keyModifier.matches(keyCode))
|
||||
+ keyModifier = net.minecraftforge.client.settings.KeyModifier.NONE;
|
||||
+ f_90810_.removeKey(this);
|
||||
+ f_90810_.remove(this);
|
||||
+ this.keyModifier = keyModifier;
|
||||
+ f_90810_.addKey(keyCode, this);
|
||||
+ f_90810_.put(keyCode, this);
|
||||
+ }
|
||||
+ /****************** Forge End *****************************/
|
||||
}
|
||||
@@ -43,7 +43,7 @@
|
||||
}
|
||||
}
|
||||
-
|
||||
+ net.minecraftforge.client.ForgeHooksClient.fireKeyInput(p_90895_, p_90896_, p_90897_, p_90898_);
|
||||
+ net.minecraftforge.client.ForgeHooksClient.onKeyInput(p_90895_, p_90896_, p_90897_, p_90898_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,14 +26,6 @@
|
||||
this.f_91033_ = p_91084_.f_101908_.f_101926_;
|
||||
this.f_91034_ = !p_91084_.f_101908_.f_101929_;
|
||||
this.f_91035_ = !p_91084_.f_101908_.f_101930_;
|
||||
@@ -426,6 +_,7 @@
|
||||
}
|
||||
|
||||
Util.f_137440_ = RenderSystem.m_69576_();
|
||||
+ if (net.minecraftforge.common.ForgeConfig.CLIENT.forceSystemNanoTime.get()) Util.f_137440_ = System::nanoTime;
|
||||
this.f_90989_ = new VirtualScreen(this);
|
||||
this.f_90990_ = this.f_90989_.m_110872_(displaydata, this.f_91066_.f_92123_, this.m_91270_());
|
||||
this.m_7440_(true);
|
||||
@@ -445,7 +_,6 @@
|
||||
|
||||
this.f_90990_.m_85380_(this.f_91066_.m_232035_().m_231551_());
|
||||
@@ -50,11 +42,16 @@
|
||||
this.f_91038_.m_10506_();
|
||||
this.f_91066_.m_92145_(this.f_91038_);
|
||||
this.f_91039_ = new LanguageManager(this.f_91066_.f_92075_);
|
||||
@@ -500,6 +_,7 @@
|
||||
@@ -496,10 +_,12 @@
|
||||
this.f_91063_ = new GameRenderer(this, this.f_90994_.m_234586_(), this.f_91036_, this.f_90993_);
|
||||
this.f_91036_.m_7217_(this.f_91063_);
|
||||
this.f_91060_ = new LevelRenderer(this, this.f_90994_, this.f_167845_, this.f_90993_);
|
||||
+ net.minecraftforge.fml.ModLoader.get().postEvent(new net.minecraftforge.client.event.RenderLevelStageEvent.RegisterStageEvent());
|
||||
this.f_91036_.m_7217_(this.f_91060_);
|
||||
this.m_91271_();
|
||||
this.f_91036_.m_7217_(this.f_90997_);
|
||||
this.f_91061_ = new ParticleEngine(this.f_91073_, this.f_90987_);
|
||||
+ net.minecraftforge.fml.ModLoader.get().postEvent(new net.minecraftforge.client.event.ParticleFactoryRegisterEvent());
|
||||
+ net.minecraftforge.client.ForgeHooksClient.onRegisterParticleProviders(f_91061_);
|
||||
this.f_91036_.m_7217_(this.f_91061_);
|
||||
this.f_91053_ = new PaintingTextureManager(this.f_90987_);
|
||||
this.f_91036_.m_7217_(this.f_91053_);
|
||||
@@ -63,12 +60,12 @@
|
||||
this.f_91036_.m_7217_(this.f_91047_);
|
||||
this.f_91036_.m_7217_(this.f_205120_);
|
||||
- this.f_91065_ = new Gui(this, this.f_90995_);
|
||||
+ this.f_91065_ = new net.minecraftforge.client.gui.ForgeIngameGui(this);
|
||||
+ this.f_91065_ = new net.minecraftforge.client.gui.overlay.ForgeGui(this);
|
||||
+ this.f_91067_.m_91524_(this.f_90990_.m_85439_()); //Forge: Moved below ingameGUI setting to prevent NPEs in handeler.
|
||||
this.f_91064_ = new DebugRenderer(this);
|
||||
RenderSystem.m_69900_(this::m_91113_);
|
||||
if (this.f_91042_.f_83915_ == this.f_90990_.m_85441_() && this.f_91042_.f_83916_ == this.f_90990_.m_85442_()) {
|
||||
@@ -526,6 +_,11 @@
|
||||
@@ -526,6 +_,19 @@
|
||||
TinyFileDialogs.tinyfd_messageBox("Minecraft", stringbuilder.toString(), "ok", "error", false);
|
||||
}
|
||||
|
||||
@@ -76,6 +73,14 @@
|
||||
+ net.minecraftforge.fml.ModLoader.get().postEvent(new net.minecraftforge.client.event.RegisterClientReloadListenersEvent(this.f_91036_));
|
||||
+ net.minecraftforge.fml.ModLoader.get().postEvent(new net.minecraftforge.client.event.EntityRenderersEvent.RegisterLayerDefinitions());
|
||||
+ net.minecraftforge.fml.ModLoader.get().postEvent(new net.minecraftforge.client.event.EntityRenderersEvent.RegisterRenderers());
|
||||
+ net.minecraftforge.client.textures.TextureAtlasSpriteLoaderManager.init();
|
||||
+ net.minecraftforge.client.gui.ClientTooltipComponentManager.init();
|
||||
+ net.minecraftforge.client.EntitySpectatorShaderManager.init();
|
||||
+ net.minecraftforge.client.ForgeHooksClient.onRegisterKeyMappings(f_91066_);
|
||||
+ net.minecraftforge.client.RecipeBookManager.init();
|
||||
+ net.minecraftforge.client.gui.overlay.GuiOverlayManager.init();
|
||||
+ net.minecraftforge.client.DimensionSpecialEffectsManager.init();
|
||||
+ net.minecraftforge.client.NamedRenderTypeManager.init();
|
||||
+
|
||||
this.f_90990_.m_85409_(this.f_91066_.m_231817_().m_231551_());
|
||||
this.f_90990_.m_85424_(this.f_91066_.m_232123_().m_231551_());
|
||||
@@ -148,33 +153,38 @@
|
||||
if (p_91153_ == null && this.f_91073_ == null) {
|
||||
p_91153_ = new TitleScreen();
|
||||
} else if (p_91153_ == null && this.f_91074_.m_21224_()) {
|
||||
@@ -906,6 +_,15 @@
|
||||
@@ -906,6 +_,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ net.minecraftforge.client.ForgeHooksClient.clearGuiLayers(this);
|
||||
+ Screen old = this.f_91080_;
|
||||
+ net.minecraftforge.client.event.ScreenOpenEvent event = new net.minecraftforge.client.event.ScreenOpenEvent(p_91153_);
|
||||
+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) return;
|
||||
+ if (p_91153_ != null) {
|
||||
+ var event = new net.minecraftforge.client.event.ScreenEvent.Opening(old, p_91153_);
|
||||
+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) return;
|
||||
+ p_91153_ = event.getNewScreen();
|
||||
+ }
|
||||
+
|
||||
+ p_91153_ = event.getScreen();
|
||||
+ if (old != null && p_91153_ != old)
|
||||
+ if (old != null && p_91153_ != old) {
|
||||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.ScreenEvent.Closing(old));
|
||||
+ old.m_7861_();
|
||||
+ }
|
||||
+
|
||||
this.f_91080_ = p_91153_;
|
||||
BufferUploader.m_166835_();
|
||||
if (p_91153_ != null) {
|
||||
@@ -1049,11 +_,13 @@
|
||||
@@ -1049,11 +_,14 @@
|
||||
RenderSystem.m_69481_();
|
||||
this.f_91026_.m_7238_();
|
||||
if (!this.f_91079_) {
|
||||
+ net.minecraftforge.event.ForgeEventFactory.onRenderTickStart(this.f_91012_ ? this.f_91013_ : this.f_90991_.f_92518_);
|
||||
+ this.realPartialTick = this.f_91012_ ? this.f_91013_ : this.f_90991_.f_92518_; // Cache this since pause is volatile
|
||||
+ net.minecraftforge.event.ForgeEventFactory.onRenderTickStart(this.realPartialTick);
|
||||
this.f_91026_.m_6182_("gameRenderer");
|
||||
this.f_91063_.m_109093_(this.f_91012_ ? this.f_91013_ : this.f_90991_.f_92518_, i, p_91384_);
|
||||
this.f_91026_.m_6182_("toasts");
|
||||
this.f_91003_.m_94920_(new PoseStack());
|
||||
this.f_91026_.m_7238_();
|
||||
+ net.minecraftforge.event.ForgeEventFactory.onRenderTickEnd(this.f_91012_ ? this.f_91013_ : this.f_90991_.f_92518_);
|
||||
+ net.minecraftforge.event.ForgeEventFactory.onRenderTickEnd(this.realPartialTick);
|
||||
}
|
||||
|
||||
if (this.f_91056_ != null) {
|
||||
@@ -205,7 +215,7 @@
|
||||
BlockPos blockpos = blockhitresult.m_82425_();
|
||||
- if (!this.f_91073_.m_8055_(blockpos).m_60795_()) {
|
||||
+ if (!this.f_91073_.m_46859_(blockpos)) {
|
||||
+ net.minecraftforge.client.event.InputEvent.ClickInputEvent inputEvent = net.minecraftforge.client.ForgeHooksClient.onClickInput(0, this.f_91066_.f_92096_, InteractionHand.MAIN_HAND);
|
||||
+ var inputEvent = net.minecraftforge.client.ForgeHooksClient.onClickInput(0, this.f_91066_.f_92096_, InteractionHand.MAIN_HAND);
|
||||
+ if (inputEvent.isCanceled()) {
|
||||
+ if (inputEvent.shouldSwingHand()) {
|
||||
+ this.f_91061_.addBlockHitEffects(blockpos, blockhitresult);
|
||||
@@ -226,7 +236,7 @@
|
||||
} else {
|
||||
boolean flag = false;
|
||||
- switch (this.f_91077_.m_6662_()) {
|
||||
+ net.minecraftforge.client.event.InputEvent.ClickInputEvent inputEvent = net.minecraftforge.client.ForgeHooksClient.onClickInput(0, this.f_91066_.f_92096_, InteractionHand.MAIN_HAND);
|
||||
+ var inputEvent = net.minecraftforge.client.ForgeHooksClient.onClickInput(0, this.f_91066_.f_92096_, InteractionHand.MAIN_HAND);
|
||||
+ HitResult.Type hitType = this.f_91077_.m_6662_();
|
||||
+ if(this.f_91077_ instanceof EntityHitResult entityHit) { // Forge: Perform attack range checks here, instead of in GameRenderer#pick, so extended-reach interactions work.
|
||||
+ if(!f_91074_.canHit(entityHit.m_82443_(), 0)) hitType = HitResult.Type.MISS; // No padding in client code.
|
||||
@@ -259,7 +269,7 @@
|
||||
}
|
||||
|
||||
for(InteractionHand interactionhand : InteractionHand.values()) {
|
||||
+ net.minecraftforge.client.event.InputEvent.ClickInputEvent inputEvent = net.minecraftforge.client.ForgeHooksClient.onClickInput(1, this.f_91066_.f_92095_, interactionhand);
|
||||
+ var inputEvent = net.minecraftforge.client.ForgeHooksClient.onClickInput(1, this.f_91066_.f_92095_, interactionhand);
|
||||
+ if (inputEvent.isCanceled()) {
|
||||
+ if (inputEvent.shouldSwingHand()) this.f_91074_.m_6674_(interactionhand);
|
||||
+ return;
|
||||
@@ -334,7 +344,7 @@
|
||||
}
|
||||
|
||||
public void m_91156_(ClientLevel p_91157_) {
|
||||
+ if (f_91073_ != null) net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Unload(f_91073_));
|
||||
+ if (f_91073_ != null) net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.level.LevelEvent.Unload(f_91073_));
|
||||
ProgressScreen progressscreen = new ProgressScreen(true);
|
||||
progressscreen.m_6309_(Component.m_237115_("connect.joining"));
|
||||
this.m_91362_(progressscreen);
|
||||
@@ -347,7 +357,7 @@
|
||||
NarratorChatListener.f_93311_.m_93328_();
|
||||
this.m_91362_(p_91321_);
|
||||
if (this.f_91073_ != null) {
|
||||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Unload(f_91073_));
|
||||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.level.LevelEvent.Unload(f_91073_));
|
||||
if (integratedserver != null) {
|
||||
this.f_91026_.m_6180_("waitForServer");
|
||||
|
||||
@@ -359,76 +369,35 @@
|
||||
this.f_91004_.m_90740_();
|
||||
}
|
||||
|
||||
@@ -2082,66 +_,9 @@
|
||||
@@ -2082,6 +_,7 @@
|
||||
|
||||
private void m_91280_() {
|
||||
if (this.f_91077_ != null && this.f_91077_.m_6662_() != HitResult.Type.MISS) {
|
||||
- boolean flag = this.f_91074_.m_150110_().f_35937_;
|
||||
- BlockEntity blockentity = null;
|
||||
- HitResult.Type hitresult$type = this.f_91077_.m_6662_();
|
||||
- ItemStack itemstack;
|
||||
- if (hitresult$type == HitResult.Type.BLOCK) {
|
||||
- BlockPos blockpos = ((BlockHitResult)this.f_91077_).m_82425_();
|
||||
- BlockState blockstate = this.f_91073_.m_8055_(blockpos);
|
||||
- if (blockstate.m_60795_()) {
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- Block block = blockstate.m_60734_();
|
||||
+ if (net.minecraftforge.client.ForgeHooksClient.onClickInput(2, this.f_91066_.f_92097_, InteractionHand.MAIN_HAND).isCanceled()) return;
|
||||
boolean flag = this.f_91074_.m_150110_().f_35937_;
|
||||
BlockEntity blockentity = null;
|
||||
HitResult.Type hitresult$type = this.f_91077_.m_6662_();
|
||||
@@ -2094,10 +_,7 @@
|
||||
}
|
||||
|
||||
Block block = blockstate.m_60734_();
|
||||
- itemstack = block.m_7397_(this.f_91073_, blockpos, blockstate);
|
||||
- if (itemstack.m_41619_()) {
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- if (flag && Screen.m_96637_() && blockstate.m_155947_()) {
|
||||
- blockentity = this.f_91073_.m_7702_(blockpos);
|
||||
- }
|
||||
- } else {
|
||||
- if (hitresult$type != HitResult.Type.ENTITY || !flag) {
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- Entity entity = ((EntityHitResult)this.f_91077_).m_82443_();
|
||||
- itemstack = entity.m_142340_();
|
||||
- if (itemstack == null) {
|
||||
- return;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (itemstack.m_41619_()) {
|
||||
- String s = "";
|
||||
- if (hitresult$type == HitResult.Type.BLOCK) {
|
||||
- s = Registry.f_122824_.m_7981_(this.f_91073_.m_8055_(((BlockHitResult)this.f_91077_).m_82425_()).m_60734_()).toString();
|
||||
- } else if (hitresult$type == HitResult.Type.ENTITY) {
|
||||
- s = Registry.f_122826_.m_7981_(((EntityHitResult)this.f_91077_).m_82443_().m_6095_()).toString();
|
||||
- }
|
||||
-
|
||||
- f_90982_.warn("Picking on: [{}] {} gave null item", hitresult$type, s);
|
||||
- } else {
|
||||
- Inventory inventory = this.f_91074_.m_150109_();
|
||||
- if (blockentity != null) {
|
||||
- this.m_91122_(itemstack, blockentity);
|
||||
- }
|
||||
-
|
||||
- int i = inventory.m_36030_(itemstack);
|
||||
- if (flag) {
|
||||
- inventory.m_36012_(itemstack);
|
||||
- this.f_91072_.m_105241_(this.f_91074_.m_21120_(InteractionHand.MAIN_HAND), 36 + inventory.f_35977_);
|
||||
- } else if (i != -1) {
|
||||
- if (Inventory.m_36045_(i)) {
|
||||
- inventory.f_35977_ = i;
|
||||
- } else {
|
||||
- this.f_91072_.m_105206_(i);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- }
|
||||
+ if (!net.minecraftforge.client.ForgeHooksClient.onClickInput(2, this.f_91066_.f_92097_, InteractionHand.MAIN_HAND).isCanceled())
|
||||
+ net.minecraftforge.common.ForgeHooks.onPickBlock(this.f_91077_, this.f_91074_, this.f_91073_);
|
||||
+ // We delete this code wholly instead of commenting it out, to make sure we detect changes in it between MC versions
|
||||
}
|
||||
}
|
||||
+ itemstack = blockstate.getCloneItemStack(this.f_91077_, this.f_91073_, blockpos, this.f_91074_);
|
||||
|
||||
if (flag && Screen.m_96637_() && blockstate.m_155947_()) {
|
||||
blockentity = this.f_91073_.m_7702_(blockpos);
|
||||
@@ -2108,7 +_,7 @@
|
||||
}
|
||||
|
||||
Entity entity = ((EntityHitResult)this.f_91077_).m_82443_();
|
||||
- itemstack = entity.m_142340_();
|
||||
+ itemstack = entity.getPickedResult(this.f_91077_);
|
||||
if (itemstack == null) {
|
||||
return;
|
||||
}
|
||||
@@ -2632,8 +_,8 @@
|
||||
return this.f_90993_;
|
||||
}
|
||||
@@ -449,18 +418,30 @@
|
||||
}
|
||||
|
||||
private static Supplier<PackResources> m_91330_(Supplier<PackResources> p_91331_) {
|
||||
@@ -2660,6 +_,14 @@
|
||||
|
||||
public void m_91312_(int p_91313_) {
|
||||
@@ -2662,6 +_,14 @@
|
||||
this.f_91051_.m_119410_(p_91313_);
|
||||
+ }
|
||||
+
|
||||
}
|
||||
|
||||
+ public ItemColors getItemColors() {
|
||||
+ return this.f_91041_;
|
||||
+ }
|
||||
+
|
||||
+ public SearchRegistry getSearchTreeManager() {
|
||||
+ return this.f_90997_;
|
||||
}
|
||||
|
||||
+ }
|
||||
+
|
||||
public EntityModelSet m_167973_() {
|
||||
return this.f_167844_;
|
||||
}
|
||||
@@ -2719,4 +_,11 @@
|
||||
|
||||
public abstract boolean m_142594_(boolean p_168035_);
|
||||
}
|
||||
+
|
||||
+ // FORGE START
|
||||
+ private float realPartialTick;
|
||||
+ public float getPartialTick() {
|
||||
+ return realPartialTick;
|
||||
+ }
|
||||
+ // FORGE END
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
this.f_91510_ = -1;
|
||||
}
|
||||
|
||||
+ if (net.minecraftforge.client.ForgeHooksClient.onRawMouseClicked(p_91532_, p_91533_, p_91534_)) return;
|
||||
+ if (net.minecraftforge.client.ForgeHooksClient.onMouseButtonPre(p_91532_, p_91533_, p_91534_)) return;
|
||||
boolean[] aboolean = new boolean[]{false};
|
||||
if (this.f_91503_.m_91265_() == null) {
|
||||
if (this.f_91503_.f_91080_ == null) {
|
||||
@@ -35,7 +35,7 @@
|
||||
}
|
||||
}
|
||||
-
|
||||
+ net.minecraftforge.client.ForgeHooksClient.fireMouseInput(p_91532_, p_91533_, p_91534_);
|
||||
+ net.minecraftforge.client.ForgeHooksClient.onMouseButtonPost(p_91532_, p_91533_, p_91534_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
--- a/net/minecraft/client/Options.java
|
||||
+++ b/net/minecraft/client/Options.java
|
||||
@@ -515,7 +_,8 @@
|
||||
}, new OptionInstance.LazyEnum<>(() -> {
|
||||
return Stream.concat(Stream.of(""), Minecraft.m_91087_().m_91106_().m_194525_().stream()).toList();
|
||||
}, (p_232011_) -> {
|
||||
- return Minecraft.m_91087_().m_91396_() && p_232011_ != "" && !Minecraft.m_91087_().m_91106_().m_194525_().contains(p_232011_) ? Optional.empty() : Optional.of(p_232011_);
|
||||
+ // FORGE: fix incorrect string comparison - PR #8767
|
||||
+ return Minecraft.m_91087_().m_91396_() && (p_232011_ == null || !p_232011_.isEmpty()) && !Minecraft.m_91087_().m_91106_().m_194525_().contains(p_232011_) ? Optional.empty() : Optional.of(p_232011_);
|
||||
}, Codec.STRING), "", (p_231994_) -> {
|
||||
SoundManager soundmanager = Minecraft.m_91087_().m_91106_();
|
||||
soundmanager.m_194526_();
|
||||
@@ -772,6 +_,7 @@
|
||||
}
|
||||
|
||||
@@ -8,9 +18,15 @@
|
||||
this.f_92060_ = p_92138_;
|
||||
this.f_92110_ = new File(p_92139_, "options.txt");
|
||||
boolean flag = p_92138_.m_91103_();
|
||||
@@ -887,10 +_,14 @@
|
||||
@@ -886,11 +_,20 @@
|
||||
p_168428_.m_213982_("chatPreview", this.f_231796_);
|
||||
p_168428_.m_213982_("onlyShowSecureChat", this.f_231798_);
|
||||
|
||||
+ processOptionsForge(p_168428_);
|
||||
+ }
|
||||
+ // FORGE: split off to allow reloading options after mod loading is done
|
||||
+ private void processOptionsForge(Options.FieldAccess p_168428_)
|
||||
+ {
|
||||
for(KeyMapping keymapping : this.f_92059_) {
|
||||
- String s = keymapping.m_90865_();
|
||||
+ String s = keymapping.m_90865_() + (keymapping.getKeyModifier() != net.minecraftforge.client.settings.KeyModifier.NONE ? ":" + keymapping.getKeyModifier() : "");
|
||||
@@ -25,6 +41,26 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -911,6 +_,9 @@
|
||||
}
|
||||
|
||||
public void m_92140_() {
|
||||
+ this.load(false);
|
||||
+ }
|
||||
+ public void load(boolean limited) {
|
||||
try {
|
||||
if (!this.f_92110_.exists()) {
|
||||
return;
|
||||
@@ -955,7 +_,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
- this.m_168427_(new Options.FieldAccess() {
|
||||
+ java.util.function.Consumer<FieldAccess> processor = limited ? this::processOptionsForge : this::m_168427_;
|
||||
+ processor.accept(new Options.FieldAccess() {
|
||||
@Nullable
|
||||
private String m_168458_(String p_168459_) {
|
||||
return compoundtag1.m_128441_(p_168459_) ? compoundtag1.m_128461_(p_168459_) : null;
|
||||
@@ -1058,6 +_,7 @@
|
||||
}
|
||||
|
||||
|
||||
@@ -14,17 +14,16 @@
|
||||
public static final List<RecipeBookCategories> f_92258_ = ImmutableList.of(FURNACE_SEARCH, FURNACE_FOOD, FURNACE_BLOCKS, FURNACE_MISC);
|
||||
public static final List<RecipeBookCategories> f_92259_ = ImmutableList.of(CRAFTING_SEARCH, CRAFTING_EQUIPMENT, CRAFTING_BUILDING_BLOCKS, CRAFTING_MISC, CRAFTING_REDSTONE);
|
||||
- public static final Map<RecipeBookCategories, List<RecipeBookCategories>> f_92260_ = ImmutableMap.of(CRAFTING_SEARCH, ImmutableList.of(CRAFTING_EQUIPMENT, CRAFTING_BUILDING_BLOCKS, CRAFTING_MISC, CRAFTING_REDSTONE), FURNACE_SEARCH, ImmutableList.of(FURNACE_FOOD, FURNACE_BLOCKS, FURNACE_MISC), BLAST_FURNACE_SEARCH, ImmutableList.of(BLAST_FURNACE_BLOCKS, BLAST_FURNACE_MISC), SMOKER_SEARCH, ImmutableList.of(SMOKER_FOOD));
|
||||
+ public static final Map<RecipeBookCategories, List<RecipeBookCategories>> f_92260_ = net.minecraftforge.client.RecipeBookRegistry.AGGREGATE_CATEGORIES_VIEW;
|
||||
+ public static final Map<RecipeBookCategories, List<RecipeBookCategories>> f_92260_ = net.minecraftforge.client.RecipeBookManager.getAggregateCategories();
|
||||
private final List<ItemStack> f_92261_;
|
||||
|
||||
private RecipeBookCategories(ItemStack... p_92267_) {
|
||||
@@ -54,11 +_,17 @@
|
||||
@@ -54,11 +_,15 @@
|
||||
case SMOKER:
|
||||
return f_92256_;
|
||||
default:
|
||||
+ if (net.minecraftforge.client.RecipeBookRegistry.TYPE_TO_CATEGORIES_VIEW.containsKey(p_92270_))
|
||||
+ return net.minecraftforge.client.RecipeBookRegistry.TYPE_TO_CATEGORIES_VIEW.get(p_92270_);
|
||||
return ImmutableList.of();
|
||||
- return ImmutableList.of();
|
||||
+ return net.minecraftforge.client.RecipeBookManager.getCustomCategoriesOrEmpty(p_92270_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
if (blockcolor != null) {
|
||||
return blockcolor.m_92566_(p_92583_, (BlockAndTintGetter)null, (BlockPos)null, 0);
|
||||
} else {
|
||||
@@ -87,13 +_,13 @@
|
||||
@@ -87,13 +_,15 @@
|
||||
}
|
||||
|
||||
public int m_92577_(BlockState p_92578_, @Nullable BlockAndTintGetter p_92579_, @Nullable BlockPos p_92580_, int p_92581_) {
|
||||
@@ -33,6 +33,8 @@
|
||||
return blockcolor == null ? -1 : blockcolor.m_92566_(p_92578_, p_92579_, p_92580_, p_92581_);
|
||||
}
|
||||
|
||||
+ /** @deprecated Register via {@link net.minecraftforge.client.event.RegisterColorHandlersEvent.Block} */
|
||||
+ @Deprecated
|
||||
public void m_92589_(BlockColor p_92590_, Block... p_92591_) {
|
||||
for(Block block : p_92591_) {
|
||||
- this.f_92571_.m_122664_(p_92590_, Registry.f_122824_.m_7447_(block));
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
public static ItemColors m_92683_(BlockColors p_92684_) {
|
||||
ItemColors itemcolors = new ItemColors();
|
||||
@@ -88,17 +_,18 @@
|
||||
@@ -88,17 +_,20 @@
|
||||
itemcolors.m_92689_((p_232352_, p_232353_) -> {
|
||||
return p_232353_ == 0 ? -1 : MapItem.m_42918_(p_232352_);
|
||||
}, Items.f_42573_);
|
||||
@@ -24,6 +24,8 @@
|
||||
return itemcolor == null ? -1 : itemcolor.m_92671_(p_92677_, p_92678_);
|
||||
}
|
||||
|
||||
+ /** @deprecated Register via {@link net.minecraftforge.client.event.RegisterColorHandlersEvent.Item} */
|
||||
+ @Deprecated
|
||||
public void m_92689_(ItemColor p_92690_, ItemLike... p_92691_) {
|
||||
for(ItemLike itemlike : p_92691_) {
|
||||
- this.f_92674_.m_122664_(p_92690_, Item.m_41393_(itemlike.m_5456_()));
|
||||
|
||||
@@ -12,21 +12,21 @@
|
||||
|
||||
for(MobEffectInstance mobeffectinstance : Ordering.natural().reverse().sortedCopy(collection)) {
|
||||
MobEffect mobeffect = mobeffectinstance.m_19544_();
|
||||
+ net.minecraftforge.client.EffectRenderer renderer = net.minecraftforge.client.RenderProperties.getEffectRenderer(mobeffectinstance);
|
||||
+ if (!renderer.shouldRenderHUD(mobeffectinstance)) continue;
|
||||
+ var renderer = net.minecraftforge.client.extensions.common.IClientMobEffectExtensions.of(mobeffectinstance);
|
||||
+ if (!renderer.isVisibleInGui(mobeffectinstance)) continue;
|
||||
+ // Rebind in case previous renderHUDEffect changed texture
|
||||
+ RenderSystem.m_157456_(0, AbstractContainerScreen.f_97725_);
|
||||
if (mobeffectinstance.m_19575_()) {
|
||||
int i = this.f_92977_;
|
||||
int j = 1;
|
||||
@@ -489,6 +_,7 @@
|
||||
RenderSystem.m_157429_(1.0F, 1.0F, 1.0F, f1);
|
||||
m_93200_(p_93029_, l + 3, i1 + 3, this.m_93252_(), 18, 18, textureatlassprite);
|
||||
});
|
||||
+ renderer.renderHUDEffect(mobeffectinstance,this, p_93029_, i, j, this.m_93252_(), f);
|
||||
}
|
||||
}
|
||||
@@ -480,6 +_,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ if (renderer.renderGuiIcon(mobeffectinstance, this, p_93029_, i, j, this.m_93252_(), f)) continue;
|
||||
TextureAtlasSprite textureatlassprite = mobeffecttexturemanager.m_118732_(mobeffect);
|
||||
int l = i;
|
||||
int i1 = j;
|
||||
@@ -609,12 +_,13 @@
|
||||
public void m_93069_(PoseStack p_93070_) {
|
||||
this.f_92986_.m_91307_().m_6180_("selectedItemName");
|
||||
@@ -48,7 +48,7 @@
|
||||
RenderSystem.m_69453_();
|
||||
m_93172_(p_93070_, j - 2, k - 2, j + i + 2, k + 9 + 2, this.f_92986_.f_91066_.m_92143_(0));
|
||||
- this.m_93082_().m_92763_(p_93070_, mutablecomponent, (float)j, (float)k, 16777215 + (l << 24));
|
||||
+ Font font = net.minecraftforge.client.RenderProperties.get(f_92994_).getFont(f_92994_);
|
||||
+ Font font = net.minecraftforge.client.extensions.common.IClientItemExtensions.of(f_92994_).getFont(f_92994_, net.minecraftforge.client.extensions.common.IClientItemExtensions.FontContext.SELECTED_ITEM_NAME);
|
||||
+ if (font == null) {
|
||||
+ this.m_93082_().m_92763_(p_93070_, highlightTip, (float)j, (float)k, 16777215 + (l << 24));
|
||||
+ } else {
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
--- a/net/minecraft/client/gui/components/BossHealthOverlay.java
|
||||
+++ b/net/minecraft/client/gui/components/BossHealthOverlay.java
|
||||
@@ -34,6 +_,9 @@
|
||||
@@ -34,6 +_,8 @@
|
||||
|
||||
for(LerpingBossEvent lerpingbossevent : this.f_93699_.values()) {
|
||||
int k = i / 2 - 91;
|
||||
+ net.minecraftforge.client.event.RenderGameOverlayEvent.BossInfo event =
|
||||
+ net.minecraftforge.client.ForgeHooksClient.renderBossEventPre(p_93705_, this.f_93698_.m_91268_(), lerpingbossevent, k, j, 10 + this.f_93698_.f_91062_.f_92710_);
|
||||
+ var event = net.minecraftforge.client.ForgeHooksClient.onCustomizeBossEventProgress(p_93705_, this.f_93698_.m_91268_(), lerpingbossevent, k, j, 10 + this.f_93698_.f_91062_.f_92710_);
|
||||
+ if (!event.isCanceled()) {
|
||||
RenderSystem.m_157429_(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
RenderSystem.m_157456_(0, f_93697_);
|
||||
this.m_93706_(p_93705_, k, j, lerpingbossevent);
|
||||
@@ -42,7 +_,9 @@
|
||||
@@ -42,7 +_,8 @@
|
||||
int i1 = i / 2 - l / 2;
|
||||
int j1 = j - 9;
|
||||
this.f_93698_.f_91062_.m_92763_(p_93705_, component, (float)i1, (float)j1, 16777215);
|
||||
- j += 10 + 9;
|
||||
+ }
|
||||
+ j += event.getIncrement();
|
||||
+ net.minecraftforge.client.ForgeHooksClient.renderBossEventPost(p_93705_, this.f_93698_.m_91268_());
|
||||
if (j >= this.f_93698_.m_91268_().m_85446_() / 3) {
|
||||
break;
|
||||
}
|
||||
@@ -156,12 +156,12 @@
|
||||
+ this.f_169368_.add(ne);
|
||||
+ f_96540_.add(b);
|
||||
+ };
|
||||
+ if (!net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.ScreenEvent.InitScreenEvent.Pre(this, this.f_96540_, add, this::m_169411_))) {
|
||||
+ if (!net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.ScreenEvent.Init.Pre(this, this.f_96540_, add, this::m_169411_))) {
|
||||
this.m_232761_();
|
||||
this.m_169407_(false);
|
||||
this.m_169378_(f_169370_);
|
||||
+ }
|
||||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.ScreenEvent.InitScreenEvent.Post(this, this.f_96540_, add, this::m_169411_));
|
||||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.ScreenEvent.Init.Post(this, this.f_96540_, add, this::m_169411_));
|
||||
}
|
||||
|
||||
protected void m_232761_() {
|
||||
@@ -169,7 +169,7 @@
|
||||
public void m_96558_(PoseStack p_96559_, int p_96560_) {
|
||||
if (this.f_96541_.f_91073_ != null) {
|
||||
this.m_93179_(p_96559_, 0, 0, this.f_96543_, this.f_96544_, -1072689136, -804253680);
|
||||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.ScreenEvent.BackgroundDrawnEvent(this, p_96559_));
|
||||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.ScreenEvent.BackgroundRendered(this, p_96559_));
|
||||
} else {
|
||||
this.m_96626_(p_96560_);
|
||||
}
|
||||
@@ -177,7 +177,7 @@
|
||||
bufferbuilder.m_5483_((double)this.f_96543_, 0.0D, 0.0D).m_7421_((float)this.f_96543_ / 32.0F, (float)p_96627_).m_6122_(64, 64, 64, 255).m_5752_();
|
||||
bufferbuilder.m_5483_(0.0D, 0.0D, 0.0D).m_7421_(0.0F, (float)p_96627_).m_6122_(64, 64, 64, 255).m_5752_();
|
||||
tesselator.m_85914_();
|
||||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.ScreenEvent.BackgroundDrawnEvent(this, new PoseStack()));
|
||||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.ScreenEvent.BackgroundRendered(this, new PoseStack()));
|
||||
}
|
||||
|
||||
public boolean m_7043_() {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
private long f_96715_;
|
||||
@Nullable
|
||||
private TitleScreen.WarningLabel f_232768_;
|
||||
+ private net.minecraftforge.client.gui.NotificationModUpdateScreen modUpdateNotification;
|
||||
+ private net.minecraftforge.client.gui.TitleScreenModUpdateIndicator modUpdateNotification;
|
||||
|
||||
public TitleScreen() {
|
||||
this(false);
|
||||
@@ -21,7 +21,7 @@
|
||||
+ this.f_96541_.m_91152_(new net.minecraftforge.client.gui.ModListScreen(this));
|
||||
+ }));
|
||||
}
|
||||
+ modUpdateNotification = net.minecraftforge.client.gui.NotificationModUpdateScreen.init(this, modButton);
|
||||
+ modUpdateNotification = net.minecraftforge.client.gui.TitleScreenModUpdateIndicator.init(this, modButton);
|
||||
|
||||
this.m_142416_(new ImageButton(this.f_96543_ / 2 - 124, l + 72 + 12, 20, 20, 0, 106, 20, Button.f_93617_, 256, 256, (p_96791_) -> {
|
||||
this.f_96541_.m_91152_(new LanguageSelectScreen(this, this.f_96541_.f_91066_, this.f_96541_.m_91102_()));
|
||||
|
||||
+3
-3
@@ -4,7 +4,7 @@
|
||||
int i = this.f_97735_;
|
||||
int j = this.f_97736_;
|
||||
this.m_7286_(p_97795_, p_97798_, p_97796_, p_97797_);
|
||||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.ContainerScreenEvent.DrawBackground(this, p_97795_, p_97796_, p_97797_));
|
||||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.ContainerScreenEvent.Render.Background(this, p_97795_, p_97796_, p_97797_));
|
||||
RenderSystem.m_69465_();
|
||||
super.m_6305_(p_97795_, p_97796_, p_97797_, p_97798_);
|
||||
PoseStack posestack = RenderSystem.m_157191_();
|
||||
@@ -18,7 +18,7 @@
|
||||
}
|
||||
|
||||
this.m_7027_(p_97795_, p_97796_, p_97797_);
|
||||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.ContainerScreenEvent.DrawForeground(this, p_97795_, p_97796_, p_97797_));
|
||||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.ContainerScreenEvent.Render.Foreground(this, p_97795_, p_97796_, p_97797_));
|
||||
ItemStack itemstack = this.f_97711_.m_41619_() ? this.f_97732_.m_142621_() : this.f_97711_;
|
||||
if (!itemstack.m_41619_()) {
|
||||
int l1 = 8;
|
||||
@@ -41,7 +41,7 @@
|
||||
RenderSystem.m_157182_();
|
||||
this.m_93250_(200);
|
||||
this.f_96542_.f_115093_ = 200.0F;
|
||||
+ net.minecraft.client.gui.Font font = net.minecraftforge.client.RenderProperties.get(p_97783_).getFont(p_97783_);
|
||||
+ var font = net.minecraftforge.client.extensions.common.IClientItemExtensions.of(p_97783_).getFont(p_97783_, net.minecraftforge.client.extensions.common.IClientItemExtensions.FontContext.ITEM_COUNT);
|
||||
+ if (font == null) font = this.f_96547_;
|
||||
this.f_96542_.m_115203_(p_97783_, p_97784_, p_97785_);
|
||||
- this.f_96542_.m_115174_(this.f_96547_, p_97783_, p_97784_, p_97785_ - (this.f_97711_.m_41619_() ? 0 : 8), p_97786_);
|
||||
|
||||
+19
-7
@@ -1,11 +1,12 @@
|
||||
--- a/net/minecraft/client/gui/screens/inventory/EffectRenderingInventoryScreen.java
|
||||
+++ b/net/minecraft/client/gui/screens/inventory/EffectRenderingInventoryScreen.java
|
||||
@@ -42,12 +_,15 @@
|
||||
@@ -42,12 +_,16 @@
|
||||
if (!collection.isEmpty() && j >= 32) {
|
||||
RenderSystem.m_157429_(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
boolean flag = j >= 120;
|
||||
+ var event = net.minecraftforge.client.ForgeHooksClient.onScreenPotionSize(this);
|
||||
+ if (event != net.minecraftforge.eventbus.api.Event.Result.DEFAULT) flag = event == net.minecraftforge.eventbus.api.Event.Result.DENY; // true means classic mode
|
||||
+ var event = net.minecraftforge.client.ForgeHooksClient.onScreenPotionSize(this, j, !flag);
|
||||
+ if (event == 0) return; // 0 = cancel rendering
|
||||
+ flag = event == 2; // 2 = full-size / 1 = compact
|
||||
int k = 33;
|
||||
if (collection.size() > 5) {
|
||||
k = 132 / (collection.size() - 1);
|
||||
@@ -17,13 +18,24 @@
|
||||
this.m_194002_(p_194015_, i, k, iterable, flag);
|
||||
this.m_194008_(p_194015_, i, k, iterable, flag);
|
||||
if (flag) {
|
||||
@@ -108,6 +_,12 @@
|
||||
@@ -95,6 +_,11 @@
|
||||
int i = this.f_97736_;
|
||||
|
||||
for(MobEffectInstance mobeffectinstance : p_194012_) {
|
||||
+ var renderer = net.minecraftforge.client.extensions.common.IClientMobEffectExtensions.of(mobeffectinstance);
|
||||
+ if (renderer.renderInventoryIcon(mobeffectinstance, this, p_194009_, p_194010_ + (p_194013_ ? 6 : 7), i, this.m_93252_())) {
|
||||
+ i += p_194011_;
|
||||
+ continue;
|
||||
+ }
|
||||
MobEffect mobeffect = mobeffectinstance.m_19544_();
|
||||
TextureAtlasSprite textureatlassprite = mobeffecttexturemanager.m_118732_(mobeffect);
|
||||
RenderSystem.m_157456_(0, textureatlassprite.m_118414_().m_118330_());
|
||||
@@ -108,6 +_,11 @@
|
||||
int i = this.f_97736_;
|
||||
|
||||
for(MobEffectInstance mobeffectinstance : p_98726_) {
|
||||
+ net.minecraftforge.client.EffectRenderer renderer = net.minecraftforge.client.RenderProperties.getEffectRenderer(mobeffectinstance);
|
||||
+ renderer.renderInventoryEffect(mobeffectinstance, this, p_98723_, p_98724_, i, this.m_93252_());
|
||||
+ if (!renderer.shouldRenderInvText(mobeffectinstance)) {
|
||||
+ var renderer = net.minecraftforge.client.extensions.common.IClientMobEffectExtensions.of(mobeffectinstance);
|
||||
+ if (renderer.renderInventoryText(mobeffectinstance, this, p_98723_, p_98724_, i, this.m_93252_())) {
|
||||
+ i += p_98725_;
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
--- a/net/minecraft/client/gui/screens/inventory/MerchantScreen.java
|
||||
+++ b/net/minecraft/client/gui/screens/inventory/MerchantScreen.java
|
||||
@@ -240,7 +_,12 @@
|
||||
this.f_96542_.m_115169_(this.f_96547_, p_99164_, p_99166_, p_99167_);
|
||||
} else {
|
||||
this.f_96542_.m_115174_(this.f_96547_, p_99165_, p_99166_, p_99167_, p_99165_.m_41613_() == 1 ? "1" : null);
|
||||
- this.f_96542_.m_115174_(this.f_96547_, p_99164_, p_99166_ + 14, p_99167_, p_99164_.m_41613_() == 1 ? "1" : null);
|
||||
+ // Forge: fixes Forge-8806, code for count rendering taken from ItemRenderer#renderGuiItemDecorations
|
||||
+ PoseStack posestack = new PoseStack();
|
||||
+ posestack.m_85837_(0.0D, 0.0D, (f_96542_.f_115093_ + 200.0F));
|
||||
+ net.minecraft.client.renderer.MultiBufferSource.BufferSource bufferSource = net.minecraft.client.renderer.MultiBufferSource.m_109898_(com.mojang.blaze3d.vertex.Tesselator.m_85913_().m_85915_());
|
||||
+ f_96547_.m_92811_(String.valueOf(p_99164_.m_41613_()), (p_99166_ + 14) + 19 - 2 - f_96547_.m_92895_(String.valueOf(p_99164_.m_41613_())), p_99167_ + 6 + 3, 0xFFFFFF, true, posestack.m_85850_().m_85861_(), bufferSource, false, 0, 15728880);
|
||||
+ bufferSource.m_109911_();
|
||||
RenderSystem.m_157427_(GameRenderer::m_172817_);
|
||||
RenderSystem.m_157456_(0, f_99113_);
|
||||
this.m_93250_(this.m_93252_() + 300);
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
if (p_169951_ instanceof BundleTooltip) {
|
||||
return new ClientBundleTooltip((BundleTooltip)p_169951_);
|
||||
} else {
|
||||
+ ClientTooltipComponent result = net.minecraftforge.client.MinecraftForgeClient.getClientTooltipComponent(p_169951_);
|
||||
+ ClientTooltipComponent result = net.minecraftforge.client.gui.ClientTooltipComponentManager.createClientTooltipComponent(p_169951_);
|
||||
+ if (result != null) return result;
|
||||
throw new IllegalArgumentException("Unknown TooltipComponent");
|
||||
}
|
||||
|
||||
+30
@@ -1,5 +1,35 @@
|
||||
--- a/net/minecraft/client/gui/screens/worldselection/CreateWorldScreen.java
|
||||
+++ b/net/minecraft/client/gui/screens/worldselection/CreateWorldScreen.java
|
||||
@@ -112,7 +_,7 @@
|
||||
public static void m_232896_(Minecraft p_232897_, @Nullable Screen p_232898_) {
|
||||
m_232899_(p_232897_, f_232866_);
|
||||
PackRepository packrepository = new PackRepository(PackType.SERVER_DATA, new ServerPacksSource());
|
||||
- WorldLoader.InitConfig worldloader$initconfig = m_232872_(packrepository, DataPackConfig.f_45842_);
|
||||
+ WorldLoader.InitConfig worldloader$initconfig = m_232872_(packrepository, new DataPackConfig(ImmutableList.of("vanilla"), ImmutableList.of())); // FORGE: Load vanilla fallback with vanilla datapacks.
|
||||
CompletableFuture<WorldCreationContext> completablefuture = WorldLoader.m_214362_(worldloader$initconfig, (p_232935_, p_232936_) -> {
|
||||
RegistryAccess.Frozen registryaccess$frozen = RegistryAccess.m_206197_().m_203557_();
|
||||
WorldGenSettings worldgensettings = WorldPresets.m_226449_(registryaccess$frozen);
|
||||
@@ -122,7 +_,10 @@
|
||||
return new WorldCreationContext(p_232884_, Lifecycle.stable(), p_232883_, p_232882_);
|
||||
}, Util.m_183991_(), p_232897_);
|
||||
p_232897_.m_18701_(completablefuture::isDone);
|
||||
- p_232897_.m_91152_(new CreateWorldScreen(p_232898_, DataPackConfig.f_45842_, new WorldGenSettingsComponent(completablefuture.join(), Optional.of(WorldPresets.f_226437_), OptionalLong.empty())));
|
||||
+ // FORGE: Force load mods' datapacks after setting screen and ensure datapack selection reverts to vanilla if invalid.
|
||||
+ CreateWorldScreen createWorldScreen = new CreateWorldScreen(p_232898_, new DataPackConfig(ImmutableList.of("vanilla"), ImmutableList.of()), new WorldGenSettingsComponent(completablefuture.join(), Optional.of(WorldPresets.f_226437_), OptionalLong.empty()));
|
||||
+ p_232897_.m_91152_(createWorldScreen);
|
||||
+ createWorldScreen.m_100878_(packrepository);
|
||||
}
|
||||
|
||||
public static CreateWorldScreen m_205426_(@Nullable Screen p_205427_, WorldStem p_205428_, @Nullable Path p_205429_) {
|
||||
@@ -478,7 +_,7 @@
|
||||
if (p_232949_) {
|
||||
this.m_100975_();
|
||||
} else {
|
||||
- this.f_100846_ = DataPackConfig.f_45842_;
|
||||
+ this.f_100846_ = new DataPackConfig(ImmutableList.of("vanilla"), ImmutableList.of()); // FORGE: Revert to *actual* vanilla data
|
||||
this.f_96541_.m_91152_(this);
|
||||
}
|
||||
|
||||
@@ -653,6 +_,7 @@
|
||||
File file1 = path.toFile();
|
||||
if (this.f_100832_ == null) {
|
||||
|
||||
+22
-6
@@ -1,13 +1,29 @@
|
||||
--- a/net/minecraft/client/gui/screens/worldselection/WorldOpenFlows.java
|
||||
+++ b/net/minecraft/client/gui/screens/worldselection/WorldOpenFlows.java
|
||||
@@ -66,6 +_,7 @@
|
||||
@@ -132,13 +_,23 @@
|
||||
}
|
||||
|
||||
private void m_233145_(Screen p_233146_, String p_233147_, boolean p_233148_, boolean p_233149_) {
|
||||
+ // FORGE: Patch in overload to reduce further patching
|
||||
+ this.doLoadLevel(p_233146_, p_233147_, p_233148_, p_233149_, false);
|
||||
+ }
|
||||
+
|
||||
+ // FORGE: Patch in confirmExperimentalWarning which confirms the experimental warning when true
|
||||
+ private void doLoadLevel(Screen p_233146_, String p_233147_, boolean p_233148_, boolean p_233149_, boolean confirmExperimentalWarning) {
|
||||
LevelStorageSource.LevelStorageAccess levelstoragesource$levelstorageaccess = this.m_233155_(p_233147_);
|
||||
if (levelstoragesource$levelstorageaccess != null) {
|
||||
PackRepository packrepository = m_233105_(levelstoragesource$levelstorageaccess);
|
||||
|
||||
WorldStem worldstem;
|
||||
try {
|
||||
WorldLoader.PackConfig worldloader$packconfig = new WorldLoader.PackConfig(packrepository, datapackconfig, false);
|
||||
+ levelstoragesource$levelstorageaccess.readAdditionalLevelSaveData(); // Read extra (e.g. modded) data from the world before creating it
|
||||
WorldStem worldstem = this.m_233096_(worldloader$packconfig, (p_233103_, p_233104_) -> {
|
||||
return Pair.of(new PrimaryLevelData(p_233159_, p_233161_, Lifecycle.stable()), p_233160_.m_203557_());
|
||||
});
|
||||
worldstem = this.m_233122_(levelstoragesource$levelstorageaccess, p_233148_, packrepository);
|
||||
+ if (confirmExperimentalWarning && worldstem.f_206895_() instanceof PrimaryLevelData pld) {
|
||||
+ pld.withConfirmedWarning(true);
|
||||
+ }
|
||||
} catch (Exception exception) {
|
||||
f_233088_.warn("Failed to load datapacks, can't proceed with server load", (Throwable)exception);
|
||||
this.f_233089_.m_91152_(new DatapackLoadFailureScreen(() -> {
|
||||
@@ -151,7 +_,9 @@
|
||||
WorldData worlddata = worldstem.f_206895_();
|
||||
boolean flag = worlddata.m_5961_().m_64670_();
|
||||
@@ -27,7 +43,7 @@
|
||||
this.m_233140_(p_233146_, p_233147_, flag, () -> {
|
||||
this.m_233145_(p_233146_, p_233147_, p_233148_, false);
|
||||
});
|
||||
+ else net.minecraftforge.client.ForgeHooksClient.createWorldConfirmationScreen(p_233147_, levelstoragesource$levelstorageaccess, packrepository, worldstem);
|
||||
+ else net.minecraftforge.client.ForgeHooksClient.createWorldConfirmationScreen(() -> this.doLoadLevel(p_233146_, p_233147_, p_233148_, false, true));
|
||||
worldstem.close();
|
||||
m_233116_(levelstoragesource$levelstorageaccess, p_233147_);
|
||||
}
|
||||
@@ -1,5 +1,13 @@
|
||||
--- a/net/minecraft/client/main/Main.java
|
||||
+++ b/net/minecraft/client/main/Main.java
|
||||
@@ -49,6 +_,7 @@
|
||||
@DontObfuscate
|
||||
public static void main(String[] p_129642_) {
|
||||
SharedConstants.m_142977_();
|
||||
+ if (!net.minecraftforge.fml.loading.FMLConfig.isOptimizedDFUDisabled())
|
||||
SharedConstants.m_214358_();
|
||||
OptionParser optionparser = new OptionParser();
|
||||
optionparser.allowsUnrecognizedOptions();
|
||||
@@ -135,7 +_,7 @@
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
int i = this.f_104410_.m_104481_(p_104456_, p_104457_);
|
||||
LevelChunk levelchunk = this.f_104410_.m_104479_(i);
|
||||
if (m_104438_(levelchunk, p_104456_, p_104457_)) {
|
||||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkEvent.Unload(levelchunk));
|
||||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.level.ChunkEvent.Unload(levelchunk));
|
||||
this.f_104410_.m_104487_(i, levelchunk, (LevelChunk)null);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
}
|
||||
|
||||
this.f_104411_.m_171649_(chunkpos);
|
||||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkEvent.Load(levelchunk));
|
||||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.level.ChunkEvent.Load(levelchunk));
|
||||
return levelchunk;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
--- a/net/minecraft/client/multiplayer/ClientLevel.java
|
||||
+++ b/net/minecraft/client/multiplayer/ClientLevel.java
|
||||
@@ -121,6 +_,7 @@
|
||||
@@ -121,6 +_,8 @@
|
||||
private int f_194123_;
|
||||
private final BlockStatePredictionHandler f_233599_ = new BlockStatePredictionHandler();
|
||||
private static final Set<Item> f_194124_ = Set.of(Items.f_42127_, Items.f_151033_);
|
||||
+ private final it.unimi.dsi.fastutil.ints.Int2ObjectMap<net.minecraftforge.entity.PartEntity<?>> partEntities = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>();
|
||||
+ private final net.minecraftforge.client.model.data.ModelDataManager modelDataManager = new net.minecraftforge.client.model.data.ModelDataManager(this);
|
||||
|
||||
public void m_233651_(int p_233652_) {
|
||||
this.f_233599_.m_233856_(p_233652_, this);
|
||||
@@ -13,7 +14,7 @@
|
||||
this.m_46465_();
|
||||
this.m_46466_();
|
||||
+ this.gatherCapabilities();
|
||||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Load(this));
|
||||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.level.LevelEvent.Load(this));
|
||||
}
|
||||
|
||||
public void m_194171_(Runnable p_194172_) {
|
||||
@@ -29,7 +30,7 @@
|
||||
}
|
||||
|
||||
private void m_104739_(int p_104740_, Entity p_104741_) {
|
||||
+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityJoinWorldEvent(p_104741_, this))) return;
|
||||
+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityJoinLevelEvent(p_104741_, this))) return;
|
||||
this.m_171642_(p_104740_, Entity.RemovalReason.DISCARDED);
|
||||
this.f_171631_.m_157653_(p_104741_);
|
||||
+ p_104741_.onAddedToWorld();
|
||||
@@ -53,7 +54,7 @@
|
||||
}
|
||||
|
||||
public void m_213890_(@Nullable Player p_233631_, Entity p_233632_, SoundEvent p_233633_, SoundSource p_233634_, float p_233635_, float p_233636_, long p_233637_) {
|
||||
+ net.minecraftforge.event.PlayLevelSoundEvent.AtEntity event = net.minecraftforge.event.ForgeEventFactory.onPlaySoundAtEntity(p_233631_, p_233633_, p_233634_, p_233635_, p_233636_);
|
||||
+ net.minecraftforge.event.PlayLevelSoundEvent.AtEntity event = net.minecraftforge.event.ForgeEventFactory.onPlaySoundAtEntity(p_233632_, p_233633_, p_233634_, p_233635_, p_233636_);
|
||||
+ if (event.isCanceled() || event.getSound() == null) return;
|
||||
+ p_233633_ = event.getSound();
|
||||
+ p_233634_ = event.getSource();
|
||||
@@ -70,7 +71,7 @@
|
||||
this.f_104840_ = p_104852_;
|
||||
}
|
||||
|
||||
@@ -939,14 +_,33 @@
|
||||
@@ -939,14 +_,46 @@
|
||||
ClientLevel.this.f_104566_.add((AbstractClientPlayer)p_171712_);
|
||||
}
|
||||
|
||||
@@ -85,8 +86,8 @@
|
||||
p_171716_.m_19877_();
|
||||
ClientLevel.this.f_104566_.remove(p_171716_);
|
||||
+
|
||||
+ p_171716_.onRemovedFromWorld();
|
||||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityLeaveWorldEvent(p_171716_, ClientLevel.this));
|
||||
+ p_171716_.onRemovedFromWorld();
|
||||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityLeaveLevelEvent(p_171716_, ClientLevel.this));
|
||||
+
|
||||
+ if (p_171716_.isMultipartEntity()) {
|
||||
+ for (net.minecraftforge.entity.PartEntity<?> part : p_171716_.getParts()) {
|
||||
@@ -102,5 +103,18 @@
|
||||
+ @Override
|
||||
+ public java.util.Collection<net.minecraftforge.entity.PartEntity<?>> getPartEntities() {
|
||||
+ return this.partEntities.values();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public net.minecraftforge.client.model.data.ModelDataManager getModelDataManager() {
|
||||
+ return modelDataManager;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public float getShade(float normalX, float normalY, float normalZ, boolean shade) {
|
||||
+ boolean constantAmbientLight = this.m_104583_().m_108885_();
|
||||
+ if (!shade)
|
||||
+ return constantAmbientLight ? 0.9F : 1.0F;
|
||||
+ return net.minecraftforge.client.model.lighting.QuadLighter.calculateShade(normalX, normalY, normalZ, constantAmbientLight);
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@
|
||||
}
|
||||
|
||||
Component component = flag ? p_233693_.f_237213_() : p_233693_.m_237220_();
|
||||
+ component = net.minecraftforge.event.ForgeEventFactory.onClientChat(p_233692_, component, p_233694_);
|
||||
+ component = net.minecraftforge.client.ForgeHooksClient.onClientChat(p_233692_, component, p_233694_);
|
||||
+ if (component == null) return;
|
||||
this.f_104888_.f_91065_.m_232360_(p_233692_, component, p_233694_);
|
||||
}
|
||||
@@ -48,11 +48,14 @@
|
||||
|
||||
if (p_205557_ instanceof CommandBlockEntity && this.f_104888_.f_91080_ instanceof CommandBlockEditScreen) {
|
||||
((CommandBlockEditScreen)this.f_104888_.f_91080_).m_98398_();
|
||||
@@ -1185,6 +_,7 @@
|
||||
@@ -1184,7 +_,9 @@
|
||||
|
||||
public void m_7443_(ClientboundCommandsPacket p_104990_) {
|
||||
PacketUtils.m_131363_(p_104990_, this, this.f_104888_);
|
||||
this.f_104899_ = new CommandDispatcher<>(p_104990_.m_237624_(new CommandBuildContext(this.f_104903_)));
|
||||
+ this.f_104899_ = net.minecraftforge.client.ClientCommandHandler.mergeServerCommands(this.f_104899_);
|
||||
- this.f_104899_ = new CommandDispatcher<>(p_104990_.m_237624_(new CommandBuildContext(this.f_104903_)));
|
||||
+ var context = new CommandBuildContext(this.f_104903_);
|
||||
+ this.f_104899_ = new CommandDispatcher<>(p_104990_.m_237624_(context));
|
||||
+ this.f_104899_ = net.minecraftforge.client.ClientCommandHandler.mergeServerCommands(this.f_104899_, context);
|
||||
}
|
||||
|
||||
public void m_7183_(ClientboundStopSoundPacket p_105116_) {
|
||||
@@ -72,12 +75,19 @@
|
||||
}
|
||||
|
||||
private <T> void m_205560_(ResourceKey<? extends Registry<? extends T>> p_205561_, TagNetworkSerialization.NetworkPayload p_205562_) {
|
||||
@@ -1843,7 +_,8 @@
|
||||
@@ -1646,6 +_,7 @@
|
||||
}
|
||||
|
||||
public void m_7413_(ClientboundCustomPayloadPacket p_105004_) {
|
||||
+ if (!f_104888_.m_18695_() && net.minecraftforge.network.NetworkHooks.onCustomPayload(p_105004_, this.f_104885_)) return;
|
||||
PacketUtils.m_131363_(p_105004_, this, this.f_104888_);
|
||||
ResourceLocation resourcelocation = p_105004_.m_132042_();
|
||||
FriendlyByteBuf friendlybytebuf = null;
|
||||
@@ -1843,7 +_,7 @@
|
||||
int j5 = friendlybytebuf.m_130242_();
|
||||
this.f_104888_.f_91064_.f_173815_.m_173830_(positionsource, j5);
|
||||
} else {
|
||||
- f_104883_.warn("Unknown custom packed identifier: {}", (Object)resourcelocation);
|
||||
+ if (!net.minecraftforge.network.NetworkHooks.onCustomPayload(p_105004_, this.f_104885_))
|
||||
+ f_104883_.warn("Unknown custom packet identifier: {}", (Object)resourcelocation);
|
||||
}
|
||||
} finally {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
super(p_105665_, p_105666_, p_105667_, p_105668_, 0.0D, 0.0D, 0.0D);
|
||||
- this.m_108337_(Minecraft.m_91087_().m_91291_().m_174264_(p_105669_, p_105665_, (LivingEntity)null, 0).m_6160_());
|
||||
+ var model = Minecraft.m_91087_().m_91291_().m_174264_(p_105669_, p_105665_, (LivingEntity)null, 0);
|
||||
+ this.m_108337_(model.m_7343_().m_173464_(model, p_105669_, p_105665_, null, 0).getParticleIcon(net.minecraftforge.client.model.data.EmptyModelData.INSTANCE));
|
||||
+ this.m_108337_(model.m_7343_().m_173464_(model, p_105669_, p_105665_, null, 0).getParticleIcon(net.minecraftforge.client.model.data.ModelData.EMPTY));
|
||||
this.f_107226_ = 1.0F;
|
||||
this.f_107663_ /= 2.0F;
|
||||
this.f_105643_ = this.f_107223_.m_188501_() * 3.0F;
|
||||
@@ -14,14 +14,19 @@
|
||||
private final Queue<Particle> f_107294_ = Queues.newArrayDeque();
|
||||
private final Map<ResourceLocation, ParticleEngine.MutableSpriteSet> f_107295_ = Maps.newHashMap();
|
||||
private final TextureAtlas f_107296_;
|
||||
@@ -178,13 +_,13 @@
|
||||
@@ -177,14 +_,18 @@
|
||||
this.m_107378_(ParticleTypes.f_235901_, ShriekParticle.Provider::new);
|
||||
}
|
||||
|
||||
+ /** @deprecated Register via {@link net.minecraftforge.client.event.RegisterParticleProvidersEvent} */
|
||||
+ @Deprecated
|
||||
public <T extends ParticleOptions> void m_107381_(ParticleType<T> p_107382_, ParticleProvider<T> p_107383_) {
|
||||
- this.f_107293_.put(Registry.f_122829_.m_7447_(p_107382_), p_107383_);
|
||||
+ this.f_107293_.put(Registry.f_122829_.m_7981_(p_107382_), p_107383_);
|
||||
}
|
||||
|
||||
+ /** @deprecated Register via {@link net.minecraftforge.client.event.RegisterParticleProvidersEvent} */
|
||||
+ @Deprecated
|
||||
public <T extends ParticleOptions> void m_107378_(ParticleType<T> p_107379_, ParticleEngine.SpriteParticleRegistration<T> p_107380_) {
|
||||
ParticleEngine.MutableSpriteSet particleengine$mutablespriteset = new ParticleEngine.MutableSpriteSet();
|
||||
this.f_107295_.put(Registry.f_122829_.m_7981_(p_107379_), particleengine$mutablespriteset);
|
||||
@@ -79,7 +84,7 @@
|
||||
|
||||
public void m_107355_(BlockPos p_107356_, BlockState p_107357_) {
|
||||
- if (!p_107357_.m_60795_()) {
|
||||
+ if (!p_107357_.m_60795_() && !net.minecraftforge.client.RenderProperties.get(p_107357_).addDestroyEffects(p_107357_, this.f_107287_, p_107356_, this)) {
|
||||
+ if (!p_107357_.m_60795_() && !net.minecraftforge.client.extensions.common.IClientBlockExtensions.of(p_107357_).addDestroyEffects(p_107357_, this.f_107287_, p_107356_, this)) {
|
||||
VoxelShape voxelshape = p_107357_.m_60808_(this.f_107287_, p_107356_);
|
||||
double d0 = 0.25D;
|
||||
voxelshape.m_83286_((p_172273_, p_172274_, p_172275_, p_172276_, p_172277_, p_172278_) -> {
|
||||
@@ -107,7 +112,7 @@
|
||||
+
|
||||
+ public void addBlockHitEffects(BlockPos pos, net.minecraft.world.phys.BlockHitResult target) {
|
||||
+ BlockState state = f_107287_.m_8055_(pos);
|
||||
+ if (!net.minecraftforge.client.RenderProperties.get(state).addHitEffects(state, f_107287_, target, this))
|
||||
+ if (!net.minecraftforge.client.extensions.common.IClientBlockExtensions.of(state).addHitEffects(state, f_107287_, target, this))
|
||||
+ m_107367_(pos, target.m_82434_());
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
}
|
||||
|
||||
- return Mth.m_14179_(Minecraft.m_91087_().f_91066_.m_231925_().m_231551_().floatValue(), 1.0F, f);
|
||||
+ return net.minecraftforge.client.ForgeHooksClient.getFieldOfView(this, f);
|
||||
+ return net.minecraftforge.client.ForgeHooksClient.getFieldOfViewModifier(this, f);
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
public void m_234125_(String p_234126_, @Nullable Component p_234127_) {
|
||||
+ // TODO-PATCHING: If the chat preview component is not null and the message is changed by this event, it looks like the signatures will de-sync and the server will skip the message. Fix? -SS
|
||||
+ p_234126_ = net.minecraftforge.event.ForgeEventFactory.onClientSendMessage(p_234126_);
|
||||
+ p_234126_ = net.minecraftforge.client.ForgeHooksClient.onClientSendMessage(p_234126_);
|
||||
+ if (p_234126_.isEmpty()) return;
|
||||
MessageSigner messagesigner = MessageSigner.m_237183_(this.m_20148_());
|
||||
this.m_234141_(messagesigner, p_234126_, p_234127_);
|
||||
@@ -49,7 +49,35 @@
|
||||
this.f_108619_.m_91301_().m_120586_(this.f_108618_);
|
||||
if (this.m_6117_() && !this.m_20159_()) {
|
||||
this.f_108618_.f_108566_ *= 0.2F;
|
||||
@@ -772,7 +_,7 @@
|
||||
@@ -726,7 +_,7 @@
|
||||
}
|
||||
|
||||
boolean flag4 = (float)this.m_36324_().m_38702_() > 6.0F || this.m_150110_().f_35936_;
|
||||
- if ((this.f_19861_ || this.m_5842_()) && !flag1 && !flag2 && this.m_108733_() && !this.m_20142_() && flag4 && !this.m_6117_() && !this.m_21023_(MobEffects.f_19610_)) {
|
||||
+ if ((this.f_19861_ || this.m_5842_() || this.canStartSwimming()) && !flag1 && !flag2 && this.m_108733_() && !this.m_20142_() && flag4 && !this.m_6117_() && !this.m_21023_(MobEffects.f_19610_)) {
|
||||
if (this.f_108583_ <= 0 && !this.f_108619_.f_91066_.f_92091_.m_90857_()) {
|
||||
this.f_108583_ = 7;
|
||||
} else {
|
||||
@@ -734,15 +_,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
- if (!this.m_20142_() && (!this.m_20069_() || this.m_5842_()) && this.m_108733_() && flag4 && !this.m_6117_() && !this.m_21023_(MobEffects.f_19610_) && this.f_108619_.f_91066_.f_92091_.m_90857_()) {
|
||||
+ if (!this.m_20142_() && (!(this.m_20069_() || this.isInFluidType((fluidType, height) -> this.canSwimInFluidType(fluidType))) || (this.m_5842_() || this.canStartSwimming())) && this.m_108733_() && flag4 && !this.m_6117_() && !this.m_21023_(MobEffects.f_19610_) && this.f_108619_.f_91066_.f_92091_.m_90857_()) {
|
||||
this.m_6858_(true);
|
||||
}
|
||||
|
||||
if (this.m_20142_()) {
|
||||
boolean flag5 = !this.f_108618_.m_108577_() || !flag4;
|
||||
- boolean flag6 = flag5 || this.f_19862_ && !this.f_185931_ || this.m_20069_() && !this.m_5842_();
|
||||
+ boolean flag6 = flag5 || this.f_19862_ && !this.f_185931_ || (this.m_20069_() && !this.m_5842_()) || (this.isInFluidType((fluidType, height) -> this.canSwimInFluidType(fluidType)) && !this.canStartSwimming());
|
||||
if (this.m_6069_()) {
|
||||
- if (!this.f_19861_ && !this.f_108618_.f_108573_ && flag5 || !this.m_20069_()) {
|
||||
+ if (!this.f_19861_ && !this.f_108618_.f_108573_ && flag5 || !(this.m_20069_() || this.isInFluidType((fluidType, height) -> this.canSwimInFluidType(fluidType)))) {
|
||||
this.m_6858_(false);
|
||||
}
|
||||
} else if (flag6) {
|
||||
@@ -772,14 +_,15 @@
|
||||
|
||||
if (this.f_108618_.f_108572_ && !flag7 && !flag && !this.m_150110_().f_35935_ && !this.m_20159_() && !this.m_6147_()) {
|
||||
ItemStack itemstack = this.m_6844_(EquipmentSlot.CHEST);
|
||||
@@ -58,6 +86,16 @@
|
||||
this.f_108617_.m_104955_(new ServerboundPlayerCommandPacket(this, ServerboundPlayerCommandPacket.Action.START_FALL_FLYING));
|
||||
}
|
||||
}
|
||||
|
||||
this.f_108614_ = this.m_21255_();
|
||||
- if (this.m_20069_() && this.f_108618_.f_108573_ && this.m_6129_()) {
|
||||
- this.m_21208_();
|
||||
+ net.minecraftforge.fluids.FluidType fluidType = this.getMaxHeightFluidType();
|
||||
+ if ((this.m_20069_() || (!fluidType.isAir() && this.canSwimInFluidType(fluidType))) && this.f_108618_.f_108573_ && this.m_6129_()) {
|
||||
+ this.sinkInFluid(this.m_20069_() ? net.minecraftforge.common.ForgeMod.WATER_TYPE.get() : fluidType);
|
||||
}
|
||||
|
||||
if (this.m_204029_(FluidTags.f_13131_)) {
|
||||
@@ -890,6 +_,7 @@
|
||||
|
||||
public void m_6083_() {
|
||||
|
||||
+15
-44
@@ -1,49 +1,20 @@
|
||||
--- a/net/minecraft/client/renderer/DimensionSpecialEffects.java
|
||||
+++ b/net/minecraft/client/renderer/DimensionSpecialEffects.java
|
||||
@@ -27,6 +_,10 @@
|
||||
private final DimensionSpecialEffects.SkyType f_108861_;
|
||||
private final boolean f_108862_;
|
||||
private final boolean f_108863_;
|
||||
+ private net.minecraftforge.client.IWeatherRenderHandler weatherRenderHandler = null;
|
||||
+ private net.minecraftforge.client.IWeatherParticleRenderHandler weatherParticleRenderHandler = null;
|
||||
+ private net.minecraftforge.client.ISkyRenderHandler skyRenderHandler = null;
|
||||
+ private net.minecraftforge.client.ICloudRenderHandler cloudRenderHandler = null;
|
||||
@@ -13,7 +_,7 @@
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
public DimensionSpecialEffects(float p_108866_, boolean p_108867_, DimensionSpecialEffects.SkyType p_108868_, boolean p_108869_, boolean p_108870_) {
|
||||
this.f_108859_ = p_108866_;
|
||||
@@ -81,6 +_,35 @@
|
||||
|
||||
public boolean m_108885_() {
|
||||
return this.f_108863_;
|
||||
+ }
|
||||
+
|
||||
+ public void setWeatherRenderHandler(net.minecraftforge.client.IWeatherRenderHandler weatherRenderHandler) {
|
||||
+ this.weatherRenderHandler = weatherRenderHandler;
|
||||
+ }
|
||||
+ public void setWeatherParticleRenderHandler(net.minecraftforge.client.IWeatherParticleRenderHandler weatherParticleRenderHandler) {
|
||||
+ this.weatherParticleRenderHandler = weatherParticleRenderHandler;
|
||||
+ }
|
||||
+ public void setSkyRenderHandler(net.minecraftforge.client.ISkyRenderHandler skyRenderHandler) {
|
||||
+ this.skyRenderHandler = skyRenderHandler;
|
||||
+ }
|
||||
+ public void setCloudRenderHandler(net.minecraftforge.client.ICloudRenderHandler cloudRenderHandler) {
|
||||
+ this.cloudRenderHandler = cloudRenderHandler;
|
||||
+ }
|
||||
+ @Nullable
|
||||
+ public net.minecraftforge.client.ICloudRenderHandler getCloudRenderHandler() {
|
||||
+ return cloudRenderHandler;
|
||||
+ }
|
||||
+ @Nullable
|
||||
+ public net.minecraftforge.client.IWeatherRenderHandler getWeatherRenderHandler() {
|
||||
+ return weatherRenderHandler;
|
||||
+ }
|
||||
+ @Nullable
|
||||
+ public net.minecraftforge.client.IWeatherParticleRenderHandler getWeatherParticleRenderHandler() {
|
||||
+ return weatherParticleRenderHandler;
|
||||
+ }
|
||||
+ @Nullable
|
||||
+ public net.minecraftforge.client.ISkyRenderHandler getSkyRenderHandler() {
|
||||
+ return skyRenderHandler;
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
-public abstract class DimensionSpecialEffects {
|
||||
+public abstract class DimensionSpecialEffects implements net.minecraftforge.client.extensions.IForgeDimensionSpecialEffects {
|
||||
private static final Object2ObjectMap<ResourceLocation, DimensionSpecialEffects> f_108857_ = Util.m_137469_(new Object2ObjectArrayMap<>(), (p_108881_) -> {
|
||||
DimensionSpecialEffects.OverworldEffects dimensionspecialeffects$overworldeffects = new DimensionSpecialEffects.OverworldEffects();
|
||||
p_108881_.defaultReturnValue(dimensionspecialeffects$overworldeffects);
|
||||
@@ -37,7 +_,7 @@
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static DimensionSpecialEffects m_108876_(DimensionType p_108877_) {
|
||||
- return f_108857_.get(p_108877_.f_63837_());
|
||||
+ return net.minecraftforge.client.DimensionSpecialEffectsManager.getForType(p_108877_.f_63837_());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -1,15 +1,14 @@
|
||||
--- a/net/minecraft/client/renderer/FogRenderer.java
|
||||
+++ b/net/minecraft/client/renderer/FogRenderer.java
|
||||
@@ -182,6 +_,13 @@
|
||||
@@ -182,6 +_,12 @@
|
||||
f_109012_ = f_109012_ * (1.0F - f7) + f_109012_ * f9 * f7;
|
||||
}
|
||||
|
||||
+ net.minecraftforge.client.event.EntityViewRenderEvent.FogColors event = new net.minecraftforge.client.event.EntityViewRenderEvent.FogColors(p_109019_, p_109020_, f_109010_, f_109011_, f_109012_);
|
||||
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event);
|
||||
+ Vector3f fogColor = net.minecraftforge.client.ForgeHooksClient.getFogColor(p_109019_, p_109020_, p_109021_, p_109022_, p_109023_, f_109010_, f_109011_, f_109012_);
|
||||
+
|
||||
+ f_109010_ = event.getRed();
|
||||
+ f_109011_ = event.getGreen();
|
||||
+ f_109012_ = event.getBlue();
|
||||
+ f_109010_ = fogColor.m_122239_();
|
||||
+ f_109011_ = fogColor.m_122260_();
|
||||
+ f_109012_ = fogColor.m_122269_();
|
||||
+
|
||||
RenderSystem.m_69424_(f_109010_, f_109011_, f_109012_, 0.0F);
|
||||
}
|
||||
@@ -18,7 +17,7 @@
|
||||
RenderSystem.m_157445_(fogrenderer$fogdata.f_234200_);
|
||||
RenderSystem.m_157443_(fogrenderer$fogdata.f_234201_);
|
||||
RenderSystem.m_202160_(fogrenderer$fogdata.f_234202_);
|
||||
+ net.minecraftforge.client.ForgeHooksClient.onFogRender(fogtype, p_234173_, p_234177_, fogrenderer$fogdata.f_234200_, fogrenderer$fogdata.f_234201_, fogrenderer$fogdata.f_234202_);
|
||||
+ net.minecraftforge.client.ForgeHooksClient.onFogRender(p_234174_, fogtype, p_234173_, p_234177_, p_234175_, fogrenderer$fogdata.f_234200_, fogrenderer$fogdata.f_234201_, fogrenderer$fogdata.f_234202_);
|
||||
}
|
||||
|
||||
public static void m_109036_() {
|
||||
@@ -56,7 +56,7 @@
|
||||
}
|
||||
|
||||
- return d0;
|
||||
+ return net.minecraftforge.client.ForgeHooksClient.getFieldOfView(this, p_109142_, p_109143_, d0);
|
||||
+ return net.minecraftforge.client.ForgeHooksClient.getFieldOfView(this, p_109142_, p_109143_, d0, p_109144_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
this.m_109111_(matrix4f);
|
||||
camera.m_90575_(this.f_109059_.f_91073_, (Entity)(this.f_109059_.m_91288_() == null ? this.f_109059_.f_91074_ : this.f_109059_.m_91288_()), !this.f_109059_.f_91066_.m_92176_().m_90612_(), this.f_109059_.f_91066_.m_92176_().m_90613_(), p_109090_);
|
||||
+
|
||||
+ net.minecraftforge.client.event.EntityViewRenderEvent.CameraSetup cameraSetup = net.minecraftforge.client.ForgeHooksClient.onCameraSetup(this, camera, p_109090_);
|
||||
+ net.minecraftforge.client.event.ViewportEvent.ComputeCameraAngles cameraSetup = net.minecraftforge.client.ForgeHooksClient.onCameraSetup(this, camera, p_109090_);
|
||||
+ camera.setAnglesInternal(cameraSetup.getYaw(), cameraSetup.getPitch());
|
||||
+ p_109092_.m_85845_(Vector3f.f_122227_.m_122240_(cameraSetup.getRoll()));
|
||||
+
|
||||
|
||||
@@ -16,86 +16,103 @@
|
||||
private static final Map<Fluid, RenderType> f_109276_ = Util.m_137469_(Maps.newHashMap(), (p_109290_) -> {
|
||||
RenderType rendertype = RenderType.m_110466_();
|
||||
p_109290_.put(Fluids.f_76192_, rendertype);
|
||||
@@ -303,6 +_,7 @@
|
||||
@@ -303,6 +_,8 @@
|
||||
});
|
||||
private static boolean f_109277_;
|
||||
|
||||
+ @Deprecated // FORGE: Use canRenderInLayer
|
||||
+ /** @deprecated Forge: Use {@link net.minecraft.client.resources.model.BakedModel#getRenderTypes(BlockState, net.minecraft.util.RandomSource, net.minecraftforge.client.model.data.ModelData)}. */
|
||||
+ @Deprecated // Note: this method does NOT support model-based render types
|
||||
public static RenderType m_109282_(BlockState p_109283_) {
|
||||
Block block = p_109283_.m_60734_();
|
||||
if (block instanceof LeavesBlock) {
|
||||
@@ -313,6 +_,7 @@
|
||||
@@ -313,6 +_,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ @Deprecated // FORGE: Use canRenderInLayer
|
||||
+ /** @deprecated Forge: Use {@link net.minecraftforge.client.RenderTypeHelper#getMovingBlockRenderType(RenderType)} while iterating through {@link net.minecraft.client.resources.model.BakedModel#getRenderTypes(BlockState, net.minecraft.util.RandomSource, net.minecraftforge.client.model.data.ModelData)}. */
|
||||
+ @Deprecated // Note: this method does NOT support model-based render types
|
||||
public static RenderType m_109293_(BlockState p_109294_) {
|
||||
Block block = p_109294_.m_60734_();
|
||||
if (block instanceof LeavesBlock) {
|
||||
@@ -328,8 +_,7 @@
|
||||
}
|
||||
|
||||
public static RenderType m_109284_(BlockState p_109285_, boolean p_109286_) {
|
||||
- RenderType rendertype = m_109282_(p_109285_);
|
||||
- if (rendertype == RenderType.m_110466_()) {
|
||||
+ if (canRenderInLayer(p_109285_, RenderType.m_110466_())) {
|
||||
if (!Minecraft.m_91085_()) {
|
||||
return Sheets.m_110792_();
|
||||
} else {
|
||||
@@ -350,9 +_,68 @@
|
||||
@@ -327,6 +_,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ @Deprecated // FORGE: Use canRenderInLayer
|
||||
+ /** @deprecated Forge: Use {@link net.minecraftforge.client.RenderTypeHelper#getEntityRenderType(RenderType, boolean)} while iterating through {@link net.minecraft.client.resources.model.BakedModel#getRenderTypes(BlockState, net.minecraft.util.RandomSource, net.minecraftforge.client.model.data.ModelData)}. */
|
||||
+ @Deprecated // Note: this method does NOT support model-based render types
|
||||
public static RenderType m_109284_(BlockState p_109285_, boolean p_109286_) {
|
||||
RenderType rendertype = m_109282_(p_109285_);
|
||||
if (rendertype == RenderType.m_110466_()) {
|
||||
@@ -340,6 +_,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ /** @deprecated Forge: Use {@link net.minecraft.client.resources.model.BakedModel#getRenderPasses(ItemStack, boolean)} and {@link net.minecraft.client.resources.model.BakedModel#getRenderTypes(ItemStack, boolean)}. */
|
||||
+ @Deprecated // Note: this method does NOT support model-based render types
|
||||
public static RenderType m_109279_(ItemStack p_109280_, boolean p_109281_) {
|
||||
Item item = p_109280_.m_41720_();
|
||||
if (item instanceof BlockItem) {
|
||||
@@ -351,8 +_,73 @@
|
||||
}
|
||||
|
||||
public static RenderType m_109287_(FluidState p_109288_) {
|
||||
RenderType rendertype = f_109276_.get(p_109288_.m_76152_());
|
||||
- RenderType rendertype = f_109276_.get(p_109288_.m_76152_());
|
||||
+ RenderType rendertype = FLUID_RENDER_TYPES.get(net.minecraftforge.registries.ForgeRegistries.FLUIDS.getDelegateOrThrow(p_109288_.m_76152_()));
|
||||
return rendertype != null ? rendertype : RenderType.m_110451_();
|
||||
+ }
|
||||
+
|
||||
+ // FORGE START
|
||||
+
|
||||
+ private static final java.util.function.Predicate<RenderType> SOLID_PREDICATE = type -> type == RenderType.m_110451_();
|
||||
+ private static final Map<net.minecraft.core.Holder.Reference<Block>, java.util.function.Predicate<RenderType>> blockRenderChecks = createRenderCheckMap(net.minecraftforge.registries.ForgeRegistries.BLOCKS, f_109275_);
|
||||
+ private static final Map<net.minecraft.core.Holder.Reference<Fluid>, java.util.function.Predicate<RenderType>> fluidRenderChecks = createRenderCheckMap(net.minecraftforge.registries.ForgeRegistries.FLUIDS, f_109276_);
|
||||
+ private static final net.minecraftforge.client.ChunkRenderTypeSet CUTOUT_MIPPED = net.minecraftforge.client.ChunkRenderTypeSet.of(RenderType.m_110457_());
|
||||
+ private static final net.minecraftforge.client.ChunkRenderTypeSet SOLID = net.minecraftforge.client.ChunkRenderTypeSet.of(RenderType.m_110451_());
|
||||
+ private static final Map<net.minecraft.core.Holder.Reference<Block>, net.minecraftforge.client.ChunkRenderTypeSet> BLOCK_RENDER_TYPES = Util.m_137469_(new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(f_109275_.size(), 0.5F), map -> {
|
||||
+ map.defaultReturnValue(SOLID);
|
||||
+ for(Map.Entry<Block, RenderType> entry : f_109275_.entrySet()) {
|
||||
+ map.put(net.minecraftforge.registries.ForgeRegistries.BLOCKS.getDelegateOrThrow(entry.getKey()), net.minecraftforge.client.ChunkRenderTypeSet.of(entry.getValue()));
|
||||
+ }
|
||||
+ });
|
||||
+ private static final Map<net.minecraft.core.Holder.Reference<Fluid>, RenderType> FLUID_RENDER_TYPES = Util.m_137469_(new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(f_109276_.size(), 0.5F), map -> {
|
||||
+ map.defaultReturnValue(RenderType.m_110451_());
|
||||
+ for(Map.Entry<Fluid, RenderType> entry : f_109276_.entrySet()) {
|
||||
+ map.put(net.minecraftforge.registries.ForgeRegistries.FLUIDS.getDelegateOrThrow(entry.getKey()), entry.getValue());
|
||||
+ }
|
||||
+ });
|
||||
+
|
||||
+ private static <T> Map<net.minecraft.core.Holder.Reference<T>, java.util.function.Predicate<RenderType>> createRenderCheckMap(net.minecraftforge.registries.IForgeRegistry<T> registry, Map<T, RenderType> vanillaMap) {
|
||||
+ return Util.m_137469_(new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(vanillaMap.size(), 0.5F), map -> {
|
||||
+ map.defaultReturnValue(SOLID_PREDICATE);
|
||||
+ for(Map.Entry<T, RenderType> entry : vanillaMap.entrySet()) {
|
||||
+ map.put(registry.getDelegateOrThrow(entry.getKey()), createMatchingLayerPredicate(entry.getValue()));
|
||||
+ }
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ public static boolean canRenderInLayer(BlockState state, RenderType type) {
|
||||
+ /** @deprecated Use {@link net.minecraft.client.resources.model.BakedModel#getRenderTypes(BlockState, net.minecraft.util.RandomSource, net.minecraftforge.client.model.data.ModelData)}. */
|
||||
+ @Deprecated(forRemoval = true, since = "1.19")
|
||||
+ public static net.minecraftforge.client.ChunkRenderTypeSet getRenderLayers(BlockState state) {
|
||||
+ Block block = state.m_60734_();
|
||||
+ if (block instanceof LeavesBlock) {
|
||||
+ return f_109277_ ? type == RenderType.m_110457_() : type == RenderType.m_110451_();
|
||||
+ return f_109277_ ? CUTOUT_MIPPED : SOLID;
|
||||
+ } else {
|
||||
+ return blockRenderChecks.get(net.minecraftforge.registries.ForgeRegistries.BLOCKS.getDelegateOrThrow(block)).test(type);
|
||||
+ return BLOCK_RENDER_TYPES.get(net.minecraftforge.registries.ForgeRegistries.BLOCKS.getDelegateOrThrow(block));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public static boolean canRenderInLayer(FluidState fluid, RenderType type) {
|
||||
+ return fluidRenderChecks.get(net.minecraftforge.registries.ForgeRegistries.FLUIDS.getDelegateOrThrow(fluid.m_76152_())).test(type);
|
||||
+ }
|
||||
+
|
||||
+ /** @deprecated Set your render type in your block model's JSON (eg. {@code "render_type": "cutout"}) or override {@link net.minecraft.client.resources.model.BakedModel#getRenderTypes(BlockState, net.minecraft.util.RandomSource, net.minecraftforge.client.model.data.ModelData)} */
|
||||
+ @Deprecated(forRemoval = true, since = "1.19")
|
||||
+ public static void setRenderLayer(Block block, RenderType type) {
|
||||
+ setRenderLayer(block, createMatchingLayerPredicate(type));
|
||||
+ com.google.common.base.Preconditions.checkArgument(type.getChunkLayerId() >= 0, "The argument must be a valid chunk render type returned by RenderType#chunkBufferLayers().");
|
||||
+ setRenderLayer(block, net.minecraftforge.client.ChunkRenderTypeSet.of(type));
|
||||
+ }
|
||||
+
|
||||
+ /** @deprecated Set your render type in your block model's JSON (eg. {@code "render_type": "cutout"}) or override {@link net.minecraft.client.resources.model.BakedModel#getRenderTypes(BlockState, net.minecraft.util.RandomSource, net.minecraftforge.client.model.data.ModelData)} */
|
||||
+ @Deprecated(forRemoval = true, since = "1.19")
|
||||
+ public static synchronized void setRenderLayer(Block block, java.util.function.Predicate<RenderType> predicate) {
|
||||
+ setRenderLayer(block, createSetFromPredicate(predicate));
|
||||
+ }
|
||||
+
|
||||
+ /** @deprecated Set your render type in your block model's JSON (eg. {@code "render_type": "cutout"}) or override {@link net.minecraft.client.resources.model.BakedModel#getRenderTypes(BlockState, net.minecraft.util.RandomSource, net.minecraftforge.client.model.data.ModelData)} */
|
||||
+ @Deprecated(forRemoval = true, since = "1.19")
|
||||
+ public static synchronized void setRenderLayer(Block block, net.minecraftforge.client.ChunkRenderTypeSet layers) {
|
||||
+ checkClientLoading();
|
||||
+ blockRenderChecks.put(net.minecraftforge.registries.ForgeRegistries.BLOCKS.getDelegateOrThrow(block), predicate);
|
||||
+ BLOCK_RENDER_TYPES.put(net.minecraftforge.registries.ForgeRegistries.BLOCKS.getDelegateOrThrow(block), layers);
|
||||
+ }
|
||||
+
|
||||
+ public static void setRenderLayer(Fluid fluid, RenderType type) {
|
||||
+ setRenderLayer(fluid, createMatchingLayerPredicate(type));
|
||||
+ }
|
||||
+
|
||||
+ public static synchronized void setRenderLayer(Fluid fluid, java.util.function.Predicate<RenderType> predicate) {
|
||||
+ com.google.common.base.Preconditions.checkArgument(type.getChunkLayerId() >= 0, "The argument must be a valid chunk render type returned by RenderType#chunkBufferLayers().");
|
||||
+ checkClientLoading();
|
||||
+ fluidRenderChecks.put(net.minecraftforge.registries.ForgeRegistries.FLUIDS.getDelegateOrThrow(fluid), predicate);
|
||||
+ FLUID_RENDER_TYPES.put(net.minecraftforge.registries.ForgeRegistries.FLUIDS.getDelegateOrThrow(fluid), type);
|
||||
+ }
|
||||
+
|
||||
+ private static void checkClientLoading() {
|
||||
@@ -105,9 +122,8 @@
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
+ private static java.util.function.Predicate<RenderType> createMatchingLayerPredicate(RenderType type) {
|
||||
+ java.util.Objects.requireNonNull(type);
|
||||
+ return type::equals;
|
||||
+ private static net.minecraftforge.client.ChunkRenderTypeSet createSetFromPredicate(java.util.function.Predicate<RenderType> predicate) {
|
||||
+ return net.minecraftforge.client.ChunkRenderTypeSet.of(RenderType.m_110506_().stream().filter(predicate).toArray(RenderType[]::new));
|
||||
}
|
||||
|
||||
public static void m_109291_(boolean p_109292_) {
|
||||
@@ -1,30 +1,24 @@
|
||||
--- a/net/minecraft/client/renderer/LevelRenderer.java
|
||||
+++ b/net/minecraft/client/renderer/LevelRenderer.java
|
||||
@@ -263,6 +_,11 @@
|
||||
@@ -263,6 +_,8 @@
|
||||
}
|
||||
|
||||
private void m_109703_(LightTexture p_109704_, float p_109705_, double p_109706_, double p_109707_, double p_109708_) {
|
||||
+ net.minecraftforge.client.IWeatherRenderHandler renderHandler = f_109465_.m_104583_().getWeatherRenderHandler();
|
||||
+ if (renderHandler != null) {
|
||||
+ renderHandler.render(f_109477_, p_109705_, f_109465_, f_109461_, p_109704_, p_109706_, p_109707_, p_109708_);
|
||||
+ if (f_109465_.m_104583_().renderSnowAndRain(f_109465_, f_109477_, p_109705_, p_109704_, p_109706_, p_109707_, p_109708_))
|
||||
+ return;
|
||||
+ }
|
||||
float f = this.f_109461_.f_91073_.m_46722_(p_109705_);
|
||||
if (!(f <= 0.0F)) {
|
||||
p_109704_.m_109896_();
|
||||
@@ -383,6 +_,11 @@
|
||||
@@ -383,6 +_,8 @@
|
||||
}
|
||||
|
||||
public void m_109693_(Camera p_109694_) {
|
||||
+ net.minecraftforge.client.IWeatherParticleRenderHandler renderHandler = f_109465_.m_104583_().getWeatherParticleRenderHandler();
|
||||
+ if (renderHandler != null) {
|
||||
+ renderHandler.render(f_109477_, f_109465_, f_109461_, p_109694_);
|
||||
+ if (f_109465_.m_104583_().tickRain(f_109465_, f_109477_, p_109694_))
|
||||
+ return;
|
||||
+ }
|
||||
float f = this.f_109461_.f_91073_.m_46722_(1.0F) / (Minecraft.m_91405_() ? 1.0F : 2.0F);
|
||||
if (!(f <= 0.0F)) {
|
||||
RandomSource randomsource = RandomSource.m_216335_((long)this.f_109477_ * 312987231L);
|
||||
@@ -1140,6 +_,7 @@
|
||||
@@ -1140,11 +_,13 @@
|
||||
RenderSystem.m_69421_(16640, Minecraft.f_91002_);
|
||||
float f = p_109605_.m_109152_();
|
||||
boolean flag2 = this.f_109461_.f_91073_.m_104583_().m_5781_(Mth.m_14107_(d0), Mth.m_14107_(d1)) || this.f_109461_.f_91065_.m_93090_().m_93715_();
|
||||
@@ -32,6 +26,12 @@
|
||||
profilerfiller.m_6182_("sky");
|
||||
RenderSystem.m_157427_(GameRenderer::m_172808_);
|
||||
this.m_202423_(p_109600_, p_109607_, p_109601_, p_109604_, flag2, () -> {
|
||||
FogRenderer.m_234172_(p_109604_, FogRenderer.FogMode.FOG_SKY, f, flag2, p_109601_);
|
||||
});
|
||||
+ net.minecraftforge.client.ForgeHooksClient.dispatchRenderStage(net.minecraftforge.client.event.RenderLevelStageEvent.Stage.AFTER_SKY, this, p_109600_, p_109607_, this.f_109477_, p_109604_, frustum);
|
||||
profilerfiller.m_6182_("fog");
|
||||
FogRenderer.m_234172_(p_109604_, FogRenderer.FogMode.FOG_TERRAIN, Math.max(f, 32.0F), flag2, p_109601_);
|
||||
profilerfiller.m_6182_("terrain_setup");
|
||||
@@ -1153,7 +_,9 @@
|
||||
this.m_194370_(p_109604_);
|
||||
profilerfiller.m_6182_("terrain");
|
||||
@@ -67,6 +67,16 @@
|
||||
BlockPos blockpos3 = blockentity.m_58899_();
|
||||
p_109600_.m_85836_();
|
||||
p_109600_.m_85837_((double)blockpos3.m_123341_() - d0, (double)blockpos3.m_123342_() - d1, (double)blockpos3.m_123343_() - d2);
|
||||
@@ -1289,7 +_,8 @@
|
||||
p_109600_.m_85837_((double)blockpos2.m_123341_() - d0, (double)blockpos2.m_123342_() - d1, (double)blockpos2.m_123343_() - d2);
|
||||
PoseStack.Pose posestack$pose = p_109600_.m_85850_();
|
||||
VertexConsumer vertexconsumer1 = new SheetedDecalTextureGenerator(this.f_109464_.m_110108_().m_6299_(ModelBakery.f_119229_.get(k1)), posestack$pose.m_85861_(), posestack$pose.m_85864_());
|
||||
- this.f_109461_.m_91289_().m_110918_(this.f_109465_.m_8055_(blockpos2), blockpos2, this.f_109465_, p_109600_, vertexconsumer1);
|
||||
+ net.minecraftforge.client.model.data.ModelData modelData = f_109465_.getModelDataManager().getAt(blockpos2);
|
||||
+ this.f_109461_.m_91289_().renderBreakingTexture(this.f_109465_.m_8055_(blockpos2), blockpos2, this.f_109465_, p_109600_, vertexconsumer1, modelData == null ? net.minecraftforge.client.model.data.ModelData.EMPTY : modelData);
|
||||
p_109600_.m_85849_();
|
||||
}
|
||||
}
|
||||
@@ -1301,10 +_,13 @@
|
||||
profilerfiller.m_6182_("outline");
|
||||
BlockPos blockpos1 = ((BlockHitResult)hitresult).m_82425_();
|
||||
@@ -81,45 +91,65 @@
|
||||
}
|
||||
|
||||
PoseStack posestack = RenderSystem.m_157191_();
|
||||
@@ -1339,7 +_,7 @@
|
||||
@@ -1339,7 +_,8 @@
|
||||
this.f_109415_.m_83945_(this.f_109461_.m_91385_());
|
||||
RenderStateShard.f_110126_.m_110185_();
|
||||
profilerfiller.m_6182_("particles");
|
||||
- this.f_109461_.f_91061_.m_107336_(p_109600_, multibuffersource$buffersource, p_109606_, p_109604_, p_109601_);
|
||||
+ this.f_109461_.f_91061_.render(p_109600_, multibuffersource$buffersource, p_109606_, p_109604_, p_109601_, frustum);
|
||||
+ net.minecraftforge.client.ForgeHooksClient.dispatchRenderStage(net.minecraftforge.client.event.RenderLevelStageEvent.Stage.AFTER_PARTICLES, this, p_109600_, p_109607_, this.f_109477_, p_109604_, frustum);
|
||||
RenderStateShard.f_110126_.m_110188_();
|
||||
} else {
|
||||
profilerfiller.m_6182_("translucent");
|
||||
@@ -1353,7 +_,7 @@
|
||||
@@ -1353,7 +_,8 @@
|
||||
profilerfiller.m_6182_("string");
|
||||
this.m_172993_(RenderType.m_110503_(), p_109600_, d0, d1, d2, p_109607_);
|
||||
profilerfiller.m_6182_("particles");
|
||||
- this.f_109461_.f_91061_.m_107336_(p_109600_, multibuffersource$buffersource, p_109606_, p_109604_, p_109601_);
|
||||
+ this.f_109461_.f_91061_.render(p_109600_, multibuffersource$buffersource, p_109606_, p_109604_, p_109601_, frustum);
|
||||
+ net.minecraftforge.client.ForgeHooksClient.dispatchRenderStage(net.minecraftforge.client.event.RenderLevelStageEvent.Stage.AFTER_PARTICLES, this, p_109600_, p_109607_, this.f_109477_, p_109604_, frustum);
|
||||
}
|
||||
|
||||
posestack.m_85836_();
|
||||
@@ -1781,6 +_,11 @@
|
||||
@@ -1377,6 +_,7 @@
|
||||
RenderStateShard.f_110127_.m_110185_();
|
||||
profilerfiller.m_6182_("weather");
|
||||
this.m_109703_(p_109606_, p_109601_, d0, d1, d2);
|
||||
+ net.minecraftforge.client.ForgeHooksClient.dispatchRenderStage(net.minecraftforge.client.event.RenderLevelStageEvent.Stage.AFTER_WEATHER, this, p_109600_, p_109607_, this.f_109477_, p_109604_, frustum);
|
||||
this.m_173012_(p_109604_);
|
||||
RenderStateShard.f_110127_.m_110188_();
|
||||
this.f_109418_.m_110023_(p_109601_);
|
||||
@@ -1385,6 +_,7 @@
|
||||
RenderSystem.m_69458_(false);
|
||||
profilerfiller.m_6182_("weather");
|
||||
this.m_109703_(p_109606_, p_109601_, d0, d1, d2);
|
||||
+ net.minecraftforge.client.ForgeHooksClient.dispatchRenderStage(net.minecraftforge.client.event.RenderLevelStageEvent.Stage.AFTER_WEATHER, this, p_109600_, p_109607_, this.f_109477_, p_109604_, frustum);
|
||||
this.m_173012_(p_109604_);
|
||||
RenderSystem.m_69458_(true);
|
||||
}
|
||||
@@ -1519,6 +_,7 @@
|
||||
shaderinstance.m_173362_();
|
||||
VertexBuffer.m_85931_();
|
||||
this.f_109461_.m_91307_().m_7238_();
|
||||
+ net.minecraftforge.client.ForgeHooksClient.dispatchRenderStage(p_172994_, this, p_172995_, p_172999_, this.f_109477_, this.f_109461_.f_91063_.m_109153_(), this.f_109442_ != null ? this.f_109442_ : this.f_172938_);
|
||||
p_172994_.m_110188_();
|
||||
}
|
||||
|
||||
@@ -1780,6 +_,8 @@
|
||||
}
|
||||
|
||||
public void m_202423_(PoseStack p_202424_, Matrix4f p_202425_, float p_202426_, Camera p_202427_, boolean p_202428_, Runnable p_202429_) {
|
||||
p_202429_.run();
|
||||
+ net.minecraftforge.client.ISkyRenderHandler renderHandler = f_109465_.m_104583_().getSkyRenderHandler();
|
||||
+ if (renderHandler != null) {
|
||||
+ renderHandler.render(f_109477_, p_202426_, p_202424_, f_109465_, f_109461_);
|
||||
+ if (f_109465_.m_104583_().renderSky(f_109465_, f_109477_, p_202426_, p_202424_, p_202427_, p_202425_, p_202428_, p_202429_))
|
||||
+ return;
|
||||
+ }
|
||||
p_202429_.run();
|
||||
if (!p_202428_) {
|
||||
FogType fogtype = p_202427_.m_167685_();
|
||||
if (fogtype != FogType.POWDER_SNOW && fogtype != FogType.LAVA && !this.m_234310_(p_202427_)) {
|
||||
@@ -1912,6 +_,11 @@
|
||||
@@ -1912,6 +_,8 @@
|
||||
}
|
||||
|
||||
public void m_172954_(PoseStack p_172955_, Matrix4f p_172956_, float p_172957_, double p_172958_, double p_172959_, double p_172960_) {
|
||||
+ net.minecraftforge.client.ICloudRenderHandler renderHandler = f_109465_.m_104583_().getCloudRenderHandler();
|
||||
+ if (renderHandler != null) {
|
||||
+ renderHandler.render(f_109477_, p_172957_, p_172955_, f_109465_, f_109461_, p_172958_, p_172959_, p_172960_);
|
||||
+ if (f_109465_.m_104583_().renderClouds(f_109465_, f_109477_, p_172957_, p_172955_, p_172958_, p_172959_, p_172960_, p_172956_))
|
||||
+ return;
|
||||
+ }
|
||||
float f = this.f_109465_.m_104583_().m_108871_();
|
||||
if (!Float.isNaN(f)) {
|
||||
RenderSystem.m_69464_();
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
--- a/net/minecraft/client/renderer/LightTexture.java
|
||||
+++ b/net/minecraft/client/renderer/LightTexture.java
|
||||
@@ -138,6 +_,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ clientlevel.m_104583_().adjustLightmapColors(clientlevel, p_109882_, f, f7, f8, j, i, vector3f1);
|
||||
+
|
||||
if (f5 > 0.0F) {
|
||||
float f13 = Math.max(vector3f1.m_122239_(), Math.max(vector3f1.m_122260_(), vector3f1.m_122269_()));
|
||||
if (f13 < 1.0F) {
|
||||
@@ -193,7 +_,7 @@
|
||||
}
|
||||
|
||||
|
||||
@@ -34,3 +34,21 @@
|
||||
}
|
||||
|
||||
public static RenderType m_110502_() {
|
||||
@@ -608,4 +_,17 @@
|
||||
return this.f_110696_;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // FORGE START
|
||||
+ private int chunkLayerId = -1;
|
||||
+ /** {@return the unique ID of this {@link RenderType} for chunk rendering purposes, or {@literal -1} if this is not a chunk {@link RenderType}} */
|
||||
+ public final int getChunkLayerId() {
|
||||
+ return chunkLayerId;
|
||||
+ }
|
||||
+ static {
|
||||
+ int i = 0;
|
||||
+ for (var layer : m_110506_())
|
||||
+ layer.chunkLayerId = i++;
|
||||
+ }
|
||||
+ // FORGE END
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/client/renderer/ScreenEffectRenderer.java
|
||||
+++ b/net/minecraft/client/renderer/ScreenEffectRenderer.java
|
||||
@@ -30,18 +_,21 @@
|
||||
@@ -30,18 +_,22 @@
|
||||
public static void m_110718_(Minecraft p_110719_, PoseStack p_110720_) {
|
||||
Player player = p_110719_.f_91074_;
|
||||
if (!player.f_19794_) {
|
||||
@@ -9,7 +9,7 @@
|
||||
- m_173296_(p_110719_.m_91289_().m_110907_().m_110882_(blockstate), p_110720_);
|
||||
+ org.apache.commons.lang3.tuple.Pair<BlockState, BlockPos> overlay = getOverlayBlock(player);
|
||||
+ if (overlay != null) {
|
||||
+ if (!net.minecraftforge.client.ForgeHooksClient.renderBlockOverlay(player, p_110720_, net.minecraftforge.client.event.RenderBlockOverlayEvent.OverlayType.BLOCK, overlay.getLeft(), overlay.getRight()))
|
||||
+ if (!net.minecraftforge.client.ForgeHooksClient.renderBlockOverlay(player, p_110720_, net.minecraftforge.client.event.RenderBlockScreenEffectEvent.OverlayType.BLOCK, overlay.getLeft(), overlay.getRight()))
|
||||
+ m_173296_(p_110719_.m_91289_().m_110907_().getTexture(overlay.getLeft(), p_110719_.f_91073_, overlay.getRight()), p_110720_);
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@
|
||||
+ if (!net.minecraftforge.client.ForgeHooksClient.renderWaterOverlay(player, p_110720_))
|
||||
m_110725_(p_110719_, p_110720_);
|
||||
}
|
||||
+ else if (!player.getEyeInFluidType().isAir()) net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions.of(player.getEyeInFluidType()).renderOverlay(p_110719_, p_110720_);
|
||||
|
||||
if (p_110719_.f_91074_.m_6060_()) {
|
||||
+ if (!net.minecraftforge.client.ForgeHooksClient.renderFireOverlay(player, p_110720_))
|
||||
@@ -46,3 +47,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,9 +_,13 @@
|
||||
}
|
||||
|
||||
private static void m_110725_(Minecraft p_110726_, PoseStack p_110727_) {
|
||||
+ renderFluid(p_110726_, p_110727_, f_110714_);
|
||||
+ }
|
||||
+
|
||||
+ public static void renderFluid(Minecraft p_110726_, PoseStack p_110727_, ResourceLocation texture) {
|
||||
RenderSystem.m_157427_(GameRenderer::m_172817_);
|
||||
RenderSystem.m_69493_();
|
||||
- RenderSystem.m_157456_(0, f_110714_);
|
||||
+ RenderSystem.m_157456_(0, texture);
|
||||
BufferBuilder bufferbuilder = Tesselator.m_85913_().m_85915_();
|
||||
BlockPos blockpos = new BlockPos(p_110726_.f_91074_.m_20185_(), p_110726_.f_91074_.m_20188_(), p_110726_.f_91074_.m_20189_());
|
||||
float f = LightTexture.m_234316_(p_110726_.f_91074_.f_19853_.m_6042_(), p_110726_.f_91074_.f_19853_.m_46803_(blockpos));
|
||||
@@ -7,13 +7,13 @@
|
||||
+ @Deprecated
|
||||
public TextureAtlasSprite m_110882_(BlockState p_110883_) {
|
||||
- return this.m_110893_(p_110883_).m_6160_();
|
||||
+ return this.m_110893_(p_110883_).getParticleIcon(net.minecraftforge.client.model.data.EmptyModelData.INSTANCE);
|
||||
+ return this.m_110893_(p_110883_).getParticleIcon(net.minecraftforge.client.model.data.ModelData.EMPTY);
|
||||
+ }
|
||||
+
|
||||
+ public TextureAtlasSprite getTexture(BlockState p_110883_, net.minecraft.world.level.Level level, net.minecraft.core.BlockPos pos) {
|
||||
+ net.minecraftforge.client.model.data.IModelData data = net.minecraftforge.client.model.ModelDataManager.getModelData(level, pos);
|
||||
+ var data = level.getModelDataManager().getAt(pos);
|
||||
+ BakedModel model = this.m_110893_(p_110883_);
|
||||
+ return model.getParticleIcon(model.getModelData(level, pos, p_110883_, data == null ? net.minecraftforge.client.model.data.EmptyModelData.INSTANCE : data));
|
||||
+ return model.getParticleIcon(model.getModelData(level, pos, p_110883_, data == null ? net.minecraftforge.client.model.data.ModelData.EMPTY : data));
|
||||
}
|
||||
|
||||
public BakedModel m_110893_(BlockState p_110894_) {
|
||||
+16
-15
@@ -5,7 +5,7 @@
|
||||
this.f_173397_ = p_173400_;
|
||||
this.f_110903_ = p_173401_;
|
||||
- this.f_110900_ = new ModelBlockRenderer(this.f_110903_);
|
||||
+ this.f_110900_ = new net.minecraftforge.client.model.pipeline.ForgeBlockModelRenderer(this.f_110903_);
|
||||
+ this.f_110900_ = new net.minecraftforge.client.model.lighting.ForgeModelBlockRenderer(this.f_110903_);
|
||||
this.f_110901_ = new LiquidBlockRenderer();
|
||||
}
|
||||
|
||||
@@ -13,29 +13,29 @@
|
||||
return this.f_110899_;
|
||||
}
|
||||
|
||||
+ @Deprecated //Forge: Model parameter
|
||||
+ @Deprecated //Forge: Model data parameter
|
||||
public void m_110918_(BlockState p_110919_, BlockPos p_110920_, BlockAndTintGetter p_110921_, PoseStack p_110922_, VertexConsumer p_110923_) {
|
||||
+ renderBreakingTexture(p_110919_, p_110920_, p_110921_, p_110922_, p_110923_, net.minecraftforge.client.model.data.EmptyModelData.INSTANCE);
|
||||
+ renderBreakingTexture(p_110919_, p_110920_, p_110921_, p_110922_, p_110923_, net.minecraftforge.client.model.data.ModelData.EMPTY);
|
||||
+ }
|
||||
+ public void renderBreakingTexture(BlockState p_110919_, BlockPos p_110920_, BlockAndTintGetter p_110921_, PoseStack p_110922_, VertexConsumer p_110923_, net.minecraftforge.client.model.data.IModelData modelData) {
|
||||
+ public void renderBreakingTexture(BlockState p_110919_, BlockPos p_110920_, BlockAndTintGetter p_110921_, PoseStack p_110922_, VertexConsumer p_110923_, net.minecraftforge.client.model.data.ModelData modelData) {
|
||||
if (p_110919_.m_60799_() == RenderShape.MODEL) {
|
||||
BakedModel bakedmodel = this.f_110899_.m_110893_(p_110919_);
|
||||
long i = p_110919_.m_60726_(p_110920_);
|
||||
- this.f_110900_.m_234379_(p_110921_, bakedmodel, p_110919_, p_110920_, p_110922_, p_110923_, true, this.f_110902_, i, OverlayTexture.f_118083_);
|
||||
+ this.f_110900_.tesselateBlock(p_110921_, bakedmodel, p_110919_, p_110920_, p_110922_, p_110923_, true, this.f_110902_, i, OverlayTexture.f_118083_, modelData);
|
||||
+ this.f_110900_.tesselateBlock(p_110921_, bakedmodel, p_110919_, p_110920_, p_110922_, p_110923_, true, this.f_110902_, i, OverlayTexture.f_118083_, modelData, null);
|
||||
}
|
||||
}
|
||||
|
||||
+ @Deprecated //Forge: Model parameter
|
||||
+ @Deprecated //Forge: Model data and render type parameter
|
||||
public void m_234355_(BlockState p_234356_, BlockPos p_234357_, BlockAndTintGetter p_234358_, PoseStack p_234359_, VertexConsumer p_234360_, boolean p_234361_, RandomSource p_234362_) {
|
||||
+ renderBatched(p_234356_, p_234357_, p_234358_, p_234359_, p_234360_, p_234361_, p_234362_, net.minecraftforge.client.model.data.EmptyModelData.INSTANCE);
|
||||
+ renderBatched(p_234356_, p_234357_, p_234358_, p_234359_, p_234360_, p_234361_, p_234362_, net.minecraftforge.client.model.data.ModelData.EMPTY, null);
|
||||
+ }
|
||||
+ public void renderBatched(BlockState p_234356_, BlockPos p_234357_, BlockAndTintGetter p_234358_, PoseStack p_234359_, VertexConsumer p_234360_, boolean p_234361_, RandomSource p_234362_, net.minecraftforge.client.model.data.IModelData modelData) {
|
||||
+ public void renderBatched(BlockState p_234356_, BlockPos p_234357_, BlockAndTintGetter p_234358_, PoseStack p_234359_, VertexConsumer p_234360_, boolean p_234361_, RandomSource p_234362_, net.minecraftforge.client.model.data.ModelData modelData, net.minecraft.client.renderer.RenderType renderType) {
|
||||
try {
|
||||
RenderShape rendershape = p_234356_.m_60799_();
|
||||
if (rendershape == RenderShape.MODEL) {
|
||||
- this.f_110900_.m_234379_(p_234358_, this.m_110910_(p_234356_), p_234356_, p_234357_, p_234359_, p_234360_, p_234361_, p_234362_, p_234356_.m_60726_(p_234357_), OverlayTexture.f_118083_);
|
||||
+ this.f_110900_.tesselateBlock(p_234358_, this.m_110910_(p_234356_), p_234356_, p_234357_, p_234359_, p_234360_, p_234361_, p_234362_, p_234356_.m_60726_(p_234357_), OverlayTexture.f_118083_, modelData);
|
||||
+ this.f_110900_.tesselateBlock(p_234358_, this.m_110910_(p_234356_), p_234356_, p_234357_, p_234359_, p_234360_, p_234361_, p_234362_, p_234356_.m_60726_(p_234357_), OverlayTexture.f_118083_, modelData, renderType);
|
||||
}
|
||||
|
||||
} catch (Throwable throwable) {
|
||||
@@ -43,25 +43,26 @@
|
||||
return this.f_110899_.m_110893_(p_110911_);
|
||||
}
|
||||
|
||||
+ @Deprecated //Forge: Model parameter
|
||||
+ @Deprecated //Forge: Model data and render type parameter
|
||||
public void m_110912_(BlockState p_110913_, PoseStack p_110914_, MultiBufferSource p_110915_, int p_110916_, int p_110917_) {
|
||||
+ renderSingleBlock(p_110913_, p_110914_, p_110915_, p_110916_, p_110917_, net.minecraftforge.client.model.data.EmptyModelData.INSTANCE);
|
||||
+ renderSingleBlock(p_110913_, p_110914_, p_110915_, p_110916_, p_110917_, net.minecraftforge.client.model.data.ModelData.EMPTY, null);
|
||||
+ }
|
||||
+ public void renderSingleBlock(BlockState p_110913_, PoseStack p_110914_, MultiBufferSource p_110915_, int p_110916_, int p_110917_, net.minecraftforge.client.model.data.IModelData modelData) {
|
||||
+ public void renderSingleBlock(BlockState p_110913_, PoseStack p_110914_, MultiBufferSource p_110915_, int p_110916_, int p_110917_, net.minecraftforge.client.model.data.ModelData modelData, net.minecraft.client.renderer.RenderType renderType) {
|
||||
RenderShape rendershape = p_110913_.m_60799_();
|
||||
if (rendershape != RenderShape.INVISIBLE) {
|
||||
switch (rendershape) {
|
||||
@@ -97,10 +_,11 @@
|
||||
@@ -97,10 +_,12 @@
|
||||
float f = (float)(i >> 16 & 255) / 255.0F;
|
||||
float f1 = (float)(i >> 8 & 255) / 255.0F;
|
||||
float f2 = (float)(i & 255) / 255.0F;
|
||||
- this.f_110900_.m_111067_(p_110914_.m_85850_(), p_110915_.m_6299_(ItemBlockRenderTypes.m_109284_(p_110913_, false)), p_110913_, bakedmodel, f, f1, f2, p_110916_, p_110917_);
|
||||
+ this.f_110900_.renderModel(p_110914_.m_85850_(), p_110915_.m_6299_(ItemBlockRenderTypes.m_109284_(p_110913_, false)), p_110913_, bakedmodel, f, f1, f2, p_110916_, p_110917_, modelData);
|
||||
+ for (net.minecraft.client.renderer.RenderType rt : bakedmodel.getRenderTypes(p_110913_, RandomSource.m_216335_(42), modelData))
|
||||
+ this.f_110900_.renderModel(p_110914_.m_85850_(), p_110915_.m_6299_(renderType != null ? renderType : net.minecraftforge.client.RenderTypeHelper.getEntityRenderType(rt, false)), p_110913_, bakedmodel, f, f1, f2, p_110916_, p_110917_, modelData, rt);
|
||||
break;
|
||||
case ENTITYBLOCK_ANIMATED:
|
||||
- this.f_173397_.m_108829_(new ItemStack(p_110913_.m_60734_()), ItemTransforms.TransformType.NONE, p_110914_, p_110915_, p_110916_, p_110917_);
|
||||
+ ItemStack stack = new ItemStack(p_110913_.m_60734_());
|
||||
+ net.minecraftforge.client.RenderProperties.get(stack).getItemStackRenderer().m_108829_(stack, ItemTransforms.TransformType.NONE, p_110914_, p_110915_, p_110916_, p_110917_);
|
||||
+ net.minecraftforge.client.extensions.common.IClientItemExtensions.of(stack).getCustomRenderer().m_108829_(stack, ItemTransforms.TransformType.NONE, p_110914_, p_110915_, p_110916_, p_110917_);
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
- TextureAtlasSprite[] atextureatlassprite = flag ? this.f_110940_ : this.f_110941_;
|
||||
- int i = flag ? 16777215 : BiomeColors.m_108811_(p_234370_, p_234371_);
|
||||
+ TextureAtlasSprite[] atextureatlassprite = net.minecraftforge.client.ForgeHooksClient.getFluidSprites(p_234370_, p_234371_, p_234374_);
|
||||
+ int i = p_234374_.m_76152_().getAttributes().getColor(p_234370_, p_234371_);
|
||||
+ int i = net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions.of(p_234374_).getTintColor(p_234374_, p_234370_, p_234371_);
|
||||
+ float alpha = (float)(i >> 24 & 255) / 255.0F;
|
||||
float f = (float)(i >> 16 & 255) / 255.0F;
|
||||
float f1 = (float)(i >> 8 & 255) / 255.0F;
|
||||
|
||||
+21
-21
@@ -4,15 +4,15 @@
|
||||
this.f_110995_ = p_110999_;
|
||||
}
|
||||
|
||||
+ @Deprecated //Forge: Model data argument
|
||||
+ @Deprecated //Forge: Model data and render type parameter
|
||||
public void m_234379_(BlockAndTintGetter p_234380_, BakedModel p_234381_, BlockState p_234382_, BlockPos p_234383_, PoseStack p_234384_, VertexConsumer p_234385_, boolean p_234386_, RandomSource p_234387_, long p_234388_, int p_234389_) {
|
||||
- boolean flag = Minecraft.m_91086_() && p_234382_.m_60791_() == 0 && p_234381_.m_7541_();
|
||||
- Vec3 vec3 = p_234382_.m_60824_(p_234380_, p_234383_);
|
||||
- p_234384_.m_85837_(vec3.f_82479_, vec3.f_82480_, vec3.f_82481_);
|
||||
+ tesselateBlock(p_234380_, p_234381_, p_234382_, p_234383_, p_234384_, p_234385_, p_234386_, p_234387_, p_234388_, p_234389_, net.minecraftforge.client.model.data.EmptyModelData.INSTANCE);
|
||||
+ tesselateBlock(p_234380_, p_234381_, p_234382_, p_234383_, p_234384_, p_234385_, p_234386_, p_234387_, p_234388_, p_234389_, net.minecraftforge.client.model.data.ModelData.EMPTY, null);
|
||||
+ }
|
||||
+ public void tesselateBlock(BlockAndTintGetter p_111048_, BakedModel p_111049_, BlockState p_111050_, BlockPos p_111051_, PoseStack p_111052_, VertexConsumer p_111053_, boolean p_111054_, RandomSource p_111055_, long p_111056_, int p_111057_, net.minecraftforge.client.model.data.IModelData modelData) {
|
||||
+ boolean flag = Minecraft.m_91086_() && p_111050_.getLightEmission(p_111048_, p_111051_) == 0 && p_111049_.m_7541_();
|
||||
+ public void tesselateBlock(BlockAndTintGetter p_111048_, BakedModel p_111049_, BlockState p_111050_, BlockPos p_111051_, PoseStack p_111052_, VertexConsumer p_111053_, boolean p_111054_, RandomSource p_111055_, long p_111056_, int p_111057_, net.minecraftforge.client.model.data.ModelData modelData, net.minecraft.client.renderer.RenderType renderType) {
|
||||
+ boolean flag = Minecraft.m_91086_() && p_111050_.getLightEmission(p_111048_, p_111051_) == 0 && p_111049_.useAmbientOcclusion(p_111050_, renderType);
|
||||
+ Vec3 vec3 = p_111050_.m_60824_(p_111048_, p_111051_);
|
||||
+ p_111052_.m_85837_(vec3.f_82479_, vec3.f_82480_, vec3.f_82481_);
|
||||
+ modelData = p_111049_.getModelData(p_111048_, p_111051_, p_111050_, modelData);
|
||||
@@ -20,10 +20,10 @@
|
||||
try {
|
||||
if (flag) {
|
||||
- this.m_234390_(p_234380_, p_234381_, p_234382_, p_234383_, p_234384_, p_234385_, p_234386_, p_234387_, p_234388_, p_234389_);
|
||||
+ this.tesselateWithAO(p_111048_, p_111049_, p_111050_, p_111051_, p_111052_, p_111053_, p_111054_, p_111055_, p_111056_, p_111057_, modelData);
|
||||
+ this.tesselateWithAO(p_111048_, p_111049_, p_111050_, p_111051_, p_111052_, p_111053_, p_111054_, p_111055_, p_111056_, p_111057_, modelData, renderType);
|
||||
} else {
|
||||
- this.m_234401_(p_234380_, p_234381_, p_234382_, p_234383_, p_234384_, p_234385_, p_234386_, p_234387_, p_234388_, p_234389_);
|
||||
+ this.tesselateWithoutAO(p_111048_, p_111049_, p_111050_, p_111051_, p_111052_, p_111053_, p_111054_, p_111055_, p_111056_, p_111057_, modelData);
|
||||
+ this.tesselateWithoutAO(p_111048_, p_111049_, p_111050_, p_111051_, p_111052_, p_111053_, p_111054_, p_111055_, p_111056_, p_111057_, modelData, renderType);
|
||||
}
|
||||
|
||||
} catch (Throwable throwable) {
|
||||
@@ -36,11 +36,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ @Deprecated //Forge: Model data argument
|
||||
+ @Deprecated //Forge: Model data and render type parameter
|
||||
public void m_234390_(BlockAndTintGetter p_234391_, BakedModel p_234392_, BlockState p_234393_, BlockPos p_234394_, PoseStack p_234395_, VertexConsumer p_234396_, boolean p_234397_, RandomSource p_234398_, long p_234399_, int p_234400_) {
|
||||
+ tesselateWithAO(p_234391_, p_234392_, p_234393_, p_234394_, p_234395_, p_234396_, p_234397_, p_234398_, p_234399_, p_234400_, net.minecraftforge.client.model.data.EmptyModelData.INSTANCE);
|
||||
+ tesselateWithAO(p_234391_, p_234392_, p_234393_, p_234394_, p_234395_, p_234396_, p_234397_, p_234398_, p_234399_, p_234400_, net.minecraftforge.client.model.data.ModelData.EMPTY, null);
|
||||
+ }
|
||||
+ public void tesselateWithAO(BlockAndTintGetter p_111079_, BakedModel p_111080_, BlockState p_111081_, BlockPos p_111082_, PoseStack p_111083_, VertexConsumer p_111084_, boolean p_111085_, RandomSource p_111086_, long p_111087_, int p_111088_, net.minecraftforge.client.model.data.IModelData modelData) {
|
||||
+ public void tesselateWithAO(BlockAndTintGetter p_111079_, BakedModel p_111080_, BlockState p_111081_, BlockPos p_111082_, PoseStack p_111083_, VertexConsumer p_111084_, boolean p_111085_, RandomSource p_111086_, long p_111087_, int p_111088_, net.minecraftforge.client.model.data.ModelData modelData, net.minecraft.client.renderer.RenderType renderType) {
|
||||
float[] afloat = new float[f_173405_.length * 2];
|
||||
BitSet bitset = new BitSet(3);
|
||||
ModelBlockRenderer.AmbientOcclusionFace modelblockrenderer$ambientocclusionface = new ModelBlockRenderer.AmbientOcclusionFace();
|
||||
@@ -51,7 +51,7 @@
|
||||
- p_234398_.m_188584_(p_234399_);
|
||||
- List<BakedQuad> list = p_234392_.m_213637_(p_234393_, direction, p_234398_);
|
||||
+ p_111086_.m_188584_(p_111087_);
|
||||
+ List<BakedQuad> list = p_111080_.getQuads(p_111081_, direction, p_111086_, modelData);
|
||||
+ List<BakedQuad> list = p_111080_.getQuads(p_111081_, direction, p_111086_, modelData, renderType);
|
||||
if (!list.isEmpty()) {
|
||||
- blockpos$mutableblockpos.m_122159_(p_234394_, direction);
|
||||
- if (!p_234397_ || Block.m_152444_(p_234393_, p_234391_, p_234394_, direction, blockpos$mutableblockpos)) {
|
||||
@@ -66,7 +66,7 @@
|
||||
- p_234398_.m_188584_(p_234399_);
|
||||
- List<BakedQuad> list1 = p_234392_.m_213637_(p_234393_, (Direction)null, p_234398_);
|
||||
+ p_111086_.m_188584_(p_111087_);
|
||||
+ List<BakedQuad> list1 = p_111080_.getQuads(p_111081_, (Direction)null, p_111086_, modelData);
|
||||
+ List<BakedQuad> list1 = p_111080_.getQuads(p_111081_, (Direction)null, p_111086_, modelData, renderType);
|
||||
if (!list1.isEmpty()) {
|
||||
- this.m_111012_(p_234391_, p_234393_, p_234394_, p_234395_, p_234396_, list1, afloat, bitset, modelblockrenderer$ambientocclusionface, p_234400_);
|
||||
+ this.m_111012_(p_111079_, p_111081_, p_111082_, p_111083_, p_111084_, list1, afloat, bitset, modelblockrenderer$ambientocclusionface, p_111088_);
|
||||
@@ -74,11 +74,11 @@
|
||||
|
||||
}
|
||||
|
||||
+ @Deprecated //Forge: Model data argument
|
||||
+ @Deprecated //Forge: Model data and render type parameter
|
||||
public void m_234401_(BlockAndTintGetter p_234402_, BakedModel p_234403_, BlockState p_234404_, BlockPos p_234405_, PoseStack p_234406_, VertexConsumer p_234407_, boolean p_234408_, RandomSource p_234409_, long p_234410_, int p_234411_) {
|
||||
+ tesselateWithoutAO(p_234402_, p_234403_, p_234404_, p_234405_, p_234406_, p_234407_, p_234408_, p_234409_, p_234410_, p_234411_, net.minecraftforge.client.model.data.EmptyModelData.INSTANCE);
|
||||
+ tesselateWithoutAO(p_234402_, p_234403_, p_234404_, p_234405_, p_234406_, p_234407_, p_234408_, p_234409_, p_234410_, p_234411_, net.minecraftforge.client.model.data.ModelData.EMPTY, null);
|
||||
+ }
|
||||
+ public void tesselateWithoutAO(BlockAndTintGetter p_111091_, BakedModel p_111092_, BlockState p_111093_, BlockPos p_111094_, PoseStack p_111095_, VertexConsumer p_111096_, boolean p_111097_, RandomSource p_111098_, long p_111099_, int p_111100_, net.minecraftforge.client.model.data.IModelData modelData) {
|
||||
+ public void tesselateWithoutAO(BlockAndTintGetter p_111091_, BakedModel p_111092_, BlockState p_111093_, BlockPos p_111094_, PoseStack p_111095_, VertexConsumer p_111096_, boolean p_111097_, RandomSource p_111098_, long p_111099_, int p_111100_, net.minecraftforge.client.model.data.ModelData modelData, net.minecraft.client.renderer.RenderType renderType) {
|
||||
BitSet bitset = new BitSet(3);
|
||||
- BlockPos.MutableBlockPos blockpos$mutableblockpos = p_234405_.m_122032_();
|
||||
+ BlockPos.MutableBlockPos blockpos$mutableblockpos = p_111094_.m_122032_();
|
||||
@@ -87,7 +87,7 @@
|
||||
- p_234409_.m_188584_(p_234410_);
|
||||
- List<BakedQuad> list = p_234403_.m_213637_(p_234404_, direction, p_234409_);
|
||||
+ p_111098_.m_188584_(p_111099_);
|
||||
+ List<BakedQuad> list = p_111092_.getQuads(p_111093_, direction, p_111098_, modelData);
|
||||
+ List<BakedQuad> list = p_111092_.getQuads(p_111093_, direction, p_111098_, modelData, renderType);
|
||||
if (!list.isEmpty()) {
|
||||
- blockpos$mutableblockpos.m_122159_(p_234405_, direction);
|
||||
- if (!p_234408_ || Block.m_152444_(p_234404_, p_234402_, p_234405_, direction, blockpos$mutableblockpos)) {
|
||||
@@ -104,7 +104,7 @@
|
||||
- p_234409_.m_188584_(p_234410_);
|
||||
- List<BakedQuad> list1 = p_234403_.m_213637_(p_234404_, (Direction)null, p_234409_);
|
||||
+ p_111098_.m_188584_(p_111099_);
|
||||
+ List<BakedQuad> list1 = p_111092_.getQuads(p_111093_, (Direction)null, p_111098_, modelData);
|
||||
+ List<BakedQuad> list1 = p_111092_.getQuads(p_111093_, (Direction)null, p_111098_, modelData, renderType);
|
||||
if (!list1.isEmpty()) {
|
||||
- this.m_111001_(p_234402_, p_234404_, p_234405_, -1, p_234411_, true, p_234406_, p_234407_, list1, bitset);
|
||||
+ this.m_111001_(p_111091_, p_111093_, p_111094_, -1, p_111100_, true, p_111095_, p_111096_, list1, bitset);
|
||||
@@ -115,23 +115,23 @@
|
||||
|
||||
}
|
||||
|
||||
+ @Deprecated //Forge: Model data argument
|
||||
+ @Deprecated //Forge: Model data and render type parameter
|
||||
public void m_111067_(PoseStack.Pose p_111068_, VertexConsumer p_111069_, @Nullable BlockState p_111070_, BakedModel p_111071_, float p_111072_, float p_111073_, float p_111074_, int p_111075_, int p_111076_) {
|
||||
+ renderModel(p_111068_, p_111069_, p_111070_, p_111071_, p_111072_, p_111073_, p_111074_, p_111075_, p_111076_, net.minecraftforge.client.model.data.EmptyModelData.INSTANCE);
|
||||
+ renderModel(p_111068_, p_111069_, p_111070_, p_111071_, p_111072_, p_111073_, p_111074_, p_111075_, p_111076_, net.minecraftforge.client.model.data.ModelData.EMPTY, null);
|
||||
+ }
|
||||
+ public void renderModel(PoseStack.Pose p_111068_, VertexConsumer p_111069_, @Nullable BlockState p_111070_, BakedModel p_111071_, float p_111072_, float p_111073_, float p_111074_, int p_111075_, int p_111076_, net.minecraftforge.client.model.data.IModelData modelData) {
|
||||
+ public void renderModel(PoseStack.Pose p_111068_, VertexConsumer p_111069_, @Nullable BlockState p_111070_, BakedModel p_111071_, float p_111072_, float p_111073_, float p_111074_, int p_111075_, int p_111076_, net.minecraftforge.client.model.data.ModelData modelData, net.minecraft.client.renderer.RenderType renderType) {
|
||||
RandomSource randomsource = RandomSource.m_216327_();
|
||||
long i = 42L;
|
||||
|
||||
for(Direction direction : f_173405_) {
|
||||
randomsource.m_188584_(42L);
|
||||
- m_111058_(p_111068_, p_111069_, p_111072_, p_111073_, p_111074_, p_111071_.m_213637_(p_111070_, direction, randomsource), p_111075_, p_111076_);
|
||||
+ m_111058_(p_111068_, p_111069_, p_111072_, p_111073_, p_111074_, p_111071_.getQuads(p_111070_, direction, randomsource, modelData), p_111075_, p_111076_);
|
||||
+ m_111058_(p_111068_, p_111069_, p_111072_, p_111073_, p_111074_, p_111071_.getQuads(p_111070_, direction, randomsource, modelData, renderType), p_111075_, p_111076_);
|
||||
}
|
||||
|
||||
randomsource.m_188584_(42L);
|
||||
- m_111058_(p_111068_, p_111069_, p_111072_, p_111073_, p_111074_, p_111071_.m_213637_(p_111070_, (Direction)null, randomsource), p_111075_, p_111076_);
|
||||
+ m_111058_(p_111068_, p_111069_, p_111072_, p_111073_, p_111074_, p_111071_.getQuads(p_111070_, (Direction)null, randomsource, modelData), p_111075_, p_111076_);
|
||||
+ m_111058_(p_111068_, p_111069_, p_111072_, p_111073_, p_111074_, p_111071_.getQuads(p_111070_, (Direction)null, randomsource, modelData, renderType), p_111075_, p_111076_);
|
||||
}
|
||||
|
||||
private static void m_111058_(PoseStack.Pose p_111059_, VertexConsumer p_111060_, float p_111061_, float p_111062_, float p_111063_, List<BakedQuad> p_111064_, int p_111065_, int p_111066_) {
|
||||
@@ -1,23 +0,0 @@
|
||||
--- a/net/minecraft/client/renderer/block/model/BakedQuad.java
|
||||
+++ b/net/minecraft/client/renderer/block/model/BakedQuad.java
|
||||
@@ -6,7 +_,7 @@
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
-public class BakedQuad {
|
||||
+public class BakedQuad implements net.minecraftforge.client.model.pipeline.IVertexProducer {
|
||||
protected final int[] f_111292_;
|
||||
protected final int f_111293_;
|
||||
protected final Direction f_111294_;
|
||||
@@ -39,6 +_,11 @@
|
||||
|
||||
public Direction m_111306_() {
|
||||
return this.f_111294_;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void pipe(net.minecraftforge.client.model.pipeline.IVertexConsumer consumer) {
|
||||
+ net.minecraftforge.client.model.pipeline.LightUtil.putBakedQuad(consumer, this);
|
||||
}
|
||||
|
||||
public boolean m_111307_() {
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
--- a/net/minecraft/client/renderer/block/model/BlockElementFace.java
|
||||
+++ b/net/minecraft/client/renderer/block/model/BlockElementFace.java
|
||||
@@ -19,12 +_,18 @@
|
||||
public final int f_111355_;
|
||||
public final String f_111356_;
|
||||
public final BlockFaceUV f_111357_;
|
||||
+ public final int emissivity;
|
||||
|
||||
public BlockElementFace(@Nullable Direction p_111359_, int p_111360_, String p_111361_, BlockFaceUV p_111362_) {
|
||||
+ this(p_111359_, p_111360_, p_111361_, p_111362_, 0);
|
||||
+ }
|
||||
+
|
||||
+ public BlockElementFace(@Nullable Direction p_111359_, int p_111360_, String p_111361_, BlockFaceUV p_111362_, int emissivity) {
|
||||
this.f_111354_ = p_111359_;
|
||||
this.f_111355_ = p_111360_;
|
||||
this.f_111356_ = p_111361_;
|
||||
this.f_111357_ = p_111362_;
|
||||
+ this.emissivity = emissivity;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@@ -37,7 +_,10 @@
|
||||
int i = this.m_111368_(jsonobject);
|
||||
String s = this.m_111370_(jsonobject);
|
||||
BlockFaceUV blockfaceuv = p_111367_.deserialize(jsonobject, BlockFaceUV.class);
|
||||
- return new BlockElementFace(direction, i, s, blockfaceuv);
|
||||
+ int emissivity = GsonHelper.m_13824_(jsonobject, "emissivity", 0);
|
||||
+ if (emissivity != net.minecraft.util.Mth.m_14045_(emissivity, 0, 15))
|
||||
+ throw new JsonParseException("The emissivity value must be between 0 and 15. Found: " + emissivity);
|
||||
+ return new BlockElementFace(direction, i, s, blockfaceuv, emissivity);
|
||||
}
|
||||
|
||||
protected int m_111368_(JsonObject p_111369_) {
|
||||
Loaded 100 of 661 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user