aboutsummaryrefslogtreecommitdiff
path: root/src/Java/gtPlusPlus/xmod/gregtech/loaders/GT_Material_Loader.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/Java/gtPlusPlus/xmod/gregtech/loaders/GT_Material_Loader.java')
-rw-r--r--src/Java/gtPlusPlus/xmod/gregtech/loaders/GT_Material_Loader.java292
1 files changed, 292 insertions, 0 deletions
diff --git a/src/Java/gtPlusPlus/xmod/gregtech/loaders/GT_Material_Loader.java b/src/Java/gtPlusPlus/xmod/gregtech/loaders/GT_Material_Loader.java
new file mode 100644
index 0000000000..c57ad71fc7
--- /dev/null
+++ b/src/Java/gtPlusPlus/xmod/gregtech/loaders/GT_Material_Loader.java
@@ -0,0 +1,292 @@
+package gtPlusPlus.xmod.gregtech.loaders;
+
+import java.lang.reflect.*;
+import java.util.HashMap;
+import java.util.Map;
+
+import gregtech.api.enums.Materials;
+import gregtech.api.enums.OrePrefixes;
+import gtPlusPlus.api.objects.Logger;
+import gtPlusPlus.core.lib.CORE;
+import gtPlusPlus.core.util.Utils;
+import gtPlusPlus.core.util.array.AutoMap;
+import gtPlusPlus.core.util.materials.MaterialUtils;
+import gtPlusPlus.core.util.reflect.ReflectionUtils;
+
+public class GT_Material_Loader {
+
+ private volatile static GT_Material_Loader instance = new GT_Material_Loader();
+ private volatile Object mProxyObject;
+ private static AutoMap<Materials> mMaterials = new AutoMap<Materials>();
+ private static volatile boolean mHasRun = false;
+
+ public synchronized GT_Material_Loader getInstance(){
+ return GT_Material_Loader.instance;
+ }
+
+ public synchronized boolean getRunAbility(){
+ return (mHasRun ? false : true);
+ }
+ public synchronized void setRunAbility(boolean b){
+ mHasRun = Utils.invertBoolean(b);
+ }
+
+ public GT_Material_Loader() {
+ if (getRunAbility()){
+ //Set Singleton Instance
+ instance = this;
+
+ //Try Reflectively add ourselves to the GT loader.
+ try {
+ Class mInterface = Class.forName("gregtech.api.interfaces.IMaterialHandler");
+ if (CORE.MAIN_GREGTECH_5U_EXPERIMENTAL_FORK && mInterface != null){
+
+ //Make this class Dynamically implement IMaterialHandler
+ if (mProxyObject == null){
+ mProxyObject = Proxy.newProxyInstance(
+ mInterface.getClassLoader(), new Class[] { mInterface },
+ new MaterialHandler(getInstance()));
+ }
+
+ if (ReflectionUtils.invoke(Materials.class, "add", new Class[]{Class.forName("gregtech.api.interfaces.IMaterialHandler")}, new Object[]{mProxyObject})){
+ Logger.REFLECTION("Successfully invoked add, on the proxied object implementing IMaterialHandler.");
+
+
+ Logger.REFLECTION("Examining Proxy to ensure it implements the correct Interface.");
+ Class[] i = mProxyObject.getClass().getInterfaces();
+ for (int r=0;r<i.length;r++){
+ Logger.REFLECTION("Contains "+i[r].getCanonicalName()+".");
+ if (i[r] == mInterface){
+ Logger.REFLECTION("Found gregtech.api.interfaces.IMaterialHandler. This Proxy is valid.");
+ }
+ }
+ }
+ else {
+ Logger.REFLECTION("Failed to invoke add, on the proxied object implementing IMaterialHandler.");
+ }
+ }
+ }
+ catch (ClassNotFoundException e) {}
+ //Materials.add(this);
+
+ //Stupid shit running twice, I don't think so.
+ setRunAbility(false);
+ }
+ }
+
+ public void onMaterialsInit() {
+ Logger.DEBUG_MATERIALS("onMaterialsInit()");
+ }
+
+ public void onComponentInit() {
+ Logger.DEBUG_MATERIALS("onComponentInit()");
+ if (!mMaterials.isEmpty()){
+ Logger.DEBUG_MATERIALS("Found "+mMaterials.size()+" materials to re-enable.");
+ for (Materials M : mMaterials.values()){
+ String name = MaterialUtils.getMaterialName(M);
+ Logger.DEBUG_MATERIALS("Trying to enable "+name+".");
+ boolean success = tryEnableAllComponentsForMaterial(M);
+ if (success){
+ Logger.DEBUG_MATERIALS("Success! Enabled "+name+".");
+ }
+ else {
+ Logger.DEBUG_MATERIALS("Failure... Did not enable "+name+".");
+ }
+ }
+ }
+ }
+
+ public void onComponentIteration(Materials aMaterial) {
+ Logger.DEBUG_MATERIALS("onComponentIteration()");
+ }
+
+ public synchronized boolean enableMaterial(Materials m){
+ if (mMaterials.setValue(m)){
+ Logger.DEBUG_MATERIALS("Added "+MaterialUtils.getMaterialName(m)+" to internal Map.");
+ return true;
+ }
+ Logger.DEBUG_MATERIALS("Failed to add "+MaterialUtils.getMaterialName(m)+" to internal Map.");
+ return false;
+ }
+
+
+
+
+
+
+ /*
+ * Static internal handler methods
+ */
+
+ private static synchronized boolean tryEnableMaterial(Materials mMaterial){
+ if (!CORE.MAIN_GREGTECH_5U_EXPERIMENTAL_FORK){
+ return false;
+ }
+
+ boolean value = ReflectionUtils.setField(mMaterial, "mHasParentMod", true);
+ if (value){
+ Logger.DEBUG_MATERIALS("Set mHasParentMod true for "+mMaterial.mDefaultLocalName);
+ }
+ else {
+ Logger.DEBUG_MATERIALS("Failed to set mHasParentMod true for "+mMaterial.mDefaultLocalName);
+ }
+ return value;
+ }
+
+ private static synchronized boolean tryEnableMaterialPart(OrePrefixes prefix, Materials mMaterial){
+ if (!CORE.MAIN_GREGTECH_5U_EXPERIMENTAL_FORK){
+ return false;
+ }
+ try {
+ Method enableComponent = Class.forName("gregtech.api.enums.OrePrefixes").getDeclaredMethod("enableComponent", Materials.class);
+ enableComponent.invoke(prefix, mMaterial);
+ Logger.DEBUG_MATERIALS("Enabled "+prefix.name()+" for "+mMaterial.mDefaultLocalName+".");
+ return true;
+ }
+ catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException | ClassNotFoundException error) {
+ Logger.DEBUG_MATERIALS("Failed to enabled "+prefix.name()+" for "+mMaterial.mDefaultLocalName+". Caught "+error.getCause().toString()+".");
+ error.printStackTrace();
+ }
+ Logger.DEBUG_MATERIALS("Did not enable "+prefix.name()+" for "+mMaterial.mDefaultLocalName+". Report this error to Alkalus on Github.");
+ return false;
+ }
+
+ private static synchronized boolean tryEnableAllComponentsForMaterial(Materials material){
+ if (!CORE.MAIN_GREGTECH_5U_EXPERIMENTAL_FORK){
+ return false;
+ }
+ try {
+ tryEnableMaterial(material);
+ int mValid = 0;
+ for(OrePrefixes ore:OrePrefixes.values()){
+ if (tryEnableMaterialPart(ore, material)){
+ mValid++;
+ }
+ }
+ if (mValid > 0){
+ Logger.DEBUG_MATERIALS("Success - Re-enabled all components for "+MaterialUtils.getMaterialName(material));
+ }
+ else {
+ Logger.DEBUG_MATERIALS("Failure - Did not enable any components for "+MaterialUtils.getMaterialName(material));
+ }
+ return mValid > 0;
+ }
+ catch (SecurityException | IllegalArgumentException e) {
+ Logger.DEBUG_MATERIALS("Total Failure - Unable to re-enable "+MaterialUtils.getMaterialName(material)+". Most likely an IllegalArgumentException, but small chance it's a SecurityException.");
+ return false;
+ }
+ }
+
+
+
+
+
+
+
+
+
+ /**
+ * Special Dynamic Interface Class
+ */
+
+ public class MaterialHandler implements InvocationHandler {
+
+ private final Map<String, Method> methods = new HashMap<String, Method>();
+ private Object target;
+
+ public MaterialHandler(Object target) {
+ Logger.REFLECTION("Created a Proxy Interface which implements IMaterialHandler.");
+ this.target = target;
+ for(Method method: target.getClass().getDeclaredMethods()) {
+ Logger.REFLECTION("Adding "+method.getName()+" to internal method map.");
+ this.methods.put(method.getName(), method);
+ }
+ }
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+ long start = System.nanoTime();
+ Object result = methods.get(method.getName()).invoke(target, args);
+ long elapsed = System.nanoTime() - start;
+ Logger.INFO("[Debug] Executed "+method.getName()+" in "+elapsed+" ns");
+ return result;
+ }
+ }
+
+
+ /*
+ public static class ProxyListener implements java.lang.reflect.InvocationHandler {
+
+ public static Object IMaterialHandlerProxy;
+
+ ProxyListener(){
+
+ Logger.REFLECTION("Failed setting IMaterialHandler Proxy instance.");
+ }
+
+ //Loading the class at runtime
+ public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, ClassNotFoundException {
+ Class<?> someInterface = Class.forName("gregtech.api.interfaces.IMaterialHandler");
+ Object instance = Proxy.newProxyInstance(someInterface.getClassLoader(), new Class<?>[]{someInterface}, new InvocationHandler() {
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ //Handle the invocations
+ if(method.getName().equals("onMaterialsInit")){
+ Logger.REFLECTION("Invoked onMaterialsInit() via IMaterialHandler proxy");
+ return 1;
+ }
+ else if(method.getName().equals("onComponentInit")){
+ Logger.REFLECTION("Invoked onComponentInit() via IMaterialHandler proxy");
+ return 2;
+ }
+ else if(method.getName().equals("onComponentIteration")){
+ Logger.REFLECTION("Invoked onComponentIteration() via IMaterialHandler proxy");
+ return 3;
+ }
+ else {
+ return -1;
+ }
+ }
+ });
+ System.out.println(instance.getClass().getDeclaredMethod("someMethod", (Class<?>[])null).invoke(instance, new Object[]{}));
+ }
+
+ private static class MaterialHandler implements InvocationHandler {
+ private final Object original;
+
+ public MaterialHandler(Object original) {
+ this.original = original;
+ }
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws IllegalAccessException, IllegalArgumentException,
+ InvocationTargetException {
+ System.out.println("BEFORE");
+ method.invoke(original, args);
+ System.out.println("AFTER");
+ return null;
+ }
+ }
+
+ public static void init(){
+
+ Class<?> someInterface = Class.forName("gregtech.api.interfaces.IMaterialHandler");
+ GT_Material_Loader original = GT_Material_Loader.instance;
+ MaterialHandler handler = new MaterialHandler(original);
+
+ Object f = Proxy.newProxyInstance(someInterface.getClassLoader(),
+ new Class[] { someInterface },
+ handler);
+
+ f.originalMethod("Hallo");
+ }
+
+
+
+ }
+
+ */
+}