Commit 68f130d25aa5439ad1e5d9f1bf1bea2541110fc5

Authored by Mumfrey
1 parent 9455bbc3

Liteloader working version for Minecraft 1.3.2

.classpath 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<classpath>
  3 + <classpathentry kind="src" path="java"/>
  4 + <classpathentry combineaccessrules="false" kind="src" path="/Client"/>
  5 + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jre6"/>
  6 + <classpathentry kind="lib" path="jars/bin/jinput.jar">
  7 + <attributes>
  8 + <attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="LiteLoader/jars/bin/natives"/>
  9 + </attributes>
  10 + </classpathentry>
  11 + <classpathentry kind="lib" path="jars/bin/lwjgl_util.jar">
  12 + <attributes>
  13 + <attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="LiteLoader/jars/bin/natives"/>
  14 + </attributes>
  15 + </classpathentry>
  16 + <classpathentry kind="lib" path="jars/bin/lwjgl.jar">
  17 + <attributes>
  18 + <attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="LiteLoader/jars/bin/natives"/>
  19 + </attributes>
  20 + </classpathentry>
  21 + <classpathentry kind="lib" path="jars/bin/minecraft.jar"/>
  22 + <classpathentry kind="output" path="bin"/>
  23 +</classpath>
... ...
.project 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<projectDescription>
  3 + <name>LiteLoader</name>
  4 + <comment></comment>
  5 + <projects>
  6 + </projects>
  7 + <buildSpec>
  8 + <buildCommand>
  9 + <name>org.eclipse.jdt.core.javabuilder</name>
  10 + <arguments>
  11 + </arguments>
  12 + </buildCommand>
  13 + </buildSpec>
  14 + <natures>
  15 + <nature>org.eclipse.jdt.core.javanature</nature>
  16 + </natures>
  17 + <linkedResources>
  18 + <link>
  19 + <name>jars</name>
  20 + <type>2</type>
  21 + <locationURI>MCP_LOC/jars</locationURI>
  22 + </link>
  23 + </linkedResources>
  24 + <variableList>
  25 + <variable>
  26 + <name>MCP_LOC</name>
  27 + <value>$%7BPARENT-2-PROJECT_LOC%7D</value>
  28 + </variable>
  29 + </variableList>
  30 +</projectDescription>
... ...
.settings/org.eclipse.jdt.core.prefs 0 → 100644
  1 +#Fri Aug 17 17:54:35 BST 2012
  2 +eclipse.preferences.version=1
  3 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
  4 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
  5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
  6 +org.eclipse.jdt.core.compiler.compliance=1.6
  7 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate
  8 +org.eclipse.jdt.core.compiler.debug.localVariable=generate
  9 +org.eclipse.jdt.core.compiler.debug.sourceFile=generate
  10 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
  11 +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
  12 +org.eclipse.jdt.core.compiler.source=1.6
... ...
.settings/org.eclipse.jdt.ui.prefs 0 → 100644
  1 +#Fri Aug 17 17:54:35 BST 2012
  2 +eclipse.preferences.version=1
  3 +formatter_settings_version=11
... ...
java/com/mumfrey/liteloader/ChatFilter.java 0 → 100644
  1 +package com.mumfrey.liteloader;
  2 +
  3 +import net.minecraft.src.Packet3Chat;
  4 +
  5 +/**
  6 + * Interface for mods which can filter inbound chat
  7 + *
  8 + * @author Adam Mummery-Smith
  9 + */
  10 +public interface ChatFilter extends LiteMod
  11 +{
  12 + /**
  13 + * Chat filter function, return false to filter this packet, true to pass the packet
  14 + *
  15 + * @param chatPacket Chat packet to examine
  16 + * @return True to keep the packet, false to discard
  17 + */
  18 + public abstract boolean onChat(Packet3Chat chatPacket);
  19 +}
... ...
java/com/mumfrey/liteloader/ChatListener.java 0 → 100644
  1 +package com.mumfrey.liteloader;
  2 +
  3 +/**
  4 + * Interface for mods which receive inbound chat
  5 + *
  6 + * @author Adam Mummery-Smith
  7 + */
  8 +public interface ChatListener extends LiteMod
  9 +{
  10 + /**
  11 + * Handle an inbound message
  12 + *
  13 + * @param message
  14 + */
  15 + public abstract void onChat(String message);
  16 +}
... ...
java/com/mumfrey/liteloader/LiteMod.java 0 → 100644
  1 +package com.mumfrey.liteloader;
  2 +
  3 +public interface LiteMod
  4 +{
  5 + public abstract String getName();
  6 +
  7 + public abstract String getVersion();
  8 +
  9 + public abstract void init();
  10 +}
... ...
java/com/mumfrey/liteloader/LoginListener.java 0 → 100644
  1 +package com.mumfrey.liteloader;
  2 +
  3 +import net.minecraft.src.NetHandler;
  4 +import net.minecraft.src.Packet1Login;
  5 +
  6 +/**
  7 + * Interface for mods which wish to be notified when the player connects to a server (or local game)
  8 + *
  9 + * @author Adam Mummery-Smith
  10 + */
  11 +public interface LoginListener extends LiteMod
  12 +{
  13 + /**
  14 + * Called on login
  15 + *
  16 + * @param netHandler Net handler
  17 + * @param loginPacket Login packet
  18 + */
  19 + public abstract void onLogin(NetHandler netHandler, Packet1Login loginPacket);
  20 +}
