Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Javadoc #25

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
import java.io.File;
import java.util.List;

/**
* A tweaker for the Alpha versions of Minecraft.
*
* @author Nathan Adams
*
*/
public class AlphaVanillaTweaker implements ITweaker {
private List<String> args;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
package net.minecraft.launchwrapper;

/**
* A transformer that transforms the names of classes. Please note that even though this interface does not extend {@link IClassTransformer}, name transformers registered to the class loader must implement it.
*
* @author Erik Broes
*
*/
public interface IClassNameTransformer {

/**
* Unmaps a class name.
*
* @param name The original name of the class.
* @return The unmapped name, which will become the name passed to {@link IClassTransformer#transform}.
*/
String unmapClassName(String name);


/**
* Remaps a class name.
*
* @param name The original name of the class.
* @return The remapped name, which will become the transformedName passed tp {@link IClassTransformer#transform}.
*/
String remapClassName(String name);

}
16 changes: 14 additions & 2 deletions src/main/java/net/minecraft/launchwrapper/IClassTransformer.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
package net.minecraft.launchwrapper;

/**
* A transformer that modifies bytecode of classes loaded by the class loader.
*
* @author Erik Broes
*
*/
public interface IClassTransformer {

/**
* Transforms the bytecode of a class.
*
* @param name The untransformed name of the class, which is the result of {@link IClassNameTransformer#unmapClassName}, or the original name if no class name transformer is present.
* @param transformedName The transformed name of the class, which is the result of {@link IClassNameTransformer#remapClassName}, or the original name if no class name transformer is present.
* @param basicClass The bytecode of the class to transform.
* @return The transformed bytecode.
*/
byte[] transform(String name, String transformedName, byte[] basicClass);

}
37 changes: 32 additions & 5 deletions src/main/java/net/minecraft/launchwrapper/ITweaker.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,41 @@
import java.io.File;
import java.util.List;

/**
* A tweaker that changes parts of Minecraft.
*
* @author Erik Broes
*
*/
public interface ITweaker {

/**
* Provides the tweaker with options that may influence the behavior.
*
* @param args The arguments that were passed, excluding the gameDir, assetsDir, profile, and tweakClass arguments.
* @param gameDir The game directory that Minecraft is being launched in.
* @param assetsDir The directory that contains Minecraft's assets.
* @param profile The version that Minecraft is being launched in.
*/
void acceptOptions(List<String> args, File gameDir, final File assetsDir, String profile);


/**
* Performs injection into the class loader. Transformers are registered with {@link LaunchClassLoader#registerTransformer}.
*
* @param classLoader The class loader where transformers should be injected. The tweak class was not loaded with this class loader.
*/
void injectIntoClassLoader(LaunchClassLoader classLoader);


/**
* Gets the main class that should be launched. This method is only invoked on the primary tweaker (the tweaker that appears first).
*
* @return The main class.
*/
String getLaunchTarget();


/**
* Gets a list of arguments. This list will be combined with arguments from other tweakers to form an uber list. Please note that the original launch args are not added automatically.
*
* @return A list of arguments to add.
*/
String[] getLaunchArguments();

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
import java.io.File;
import java.util.List;

/**
* A tweaker to inject into the Indev versions of Minecraft.
*
* @author Nathan Adams
*
*/
public class IndevVanillaTweaker implements ITweaker {
private List<String> args;

Expand Down
56 changes: 45 additions & 11 deletions src/main/java/net/minecraft/launchwrapper/Launch.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,52 +18,86 @@

import org.apache.logging.log4j.Level;

/**
* The main class of the launch wrapper.
*
* @author cpw, Erik Broes, Mumfrey, and Nathan Adams
*
*/
public class Launch {
private static final String DEFAULT_TWEAK = "net.minecraft.launchwrapper.VanillaTweaker";

/**
* The game dir of Minecraft. Changing this will change the gameDir value passed to tweakers.
*/
public static File minecraftHome;

/**
* The asset dir of Minecraft. Changing this will change the assetsDir value passed to tweakers.
*/
public static File assetsDir;

/**
* A map that contains information that tweakers can access.
*/
public static Map<String,Object> blackboard;


/**
* The main method. Please don't invoke this.
*
* @param args The command line arguments.
*/
public static void main(String[] args) {
new Launch().launch(args);
}


/**
* The class loader to register transformers to. Changing this will change the class loader passed to tweakers.
*/
public static LaunchClassLoader classLoader;


/**
* Creates a new instance of Launch. This is only used in the main method.
*/
private Launch() {
final URLClassLoader ucl = (URLClassLoader) getClass().getClassLoader();
classLoader = new LaunchClassLoader(ucl.getURLs());
blackboard = new HashMap<String,Object>();
Thread.currentThread().setContextClassLoader(classLoader);
}


/**
* Runs the launch wrapper. This is only used in the main method.
*
* @param args The command line arguments.
*/
private void launch(String[] args) {
final OptionParser parser = new OptionParser();
parser.allowsUnrecognizedOptions();

final OptionSpec<String> profileOption = parser.accepts("version", "The version we launched with").withRequiredArg();
final OptionSpec<File> gameDirOption = parser.accepts("gameDir", "Alternative game directory").withRequiredArg().ofType(File.class);
final OptionSpec<File> assetsDirOption = parser.accepts("assetsDir", "Assets directory").withRequiredArg().ofType(File.class);
final OptionSpec<String> tweakClassOption = parser.accepts("tweakClass", "Tweak class(es) to load").withRequiredArg().defaultsTo(DEFAULT_TWEAK);
final OptionSpec<String> nonOption = parser.nonOptions();

final OptionSet options = parser.parse(args);
minecraftHome = options.valueOf(gameDirOption);
assetsDir = options.valueOf(assetsDirOption);
final String profileName = options.valueOf(profileOption);
final List<String> tweakClassNames = new ArrayList<String>(options.valuesOf(tweakClassOption));

final List<String> argumentList = new ArrayList<String>();
// This list of names will be interacted with through tweakers. They can append to this list
// any 'discovered' tweakers from their preferred mod loading mechanism
// By making this object discoverable and accessible it's possible to perform
// things like cascading of tweakers
blackboard.put("TweakClasses", tweakClassNames);

// This argument list will be constructed from all tweakers. It is visible here so
// all tweakers can figure out if a particular argument is present, and add it if not
blackboard.put("ArgumentList", argumentList);

// This is to prevent duplicates - in case a tweaker decides to add itself or something
final Set<String> allTweakerNames = new HashSet<String>();
// The 'definitive' list of tweakers
Expand Down Expand Up @@ -106,7 +140,7 @@ private void launch(String[] args) {
primaryTweaker = tweaker;
}
}

// Now, iterate all the tweakers we just instantiated
for (final Iterator<ITweaker> it = tweakers.iterator(); it.hasNext(); ) {
final ITweaker tweaker = it.next();
Expand All @@ -125,7 +159,7 @@ private void launch(String[] args) {
for (final ITweaker tweaker : allTweakers) {
argumentList.addAll(Arrays.asList(tweaker.getLaunchArguments()));
}

// Finally we turn to the primary tweaker, and let it tell us where to go to launch
final String launchTarget = primaryTweaker.getLaunchTarget();
final Class<?> clazz = Class.forName(launchTarget, false, classLoader);
Expand Down
81 changes: 71 additions & 10 deletions src/main/java/net/minecraft/launchwrapper/LaunchClassLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,16 @@
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;

/**
* The class loader to inject transformers in to.
*
* @author cpw, Erik Broes, Mumfrey, and Nathan Adams
*
*/
public class LaunchClassLoader extends URLClassLoader {
/**
* The size of the chunks when fully reading a stream.
*/
public static final int BUFFER_SIZE = 1 << 12;
private List<URL> sources;
private ClassLoader parent = getClass().getClassLoader();
Expand All @@ -42,7 +51,12 @@ public class LaunchClassLoader extends URLClassLoader {
private static final boolean DEBUG_FINER = DEBUG && Boolean.parseBoolean(System.getProperty("legacy.debugClassLoadingFiner", "false"));
private static final boolean DEBUG_SAVE = DEBUG && Boolean.parseBoolean(System.getProperty("legacy.debugClassLoadingSave", "false"));
private static File tempFolder = null;


/**
* Creates a new {@link LaunchClassLoader}.
*
* @param sources The URLs to load from.
*/
public LaunchClassLoader(URL[] sources) {
super(sources, null);
this.sources = new ArrayList<URL>(Arrays.asList(sources));
Expand Down Expand Up @@ -78,7 +92,12 @@ public LaunchClassLoader(URL[] sources) {
}
}
}


/**
* Registers a transformer. The transformer will be loaded with this class loader, not the parent one.
*
* @param transformerClassName The transformer to inject.
*/
public void registerTransformer(String transformerClassName) {
try {
IClassTransformer transformer = (IClassTransformer) loadClass(transformerClassName).newInstance();
Expand All @@ -90,7 +109,12 @@ public void registerTransformer(String transformerClassName) {
LogWrapper.log(Level.ERROR, e, "A critical problem occurred registering the ASM transformer class %s", transformerClassName);
}
}


/**
* Loads in a class. It is recommended to use {@link ClassLoader#loadClass} instead.
*
* @param name The name of the class to load.
*/
@Override
public Class<?> findClass(final String name) throws ClassNotFoundException {
if (invalidClasses.contains(name)) {
Expand Down Expand Up @@ -275,13 +299,23 @@ private byte[] runTransformers(final String name, final String transformedName,
}
return basicClass;
}


/**
* Adds a URL for the class loader to check.
*
* @param url The url to add.
*/
@Override
public void addURL(final URL url) {
super.addURL(url);
sources.add(url);
}


/**
* Gets the URL list.
*
* @return A list of URLs that this class loader checks.
*/
public List<URL> getSources() {
return sources;
}
Expand Down Expand Up @@ -320,19 +354,41 @@ private byte[] getOrCreateBuffer() {
}
return buffer;
}


/**
* Gets the transformers injected.
*
* @return An immutable list of transformers.
*/
public List<IClassTransformer> getTransformers() {
return Collections.unmodifiableList(transformers);
}


/**
* Adds the given prefix to the class loader exclusion list. Classes that have a prefix in this list will be loaded with the parent class loader.
*
* @param toExclude The prefix to exclude.
*/
public void addClassLoaderExclusion(String toExclude) {
classLoaderExceptions.add(toExclude);
}


/**
* Adds the given prefix to the transformer exclusion list. Classes that have a prefix in this list will be loaded without transformers being run on them.
*
* @param toExclude The prefix to exclude.
*/
public void addTransformerExclusion(String toExclude) {
transformerExceptions.add(toExclude);
}


/**
* Gets the bytecode of a class.
*
* @param name The name of the class.
* @return The untransformed bytecode of the class.
* @throws IOException If the class loader fails to open a connection to the URL.
*/
public byte[] getClassBytes(String name) throws IOException {
if (negativeResourceCache.contains(name)) {
return null;
Expand Down Expand Up @@ -380,7 +436,12 @@ private static void closeSilently(Closeable closeable) {
}
}
}


/**
* Removes entries that were previously marked invalid.
*
* @param entriesToClear The entries to remove.
*/
public void clearNegativeEntries(Set<String> entriesToClear) {
negativeResourceCache.removeAll(entriesToClear);
}
Expand Down
Loading