Compare commits

..
10 Commits
Author SHA1 Message Date
TacoMagickandRecursivePineapple bb98bdc6d4 Revert "Fix ItemStack packet id limited by short" (#23) (#37)
Co-authored-by: RecursivePineapple <recursive_pineapple@proton.me>
2025-11-11 17:21:20 +00:00
Alexdoru 4e5bcf829c ASM Housekeeping (#36) 2025-11-11 12:13:45 -05:00
Alexdoru 678970e48b Delete DepLoader entirely (#35) 2025-08-11 16:52:51 +02:00
AlexdoruandMartin Robertz 5ad7ebe1ac further empty DepLoader (#34)
Co-authored-by: Martin Robertz <dream-master@gmx.net>
2025-08-09 23:51:19 +02:00
Dream Master 033009fed5 update 2025-08-08 18:58:12 +07:00
Alexdoru acd863e748 Speedup ClassDiscoverer by using ClassReader.SKIP_CODE (#33) 2025-08-07 22:10:04 +02:00
Martin Robertz 850e2b9368 update 2025-05-29 22:09:14 +02:00
FalsePattern 4713f7aebd modern java compat (#31) 2025-05-29 19:26:51 +00:00
Jason Mitchell b999279656 More thread safe, again. (#30) 2025-05-04 08:08:02 +09:00
mts2200 1879ba2071 Improve NPE checks (#26) 2025-01-08 18:51:06 +00:00
30 changed files with 357 additions and 461 deletions

No files matched your search

+5
View File
@@ -3,3 +3,8 @@
plugins {
id 'com.gtnewhorizons.gtnhconvention'
}
minecraft {
//extraRunJvmArguments.add("-Dccc.dev.runtimePublic=true")
//extraRunJvmArguments.add("-Dccc.dev.deobfuscate=true")
}
+2 -2
View File
@@ -14,7 +14,7 @@ modId = CodeChickenCore
modGroup = codechicken
# Whether to use modGroup as the maven publishing group.
# Due to a history of using JitPack, the default is com.github.GTNewHorizons for all mods.
# When false, com.github.GTNewHorizons is used.
useModGroupForPublishing = false
# Updates your build.gradle and settings.gradle automatically whenever an update is available.
@@ -145,7 +145,7 @@ modrinthProjectId = codechickencore-unofficial
# type can be one of [project, version],
# and the name is the Modrinth project or version slug/id of the other mod.
# Example: required-project:fplib;optional-project:gasstation;incompatible-project:gregtech
# Note: GTNH Mixins is automatically set as a required dependency if usesMixins = true
# Note: UniMixins is automatically set as a required dependency if usesMixins = true.
modrinthRelations =
# Publishing to CurseForge requires you to set the CURSEFORGE_TOKEN environment variable to one of your CurseForge API tokens.
Binary file not shown.
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Vendored
+2 -3
View File
@@ -86,8 +86,7 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -206,7 +205,7 @@ fi
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
+1
View File
@@ -1,4 +1,5 @@
// Add any additional repositiroes for your dependencies here
repositories {
mavenLocal()
}
+1 -1
View File
@@ -17,7 +17,7 @@ pluginManagement {
}
plugins {
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.30'
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.41'
}
@@ -11,6 +11,7 @@ import java.util.zip.ZipFile;
import net.minecraft.launchwrapper.Launch;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.ClassNode;
import com.google.common.collect.ImmutableList;
@@ -22,6 +23,7 @@ import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ModClassLoader;
import cpw.mods.fml.relauncher.CoreModManager;
@SuppressWarnings("unused")
public class ClassDiscoverer {
public IStringMatcher matcher;
@@ -35,17 +37,12 @@ public class ClassDiscoverer {
for (int i = 0; i < superclasses.length; i++)
this.superclasses[i] = superclasses[i].getName().replace('.', '/');
classes = new ArrayList<Class<?>>();
classes = new ArrayList<>();
modClassLoader = (ModClassLoader) Loader.instance().getModClassLoader();
}
public ClassDiscoverer(Class<?>... superclasses) {
this(new IStringMatcher() {
public boolean matches(String test) {
return true;
}
}, superclasses);
this(test -> true, superclasses);
}
public ArrayList<Class<?>> findClasses() {
@@ -63,7 +60,7 @@ public class ClassDiscoverer {
byte[] bytes = Launch.classLoader.getClassBytes(classname);
if (bytes == null) return;
ClassNode cnode = ASMHelper.createClassNode(bytes);
ClassNode cnode = ASMHelper.createClassNode(bytes, ClassReader.SKIP_CODE);
for (String superclass : superclasses)
if (!cnode.interfaces.contains(superclass) && !cnode.superName.equals(superclass)) return;
@@ -86,7 +83,7 @@ public class ClassDiscoverer {
List<String> knownLibraries = ImmutableList.<String>builder().addAll(modClassLoader.getDefaultLibraries())
.addAll(CoreModManager.getLoadedCoremods()).build();
File[] minecraftSources = modClassLoader.getParentSources();
HashSet<String> searchedSources = new HashSet<String>();
HashSet<String> searchedSources = new HashSet<>();
for (File minecraftSource : minecraftSources) {
if (searchedSources.contains(minecraftSource.getAbsolutePath())) continue;
searchedSources.add(minecraftSource.getAbsolutePath());
@@ -5,32 +5,19 @@ import java.lang.reflect.Field;
import com.google.common.collect.ImmutableBiMap;
import codechicken.lib.asm.ObfMapping;
import cpw.mods.fml.common.asm.transformers.AccessTransformer;
import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
// This AccessTransformer will make all minecraft classes public at runtime in MCP just as they are in modloader.
// You should ONLY use this when you are testing with a mod that relies on runtime publicity and doesn't include
// access transformers. Such mods are doing the wrong thing and should be fixed.
public class CodeChickenAccessTransformer extends AccessTransformer {
private static boolean makeAllPublic;
private static Field f_classNameBiMap;
private static final Field f_classNameBiMap;
@SuppressWarnings("FieldMayBeFinal")
private static Object emptyMap = ImmutableBiMap.of();
public CodeChickenAccessTransformer() throws IOException {
super();
loadPublicConfig();
}
private void loadPublicConfig() {
if (ObfMapping.obfuscated) return;
makeAllPublic = CodeChickenCoreModContainer.config.getTag("dev.runtimePublic").setComment(
"Enabling this setting will make all minecraft classes public at runtime in MCP just as they are in modloader."
+ "\nYou should ONLY use this when you are testing with a mod that relies on runtime publicity and doesn't include access transformers."
+ "\nSuch mods are doing the wrong thing and should be fixed.")
.getBooleanValue(false);
if (!makeAllPublic) return;
static {
try {
f_classNameBiMap = FMLDeobfuscatingRemapper.class.getDeclaredField("classNameBiMap");
f_classNameBiMap.setAccessible(true);
@@ -39,16 +26,18 @@ public class CodeChickenAccessTransformer extends AccessTransformer {
}
}
public CodeChickenAccessTransformer() throws IOException {}
@Override
public byte[] transform(String name, String transformedName, byte[] bytes) {
boolean setPublic = makeAllPublic && name.startsWith("net.minecraft.");
boolean setPublic = name.startsWith("net.minecraft.");
if (setPublic) setClassMap(name);
bytes = super.transform(name, transformedName, bytes);
if (setPublic) restoreClassMap();
return bytes;
}
private void restoreClassMap() {
private static void restoreClassMap() {
try {
f_classNameBiMap.set(FMLDeobfuscatingRemapper.INSTANCE, emptyMap);
} catch (Exception e) {
@@ -56,7 +45,7 @@ public class CodeChickenAccessTransformer extends AccessTransformer {
}
}
private void setClassMap(String name) {
private static void setClassMap(String name) {
try {
f_classNameBiMap.set(FMLDeobfuscatingRemapper.INSTANCE, ImmutableBiMap.of(name.replace('.', '/'), ""));
} catch (Exception e) {
@@ -1,6 +1,5 @@
package codechicken.core.asm;
import java.io.File;
import java.util.LinkedList;
import java.util.List;
@@ -13,7 +12,6 @@ import codechicken.core.ClientUtils;
import codechicken.core.featurehack.LiquidTextures;
import codechicken.core.internal.CCCEventHandler;
import codechicken.core.launch.CodeChickenCorePlugin;
import codechicken.lib.config.ConfigFile;
import cpw.mods.fml.common.DummyModContainer;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.LoadController;
@@ -26,14 +24,6 @@ import cpw.mods.fml.common.versioning.VersionRange;
public class CodeChickenCoreModContainer extends DummyModContainer {
public static ConfigFile config;
public static void loadConfig() {
if (config == null)
config = new ConfigFile(new File(CodeChickenCorePlugin.minecraftDir, "config/CodeChickenCore.cfg"))
.setComment("CodeChickenCore configuration file.");
}
public CodeChickenCoreModContainer() {
super(getModMetadata());
}
@@ -7,35 +7,50 @@ import java.util.HashSet;
import java.util.LinkedList;
import net.minecraft.launchwrapper.IClassTransformer;
import net.minecraft.launchwrapper.LaunchClassLoader;
import net.minecraft.launchwrapper.Launch;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import codechicken.lib.asm.ASMHelper;
import codechicken.lib.asm.ClassHeirachyManager;
import codechicken.lib.asm.ObfMapping;
import cpw.mods.fml.relauncher.FMLRelaunchLog;
public class DefaultImplementationTransformer implements IClassTransformer {
private static LaunchClassLoader cl = (LaunchClassLoader) ClassHeirachyManager.class.getClassLoader();
private static final HashMap<String, InterfaceImpl> impls = new HashMap<>();
private static ClassNode getClassNode(String name) {
try {
return ASMHelper.createClassNode(cl.getClassBytes(name.replace('/', '.')));
} catch (IOException e) {
throw new RuntimeException(e);
public static void registerDefaultImpl(String iname, String cname) {
if (impls.isEmpty()) {
String name = DefaultImplementationTransformer.class.getName();
FMLRelaunchLog.finer("Registering transformer %s", name);
Launch.classLoader.registerTransformer(name);
}
impls.put(iname.replace('.', '/'), new InterfaceImpl(iname, cname));
}
@Override
public byte[] transform(String name, String transformedName, byte[] bytes) {
if (transformedName.startsWith("net.minecraft") || impls.isEmpty()) return bytes;
ClassNode cnode = ASMHelper.createClassNode(bytes);
boolean changed = false;
for (String iname : cnode.interfaces) {
InterfaceImpl impl = impls.get(iname);
if (impl != null) changed |= impl.patch(cnode);
}
return changed ? ASMHelper.createBytes(cnode, 0) : bytes;
}
static class InterfaceImpl {
public final String iname;
public ArrayList<MethodNode> impls = new ArrayList<MethodNode>();
public ArrayList<MethodNode> impls = new ArrayList<>();
public InterfaceImpl(String iname, String cname) {
this.iname = iname;
HashSet<String> names = new HashSet<String>();
HashSet<String> names = new HashSet<>();
ClassNode inode = getClassNode(iname);
for (MethodNode method : inode.methods) names.add(method.name + method.desc);
@@ -47,7 +62,7 @@ public class DefaultImplementationTransformer implements IClassTransformer {
}
public boolean patch(ClassNode cnode) {
LinkedList<String> names = new LinkedList<String>();
LinkedList<String> names = new LinkedList<>();
for (MethodNode method : cnode.methods) {
ObfMapping m = new ObfMapping(cnode.name, method.name, method.desc).toRuntime();
names.add(m.s_name + m.s_desc);
@@ -69,25 +84,13 @@ public class DefaultImplementationTransformer implements IClassTransformer {
}
return changed;
}
}
private static HashMap<String, InterfaceImpl> impls = new HashMap<String, InterfaceImpl>();
public static void registerDefaultImpl(String iname, String cname) {
impls.put(iname.replace('.', '/'), new InterfaceImpl(iname, cname));
}
@Override
public byte[] transform(String name, String transformedName, byte[] bytes) {
if (transformedName.startsWith("net.minecraft") || impls.isEmpty()) return bytes;
ClassNode cnode = ASMHelper.createClassNode(bytes);
boolean changed = false;
for (String iname : cnode.interfaces) {
InterfaceImpl impl = impls.get(iname);
if (impl != null) changed |= impl.patch(cnode);
private static ClassNode getClassNode(String name) {
try {
return ASMHelper.createClassNode(Launch.classLoader.getClassBytes(name.replace('/', '.')));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return changed ? ASMHelper.createBytes(cnode, 0) : bytes;
}
}
@@ -1,7 +1,5 @@
package codechicken.core.asm;
import static codechicken.core.launch.CodeChickenCorePlugin.logger;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
@@ -11,7 +9,9 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Map;
import java.util.Stack;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import net.minecraft.launchwrapper.IClassTransformer;
@@ -21,14 +21,18 @@ import net.minecraft.launchwrapper.LaunchClassLoader;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Opcodes;
import codechicken.core.launch.CodeChickenCorePlugin;
import cpw.mods.fml.relauncher.FMLRelaunchLog;
public class DelegatedTransformer implements IClassTransformer {
private static ArrayList<IClassTransformer> delegatedTransformers;
private static Method m_defineClass;
private static Field f_cachedClasses;
private static final ArrayList<IClassTransformer> delegatedTransformers;
private static final Method m_defineClass;
private static final Field f_cachedClasses;
private static IClassTransformer[] transformers;
public DelegatedTransformer() {
delegatedTransformers = new ArrayList<IClassTransformer>();
static {
delegatedTransformers = new ArrayList<>();
try {
m_defineClass = ClassLoader.class
.getDeclaredMethod("defineClass", String.class, byte[].class, Integer.TYPE, Integer.TYPE);
@@ -41,14 +45,75 @@ public class DelegatedTransformer implements IClassTransformer {
}
@Override
public byte[] transform(String name, String tname, byte[] bytes) {
if (bytes == null) return null;
for (IClassTransformer trans : delegatedTransformers) bytes = trans.transform(name, tname, bytes);
return bytes;
public byte[] transform(String name, String transformedName, byte[] basicClass) {
if (basicClass == null) return null;
for (IClassTransformer t : transformers) {
basicClass = t.transform(name, transformedName, basicClass);
}
return basicClass;
}
public static void load() {
scanModsForDelegatedTransformers();
final int size = delegatedTransformers.size();
if (size == 0) {
CodeChickenCorePlugin.logger
.debug("No delegated transformer found, skipping registration of main DelegatedTransformer.");
return;
}
CodeChickenCorePlugin.logger
.debug("Found " + size + " delegated transformers, registering main DelegatedTransformer.");
transformers = delegatedTransformers.toArray(new IClassTransformer[0]);
String name = DelegatedTransformer.class.getName();
FMLRelaunchLog.finer("Registering transformer %s", name);
Launch.classLoader.registerTransformer(name);
}
private static void scanModsForDelegatedTransformers() {
File modsDir = new File(CodeChickenCorePlugin.minecraftDir, "mods");
if (modsDir.exists()) {
final File[] files = modsDir.listFiles();
if (files != null) {
for (File file : files) {
scanMod(file);
}
}
}
File versionModsDir = new File(
CodeChickenCorePlugin.minecraftDir,
"mods/" + CodeChickenCorePlugin.currentMcVersion);
if (versionModsDir.exists()) {
final File[] files = versionModsDir.listFiles();
if (files != null) {
for (File file : files) {
scanMod(file);
}
}
}
}
private static void scanMod(File file) {
if (!file.getName().endsWith(".jar") && !file.getName().endsWith(".zip")) return;
try {
try (JarFile jar = new JarFile(file)) {
Manifest manifest = jar.getManifest();
if (manifest == null) return;
Attributes attr = manifest.getMainAttributes();
if (attr == null) return;
String transformer = attr.getValue("CCTransformer");
if (transformer != null) {
addTransformer(transformer, jar, file);
}
}
} catch (Exception e) {
CodeChickenCorePlugin.logger.error("CodeChickenCore: Failed to read jar file: " + file.getName(), e);
}
}
public static void addTransformer(String transformer, JarFile jar, File jarFile) {
logger.debug("Adding CCTransformer: " + transformer);
CodeChickenCorePlugin.logger.debug("Adding CCTransformer: " + transformer);
try {
byte[] bytes;
bytes = Launch.classLoader.getClassBytes(transformer);
@@ -107,7 +172,7 @@ public class DelegatedTransformer implements IClassTransformer {
byte[] depbytes = readFully(jar.getInputStream(entry));
defineDependancies(depbytes, jar, jarFile, depStack);
logger.debug("Defining dependancy: " + dependancy);
CodeChickenCorePlugin.logger.debug("Defining dependancy: " + dependancy);
defineClass(dependancy.replace('/', '.'), depbytes);
}
@@ -128,7 +193,6 @@ public class DelegatedTransformer implements IClassTransformer {
while ((r = stream.read()) != -1) {
bos.write(r);
}
return bos.toByteArray();
}
}
@@ -24,7 +24,6 @@ import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import codechicken.lib.asm.ASMHelper;
import codechicken.lib.asm.ASMInit;
import codechicken.lib.asm.CC_ClassWriter;
import codechicken.lib.asm.ObfMapping;
import codechicken.obfuscator.IHeirachyEvaluator;
@@ -35,15 +34,11 @@ import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
public class MCPDeobfuscationTransformer implements IClassTransformer, Opcodes, IHeirachyEvaluator {
static {
ASMInit.init();
}
public static class LoadPlugin implements IFMLLoadingPlugin {
@Override
public String[] getASMTransformerClass() {
return new String[0];
return null;
}
@Override
@@ -118,26 +113,20 @@ public class MCPDeobfuscationTransformer implements IClassTransformer, Opcodes,
}
public static void load() {
CodeChickenCoreModContainer.loadConfig();
run = new ObfuscationRun(
false,
ObfMapping.MCPRemapper.getConfFiles(),
ObfuscationRun.fillDefaults(new HashMap<String, String>()));
run.obf.setHeirachyEvaluator(instance);
run.setQuiet().parseMappings();
Collections.addAll(excludedPackages, run.config.get("excludedPackages").split(";"));
if (CodeChickenCoreModContainer.config.getTag("dev.deobfuscate")
.setComment("set to true to completely deobfuscate mcp names")
.getBooleanValue(!ObfMapping.obfuscated)) {
run = new ObfuscationRun(
false,
ObfMapping.MCPRemapper.getConfFiles(),
ObfuscationRun.fillDefaults(new HashMap<String, String>()));
run.obf.setHeirachyEvaluator(instance);
run.setQuiet().parseMappings();
Collections.addAll(excludedPackages, run.config.get("excludedPackages").split(";"));
if (ObfMapping.obfuscated) {
ObfMapping.loadMCPRemapper();
run.setSeargeConstants();
getTransformers().add(instance);
} else {
getTransformers().add(0, instance); // insert transformer as first.
}
if (ObfMapping.obfuscated) {
ObfMapping.loadMCPRemapper();
run.setSeargeConstants();
getTransformers().add(instance);
} else {
getTransformers().add(0, instance); // insert transformer as first.
}
}
@@ -5,14 +5,15 @@ import static codechicken.lib.asm.InsnComparator.findOnce;
import java.util.Map;
import net.minecraft.launchwrapper.IClassTransformer;
import net.minecraft.launchwrapper.Launch;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.MethodNode;
import codechicken.core.launch.CodeChickenCorePlugin;
import codechicken.lib.asm.ASMBlock;
import codechicken.lib.asm.ASMInit;
import codechicken.lib.asm.ASMReader;
import codechicken.lib.asm.ModularASMTransformer;
import codechicken.lib.asm.ModularASMTransformer.MethodReplacer;
@@ -20,20 +21,29 @@ import codechicken.lib.asm.ModularASMTransformer.MethodTransformer;
import codechicken.lib.asm.ModularASMTransformer.MethodWriter;
import codechicken.lib.asm.ObfMapping;
import codechicken.lib.config.ConfigTag;
import cpw.mods.fml.relauncher.FMLRelaunchLog;
public class TweakTransformer implements IClassTransformer, Opcodes {
static {
ASMInit.init();
}
private static ModularASMTransformer transformer = new ModularASMTransformer();
private static Map<String, ASMBlock> blocks = ASMReader.loadResource("/assets/codechickencore/asm/tweaks.asm");
private static final ModularASMTransformer transformer = new ModularASMTransformer();
private static final Map<String, ASMBlock> blocks = ASMReader
.loadResource("/assets/codechickencore/asm/tweaks.asm");
public static ConfigTag tweaks;
public static void load() {
CodeChickenCoreModContainer.loadConfig();
tweaks = CodeChickenCoreModContainer.config.getTag("tweaks")
loadTransformersFromConfig();
if (transformer.isEmpty()) {
CodeChickenCorePlugin.logger
.debug("No tweaks parsed from config, skipping registration of TweakTransformer.");
return;
}
String name = TweakTransformer.class.getName();
FMLRelaunchLog.finer("Registering transformer %s", name);
Launch.classLoader.registerTransformer(name);
}
private static void loadTransformersFromConfig() {
tweaks = CodeChickenCorePlugin.config.getTag("tweaks")
.setComment("Various tweaks that can be applied to game mechanics.").useBraces();
tweaks.removeTag("persistantLava");
@@ -103,7 +113,7 @@ public class TweakTransformer implements IClassTransformer, Opcodes {
}
@Override
public byte[] transform(String name, String tname, byte[] bytes) {
public final byte[] transform(String name, String tname, byte[] bytes) {
return transformer.transform(name, bytes);
}
}
@@ -9,9 +9,6 @@ import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.List;
import java.util.Map;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import javax.swing.JEditorPane;
import javax.swing.JOptionPane;
@@ -21,48 +18,87 @@ import javax.swing.event.HyperlinkListener;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import codechicken.core.asm.CodeChickenCoreModContainer;
import codechicken.core.asm.DelegatedTransformer;
import codechicken.core.asm.MCPDeobfuscationTransformer;
import codechicken.core.asm.Tags;
import codechicken.core.asm.TweakTransformer;
import codechicken.lib.config.ConfigFile;
import codechicken.lib.config.ConfigTag;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
import cpw.mods.fml.common.versioning.VersionParser;
import cpw.mods.fml.relauncher.CoreModManager;
import cpw.mods.fml.relauncher.FMLInjectionData;
import cpw.mods.fml.relauncher.IFMLCallHook;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin.MCVersion;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin.TransformerExclusions;
@TransformerExclusions(value = { "codechicken.core.asm", "codechicken.obfuscator" })
@MCVersion("1.7.10")
public class CodeChickenCorePlugin implements IFMLLoadingPlugin, IFMLCallHook {
@IFMLLoadingPlugin.MCVersion("1.7.10")
@IFMLLoadingPlugin.TransformerExclusions({ "codechicken.core.asm", "codechicken.obfuscator", "codechicken.lib.asm",
"codechicken.lib.config" })
public class CodeChickenCorePlugin implements IFMLLoadingPlugin {
public static final String mcVersion = "[1.7.10]";
@Deprecated
public static final String version = Tags.VERSION;
public static ConfigFile config;
public static File minecraftDir;
public static String currentMcVersion;
public static Logger logger = LogManager.getLogger("CodeChickenCore");
public CodeChickenCorePlugin() {
if (minecraftDir != null) return; // get called twice, once for IFMLCallHook
if (minecraftDir != null) return;
minecraftDir = (File) FMLInjectionData.data()[6];
currentMcVersion = (String) FMLInjectionData.data()[4];
config = new ConfigFile(new File(minecraftDir, "config/CodeChickenCore.cfg"))
.setComment("CodeChickenCore configuration file.");
if (Boolean.getBoolean("ccc.dev.deobfuscate")) {
injectDeobfPlugin();
}
}
injectDeobfPlugin();
@Override
public String[] getASMTransformerClass() {
versionCheck(mcVersion, "CodeChickenCore");
return new String[] { "codechicken.lib.asm.ClassHeirachyManager", "codechicken.lib.asm.RedirectorTransformer" };
}
@Override
public String getAccessTransformerClass() {
if (Boolean.getBoolean("ccc.dev.runtimePublic")) {
return "codechicken.core.asm.CodeChickenAccessTransformer";
} else {
return null;
}
}
@Override
public String getModContainerClass() {
return "codechicken.core.asm.CodeChickenCoreModContainer";
}
@Override
public String getSetupClass() {
return null;
}
@Override
public void injectData(Map<String, Object> data) {
ConfigTag checkRAM = CodeChickenCorePlugin.config.getTag("checks")
.setComment("Configuration options for checking various requirements for a modpack.").useBraces();
if (checkRAM.getTag("checkRAM")
.setComment("If set to true, check RAM available for Minecraft before continuing to load")
.getBooleanValue(false)) {
systemCheck(checkRAM);
}
TweakTransformer.load();
DelegatedTransformer.load();
}
private void injectDeobfPlugin() {
try {
Class<?> wrapperClass = Class.forName("cpw.mods.fml.relauncher.CoreModManager$FMLPluginWrapper");
Constructor wrapperConstructor = wrapperClass
Constructor<?> wrapperConstructor = wrapperClass
.getConstructor(String.class, IFMLLoadingPlugin.class, File.class, Integer.TYPE, String[].class);
Field f_loadPlugins = CoreModManager.class.getDeclaredField("loadPlugins");
wrapperConstructor.setAccessible(true);
@@ -76,7 +112,7 @@ public class CodeChickenCorePlugin implements IFMLLoadingPlugin, IFMLCallHook {
0,
new String[0]));
} catch (Exception e) {
logger.error("Failed to inject MCPDeobfuscation Transformer", e);
logger.error("Failed to inject FMLPluginWrapper for MCPDeobfuscation Transformer", e);
}
}
@@ -186,74 +222,4 @@ public class CodeChickenCorePlugin implements IFMLLoadingPlugin, IFMLCallHook {
FMLCommonHandler.instance().exitJava(-98, true);
}
}
@Override
public String[] getASMTransformerClass() {
versionCheck(mcVersion, "CodeChickenCore");
return new String[] { "codechicken.lib.asm.ClassHeirachyManager", "codechicken.core.asm.TweakTransformer",
"codechicken.core.asm.DelegatedTransformer", "codechicken.core.asm.DefaultImplementationTransformer",
"codechicken.lib.asm.RedirectorTransformer" };
}
@Override
public String getAccessTransformerClass() {
return "codechicken.core.asm.CodeChickenAccessTransformer";
}
@Override
public String getModContainerClass() {
return "codechicken.core.asm.CodeChickenCoreModContainer";
}
@Override
public String getSetupClass() {
return getClass().getName();
}
@Override
public void injectData(Map<String, Object> data) {}
@Override
public Void call() {
CodeChickenCoreModContainer.loadConfig();
ConfigTag checkRAM;
checkRAM = CodeChickenCoreModContainer.config.getTag("checks")
.setComment("Configuration options for checking various requirements for a modpack.").useBraces();
if (checkRAM.getTag("checkRAM")
.setComment("If set to true, check RAM available for Minecraft before continuing to load")
.getBooleanValue(false))
systemCheck(checkRAM);
TweakTransformer.load();
scanCodeChickenMods();
return null;
}
private void scanCodeChickenMods() {
File modsDir = new File(minecraftDir, "mods");
for (File file : modsDir.listFiles()) scanMod(file);
File versionModsDir = new File(minecraftDir, "mods/" + currentMcVersion);
if (versionModsDir.exists()) for (File file : versionModsDir.listFiles()) scanMod(file);
}
private void scanMod(File file) {
if (!file.getName().endsWith(".jar") && !file.getName().endsWith(".zip")) return;
try {
JarFile jar = new JarFile(file);
try {
Manifest manifest = jar.getManifest();
if (manifest == null) return;
Attributes attr = manifest.getMainAttributes();
if (attr == null) return;
String transformer = attr.getValue("CCTransformer");
if (transformer != null) DelegatedTransformer.addTransformer(transformer, jar, file);
} finally {
jar.close();
}
} catch (Exception e) {
logger.error("CodeChickenCore: Failed to read jar file: " + file.getName(), e);
}
}
}
@@ -1,186 +0,0 @@
package codechicken.core.launch;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.Box;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import cpw.mods.fml.common.versioning.ComparableVersion;
import cpw.mods.fml.relauncher.IFMLCallHook;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin.MCVersion;
/**
* For autodownloading stuff. This is really unoriginal, mostly ripped off FML, credits to cpw.
*/
@MCVersion("1.7.10")
public class DepLoader implements IFMLLoadingPlugin, IFMLCallHook {
public interface IDownloadDisplay {
void resetProgress(int sizeGuess);
void setPokeThread(Thread currentThread);
void updateProgress(int fullLength);
boolean shouldStopIt();
void updateProgressString(String string, Object... data);
Object makeDialog();
void showErrorDialog(String name, String url);
}
@SuppressWarnings("serial")
public static class Downloader extends JOptionPane implements IDownloadDisplay {
boolean stopIt;
Thread pokeThread;
private Box makeProgressPanel() {
return null;
}
@Override
public JDialog makeDialog() {
return null;
}
protected void requestClose(String message) {}
@Override
public void updateProgressString(String progressUpdate, Object... data) {}
@Override
public void resetProgress(int sizeGuess) {}
@Override
public void updateProgress(int fullLength) {}
@Override
public void setPokeThread(Thread currentThread) {}
@Override
public boolean shouldStopIt() {
return true;
}
@Override
public void showErrorDialog(String name, String url) {}
}
public static class DummyDownloader implements IDownloadDisplay {
@Override
public void resetProgress(int sizeGuess) {}
@Override
public void setPokeThread(Thread currentThread) {}
@Override
public void updateProgress(int fullLength) {}
@Override
public boolean shouldStopIt() {
return false;
}
@Override
public void updateProgressString(String string, Object... data) {}
@Override
public Object makeDialog() {
return null;
}
@Override
public void showErrorDialog(String name, String url) {}
}
public static class VersionedFile {
public final Pattern pattern;
public final String filename;
public final ComparableVersion version;
public final String name;
public VersionedFile(String filename, Pattern pattern) {
this.pattern = pattern;
this.filename = filename;
Matcher m = pattern.matcher(filename);
if (m.matches()) {
name = m.group(1);
version = new ComparableVersion(m.group(2));
} else {
name = null;
version = null;
}
}
public boolean matches() {
return name != null;
}
}
public static class Dependency {
public String url;
public VersionedFile file;
public String existing;
/**
* Flag set to add this dep to the classpath immediately because it is required for a coremod.
*/
public boolean coreLib;
public Dependency(String url, VersionedFile file, boolean coreLib) {
this.url = url;
this.file = file;
this.coreLib = coreLib;
}
}
public static class DepLoadInst {
public DepLoadInst() {}
public void load() {}
}
public static void load() {}
@Override
public String[] getASMTransformerClass() {
return null;
}
@Override
public String getModContainerClass() {
return null;
}
@Override
public String getSetupClass() {
return getClass().getName();
}
@Override
public void injectData(Map<String, Object> data) {}
@Override
public Void call() {
load();
return null;
}
@Override
public String getAccessTransformerClass() {
return null;
}
}
@@ -18,10 +18,6 @@ import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
*/
public class ClassHeirachyManager implements IClassTransformer {
static {
ASMInit.init();
}
public static class SuperCache {
String superclass;
@@ -275,17 +275,22 @@ public class ModularASMTransformer {
}
}
public HashMap<String, ClassNodeTransformerList> transformers = new HashMap<String, ClassNodeTransformerList>();
public HashMap<String, ClassNodeTransformerList> transformers = new HashMap<>();
public void add(ClassNodeTransformer t) {
ClassNodeTransformerList list = transformers.get(t.className());
if (list == null) transformers.put(t.className(), list = new ClassNodeTransformerList());
if (list == null) {
transformers.put(t.className(), list = new ClassNodeTransformerList());
}
list.add(t);
}
public boolean isEmpty() {
return transformers.isEmpty();
}
public byte[] transform(String name, byte[] bytes) {
if (bytes == null) return null;
ClassNodeTransformerList list = transformers.get(name);
return list == null ? bytes : list.transform(bytes);
}
@@ -59,7 +59,12 @@ public class RedirectorTransformer implements IClassTransformer, Opcodes {
"hasBrightness",
"brightness",
"side",
"lc"
"lc",
"normalAttrib",
"colourAttrib",
"lightCoordAttrib",
"sideAttrib",
"lightingAttrib"
);
Collections.addAll(redirectedSimpleMethods, "reset", "pullLightmap", "pushLightmap", "setDynamic", "draw");
@@ -81,8 +81,8 @@ public class LightModel implements CCRenderState.IVertexOperation {
public boolean load(CCRenderState state) {
if (!state.computeLighting) return false;
state.pipeline.addDependency(CCRenderState.normalAttrib);
state.pipeline.addDependency(CCRenderState.colourAttrib);
state.pipeline.addDependency(CCRenderState.normalAttrib());
state.pipeline.addDependency(CCRenderState.colourAttrib());
return true;
}
@@ -40,7 +40,7 @@ public class PlanarLightMatrix extends PlanarLightModel {
@Override
public boolean load(CCRenderState state) {
state.pipeline.addDependency(CCRenderState.sideAttrib);
state.pipeline.addDependency(CCRenderState.sideAttrib());
return true;
}
@@ -20,8 +20,8 @@ public class PlanarLightModel implements CCRenderState.IVertexOperation {
public boolean load(CCRenderState state) {
if (!state.computeLighting) return false;
state.pipeline.addDependency(CCRenderState.sideAttrib);
state.pipeline.addDependency(CCRenderState.colourAttrib);
state.pipeline.addDependency(CCRenderState.sideAttrib());
state.pipeline.addDependency(CCRenderState.colourAttrib());
return true;
}
@@ -40,7 +40,7 @@ public class SimpleBrightnessModel implements CCRenderState.IVertexOperation {
@Override
public boolean load(CCRenderState state) {
state.pipeline.addDependency(CCRenderState.sideAttrib);
state.pipeline.addDependency(CCRenderState.sideAttrib());
return true;
}
@@ -351,9 +351,9 @@ public final class PacketCustom implements MCDataInput, MCDataOutput {
public PacketCustom writeItemStack(ItemStack stack, boolean large) {
if (stack == null) {
writeInt(-1);
writeShort(-1);
} else {
writeInt(Item.getIdFromItem(stack.getItem()));
writeShort(Item.getIdFromItem(stack.getItem()));
if (large) writeInt(stack.stackSize);
else writeByte(stack.stackSize);
writeShort(stack.getItemDamage());
@@ -448,7 +448,7 @@ public final class PacketCustom implements MCDataInput, MCDataOutput {
public ItemStack readItemStack(boolean large) {
ItemStack item = null;
int itemID = readInt();
short itemID = readShort();
if (itemID >= 0) {
int stackSize = large ? readInt() : readByte();
@@ -20,12 +20,12 @@ public class BlockRenderer {
@Override
public <T> T getAttributes(CCRenderState.VertexAttribute<T> attr) {
return attr == CCRenderState.lightCoordAttrib && lcComputed ? (T) lightCoords : null;
return attr == CCRenderState.lightCoordAttrib() && lcComputed ? (T) lightCoords : null;
}
@Override
public boolean hasAttribute(CCRenderState.VertexAttribute<?> attr) {
return attr == CCRenderState.sideAttrib || attr == CCRenderState.lightCoordAttrib && lcComputed;
return attr == CCRenderState.sideAttrib() || attr == CCRenderState.lightCoordAttrib() && lcComputed;
}
@Override
@@ -136,12 +136,12 @@ public class BlockRenderer {
@Override
public <T> T getAttributes(VertexAttribute<T> attr) {
return attr == CCRenderState.lightCoordAttrib ? (T) lightCoords : null;
return attr == CCRenderState.lightCoordAttrib() ? (T) lightCoords : null;
}
@Override
public boolean hasAttribute(VertexAttribute<?> attr) {
return attr == CCRenderState.sideAttrib || attr == CCRenderState.lightCoordAttrib;
return attr == CCRenderState.sideAttrib() || attr == CCRenderState.lightCoordAttrib();
}
@Override
@@ -164,7 +164,7 @@ public class BlockRenderer {
/**
* Renders faces of a block-like model based on a sideMask. Eg for side 2, verts 8-11 will be rendered
*
*
* @param sideMask A mask of faces not to render
*/
// public static void renderFaces(int sideMask) {
@@ -184,7 +184,7 @@ public class BlockRenderer {
/**
* Renders faces of a cuboid with texture coordinates mapped to match a standard minecraft block
*
*
* @param bounds The bounding cuboid to render
* @param sideMask A mask of faces not to render
*/
@@ -68,7 +68,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
}
public Vector3[] normals() {
return getAttributes(CCRenderState.normalAttrib);
return getAttributes(CCRenderState.normalAttrib());
}
@Override
@@ -102,7 +102,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Each pixel corresponds to one unit of position when generating the model
*
*
* @param i Vertex index to start generating at
* @param x1 The minX bound of the box
* @param y1 The minY bound of the box
@@ -195,7 +195,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Generates a box, uv mapped to be the same as a minecraft block with the same bounds
*
*
* @param i The vertex index to start generating at
* @param bounds The bounds of the block, 0 to 1
* @return The generated model. When rendering an icon will need to be supplied for the UV transformation.
@@ -222,7 +222,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Generates a box, uv mapped to be the same as a minecraft block with the same bounds
*
*
* @param i The vertex index to start generating at
* @param x1 minX
* @param y1 minY
@@ -311,7 +311,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Computes the normals of all faces in the model. Uses the cross product of the vectors along 2 sides of the face
*
*
* @param start The first vertex to generate normals for
* @param length The number of vertices to generate normals for. Note this must be a multiple of 3 for triangles or
* 4 for quads
@@ -321,7 +321,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
if (length % vp != 0 || start % vp != 0)
throw new IllegalArgumentException("Cannot generate normals across polygons");
Vector3[] normals = getOrAllocate(CCRenderState.normalAttrib);
Vector3[] normals = getOrAllocate(CCRenderState.normalAttrib());
for (int k = 0; k < length; k += vp) {
int i = k + start;
Vector3 diff1 = verts[i + 1].vec.copy().subtract(verts[i].vec);
@@ -336,14 +336,14 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Computes lighting using the normals add a light model If the model is rotated, the lighting will no longer be
* valid
*
*
* @return The model
*/
public CCModel computeLighting(LightModel light) {
Vector3[] normals = normals();
int[] colours = getAttributes(CCRenderState.lightingAttrib);
int[] colours = getAttributes(CCRenderState.lightingAttrib());
if (colours == null) {
colours = getOrAllocate(CCRenderState.lightingAttrib);
colours = getOrAllocate(CCRenderState.lightingAttrib());
Arrays.fill(colours, -1);
}
for (int k = 0; k < verts.length; k++) colours[k] = light.apply(colours[k], normals[k]);
@@ -351,18 +351,18 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
}
public CCModel setColour(int c) {
int[] colours = getOrAllocate(CCRenderState.colourAttrib);
int[] colours = getOrAllocate(CCRenderState.colourAttrib());
Arrays.fill(colours, c);
return this;
}
/**
* Computes the minecraft lighting coordinates for use with a LightMatrix
*
*
* @return The model
*/
public CCModel computeLightCoords() {
LC[] lcs = getOrAllocate(CCRenderState.lightCoordAttrib);
LC[] lcs = getOrAllocate(CCRenderState.lightCoordAttrib());
Vector3[] normals = normals();
for (int i = 0; i < verts.length; i++) lcs[i] = new LC().compute(verts[i].vec, normals[i]);
return this;
@@ -370,7 +370,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Averages all normals at the same position to produce a smooth lighting effect.
*
*
* @return The model
*/
public CCModel smoothNormals() {
@@ -461,7 +461,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Renders vertices start through start+length-1 of the model
*
*
* @param start The first vertex index to render
* @param end The vertex index to render until
* @param ops Operations to apply
@@ -520,7 +520,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Parses vertices, texture coords, normals and polygons from a WaveFront Obj file
*
*
* @param input An input stream to a obj file
* @param vertexMode The vertex mode to create the model for (GL_TRIANGLES or GL_QUADS)
* @param coordSystem The cooridnate system transformation to apply
@@ -624,7 +624,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Parses vertices, texture coords, normals and polygons from a WaveFront Obj file
*
*
* @param res The resource for the obj file
* @return A map of group names to models
*/
@@ -634,7 +634,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Parses vertices, texture coords, normals and polygons from a WaveFront Obj file
*
*
* @param res The resource for the obj file
* @param coordSystem The cooridnate system transformation to apply
* @return A map of group names to models
@@ -652,7 +652,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Parses vertices, texture coords, normals and polygons from a WaveFront Obj file
*
*
* @param res The resource for the obj file
* @param vertexMode The vertex mode to create the model for (GL_TRIANGLES or GL_QUADS)
* @param coordSystem The cooridnate system transformation to apply
@@ -678,7 +678,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
boolean hasNormals = polys.get(0)[2] > 0;
CCModel model = CCModel.newModel(vertexMode, polys.size());
if (hasNormals) model.getOrAllocate(CCRenderState.normalAttrib);
if (hasNormals) model.getOrAllocate(CCRenderState.normalAttrib());
for (int i = 0; i < polys.size(); i++) {
int[] ai = polys.get(i);
@@ -807,7 +807,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Generate models rotated to the other 5 sides of the block
*
*
* @param models An array of 6 models
* @param side The side of this model
* @param point The rotation point
@@ -822,7 +822,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Generate models rotated to the other 3 horizontal of the block
*
*
* @param models An array of 4 models
* @param side The side of this model
* @param point The rotation point
@@ -841,7 +841,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Generates copies of faces with clockwise vertices
*
*
* @return The model
*/
public static CCModel generateBackface(CCModel src, int srcpos, CCModel dst, int destpos, int length) {
@@ -169,7 +169,27 @@ public class CCRenderState {
}
}
public static VertexAttribute<Vector3[]> normalAttrib = new VertexAttribute<>() {
public static VertexAttribute<Vector3[]> normalAttrib() {
return instances.get().normalAttrib;
}
public static VertexAttribute<int[]> colourAttrib() {
return instances.get().colourAttrib;
}
public static VertexAttribute<LC[]> lightCoordAttrib() {
return instances.get().lightCoordAttrib;
}
public static VertexAttribute<int[]> sideAttrib() {
return instances.get().sideAttrib;
}
public static VertexAttribute<int[]> lightingAttrib() {
return instances.get().lightingAttrib;
}
public VertexAttribute<Vector3[]> normalAttrib = new VertexAttribute<>() {
private Vector3[] normalRef;
@@ -197,7 +217,7 @@ public class CCRenderState {
else state.setNormalInstance(Rotation.axes[state.side]);
}
};
public static VertexAttribute<int[]> colourAttrib = new VertexAttribute<>() {
public VertexAttribute<int[]> colourAttrib = new VertexAttribute<>() {
private int[] colourRef;
@@ -219,7 +239,7 @@ public class CCRenderState {
else state.setColourInstance(state.baseColour);
}
};
public static VertexAttribute<int[]> lightingAttrib = new VertexAttribute<>() {
public VertexAttribute<int[]> lightingAttrib = new VertexAttribute<>() {
private int[] colourRef;
@@ -245,7 +265,7 @@ public class CCRenderState {
state.setColourInstance(ColourRGBA.multiply(state.colour, colourRef[state.vertexIndex]));
}
};
public static VertexAttribute<int[]> sideAttrib = new VertexAttribute<>() {
public VertexAttribute<int[]> sideAttrib = new VertexAttribute<>() {
private int[] sideRef;
@@ -272,7 +292,7 @@ public class CCRenderState {
/**
* Uses the position of the lightmatrix to compute LC if not provided
*/
public static VertexAttribute<LC[]> lightCoordAttrib = new VertexAttribute<>() {
public VertexAttribute<LC[]> lightCoordAttrib = new VertexAttribute<>() {
private LC[] lcRef;
private final Vector3 vec = new Vector3(); // for computation
@@ -14,14 +14,14 @@ public abstract class Transformation extends ITransformation<Vector3, Transforma
/**
* Applies this transformation to a normal (doesn't translate)
*
*
* @param normal The normal to transform
*/
public abstract void applyN(Vector3 normal);
/**
* Applies this transformation to a matrix as a multiplication on the right hand side.
*
*
* @param mat The matrix to combine this transformation with
*/
public abstract void apply(Matrix4 mat);
@@ -39,14 +39,14 @@ public abstract class Transformation extends ITransformation<Vector3, Transforma
@Override
public boolean load(CCRenderState state) {
state.pipeline.addRequirement(CCRenderState.normalAttrib.operationID());
state.pipeline.addRequirement(CCRenderState.normalAttrib().operationID());
return !isRedundant();
}
@Override
public void operate(CCRenderState state) {
apply(state.vert.vec);
if (CCRenderState.normalAttrib.active) applyN(state.normal);
if (CCRenderState.normalAttrib().active) applyN(state.normal);
}
@Override
@@ -79,17 +79,25 @@ public class WorldExtensionManager {
@SubscribeEvent
public void onChunkWatch(Watch event) {
Chunk chunk = event.player.worldObj.getChunkFromChunkCoords(event.chunk.chunkXPos, event.chunk.chunkZPos);
for (WorldExtension extension : worldMap.get(event.player.worldObj))
extension.watchChunk(chunk, event.player);
WorldExtension[] extensions = worldMap.get(event.player.worldObj);
if (extensions != null) {
Chunk chunk = event.player.worldObj
.getChunkFromChunkCoords(event.chunk.chunkXPos, event.chunk.chunkZPos);
for (WorldExtension extension : extensions) extension.watchChunk(chunk, event.player);
}
}
@SubscribeEvent
@SideOnly(Side.CLIENT)
public void onChunkUnWatch(UnWatch event) {
Chunk chunk = event.player.worldObj.getChunkFromChunkCoords(event.chunk.chunkXPos, event.chunk.chunkZPos);
for (WorldExtension extension : worldMap.get(event.player.worldObj))
extension.unwatchChunk(chunk, event.player);
WorldExtension[] extensions = worldMap.get(event.player.worldObj);
if (extensions != null) {
Chunk chunk = event.player.worldObj
.getChunkFromChunkCoords(event.chunk.chunkXPos, event.chunk.chunkZPos);
for (WorldExtension extension : extensions) extension.unwatchChunk(chunk, event.player);
}
}
@SubscribeEvent
@@ -110,7 +118,7 @@ public class WorldExtensionManager {
}
private static boolean initialised;
private static ArrayList<WorldExtensionInstantiator> extensionIntialisers = new ArrayList<WorldExtensionInstantiator>();
private static ArrayList<WorldExtensionInstantiator> extensionIntialisers = new ArrayList<>();
public static void registerWorldExtension(WorldExtensionInstantiator init) {
if (!initialised) init();
@@ -125,7 +133,7 @@ public class WorldExtensionManager {
FMLCommonHandler.instance().bus().register(new WorldExtensionEventHandler());
}
private static HashMap<World, WorldExtension[]> worldMap = new HashMap<World, WorldExtension[]>();
private static HashMap<World, WorldExtension[]> worldMap = new HashMap<>();
private static void onWorldLoad(World world) {
WorldExtension[] extensions = new WorldExtension[extensionIntialisers.size()];
@@ -4,13 +4,15 @@ import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.PrintStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.text.DecimalFormat;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.commons.RemappingClassAdapter;
import org.objectweb.asm.commons.Remapper;
import org.objectweb.asm.tree.ClassNode;
import com.google.common.base.Function;
@@ -181,7 +183,40 @@ public class ObfuscationRun implements ILogStreams {
public void remap(ClassNode cnode, ClassVisitor cv) {
cstMappper.transform(cnode);
cnode.accept(new RemappingClassAdapter(cv, obfMapper));
cnode.accept(newRemapper(cv, obfMapper));
}
private static ClassVisitor newRemapper(ClassVisitor visitor, Remapper remapper) {
try {
return theConstructor.newInstance(visitor, remapper);
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
private static final Constructor<? extends ClassVisitor> theConstructor;
static {
Class<? extends ClassVisitor> remapperClass;
try {
// noinspection unchecked
remapperClass = (Class<? extends ClassVisitor>) Class.forName("org.objectweb.asm.commons.ClassRemapper");
} catch (ClassNotFoundException e) {
try {
// noinspection unchecked
remapperClass = (Class<? extends ClassVisitor>) Class
.forName("org.objectweb.asm.commons.RemappingClassAdapter");
} catch (ClassNotFoundException ex) {
RuntimeException err = new RuntimeException(ex);
err.addSuppressed(e);
throw err;
}
}
try {
theConstructor = remapperClass.getConstructor(ClassVisitor.class, Remapper.class);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
public static List<String> getParents(ClassNode cnode) {