... ...
java/com/mumfrey/liteloader/Tickable.java 0 → 100644
  1 +package com.mumfrey.liteloader;
  2 +
  3 +import net.minecraft.client.Minecraft;
  4 +
  5 +/**
  6 + * Interface for mods which want tick events
  7 + *
  8 + * @author Adam Mummery-Smith
  9 + */
  10 +public interface Tickable extends LiteMod
  11 +{
  12 + /**
  13 + * Called every frame
  14 + *
  15 + * @param minecraft Minecraft instance
  16 + * @param partialTicks Partial tick value
  17 + * @param inGame True if in-game, false if in the menu
  18 + * @param clock True if this is a new tick, otherwise false if it's a regular frame
  19 + */
  20 + public abstract void onTick(Minecraft minecraft, float partialTicks, boolean inGame, boolean clock);
  21 +}
... ...
java/com/mumfrey/liteloader/core/HookChat.java 0 → 100644
  1 +package com.mumfrey.liteloader.core;
  2 +
  3 +import net.minecraft.src.NetHandler;
  4 +import net.minecraft.src.Packet3Chat;
  5 +
  6 +public class HookChat extends Packet3Chat
  7 +{
  8 + public static LiteLoader loader;
  9 +
  10 + public HookChat()
  11 + {
  12 + super();
  13 + }
  14 +
  15 + public HookChat(String par1Str)
  16 + {
  17 + super(par1Str);
  18 + }
  19 +
  20 + public HookChat(String par1Str, boolean par2)
  21 + {
  22 + super(par1Str, par2);
  23 + }
  24 +
  25 + /* (non-Javadoc)
  26 + * @see net.minecraft.src.Packet3Chat#processPacket(net.minecraft.src.NetHandler)
  27 + */
  28 + @Override
  29 + public void processPacket(NetHandler par1NetHandler)
  30 + {
  31 + if (loader == null || loader.onChat(this))
  32 + {
  33 + super.processPacket(par1NetHandler);
  34 + }
  35 + }
  36 +}
... ...
java/com/mumfrey/liteloader/core/HookLogin.java 0 → 100644
  1 +package com.mumfrey.liteloader.core;
  2 +
  3 +import net.minecraft.src.EnumGameType;
  4 +import net.minecraft.src.NetHandler;
  5 +import net.minecraft.src.Packet1Login;
  6 +import net.minecraft.src.WorldType;
  7 +
  8 +public class HookLogin extends Packet1Login
  9 +{
  10 + public static LiteLoader loader;
  11 +
  12 + public HookLogin()
  13 + {
  14 + super();
  15 + }
  16 +
  17 + public HookLogin(int par1, WorldType par2WorldType, EnumGameType par3EnumGameType, boolean par4, int par5, int par6, int par7, int par8)
  18 + {
  19 + super(par1, par2WorldType, par3EnumGameType, par4, par5, par6, par7, par8);
  20 + }
  21 +
  22 + /* (non-Javadoc)
  23 + * @see net.minecraft.src.Packet1Login#processPacket(net.minecraft.src.NetHandler)
  24 + */
  25 + @Override
  26 + public void processPacket(NetHandler par1NetHandler)
  27 + {
  28 + super.processPacket(par1NetHandler);
  29 +
  30 + if (loader != null) loader.onConnectToServer(par1NetHandler, this);
  31 + }
  32 +}
