package net.minecraftforge.gradle.tweakers;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import net.minecraft.launchwrapper.ITweaker;
import net.minecraft.launchwrapper.Launch;
import net.minecraft.launchwrapper.LaunchClassLoader;
import net.minecraftforge.gradle.GradleStartCommon;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class CoremodTweaker implements ITweaker
{
protected static final Logger LOGGER = LogManager.getLogger("GradleStart");
private static final String COREMOD_CLASS = "fml.relauncher.CoreModManager";
private static final String TWEAKER_SORT_FIELD = "tweakSorting";
@Override
public void acceptOptions(List<String> args, File gameDir, File assetsDir, String profile)
{
}
@SuppressWarnings("unchecked")
@Override
public void injectIntoClassLoader(LaunchClassLoader classLoader)
{
try
{
Field coreModList = GradleStartCommon.getFmlClass("fml.relauncher.CoreModManager", classLoader).getDeclaredField("loadPlugins");
coreModList.setAccessible(true);
// grab constructor.
Class<ITweaker> clazz = (Class<ITweaker>) GradleStartCommon.getFmlClass("fml.relauncher.CoreModManager$FMLPluginWrapper", classLoader);
Constructor<ITweaker> construct = (Constructor<ITweaker>) clazz.getConstructors()[0];
construct.setAccessible(true);
Field[] fields = clazz.getDeclaredFields();
Field pluginField = fields[1]; // 1
Field fileField = fields[3]; // 3
Field listField = fields[2]; // 2
Field.setAccessible(clazz.getConstructors(), true);
Field.setAccessible(fields, true);
List<ITweaker> oldList = (List<ITweaker>) coreModList.get(null);
for (int i = 0; i < oldList.size(); i++)
{
ITweaker tweaker = oldList.get(i);
if (clazz.isInstance(tweaker))
{
Object coreMod = pluginField.get(tweaker);
Object oldFile = fileField.get(tweaker);
File newFile = GradleStartCommon.coreMap.get(coreMod.getClass().getCanonicalName());
LOGGER.info("Injecting location in coremod {}", coreMod.getClass().getCanonicalName());
if (newFile != null && oldFile == null)
{
// build new tweaker.
oldList.set(i, construct.newInstance(new Object[] {
(String) fields[0].get(tweaker), // name
coreMod, // coremod
newFile, // location
fields[4].getInt(tweaker), // sort index?
((List<String>) listField.get(tweaker)).toArray(new String[0])
}));
}
}
}
}
catch (Throwable t)
{
LOGGER.log(Level.ERROR, "Something went wrong with the coremod adding.");
t.printStackTrace();
}
// inject the additional AT tweaker
String atTweaker = "net.minecraftforge.gradle.tweakers.AccessTransformerTweaker";
((List<String>) Launch.blackboard.get("TweakClasses")).add(atTweaker);
// make sure its after the deobf tweaker
try
{
Field f = GradleStartCommon.getFmlClass(COREMOD_CLASS, classLoader).getDeclaredField(TWEAKER_SORT_FIELD);
f.setAccessible(true);
((Map<String, Integer>) f.get(null)).put(atTweaker, Integer.valueOf(1001));
}
catch (Throwable t)
{
LOGGER.log(Level.ERROR, "Something went wrong with the adding the AT tweaker adding.");
t.printStackTrace();
}
}
@Override
public String getLaunchTarget()
{
// if it gets here... something went terribly wrong..
return null;
}
@Override
public String[] getLaunchArguments()
{
// if it gets here... something went terribly wrong.
return new String[0];
}
}