Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ subprojects {
maven("https://repo.spongepowered.org/repository/maven-public/") {
name = "sponge"
}

maven ("https://maven.parchmentmc.org/") {
name = "ParchmentMC"
}
}

extensions.configure(net.kyori.indra.IndraExtension::class) {
Expand Down
7 changes: 7 additions & 0 deletions subprojects/gradle-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,14 @@ dependencies {
exclude("org.ow2.asm") // Use our own ASM
}

// Mappings
implementation("org.cadixdev:lorenz-io-proguard:0.5.7")
implementation("net.fabricmc:lorenz-tiny:4.0.1") {
isTransitive = false
}
implementation("org.parchmentmc:feather:0.6.5.3-dev-SNAPSHOT")
implementation("org.parchmentmc.feather:io-gson:0.6.5.3-dev-SNAPSHOT")
implementation("net.fabricmc:mapping-io:0.2.1")

compileOnlyApi("org.checkerframework:checker-qual:3.15.0")
annotationProcessor("org.immutables:value:2.8.8")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
import org.spongepowered.gradle.vanilla.repository.MinecraftRepositoryExtension;
import org.spongepowered.gradle.vanilla.runs.RunConfigurationContainer;

import java.util.List;

/**
* Properties that can configure how VanillaGradle applies Minecraft to the
* current project.
Expand Down Expand Up @@ -67,7 +69,7 @@ public interface MinecraftExtension extends MinecraftRepositoryExtension {
* available in the ordinary version list, such as combat snapshots.</p>
*
* @param versionFile a file-like object that can be handled
* by {@link Project#file(Object)}
* by {@link Project#file(Object)}
*/
void injectedVersion(Object versionFile);

Expand Down Expand Up @@ -113,6 +115,18 @@ public interface MinecraftExtension extends MinecraftRepositoryExtension {
*/
void accessWideners(Object... file);

/**
* Apply mappings to a

* <p>Access wideners can only be added before the first time a Minecraft
* dependency is resolved.</p>
*
* @param dependency any dependency pointing ot mappings. for example "net.fabricmc:yarn:1.16.5+build.1"
*/
void mappings(String... dependency);

List<String> mappings();

/**
* Get run configurations configured for this project.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.invocation.Gradle;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.ListProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.provider.Provider;
import org.gradle.util.ConfigureUtil;
Expand All @@ -51,10 +52,7 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.*;
import java.util.concurrent.ExecutionException;

import javax.inject.Inject;
Expand All @@ -64,6 +62,7 @@ public class MinecraftExtensionImpl implements MinecraftExtension {
// User-set properties
private final Provider<MinecraftProviderService> providerService;
private final Property<String> version;
private final ListProperty<String> mappings;
private final Property<MinecraftPlatform> platform;
private final Property<Boolean> injectRepositories;
private final DirectoryProperty sharedCache;
Expand All @@ -84,6 +83,7 @@ public MinecraftExtensionImpl(final Gradle gradle, final ObjectFactory factory,
this.project = project;
this.providerService = providerService;
this.version = factory.property(String.class);
this.mappings = factory.listProperty(String.class);
this.platform = factory.property(MinecraftPlatform.class).convention(MinecraftPlatform.JOINED);
this.injectRepositories = factory.property(Boolean.class).convention(project.provider(() -> !gradle.getPlugins().hasPlugin(MinecraftRepositoryPlugin.class))); // only inject if we aren't already in Settings
this.accessWideners = factory.fileCollection();
Expand Down Expand Up @@ -223,6 +223,16 @@ public void accessWideners(final Object... files) {
this.accessWideners.from(files);
}

@Override
public void mappings(String... dependencies) {
this.mappings.set(Arrays.asList(dependencies));
}

@Override
public List<String> mappings() {
return this.mappings.get();
}

public ConfigurableFileCollection accessWideners() {
return this.accessWideners;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* This file is part of VanillaGradle, licensed under the MIT License (MIT).
*
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.spongepowered.gradle.vanilla.internal.mappings;

/**
* Represents the possible MappingType's supported.
*/
public enum MappingType {
PROGUARD("txt"),
SRG(".srg"),
TSRG(".tsrg"),
TINY(".tiny"),
PARCHMENT(".json"),
JAR(".jar"),
ZIP(".zip"),
EMPTY(null);

public final String fileExtension;

MappingType(String fileExtension) {
this.fileExtension = fileExtension;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
/*
* This file is part of VanillaGradle, licensed under the MIT License (MIT).
*
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.spongepowered.gradle.vanilla.internal.mappings;

import net.fabricmc.lorenztiny.TinyMappingFormat;
import org.cadixdev.lorenz.MappingSet;
import org.cadixdev.lorenz.io.proguard.ProGuardReader;
import org.cadixdev.lorenz.io.srg.SrgReader;
import org.cadixdev.lorenz.io.srg.tsrg.TSrgReader;
import org.gradle.api.GradleException;

import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.function.Consumer;

public class MappingUtils {

/**
* Reads mappings into a {@link MappingSet}.
*
* @param mappingsFile the location of the file containing mappings
* @return a {@link MappingSet} containing all mappings provided.
*/
public static MappingSet readMappings(Path mappingsFile) {
MappingSet mappings = MappingSet.create();
MappingType type = getMappingType(mappingsFile);
FileSystem fileSystem = null; // If a filesystem is created in a jar, we need to close it manually

if (type == MappingType.JAR || type == MappingType.ZIP) {
// We need to find the mappings. Find the first valid mapping file we can.
try {
fileSystem = FileSystems.newFileSystem(mappingsFile, (ClassLoader) null);
mappingsFile = fileSystem.getPath("/mappings/mappings.tiny");

if (!Files.isRegularFile(mappingsFile)) {
mappingsFile = fileSystem.getPath("/parchment.json");

if (!Files.isRegularFile(mappingsFile)) {
throw new GradleException("Failed to read mappings from " + mappingsFile);
}
}
} catch (IOException ex) {
throw new GradleException("Failed to read mappings from " + mappingsFile, ex);
}
}

type = getMappingType(mappingsFile);
switch (type) {
case PROGUARD: {
try (BufferedReader reader = Files.newBufferedReader(mappingsFile, StandardCharsets.UTF_8)) {
final ProGuardReader proguard = new ProGuardReader(reader);
proguard.read(mappings);
mappings = mappings.reverse(); // Flip from named -> obf to named -> obf
} catch (IOException ex) {
throw new GradleException("Failed to read mappings from " + mappingsFile, ex);
}
break;
}

case TINY: {
try {
mappings = TinyMappingFormat.DETECT.read(mappingsFile, "official", "named");
} catch (IOException ex) {
throw new GradleException("Failed to read mappings from " + mappingsFile, ex);
}
break;
}

case SRG: {
final MappingSet finalMappings = mappings;
read(mappingsFile, (reader) -> {
final SrgReader srg = new SrgReader(reader);
srg.read(finalMappings);
});
break;
}

case TSRG: {
final MappingSet finalMappings = mappings;
read(mappingsFile, (reader) -> {
final TSrgReader tsrg = new TSrgReader(reader);
tsrg.read(finalMappings);
});
break;
}

case PARCHMENT: {
final MappingSet finalMappings = mappings;

read(mappingsFile, (reader) -> {
//TODO: complete. This is a bit trickier than the others.
// We need to first get the mapping set for mojmap, then apply Parchment on top.
// But how do we know which mojmap to use? probably could just guess by using the version.
final ParchmentReader parchment = new ParchmentReader(reader);
parchment.read(finalMappings);
});
break;
}

case EMPTY:
throw new GradleException("Unknown mappings type");
}

if (fileSystem != null) {
try {
fileSystem.close();
} catch (IOException ex) {
throw new GradleException("Failed to close jar filesystem");
}
}

return mappings;
}

/**
* Reads a file into a buffered reader and automatically closes it. Also lowers the amount of duplicated code in here.
*/
private static void read(Path path, Consumer<BufferedReader> consumer) {
try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
consumer.accept(reader);
} catch (IOException ex) {
throw new GradleException("Failed to read mappings from " + path, ex);
}
}

/**
* Returns the {@link MappingType} based off the extension of the file
*
* @param mappingsFile The {@link Path} of the mappings
*/
private static MappingType getMappingType(Path mappingsFile) {
return getMappingType(mappingsFile.toString());
}

/**
* Returns the {@link MappingType} based off the extension of the file
*
* @param fileName The name of the file you are checking.
*/
private static MappingType getMappingType(String fileName) {
for (MappingType type : MappingType.values()) {
if (fileName.endsWith(type.fileExtension)) {
return type;
}
}
return MappingType.EMPTY;
}
}
Loading