... ...
java/com/mumfrey/liteloader/core/LiteLoader.java 0 → 100644
  1 +package com.mumfrey.liteloader.core;
  2 +
  3 +import java.io.BufferedReader;
  4 +import java.io.File;
  5 +import java.io.FileInputStream;
  6 +import java.io.FileNotFoundException;
  7 +import java.io.FilenameFilter;
  8 +import java.io.IOException;
  9 +import java.io.InputStream;
  10 +import java.io.InputStreamReader;
  11 +import java.lang.reflect.Field;
  12 +import java.lang.reflect.Method;
  13 +import java.lang.reflect.Modifier;
  14 +import java.net.URL;
  15 +import java.net.URLClassLoader;
  16 +import java.util.HashMap;
  17 +import java.util.Iterator;
  18 +import java.util.LinkedList;
  19 +import java.util.Map;
  20 +import java.util.logging.Logger;
  21 +import java.util.logging.SimpleFormatter;
  22 +import java.util.logging.StreamHandler;
  23 +import java.util.zip.ZipEntry;
  24 +import java.util.zip.ZipFile;
  25 +import java.util.zip.ZipInputStream;
  26 +
  27 +import net.minecraft.client.Minecraft;
  28 +import net.minecraft.src.IntHashMap;
  29 +import net.minecraft.src.NetHandler;
  30 +import net.minecraft.src.Packet;
  31 +import net.minecraft.src.Packet1Login;
  32 +import net.minecraft.src.Packet3Chat;
  33 +import net.minecraft.src.Timer;
  34 +
  35 +import com.mumfrey.liteloader.ChatFilter;
  36 +import com.mumfrey.liteloader.ChatListener;
  37 +import com.mumfrey.liteloader.LoginListener;
  38 +import com.mumfrey.liteloader.LiteMod;
  39 +import com.mumfrey.liteloader.Tickable;
  40 +
  41 +/**
  42 + * LiteLoader is a simple loader which provides tick events to loaded mods
  43 + *
  44 + * @author Adam Mummery-Smith
  45 + * @version 1.3.2_01
  46 + */
  47 +public final class LiteLoader implements FilenameFilter
  48 +{
  49 + /**
  50 + * Minecraft version that we will load mods for, this will be compared
  51 + * against the version.txt value in mod files to prevent outdated mods being
  52 + * loaded!!!
  53 + */
  54 + private static final String MINECRAFT_VERSION = "1.3.1";
  55 +
  56 + /**
  57 + * LiteLoader is a singleton, this is the singleton instance
  58 + */
  59 + private static LiteLoader instance;
  60 +
  61 + /**
  62 + * Logger for LiteLoader events
  63 + */
  64 + private static Logger logger = Logger.getLogger("liteloader");
  65 +
  66 + private File logFile;
  67 +
  68 + /**
  69 + * "mods" folder which contains mods and config files
  70 + */
  71 + private File modsFolder;
  72 +
  73 + /**
  74 + * Reference to the Minecraft game instance
  75 + */
  76 + private Minecraft minecraft = Minecraft.getMinecraft();
  77 +
  78 + /**
  79 + * Reference to the minecraft timer
  80 + */
  81 + private Timer minecraftTimer;
  82 +
  83 + /**
  84 + * Global list of mods which we have loaded
  85 + */
  86 + private LinkedList<LiteMod> mods = new LinkedList<LiteMod>();
  87 +
  88 + /**
  89 + * List of mods which implement Tickable interface and will receive tick
  90 + * events
  91 + */
  92 + private LinkedList<Tickable> tickMods = new LinkedList<Tickable>();
  93 +
  94 + /**
  95 + * List of mods which implement ChatListener interface and will receive chat
  96 + * events
  97 + */
  98 + private LinkedList<ChatListener> chatListeners = new LinkedList<ChatListener>();
  99 +
  100 + /**
  101 + * List of mods which implement ChatFilter interface and will receive chat
  102 + * filter events
  103 + */
  104 + private LinkedList<ChatFilter> chatFilters = new LinkedList<ChatFilter>();
  105 +
  106 + /**
  107 + * List of mods which implement LoginListener interface and will receive client login events
  108 + */
  109 + private LinkedList<LoginListener> loginListeners = new LinkedList<LoginListener>();
  110 +
  111 + /**
  112 + * Reference to the addUrl method on URLClassLoader
  113 + */
  114 + private Method mAddUrl;
  115 +
  116 + /**
  117 + * Get the singleton instance of LiteLoader, initialises the loader if necessary
  118 + *
  119 + * @return LiteLoader instance
  120 + */
  121 + public static final LiteLoader getInstance()
  122 + {
  123 + if (instance == null)
  124 + {
  125 + instance = new LiteLoader();
  126 + }
  127 +
  128 + return instance;
  129 + }
  130 +
  131 + /**
  132 + * LiteLoader constructor
  133 + */
  134 + private LiteLoader()
  135 + {
  136 + // Set up loader, initialises any reflection methods needed
  137 + prepareLoader();
  138 +
  139 + logger.info("Liteloader for " + MINECRAFT_VERSION + " starting up...");
  140 +
  141 + // Examines the class path and mods folder and locates loadable mods
  142 + prepareMods();
  143 +
  144 + // Initialises enumerated mods
  145 + initMods();
  146 +
  147 + // Initialises the required hooks for loaded mods
  148 + initHooks();
  149 + }
  150 +
  151 + /**
  152 + * Set up reflection methods required by the loader
  153 + */
  154 + private void prepareLoader()
  155 + {
  156 + try
  157 + {
  158 + // addURL method is used by the class loader to
  159 + mAddUrl = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
  160 + mAddUrl.setAccessible(true);
  161 + }
  162 + catch (Exception ex)
  163 + {
  164 + // TODO Auto-generated catch block
  165 + ex.printStackTrace();
  166 + }
  167 +
  168 + logger.addHandler(new StreamHandler(System.err, new SimpleFormatter()));
  169 + }
  170 +
  171 + /**
  172 + * Get the "mods" folder
  173 + */
  174 + public File getModsFolder()
  175 + {
  176 + if (modsFolder == null)
  177 + {
  178 + modsFolder = new File(Minecraft.getMinecraftDir(), "mods");
  179 +
  180 + if (!modsFolder.exists() || !modsFolder.isDirectory())
  181 + {
  182 + try
  183 + {
  184 + // Attempt to create the "mods" folder if it does not already exist
  185 + modsFolder.mkdirs();
  186 + }
  187 + catch (Exception ex) {}
  188 + }
  189 + }
  190 +
  191 + return modsFolder;
  192 + }
  193 +
  194 + /**
  195 + * Enumerate the java class path and "mods" folder to find mod classes, then load the classes
  196 + */
  197 + private void prepareMods()
  198 + {
  199 + // List of mod files in the "mods" folder
  200 + LinkedList<File> modFiles = new LinkedList<File>();
  201 +
  202 + // Find and enumerate the "mods" folder
  203 + File modFolder = getModsFolder();
  204 + if (modFolder.exists() && modFolder.isDirectory())
  205 + {
  206 + logger.info("Mods folder found, searching " + modFolder.getPath());
  207 + findModFiles(modFolder, modFiles);
  208 + logger.info("Found " + modFiles.size() + " mod file(s)");
  209 + }
  210 +
  211 + // Find and enumerate classes on the class path
  212 + HashMap<String, Class> modsToLoad = null;
  213 + try
  214 + {
  215 + logger.info("Loading mods from class path");
  216 +
  217 + String[] classPathEntries = System.getProperty("java.class.path").split(";");
  218 + modsToLoad = findModClasses(classPathEntries, modFiles);
  219 + }
  220 + catch (Exception ex)
  221 + {
  222 + // TODO Auto-generated catch block
  223 + ex.printStackTrace();
  224 + }
  225 +
  226 + loadMods(modsToLoad);
  227 + }
  228 +
  229 + /**
  230 + * Find mod files in the "mods" folder
  231 + *
  232 + * @param modFolder Folder to search
  233 + * @param modFiles List of mod files to load
  234 + */
  235 + protected void findModFiles(File modFolder, LinkedList<File> modFiles)
  236 + {
  237 + for (File modFile : modFolder.listFiles(this))
  238 + {
  239 + try
  240 + {
  241 + // Check for a version file
  242 + ZipFile modZip = new ZipFile(modFile);
  243 + ZipEntry version = modZip.getEntry("version.txt");
  244 +
  245 + if (version != null)
  246 + {
  247 + // Read the version string
  248 + InputStream versionStream = modZip.getInputStream(version);
  249 + BufferedReader versionReader = new BufferedReader(new InputStreamReader(versionStream));
  250 + String strVersion = versionReader.readLine();
  251 + versionReader.close();
  252 +
  253 + // Only add the mod if the version matches and we were able to successfully add it to the class path
  254 + if (strVersion.equals(MINECRAFT_VERSION) && addURLToClassPath(modFile.toURI().toURL()))
  255 + {
  256 + modFiles.add(modFile);
  257 + }
  258 + }
  259 +
  260 + modZip.close();
  261 + }
  262 + catch (Exception ex)
  263 + {
  264 + logger.warning("Error enumerating '" + modFile.getAbsolutePath() + "': Invalid zip file or error reading file");
  265 + }
  266 + }
  267 + }
  268 +
  269 + /* (non-Javadoc)
  270 + * @see java.io.FilenameFilter#accept(java.io.File, java.lang.String)
  271 + */
  272 + @Override
  273 + public boolean accept(File dir, String fileName)
  274 + {
  275 + return fileName.toLowerCase().endsWith(".litemod");
  276 + }
  277 +
  278 + /**
  279 + * Find mod classes in the class path and enumerated mod files list
  280 + *
  281 + * @param classPathEntries Java class path split into string entries
  282 + * @return map of classes to load
  283 + */
  284 + private HashMap<String, Class> findModClasses(String[] classPathEntries, LinkedList<File> modFiles)
  285 + {
  286 + // To try to avoid loading the same mod multiple times if it appears in more than one entry in the class path, we index
  287 + // the mods by name and hopefully match only a single instance of a particular mod
  288 + HashMap<String, Class> modsToLoad = new HashMap<String, Class>();
  289 +
  290 + // Search through the class path and find mod classes
  291 + for (String classPathPart : classPathEntries)
  292 + {
  293 + File packagePath = new File(classPathPart);
  294 + LinkedList<Class> modClasses = getSubclassesFor(packagePath, Minecraft.class.getClassLoader(), LiteMod.class, "LiteMod");
  295 +
  296 + for (Class mod : modClasses)
  297 + {
  298 + modsToLoad.put(mod.getSimpleName(), mod);
  299 + }
  300 + }
  301 +
  302 + // Search through mod files and find mod classes
  303 + for (File modFile : modFiles)
  304 + {
  305 + LinkedList<Class> modClasses = getSubclassesFor(modFile, Minecraft.class.getClassLoader(), LiteMod.class, "LiteMod");
  306 +
  307 + for (Class mod : modClasses)
  308 + {
  309 + modsToLoad.put(mod.getSimpleName(), mod);
  310 + }
  311 + }
  312 +
  313 + return modsToLoad;
  314 + }
  315 +
  316 + /**
  317 + * Create mod instances from the enumerated classes
  318 + *
  319 + * @param modsToLoad List of mods to load
  320 + */
  321 + private void loadMods(HashMap<String, Class> modsToLoad)
  322 + {
  323 + if (modsToLoad == null) return;
  324 +
  325 + logger.info("Loading mods");
  326 +
  327 + for (Class mod : modsToLoad.values())
  328 + {
  329 + try
  330 + {
  331 + logger.info("Loading mod from " + mod.getName());
  332 +
  333 + LiteMod newMod = (LiteMod)mod.newInstance();
  334 + mods.add(newMod);
  335 +
  336 + logger.info("Successfully added mod " + newMod.getName() + " version " + newMod.getVersion());
  337 + }
  338 + catch (Throwable th)
  339 + {
  340 + logger.warning(th.getMessage());
  341 + }
  342 + }
  343 + }
  344 +
  345 + /**
  346 + * Initialise the mods which were loaded
  347 + */
  348 + private void initMods()
  349 + {
  350 + for (Iterator<LiteMod> iter = mods.iterator(); iter.hasNext();)
  351 + {
  352 + LiteMod mod = iter.next();
  353 +
  354 + try
  355 + {
  356 + mod.init();
  357 +
  358 + if (mod instanceof Tickable)
  359 + {
  360 + tickMods.add((Tickable)mod);
  361 + }
  362 +
  363 + if (mod instanceof ChatFilter)
  364 + {
  365 + chatFilters.add((ChatFilter)mod);
  366 + }
  367 +
  368 + if (mod instanceof ChatListener && !(mod instanceof ChatFilter))
  369 + {
  370 + chatListeners.add((ChatListener)mod);
  371 + }
  372 +
  373 + if (mod instanceof LoginListener)
  374 + {
  375 + loginListeners.add((LoginListener)mod);
  376 + }
  377 + }
  378 + catch (Throwable th)
  379 + {
  380 + logger.warning("Error initialising mod '" + mod.getName() + "': " + th.getMessage());
  381 + iter.remove();
  382 + }
  383 + }
  384 + }
  385 +
  386 + /**
  387 + * Initialise mod hooks
  388 + */
  389 + private void initHooks()
  390 + {
  391 + try
  392 + {
  393 + // Chat hook
  394 + if (chatListeners.size() > 0 || chatFilters.size() > 0)
  395 + {
  396 + registerPacketOverride(3, HookChat.class);
  397 + HookChat.loader = this;
  398 + }
  399 +
  400 + // Login hook
  401 + if (loginListeners.size() > 0)
  402 + {
  403 + registerPacketOverride(1, HookLogin.class);
  404 + HookLogin.loader = this;
  405 + }
  406 +
  407 + // Tick hook
  408 + if (tickMods.size() > 0)
  409 + {
  410 + Field modifiers = Field.class.getDeclaredField("modifiers");
  411 + modifiers.setAccessible(true);
  412 +
  413 + Field profiler = Minecraft.class.getDeclaredField(getObfuscatedFieldName("mcProfiler", "I"));
  414 + modifiers.setInt(profiler, profiler.getModifiers() & ~Modifier.FINAL);
  415 + profiler.setAccessible(true);
  416 + profiler.set(minecraft, new LiteLoaderHook(this, logger));
  417 + }
  418 + }
  419 + catch (Exception ex)
  420 + {
  421 + logger.warning("Error creating hooks: " + ex.getMessage());
  422 + }
  423 + }
  424 +
  425 + /**
  426 + * Enumerate classes on the classpath which are subclasses of the specified
  427 + * class
  428 + *
  429 + * @param superClass
  430 + * @return
  431 + */
  432 + private static LinkedList<Class> getSubclassesFor(File packagePath, ClassLoader classloader, Class superClass, String prefix)
  433 + {
  434 + LinkedList<Class> classes = new LinkedList<Class>();
  435 +
  436 + try
  437 + {
  438 + if (packagePath.isDirectory())
  439 + {
  440 + enumerateDirectory(prefix, superClass, classloader, classes, packagePath);
  441 + }
  442 + else if (packagePath.isFile() && (packagePath.getName().endsWith(".jar") || packagePath.getName().endsWith(".zip") || packagePath.getName().endsWith(".litemod")))
  443 + {
  444 + enumerateCompressedPackage(prefix, superClass, classloader, classes, packagePath);
  445 + }
  446 + }
  447 + catch (Throwable th)
  448 + {
  449 + logger.warning(th.getMessage());
  450 + }
  451 +
  452 + return classes;
  453 + }
  454 +
  455 + /**
  456 + * @param superClass
  457 + * @param classloader
  458 + * @param classes
  459 + * @param packagePath
  460 + * @throws FileNotFoundException
  461 + * @throws IOException
  462 + */
  463 + private static void enumerateCompressedPackage(String prefix, Class superClass, ClassLoader classloader, LinkedList<Class> classes, File packagePath) throws FileNotFoundException, IOException
  464 + {
  465 + FileInputStream fileinputstream = new FileInputStream(packagePath);
  466 + ZipInputStream zipinputstream = new ZipInputStream(fileinputstream);
  467 +
  468 + ZipEntry zipentry = null;
  469 +
  470 + do
  471 + {
  472 + zipentry = zipinputstream.getNextEntry();
  473 +
  474 + if (zipentry != null && zipentry.getName().endsWith(".class"))
  475 + {
  476 + String classFileName = zipentry.getName();
  477 + String className = classFileName.lastIndexOf('/') > -1 ? classFileName.substring(classFileName.lastIndexOf('/') + 1) : classFileName;
  478 +
  479 + if (prefix == null || className.startsWith(prefix))
  480 + {
  481 + try
  482 + {
  483 + String fullClassName = classFileName.substring(0, classFileName.length() - 6).replaceAll("/", ".");
  484 + checkAndAddClass(classloader, superClass, classes, fullClassName);
  485 + }
  486 + catch (Exception ex)
  487 + {
  488 + }
  489 + }
  490 + }
  491 + } while (zipentry != null);
  492 +
  493 + fileinputstream.close();
  494 + }
  495 +
  496 + /**
  497 + * Recursive function to enumerate classes inside a classpath folder
  498 + *
  499 + * @param superClass
  500 + * @param classloader
  501 + * @param classes
  502 + * @param packagePath
  503 + * @param packageName
  504 + */
  505 + private static void enumerateDirectory(String prefix, Class superClass, ClassLoader classloader, LinkedList<Class> classes, File packagePath)
  506 + {
  507 + enumerateDirectory(prefix, superClass, classloader, classes, packagePath, "");
  508 + }
  509 +
  510 + /**
  511 + * Recursive function to enumerate classes inside a classpath folder
  512 + *
  513 + * @param superClass
  514 + * @param classloader
  515 + * @param classes
  516 + * @param packagePath
  517 + * @param packageName
  518 + */
  519 + private static void enumerateDirectory(String prefix, Class superClass, ClassLoader classloader, LinkedList<Class> classes, File packagePath, String packageName)
  520 + {
  521 + File[] classFiles = packagePath.listFiles();
  522 +
  523 + for (File classFile : classFiles)
  524 + {
  525 + if (classFile.isDirectory())
  526 + {
  527 + enumerateDirectory(prefix, superClass, classloader, classes, classFile, packageName + classFile.getName() + ".");
  528 + }
  529 + else
  530 + {
  531 + if (classFile.getName().endsWith(".class") && (prefix == null || classFile.getName().startsWith(prefix)))
  532 + {
  533 + String classFileName = classFile.getName();
  534 + String className = packageName + classFileName.substring(0, classFileName.length() - 6);
  535 + checkAndAddClass(classloader, superClass, classes, className);
  536 + }
  537 + }
  538 + }
  539 + }
  540 +
  541 + /**
  542 + * @param classloader
  543 + * @param superClass
  544 + * @param classes
  545 + * @param className
  546 + */
  547 + private static void checkAndAddClass(ClassLoader classloader, Class superClass, LinkedList<Class> classes, String className)
  548 + {
  549 + if (className.indexOf('$') > -1)
  550 + return;
  551 +
  552 + try
  553 + {
  554 + Class subClass = classloader.loadClass(className);
  555 +
  556 + if (subClass != null && !superClass.equals(subClass) && superClass.isAssignableFrom(subClass) && !subClass.isInterface() && !classes.contains(subClass))
  557 + {
  558 + classes.add(subClass);
  559 + }
  560 + }
  561 + catch (Throwable th)
  562 + {
  563 + logger.warning(th.getMessage());
  564 + }
  565 + }
  566 +
  567 + /**
  568 + * Register a packet override
  569 + *
  570 + * @param packetId
  571 + * @param newPacket
  572 + */
  573 + private static boolean registerPacketOverride(int packetId, Class newPacket)
  574 + {
  575 + try
  576 + {
  577 + IntHashMap packetIdToClassMap = Packet.packetIdToClassMap;
  578 + Field fPacketClassToIdMap = Packet.class.getDeclaredField(getObfuscatedFieldName("packetClassToIdMap", "a"));
  579 + fPacketClassToIdMap.setAccessible(true);
  580 + Map packetClassToIdMap = (Map)fPacketClassToIdMap.get(null);
  581 +
  582 + packetIdToClassMap.removeObject(packetId);
  583 + packetIdToClassMap.addKey(packetId, newPacket);
  584 + packetClassToIdMap.put(newPacket, Integer.valueOf(packetId));
  585 +
  586 + return true;
  587 + }
  588 + catch (Exception ex)
  589 + {
  590 + logger.warning("Error registering packet override for packet id " + packetId + ": " + ex.getMessage());
  591 + return false;
  592 + }
  593 + }
  594 +
  595 + /**
  596 + * Abstraction helper function
  597 + *
  598 + * @param fieldName Name of field to get, returned unmodified if in debug mode
  599 + * @return Obfuscated field name if present
  600 + */
  601 + private static String getObfuscatedFieldName(String fieldName, String obfuscatedFieldName)
  602 + {
  603 + return (!net.minecraft.src.Tessellator.instance.getClass().getSimpleName().equals("Tessellator")) ? obfuscatedFieldName : fieldName;
  604 + }
  605 +
  606 + /**
  607 + * Add a URL to the Minecraft classloader class path
  608 + *
  609 + * @param classUrl URL of the resource to add
  610 + */
  611 + private boolean addURLToClassPath(URL classUrl)
  612 + {
  613 + try
  614 + {
  615 + if (Minecraft.class.getClassLoader() instanceof URLClassLoader && mAddUrl != null && mAddUrl.isAccessible())
  616 + {
  617 + URLClassLoader classLoader = (URLClassLoader)Minecraft.class.getClassLoader();
  618 + mAddUrl.invoke(classLoader, classUrl);
  619 + return true;
  620 + }
  621 + }
  622 + catch (Throwable th)
  623 + {
  624 + logger.warning("Error adding class path entry: " + th.getMessage());
  625 + }
  626 +
  627 + return false;
  628 + }
  629 +
  630 + /**
  631 + * Callback from the tick hook, ticks all tickable mods
  632 + *
  633 + * @param tick True if this is a new tick (otherwise it's just a new frame)
  634 + */
  635 + public void onTick(boolean tick)
  636 + {
  637 + float partialTicks = 0.0F;
  638 +
  639 + // Try to get the minecraft timer object and determine the value of the partialTicks
  640 + if (tick || minecraftTimer == null)
  641 + {
  642 + try
  643 + {
  644 + Field fTimer = Minecraft.class.getDeclaredField(getObfuscatedFieldName("Timer", "T"));
  645 + fTimer.setAccessible(true);
  646 + minecraftTimer = (Timer)fTimer.get(minecraft);
  647 +
  648 + }
  649 + catch (Exception ex) {}
  650 +
  651 + // Hooray, we got the timer reference
  652 + if (minecraftTimer != null)
  653 + {
  654 + partialTicks = minecraftTimer.elapsedPartialTicks;
  655 + }
  656 + }
  657 +
  658 + // Flag indicates whether we are in game at the moment
  659 + boolean inGame = minecraft.renderViewEntity != null && minecraft.renderViewEntity.worldObj != null;
  660 +
  661 + // Iterate tickable mods
  662 + for (Tickable tickable : tickMods)
  663 + {
  664 + tickable.onTick(minecraft, partialTicks, inGame, tick);
  665 + }
  666 + }
  667 +
  668 + /**
  669 + * Callback from the chat hook
  670 + *
  671 + * @param chatPacket
  672 + * @return
  673 + */
  674 + public boolean onChat(Packet3Chat chatPacket)
  675 + {
  676 + // Chat filters get a stab at the chat first, if any filter returns false the chat is discarded
  677 + for (ChatFilter chatFilter : chatFilters)
  678 + if (!chatFilter.onChat(chatPacket))
  679 + return false;
  680 +
  681 + // Chat listeners get the chat if no filter removed it
  682 + for (ChatListener chatListener : chatListeners)
  683 + chatListener.onChat(chatPacket.message);
  684 +
  685 + return true;
  686 + }
  687 +
  688 + /**
  689 + * Callback from the login hook
  690 + *
  691 + * @param netHandler
  692 + * @param loginPacket
  693 + */
  694 + public void onConnectToServer(NetHandler netHandler, Packet1Login loginPacket)
  695 + {
  696 + for (LoginListener loginListener : loginListeners)
  697 + loginListener.onLogin(netHandler, loginPacket);
  698 + }
  699 +}
