Skip to content

Commit eaa039d

Browse files
authored
Merge pull request #35 from FlintMC/feature/instrumentation
Feature/instrumentation
2 parents a0b8c89 + c5e01d6 commit eaa039d

18 files changed

+922
-105
lines changed

build.gradle.kts

+4
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ dependencies {
8787
implementation(group = "net.flintmc.installer", name = "logic-implementation", version = "2.0.2")
8888
implementation(group = "net.flintmc.installer", name = "logic", version = "2.0.2")
8989

90+
implementation(group = "org.ow2.asm", name = "asm", version = "9.1")
91+
implementation(group = "org.ow2.asm",name = "asm-tree", version = "9.1")
92+
implementation(group = "org.ow2.asm", name ="asm-commons", version = "9.1")
93+
9094
implementation(group = "com.cloudbees", name = "diff4j", version = "1.2")
9195
}
9296

src/main/java/net/flintmc/gradle/FlintGradlePlugin.java

+16
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import net.flintmc.gradle.java.JarTaskProvider;
2727
import net.flintmc.gradle.java.JavaPluginInteraction;
2828
import net.flintmc.gradle.java.RunConfigurationProvider;
29+
import net.flintmc.gradle.java.instrumentation.Instrumentation;
2930
import net.flintmc.gradle.manifest.ManifestConfigurator;
3031
import net.flintmc.gradle.manifest.dev.DevelopmentStaticFiles;
3132
import net.flintmc.gradle.maven.FlintResolutionStrategy;
@@ -77,6 +78,8 @@ public class FlintGradlePlugin implements Plugin<Project> {
7778

7879
private FlintGradlePlugin parentPlugin;
7980

81+
private Instrumentation instrumentation;
82+
8083
@Override
8184
public void apply(@Nonnull Project project) {
8285
this.project = project;
@@ -132,6 +135,9 @@ public void apply(@Nonnull Project project) {
132135
throw new UncheckedIOException("Failed to create Yggdrasil authenticator", e);
133136
}
134137

138+
this.instrumentation = new Instrumentation();
139+
this.instrumentation.apply(project);
140+
135141
this.runConfigurationProvider = new RunConfigurationProvider(
136142
project, minecraftRepository, minecraftCache.resolve("run"), authenticator, httpClient);
137143
this.jarTaskProvider = new JarTaskProvider();
@@ -153,6 +159,8 @@ public void apply(@Nonnull Project project) {
153159
this.runConfigurationProvider = parentPlugin.runConfigurationProvider;
154160
this.jarTaskProvider = parentPlugin.jarTaskProvider;
155161
this.mavenArtifactURLCache = parentPlugin.mavenArtifactURLCache;
162+
this.instrumentation = parentPlugin.instrumentation;
163+
this.instrumentation.apply(project);
156164
}
157165

158166
this.manifestConfigurator = new ManifestConfigurator(this);
@@ -328,4 +336,12 @@ public Project getProject() {
328336
public MavenArtifactDownloader getDownloader() {
329337
return this.downloader;
330338
}
339+
340+
public FlintGradleExtension getExtension() {
341+
return extension;
342+
}
343+
344+
public MinecraftRepository getMinecraftRepository() {
345+
return this.minecraftRepository;
346+
}
331347
}

src/main/java/net/flintmc/gradle/environment/DefaultDeobfuscationEnvironment.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,20 @@
1919

2020
package net.flintmc.gradle.environment;
2121

22+
import java.io.File;
2223
import java.io.IOException;
2324
import java.net.URI;
2425
import java.net.URISyntaxException;
2526
import java.nio.file.Files;
2627
import java.nio.file.Path;
2728
import java.nio.file.StandardCopyOption;
28-
import java.util.Collection;
29-
import java.util.Collections;
30-
import java.util.Enumeration;
31-
import java.util.HashSet;
32-
import java.util.Set;
29+
import java.util.*;
3330
import java.util.jar.JarEntry;
3431
import java.util.jar.JarFile;
3532
import java.util.jar.JarInputStream;
3633
import java.util.jar.JarOutputStream;
34+
35+
import com.google.common.collect.ImmutableMap;
3736
import net.flintmc.gradle.maven.pom.MavenArtifact;
3837
import net.flintmc.gradle.minecraft.data.environment.DefaultInput;
3938
import net.flintmc.gradle.minecraft.data.environment.EnvironmentType;

src/main/java/net/flintmc/gradle/environment/DeobfuscationEnvironment.java

+7
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,18 @@
1919

2020
package net.flintmc.gradle.environment;
2121

22+
import java.io.File;
2223
import java.util.Collection;
24+
import java.util.Map;
25+
2326
import net.flintmc.gradle.environment.mcp.ModCoderPackEnvironment;
2427
import net.flintmc.gradle.environment.yarn.YarnEnvironment;
2528
import net.flintmc.gradle.maven.pom.MavenArtifact;
2629
import net.flintmc.gradle.maven.pom.MavenPom;
30+
import net.flintmc.gradle.minecraft.data.environment.DefaultInput;
2731
import net.flintmc.gradle.minecraft.data.environment.EnvironmentInput;
2832
import net.flintmc.gradle.minecraft.data.environment.EnvironmentType;
33+
import okhttp3.OkHttpClient;
2934

3035
/** Represents a deobfuscation environment which can be used to obtain the minecraft source. */
3136
public interface DeobfuscationEnvironment {
@@ -43,6 +48,8 @@ static DeobfuscationEnvironment createFor(EnvironmentInput input, EnvironmentTyp
4348
*/
4449
String name();
4550

51+
Map<String, File> getDownloadedMappingFiles(OkHttpClient httpClient, EnvironmentCacheFileProvider environmentCacheFileProvider) throws DeobfuscationException;
52+
4653
/**
4754
* Runs the deobfuscation on the given client and server artifacts. One of the 2 artifacts may be null, but never both
4855
* at the same time.

src/main/java/net/flintmc/gradle/environment/mcp/ModCoderPackEnvironment.java

+40-15
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,8 @@
1919

2020
package net.flintmc.gradle.environment.mcp;
2121

22-
import java.io.IOException;
23-
import java.io.UncheckedIOException;
24-
import java.nio.file.Files;
25-
import java.nio.file.Path;
26-
import java.util.ArrayList;
27-
import java.util.HashMap;
28-
import java.util.List;
29-
import java.util.Map;
30-
import net.flintmc.gradle.environment.DefaultDeobfuscationEnvironment;
31-
import net.flintmc.gradle.environment.DeobfuscationException;
32-
import net.flintmc.gradle.environment.DeobfuscationUtilities;
33-
import net.flintmc.gradle.environment.EnvironmentCacheFileProvider;
34-
import net.flintmc.gradle.environment.SourceJarProcessor;
22+
import com.google.common.collect.ImmutableMap;
23+
import net.flintmc.gradle.environment.*;
3524
import net.flintmc.gradle.java.exec.JavaExecutionResult;
3625
import net.flintmc.gradle.maven.SimpleMavenRepository;
3726
import net.flintmc.gradle.maven.pom.MavenArtifact;
@@ -45,7 +34,19 @@
4534
import org.gradle.api.logging.Logger;
4635
import org.gradle.api.logging.Logging;
4736

48-
/** Implementation of the MCP as a deobfuscation environment. */
37+
import java.io.File;
38+
import java.io.IOException;
39+
import java.io.UncheckedIOException;
40+
import java.nio.file.Files;
41+
import java.nio.file.Path;
42+
import java.util.ArrayList;
43+
import java.util.HashMap;
44+
import java.util.List;
45+
import java.util.Map;
46+
47+
/**
48+
* Implementation of the MCP as a deobfuscation environment.
49+
*/
4950
public class ModCoderPackEnvironment extends DefaultDeobfuscationEnvironment {
5051
private static final Logger LOGGER = Logging.getLogger(ModCoderPackEnvironment.class);
5152

@@ -61,7 +62,31 @@ public ModCoderPackEnvironment(DefaultInput input) {
6162
this.input = input;
6263
}
6364

64-
/** {@inheritDoc} */
65+
@Override
66+
public Map<String, File> getDownloadedMappingFiles(OkHttpClient httpClient, EnvironmentCacheFileProvider cacheFileProvider) throws DeobfuscationException {
67+
68+
return ImmutableMap.of(
69+
"mcp-config",
70+
this.downloadAndExtractZip(
71+
LOGGER,
72+
cacheFileProvider,
73+
httpClient,
74+
input.getConfigDownload().toExternalForm(),
75+
"mcp-config_" + input.getConfigVersion()).toFile(),
76+
"mcp-mappings",
77+
this.downloadAndExtractZip(
78+
LOGGER,
79+
cacheFileProvider,
80+
httpClient,
81+
input.getMappingsDownload().toExternalForm(),
82+
"mcp-mappings_" + input.getMappingsVersion())
83+
.toFile()
84+
);
85+
}
86+
87+
/**
88+
* {@inheritDoc}
89+
*/
6590
@Override
6691
public void runDeobfuscation(
6792
MavenPom clientPom, MavenPom serverPom, DeobfuscationUtilities utilities)

src/main/java/net/flintmc/gradle/environment/yarn/YarnEnvironment.java

+6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
package net.flintmc.gradle.environment.yarn;
2121

22+
import java.io.File;
2223
import java.io.IOException;
2324
import java.nio.file.Files;
2425
import java.nio.file.Path;
@@ -57,6 +58,11 @@ public YarnEnvironment(DefaultInput input) {
5758
this.input = input;
5859
}
5960

61+
@Override
62+
public Map<String, File> getDownloadedMappingFiles(OkHttpClient httpClient, EnvironmentCacheFileProvider environmentCacheFileProvider) throws DeobfuscationException {
63+
return null;
64+
}
65+
6066
/** {@inheritDoc} */
6167
@Override
6268
public void runDeobfuscation(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* FlintMC
3+
* Copyright (C) 2020-2021 LabyMedia GmbH and contributors
4+
*
5+
* This program is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation; either
8+
* version 3 of the License, or (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public License
16+
* along with this program; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18+
*/
19+
20+
package net.flintmc.gradle.java.instrumentation;
21+
22+
import net.flintmc.gradle.java.instrumentation.tasks.InstrumentationTask;
23+
import net.flintmc.gradle.util.Util;
24+
import org.gradle.api.Project;
25+
import org.gradle.api.Task;
26+
import org.gradle.api.artifacts.Configuration;
27+
import org.gradle.api.file.ConfigurableFileCollection;
28+
import org.gradle.api.plugins.JavaBasePlugin;
29+
import org.gradle.api.tasks.SourceSet;
30+
import org.gradle.api.tasks.SourceSetContainer;
31+
32+
public class Instrumentation {
33+
34+
private static final String GROUP = "flint-instrumentation";
35+
36+
/**
37+
* Applies post compile instrumentation capabilities to a given project.
38+
*
39+
* @param project the project to apply the instrumentation to
40+
*/
41+
public void apply(final Project project) {
42+
// Whether the project has applied the java base plugin
43+
if (!project.getPlugins().hasPlugin(JavaBasePlugin.class)) {
44+
return;
45+
}
46+
47+
Configuration instrumentation = project.getConfigurations().maybeCreate("instrumentation");
48+
instrumentation.setCanBeResolved(true);
49+
50+
SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);
51+
sourceSets.all(sourceSet -> this.configure(project, sourceSet, instrumentation));
52+
}
53+
54+
/**
55+
* Configures the instrumentation tasks.
56+
*
57+
* @param project The project in which the instrumentation tasks are to be configured.
58+
* @param sourceSet The {@link SourceSet} in which the instrumentation tasks are to be
59+
* configured.
60+
*/
61+
private void configure(final Project project, final SourceSet sourceSet, Configuration instrumentationConfiguration) {
62+
InstrumentationTask instrumentationTask = project.getTasks()
63+
.create(sourceSet.getTaskName("instrument", "code") + Util.capitalize(project.getName()),
64+
InstrumentationTask.class);
65+
instrumentationTask.getOutputs().dir(sourceSet.getOutput().getClassesDirs().getSingleFile().getPath() + "-instrumented");
66+
instrumentationTask.dependsOn(sourceSet.getClassesTaskName());
67+
instrumentationTask.setGroup(GROUP);
68+
instrumentationTask.setSourceSet(sourceSet);
69+
instrumentationTask.setConfiguration(instrumentationConfiguration);
70+
71+
Task postInstrumentationTask = project.getTasks()
72+
.create("post" + Util.capitalize(instrumentationTask.getName()));
73+
postInstrumentationTask.dependsOn(instrumentationTask);
74+
postInstrumentationTask.setGroup(GROUP);
75+
postInstrumentationTask.doLast(task -> {
76+
((ConfigurableFileCollection) sourceSet.getOutput().getClassesDirs()).setFrom(instrumentationTask.getOutputs().getFiles().getSingleFile());
77+
});
78+
sourceSet.compiledBy(postInstrumentationTask);
79+
}
80+
81+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* FlintMC
3+
* Copyright (C) 2020-2021 LabyMedia GmbH and contributors
4+
*
5+
* This program is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation; either
8+
* version 3 of the License, or (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public License
16+
* along with this program; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18+
*/
19+
20+
package net.flintmc.gradle.java.instrumentation.api;
21+
22+
import net.flintmc.gradle.FlintGradleException;
23+
24+
public class InstrumentationException extends FlintGradleException {
25+
26+
public InstrumentationException() {
27+
}
28+
29+
public InstrumentationException(String message) {
30+
super(message);
31+
}
32+
33+
public InstrumentationException(String message, Throwable cause) {
34+
super(message, cause);
35+
}
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* FlintMC
3+
* Copyright (C) 2020-2021 LabyMedia GmbH and contributors
4+
*
5+
* This program is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation; either
8+
* version 3 of the License, or (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public License
16+
* along with this program; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18+
*/
19+
20+
package net.flintmc.gradle.java.instrumentation.api;
21+
22+
/**
23+
* Entry point of an instrumentation.
24+
* Requires a Java Service to be registered and findable via a {@link java.util.ServiceLoader}.
25+
* This class exists only to make it possible to use things like dependency injection in a {@link net.flintmc.gradle.java.instrumentation.api.transformer.InstrumentationTransformer}.
26+
* If the {@link java.util.ServiceLoader} would look for {@link net.flintmc.gradle.java.instrumentation.api.transformer.InstrumentationTransformer} this would not be possible to do.
27+
* Furthermore, it is possible to specify more details about the {@link net.flintmc.gradle.java.instrumentation.api.transformer.InstrumentationTransformer} to register.
28+
*
29+
* @see InstrumentationTransformerRegistry
30+
*/
31+
public interface InstrumentationTransformerRegistrator {
32+
33+
/**
34+
* Initialize the instrumentation chain.
35+
*
36+
* @param registry the transformer registry to register all transformers on and retrieve information about the current transformation
37+
*/
38+
void initialize(InstrumentationTransformerRegistry registry);
39+
40+
}

0 commit comments

Comments
 (0)