|
|
|
|
@@ -28,112 +28,155 @@ import java.util.regex.Matcher;
|
|
|
|
|
import java.util.regex.Pattern;
|
|
|
|
|
|
|
|
|
|
import org.gradle.api.Project;
|
|
|
|
|
import org.gradle.api.artifacts.ExternalModuleDependency;
|
|
|
|
|
|
|
|
|
|
import net.fabricmc.loom.LoomGradleExtension;
|
|
|
|
|
import net.fabricmc.loom.LoomRepositoryPlugin;
|
|
|
|
|
import net.fabricmc.loom.configuration.providers.BundleMetadata;
|
|
|
|
|
import net.fabricmc.loom.util.Architecture;
|
|
|
|
|
import net.fabricmc.loom.util.Constants;
|
|
|
|
|
import net.fabricmc.loom.util.OperatingSystem;
|
|
|
|
|
|
|
|
|
|
public class MinecraftLibraryProvider {
|
|
|
|
|
private static final Pattern NATIVES_PATTERN = Pattern.compile("^(?<group>.*)/(.*?)/(?<version>.*)/((?<name>.*?)-(\\k<version>)-)(?<classifier>.*).jar$");
|
|
|
|
|
private static final boolean IS_MACOS = OperatingSystem.CURRENT_OS.equals(OperatingSystem.MAC_OS);
|
|
|
|
|
|
|
|
|
|
public void provide(MinecraftProvider minecraftProvider, Project project) {
|
|
|
|
|
private final Project project;
|
|
|
|
|
private final MinecraftVersionMeta versionInfo;
|
|
|
|
|
private final BundleMetadata serverBundleMetadata;
|
|
|
|
|
private final boolean runtimeOnlyLog4j;
|
|
|
|
|
private final boolean provideClient;
|
|
|
|
|
private final boolean provideServer;
|
|
|
|
|
|
|
|
|
|
public MinecraftLibraryProvider(MinecraftProvider minecraftProvider, Project project) {
|
|
|
|
|
final LoomGradleExtension extension = LoomGradleExtension.get(project);
|
|
|
|
|
final MinecraftJarConfiguration jarConfiguration = extension.getMinecraftJarConfiguration().get();
|
|
|
|
|
final MinecraftVersionMeta versionInfo = minecraftProvider.getVersionInfo();
|
|
|
|
|
final BundleMetadata serverBundleMetadata = minecraftProvider.getServerBundleMetadata();
|
|
|
|
|
final boolean runtimeOnlyLog4j = extension.getRuntimeOnlyLog4j().get();
|
|
|
|
|
|
|
|
|
|
final boolean hasNativesToExtract = versionInfo.hasNativesToExtract();
|
|
|
|
|
final boolean overrideLWJGL = hasNativesToExtract && (LWJGLVersionOverride.overrideByDefault(versionInfo) || LWJGLVersionOverride.forceOverride(project) || Boolean.getBoolean("loom.test.lwjgloverride"));
|
|
|
|
|
final boolean isMacOS = OperatingSystem.CURRENT_OS.equals(OperatingSystem.MAC_OS);
|
|
|
|
|
this.project = project;
|
|
|
|
|
this.versionInfo = minecraftProvider.getVersionInfo();
|
|
|
|
|
this.serverBundleMetadata = minecraftProvider.getServerBundleMetadata();
|
|
|
|
|
this.runtimeOnlyLog4j = extension.getRuntimeOnlyLog4j().get();
|
|
|
|
|
this.provideClient = jarConfiguration.getSupportedEnvironments().contains("client");
|
|
|
|
|
this.provideServer = jarConfiguration.getSupportedEnvironments().contains("server");
|
|
|
|
|
assert provideClient || provideServer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (overrideLWJGL) {
|
|
|
|
|
project.getLogger().warn("Loom is upgrading Minecraft's LWJGL version to {}", LWJGLVersionOverride.LWJGL_VERSION);
|
|
|
|
|
public void provide() {
|
|
|
|
|
if (provideClient) {
|
|
|
|
|
// Modern 1.19 version put the natives on the classpath.
|
|
|
|
|
final boolean hasNativesToExtract = versionInfo.hasNativesToExtract();
|
|
|
|
|
final boolean overrideLWJGL = hasNativesToExtract && (LWJGLVersionOverride.overrideByDefault(versionInfo) || LWJGLVersionOverride.forceOverride(project) || Boolean.getBoolean("loom.test.lwjgloverride"));
|
|
|
|
|
|
|
|
|
|
if (overrideLWJGL) {
|
|
|
|
|
project.getLogger().warn("Loom is upgrading Minecraft's LWJGL version to {}", LWJGLVersionOverride.LWJGL_VERSION);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (hasNativesToExtract) {
|
|
|
|
|
// Create a configuration for
|
|
|
|
|
project.getConfigurations().register(Constants.Configurations.MINECRAFT_NATIVES, configuration -> configuration.setTransitive(false));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
provideClientLibraries(overrideLWJGL, hasNativesToExtract);
|
|
|
|
|
|
|
|
|
|
if (overrideLWJGL) {
|
|
|
|
|
LWJGLVersionOverride.applyOverrides(project, IS_MACOS);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (hasNativesToExtract) {
|
|
|
|
|
project.getConfigurations().register(Constants.Configurations.MINECRAFT_NATIVES, configuration -> configuration.setTransitive(false));
|
|
|
|
|
if (provideServer) {
|
|
|
|
|
provideServerLibraries();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void provideClientLibraries(boolean overrideLWJGL, boolean hasNativesToExtract) {
|
|
|
|
|
final boolean isArm = Architecture.CURRENT.isArm();
|
|
|
|
|
final boolean classpathArmNatives = !hasNativesToExtract && isArm;
|
|
|
|
|
|
|
|
|
|
if (classpathArmNatives) {
|
|
|
|
|
LoomRepositoryPlugin.forceLWJGLFromMavenCentral(project);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (MinecraftVersionMeta.Library library : versionInfo.libraries()) {
|
|
|
|
|
if (overrideLWJGL && library.name().startsWith("org.lwjgl")) {
|
|
|
|
|
// Skip over Minecraft's LWJGL version, will will replace this with a newer version later.
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (library.isValidForOS() && !library.hasNatives() && library.artifact() != null) {
|
|
|
|
|
// 1.4.7 contains an LWJGL version with an invalid maven pom, set the metadata sources to not use the pom for this version.
|
|
|
|
|
if ("org.lwjgl.lwjgl:lwjgl:2.9.1-nightly-20130708-debug3".equals(library.name()) || "org.lwjgl.lwjgl:lwjgl:2.9.1-nightly-20131017".equals(library.name())) {
|
|
|
|
|
final String name = library.name();
|
|
|
|
|
|
|
|
|
|
if ("org.lwjgl.lwjgl:lwjgl:2.9.1-nightly-20130708-debug3".equals(name) || "org.lwjgl.lwjgl:lwjgl:2.9.1-nightly-20131017".equals(name)) {
|
|
|
|
|
// 1.4.7 contains an LWJGL version with an invalid maven pom, set the metadata sources to not use the pom for this version.
|
|
|
|
|
LoomRepositoryPlugin.setupForLegacyVersions(project);
|
|
|
|
|
} else if (library.name().startsWith("org.ow2.asm:asm-all")) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (name.startsWith("org.ow2.asm:asm-all")) {
|
|
|
|
|
// Don't want asm-all, use the modern split version.
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (runtimeOnlyLog4j && library.name().startsWith("org.apache.logging.log4j")) {
|
|
|
|
|
if (runtimeOnlyLog4j && name.startsWith("org.apache.logging.log4j")) {
|
|
|
|
|
// Make log4j a runtime only dep to force slf4j.
|
|
|
|
|
project.getDependencies().add(Constants.Configurations.MINECRAFT_RUNTIME_DEPENDENCIES, library.name());
|
|
|
|
|
} else if (jarConfiguration.getSupportedEnvironments().contains("client")) {
|
|
|
|
|
// Client only library, or legacy version
|
|
|
|
|
project.getDependencies().add(Constants.Configurations.MINECRAFT_DEPENDENCIES, library.name());
|
|
|
|
|
} else {
|
|
|
|
|
project.getLogger().debug("Minecraft library ({}) was not added to any configuration", library.name());
|
|
|
|
|
project.getDependencies().add(Constants.Configurations.MINECRAFT_RUNTIME_DEPENDENCIES, name);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (classpathArmNatives && name.startsWith("org.lwjgl:")
|
|
|
|
|
&& (name.endsWith("natives-windows") || name.endsWith("natives-linux"))) {
|
|
|
|
|
// Add windows and Linux arm64 natives for modern classpath native MC versions.
|
|
|
|
|
project.getDependencies().add(Constants.Configurations.MINECRAFT_DEPENDENCIES, name + "-arm64");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
project.getDependencies().add(Constants.Configurations.MINECRAFT_DEPENDENCIES, name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (library.hasNativesForOS()) {
|
|
|
|
|
MinecraftVersionMeta.Download nativeDownload = library.classifierForOS();
|
|
|
|
|
|
|
|
|
|
if (nativeDownload == null) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final String path = nativeDownload.path();
|
|
|
|
|
final Matcher matcher = NATIVES_PATTERN.matcher(path);
|
|
|
|
|
|
|
|
|
|
if (!matcher.find()) {
|
|
|
|
|
project.getLogger().warn("Failed to match regex for natives path : " + path);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final String group = matcher.group("group").replace("/", ".");
|
|
|
|
|
final String name = matcher.group("name");
|
|
|
|
|
final String version = matcher.group("version");
|
|
|
|
|
final String classifier = matcher.group("classifier");
|
|
|
|
|
|
|
|
|
|
final String dependencyNotation = "%s:%s:%s:%s".formatted(group, name, version, classifier);
|
|
|
|
|
|
|
|
|
|
if (overrideLWJGL && isMacOS && "java-objc-bridge".equals(name)) {
|
|
|
|
|
// Mojang split out the natives into their own jar, skip over Mojang's jar and use the official jar later on.
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
project.getLogger().debug("Add native dependency '{}'", dependencyNotation);
|
|
|
|
|
project.getDependencies().add(Constants.Configurations.MINECRAFT_NATIVES, dependencyNotation);
|
|
|
|
|
provideNativesForLibrary(library, overrideLWJGL, IS_MACOS);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void provideServerLibraries() {
|
|
|
|
|
if (serverBundleMetadata != null) {
|
|
|
|
|
for (BundleMetadata.Entry library : serverBundleMetadata.libraries()) {
|
|
|
|
|
if (runtimeOnlyLog4j && library.name().startsWith("org.apache.logging.log4j")) {
|
|
|
|
|
// Make log4j a runtime only dep to force slf4j.
|
|
|
|
|
project.getDependencies().add(Constants.Configurations.MINECRAFT_RUNTIME_DEPENDENCIES, library.name());
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
project.getDependencies().add(Constants.Configurations.MINECRAFT_SERVER_DEPENDENCIES, library.name());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (overrideLWJGL) {
|
|
|
|
|
LWJGLVersionOverride.DEPENDENCIES.forEach(s -> project.getDependencies().add(Constants.Configurations.MINECRAFT_DEPENDENCIES, s));
|
|
|
|
|
LWJGLVersionOverride.NATIVES.forEach(s -> project.getDependencies().add(Constants.Configurations.MINECRAFT_NATIVES, s));
|
|
|
|
|
private void provideNativesForLibrary(MinecraftVersionMeta.Library library, boolean overrideLWJGL, boolean isMacOS) {
|
|
|
|
|
MinecraftVersionMeta.Download nativeDownload = library.classifierForOS();
|
|
|
|
|
|
|
|
|
|
if (isMacOS) {
|
|
|
|
|
LWJGLVersionOverride.MACOS_DEPENDENCIES.forEach(s -> project.getDependencies().add(Constants.Configurations.MINECRAFT_DEPENDENCIES, s));
|
|
|
|
|
LWJGLVersionOverride.MACOS_NATIVES.forEach(s -> project.getDependencies().add(Constants.Configurations.MINECRAFT_NATIVES, s));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add the native support mod that fixes a handful of issues related to the LWJGL update at runtime.
|
|
|
|
|
ExternalModuleDependency dependency = (ExternalModuleDependency) project.getDependencies().create(Constants.Dependencies.NATIVE_SUPPORT + Constants.Dependencies.Versions.NATIVE_SUPPORT_VERSION);
|
|
|
|
|
dependency.setTransitive(false);
|
|
|
|
|
project.getDependencies().add("modLocalRuntime", dependency);
|
|
|
|
|
if (nativeDownload == null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final String path = nativeDownload.path();
|
|
|
|
|
final Matcher matcher = NATIVES_PATTERN.matcher(path);
|
|
|
|
|
|
|
|
|
|
if (!matcher.find()) {
|
|
|
|
|
project.getLogger().warn("Failed to match regex for natives path : " + path);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final String group = matcher.group("group").replace("/", ".");
|
|
|
|
|
final String name = matcher.group("name");
|
|
|
|
|
final String version = matcher.group("version");
|
|
|
|
|
final String classifier = matcher.group("classifier");
|
|
|
|
|
|
|
|
|
|
final String dependencyNotation = "%s:%s:%s:%s".formatted(group, name, version, classifier);
|
|
|
|
|
|
|
|
|
|
if (overrideLWJGL && isMacOS && "java-objc-bridge".equals(name)) {
|
|
|
|
|
// Mojang split out the natives into their own jar, skip over Mojang's jar and use the official jar later on.
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
project.getLogger().debug("Add native dependency '{}'", dependencyNotation);
|
|
|
|
|
project.getDependencies().add(Constants.Configurations.MINECRAFT_NATIVES, dependencyNotation);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|