... ...
java/com/mumfrey/liteloader/core/LiteLoaderHook.java 0 → 100644
  1 +package com.mumfrey.liteloader.core;
  2 +
  3 +import java.util.LinkedList;
  4 +import java.util.logging.Logger;
  5 +
  6 +import net.minecraft.src.Profiler;
  7 +
  8 +public class LiteLoaderHook extends Profiler
  9 +{
  10 + private Logger logger;
  11 +
  12 + private LiteLoader core;
  13 +
  14 + private LinkedList<String> sections = new LinkedList<String>();
  15 +
  16 + private boolean tick;
  17 +
  18 + public LiteLoaderHook(LiteLoader core, Logger logger)
  19 + {
  20 + this.core = core;
  21 + this.logger = logger;
  22 + }
  23 +
  24 + /* (non-Javadoc)
  25 + * @see net.minecraft.src.Profiler#startSection(java.lang.String)
  26 + */
  27 + @Override
  28 + public void startSection(String sectionName)
  29 + {
  30 + if (sectionName.equals("animateTick")) tick = true;
  31 + sections.add(sectionName);
  32 + super.startSection(sectionName);
  33 + }
  34 +
  35 + /* (non-Javadoc)
  36 + * @see net.minecraft.src.Profiler#endSection()
  37 + */
  38 + @Override
  39 + public void endSection()
  40 + {
  41 + super.endSection();
  42 +
  43 + String endingSection = sections.removeLast();
  44 +
  45 + if (endingSection.equalsIgnoreCase("gameRenderer") && sections.getLast().equalsIgnoreCase("root"))
  46 + {
  47 + super.startSection("litetick");
  48 +
  49 + core.onTick(tick);
  50 + tick = false;
  51 +
  52 + super.endSection();
  53 + }
  54 + }
  55 +
  56 +}
