Commit c20429cdc6a4f3b4ae89e1f0d435d4e8a5f7f05a

Authored by Mumfrey
1 parent 54397026

LiteLoader 1.6.4_02 - dev only - allow mods to be injected at the top of the cla…

…ss path (wow, this could all go horribly wrong)
java/com/mumfrey/liteloader/core/ModFile.java
@@ -17,6 +17,7 @@ import joptsimple.internal.Strings; @@ -17,6 +17,7 @@ import joptsimple.internal.Strings;
17 17
18 import com.google.gson.Gson; 18 import com.google.gson.Gson;
19 import com.google.gson.JsonSyntaxException; 19 import com.google.gson.JsonSyntaxException;
  20 +import com.mumfrey.liteloader.launch.ClassPathInjector;
20 import com.mumfrey.liteloader.launch.LiteLoaderTweaker; 21 import com.mumfrey.liteloader.launch.LiteLoaderTweaker;
21 import com.mumfrey.liteloader.resources.ModResourcePack; 22 import com.mumfrey.liteloader.resources.ModResourcePack;
22 23
@@ -94,6 +95,11 @@ public class ModFile extends File @@ -94,6 +95,11 @@ public class ModFile extends File
94 private boolean injected; 95 private boolean injected;
95 96
96 /** 97 /**
  98 + * True if this mod contains base class edits (dirty horribleness) inject at the TOP of the class path
  99 + */
  100 + private boolean injectAtTop;
  101 +
  102 + /**
97 * @param file 103 * @param file
98 * @param strVersion 104 * @param strVersion
99 */ 105 */
@@ -148,6 +154,7 @@ public class ModFile extends File @@ -148,6 +154,7 @@ public class ModFile extends File
148 154
149 this.tweakClassName = this.metaData.get("tweakClass"); 155 this.tweakClassName = this.metaData.get("tweakClass");
150 this.classTransformerClassName = this.metaData.get("classTransformerClass"); 156 this.classTransformerClassName = this.metaData.get("classTransformerClass");
  157 + this.injectAtTop = "top".equalsIgnoreCase(this.metaData.get("injectAt"));
151 } 158 }
152 159
153 protected String getDefaultName() 160 protected String getDefaultName()
@@ -214,6 +221,11 @@ public class ModFile extends File @@ -214,6 +221,11 @@ public class ModFile extends File
214 { 221 {
215 if (!this.injected) 222 if (!this.injected)
216 { 223 {
  224 + if (this.injectAtTop)
  225 + {
  226 + ClassPathInjector.injectIntoClassPath(classLoader, this.toURI().toURL());
  227 + }
  228 +
217 if (injectIntoParent) 229 if (injectIntoParent)
218 { 230 {
219 LiteLoaderTweaker.addURLToParentClassLoader(this.toURI().toURL()); 231 LiteLoaderTweaker.addURLToParentClassLoader(this.toURI().toURL());
java/com/mumfrey/liteloader/launch/ClassPathInjector.java 0 → 100644
  1 +package com.mumfrey.liteloader.launch;
  2 +
  3 +import java.lang.reflect.Field;
  4 +import java.net.URL;
  5 +import java.net.URLClassLoader;
  6 +import java.util.ArrayList;
  7 +import java.util.Stack;
  8 +
  9 +import net.minecraft.launchwrapper.LaunchClassLoader;
  10 +import sun.misc.URLClassPath;
  11 +
  12 +/**
  13 + * Nasty horrible reflection hack to inject a classpath entry at the top of the classpath stack
  14 + *
  15 + * @author Adam Mummery-Smith
  16 + */
  17 +public abstract class ClassPathInjector
  18 +{
  19 + private static Field ucp;
  20 + private static Field classPathURLs;
  21 + private static Field classPathPath;
  22 +
  23 + static
  24 + {
  25 + try
  26 + {
  27 + ucp = URLClassLoader.class.getDeclaredField("ucp");
  28 + ucp.setAccessible(true);
  29 + classPathURLs = URLClassPath.class.getDeclaredField("urls");
  30 + classPathURLs.setAccessible(true);
  31 + classPathPath = URLClassPath.class.getDeclaredField("path");
  32 + classPathPath.setAccessible(true);
  33 + }
  34 + catch (Exception ex)
  35 + {
  36 + ex.printStackTrace();
  37 + }
  38 + }
  39 +
  40 + /**
  41 + * Injects a URL into the classpath at the TOP of the stack
  42 + *
  43 + * @param classLoader
  44 + * @param url
  45 + */
  46 + @SuppressWarnings({ "rawtypes", "unchecked" })
  47 + public static void injectIntoClassPath(URLClassLoader classLoader, URL url)
  48 + {
  49 + try
  50 + {
  51 + URLClassPath classPath = (URLClassPath)ucp.get(classLoader);
  52 +
  53 + Stack urls = (Stack)classPathURLs.get(classPath);
  54 + ArrayList path = (ArrayList)classPathPath.get(classPath);
  55 +
  56 + synchronized (urls)
  57 + {
  58 + if (!path.contains(url))
  59 + {
  60 + urls.add(url);
  61 + path.add(0, url);
  62 + }
  63 + }
  64 + }
  65 + catch (Exception ex) {}
  66 +
  67 + if (classLoader instanceof LaunchClassLoader)
  68 + {
  69 + ((LaunchClassLoader)classLoader).addURL(url);
  70 + }
  71 + }
  72 +}