... ...
java/net/minecraft/src/RenderLightningBolt.java 0 → 100644
  1 +package net.minecraft.src;
  2 +
  3 +import java.util.Random;
  4 +import org.lwjgl.opengl.GL11;
  5 +
  6 +import com.mumfrey.liteloader.core.LiteLoader;
  7 +
  8 +public class RenderLightningBolt extends Render
  9 +{
  10 + static
  11 + {
  12 + // LiteLoader init
  13 + LiteLoader.getInstance();
  14 + }
  15 +
  16 + /**
  17 + * Actually renders the lightning bolt. This method is called through the doRender method.
  18 + */
  19 + public void doRenderLightningBolt(EntityLightningBolt par1EntityLightningBolt, double par2, double par4, double par6, float par8, float par9)
  20 + {
  21 + Tessellator var10 = Tessellator.instance;
  22 + GL11.glDisable(GL11.GL_TEXTURE_2D);
  23 + GL11.glDisable(GL11.GL_LIGHTING);
  24 + GL11.glEnable(GL11.GL_BLEND);
  25 + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);
  26 + double[] var11 = new double[8];
  27 + double[] var12 = new double[8];
  28 + double var13 = 0.0D;
  29 + double var15 = 0.0D;
  30 + Random var17 = new Random(par1EntityLightningBolt.boltVertex);
  31 +
  32 + for (int var18 = 7; var18 >= 0; --var18)
  33 + {
  34 + var11[var18] = var13;
  35 + var12[var18] = var15;
  36 + var13 += (double)(var17.nextInt(11) - 5);
  37 + var15 += (double)(var17.nextInt(11) - 5);
  38 + }
  39 +
  40 + for (int var45 = 0; var45 < 4; ++var45)
  41 + {
  42 + Random var46 = new Random(par1EntityLightningBolt.boltVertex);
  43 +
  44 + for (int var19 = 0; var19 < 3; ++var19)
  45 + {
  46 + int var20 = 7;
  47 + int var21 = 0;
  48 +
  49 + if (var19 > 0)
  50 + {
  51 + var20 = 7 - var19;
  52 + }
  53 +
  54 + if (var19 > 0)
  55 + {
  56 + var21 = var20 - 2;
  57 + }
  58 +
  59 + double var22 = var11[var20] - var13;
  60 + double var24 = var12[var20] - var15;
  61 +
  62 + for (int var26 = var20; var26 >= var21; --var26)
  63 + {
  64 + double var27 = var22;
  65 + double var29 = var24;
  66 +
  67 + if (var19 == 0)
  68 + {
  69 + var22 += (double)(var46.nextInt(11) - 5);
  70 + var24 += (double)(var46.nextInt(11) - 5);
  71 + }
  72 + else
  73 + {
  74 + var22 += (double)(var46.nextInt(31) - 15);
  75 + var24 += (double)(var46.nextInt(31) - 15);
  76 + }
  77 +
  78 + var10.startDrawing(5);
  79 + float var31 = 0.5F;
  80 + var10.setColorRGBA_F(0.9F * var31, 0.9F * var31, 1.0F * var31, 0.3F);
  81 + double var32 = 0.1D + (double)var45 * 0.2D;
  82 +
  83 + if (var19 == 0)
  84 + {
  85 + var32 *= (double)var26 * 0.1D + 1.0D;
  86 + }
  87 +
  88 + double var34 = 0.1D + (double)var45 * 0.2D;
  89 +
  90 + if (var19 == 0)
  91 + {
  92 + var34 *= (double)(var26 - 1) * 0.1D + 1.0D;
  93 + }
  94 +
  95 + for (int var36 = 0; var36 < 5; ++var36)
  96 + {
  97 + double var37 = par2 + 0.5D - var32;
  98 + double var39 = par6 + 0.5D - var32;
  99 +
  100 + if (var36 == 1 || var36 == 2)
  101 + {
  102 + var37 += var32 * 2.0D;
  103 + }
  104 +
  105 + if (var36 == 2 || var36 == 3)
  106 + {
  107 + var39 += var32 * 2.0D;
  108 + }
  109 +
  110 + double var41 = par2 + 0.5D - var34;
  111 + double var43 = par6 + 0.5D - var34;
  112 +
  113 + if (var36 == 1 || var36 == 2)
  114 + {
  115 + var41 += var34 * 2.0D;
  116 + }
  117 +
  118 + if (var36 == 2 || var36 == 3)
  119 + {
  120 + var43 += var34 * 2.0D;
  121 + }
  122 +
  123 + var10.addVertex(var41 + var22, par4 + (double)(var26 * 16), var43 + var24);
  124 + var10.addVertex(var37 + var27, par4 + (double)((var26 + 1) * 16), var39 + var29);
  125 + }
  126 +
  127 + var10.draw();
  128 + }
  129 + }
  130 + }
  131 +
  132 + GL11.glDisable(GL11.GL_BLEND);
  133 + GL11.glEnable(GL11.GL_LIGHTING);
  134 + GL11.glEnable(GL11.GL_TEXTURE_2D);
  135 + }
  136 +
  137 + /**
  138 + * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then
  139 + * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic
  140 + * (Render<T extends Entity) and this method has signature public void doRender(T entity, double d, double d1,
  141 + * double d2, float f, float f1). But JAD is pre 1.5 so doesn't do that.
  142 + */
  143 + public void doRender(Entity par1Entity, double par2, double par4, double par6, float par8, float par9)
  144 + {
  145 + this.doRenderLightningBolt((EntityLightningBolt)par1Entity, par2, par4, par6, par8, par9);
  146 + }
  147 +}
... ...