Commit 34ccde51f499b777cbe30d71c21eaca8df9d8c55

Authored by Mumfrey
1 parent 71879cd0

Preliminary commit for 1.6.3

+ Merged in launcher code
 + Refactored events and plugin channels into separate classes
 + Added HUDRenderListener
 + Added ClientBrandRetriever support
 + Added mod disablement support
 + Cross-thread check in profiler hook
Showing 33 changed files with 2266 additions and 1159 deletions
.classpath
... ... @@ -8,5 +8,8 @@
8 8 <classpathentry kind="lib" path="/Client/jars/libraries/com/google/code/gson/gson/2.2.2/gson-2.2.2.jar"/>
9 9 <classpathentry kind="lib" path="/Client/jars/libraries/com/google/guava/guava/14.0/guava-14.0.jar"/>
10 10 <classpathentry kind="lib" path="/Client/jars/libraries/commons-io/commons-io/2.4/commons-io-2.4.jar"/>
  11 + <classpathentry kind="lib" path="lib/launchwrapper-1.7.jar"/>
  12 + <classpathentry kind="lib" path="lib/jopt-simple-4.5.jar"/>
  13 + <classpathentry kind="src" path="run"/>
11 14 <classpathentry kind="output" path="bin"/>
12 15 </classpath>
... ...
ant/build_liteloader.xml
... ... @@ -4,14 +4,14 @@
4 4 <taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
5 5  
6 6 <!-- Versions !!IMPORTANT -->
7   - <property name="version" value="1.6.2" />
8   - <property name="mcversion" value="1.6.2" />
  7 + <property name="version" value="1.6.3" />
  8 + <property name="mcversion" value="1.6.3" />
9 9 <property name="author" value="Mumfrey" />
10 10  
11 11 <!-- Project definitions and dependencies -->
12   - <property name="upstream" value="LiteLoader,LegacyLauncher" />
13   - <property name="project" value="LiteLoaderLauncher" />
14   - <property name="md5set" value="legacylauncher" />
  12 + <property name="upstream" value="" />
  13 + <property name="project" value="LiteLoader" />
  14 + <property name="md5set" value="mcp" />
15 15 <property name="outmd5set" value="liteloader" />
16 16  
17 17 <property name="mcp.dir" location="../../.." />
... ... @@ -21,6 +21,7 @@
21 21 <property name="temp" location="${mcp.dir}/temp" />
22 22 <property name="md5.dir" location="${mcp.dir}/md5" />
23 23 <property name="mc.src" location="${mcp.dir}/src/mcp" />
  24 + <property name="libs" location="${mcp.dir}/lib" />
24 25  
25 26 <property name="dist.dir" location="${build}/dist" />
26 27 <property name="stage.dir" location="${build}/stage/${ant.project.name}/${version}" />
... ... @@ -62,6 +63,10 @@
62 63 <target name="prepare" description="Prepare source for MCP" depends="preparemd5">
63 64 <echo level="info" message="Prepare sources for compile" />
64 65  
  66 + <copy todir="${libs}" verbose="true" overwrite="true">
  67 + <fileset dir="${eclipse}/LiteLoader/lib" />
  68 + </copy>
  69 +
65 70 <copy todir="${src}" verbose="false" overwrite="true">
66 71 <fileset dir="${mc.src}" />
67 72 </copy>
... ...
java/com/mumfrey/liteloader/HUDRenderListener.java 0 โ†’ 100644
  1 +package com.mumfrey.liteloader;
  2 +
  3 +/**
  4 + * Interface for mods which want callbacks when the HUD is rendered
  5 + *
  6 + * @author Adam Mummery-Smith
  7 + */
  8 +public interface HUDRenderListener
  9 +{
  10 + public abstract void onPreRenderHUD(int screenWidth, int screenHeight);
  11 +
  12 + public abstract void onPostRenderHUD(int screenWidth, int screenHeight);
  13 +}
... ...
java/com/mumfrey/liteloader/core/ClassPathMod.java
... ... @@ -35,10 +35,12 @@ public class ClassPathMod extends ModFile
35 35 {
36 36 if (this.isDirectory())
37 37 {
  38 + LiteLoader.getLogger().info(String.format("Registering \"%s/%s\" as mod resource pack with identifier \"%s\"", this.getParentFile().getName(), this.getName(), name));
38 39 this.resourcePack = new ModResourcePackDir(name, this);
39 40 }
40 41 else
41 42 {
  43 + LiteLoader.getLogger().info(String.format("Registering \"%s\" as mod resource pack with identifier \"%s\"", this.getName(), name));
42 44 this.resourcePack = new ModResourcePack(name, this);
43 45 }
44 46  
... ...
java/com/mumfrey/liteloader/core/EnabledModsList.java 0 โ†’ 100644
  1 +package com.mumfrey.liteloader.core;
  2 +
  3 +import java.io.File;
  4 +import java.io.FileReader;
  5 +import java.io.FileWriter;
  6 +import java.io.IOException;
  7 +import java.util.List;
  8 +import java.util.Map;
  9 +import java.util.TreeMap;
  10 +
  11 +import com.google.gson.Gson;
  12 +import com.google.gson.GsonBuilder;
  13 +
  14 +public class EnabledModsList
  15 +{
  16 + private static transient Gson gson = new GsonBuilder().setPrettyPrinting().create();
  17 +
  18 + private TreeMap<String, TreeMap<String, Boolean>> mods;
  19 +
  20 + private transient Boolean defaultEnabledValue = Boolean.TRUE;
  21 +
  22 + private transient boolean allowSave = true;
  23 +
  24 + private EnabledModsList()
  25 + {
  26 + }
  27 +
  28 + public boolean isEnabled(String profileName, String name)
  29 + {
  30 + Map<String, Boolean> profile = this.getProfile(profileName);
  31 + name = name.toLowerCase().trim();
  32 +
  33 + if (!profile.containsKey(name))
  34 + {
  35 + profile.put(name, this.defaultEnabledValue);
  36 + }
  37 +
  38 + return profile.get(name);
  39 + }
  40 +
  41 + public void setEnabled(String profileName, String name, boolean enabled)
  42 + {
  43 + Map<String, Boolean> profile = this.getProfile(profileName);
  44 + profile.put(name.toLowerCase().trim(), Boolean.valueOf(enabled));
  45 +
  46 + this.allowSave = true;
  47 + }
  48 +
  49 + public void processModsList(String profileName, List<String> modNameFilter)
  50 + {
  51 + Map<String, Boolean> profile = this.getProfile(profileName);
  52 +
  53 + try
  54 + {
  55 + if (modNameFilter != null)
  56 + {
  57 + for (String modName : profile.keySet())
  58 + {
  59 + profile.put(modName, Boolean.FALSE);
  60 + }
  61 +
  62 + this.defaultEnabledValue = Boolean.FALSE;
  63 + this.allowSave = false;
  64 +
  65 + for (String filterEntry : modNameFilter)
  66 + {
  67 + profile.put(filterEntry.toLowerCase().trim(), Boolean.TRUE);
  68 + }
  69 + }
  70 + }
  71 + catch (Exception ex)
  72 + {
  73 + this.defaultEnabledValue = Boolean.TRUE;
  74 + this.allowSave = true;
  75 + }
  76 + }
  77 +
  78 + private Map<String, Boolean> getProfile(String profileName)
  79 + {
  80 + if (this.mods == null) this.mods = new TreeMap<String, TreeMap<String,Boolean>>();
  81 +
  82 + if (!this.mods.containsKey(profileName))
  83 + {
  84 + this.mods.put(profileName, new TreeMap<String, Boolean>());
  85 + }
  86 +
  87 + return this.mods.get(profileName);
  88 + }
  89 +
  90 + public static EnabledModsList createFrom(File file)
  91 + {
  92 + if (file.exists())
  93 + {
  94 + FileReader reader = null;
  95 +
  96 + try
  97 + {
  98 + reader = new FileReader(file);
  99 + EnabledModsList instance = gson.fromJson(reader, EnabledModsList.class);
  100 + return instance;
  101 + }
  102 + catch (Exception ex)
  103 + {
  104 + ex.printStackTrace();
  105 + }
  106 + finally
  107 + {
  108 + try
  109 + {
  110 + if (reader != null)
  111 + reader.close();
  112 + }
  113 + catch (IOException ex)
  114 + {
  115 + ex.printStackTrace();
  116 + }
  117 + }
  118 + }
  119 +
  120 + return new EnabledModsList();
  121 + }
  122 +
  123 + public void saveTo(File file)
  124 + {
  125 + if (!this.allowSave) return;
  126 +
  127 + FileWriter writer = null;
  128 +
  129 + try
  130 + {
  131 + writer = new FileWriter(file);
  132 + gson.toJson(this, writer);
  133 + }
  134 + catch (Exception ex)
  135 + {
  136 + ex.printStackTrace();
  137 + }
  138 + finally
  139 + {
  140 + try
  141 + {
  142 + if (writer != null)
  143 + writer.close();
  144 + }
  145 + catch (IOException ex)
  146 + {
  147 + ex.printStackTrace();
  148 + }
  149 + }
  150 + }
  151 +}
... ...
java/com/mumfrey/liteloader/core/Events.java 0 โ†’ 100644
  1 +package com.mumfrey.liteloader.core;
  2 +
  3 +import java.util.LinkedList;
  4 +import java.util.logging.Level;
  5 +
  6 +import net.minecraft.src.*;
  7 +
  8 +import com.mumfrey.liteloader.*;
  9 +import com.mumfrey.liteloader.Tickable;
  10 +import com.mumfrey.liteloader.core.hooks.HookChat;
  11 +import com.mumfrey.liteloader.core.hooks.HookLogin;
  12 +import com.mumfrey.liteloader.core.hooks.HookProfiler;
  13 +import com.mumfrey.liteloader.util.ModUtilities;
  14 +import com.mumfrey.liteloader.util.PrivateFields;
  15 +
  16 +/**
  17 + *
  18 + * @author Adam Mummery-Smith
  19 + */
  20 +public class Events implements IPlayerUsage
  21 +{
  22 + /**
  23 + * Reference to the loader instance
  24 + */
  25 + private LiteLoader loader;
  26 +
  27 + /**
  28 + * Reference to the game
  29 + */
  30 + private Minecraft minecraft;
  31 +
  32 + /**
  33 + * Plugin channel manager
  34 + */
  35 + private PluginChannels pluginChannels;
  36 +
  37 + /**
  38 + * Reference to the minecraft timer
  39 + */
  40 + private Timer minecraftTimer;
  41 +
  42 + /**
  43 + * Flags which keep track of whether hooks have been applied
  44 + */
  45 + private boolean hookInitDone, lateInitDone, chatHooked, loginHooked, tickHooked;
  46 +
  47 + /**
  48 + * Profiler hook objects
  49 + */
  50 + private HookProfiler profilerHook = new HookProfiler(this);
  51 +
  52 + /**
  53 + * ScaledResolution used by the pre-chat and post-chat render callbacks
  54 + */
  55 + private ScaledResolution currentResolution;
  56 +
  57 + /**
  58 + * Current screen width
  59 + */
  60 + private int screenWidth = 854;
  61 +
  62 + /**
  63 + * Current screen height
  64 + */
  65 + private int screenHeight = 480;
  66 +
  67 +
  68 + /**
  69 + * List of mods which implement Tickable interface and will receive tick
  70 + * events
  71 + */
  72 + private LinkedList<Tickable> tickListeners = new LinkedList<Tickable>();
  73 +
  74 + /**
  75 + * List of mods which implement the GameLoopListener interface and will
  76 + * receive loop events
  77 + */
  78 + private LinkedList<GameLoopListener> loopListeners = new LinkedList<GameLoopListener>();
  79 +
  80 + /**
  81 + *
  82 + */
  83 + private LinkedList<InitCompleteListener> initListeners = new LinkedList<InitCompleteListener>();
  84 +
  85 + /**
  86 + * List of mods which implement RenderListener interface and will receive
  87 + * render events events
  88 + */
  89 + private LinkedList<RenderListener> renderListeners = new LinkedList<RenderListener>();
  90 +
  91 + /**
  92 + * List of mods which implement the PostRenderListener interface and want to
  93 + * render entities
  94 + */
  95 + private LinkedList<PostRenderListener> postRenderListeners = new LinkedList<PostRenderListener>();
  96 +
  97 + /**
  98 + * List of mods which implement HUDRenderListener and want callbacks when HUD is rendered
  99 + */
  100 + private LinkedList<HUDRenderListener> hudRenderListeners = new LinkedList<HUDRenderListener>();
  101 +
  102 + /**
  103 + * List of mods which implement ChatRenderListener and want to know when
  104 + * chat is rendered
  105 + */
  106 + private LinkedList<ChatRenderListener> chatRenderListeners = new LinkedList<ChatRenderListener>();
  107 +
  108 + /**
  109 + * List of mods which implement ChatListener interface and will receive chat
  110 + * events
  111 + */
  112 + private LinkedList<ChatListener> chatListeners = new LinkedList<ChatListener>();
  113 +
  114 + /**
  115 + * List of mods which implement ChatFilter interface and will receive chat
  116 + * filter events
  117 + */
  118 + private LinkedList<ChatFilter> chatFilters = new LinkedList<ChatFilter>();
  119 +
  120 + /**
  121 + * List of mods which implement LoginListener interface and will receive
  122 + * client login events
  123 + */
  124 + private LinkedList<LoginListener> loginListeners = new LinkedList<LoginListener>();
  125 +
  126 + /**
  127 + * List of mods which implement LoginListener interface and will receive
  128 + * client login events
  129 + */
  130 + private LinkedList<PreLoginListener> preLoginListeners = new LinkedList<PreLoginListener>();
  131 +
  132 + public Events(LiteLoader loader, Minecraft minecraft, PluginChannels pluginChannels)
  133 + {
  134 + this.loader = loader;
  135 + this.minecraft = minecraft;
  136 + this.pluginChannels = pluginChannels;
  137 + }
  138 +
  139 + /**
  140 + * Add a listener to the relevant listener lists
  141 + *
  142 + * @param listener
  143 + */
  144 + public void addListener(LiteMod listener)
  145 + {
  146 + if (listener instanceof Tickable)
  147 + {
  148 + this.addTickListener((Tickable)listener);
  149 + }
  150 +
  151 + if (listener instanceof GameLoopListener)
  152 + {
  153 + this.addLoopListener((GameLoopListener)listener);
  154 + }
  155 +
  156 + if (listener instanceof InitCompleteListener)
  157 + {
  158 + this.addInitListener((InitCompleteListener)listener);
  159 + }
  160 +
  161 + if (listener instanceof RenderListener)
  162 + {
  163 + this.addRenderListener((RenderListener)listener);
  164 + }
  165 +
  166 + if (listener instanceof PostRenderListener)
  167 + {
  168 + this.addPostRenderListener((PostRenderListener)listener);
  169 + }
  170 +
  171 + if (listener instanceof ChatFilter)
  172 + {
  173 + this.addChatFilter((ChatFilter)listener);
  174 + }
  175 +
  176 + if (listener instanceof ChatListener)
  177 + {
  178 + if (listener instanceof ChatFilter)
  179 + {
  180 + LiteLoader.getLogger().warning(String.format("Interface error initialising mod '%1s'. A mod implementing ChatFilter and ChatListener is not supported! Remove one of these interfaces", listener.getName()));
  181 + }
  182 + else
  183 + {
  184 + this.addChatListener((ChatListener)listener);
  185 + }
  186 + }
  187 +
  188 + if (listener instanceof ChatRenderListener)
  189 + {
  190 + this.addChatRenderListener((ChatRenderListener)listener);
  191 + }
  192 +
  193 + if (listener instanceof HUDRenderListener)
  194 + {
  195 + this.addHUDRenderListener((HUDRenderListener)listener);
  196 + }
  197 +
  198 + if (listener instanceof PreLoginListener)
  199 + {
  200 + this.addPreLoginListener((PreLoginListener)listener);
  201 + }
  202 +
  203 + if (listener instanceof LoginListener)
  204 + {
  205 + this.addLoginListener((LoginListener)listener);
  206 + }
  207 +
  208 + if (listener instanceof PluginChannelListener)
  209 + {
  210 + this.pluginChannels.addPluginChannelListener((PluginChannelListener)listener);
  211 + }
  212 + }
  213 +
  214 +
  215 + /**
  216 + * Initialise mod hooks
  217 + */
  218 + public void initHooks()
  219 + {
  220 + try
  221 + {
  222 + LiteLoader.getLogger().info("Event manager is registering hooks");
  223 +
  224 + // Chat hook
  225 + if ((this.chatListeners.size() > 0 || this.chatFilters.size() > 0) && !this.chatHooked)
  226 + {
  227 + this.chatHooked = true;
  228 + HookChat.register();
  229 + HookChat.registerPacketHandler(this);
  230 + }
  231 +
  232 + // Login hook
  233 + if ((this.preLoginListeners.size() > 0 || this.loginListeners.size() > 0) && !this.loginHooked)
  234 + {
  235 + this.loginHooked = true;
  236 + ModUtilities.registerPacketOverride(1, HookLogin.class);
  237 + HookLogin.events = this;
  238 + }
  239 +
  240 + // Tick hook
  241 + if (!this.tickHooked)
  242 + {
  243 + this.tickHooked = true;
  244 + PrivateFields.minecraftProfiler.setFinal(this.minecraft, this.profilerHook);
  245 + }
  246 +
  247 + // Sanity hook
  248 + PlayerUsageSnooper snooper = this.minecraft.getPlayerUsageSnooper();
  249 + PrivateFields.playerStatsCollector.setFinal(snooper, this);
  250 +
  251 + this.pluginChannels.initHook();
  252 + }
  253 + catch (Exception ex)
  254 + {
  255 + LiteLoader.getLogger().log(Level.WARNING, "Error creating hooks", ex);
  256 + ex.printStackTrace();
  257 + }
  258 +
  259 + this.hookInitDone = true;
  260 + }
  261 +
  262 + /**
  263 + * @param tickable
  264 + */
  265 + public void addTickListener(Tickable tickable)
  266 + {
  267 + if (!this.tickListeners.contains(tickable))
  268 + {
  269 + this.tickListeners.add(tickable);
  270 + if (this.hookInitDone)
  271 + this.initHooks();
  272 + }
  273 + }
  274 +
  275 + /**
  276 + * @param loopListener
  277 + */
  278 + public void addLoopListener(GameLoopListener loopListener)
  279 + {
  280 + if (!this.loopListeners.contains(loopListener))
  281 + {
  282 + this.loopListeners.add(loopListener);
  283 + if (this.hookInitDone)
  284 + this.initHooks();
  285 + }
  286 + }
  287 +
  288 + /**
  289 + * @param initCompleteListener
  290 + */
  291 + public void addInitListener(InitCompleteListener initCompleteListener)
  292 + {
  293 + if (!this.initListeners.contains(initCompleteListener))
  294 + {
  295 + this.initListeners.add(initCompleteListener);
  296 + if (this.hookInitDone)
  297 + this.initHooks();
  298 + }
  299 + }
  300 +
  301 + /**
  302 + * @param renderListener
  303 + */
  304 + public void addRenderListener(RenderListener renderListener)
  305 + {
  306 + if (!this.renderListeners.contains(renderListener))
  307 + {
  308 + this.renderListeners.add(renderListener);
  309 + if (this.hookInitDone)
  310 + this.initHooks();
  311 + }
  312 + }
  313 +
  314 + /**
  315 + * @param postRenderListener
  316 + */
  317 + public void addPostRenderListener(PostRenderListener postRenderListener)
  318 + {
  319 + if (!this.postRenderListeners.contains(postRenderListener))
  320 + {
  321 + this.postRenderListeners.add(postRenderListener);
  322 + if (this.hookInitDone)
  323 + this.initHooks();
  324 + }
  325 + }
  326 +
  327 + /**
  328 + * @param chatFilter
  329 + */
  330 + public void addChatFilter(ChatFilter chatFilter)
  331 + {
  332 + if (!this.chatFilters.contains(chatFilter))
  333 + {
  334 + this.chatFilters.add(chatFilter);
  335 + if (this.hookInitDone)
  336 + this.initHooks();
  337 + }
  338 + }
  339 +
  340 + /**
  341 + * @param chatListener
  342 + */
  343 + public void addChatListener(ChatListener chatListener)
  344 + {
  345 + if (!this.chatListeners.contains(chatListener))
  346 + {
  347 + this.chatListeners.add(chatListener);
  348 + if (this.hookInitDone)
  349 + this.initHooks();
  350 + }
  351 + }
  352 +
  353 + /**
  354 + * @param chatRenderListener
  355 + */
  356 + public void addChatRenderListener(ChatRenderListener chatRenderListener)
  357 + {
  358 + if (!this.chatRenderListeners.contains(chatRenderListener))
  359 + {
  360 + this.chatRenderListeners.add(chatRenderListener);
  361 + if (this.hookInitDone)
  362 + this.initHooks();
  363 + }
  364 + }
  365 +
  366 + /**
  367 + * @param hudRenderListener
  368 + */
  369 + public void addHUDRenderListener(HUDRenderListener hudRenderListener)
  370 + {
  371 + if (!this.hudRenderListeners.contains(hudRenderListener))
  372 + {
  373 + this.hudRenderListeners.add(hudRenderListener);
  374 + if (this.hookInitDone)
  375 + this.initHooks();
  376 + }
  377 + }
  378 +
  379 + /**
  380 + * @param loginListener
  381 + */
  382 + public void addPreLoginListener(PreLoginListener loginListener)
  383 + {
  384 + if (!this.preLoginListeners.contains(loginListener))
  385 + {
  386 + this.preLoginListeners.add(loginListener);
  387 + if (this.hookInitDone)
  388 + this.initHooks();
  389 + }
  390 + }
  391 +
  392 + /**
  393 + * @param loginListener
  394 + */
  395 + public void addLoginListener(LoginListener loginListener)
  396 + {
  397 + if (!this.loginListeners.contains(loginListener))
  398 + {
  399 + this.loginListeners.add(loginListener);
  400 + if (this.hookInitDone)
  401 + this.initHooks();
  402 + }
  403 + }
  404 +
  405 + /**
  406 + * Late initialisation callback
  407 + */
  408 + public void onInit()
  409 + {
  410 + this.loader.refreshResources();
  411 +
  412 + if (!this.lateInitDone)
  413 + {
  414 + this.lateInitDone = true;
  415 +
  416 + for (InitCompleteListener initMod : this.initListeners)
  417 + {
  418 + try
  419 + {
  420 + LiteLoader.getLogger().info("Calling late init for mod " + initMod.getName());
  421 + initMod.onInitCompleted(this.minecraft, this.loader);
  422 + }
  423 + catch (Throwable th)
  424 + {
  425 + LiteLoader.getLogger().log(Level.WARNING, "Error initialising mod " + initMod.getName(), th);
  426 + }
  427 + }
  428 + }
  429 +
  430 + this.loader.onInit();
  431 + }
  432 +
  433 + /**
  434 + * Callback from the tick hook, pre render
  435 + */
  436 + public void onRender()
  437 + {
  438 + this.loader.onRender();
  439 +
  440 + for (RenderListener renderListener : this.renderListeners)
  441 + renderListener.onRender();
  442 + }
  443 +
  444 + /**
  445 + * Callback from the tick hook, post render entities
  446 + */
  447 + public void postRenderEntities()
  448 + {
  449 + float partialTicks = (this.minecraftTimer != null) ? this.minecraftTimer.elapsedPartialTicks : 0.0F;
  450 +
  451 + for (PostRenderListener renderListener : this.postRenderListeners)
  452 + renderListener.onPostRenderEntities(partialTicks);
  453 + }
  454 +
  455 + /**
  456 + * Callback from the tick hook, post render
  457 + */
  458 + public void postRender()
  459 + {
  460 + float partialTicks = (this.minecraftTimer != null) ? this.minecraftTimer.elapsedPartialTicks : 0.0F;
  461 +
  462 + for (PostRenderListener renderListener : this.postRenderListeners)
  463 + renderListener.onPostRender(partialTicks);
  464 + }
  465 +
  466 + /**
  467 + * Called immediately before the current GUI is rendered
  468 + */
  469 + public void preRenderGUI()
  470 + {
  471 + for (RenderListener renderListener : this.renderListeners)
  472 + renderListener.onRenderGui(this.minecraft.currentScreen);
  473 + }
  474 +
  475 + /**
  476 + * Called immediately after the world/camera transform is initialised
  477 + */
  478 + public void onSetupCameraTransform()
  479 + {
  480 + for (RenderListener renderListener : this.renderListeners)
  481 + renderListener.onSetupCameraTransform();
  482 + }
  483 +
  484 + /**
  485 + * Called immediately before the chat log is rendered
  486 + */
  487 + public void onRenderChat()
  488 + {
  489 + GuiNewChat chat = this.minecraft.ingameGUI.getChatGUI();
  490 +
  491 + for (ChatRenderListener chatRenderListener : this.chatRenderListeners)
  492 + chatRenderListener.onPreRenderChat(this.screenWidth, this.screenHeight, chat);
  493 + }
  494 +
  495 + /**
  496 + * Called immediately after the chat log is rendered
  497 + */
  498 + public void postRenderChat()
  499 + {
  500 + GuiNewChat chat = this.minecraft.ingameGUI.getChatGUI();
  501 +
  502 + for (ChatRenderListener chatRenderListener : this.chatRenderListeners)
  503 + chatRenderListener.onPostRenderChat(this.screenWidth, this.screenHeight, chat);
  504 + }
  505 +
  506 + /**
  507 + * Callback when about to render the HUD
  508 + */
  509 + public void onRenderHUD()
  510 + {
  511 + this.currentResolution = new ScaledResolution(this.minecraft.gameSettings, this.minecraft.displayWidth, this.minecraft.displayHeight);
  512 + this.screenWidth = this.currentResolution.getScaledWidth();
  513 + this.screenHeight = this.currentResolution.getScaledHeight();
  514 +
  515 + if (!this.minecraft.gameSettings.hideGUI || this.minecraft.currentScreen != null)
  516 + {
  517 + for (HUDRenderListener hudRenderListener : this.hudRenderListeners)
  518 + hudRenderListener.onPreRenderHUD(this.screenWidth, this.screenHeight);
  519 + }
  520 + }
  521 +
  522 + /**
  523 + * Callback when the HUD has just been rendered
  524 + */
  525 + public void postRenderHUD()
  526 + {
  527 + if (!this.minecraft.gameSettings.hideGUI || this.minecraft.currentScreen != null)
  528 + {
  529 + for (HUDRenderListener hudRenderListener : this.hudRenderListeners)
  530 + hudRenderListener.onPostRenderHUD(this.screenWidth, this.screenHeight);
  531 + }
  532 + }
  533 +
  534 + /**
  535 + * Callback from the tick hook, called every frame when the timer is updated
  536 + */
  537 + public void onTimerUpdate()
  538 + {
  539 + for (GameLoopListener loopListener : this.loopListeners)
  540 + loopListener.onRunGameLoop(this.minecraft);
  541 + }
  542 +
  543 + /**
  544 + * Callback from the tick hook, ticks all tickable mods
  545 + *
  546 + * @param clock True if this is a new tick (otherwise it's just a new frame)
  547 + */
  548 + public void onTick(Profiler profiler, boolean clock)
  549 + {
  550 + float partialTicks = 0.0F;
  551 +
  552 + // Try to get the minecraft timer object and determine the value of the
  553 + // partialTicks
  554 + if (clock || this.minecraftTimer == null)
  555 + {
  556 + this.minecraftTimer = PrivateFields.minecraftTimer.get(this.minecraft);
  557 + }
  558 +
  559 + // Hooray, we got the timer reference
  560 + if (this.minecraftTimer != null)
  561 + {
  562 + partialTicks = this.minecraftTimer.renderPartialTicks;
  563 + clock = this.minecraftTimer.elapsedTicks > 0;
  564 + }
  565 +
  566 + // Flag indicates whether we are in game at the moment
  567 + boolean inGame = this.minecraft.renderViewEntity != null && this.minecraft.renderViewEntity.worldObj != null;
  568 +
  569 + if (clock)
  570 + {
  571 + this.loader.onTick(partialTicks, inGame);
  572 + }
  573 +
  574 + // Iterate tickable mods
  575 + for (Tickable tickable : this.tickListeners)
  576 + {
  577 + profiler.startSection(tickable.getClass().getSimpleName());
  578 + tickable.onTick(this.minecraft, partialTicks, inGame, clock);
  579 + profiler.endSection();
  580 + }
  581 + }
  582 +
  583 + /**
  584 + * Callback from the chat hook
  585 + *
  586 + * @param chatPacket
  587 + * @return
  588 + */
  589 + public boolean onChat(Packet3Chat chatPacket)
  590 + {
  591 + if (chatPacket.message == null)
  592 + return true;
  593 +
  594 + ChatMessageComponent chat = ChatMessageComponent.createFromJson(chatPacket.message);
  595 + String message = chat.toStringWithFormatting(true);
  596 +
  597 + // Chat filters get a stab at the chat first, if any filter returns
  598 + // false the chat is discarded
  599 + for (ChatFilter chatFilter : this.chatFilters)
  600 + {
  601 + if (chatFilter.onChat(chatPacket, chat, message))
  602 + {
  603 + chat = ChatMessageComponent.createFromJson(chatPacket.message);
  604 + message = chat.toStringWithFormatting(true);
  605 + }
  606 + else
  607 + {
  608 + return false;
  609 + }
  610 + }
  611 +
  612 + // Chat listeners get the chat if no filter removed it
  613 + for (ChatListener chatListener : this.chatListeners)
  614 + chatListener.onChat(chat, message);
  615 +
  616 + return true;
  617 + }
  618 +
  619 + /**
  620 + * Pre-login callback from the login hook
  621 + *
  622 + * @param netHandler
  623 + * @param hookLogin
  624 + * @return
  625 + */
  626 + public boolean onPreLogin(NetHandler netHandler, Packet1Login loginPacket)
  627 + {
  628 + boolean cancelled = false;
  629 +
  630 + for (PreLoginListener loginListener : this.preLoginListeners)
  631 + {
  632 + cancelled |= !loginListener.onPreLogin(netHandler, loginPacket);
  633 + }
  634 +
  635 + return !cancelled;
  636 + }
  637 +
  638 + /**
  639 + * Callback from the login hook
  640 + *
  641 + * @param netHandler
  642 + * @param loginPacket
  643 + */
  644 + public void onConnectToServer(NetHandler netHandler, Packet1Login loginPacket)
  645 + {
  646 + this.loader.onLogin(netHandler, loginPacket);
  647 +
  648 + for (LoginListener loginListener : this.loginListeners)
  649 + loginListener.onLogin(netHandler, loginPacket);
  650 +
  651 + this.pluginChannels.onConnectToServer(netHandler, loginPacket);
  652 + }
  653 +
  654 + /*
  655 + * (non-Javadoc)
  656 + *
  657 + * @see
  658 + * net.minecraft.src.IPlayerUsage#addServerStatsToSnooper(net.minecraft.
  659 + * src.PlayerUsageSnooper)
  660 + */
  661 + @Override
  662 + public void addServerStatsToSnooper(PlayerUsageSnooper var1)
  663 + {
  664 + this.minecraft.addServerStatsToSnooper(var1);
  665 + }
  666 +
  667 + /*
  668 + * (non-Javadoc)
  669 + *
  670 + * @see
  671 + * net.minecraft.src.IPlayerUsage#addServerTypeToSnooper(net.minecraft.src
  672 + * .PlayerUsageSnooper)
  673 + */
  674 + @Override
  675 + public void addServerTypeToSnooper(PlayerUsageSnooper var1)
  676 + {
  677 + this.sanityCheck();
  678 + this.minecraft.addServerTypeToSnooper(var1);
  679 + }
  680 +
  681 + /*
  682 + * (non-Javadoc)
  683 + *
  684 + * @see net.minecraft.src.IPlayerUsage#isSnooperEnabled()
  685 + */
  686 + @Override
  687 + public boolean isSnooperEnabled()
  688 + {
  689 + return this.minecraft.isSnooperEnabled();
  690 + }
  691 +
  692 + /*
  693 + * (non-Javadoc)
  694 + *
  695 + * @see net.minecraft.src.IPlayerUsage#getLogAgent()
  696 + */
  697 + @Override
  698 + public ILogAgent getLogAgent()
  699 + {
  700 + return this.minecraft.getLogAgent();
  701 + }
  702 +
  703 + /**
  704 + * Check that the profiler hook hasn't been overridden by something else
  705 + */
  706 + private void sanityCheck()
  707 + {
  708 + if (this.tickHooked && this.minecraft.mcProfiler != this.profilerHook)
  709 + {
  710 + PrivateFields.minecraftProfiler.setFinal(this.minecraft, this.profilerHook);
  711 + }
  712 + }
  713 +}
... ...
java/com/mumfrey/liteloader/core/LiteLoader.java
1 1 package com.mumfrey.liteloader.core;
2 2  
3 3 import java.io.*;
4   -import java.lang.reflect.Method;
  4 +import java.lang.reflect.Field;
5 5 import java.net.MalformedURLException;
6 6 import java.net.URISyntaxException;
7 7 import java.net.URL;
8   -import java.net.URLClassLoader;
9 8 import java.net.URLDecoder;
10   -import java.nio.charset.Charset;
11 9 import java.util.ArrayList;
12 10 import java.util.Arrays;
13 11 import java.util.Collections;
... ... @@ -30,24 +28,15 @@ import java.util.zip.ZipInputStream;
30 28  
31 29 import javax.activity.InvalidActivityException;
32 30  
  31 +import net.minecraft.client.ClientBrandRetriever;
  32 +import net.minecraft.launchwrapper.LaunchClassLoader;
33 33 import net.minecraft.src.*;
34 34  
35   -import com.mumfrey.liteloader.ChatFilter;
36   -import com.mumfrey.liteloader.ChatListener;
37   -import com.mumfrey.liteloader.ChatRenderListener;
38   -import com.mumfrey.liteloader.GameLoopListener;
39   -import com.mumfrey.liteloader.InitCompleteListener;
40   -import com.mumfrey.liteloader.LiteMod;
41   -import com.mumfrey.liteloader.LoginListener;
42   -import com.mumfrey.liteloader.Permissible;
43   -import com.mumfrey.liteloader.PluginChannelListener;
44   -import com.mumfrey.liteloader.PostRenderListener;
45   -import com.mumfrey.liteloader.PreLoginListener;
46   -import com.mumfrey.liteloader.RenderListener;
  35 +import com.mumfrey.liteloader.*;
47 36 import com.mumfrey.liteloader.Tickable;
48 37 import com.mumfrey.liteloader.gui.GuiControlsPaginated;
  38 +import com.mumfrey.liteloader.log.LiteLoaderLogFormatter;
49 39 import com.mumfrey.liteloader.permissions.PermissionsManagerClient;
50   -import com.mumfrey.liteloader.util.ModUtilities;
51 40 import com.mumfrey.liteloader.util.PrivateFields;
52 41  
53 42 /**
... ... @@ -55,14 +44,14 @@ import com.mumfrey.liteloader.util.PrivateFields;
55 44 * lightweight mods
56 45 *
57 46 * @author Adam Mummery-Smith
58   - * @version 1.6.2_04
  47 + * @version 1.6.3
59 48 */
60   -public final class LiteLoader implements FilenameFilter, IPlayerUsage
  49 +public final class LiteLoader implements FilenameFilter
61 50 {
62 51 /**
63 52 * Liteloader version
64 53 */
65   - private static final LiteLoaderVersion VERSION = LiteLoaderVersion.MC_1_6_2_R3;
  54 + private static final LiteLoaderVersion VERSION = LiteLoaderVersion.MC_1_6_3_R0;
66 55  
67 56 /**
68 57 * Maximum recursion depth for mod discovery
... ... @@ -77,7 +66,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
77 66 /**
78 67 * Logger for LiteLoader events
79 68 */
80   - public static Logger logger = Logger.getLogger("liteloader");
  69 + private static Logger logger = Logger.getLogger("liteloader");
81 70  
82 71 /**
83 72 * Use stdout rather than stderr
... ... @@ -100,9 +89,14 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
100 89 private static String profile = "";
101 90  
102 91 /**
  92 + * Tweak system class loader
  93 + */
  94 + private static LaunchClassLoader classLoader;
  95 +
  96 + /**
103 97 * List of mods passed into the command line
104 98 */
105   - private static List<String> modNameFilter = null;
  99 + private EnabledModsList enabledModsList = null;
106 100  
107 101 /**
108 102 * Mods folder which contains mods and legacy config files
... ... @@ -126,6 +120,16 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
126 120 private File versionConfigFolder;
127 121  
128 122 /**
  123 + * JSON file containing the list of enabled/disabled mods by profile
  124 + */
  125 + private File enabledModsFile;
  126 +
  127 + /**
  128 + * File to write log entries to
  129 + */
  130 + private File logFile;
  131 +
  132 + /**
129 133 * Reference to the Minecraft game instance
130 134 */
131 135 private Minecraft minecraft = Minecraft.getMinecraft();
... ... @@ -158,11 +162,6 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
158 162 private boolean paginateControls = true;
159 163  
160 164 /**
161   - * Reference to the minecraft timer
162   - */
163   - private Timer minecraftTimer;
164   -
165   - /**
166 165 * Classes to load, mapped by class name
167 166 */
168 167 private Map<String, Class<? extends LiteMod>> modsToLoad = new HashMap<String, Class<? extends LiteMod>>();
... ... @@ -193,103 +192,29 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
193 192 private LinkedList<LiteMod> loadedMods = new LinkedList<LiteMod>();
194 193  
195 194 /**
196   - * List of mods which implement Tickable interface and will receive tick
197   - * events
198   - */
199   - private LinkedList<Tickable> tickListeners = new LinkedList<Tickable>();
200   -
201   - /**
202   - * List of mods which implement the GameLoopListener interface and will
203   - * receive loop events
204   - */
205   - private LinkedList<GameLoopListener> loopListeners = new LinkedList<GameLoopListener>();
206   -
207   - /**
208   - *
209   - */
210   - private LinkedList<InitCompleteListener> initListeners = new LinkedList<InitCompleteListener>();
211   -
212   - /**
213   - * List of mods which implement RenderListener interface and will receive
214   - * render events events
215   - */
216   - private LinkedList<RenderListener> renderListeners = new LinkedList<RenderListener>();
217   -
218   - /**
219   - * List of mods which implement the PostRenderListener interface and want to
220   - * render entities
221   - */
222   - private LinkedList<PostRenderListener> postRenderListeners = new LinkedList<PostRenderListener>();
223   -
224   - /**
225   - * List of mods which implement ChatRenderListener and want to know when
226   - * chat is rendered
227   - */
228   - private LinkedList<ChatRenderListener> chatRenderListeners = new LinkedList<ChatRenderListener>();
229   -
230   - /**
231   - * List of mods which implement ChatListener interface and will receive chat
232   - * events
233   - */
234   - private LinkedList<ChatListener> chatListeners = new LinkedList<ChatListener>();
235   -
236   - /**
237   - * List of mods which implement ChatFilter interface and will receive chat
238   - * filter events
239   - */
240   - private LinkedList<ChatFilter> chatFilters = new LinkedList<ChatFilter>();
241   -
242   - /**
243   - * List of mods which implement LoginListener interface and will receive
244   - * client login events
245   - */
246   - private LinkedList<LoginListener> loginListeners = new LinkedList<LoginListener>();
247   -
248   - /**
249   - * List of mods which implement LoginListener interface and will receive
250   - * client login events
  195 + * Mods which are loaded but disabled
251 196 */
252   - private LinkedList<PreLoginListener> preLoginListeners = new LinkedList<PreLoginListener>();
  197 + private LinkedList<ModFile> disabledMods = new LinkedList<ModFile>();
253 198  
254 199 /**
255   - * List of mods which implement PluginChannelListener interface
  200 + * Event manager
256 201 */
257   - private LinkedList<PluginChannelListener> pluginChannelListeners = new LinkedList<PluginChannelListener>();
  202 + private Events events;
258 203  
259 204 /**
260   - * Mapping of plugin channel names to listeners
  205 + * Plugin channel manager
261 206 */
262   - private HashMap<String, LinkedList<PluginChannelListener>> pluginChannels = new HashMap<String, LinkedList<PluginChannelListener>>();
  207 + private PluginChannels pluginChannels;
263 208  
264 209 /**
265   - * Reference to the addUrl method on URLClassLoader
  210 + * Permission Manager
266 211 */
267   - private Method mAddUrl;
  212 + private PermissionsManagerClient permissionsManager = PermissionsManagerClient.getInstance();
268 213  
269 214 /**
270 215 * Flag which keeps track of whether late initialisation has been done
271 216 */
272   - private boolean loaderStartupDone, loaderStartupComplete, lateInitDone;
273   -
274   - /**
275   - * Flags which keep track of whether hooks have been applied
276   - */
277   - private boolean chatHooked, loginHooked, pluginChannelHooked, tickHooked;
278   -
279   - /**
280   - * Profiler hook objects
281   - */
282   - private HookProfiler profilerHook = new HookProfiler(this, logger);
283   -
284   - /**
285   - * ScaledResolution used by the pre-chat and post-chat render callbacks
286   - */
287   - private ScaledResolution currentResolution;
288   -
289   - /**
290   - * Permission Manager
291   - */
292   - private static PermissionsManagerClient permissionsManager = PermissionsManagerClient.getInstance();
  217 + private boolean loaderStartupDone, loaderStartupComplete;
293 218  
294 219 /**
295 220 * True while initialising mods if we need to do a resource manager reload once the process is completed
... ... @@ -319,7 +244,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
319 244 /**
320 245 * List of all registered mod keys
321 246 */
322   - private List<KeyBinding> modKeys = new ArrayList<KeyBinding>();
  247 + private List<KeyBinding> modKeyBindings = new ArrayList<KeyBinding>();
323 248  
324 249 /**
325 250 * Map of mod key bindings to their key codes, stored so that we don't need to cast from
... ... @@ -327,99 +252,35 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
327 252 */
328 253 private Map<KeyBinding, Integer> storedModKeyBindings = new HashMap<KeyBinding, Integer>();
329 254  
330   - public static final void init(File gameDirectory, File assetsDirectory, String profile, List<String> modNameFilter)
  255 + @SuppressWarnings("unused")
  256 + private static final void init(File gameDirectory, File assetsDirectory, String profile, List<String> modNameFilter, LaunchClassLoader classLoader)
331 257 {
332   - if (instance == null)
  258 + if (LiteLoader.instance == null)
333 259 {
334 260 LiteLoader.gameDirectory = gameDirectory;
335 261 LiteLoader.assetsDirectory = assetsDirectory;
336 262 LiteLoader.profile = profile;
  263 + LiteLoader.classLoader = classLoader;
337 264  
338   - try
339   - {
340   - if (modNameFilter != null)
341   - {
342   - LiteLoader.modNameFilter = new ArrayList<String>();
343   - for (String filterEntry : modNameFilter)
344   - {
345   - LiteLoader.modNameFilter.add(filterEntry.toLowerCase().trim());
346   - }
347   - }
348   - }
349   - catch (Exception ex)
350   - {
351   - LiteLoader.modNameFilter = null;
352   - }
353   -
354   - instance = new LiteLoader();
355   - instance.initLoader();
  265 + LiteLoader.instance = new LiteLoader(profile, modNameFilter);
  266 + LiteLoader.instance.initLoader();
356 267 }
357   -
358   - }
359   -
360   - /**
361   - * Get the singleton instance of LiteLoader, initialises the loader if
362   - * necessary
363   - *
364   - * @param locationProvider
365   - * @return LiteLoader instance
366   - */
367   - public static final LiteLoader getInstance()
368   - {
369   - return instance;
370   - }
371   -
372   - /**
373   - * Get the LiteLoader logger object
374   - *
375   - * @return
376   - */
377   - public static final Logger getLogger()
378   - {
379   - return logger;
380   - }
381   -
382   - /**
383   - * Get the output stream which we are using for console output
384   - *
385   - * @return
386   - */
387   - public static final PrintStream getConsoleStream()
388   - {
389   - return useStdOut ? System.out : System.err;
390   - }
391   -
392   - /**
393   - * Get LiteLoader version
394   - *
395   - * @return
396   - */
397   - public static final String getVersion()
398   - {
399   - return VERSION.getLoaderVersion();
400   - }
401   -
402   - /**
403   - * Get the loader revision
404   - *
405   - * @return
406   - */
407   - public static final int getRevision()
408   - {
409   - return VERSION.getLoaderRevision();
410   - }
411   -
412   - public static final PermissionsManagerClient getPermissionsManager()
413   - {
414   - return permissionsManager;
415 268 }
416   -
  269 +
417 270 /**
418 271 * LiteLoader constructor
  272 + * @param profile
  273 + * @param modNameFilter
419 274 */
420   - private LiteLoader()
  275 + private LiteLoader(String profile, List<String> modNameFilter)
421 276 {
422 277 this.initPaths();
  278 +
  279 + this.enabledModsList = EnabledModsList.createFrom(this.enabledModsFile);
  280 + this.enabledModsList.processModsList(profile, modNameFilter);
  281 +
  282 + this.pluginChannels = new PluginChannels(this);
  283 + this.events = new Events(this, this.minecraft, this.pluginChannels);
423 284 }
424 285  
425 286 /**
... ... @@ -439,6 +300,9 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
439 300 if (!this.versionConfigFolder.exists()) this.versionConfigFolder.mkdirs();
440 301  
441 302 this.propertiesFile = new File(this.configBaseFolder, "liteloader.properties");
  303 + this.enabledModsFile = new File(this.configBaseFolder, "liteloader.profiles.json");
  304 + this.logFile = new File(this.configBaseFolder, "liteloader.log");
  305 + this.keyMapSettingsFile = new File(this.configBaseFolder, "liteloader.keys.properties");
442 306 }
443 307  
444 308 /**
... ... @@ -466,15 +330,15 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
466 330 // Set up loader, initialises any reflection methods needed
467 331 if (this.prepareLoader())
468 332 {
469   - logger.info(String.format("LiteLoader %s starting up...", VERSION.getLoaderVersion()));
  333 + LiteLoader.getLogger().info(String.format("LiteLoader %s starting up...", VERSION.getLoaderVersion()));
470 334  
471 335 // Print the branding version if any was provided
472 336 if (this.branding != null)
473 337 {
474   - logger.info(String.format("Active Pack: %s", this.branding));
  338 + LiteLoader.getLogger().info(String.format("Active Pack: %s", this.branding));
475 339 }
476 340  
477   - logger.info(String.format("Java reports OS=\"%s\"", System.getProperty("os.name").toLowerCase()));
  341 + LiteLoader.getLogger().info(String.format("Java reports OS=\"%s\"", System.getProperty("os.name").toLowerCase()));
478 342  
479 343 boolean searchMods = this.localProperties.getProperty("search.mods", "true").equalsIgnoreCase("true");
480 344 boolean searchProtectionDomain = this.localProperties.getProperty("search.jar", "true").equalsIgnoreCase("true");
... ... @@ -482,7 +346,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
482 346  
483 347 if (!searchMods && !searchProtectionDomain && !searchClassPath)
484 348 {
485   - logger.warning("Invalid configuration, no search locations defined. Enabling all search locations.");
  349 + LiteLoader.getLogger().warning("Invalid configuration, no search locations defined. Enabling all search locations.");
486 350  
487 351 this.localProperties.setProperty("search.mods", "true");
488 352 this.localProperties.setProperty("search.jar", "true");
... ... @@ -496,18 +360,23 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
496 360 // Examines the class path and mods folder and locates loadable mods
497 361 this.prepareMods(searchMods, searchProtectionDomain, searchClassPath);
498 362  
  363 + // Spawn mod instances
  364 + this.loadMods();
  365 +
499 366 // Initialises enumerated mods
500 367 this.initMods();
501 368  
502 369 // Initialises the required hooks for loaded mods
503   - this.initHooks();
504   -
  370 + this.events.initHooks();
505 371 this.loaderStartupComplete = true;
506 372  
507 373 this.writeProperties();
  374 + this.enabledModsList.saveTo(this.enabledModsFile);
  375 +
  376 + this.setBranding("LiteLoader");
508 377 }
509 378 }
510   -
  379 +
511 380 /**
512 381 * Set up reflection methods required by the loader
513 382 */
... ... @@ -515,10 +384,6 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
515 384 {
516 385 try
517 386 {
518   - // addURL method is used by the class loader to
519   - this.mAddUrl = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
520   - this.mAddUrl.setAccessible(true);
521   -
522 387 // Prepare the properties
523 388 this.prepareProperties();
524 389  
... ... @@ -544,7 +409,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
544 409 }
545 410 catch (Throwable th)
546 411 {
547   - logger.log(Level.SEVERE, "Error initialising LiteLoader", th);
  412 + LiteLoader.getLogger().log(Level.SEVERE, "Error initialising LiteLoader", th);
548 413 return false;
549 414 }
550 415  
... ... @@ -559,16 +424,16 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
559 424 {
560 425 Formatter logFormatter = new LiteLoaderLogFormatter();
561 426  
562   - logger.setUseParentHandlers(false);
563   - this.useStdOut = System.getProperty("liteloader.log", "stderr").equalsIgnoreCase("stdout") || this.localProperties.getProperty("log", "stderr").equalsIgnoreCase("stdout");
  427 + LiteLoader.getLogger().setUseParentHandlers(false);
  428 + LiteLoader.useStdOut = System.getProperty("liteloader.log", "stderr").equalsIgnoreCase("stdout") || this.localProperties.getProperty("log", "stderr").equalsIgnoreCase("stdout");
564 429  
565 430 StreamHandler consoleHandler = useStdOut ? new com.mumfrey.liteloader.util.log.ConsoleHandler() : new java.util.logging.ConsoleHandler();
566 431 consoleHandler.setFormatter(logFormatter);
567   - logger.addHandler(consoleHandler);
  432 + LiteLoader.getLogger().addHandler(consoleHandler);
568 433  
569   - FileHandler logFileHandler = new FileHandler(new File(this.configBaseFolder, "LiteLoader.txt").getAbsolutePath());
  434 + FileHandler logFileHandler = new FileHandler(this.logFile.getAbsolutePath());
570 435 logFileHandler.setFormatter(logFormatter);
571   - logger.addHandler(logFileHandler);
  436 + LiteLoader.getLogger().addHandler(logFileHandler);
572 437 }
573 438  
574 439 /**
... ... @@ -607,8 +472,6 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
607 472 this.localProperties = new Properties(this.internalProperties);
608 473 }
609 474  
610   - this.keyMapSettingsFile = new File(this.configBaseFolder, "litemodkeys.properties");
611   -
612 475 if (this.keyMapSettingsFile.exists())
613 476 {
614 477 try
... ... @@ -648,7 +511,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
648 511 }
649 512 catch (Throwable th)
650 513 {
651   - logger.log(Level.WARNING, "Error writing liteloader properties", th);
  514 + LiteLoader.getLogger().log(Level.WARNING, "Error writing liteloader properties", th);
652 515 }
653 516 }
654 517  
... ... @@ -661,7 +524,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
661 524 */
662 525 public boolean registerModResourcePack(ResourcePack resourcePack)
663 526 {
664   - if (!this.registeredResourcePacks.containsKey(resourcePack.func_130077_b())) // TODO adamsrc -> getName()
  527 + if (!this.registeredResourcePacks.containsKey(resourcePack.getPackName()))
665 528 {
666 529 this.pendingResourceReload = true;
667 530  
... ... @@ -669,7 +532,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
669 532 if (!defaultResourcePacks.contains(resourcePack))
670 533 {
671 534 defaultResourcePacks.add(resourcePack);
672   - this.registeredResourcePacks.put(resourcePack.func_130077_b(), resourcePack); // TODO adamsrc -> getName()
  535 + this.registeredResourcePacks.put(resourcePack.getPackName(), resourcePack);
673 536 return true;
674 537 }
675 538 }
... ... @@ -688,7 +551,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
688 551 this.pendingResourceReload = true;
689 552  
690 553 List<ResourcePack> defaultResourcePacks = PrivateFields.defaultResourcePacks.get(this.minecraft);
691   - this.registeredResourcePacks.remove(resourcePack.func_130077_b()); // TODO adamsrc -> getName()
  554 + this.registeredResourcePacks.remove(resourcePack.getPackName());
692 555 defaultResourcePacks.remove(resourcePack);
693 556 return true;
694 557 }
... ... @@ -697,27 +560,107 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
697 560 }
698 561  
699 562 /**
  563 + * Get the singleton instance of LiteLoader, initialises the loader if
  564 + * necessary
  565 + *
  566 + * @param locationProvider
  567 + * @return LiteLoader instance
  568 + */
  569 + public static final LiteLoader getInstance()
  570 + {
  571 + return LiteLoader.instance;
  572 + }
  573 +
  574 + /**
  575 + * Get the LiteLoader logger object
  576 + *
  577 + * @return
  578 + */
  579 + public static final Logger getLogger()
  580 + {
  581 + return LiteLoader.logger;
  582 + }
  583 +
  584 + /**
  585 + * Get the output stream which we are using for console output
  586 + *
  587 + * @return
  588 + */
  589 + public static final PrintStream getConsoleStream()
  590 + {
  591 + return LiteLoader.useStdOut ? System.out : System.err;
  592 + }
  593 +
  594 + /**
  595 + * Get LiteLoader version
  596 + *
  597 + * @return
  598 + */
  599 + public static final String getVersion()
  600 + {
  601 + return LiteLoader.VERSION.getLoaderVersion();
  602 + }
  603 +
  604 + /**
  605 + * Get the loader revision
  606 + *
  607 + * @return
  608 + */
  609 + public static final int getRevision()
  610 + {
  611 + return LiteLoader.VERSION.getLoaderRevision();
  612 + }
  613 +
  614 + /**
  615 + * @return
  616 + */
  617 + public static PermissionsManagerClient getPermissionsManager()
  618 + {
  619 + return LiteLoader.getInstance().permissionsManager;
  620 + }
  621 +
  622 + /**
  623 + * Get the event manager
  624 + *
  625 + * @return
  626 + */
  627 + public static Events getEvents()
  628 + {
  629 + return LiteLoader.getInstance().events;
  630 + }
  631 +
  632 + /**
  633 + * Get the plugin channel manager
  634 + *
  635 + * @return
  636 + */
  637 + public static PluginChannels getPluginChannels()
  638 + {
  639 + return LiteLoader.getInstance().pluginChannels;
  640 + }
  641 +
  642 + /**
700 643 * Get the "mods" folder
701 644 */
702   - public File getModsFolder()
  645 + public static File getModsFolder()
703 646 {
704   - return this.modsFolder;
  647 + return LiteLoader.getInstance().modsFolder;
705 648 }
706 649  
707 650 /**
708 651 * Get the common (version-independent) config folder
709 652 */
710   - public File getCommonConfigFolder()
  653 + public static File getCommonConfigFolder()
711 654 {
712   - return this.commonConfigFolder;
  655 + return LiteLoader.getInstance().commonConfigFolder;
713 656 }
714 657  
715 658 /**
716 659 * Get the config folder for this version
717 660 */
718   - public File getConfigFolder()
  661 + public static File getConfigFolder()
719 662 {
720   - return this.versionConfigFolder;
  663 + return LiteLoader.getInstance().versionConfigFolder;
721 664 }
722 665  
723 666 /**
... ... @@ -761,7 +704,15 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
761 704 {
762 705 return Collections.unmodifiableList(this.loadedMods);
763 706 }
764   -
  707 +
  708 + /**
  709 + * Get a list containing all mod files which were NOT loaded
  710 + */
  711 + public List<ModFile> getDisabledMods()
  712 + {
  713 + return Collections.unmodifiableList(this.disabledMods);
  714 + }
  715 +
765 716 /**
766 717 * Used to get the name of the modpack being used
767 718 *
... ... @@ -868,7 +819,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
868 819 }
869 820  
870 821 /**
871   - * Get metadata for the specified mod, attempts to retrieve the mod by name first
  822 + * Get a metadata value for the specified mod
872 823 *
873 824 * @param mod
874 825 * @param metaDataKey
... ... @@ -893,24 +844,45 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
893 844 public String getModMetaData(LiteMod mod, String metaDataKey, String defaultValue)
894 845 {
895 846 if (mod == null || metaDataKey == null) return defaultValue;
896   -
897   - String modClassName = mod.getClass().getSimpleName();
898   - if (!this.modFiles.containsKey(modClassName)) return defaultValue;
899   -
900   - ModFile modFile = this.modFiles.get(modClassName);
901   - return modFile.getMetaValue(metaDataKey, defaultValue);
  847 + return this.getModMetaData(mod.getClass(), metaDataKey, defaultValue);
  848 + }
  849 +
  850 + /**
  851 + * Get a metadata value for the specified mod
  852 + *
  853 + * @param modClassName
  854 + * @param metaDataKey
  855 + * @param defaultValue
  856 + * @return
  857 + */
  858 + public String getModMetaData(Class<? extends LiteMod> modClass, String metaDataKey, String defaultValue)
  859 + {
  860 + ModFile modFile = this.getModFile(modClass);
  861 + return modFile != null ? modFile.getMetaValue(metaDataKey, defaultValue) : defaultValue;
902 862 }
903 863  
904 864 /**
905 865 * @param mod
906 866 * @return
907 867 */
908   - private ModFile getModFile(LiteMod mod)
  868 + private ModFile getModFile(Class<? extends LiteMod> modClass)
909 869 {
910   - String modClassName = mod.getClass().getSimpleName();
911   - return this.modFiles.containsKey(modClassName) ? this.modFiles.get(modClassName) : null;
  870 + return this.modFiles.get(modClass.getSimpleName());
912 871 }
913   -
  872 +
  873 + /**
  874 + * Get the mod "name" metadata key, this is used for versioning, exclusivity, and enablement checks
  875 + *
  876 + * @param modClass
  877 + * @return
  878 + */
  879 + public String getModMetaName(Class<? extends LiteMod> modClass)
  880 + {
  881 + String modClassName = modClass.getSimpleName();
  882 + if (!this.modFiles.containsKey(modClassName)) return null;
  883 + return this.modFiles.get(modClassName).getModName().toLowerCase();
  884 + }
  885 +
914 886 /**
915 887 * Enumerate the java class path and "mods" folder to find mod classes, then
916 888 * load the classes
... ... @@ -926,37 +898,35 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
926 898 File modFolder = this.getModsFolder();
927 899 if (modFolder.exists() && modFolder.isDirectory())
928 900 {
929   - logger.info("Mods folder found, searching " + modFolder.getPath());
  901 + LiteLoader.getLogger().info("Mods folder found, searching " + modFolder.getPath());
930 902 this.findModFiles(modFolder, modFiles);
931   - logger.info("Found " + modFiles.size() + " mod file(s)");
  903 + LiteLoader.getLogger().info("Found " + modFiles.size() + " mod file(s)");
932 904 }
933 905 }
934 906  
935 907 try
936 908 {
937   - logger.info("Enumerating class path...");
  909 + LiteLoader.getLogger().info("Enumerating class path...");
938 910  
939 911 String classPath = System.getProperty("java.class.path");
940 912 String classPathSeparator = System.getProperty("path.separator");
941 913 String[] classPathEntries = classPath.split(classPathSeparator);
942 914  
943   - logger.info(String.format("Class path separator=\"%s\"", classPathSeparator));
944   - logger.info(String.format("Class path entries=(\n classpathEntry=%s\n)", classPath.replace(classPathSeparator, "\n classpathEntry=")));
  915 + LiteLoader.getLogger().info(String.format("Class path separator=\"%s\"", classPathSeparator));
  916 + LiteLoader.getLogger().info(String.format("Class path entries=(\n classpathEntry=%s\n)", classPath.replace(classPathSeparator, "\n classpathEntry=")));
945 917  
946 918 if (searchProtectionDomain || searchClassPath)
947   - logger.info("Discovering mods on class path...");
  919 + getLogger().info("Discovering mods on class path...");
948 920  
949   - this.findModClasses(classPathEntries, modFiles, searchProtectionDomain, searchClassPath);
  921 + this.findModClasses(modFiles, searchProtectionDomain, searchClassPath, classPathEntries);
950 922  
951   - logger.info("Mod class discovery completed");
  923 + LiteLoader.getLogger().info("Mod class discovery completed");
952 924 }
953 925 catch (Throwable th)
954 926 {
955   - logger.log(Level.WARNING, "Mod class discovery failed", th);
  927 + LiteLoader.getLogger().log(Level.WARNING, "Mod class discovery failed", th);
956 928 return;
957 929 }
958   -
959   - this.loadMods();
960 930 }
961 931  
962 932 /**
... ... @@ -978,11 +948,12 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
978 948 // Check for a version file
979 949 ZipFile modZip = new ZipFile(modFile);
980 950 ZipEntry version = modZip.getEntry("litemod.json");
981   -
982   - if (version == null)
983   - {
984   - version = modZip.getEntry("version.txt");
985   - }
  951 +
  952 + // Not supporting this past 1.6.2
  953 +// if (version == null)
  954 +// {
  955 +// version = modZip.getEntry("version.txt");
  956 +// }
986 957  
987 958 if (version != null)
988 959 {
... ... @@ -1003,7 +974,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1003 974 }
1004 975 catch (Exception ex)
1005 976 {
1006   - logger.warning("Error reading version data from " + modFile.getName());
  977 + LiteLoader.getLogger().warning("Error reading version data from " + modFile.getName());
1007 978 }
1008 979 finally
1009 980 {
... ... @@ -1020,10 +991,10 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1020 991 // to successfully add it to the class path
1021 992 if (LiteLoader.VERSION.isVersionSupported(modFileInfo.getVersion()))
1022 993 {
1023   - if (!modFileInfo.isJson())
1024   - {
1025   - logger.warning("Missing or invalid litemod.json reading mod file: " + modFile.getAbsolutePath());
1026   - }
  994 +// if (!modFileInfo.isJson())
  995 +// {
  996 +// logger.warning("Missing or invalid litemod.json reading mod file: " + modFile.getAbsolutePath());
  997 +// }
1027 998  
1028 999 if (!versionOrderingSets.containsKey(modFileInfo.getName()))
1029 1000 {
... ... @@ -1034,18 +1005,26 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1034 1005 }
1035 1006 else
1036 1007 {
1037   - logger.info("Not adding invalid or outdated mod file: " + modFile.getAbsolutePath());
  1008 + LiteLoader.getLogger().info("Not adding invalid or outdated mod file: " + modFile.getAbsolutePath());
1038 1009 }
1039 1010 }
1040 1011 }
1041 1012 }
  1013 + else
  1014 + {
  1015 + ZipEntry legacyVersion = modZip.getEntry("version.txt");
  1016 + if (legacyVersion != null)
  1017 + {
  1018 + LiteLoader.getLogger().warning("version.txt is no longer supported, ignoring outdated mod file: " + modFile.getAbsolutePath());
  1019 + }
  1020 + }
1042 1021  
1043 1022 modZip.close();
1044 1023 }
1045 1024 catch (Exception ex)
1046 1025 {
1047 1026 ex.printStackTrace(System.err);
1048   - logger.warning("Error enumerating '" + modFile.getAbsolutePath() + "': Invalid zip file or error reading file");
  1027 + LiteLoader.getLogger().warning("Error enumerating '" + modFile.getAbsolutePath() + "': Invalid zip file or error reading file");
1049 1028 }
1050 1029 }
1051 1030  
... ... @@ -1056,14 +1035,12 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1056 1035  
1057 1036 try
1058 1037 {
1059   - if (this.addURLToClassPath(newestVersion.toURI().toURL()))
1060   - {
1061   - modFiles.add(newestVersion);
1062   - }
  1038 + LiteLoader.classLoader.addURL(newestVersion.toURI().toURL());
  1039 + modFiles.add(newestVersion);
1063 1040 }
1064 1041 catch (Exception ex)
1065 1042 {
1066   - logger.warning("Error injecting '" + newestVersion.getAbsolutePath() + "' into classPath. The mod will not be loaded");
  1043 + LiteLoader.getLogger().warning("Error injecting '" + newestVersion.getAbsolutePath() + "' into classPath. The mod will not be loaded");
1067 1044 }
1068 1045 }
1069 1046 }
... ... @@ -1081,10 +1058,9 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1081 1058  
1082 1059 /**
1083 1060 * Find mod classes in the class path and enumerated mod files list
1084   - *
1085 1061 * @param classPathEntries Java class path split into string entries
1086 1062 */
1087   - private void findModClasses(String[] classPathEntries, List<ModFile> modFiles, boolean searchProtectionDomain, boolean searchClassPath)
  1063 + private void findModClasses(List<ModFile> modFiles, boolean searchProtectionDomain, boolean searchClassPath, String[] classPathEntries)
1088 1064 {
1089 1065 if (searchProtectionDomain)
1090 1066 {
... ... @@ -1094,7 +1070,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1094 1070 }
1095 1071 catch (Throwable th)
1096 1072 {
1097   - logger.warning("Error loading from local class path: " + th.getMessage());
  1073 + LiteLoader.getLogger().warning("Error loading from local class path: " + th.getMessage());
1098 1074 }
1099 1075 }
1100 1076  
... ... @@ -1117,7 +1093,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1117 1093 @SuppressWarnings("unchecked")
1118 1094 private void searchProtectionDomain() throws MalformedURLException, URISyntaxException, UnsupportedEncodingException
1119 1095 {
1120   - logger.info("Searching protection domain code source...");
  1096 + LiteLoader.getLogger().info("Searching protection domain code source...");
1121 1097  
1122 1098 File packagePath = null;
1123 1099  
... ... @@ -1152,14 +1128,14 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1152 1128 {
1153 1129 if (this.modsToLoad.containsKey(mod.getSimpleName()))
1154 1130 {
1155   - logger.warning("Mod name collision for mod with class '" + mod.getSimpleName() + "', maybe you have more than one copy?");
  1131 + LiteLoader.getLogger().warning("Mod name collision for mod with class '" + mod.getSimpleName() + "', maybe you have more than one copy?");
1156 1132 }
1157 1133  
1158 1134 this.modsToLoad.put(mod.getSimpleName(), (Class<? extends LiteMod>)mod);
1159 1135 }
1160 1136  
1161 1137 if (modClasses.size() > 0)
1162   - logger.info(String.format("Found %s potential matches", modClasses.size()));
  1138 + LiteLoader.getLogger().info(String.format("Found %s potential matches", modClasses.size()));
1163 1139 }
1164 1140 }
1165 1141  
... ... @@ -1172,7 +1148,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1172 1148 {
1173 1149 for (String classPathPart : classPathEntries)
1174 1150 {
1175   - logger.info(String.format("Searching %s...", classPathPart));
  1151 + LiteLoader.getLogger().info(String.format("Searching %s...", classPathPart));
1176 1152  
1177 1153 File packagePath = new File(classPathPart);
1178 1154 LinkedList<Class<?>> modClasses = getSubclassesFor(packagePath, Minecraft.class.getClassLoader(), LiteMod.class, "LiteMod");
... ... @@ -1181,7 +1157,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1181 1157 {
1182 1158 if (this.modsToLoad.containsKey(mod.getSimpleName()))
1183 1159 {
1184   - logger.warning("Mod name collision for mod with class '" + mod.getSimpleName() + "', maybe you have more than one copy?");
  1160 + LiteLoader.getLogger().warning("Mod name collision for mod with class '" + mod.getSimpleName() + "', maybe you have more than one copy?");
1185 1161 }
1186 1162  
1187 1163 this.modsToLoad.put(mod.getSimpleName(), (Class<? extends LiteMod>)mod);
... ... @@ -1189,7 +1165,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1189 1165 }
1190 1166  
1191 1167 if (modClasses.size() > 0)
1192   - logger.info(String.format("Found %s potential matches", modClasses.size()));
  1168 + LiteLoader.getLogger().info(String.format("Found %s potential matches", modClasses.size()));
1193 1169 }
1194 1170 }
1195 1171  
... ... @@ -1202,15 +1178,15 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1202 1178 {
1203 1179 for (ModFile modFile : modFiles)
1204 1180 {
1205   - logger.info(String.format("Searching %s...", modFile.getAbsolutePath()));
  1181 + LiteLoader.getLogger().info(String.format("Searching %s...", modFile.getAbsolutePath()));
1206 1182  
1207   - LinkedList<Class<?>> modClasses = getSubclassesFor(modFile, Minecraft.class.getClassLoader(), LiteMod.class, "LiteMod");
  1183 + LinkedList<Class<?>> modClasses = LiteLoader.getSubclassesFor(modFile, Minecraft.class.getClassLoader(), LiteMod.class, "LiteMod");
1208 1184  
1209 1185 for (Class<?> mod : modClasses)
1210 1186 {
1211 1187 if (this.modsToLoad.containsKey(mod.getSimpleName()))
1212 1188 {
1213   - logger.warning("Mod name collision for mod with class '" + mod.getSimpleName() + "', maybe you have more than one copy?");
  1189 + LiteLoader.getLogger().warning("Mod name collision for mod with class '" + mod.getSimpleName() + "', maybe you have more than one copy?");
1214 1190 }
1215 1191  
1216 1192 this.modsToLoad.put(mod.getSimpleName(), (Class<? extends LiteMod>)mod);
... ... @@ -1218,7 +1194,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1218 1194 }
1219 1195  
1220 1196 if (modClasses.size() > 0)
1221   - logger.info(String.format("Found %s potential matches", modClasses.size()));
  1197 + LiteLoader.getLogger().info(String.format("Found %s potential matches", modClasses.size()));
1222 1198 }
1223 1199 }
1224 1200  
... ... @@ -1231,85 +1207,72 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1231 1207 {
1232 1208 if (this.modsToLoad == null)
1233 1209 {
1234   - logger.info("Mod class discovery failed. Not loading any mods!");
  1210 + LiteLoader.getLogger().info("Mod class discovery failed. Not loading any mods!");
1235 1211 return;
1236 1212 }
1237 1213  
1238   - logger.info("Discovered " + this.modsToLoad.size() + " total mod(s)");
  1214 + LiteLoader.getLogger().info("Discovered " + this.modsToLoad.size() + " total mod(s)");
1239 1215  
1240 1216 this.pendingResourceReload = false;
1241   - this.soundManagerReloadInhibitor = new SoundManagerReloadInhibitor((SimpleReloadableResourceManager)minecraft.func_110442_L(), minecraft.sndManager); // TODO adamsrc -> getResourceManager
1242   - if (this.inhibitSoundManagerReload) this.soundManagerReloadInhibitor.inhibit();
  1217 + this.soundManagerReloadInhibitor = new SoundManagerReloadInhibitor((SimpleReloadableResourceManager)this.minecraft.getResourceManager(), this.minecraft.sndManager);
  1218 +// if (this.inhibitSoundManagerReload) this.soundManagerReloadInhibitor.inhibit();
1243 1219  
1244 1220 for (Class<? extends LiteMod> mod : this.modsToLoad.values())
1245 1221 {
1246 1222 try
1247 1223 {
1248   - logger.info("Loading mod from " + mod.getName());
1249   -
1250   - LiteMod newMod = mod.newInstance();
1251   -
1252   - if (this.shouldAddMod(newMod))
  1224 + String metaName = this.getModMetaName(mod);
  1225 + if (metaName == null || this.enabledModsList.isEnabled(this.profile, metaName))
1253 1226 {
  1227 + LiteLoader.getLogger().info(String.format("Loading mod from %s", mod.getName()));
  1228 +
  1229 + LiteMod newMod = mod.newInstance();
  1230 +
1254 1231 this.mods.add(newMod);
1255   - logger.info("Successfully added mod " + newMod.getName() + " version " + newMod.getVersion());
  1232 + LiteLoader.getLogger().info(String.format("Successfully added mod %s version %s", newMod.getName(), newMod.getVersion()));
1256 1233  
1257 1234 // Get the mod file and register it as a resource pack if it exists
1258   - ModFile modFile = this.getModFile(newMod);
1259   - if (modFile != null && modFile.registerAsResourcePack(newMod.getName()))
  1235 + ModFile modFile = this.getModFile(mod);
  1236 + if (modFile != null)
1260 1237 {
1261   - logger.info("Adding " + modFile.getAbsolutePath() + " to resources list");
  1238 + this.disabledMods.remove(modFile);
  1239 +
  1240 + if (modFile.registerAsResourcePack(newMod.getName()))
  1241 + {
  1242 + LiteLoader.getLogger().info(String.format("Successfully added \"%s\" to active resource pack set", modFile.getAbsolutePath()));
  1243 + }
1262 1244 }
1263 1245 }
1264 1246 else
1265 1247 {
1266   - logger.info("Not loading mod " + newMod.getName() + ", excluded by filter");
  1248 + LiteLoader.getLogger().info(String.format("Not loading mod %s, excluded by filter", metaName));
  1249 + this.disabledMods.add(this.getModFile(mod));
1267 1250 }
1268 1251 }
1269 1252 catch (Throwable th)
1270 1253 {
1271   - logger.warning(th.toString());
  1254 + LiteLoader.getLogger().warning(th.toString());
1272 1255 th.printStackTrace();
1273 1256 }
1274 1257 }
1275 1258 }
1276 1259  
1277 1260 /**
1278   - * @param name
1279   - * @return
  1261 + * Initialise the mods which were loaded
1280 1262 */
1281   - private boolean shouldAddMod(LiteMod mod)
  1263 + private void initMods()
1282 1264 {
1283   - if (this.modNameFilter == null) return true;
  1265 + this.loadedModsList = "";
  1266 + int loadedModsCount = 0;
1284 1267  
1285   - String modClassName = mod.getClass().getSimpleName();
1286   - if (!this.modFiles.containsKey(modClassName)) return true;
1287   -
1288   - String metaName = this.modFiles.get(modClassName).getModName().toLowerCase();
1289   - if (this.modNameFilter.contains(metaName))
1290   - {
1291   - return true;
1292   - }
1293   -
1294   - return false;
1295   - }
1296   -
1297   - /**
1298   - * Initialise the mods which were loaded
1299   - */
1300   - private void initMods()
1301   - {
1302   - this.loadedModsList = "";
1303   - int loadedModsCount = 0;
1304   -
1305   - for (Iterator<LiteMod> iter = this.mods.iterator(); iter.hasNext();)
  1268 + for (Iterator<LiteMod> iter = this.mods.iterator(); iter.hasNext();)
1306 1269 {
1307 1270 LiteMod mod = iter.next();
1308 1271 String modName = mod.getName();
1309 1272  
1310 1273 try
1311 1274 {
1312   - logger.info("Initialising mod " + modName + " version " + mod.getVersion());
  1275 + LiteLoader.getLogger().info("Initialising mod " + modName + " version " + mod.getVersion());
1313 1276  
1314 1277 try
1315 1278 {
... ... @@ -1318,81 +1281,21 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1318 1281  
1319 1282 if (LiteLoader.VERSION.getLoaderRevision() > lastModVersion.getLoaderRevision())
1320 1283 {
1321   - logger.info("Performing config upgrade for mod " + modName + ". Upgrading " + lastModVersion + " to " + LiteLoader.VERSION + "...");
  1284 + LiteLoader.getLogger().info("Performing config upgrade for mod " + modName + ". Upgrading " + lastModVersion + " to " + LiteLoader.VERSION + "...");
1322 1285 mod.upgradeSettings(VERSION.getMinecraftVersion(), this.versionConfigFolder, this.inflectVersionedConfigPath(lastModVersion));
1323 1286  
1324 1287 this.storeLastKnownModRevision(modKey);
1325   - logger.info("Config upgrade succeeded for mod " + modName);
  1288 + LiteLoader.getLogger().info("Config upgrade succeeded for mod " + modName);
1326 1289 }
1327 1290 }
1328 1291 catch (Throwable th)
1329 1292 {
1330   - logger.warning("Error performing settings upgrade for " + modName + ". Settings may not be properly migrated");
  1293 + LiteLoader.getLogger().warning("Error performing settings upgrade for " + modName + ". Settings may not be properly migrated");
1331 1294 }
1332 1295  
1333 1296 mod.init(this.modsFolder);
1334 1297  
1335   - if (mod instanceof Tickable)
1336   - {
1337   - this.addTickListener((Tickable)mod);
1338   - }
1339   -
1340   - if (mod instanceof GameLoopListener)
1341   - {
1342   - this.addLoopListener((GameLoopListener)mod);
1343   - }
1344   -
1345   - if (mod instanceof InitCompleteListener)
1346   - {
1347   - this.addInitListener((InitCompleteListener)mod);
1348   - }
1349   -
1350   - if (mod instanceof RenderListener)
1351   - {
1352   - this.addRenderListener((RenderListener)mod);
1353   - }
1354   -
1355   - if (mod instanceof PostRenderListener)
1356   - {
1357   - this.addPostRenderListener((PostRenderListener)mod);
1358   - }
1359   -
1360   - if (mod instanceof ChatFilter)
1361   - {
1362   - this.addChatFilter((ChatFilter)mod);
1363   - }
1364   -
1365   - if (mod instanceof ChatListener)
1366   - {
1367   - if (mod instanceof ChatFilter)
1368   - {
1369   - this.logger.warning(String.format("Interface error initialising mod '%1s'. A mod implementing ChatFilter and ChatListener is not supported! Remove one of these interfaces", modName));
1370   - }
1371   - else
1372   - {
1373   - this.addChatListener((ChatListener)mod);
1374   - }
1375   - }
1376   -
1377   - if (mod instanceof ChatRenderListener)
1378   - {
1379   - this.addChatRenderListener((ChatRenderListener)mod);
1380   - }
1381   -
1382   - if (mod instanceof PreLoginListener)
1383   - {
1384   - this.addPreLoginListener((PreLoginListener)mod);
1385   - }
1386   -
1387   - if (mod instanceof LoginListener)
1388   - {
1389   - this.addLoginListener((LoginListener)mod);
1390   - }
1391   -
1392   - if (mod instanceof PluginChannelListener)
1393   - {
1394   - this.addPluginChannelListener((PluginChannelListener)mod);
1395   - }
  1298 + this.events.addListener(mod);
1396 1299  
1397 1300 if (mod instanceof Permissible)
1398 1301 {
... ... @@ -1405,7 +1308,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1405 1308 }
1406 1309 catch (Throwable th)
1407 1310 {
1408   - logger.log(Level.WARNING, "Error initialising mod '" + modName, th);
  1311 + LiteLoader.getLogger().log(Level.WARNING, "Error initialising mod '" + modName, th);
1409 1312 iter.remove();
1410 1313 }
1411 1314 }
... ... @@ -1414,198 +1317,6 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1414 1317 }
1415 1318  
1416 1319 /**
1417   - * Initialise mod hooks
1418   - */
1419   - private void initHooks()
1420   - {
1421   - try
1422   - {
1423   - // Chat hook
1424   - if ((this.chatListeners.size() > 0 || this.chatFilters.size() > 0) && !this.chatHooked)
1425   - {
1426   - this.chatHooked = true;
1427   - HookChat.register();
1428   - HookChat.registerPacketHandler(this);
1429   - }
1430   -
1431   - // Login hook
1432   - if ((this.preLoginListeners.size() > 0 || this.loginListeners.size() > 0) && !this.loginHooked)
1433   - {
1434   - this.loginHooked = true;
1435   - ModUtilities.registerPacketOverride(1, HookLogin.class);
1436   - HookLogin.loader = this;
1437   - }
1438   -
1439   - // Plugin channels hook
1440   - if (this.pluginChannelListeners.size() > 0 && !this.pluginChannelHooked)
1441   - {
1442   - this.pluginChannelHooked = true;
1443   - HookPluginChannels.register();
1444   - HookPluginChannels.registerPacketHandler(this);
1445   - }
1446   -
1447   - // Tick hook
1448   - if (!this.tickHooked)
1449   - {
1450   - this.tickHooked = true;
1451   - PrivateFields.minecraftProfiler.setFinal(this.minecraft, this.profilerHook);
1452   - }
1453   -
1454   - // Sanity hook
1455   - PlayerUsageSnooper snooper = this.minecraft.getPlayerUsageSnooper();
1456   - PrivateFields.playerStatsCollector.setFinal(snooper, this);
1457   - }
1458   - catch (Exception ex)
1459   - {
1460   - logger.log(Level.WARNING, "Error creating hooks", ex);
1461   - ex.printStackTrace();
1462   - }
1463   - }
1464   -
1465   - /**
1466   - * @param tickable
1467   - */
1468   - public void addTickListener(Tickable tickable)
1469   - {
1470   - if (!this.tickListeners.contains(tickable))
1471   - {
1472   - this.tickListeners.add(tickable);
1473   - if (this.loaderStartupComplete)
1474   - this.initHooks();
1475   - }
1476   - }
1477   -
1478   - /**
1479   - * @param loopListener
1480   - */
1481   - public void addLoopListener(GameLoopListener loopListener)
1482   - {
1483   - if (!this.loopListeners.contains(loopListener))
1484   - {
1485   - this.loopListeners.add(loopListener);
1486   - if (this.loaderStartupComplete)
1487   - this.initHooks();
1488   - }
1489   - }
1490   -
1491   - /**
1492   - * @param initCompleteListener
1493   - */
1494   - public void addInitListener(InitCompleteListener initCompleteListener)
1495   - {
1496   - if (!this.initListeners.contains(initCompleteListener))
1497   - {
1498   - this.initListeners.add(initCompleteListener);
1499   - if (this.loaderStartupComplete)
1500   - this.initHooks();
1501   - }
1502   - }
1503   -
1504   - /**
1505   - * @param tickable
1506   - */
1507   - public void addRenderListener(RenderListener tickable)
1508   - {
1509   - if (!this.renderListeners.contains(tickable))
1510   - {
1511   - this.renderListeners.add(tickable);
1512   - if (this.loaderStartupComplete)
1513   - this.initHooks();
1514   - }
1515   - }
1516   -
1517   - /**
1518   - * @param tickable
1519   - */
1520   - public void addPostRenderListener(PostRenderListener tickable)
1521   - {
1522   - if (!this.postRenderListeners.contains(tickable))
1523   - {
1524   - this.postRenderListeners.add(tickable);
1525   - if (this.loaderStartupComplete)
1526   - this.initHooks();
1527   - }
1528   - }
1529   -
1530   - /**
1531   - * @param chatFilter
1532   - */
1533   - public void addChatFilter(ChatFilter chatFilter)
1534   - {
1535   - if (!this.chatFilters.contains(chatFilter))
1536   - {
1537   - this.chatFilters.add(chatFilter);
1538   - if (this.loaderStartupComplete)
1539   - this.initHooks();
1540   - }
1541   - }
1542   -
1543   - /**
1544   - * @param chatListener
1545   - */
1546   - public void addChatListener(ChatListener chatListener)
1547   - {
1548   - if (!this.chatListeners.contains(chatListener))
1549   - {
1550   - this.chatListeners.add(chatListener);
1551   - if (this.loaderStartupComplete)
1552   - this.initHooks();
1553   - }
1554   - }
1555   -
1556   - /**
1557   - * @param chatRenderListener
1558   - */
1559   - public void addChatRenderListener(ChatRenderListener chatRenderListener)
1560   - {
1561   - if (!this.chatRenderListeners.contains(chatRenderListener))
1562   - {
1563   - this.chatRenderListeners.add(chatRenderListener);
1564   - if (this.loaderStartupComplete)
1565   - this.initHooks();
1566   - }
1567   - }
1568   -
1569   - /**
1570   - * @param loginListener
1571   - */
1572   - public void addPreLoginListener(PreLoginListener loginListener)
1573   - {
1574   - if (!this.preLoginListeners.contains(loginListener))
1575   - {
1576   - this.preLoginListeners.add(loginListener);
1577   - if (this.loaderStartupComplete)
1578   - this.initHooks();
1579   - }
1580   - }
1581   -
1582   - /**
1583   - * @param loginListener
1584   - */
1585   - public void addLoginListener(LoginListener loginListener)
1586   - {
1587   - if (!this.loginListeners.contains(loginListener))
1588   - {
1589   - this.loginListeners.add(loginListener);
1590   - if (this.loaderStartupComplete)
1591   - this.initHooks();
1592   - }
1593   - }
1594   -
1595   - /**
1596   - * @param pluginChannelListener
1597   - */
1598   - public void addPluginChannelListener(PluginChannelListener pluginChannelListener)
1599   - {
1600   - if (!this.pluginChannelListeners.contains(pluginChannelListener))
1601   - {
1602   - this.pluginChannelListeners.add(pluginChannelListener);
1603   - if (this.loaderStartupComplete)
1604   - this.initHooks();
1605   - }
1606   - }
1607   -
1608   - /**
1609 1320 * Enumerate classes on the classpath which are subclasses of the specified
1610 1321 * class
1611 1322 *
... ... @@ -1629,7 +1340,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1629 1340 }
1630 1341 catch (Throwable th)
1631 1342 {
1632   - logger.log(Level.WARNING, "Enumeration error", th);
  1343 + LiteLoader.getLogger().log(Level.WARNING, "Enumeration error", th);
1633 1344 }
1634 1345  
1635 1346 return classes;
... ... @@ -1747,72 +1458,32 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1747 1458 }
1748 1459 catch (Throwable th)
1749 1460 {
1750   - logger.log(Level.WARNING, "checkAndAddClass error", th);
  1461 + LiteLoader.getLogger().log(Level.WARNING, "checkAndAddClass error", th);
1751 1462 }
1752 1463 }
1753   -
1754   - /**
1755   - * Add a URL to the Minecraft classloader class path
1756   - *
1757   - * @param classUrl URL of the resource to add
1758   - */
1759   - private boolean addURLToClassPath(URL classUrl)
  1464 +
  1465 + public void refreshResources()
1760 1466 {
1761   - try
1762   - {
1763   - if (Minecraft.class.getClassLoader() instanceof URLClassLoader && this.mAddUrl != null && this.mAddUrl.isAccessible())
1764   - {
1765   - URLClassLoader classLoader = (URLClassLoader)Minecraft.class.getClassLoader();
1766   - this.mAddUrl.invoke(classLoader, classUrl);
1767   - return true;
1768   - }
1769   - }
1770   - catch (Throwable th)
  1467 + if (this.pendingResourceReload)
1771 1468 {
1772   - logger.log(Level.WARNING, "Error adding class path entry", th);
  1469 + this.pendingResourceReload = false;
  1470 + this.minecraft.refreshResources();
1773 1471 }
1774   -
1775   - return false;
1776 1472 }
1777 1473  
1778   - /**
1779   - * Late initialisation callback
1780   - */
1781 1474 public void onInit()
1782 1475 {
1783   - if (this.pendingResourceReload)
1784   - {
1785   - this.pendingResourceReload = false;
1786   - this.minecraft.func_110436_a(); // TODO adamsrc -> refreshResourcePacks
1787   - }
1788   -
1789   - if (!this.lateInitDone)
1790   - {
1791   - this.lateInitDone = true;
1792   -
1793   - for (InitCompleteListener initMod : this.initListeners)
1794   - {
1795   - try
1796   - {
1797   - logger.info("Calling late init for mod " + initMod.getName());
1798   - initMod.onInitCompleted(this.minecraft, this);
1799   - }
1800   - catch (Throwable th)
1801   - {
1802   - logger.log(Level.WARNING, "Error initialising mod " + initMod.getName(), th);
1803   - }
1804   - }
1805   - }
1806   -
1807 1476 if (this.soundManagerReloadInhibitor != null && this.soundManagerReloadInhibitor.isInhibited())
1808 1477 {
1809 1478 this.soundManagerReloadInhibitor.unInhibit(true);
1810 1479 }
1811 1480 }
1812   -
1813   - /**
1814   - * Callback from the tick hook, pre render
1815   - */
  1481 +
  1482 + public void onLogin(NetHandler netHandler, Packet1Login loginPacket)
  1483 + {
  1484 + this.permissionsManager.onLogin(netHandler, loginPacket);
  1485 + }
  1486 +
1816 1487 public void onRender()
1817 1488 {
1818 1489 if (this.paginateControls && this.minecraft.currentScreen != null && this.minecraft.currentScreen.getClass().equals(GuiControls.class))
... ... @@ -1827,431 +1498,191 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1827 1498 {
1828 1499 }
1829 1500 }
1830   -
1831   - for (RenderListener renderListener : this.renderListeners)
1832   - renderListener.onRender();
1833 1501 }
1834   -
1835   - /**
1836   - * Callback from the tick hook, post render entities
1837   - */
1838   - public void postRenderEntities()
1839   - {
1840   - float partialTicks = (this.minecraftTimer != null) ? this.minecraftTimer.elapsedPartialTicks : 0.0F;
1841   -
1842   - for (PostRenderListener renderListener : this.postRenderListeners)
1843   - renderListener.onPostRenderEntities(partialTicks);
1844   - }
1845   -
1846   - /**
1847   - * Callback from the tick hook, post render
1848   - */
1849   - public void postRender()
1850   - {
1851   - float partialTicks = (this.minecraftTimer != null) ? this.minecraftTimer.elapsedPartialTicks : 0.0F;
1852   -
1853   - for (PostRenderListener renderListener : this.postRenderListeners)
1854   - renderListener.onPostRender(partialTicks);
1855   - }
1856   -
1857   - /**
1858   - * Called immediately before the current GUI is rendered
1859   - */
1860   - public void onBeforeGuiRender()
1861   - {
1862   - for (RenderListener renderListener : this.renderListeners)
1863   - renderListener.onRenderGui(this.minecraft.currentScreen);
1864   - }
1865   -
1866   - /**
1867   - * Called immediately after the world/camera transform is initialised
1868   - */
1869   - public void onSetupCameraTransform()
1870   - {
1871   - for (RenderListener renderListener : this.renderListeners)
1872   - renderListener.onSetupCameraTransform();
1873   - }
1874   -
1875   - /**
1876   - * Called immediately before the chat log is rendered
1877   - */
1878   - public void onBeforeChatRender()
1879   - {
1880   - this.currentResolution = new ScaledResolution(this.minecraft.gameSettings, this.minecraft.displayWidth, this.minecraft.displayHeight);
1881   - int screenWidth = this.currentResolution.getScaledWidth();
1882   - int screenHeight = this.currentResolution.getScaledHeight();
1883   -
1884   - GuiNewChat chat = this.minecraft.ingameGUI.getChatGUI();
1885   -
1886   - for (ChatRenderListener chatRenderListener : this.chatRenderListeners)
1887   - chatRenderListener.onPreRenderChat(screenWidth, screenHeight, chat);
1888   - }
1889   -
1890   - /**
1891   - * Called immediately after the chat log is rendered
1892   - */
1893   - public void onAfterChatRender()
  1502 +
  1503 + public void onTick(float partialTicks, boolean inGame)
1894 1504 {
1895   - int screenWidth = this.currentResolution.getScaledWidth();
1896   - int screenHeight = this.currentResolution.getScaledHeight();
1897   -
1898   - GuiNewChat chat = this.minecraft.ingameGUI.getChatGUI();
  1505 + // Tick the permissions manager
  1506 + permissionsManager.onTick(this.minecraft, partialTicks, inGame);
1899 1507  
1900   - for (ChatRenderListener chatRenderListener : this.chatRenderListeners)
1901   - chatRenderListener.onPostRenderChat(screenWidth, screenHeight, chat);
  1508 + this.checkAndStoreKeyBindings();
1902 1509 }
1903 1510  
1904   - /**
1905   - * Callback from the tick hook, called every frame when the timer is updated
1906   - */
1907   - public void onTimerUpdate()
1908   - {
1909   - for (GameLoopListener loopListener : this.loopListeners)
1910   - loopListener.onRunGameLoop(this.minecraft);
1911   - }
1912   -
1913   - /**
1914   - * Callback from the tick hook, ticks all tickable mods
1915   - *
1916   - * @param tick True if this is a new tick (otherwise it's just a new frame)
1917   - */
1918   - public void onTick(Profiler profiler, boolean tick)
  1511 + public void registerModKey(KeyBinding binding)
1919 1512 {
1920   - float partialTicks = 0.0F;
1921   -
1922   - // Try to get the minecraft timer object and determine the value of the
1923   - // partialTicks
1924   - if (tick || this.minecraftTimer == null)
1925   - {
1926   - this.minecraftTimer = PrivateFields.minecraftTimer.get(this.minecraft);
1927   - }
1928   -
1929   - // Hooray, we got the timer reference
1930   - if (this.minecraftTimer != null)
1931   - {
1932   - partialTicks = this.minecraftTimer.renderPartialTicks;
1933   - tick = this.minecraftTimer.elapsedTicks > 0;
1934   - }
1935   -
1936   - // Flag indicates whether we are in game at the moment
1937   - boolean inGame = this.minecraft.renderViewEntity != null && this.minecraft.renderViewEntity.worldObj != null;
  1513 + LinkedList<KeyBinding> keyBindings = new LinkedList<KeyBinding>();
  1514 + keyBindings.addAll(Arrays.asList(this.minecraft.gameSettings.keyBindings));
1938 1515  
1939   - if (tick)
  1516 + if (!keyBindings.contains(binding))
1940 1517 {
1941   - // Tick the permissions manager
1942   - permissionsManager.onTick(this.minecraft, partialTicks, inGame);
  1518 + if (this.keyMapSettings.containsKey(binding.keyDescription))
  1519 + {
  1520 + try
  1521 + {
  1522 + binding.keyCode = Integer.parseInt(this.keyMapSettings.getProperty(binding.keyDescription, String.valueOf(binding.keyCode)));
  1523 + }
  1524 + catch (NumberFormatException ex) {}
  1525 + }
  1526 +
  1527 + keyBindings.add(binding);
  1528 + this.minecraft.gameSettings.keyBindings = keyBindings.toArray(new KeyBinding[0]);
  1529 + this.modKeyBindings.add(binding);
1943 1530  
1944   - this.checkAndStoreKeyBindings();
1945   - }
1946   -
1947   - // Iterate tickable mods
1948   - for (Tickable tickable : this.tickListeners)
1949   - {
1950   - profiler.startSection(tickable.getClass().getSimpleName());
1951   - tickable.onTick(this.minecraft, partialTicks, inGame, tick);
1952   - profiler.endSection();
  1531 + this.updateBinding(binding);
  1532 + this.storeBindings();
1953 1533 }
1954 1534 }
1955 1535  
1956 1536 /**
1957   - * Callback from the chat hook
1958   - *
1959   - * @param chatPacket
1960   - * @return
  1537 + * Checks for changed mod keybindings and stores any that have changed
1961 1538 */
1962   - public boolean onChat(Packet3Chat chatPacket)
  1539 + private void checkAndStoreKeyBindings()
1963 1540 {
1964   - if (chatPacket.message == null)
1965   - return true;
1966   -
1967   - ChatMessageComponent chat = ChatMessageComponent.func_111078_c(chatPacket.message);
1968   - String message = chat.func_111068_a(true);
  1541 + boolean updated = false;
1969 1542  
1970   - // Chat filters get a stab at the chat first, if any filter returns
1971   - // false the chat is discarded
1972   - for (ChatFilter chatFilter : this.chatFilters)
  1543 + for (KeyBinding binding : this.modKeyBindings)
1973 1544 {
1974   - if (chatFilter.onChat(chatPacket, chat, message))
1975   - {
1976   - chat = ChatMessageComponent.func_111078_c(chatPacket.message);
1977   - message = chat.func_111068_a(true);
1978   - }
1979   - else
  1545 + if (binding.keyCode != this.storedModKeyBindings.get(binding))
1980 1546 {
1981   - return false;
  1547 + this.updateBinding(binding);
  1548 + updated = true;
1982 1549 }
1983 1550 }
1984 1551  
1985   - // Chat listeners get the chat if no filter removed it
1986   - for (ChatListener chatListener : this.chatListeners)
1987   - chatListener.onChat(chat, message);
1988   -
1989   - return true;
  1552 + if (updated)
  1553 + this.storeBindings();
1990 1554 }
1991 1555  
1992 1556 /**
1993   - * Pre-login callback from the login hook
1994   - *
1995   - * @param netHandler
1996   - * @param hookLogin
1997   - * @return
  1557 + * @param binding
1998 1558 */
1999   - public boolean onPreLogin(NetHandler netHandler, Packet1Login loginPacket)
  1559 + private void updateBinding(KeyBinding binding)
2000 1560 {
2001   - boolean cancelled = false;
2002   -
2003   - for (PreLoginListener loginListener : this.preLoginListeners)
2004   - {
2005   - cancelled |= !loginListener.onPreLogin(netHandler, loginPacket);
2006   - }
2007   -
2008   - return !cancelled;
  1561 + this.keyMapSettings.setProperty(binding.keyDescription, String.valueOf(binding.keyCode));
  1562 + this.storedModKeyBindings.put(binding, Integer.valueOf(binding.keyCode));
2009 1563 }
2010   -
  1564 +
2011 1565 /**
2012   - * Callback from the login hook
2013   - *
2014   - * @param netHandler
2015   - * @param loginPacket
  1566 + * Writes mod bindings to disk
2016 1567 */
2017   - public void onConnectToServer(NetHandler netHandler, Packet1Login loginPacket)
  1568 + protected void storeBindings()
2018 1569 {
2019   - permissionsManager.onLogin(netHandler, loginPacket);
2020   -
2021   - for (LoginListener loginListener : this.loginListeners)
2022   - loginListener.onLogin(netHandler, loginPacket);
2023   -
2024   - this.setupPluginChannels();
  1570 + try
  1571 + {
  1572 + this.keyMapSettings.store(new FileWriter(this.keyMapSettingsFile), "Mod key mappings for LiteLoader mods, stored here to avoid losing settings stored in options.txt");
  1573 + }
  1574 + catch (IOException ex) {}
2025 1575 }
2026 1576  
2027 1577 /**
2028   - * Callback for the plugin channel hook
  1578 + * Set the brand in ClientBrandRetriever to the specified brand
2029 1579 *
2030   - * @param hookPluginChannels
  1580 + * @param brand
2031 1581 */
2032   - public void onPluginChannelMessage(HookPluginChannels hookPluginChannels)
  1582 + private void setBranding(String brand)
2033 1583 {
2034   - if (hookPluginChannels != null && hookPluginChannels.channel != null && this.pluginChannels.containsKey(hookPluginChannels.channel))
  1584 + try
2035 1585 {
2036   - try
2037   - {
2038   - permissionsManager.onCustomPayload(hookPluginChannels.channel, hookPluginChannels.length, hookPluginChannels.data);
2039   - }
2040   - catch (Exception ex)
2041   - {
2042   - }
  1586 + String oldBrand = ClientBrandRetriever.getClientModName();
2043 1587  
2044   - for (PluginChannelListener pluginChannelListener : this.pluginChannels.get(hookPluginChannels.channel))
  1588 + if (oldBrand.equals("vanilla"))
2045 1589 {
  1590 + char[] newValue = brand.toCharArray();
  1591 +
  1592 + Field stringValue = String.class.getDeclaredField("value");
  1593 + stringValue.setAccessible(true);
  1594 + stringValue.set(oldBrand, newValue);
  1595 +
2046 1596 try
2047 1597 {
2048   - pluginChannelListener.onCustomPayload(hookPluginChannels.channel, hookPluginChannels.length, hookPluginChannels.data);
2049   - }
2050   - catch (Exception ex)
2051   - {
  1598 + Field stringCount = String.class.getDeclaredField("count");
  1599 + stringCount.setAccessible(true);
  1600 + stringCount.set(oldBrand, newValue.length);
2052 1601 }
  1602 + catch (NoSuchFieldException ex) {} // java 1.7 doesn't have this member
2053 1603 }
2054 1604 }
  1605 + catch (Exception ex)
  1606 + {
  1607 + LiteLoader.getLogger().log(Level.WARNING, "Setting branding failed", ex);
  1608 + }
2055 1609 }
  1610 +
  1611 + // -----------------------------------------------------------------------------------------------------------
  1612 + // TODO Remove delegates below after 1.6.3
  1613 + // -----------------------------------------------------------------------------------------------------------
2056 1614  
2057 1615 /**
2058   - * Delegate to ModUtilities.sendPluginChannelMessage
  1616 + * Delegate to PluginChannels.sendMessage. Deprecated and will be removed
2059 1617 *
2060 1618 * @param channel Channel to send data to
2061 1619 * @param data Data to send
  1620 + *
  1621 + * @deprecated User PluginChannels.sendMessage(channel, data) instead.
2062 1622 */
  1623 + @Deprecated
2063 1624 public void sendPluginChannelMessage(String channel, byte[] data)
2064 1625 {
2065   - ModUtilities.sendPluginChannelMessage(channel, data);
  1626 + PluginChannels.sendMessage(channel, data);
2066 1627 }
2067   -
2068   - /**
2069   - * Query loaded mods for registered channels
2070   - */
2071   - protected void setupPluginChannels()
  1628 +
  1629 + @Deprecated
  1630 + public void addTickListener(Tickable tickable)
2072 1631 {
2073   - // Clear any channels from before
2074   - this.pluginChannels.clear();
2075   -
2076   - // Add the permissions manager channels
2077   - this.addPluginChannelsFor(permissionsManager);
2078   -
2079   - // Enumerate mods for plugin channels
2080   - for (PluginChannelListener pluginChannelListener : this.pluginChannelListeners)
2081   - {
2082   - this.addPluginChannelsFor(pluginChannelListener);
2083   - }
2084   -
2085   - // If any mods have registered channels, send the REGISTER packet
2086   - if (this.pluginChannels.keySet().size() > 0)
2087   - {
2088   - StringBuilder channelList = new StringBuilder();
2089   - boolean separator = false;
2090   -
2091   - for (String channel : this.pluginChannels.keySet())
2092   - {
2093   - if (separator)
2094   - channelList.append("\u0000");
2095   - channelList.append(channel);
2096   - separator = true;
2097   - }
2098   -
2099   - byte[] registrationData = channelList.toString().getBytes(Charset.forName("UTF8"));
2100   -
2101   - this.sendPluginChannelMessage("REGISTER", registrationData);
2102   - }
  1632 + this.events.addTickListener(tickable);
2103 1633 }
2104 1634  
2105   - /**
2106   - * Adds plugin channels for the specified listener to the local channels
2107   - * collection
2108   - *
2109   - * @param pluginChannelListener
2110   - */
2111   - private void addPluginChannelsFor(PluginChannelListener pluginChannelListener)
  1635 + @Deprecated
  1636 + public void addLoopListener(GameLoopListener loopListener)
2112 1637 {
2113   - List<String> channels = pluginChannelListener.getChannels();
2114   -
2115   - if (channels != null)
2116   - {
2117   - for (String channel : channels)
2118   - {
2119   - if (channel.length() > 16 || channel.toUpperCase().equals("REGISTER") || channel.toUpperCase().equals("UNREGISTER"))
2120   - continue;
2121   -
2122   - if (!this.pluginChannels.containsKey(channel))
2123   - {
2124   - this.pluginChannels.put(channel, new LinkedList<PluginChannelListener>());
2125   - }
2126   -
2127   - this.pluginChannels.get(channel).add(pluginChannelListener);
2128   - }
2129   - }
  1638 + this.events.addLoopListener(loopListener);
2130 1639 }
2131 1640  
2132   - /*
2133   - * (non-Javadoc)
2134   - *
2135   - * @see
2136   - * net.minecraft.src.IPlayerUsage#addServerStatsToSnooper(net.minecraft.
2137   - * src.PlayerUsageSnooper)
2138   - */
2139   - @Override
2140   - public void addServerStatsToSnooper(PlayerUsageSnooper var1)
  1641 + @Deprecated
  1642 + public void addInitListener(InitCompleteListener initCompleteListener)
2141 1643 {
2142   - this.minecraft.addServerStatsToSnooper(var1);
  1644 + this.events.addInitListener(initCompleteListener);
2143 1645 }
2144 1646  
2145   - /*
2146   - * (non-Javadoc)
2147   - *
2148   - * @see
2149   - * net.minecraft.src.IPlayerUsage#addServerTypeToSnooper(net.minecraft.src
2150   - * .PlayerUsageSnooper)
2151   - */
2152   - @Override
2153   - public void addServerTypeToSnooper(PlayerUsageSnooper var1)
  1647 + @Deprecated
  1648 + public void addRenderListener(RenderListener renderListener)
2154 1649 {
2155   - this.sanityCheck();
2156   - this.minecraft.addServerTypeToSnooper(var1);
  1650 + this.events.addRenderListener(renderListener);
2157 1651 }
2158 1652  
2159   - /*
2160   - * (non-Javadoc)
2161   - *
2162   - * @see net.minecraft.src.IPlayerUsage#isSnooperEnabled()
2163   - */
2164   - @Override
2165   - public boolean isSnooperEnabled()
  1653 + @Deprecated
  1654 + public void addPostRenderListener(PostRenderListener postRenderListener)
2166 1655 {
2167   - return this.minecraft.isSnooperEnabled();
  1656 + this.events.addPostRenderListener(postRenderListener);
2168 1657 }
2169 1658  
2170   - /*
2171   - * (non-Javadoc)
2172   - *
2173   - * @see net.minecraft.src.IPlayerUsage#getLogAgent()
2174   - */
2175   - @Override
2176   - public ILogAgent getLogAgent()
  1659 + @Deprecated
  1660 + public void addChatFilter(ChatFilter chatFilter)
2177 1661 {
2178   - return this.minecraft.getLogAgent();
  1662 + this.events.addChatFilter(chatFilter);
2179 1663 }
2180 1664  
2181   - /**
2182   - * Check that the profiler hook hasn't been overridden by something else
2183   - */
2184   - private void sanityCheck()
  1665 + @Deprecated
  1666 + public void addChatListener(ChatListener chatListener)
2185 1667 {
2186   - if (this.tickHooked && this.minecraft.mcProfiler != this.profilerHook)
2187   - {
2188   - PrivateFields.minecraftProfiler.setFinal(this.minecraft, this.profilerHook);
2189   - }
2190   - }
2191   -
2192   - public void registerModKey(KeyBinding binding)
2193   - {
2194   - LinkedList<KeyBinding> keyBindings = new LinkedList<KeyBinding>();
2195   - keyBindings.addAll(Arrays.asList(this.minecraft.gameSettings.keyBindings));
2196   -
2197   - if (!keyBindings.contains(binding))
2198   - {
2199   - if (this.keyMapSettings.containsKey(binding.keyDescription))
2200   - {
2201   - try
2202   - {
2203   - binding.keyCode = Integer.parseInt(this.keyMapSettings.getProperty(binding.keyDescription, String.valueOf(binding.keyCode)));
2204   - }
2205   - catch (NumberFormatException ex) {}
2206   - }
2207   -
2208   - keyBindings.add(binding);
2209   - this.minecraft.gameSettings.keyBindings = keyBindings.toArray(new KeyBinding[0]);
2210   - this.modKeys.add(binding);
2211   -
2212   - this.updateBinding(binding);
2213   - this.storeBindings();
2214   - }
  1668 + this.events.addChatListener(chatListener);
2215 1669 }
2216 1670  
2217   - /**
2218   - * Checks for changed mod keybindings and stores any that have changed
2219   - */
2220   - private void checkAndStoreKeyBindings()
  1671 + @Deprecated
  1672 + public void addChatRenderListener(ChatRenderListener chatRenderListener)
2221 1673 {
2222   - boolean updated = false;
2223   -
2224   - for (KeyBinding binding : this.modKeys)
2225   - {
2226   - if (binding.keyCode != this.storedModKeyBindings.get(binding))
2227   - {
2228   - this.updateBinding(binding);
2229   - updated = true;
2230   - }
2231   - }
2232   -
2233   - if (updated)
2234   - this.storeBindings();
  1674 + this.events.addChatRenderListener(chatRenderListener);
2235 1675 }
2236 1676  
2237   - /**
2238   - * @param binding
2239   - */
2240   - private void updateBinding(KeyBinding binding)
  1677 + @Deprecated
  1678 + public void addPreLoginListener(PreLoginListener loginListener)
2241 1679 {
2242   - this.keyMapSettings.setProperty(binding.keyDescription, String.valueOf(binding.keyCode));
2243   - this.storedModKeyBindings.put(binding, Integer.valueOf(binding.keyCode));
  1680 + this.events.addPreLoginListener(loginListener);
2244 1681 }
2245 1682  
2246   - /**
2247   - * Writes mod bindings to disk
2248   - */
2249   - protected void storeBindings()
  1683 + @Deprecated
  1684 + public void addLoginListener(LoginListener loginListener)
2250 1685 {
2251   - try
2252   - {
2253   - this.keyMapSettings.store(new FileWriter(this.keyMapSettingsFile), "Mod key mappings for LiteLoader mods, stored here to avoid losing settings stored in options.txt");
2254   - }
2255   - catch (IOException ex) {}
  1686 + this.events.addLoginListener(loginListener);
2256 1687 }
2257 1688 }
2258 1689 \ No newline at end of file
... ...
java/com/mumfrey/liteloader/core/LiteLoaderVersion.java
... ... @@ -7,7 +7,7 @@ import java.util.Set;
7 7 * LiteLoader version table
8 8 *
9 9 * @author Adam Mummery-Smith
10   - * @version 1.6.2_04
  10 + * @version 1.6.3
11 11 */
12 12 public enum LiteLoaderVersion
13 13 {
... ... @@ -17,8 +17,9 @@ public enum LiteLoaderVersion
17 17 MC_1_6_1_R0(11, "1.6.1", "1.6.1", "1.6.1", "1.6.r1"),
18 18 MC_1_6_2_R0(12, "1.6.2", "1.6.2", "1.6.2", "1.6.r2"),
19 19 MC_1_6_2_R1(13, "1.6.2", "1.6.2_02", "1.6.2", "1.6.r2"),
20   - MC_1_6_2_R2(13, "1.6.2", "1.6.2_03", "1.6.2", "1.6.r2"),
21   - MC_1_6_2_R3(13, "1.6.2", "1.6.2_04", "1.6.2", "1.6.r2");
  20 + MC_1_6_2_R2(14, "1.6.2", "1.6.2_03", "1.6.2", "1.6.r2"),
  21 + MC_1_6_2_R3(15, "1.6.2", "1.6.2_04", "1.6.2", "1.6.r2"),
  22 + MC_1_6_3_R0(16, "1.6.3", "1.6.3", "1.6.3", "1.6.r3");
22 23  
23 24 private int revision;
24 25  
... ...
java/com/mumfrey/liteloader/core/ModFile.java
... ... @@ -34,7 +34,7 @@ public class ModFile extends File
34 34 /**
35 35 * True if parsed from JSON, false if fallback mode using legacy version.txt
36 36 */
37   - protected boolean json = false;
  37 +// protected boolean json = false;
38 38  
39 39 /**
40 40 * Name of the mod specified in the JSON file, this can be any string but should be the same between mod versions
... ... @@ -88,8 +88,8 @@ public class ModFile extends File
88 88 protected void parseVersionFile(String strVersionData)
89 89 {
90 90 // Assume that it's json if the file starts with a brace
91   - if (strVersionData.trim().startsWith("{"))
92   - {
  91 +// if (strVersionData.trim().startsWith("{"))
  92 +// {
93 93 try
94 94 {
95 95 this.metaData = ModFile.gson.fromJson(strVersionData, HashMap.class);
... ... @@ -120,14 +120,14 @@ public class ModFile extends File
120 120 }
121 121  
122 122 this.valid = true;
123   - this.json = true;
124   - }
125   - else
126   - {
127   - // Legacy version.txt file
128   - this.version = strVersionData;
129   - this.valid = true;
130   - }
  123 +// this.json = true;
  124 +// }
  125 +// else
  126 +// {
  127 +// // Legacy version.txt file
  128 +// this.version = strVersionData;
  129 +// this.valid = true;
  130 +// }
131 131  
132 132 if (this.modName == null)
133 133 {
... ... @@ -145,10 +145,10 @@ public class ModFile extends File
145 145 return this.valid;
146 146 }
147 147  
148   - public boolean isJson()
149   - {
150   - return this.json;
151   - }
  148 +// public boolean isJson()
  149 +// {
  150 +// return this.json;
  151 +// }
152 152  
153 153 public String getVersion()
154 154 {
... ... @@ -180,6 +180,7 @@ public class ModFile extends File
180 180 {
181 181 if (this.resourcePack == null)
182 182 {
  183 + LiteLoader.getLogger().info(String.format("Registering \"%s\" as mod resource pack with identifier \"%s\"", this.getName(), name));
183 184 this.resourcePack = new ModResourcePack(name, this);
184 185 return LiteLoader.getInstance().registerModResourcePack(this.resourcePack);
185 186 }
... ...
java/com/mumfrey/liteloader/core/PluginChannels.java 0 โ†’ 100644
  1 +package com.mumfrey.liteloader.core;
  2 +
  3 +import java.nio.charset.Charset;
  4 +import java.util.HashMap;
  5 +import java.util.LinkedList;
  6 +import java.util.List;
  7 +
  8 +import net.minecraft.src.Minecraft;
  9 +import net.minecraft.src.NetHandler;
  10 +import net.minecraft.src.Packet1Login;
  11 +import net.minecraft.src.Packet250CustomPayload;
  12 +
  13 +import com.mumfrey.liteloader.PluginChannelListener;
  14 +import com.mumfrey.liteloader.core.hooks.HookPluginChannels;
  15 +import com.mumfrey.liteloader.permissions.PermissionsManagerClient;
  16 +
  17 +/**
  18 + * Manages plugin channel connections and subscriptions for LiteLoader
  19 + *
  20 + * @author Adam Mummery-Smith
  21 + */
  22 +public class PluginChannels
  23 +{
  24 + // reserved channel consts
  25 + private static final String CHANNEL_REGISTER = "REGISTER";
  26 + private static final String CHANNEL_UNREGISTER = "UNREGISTER";
  27 +
  28 + /**
  29 + * Reference to the loader
  30 + */
  31 + private LiteLoader loader;
  32 +
  33 + /**
  34 + * True if we have initialised the hook
  35 + */
  36 + private boolean hookInitDone;
  37 +
  38 + /**
  39 + * Mapping of plugin channel names to listeners
  40 + */
  41 + private HashMap<String, LinkedList<PluginChannelListener>> pluginChannels = new HashMap<String, LinkedList<PluginChannelListener>>();
  42 +
  43 + /**
  44 + * List of mods which implement PluginChannelListener interface
  45 + */
  46 + private LinkedList<PluginChannelListener> pluginChannelListeners = new LinkedList<PluginChannelListener>();
  47 +
  48 + /**
  49 + * @param loader
  50 + */
  51 + public PluginChannels(LiteLoader loader)
  52 + {
  53 + this.loader = loader;
  54 + }
  55 +
  56 + /**
  57 + *
  58 + */
  59 + public void initHook()
  60 + {
  61 + // Plugin channels hook
  62 + if (this.pluginChannelListeners.size() > 0 && !this.hookInitDone)
  63 + {
  64 + HookPluginChannels.register();
  65 + HookPluginChannels.registerPacketHandler(this);
  66 + this.hookInitDone = true;
  67 + }
  68 + }
  69 +
  70 +
  71 + /**
  72 + * @param pluginChannelListener
  73 + */
  74 + public void addPluginChannelListener(PluginChannelListener pluginChannelListener)
  75 + {
  76 + if (!this.pluginChannelListeners.contains(pluginChannelListener))
  77 + {
  78 + this.pluginChannelListeners.add(pluginChannelListener);
  79 + if (this.hookInitDone)
  80 + this.initHook();
  81 + }
  82 + }
  83 +
  84 + /**
  85 + * @param netHandler
  86 + * @param loginPacket
  87 + */
  88 + public void onConnectToServer(NetHandler netHandler, Packet1Login loginPacket)
  89 + {
  90 + this.setupPluginChannels();
  91 + }
  92 +
  93 + /**
  94 + * Callback for the plugin channel hook
  95 + *
  96 + * @param customPayload
  97 + */
  98 + public void onPluginChannelMessage(Packet250CustomPayload customPayload)
  99 + {
  100 + if (customPayload != null && customPayload.channel != null && this.pluginChannels.containsKey(customPayload.channel))
  101 + {
  102 + try
  103 + {
  104 + PermissionsManagerClient permissionsManager = this.loader.getPermissionsManager();
  105 + if (permissionsManager != null)
  106 + {
  107 + permissionsManager.onCustomPayload(customPayload.channel, customPayload.length, customPayload.data);
  108 + }
  109 + }
  110 + catch (Exception ex) {}
  111 +
  112 + for (PluginChannelListener pluginChannelListener : this.pluginChannels.get(customPayload.channel))
  113 + {
  114 + try
  115 + {
  116 + pluginChannelListener.onCustomPayload(customPayload.channel, customPayload.length, customPayload.data);
  117 + }
  118 + catch (Exception ex) {}
  119 + }
  120 + }
  121 + }
  122 +
  123 + /**
  124 + * Query loaded mods for registered channels
  125 + */
  126 + protected void setupPluginChannels()
  127 + {
  128 + // Clear any channels from before
  129 + this.pluginChannels.clear();
  130 +
  131 + // Add the permissions manager channels
  132 + this.addPluginChannelsFor(this.loader.getPermissionsManager());
  133 +
  134 + // Enumerate mods for plugin channels
  135 + for (PluginChannelListener pluginChannelListener : this.pluginChannelListeners)
  136 + {
  137 + this.addPluginChannelsFor(pluginChannelListener);
  138 + }
  139 +
  140 + // If any mods have registered channels, send the REGISTER packet
  141 + if (this.pluginChannels.keySet().size() > 0)
  142 + {
  143 + StringBuilder channelList = new StringBuilder();
  144 + boolean separator = false;
  145 +
  146 + for (String channel : this.pluginChannels.keySet())
  147 + {
  148 + if (separator) channelList.append("\u0000");
  149 + channelList.append(channel);
  150 + separator = true;
  151 + }
  152 +
  153 + byte[] registrationData = channelList.toString().getBytes(Charset.forName("UTF8"));
  154 + PluginChannels.sendMessage(CHANNEL_REGISTER, registrationData);
  155 + }
  156 + }
  157 +
  158 + /**
  159 + * Adds plugin channels for the specified listener to the local channels
  160 + * collection
  161 + *
  162 + * @param pluginChannelListener
  163 + */
  164 + private void addPluginChannelsFor(PluginChannelListener pluginChannelListener)
  165 + {
  166 + List<String> channels = pluginChannelListener.getChannels();
  167 +
  168 + if (channels != null)
  169 + {
  170 + for (String channel : channels)
  171 + {
  172 + if (channel.length() > 16 || channel.toUpperCase().equals(CHANNEL_REGISTER) || channel.toUpperCase().equals(CHANNEL_UNREGISTER))
  173 + continue;
  174 +
  175 + if (!this.pluginChannels.containsKey(channel))
  176 + {
  177 + this.pluginChannels.put(channel, new LinkedList<PluginChannelListener>());
  178 + }
  179 +
  180 + this.pluginChannels.get(channel).add(pluginChannelListener);
  181 + }
  182 + }
  183 + }
  184 +
  185 + public static void sendMessage(String channel, byte[] data)
  186 + {
  187 + if (channel == null || channel.length() > 16)
  188 + throw new RuntimeException("Invalid channel name specified");
  189 +
  190 + try
  191 + {
  192 + Minecraft minecraft = Minecraft.getMinecraft();
  193 +
  194 + if (minecraft.thePlayer != null && minecraft.thePlayer.sendQueue != null)
  195 + {
  196 + Packet250CustomPayload payload = new Packet250CustomPayload(channel, data);
  197 + minecraft.thePlayer.sendQueue.addToSendQueue(payload);
  198 + }
  199 + }
  200 + catch (Exception ex) {}
  201 + }
  202 +}
... ...
java/com/mumfrey/liteloader/core/SoundManagerReloadInhibitor.java
... ... @@ -103,7 +103,7 @@ public class SoundManagerReloadInhibitor
103 103 if (reload)
104 104 {
105 105 LiteLoader.getLogger().info("Reloading sound manager");
106   - this.soundManager.func_110549_a(this.resourceManager); // TODO adamsrc -> onReload
  106 + this.soundManager.onResourceManagerReload(this.resourceManager);
107 107 }
108 108  
109 109 this.inhibited = false;
... ...
java/com/mumfrey/liteloader/core/exceptions/ProfilerCrossThreadAccessException.java 0 โ†’ 100644
  1 +package com.mumfrey.liteloader.core.exceptions;
  2 +
  3 +/**
  4 + * Exception to throw if startSection or endSection are called from a thread other than
  5 + * the Minecraft main thread. This should NEVER happen and is an attempt to identify the
  6 + * culprit of some profiler stack corruption causes.
  7 + *
  8 + * @author Adam Mummery-Smith
  9 + */
  10 +public class ProfilerCrossThreadAccessException extends RuntimeException
  11 +{
  12 + private static final long serialVersionUID = 3225047722943528251L;
  13 +
  14 + public ProfilerCrossThreadAccessException(String message)
  15 + {
  16 + super("Calling thread name \"" + message + "\"");
  17 + }
  18 +}
... ...
java/com/mumfrey/liteloader/core/ProfilerStackCorruptionException.java renamed to java/com/mumfrey/liteloader/core/exceptions/ProfilerStackCorruptionException.java
1   -package com.mumfrey.liteloader.core;
  1 +package com.mumfrey.liteloader.core.exceptions;
2 2  
3 3 /**
4 4 * Exception to throw when a mod corrupts the profiler stack, this avoids throwing a
... ...
java/com/mumfrey/liteloader/core/HookChat.java renamed to java/com/mumfrey/liteloader/core/hooks/HookChat.java
1   -package com.mumfrey.liteloader.core;
  1 +package com.mumfrey.liteloader.core.hooks;
2 2  
3 3 import java.io.DataInput;
4 4 import java.io.DataOutput;
... ... @@ -10,6 +10,7 @@ import net.minecraft.src.NetHandler;
10 10 import net.minecraft.src.Packet;
11 11 import net.minecraft.src.Packet3Chat;
12 12  
  13 +import com.mumfrey.liteloader.core.Events;
13 14 import com.mumfrey.liteloader.util.PrivateFields;
14 15  
15 16 /**
... ... @@ -30,7 +31,7 @@ public class HookChat extends Packet3Chat
30 31 /**
31 32 * Handler module which is registered to handle inbound chat packets
32 33 */
33   - private static LiteLoader packetHandler;
  34 + private static Events events;
34 35  
35 36 /**
36 37 * Class which was overridden and will be instanced for new packets
... ... @@ -106,7 +107,7 @@ public class HookChat extends Packet3Chat
106 107 @Override
107 108 public void processPacket(NetHandler nethandler)
108 109 {
109   - if (packetHandler == null || packetHandler.onChat(this))
  110 + if (events == null || events.onChat(this))
110 111 {
111 112 if (proxyPacket != null)
112 113 proxyPacket.processPacket(nethandler);
... ... @@ -128,9 +129,9 @@ public class HookChat extends Packet3Chat
128 129 * Register the specified handler as the packet handler for this packet
129 130 * @param handler
130 131 */
131   - public static void registerPacketHandler(LiteLoader handler)
  132 + public static void registerPacketHandler(Events handler)
132 133 {
133   - packetHandler = handler;
  134 + events = handler;
134 135 }
135 136  
136 137 /**
... ...
java/com/mumfrey/liteloader/core/HookLogin.java renamed to java/com/mumfrey/liteloader/core/hooks/HookLogin.java
1   -package com.mumfrey.liteloader.core;
  1 +package com.mumfrey.liteloader.core.hooks;
  2 +
  3 +import com.mumfrey.liteloader.core.Events;
2 4  
3 5 import net.minecraft.src.EnumGameType;
4 6 import net.minecraft.src.NetHandler;
... ... @@ -7,7 +9,7 @@ import net.minecraft.src.WorldType;
7 9  
8 10 public class HookLogin extends Packet1Login
9 11 {
10   - public static LiteLoader loader;
  12 + public static Events events;
11 13  
12 14 public HookLogin()
13 15 {
... ... @@ -25,11 +27,11 @@ public class HookLogin extends Packet1Login
25 27 @Override
26 28 public void processPacket(NetHandler par1NetHandler)
27 29 {
28   - if (loader == null || loader.onPreLogin(par1NetHandler, this))
  30 + if (events == null || events.onPreLogin(par1NetHandler, this))
29 31 {
30 32 super.processPacket(par1NetHandler);
31 33  
32   - if (loader != null) loader.onConnectToServer(par1NetHandler, this);
  34 + if (events != null) events.onConnectToServer(par1NetHandler, this);
33 35 }
34 36 }
35 37 }
... ...
java/com/mumfrey/liteloader/core/HookPluginChannels.java renamed to java/com/mumfrey/liteloader/core/hooks/HookPluginChannels.java
1   -package com.mumfrey.liteloader.core;
  1 +package com.mumfrey.liteloader.core.hooks;
2 2  
3 3 import java.io.DataInput;
4 4 import java.io.DataOutput;
... ... @@ -10,6 +10,7 @@ import net.minecraft.src.NetHandler;
10 10 import net.minecraft.src.Packet;
11 11 import net.minecraft.src.Packet250CustomPayload;
12 12  
  13 +import com.mumfrey.liteloader.core.PluginChannels;
13 14 import com.mumfrey.liteloader.util.PrivateFields;
14 15  
15 16 public class HookPluginChannels extends Packet250CustomPayload
... ... @@ -22,7 +23,7 @@ public class HookPluginChannels extends Packet250CustomPayload
22 23 /**
23 24 * Handler module which is registered to handle inbound chat packets
24 25 */
25   - private static LiteLoader packetHandler;
  26 + private static PluginChannels events;
26 27  
27 28 /**
28 29 * Class which was overridden and will be instanced for new packets
... ... @@ -40,9 +41,9 @@ public class HookPluginChannels extends Packet250CustomPayload
40 41  
41 42 try
42 43 {
43   - if (proxyClass != null)
  44 + if (HookPluginChannels.proxyClass != null)
44 45 {
45   - proxyPacket = proxyClass.newInstance();
  46 + proxyPacket = HookPluginChannels.proxyClass.newInstance();
46 47 }
47 48 }
48 49 catch (Exception ex) {}
... ... @@ -54,9 +55,9 @@ public class HookPluginChannels extends Packet250CustomPayload
54 55  
55 56 try
56 57 {
57   - if (proxyClass != null)
  58 + if (HookPluginChannels.proxyClass != null)
58 59 {
59   - proxyPacket = proxyClass.newInstance();
  60 + proxyPacket = HookPluginChannels.proxyClass.newInstance();
60 61  
61 62 if (proxyPacket instanceof Packet250CustomPayload)
62 63 {
... ... @@ -101,9 +102,9 @@ public class HookPluginChannels extends Packet250CustomPayload
101 102 else
102 103 super.processPacket(nethandler);
103 104  
104   - if (packetHandler != null)
  105 + if (HookPluginChannels.events != null)
105 106 {
106   - packetHandler.onPluginChannelMessage(this);
  107 + HookPluginChannels.events.onPluginChannelMessage(this);
107 108 }
108 109 }
109 110  
... ... @@ -120,9 +121,9 @@ public class HookPluginChannels extends Packet250CustomPayload
120 121 * Register the specified handler as the packet handler for this packet
121 122 * @param handler
122 123 */
123   - public static void registerPacketHandler(LiteLoader handler)
  124 + public static void registerPacketHandler(PluginChannels handler)
124 125 {
125   - packetHandler = handler;
  126 + HookPluginChannels.events = handler;
126 127 }
127 128  
128 129 /**
... ... @@ -142,25 +143,26 @@ public class HookPluginChannels extends Packet250CustomPayload
142 143 @SuppressWarnings({ "unchecked", "rawtypes" })
143 144 public static void register(boolean force)
144 145 {
145   - if (!registered || force)
  146 + if (!HookPluginChannels.registered || force)
146 147 {
147 148 try
148 149 {
  150 + int packetId = 250;
149 151 IntHashMap packetIdToClassMap = Packet.packetIdToClassMap;
150   - proxyClass = (Class<? extends Packet>)packetIdToClassMap.lookup(250);
  152 + HookPluginChannels.proxyClass = (Class<? extends Packet>)packetIdToClassMap.lookup(packetId);
151 153  
152   - if (proxyClass.equals(Packet250CustomPayload.class))
  154 + if (HookPluginChannels.proxyClass.equals(Packet250CustomPayload.class))
153 155 {
154   - proxyClass = null;
  156 + HookPluginChannels.proxyClass = null;
155 157 }
156 158  
157   - packetIdToClassMap.removeObject(250);
158   - packetIdToClassMap.addKey(250, HookPluginChannels.class);
  159 + packetIdToClassMap.removeObject(packetId);
  160 + packetIdToClassMap.addKey(packetId, HookPluginChannels.class);
159 161  
160 162 Map packetClassToIdMap = PrivateFields.StaticFields.packetClassToIdMap.get();
161   - packetClassToIdMap.put(HookPluginChannels.class, Integer.valueOf(250));
  163 + packetClassToIdMap.put(HookPluginChannels.class, Integer.valueOf(packetId));
162 164  
163   - registered = true;
  165 + HookPluginChannels.registered = true;
164 166 }
165 167 catch (Exception ex)
166 168 {
... ...
java/com/mumfrey/liteloader/core/HookProfiler.java renamed to java/com/mumfrey/liteloader/core/hooks/HookProfiler.java
1   -package com.mumfrey.liteloader.core;
  1 +package com.mumfrey.liteloader.core.hooks;
2 2  
3 3 import java.lang.reflect.Field;
4 4 import java.lang.reflect.Method;
... ... @@ -6,6 +6,11 @@ import java.util.LinkedList;
6 6 import java.util.NoSuchElementException;
7 7 import java.util.logging.Logger;
8 8  
  9 +import com.mumfrey.liteloader.core.Events;
  10 +import com.mumfrey.liteloader.core.LiteLoader;
  11 +import com.mumfrey.liteloader.core.exceptions.ProfilerCrossThreadAccessException;
  12 +import com.mumfrey.liteloader.core.exceptions.ProfilerStackCorruptionException;
  13 +
9 14 import net.minecraft.src.Minecraft;
10 15 import net.minecraft.src.GameSettings;
11 16 import net.minecraft.src.Profiler;
... ... @@ -18,14 +23,19 @@ import net.minecraft.src.Profiler;
18 23 public class HookProfiler extends Profiler
19 24 {
20 25 /**
  26 + * Cross-thread sanity check
  27 + */
  28 + private final Thread minecraftThread;
  29 +
  30 + /**
21 31 * Logger instance
22 32 */
23 33 private Logger logger;
24 34  
25 35 /**
26   - * LiteLoader instance which will receive callbacks
  36 + * Event manager instance which will receive callbacks
27 37 */
28   - private LiteLoader loader;
  38 + private Events events;
29 39  
30 40 /**
31 41 * Section list, used as a kind of stack to determine where we are in the profiler stack
... ... @@ -55,18 +65,20 @@ public class HookProfiler extends Profiler
55 65 /**
56 66 * .ctor
57 67 *
58   - * @param core LiteLoader object which will get callbacks
  68 + * @param events LiteLoader object which will get callbacks
59 69 * @param logger Logger instance
60 70 */
61   - public HookProfiler(LiteLoader core, Logger logger)
  71 + public HookProfiler(Events events)
62 72 {
63 73 this.mc = Minecraft.getMinecraft();
64 74  
65   - this.loader = core;
66   - this.logger = logger;
  75 + this.events = events;
  76 + this.logger = LiteLoader.getLogger();
67 77  
68 78 // Detect optifine (duh!)
69 79 this.detectOptifine();
  80 +
  81 + this.minecraftThread = Thread.currentThread();
70 82 }
71 83  
72 84 /**
... ... @@ -126,35 +138,40 @@ public class HookProfiler extends Profiler
126 138 @Override
127 139 public void startSection(String sectionName)
128 140 {
  141 + if (Thread.currentThread() != this.minecraftThread)
  142 + {
  143 + throw new ProfilerCrossThreadAccessException(Thread.currentThread().getName());
  144 + }
  145 +
129 146 if (!this.initDone)
130 147 {
131 148 this.initDone = true;
132   - this.loader.onInit();
  149 + this.events.onInit();
133 150 }
134 151  
135 152 if ("gameRenderer".equals(sectionName) && "root".equals(this.sectionStack.getLast()))
136 153 {
137   - this.loader.onRender();
  154 + this.events.onRender();
138 155 }
139   -
140   - if ("frustrum".equals(sectionName) && "level".equals(this.sectionStack.getLast()))
  156 + else if ("frustrum".equals(sectionName) && "level".equals(this.sectionStack.getLast()))
141 157 {
142   - this.loader.onSetupCameraTransform();
  158 + this.events.onSetupCameraTransform();
143 159 }
144   -
145   - if ("litParticles".equals(sectionName))
  160 + else if ("litParticles".equals(sectionName))
146 161 {
147   - this.loader.postRenderEntities();
  162 + this.events.postRenderEntities();
148 163 }
149   -
150   - if ("tick".equals(sectionName) && "root".equals(this.sectionStack.getLast()))
  164 + else if ("tick".equals(sectionName) && "root".equals(this.sectionStack.getLast()))
151 165 {
152   - this.loader.onTimerUpdate();
  166 + this.events.onTimerUpdate();
153 167 }
154   -
155   - if ("chat".equals(sectionName))
  168 + else if ("chat".equals(sectionName))
156 169 {
157   - this.loader.onBeforeChatRender();
  170 + this.events.onRenderChat();
  171 + }
  172 + else if ("gui".equals(sectionName) && "gameRenderer".equals(this.sectionStack.getLast()))
  173 + {
  174 + this.events.onRenderHUD();
158 175 }
159 176  
160 177 if ("animateTick".equals(sectionName)) this.tick = true;
... ... @@ -184,6 +201,11 @@ public class HookProfiler extends Profiler
184 201 @Override
185 202 public void endSection()
186 203 {
  204 + if (Thread.currentThread() != this.minecraftThread)
  205 + {
  206 + throw new ProfilerCrossThreadAccessException(Thread.currentThread().getName());
  207 + }
  208 +
187 209 super.endSection();
188 210  
189 211 try
... ... @@ -191,26 +213,34 @@ public class HookProfiler extends Profiler
191 213 String endingSection = this.sectionStack.size() > 0 ? this.sectionStack.removeLast() : null;
192 214 String nextSection = this.sectionStack.size() > 0 ? this.sectionStack.getLast() : null;
193 215  
194   - if ("gameRenderer".equals(endingSection) && "root".equals(this.sectionStack.getLast()))
  216 + if ("gameRenderer".equals(endingSection) && "root".equals(nextSection))
195 217 {
196 218 super.startSection("litetick");
197 219  
198   - this.loader.onTick(this, this.tick);
  220 + this.events.onTick(this, this.tick);
199 221 this.tick = false;
200 222  
201 223 super.endSection();
202 224 }
203   - else if (("mouse".equals(endingSection) && "gameRenderer".equals(nextSection) && (this.mc.skipRenderWorld || this.mc.theWorld == null)) || ("gui".equals(endingSection) && "gameRenderer".equals(nextSection) && this.mc.theWorld != null))
204   - {
205   - this.loader.onBeforeGuiRender();
206   - }
207   - else if ("hand".equals(endingSection) && "level".equals(this.sectionStack.getLast()))
  225 + else
208 226 {
209   - this.loader.postRender();
210   - }
211   - else if ("chat".equals(endingSection))
212   - {
213   - this.loader.onAfterChatRender();
  227 + if ("gui".equals(endingSection) && "gameRenderer".equals(nextSection) && this.mc.theWorld != null)
  228 + {
  229 + this.events.postRenderHUD();
  230 + this.events.preRenderGUI();
  231 + }
  232 + else if ("mouse".equals(endingSection) && "gameRenderer".equals(nextSection) && (this.mc.skipRenderWorld || this.mc.theWorld == null))
  233 + {
  234 + this.events.preRenderGUI();
  235 + }
  236 + else if ("hand".equals(endingSection) && "level".equals(nextSection))
  237 + {
  238 + this.events.postRender();
  239 + }
  240 + else if ("chat".equals(endingSection))
  241 + {
  242 + this.events.postRenderChat();
  243 + }
214 244 }
215 245 }
216 246 catch (NoSuchElementException ex)
... ... @@ -219,4 +249,14 @@ public class HookProfiler extends Profiler
219 249 throw new ProfilerStackCorruptionException("Corrupted Profiler stack detected");
220 250 }
221 251 }
  252 +//
  253 +// @Override
  254 +// public void dumpState()
  255 +// {
  256 +// String endingSection = this.sectionStack.size() > 0 ? this.sectionStack.getLast() : null;
  257 +// String nextSection = this.sectionStack.size() > 1 ? this.sectionStack.get(sectionStack.size() - 2) : null;
  258 +//
  259 +// System.out.println("endingSection=" + endingSection + " nextSection=" + nextSection);
  260 +// }
  261 +
222 262 }
... ...
java/com/mumfrey/liteloader/gui/GuiControlsPaginated.java
... ... @@ -105,17 +105,17 @@ public class GuiControlsPaginated extends GuiScreen
105 105 {
106 106 this.getLegacyControlList().add(this.btnNext = new GuiButton(201, this.getWidth() / 2 - 51, buttonY, 50, 20, ">>"));
107 107 this.getLegacyControlList().add(this.btnPrevious = new GuiButton(202, this.getWidth() / 2 - 103, buttonY, 50, 20, "<<"));
108   - this.getLegacyControlList().add(new GuiButton(200, this.getWidth() / 2 + 1, buttonY, 100, 20, I18n.func_135053_a("gui.done"))); // TODO adamsrc -> translate
  108 + this.getLegacyControlList().add(new GuiButton(200, this.getWidth() / 2 + 1, buttonY, 100, 20, I18n.getString("gui.done")));
109 109  
110 110 this.btnNext.enabled = this.startIndex < this.endIndex;
111 111 this.btnPrevious.enabled = this.startIndex > 0;
112 112 }
113 113 else
114 114 {
115   - this.getLegacyControlList().add(new GuiButton(200, this.getWidth() / 2 - 100, buttonY, I18n.func_135053_a("gui.done"))); // TODO adamsrc -> translate
  115 + this.getLegacyControlList().add(new GuiButton(200, this.getWidth() / 2 - 100, buttonY, I18n.getString("gui.done")));
116 116 }
117 117  
118   - this.screenTitle = I18n.func_135053_a("controls.title"); // TODO adamsrc -> translate
  118 + this.screenTitle = I18n.getString("controls.title");
119 119 }
120 120  
121 121 /**
... ...
java/com/mumfrey/liteloader/launch/LiteLoaderTransformer.java 0 โ†’ 100644
  1 +package com.mumfrey.liteloader.launch;
  2 +
  3 +import java.io.File;
  4 +import java.lang.reflect.Method;
  5 +import java.util.List;
  6 +import java.util.logging.Level;
  7 +import java.util.logging.Logger;
  8 +
  9 +import net.minecraft.launchwrapper.IClassTransformer;
  10 +import net.minecraft.launchwrapper.LaunchClassLoader;
  11 +
  12 +public class LiteLoaderTransformer implements IClassTransformer
  13 +{
  14 + private static final String classMappingRenderLightningBolt = "net.minecraft.src.RenderLightningBolt";
  15 +
  16 + // TODO Obfuscation 1.6.3
  17 + private static final String classMappingRenderLightningBoltObf = "bha";
  18 +
  19 + private static Logger logger = Logger.getLogger("liteloader");
  20 +
  21 + public static LaunchClassLoader launchClassLoader;
  22 +
  23 + public static List<String> modsToLoad;
  24 +
  25 + public static File gameDirectory;
  26 +
  27 + public static File assetsDirectory;
  28 +
  29 + public static String profile;
  30 +
  31 + @Override
  32 + public byte[] transform(String name, String transformedName, byte[] basicClass)
  33 + {
  34 + if (classMappingRenderLightningBolt.equals(name) || classMappingRenderLightningBoltObf.equals(name))
  35 + {
  36 + logger.info("Beginning LiteLoader Init...");
  37 +
  38 + try
  39 + {
  40 + Class<?> loaderClass = Class.forName("com.mumfrey.liteloader.core.LiteLoader", false, LiteLoaderTransformer.launchClassLoader);
  41 + Method mInit = loaderClass.getDeclaredMethod("init", File.class, File.class, String.class, List.class, LaunchClassLoader.class);
  42 + mInit.setAccessible(true);
  43 + mInit.invoke(null, LiteLoaderTransformer.gameDirectory, LiteLoaderTransformer.assetsDirectory, LiteLoaderTransformer.profile, LiteLoaderTransformer.modsToLoad, LiteLoaderTransformer.launchClassLoader);
  44 + }
  45 + catch (Throwable th)
  46 + {
  47 + logger.log(Level.SEVERE, String.format("Error initialising LiteLoader: %s", th.getMessage()), th);
  48 + }
  49 + }
  50 +
  51 + return basicClass;
  52 + }
  53 +}
... ...
java/com/mumfrey/liteloader/launch/LiteLoaderTweaker.java 0 โ†’ 100644
  1 +package com.mumfrey.liteloader.launch;
  2 +
  3 +import java.io.File;
  4 +import java.util.ArrayList;
  5 +import java.util.HashMap;
  6 +import java.util.List;
  7 +import java.util.Map;
  8 +import java.util.Map.Entry;
  9 +
  10 +import joptsimple.ArgumentAcceptingOptionSpec;
  11 +import joptsimple.NonOptionArgumentSpec;
  12 +import joptsimple.OptionParser;
  13 +import joptsimple.OptionSet;
  14 +import net.minecraft.launchwrapper.ITweaker;
  15 +import net.minecraft.launchwrapper.Launch;
  16 +import net.minecraft.launchwrapper.LaunchClassLoader;
  17 +
  18 +/**
  19 + *
  20 + * @author Adam Mummery-Smith
  21 + */
  22 +public class LiteLoaderTweaker implements ITweaker
  23 +{
  24 + public static final String VERSION = "1.6.3";
  25 +
  26 + private File gameDirectory;
  27 +
  28 + private File assetsDirectory;
  29 +
  30 + private String profile;
  31 +
  32 + private List<String> unClassifiedArgs = new ArrayList<String>();
  33 +
  34 + private Map<String, String> classifiedArgs = new HashMap<String, String>();
  35 +
  36 + private ArgumentAcceptingOptionSpec<String> modsOption;
  37 + private OptionSet parsedOptions;
  38 +
  39 + private List<String> passThroughArgs;
  40 +
  41 + @Override
  42 + public void acceptOptions(List<String> args, File gameDirectory, File assetsDirectory, String profile)
  43 + {
  44 + this.gameDirectory = gameDirectory;
  45 + this.assetsDirectory = assetsDirectory;
  46 + this.profile = profile;
  47 +
  48 + LiteLoaderTransformer.gameDirectory = gameDirectory;
  49 + LiteLoaderTransformer.assetsDirectory = assetsDirectory;
  50 + LiteLoaderTransformer.profile = profile;
  51 +
  52 + OptionParser optionParser = new OptionParser();
  53 + this.modsOption = optionParser.accepts("mods", "Comma-separated list of mods to load").withRequiredArg().ofType(String.class).withValuesSeparatedBy(',');
  54 + optionParser.allowsUnrecognizedOptions();
  55 + NonOptionArgumentSpec<String> nonOptions = optionParser.nonOptions();
  56 +
  57 + this.parsedOptions = optionParser.parse(args.toArray(new String[args.size()]));
  58 + this.passThroughArgs = this.parsedOptions.valuesOf(nonOptions);
  59 +
  60 + // Parse out the arguments ourself because joptsimple doesn't really provide a good way to
  61 + // add arguments to the unparsed argument list after parsing
  62 + this.parseArgs(this.passThroughArgs);
  63 +
  64 + // Put required arguments to the blackboard if they don't already exist there
  65 + this.provideRequiredArgs(gameDirectory, assetsDirectory);
  66 +
  67 + if (this.parsedOptions.has(this.modsOption))
  68 + {
  69 + LiteLoaderTransformer.modsToLoad = this.modsOption.values(this.parsedOptions);
  70 + }
  71 + }
  72 +
  73 + /**
  74 + * @param gameDirectory
  75 + * @param assetsDirectory
  76 + */
  77 + public void provideRequiredArgs(File gameDirectory, File assetsDirectory)
  78 + {
  79 + @SuppressWarnings("unchecked")
  80 + final List<String> argumentList = (List<String>)Launch.blackboard.get("ArgumentList");
  81 +
  82 + if (argumentList != null)
  83 + {
  84 + if (!argumentList.contains("--version"))
  85 + {
  86 + argumentList.add("--version");
  87 + argumentList.add(this.VERSION);
  88 + }
  89 +
  90 + if (!argumentList.contains("--gameDir") && gameDirectory != null)
  91 + {
  92 + argumentList.add("--gameDir");
  93 + argumentList.add(gameDirectory.getAbsolutePath());
  94 + }
  95 +
  96 + if (!argumentList.contains("--assetsDir") && assetsDirectory != null)
  97 + {
  98 + argumentList.add("--assetsDir");
  99 + argumentList.add(assetsDirectory.getAbsolutePath());
  100 + }
  101 + }
  102 + }
  103 +
  104 + private void parseArgs(List<String> args)
  105 + {
  106 + String classifier = null;
  107 +
  108 + for (String arg : args)
  109 + {
  110 + if (arg.startsWith("-"))
  111 + {
  112 + if (classifier != null)
  113 + classifier = this.addClassifiedArg(classifier, "");
  114 + else if (arg.contains("="))
  115 + classifier = this.addClassifiedArg(arg.substring(0, arg.indexOf('=')), arg.substring(arg.indexOf('=') + 1));
  116 + else
  117 + classifier = arg;
  118 + }
  119 + else
  120 + {
  121 + if (classifier != null)
  122 + classifier = this.addClassifiedArg(classifier, arg);
  123 + else
  124 + this.unClassifiedArgs.add(arg);
  125 + }
  126 + }
  127 + }
  128 +
  129 + private String addClassifiedArg(String classifiedArg, String arg)
  130 + {
  131 + this.classifiedArgs.put(classifiedArg, arg);
  132 + return null;
  133 + }
  134 +
  135 + @Override
  136 + public void injectIntoClassLoader(LaunchClassLoader classLoader)
  137 + {
  138 + LiteLoaderTransformer.launchClassLoader = classLoader;
  139 + classLoader.registerTransformer("com.mumfrey.liteloader.launch.LiteLoaderTransformer");
  140 + }
  141 +
  142 + @Override
  143 + public String getLaunchTarget()
  144 + {
  145 + return "net.minecraft.client.main.Main";
  146 + }
  147 +
  148 + @Override
  149 + public String[] getLaunchArguments()
  150 + {
  151 + List<String> args = new ArrayList<String>();
  152 +
  153 + for (String unClassifiedArg : this.unClassifiedArgs)
  154 + args.add(unClassifiedArg);
  155 +
  156 + for (Entry<String, String> classifiedArg : this.classifiedArgs.entrySet())
  157 + {
  158 + args.add(classifiedArg.getKey().trim());
  159 + args.add(classifiedArg.getValue().trim());
  160 + }
  161 +
  162 + return args.toArray(new String[args.size()]);
  163 + }
  164 +
  165 + public File getGameDirectory()
  166 + {
  167 + return this.gameDirectory;
  168 + }
  169 +
  170 + public File getAssetsDirectory()
  171 + {
  172 + return this.assetsDirectory;
  173 + }
  174 +
  175 + public String getProfile()
  176 + {
  177 + return this.profile;
  178 + }
  179 +}
... ...
java/com/mumfrey/liteloader/core/LiteLoaderLogFormatter.java renamed to java/com/mumfrey/liteloader/log/LiteLoaderLogFormatter.java
1   -package com.mumfrey.liteloader.core;
  1 +package com.mumfrey.liteloader.log;
2 2  
3 3 import java.io.PrintWriter;
4 4 import java.io.StringWriter;
... ... @@ -7,7 +7,7 @@ import java.util.logging.Formatter;
7 7 import java.util.logging.Level;
8 8 import java.util.logging.LogRecord;
9 9  
10   -final class LiteLoaderLogFormatter extends Formatter
  10 +public class LiteLoaderLogFormatter extends Formatter
11 11 {
12 12 private SimpleDateFormat simpleDateFormatLogFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
13 13  
... ... @@ -29,9 +29,9 @@ final class LiteLoaderLogFormatter extends Formatter
29 29  
30 30 if (th != null)
31 31 {
32   - StringWriter var5 = new StringWriter();
33   - th.printStackTrace(new PrintWriter(var5));
34   - sb.append(var5.toString());
  32 + StringWriter stringWriter = new StringWriter();
  33 + th.printStackTrace(new PrintWriter(stringWriter));
  34 + sb.append(stringWriter.toString());
35 35 }
36 36  
37 37 return sb.toString();
... ...
java/com/mumfrey/liteloader/permissions/PermissionsManagerClient.java
... ... @@ -16,7 +16,7 @@ import net.minecraft.src.Packet1Login;
16 16  
17 17 import com.mumfrey.liteloader.Permissible;
18 18 import com.mumfrey.liteloader.PluginChannelListener;
19   -import com.mumfrey.liteloader.util.ModUtilities;
  19 +import com.mumfrey.liteloader.core.PluginChannels;
20 20  
21 21 /**
22 22 * This class manages permissions on the client, it is a singleton class which can manage permissions for multiple
... ... @@ -220,7 +220,7 @@ public class PermissionsManagerClient implements PermissionsManager, PluginChann
220 220 if (!query.modName.equals("all") || query.permissions.size() > 0)
221 221 {
222 222 byte[] data = query.getBytes();
223   - ModUtilities.sendPluginChannelMessage(ReplicatedPermissionsContainer.CHANNEL, data);
  223 + PluginChannels.sendMessage(ReplicatedPermissionsContainer.CHANNEL, data);
224 224 }
225 225 }
226 226 }
... ...
java/com/mumfrey/liteloader/resources/ModResourcePack.java
... ... @@ -28,29 +28,29 @@ public class ModResourcePack extends FileResourcePack
28 28 super(modFile);
29 29 this.name = name;
30 30 }
31   -
32   - /* (non-Javadoc)
33   - * @see net.minecraft.src.AbstractResourcePack#getMetadataSection(net.minecraft.src.MetadataSerializer, java.lang.String)
34   - */
35   - @Override
36   - public MetadataSection func_135058_a(MetadataSerializer metadataSerializer, String metadataSectionName) throws IOException // TODO adamsrc -> getMetadataSection
37   - {
38   - try
  31 +
  32 + /* (non-Javadoc)
  33 + * @see net.minecraft.src.AbstractResourcePack#getMetadataSection(net.minecraft.src.MetadataSerializer, java.lang.String)
  34 + */
  35 + @Override
  36 + public MetadataSection getPackMetadata(MetadataSerializer metadataSerializer, String metadataSectionName) throws IOException
  37 + {
  38 + try
39 39 {
40   - // This will fail when fetching pack.mcmeta if there isn't one in the mod file, since we don't care we
41   - // just catch the exception and return null instead
42   - return super.func_135058_a(metadataSerializer, metadataSectionName); // TODO adamsrc -> getMetadataSection
  40 + // This will fail when fetching pack.mcmeta if there isn't one in the mod file, since we don't care we
  41 + // just catch the exception and return null instead
  42 + return super.getPackMetadata(metadataSerializer, metadataSectionName);
43 43 }
44 44 catch (Exception ex) {}
45   -
46   - return null;
47   - }
  45 +
  46 + return null;
  47 + }
48 48  
49 49 /* (non-Javadoc)
50 50 * @see net.minecraft.src.AbstractResourcePack#getName()
51 51 */
52 52 @Override
53   - public String func_130077_b() // TODO adamsrc -> getName()
  53 + public String getPackName()
54 54 {
55 55 return this.name;
56 56 }
... ...
java/com/mumfrey/liteloader/resources/ModResourcePackDir.java
... ... @@ -28,29 +28,29 @@ public class ModResourcePackDir extends FolderResourcePack
28 28 super(modFile);
29 29 this.name = name;
30 30 }
31   -
32   - /* (non-Javadoc)
33   - * @see net.minecraft.src.AbstractResourcePack#getMetadataSection(net.minecraft.src.MetadataSerializer, java.lang.String)
34   - */
35   - @Override
36   - public MetadataSection func_135058_a(MetadataSerializer metadataSerializer, String metadataSectionName) throws IOException // TODO adamsrc -> getMetadataSection
37   - {
38   - try
  31 +
  32 + /* (non-Javadoc)
  33 + * @see net.minecraft.src.AbstractResourcePack#getMetadataSection(net.minecraft.src.MetadataSerializer, java.lang.String)
  34 + */
  35 + @Override
  36 + public MetadataSection getPackMetadata(MetadataSerializer metadataSerializer, String metadataSectionName) throws IOException
  37 + {
  38 + try
39 39 {
40   - // This will fail when fetching pack.mcmeta if there isn't one in the mod file, since we don't care we
41   - // just catch the exception and return null instead
42   - return super.func_135058_a(metadataSerializer, metadataSectionName); // TODO adamsrc -> getMetadataSection
  40 + // This will fail when fetching pack.mcmeta if there isn't one in the mod file, since we don't care we
  41 + // just catch the exception and return null instead
  42 + return super.getPackMetadata(metadataSerializer, metadataSectionName);
43 43 }
44 44 catch (Exception ex) {}
45   -
46   - return null;
47   - }
  45 +
  46 + return null;
  47 + }
48 48  
49 49 /* (non-Javadoc)
50 50 * @see net.minecraft.src.AbstractResourcePack#getName()
51 51 */
52 52 @Override
53   - public String func_130077_b() // TODO adamsrc -> getName()
  53 + public String getPackName()
54 54 {
55 55 return this.name;
56 56 }
... ...
java/com/mumfrey/liteloader/util/ModUtilities.java
... ... @@ -7,9 +7,9 @@ import java.util.Map;
7 7 import java.util.Set;
8 8  
9 9 import com.mumfrey.liteloader.core.LiteLoader;
  10 +import com.mumfrey.liteloader.core.PluginChannels;
10 11  
11 12 import net.minecraft.client.ClientBrandRetriever;
12   -import net.minecraft.src.Minecraft;
13 13 import net.minecraft.src.*;
14 14  
15 15 public abstract class ModUtilities
... ... @@ -27,7 +27,7 @@ public abstract class ModUtilities
27 27 static
28 28 {
29 29 // Check for FML
30   - forgeModLoader = ClientBrandRetriever.getClientModName().contains("fml");
  30 + ModUtilities.forgeModLoader = ClientBrandRetriever.getClientModName().contains("fml");
31 31 }
32 32  
33 33 /**
... ... @@ -53,6 +53,11 @@ public abstract class ModUtilities
53 53 @SuppressWarnings("unchecked")
54 54 public static boolean registerPacketOverride(int packetId, Class<? extends Packet> newPacket)
55 55 {
  56 + if (packetId == 250)
  57 + {
  58 + throw new RuntimeException("Cannot override packet 250, register a plugin channel listener instead");
  59 + }
  60 +
56 61 if (overriddenPackets.contains(Integer.valueOf(packetId)))
57 62 {
58 63 LiteLoader.getLogger().warning(String.format("Packet with ID %s was already overridden by another mod, one or mods may not function correctly", packetId));
... ... @@ -72,7 +77,7 @@ public abstract class ModUtilities
72 77 }
73 78 catch (Exception ex)
74 79 {
75   - LiteLoader.logger.warning("Error registering packet override for packet id " + packetId + ": " + ex.getMessage());
  80 + LiteLoader.getLogger().warning("Error registering packet override for packet id " + packetId + ": " + ex.getMessage());
76 81 return false;
77 82 }
78 83 }
... ... @@ -82,23 +87,13 @@ public abstract class ModUtilities
82 87 *
83 88 * @param channel Channel to send the data
84 89 * @param data
  90 + *
  91 + * @deprecated User PluginChannels.sendMessage(channel, data) instead.
85 92 */
  93 + @Deprecated
86 94 public static void sendPluginChannelMessage(String channel, byte[] data)
87 95 {
88   - if (channel == null || channel.length() > 16)
89   - throw new RuntimeException("Invalid channel name specified");
90   -
91   - try
92   - {
93   - Minecraft minecraft = Minecraft.getMinecraft();
94   -
95   - if (minecraft.thePlayer != null)
96   - {
97   - Packet250CustomPayload payload = new Packet250CustomPayload(channel, data);
98   - minecraft.thePlayer.sendQueue.addToSendQueue(payload);
99   - }
100   - }
101   - catch (Exception ex) {}
  96 + PluginChannels.sendMessage(channel, data);
102 97 }
103 98  
104 99 /**
... ...
java/com/mumfrey/liteloader/util/PrivateFields.java
... ... @@ -15,7 +15,7 @@ import net.minecraft.src.*;
15 15 * @param <P> Parent class type, the type of the class that owns the field
16 16 * @param <T> Field type, the type of the field value
17 17 *
18   - * TODO Obfuscation - updated 1.6.2
  18 + * TODO Obfuscation - updated 1.6.3
19 19 */
20 20 @SuppressWarnings("rawtypes")
21 21 public class PrivateFields<P, T>
... ... @@ -147,6 +147,6 @@ public class PrivateFields&lt;P, T&gt;
147 147 public static final PrivateFields<RenderManager, Map> entityRenderMap = new PrivateFields<RenderManager, Map> (RenderManager.class, "entityRenderMap", "q", "field_78729_o"); // RenderManager/entityRenderMap
148 148 public static final PrivateFields<GuiControls, GuiScreen> guiControlsParentScreen = new PrivateFields<GuiControls, GuiScreen> (GuiControls.class, "parentScreen", "b", "field_73909_b"); // GuiControls/parentScreen
149 149 public static final PrivateFields<PlayerUsageSnooper, IPlayerUsage> playerStatsCollector = new PrivateFields<PlayerUsageSnooper, IPlayerUsage>(PlayerUsageSnooper.class, "playerStatsCollector", "d", "field_76478_d"); // PlayerUsageSnooper/playerStatsCollector
150   - public static final PrivateFields<SimpleReloadableResourceManager, List<ResourceManagerReloadListener>> reloadListeners = new PrivateFields<SimpleReloadableResourceManager, List<ResourceManagerReloadListener>>(SimpleReloadableResourceManager.class, "field_110546_b", "c", "field_110546_b"); // SimpleReloadableResourceManager/field_110546_b
  150 + public static final PrivateFields<SimpleReloadableResourceManager, List<ResourceManagerReloadListener>> reloadListeners = new PrivateFields<SimpleReloadableResourceManager, List<ResourceManagerReloadListener>>(SimpleReloadableResourceManager.class, "reloadListeners", "c", "field_110546_b"); // SimpleReloadableResourceManager/reloadListeners
151 151 }
152 152  
... ...
java/com/mumfrey/liteloader/util/log/ConsoleHandler.java
... ... @@ -24,15 +24,13 @@ public class ConsoleHandler extends StreamHandler
24 24 * initialized the <tt>LogRecord</tt> and forwarded it here.
25 25 * <p>
26 26 *
27   - * @param record
28   - * description of the log event. A null record is silently
29   - * ignored and is not published
  27 + * @param record description of the log event. A null record is silently ignored and is not published
30 28 */
31 29 @Override
32 30 public synchronized void publish(LogRecord record)
33 31 {
34 32 super.publish(record);
35   - flush();
  33 + this.flush();
36 34 }
37 35  
38 36 /**
... ... @@ -42,6 +40,6 @@ public class ConsoleHandler extends StreamHandler
42 40 @Override
43 41 public synchronized void close()
44 42 {
45   - flush();
  43 + this.flush();
46 44 }
47 45 }
... ...
java/net/minecraft/src/CallableJVMFlags.java
... ... @@ -11,48 +11,48 @@ import com.mumfrey.liteloader.core.CallableLiteLoaderMods;
11 11  
12 12 class CallableJVMFlags implements Callable<String>
13 13 {
14   - /** Reference to the CrashReport object. */
15   - final CrashReport theCrashReport;
16   -
17   - CallableJVMFlags(CrashReport par1CrashReport)
18   - {
19   - this.theCrashReport = par1CrashReport;
20   - par1CrashReport.func_85056_g().addCrashSectionCallable("Mod Pack", new CallableLiteLoaderBrand(par1CrashReport));
21   - par1CrashReport.func_85056_g().addCrashSectionCallable("LiteLoader Mods", new CallableLiteLoaderMods(par1CrashReport));
22   - }
23   -
24   - /**
25   - * Returns the number of JVM Flags along with the passed JVM Flags.
26   - */
27   - public String getJVMFlagsAsString()
28   - {
29   - RuntimeMXBean var1 = ManagementFactory.getRuntimeMXBean();
30   - List<String> var2 = var1.getInputArguments();
31   - int var3 = 0;
32   - StringBuilder var4 = new StringBuilder();
33   - Iterator<String> var5 = var2.iterator();
34   -
35   - while (var5.hasNext())
36   - {
37   - String var6 = var5.next();
38   -
39   - if (var6.startsWith("-X"))
40   - {
41   - if (var3++ > 0)
42   - {
43   - var4.append(" ");
44   - }
45   -
46   - var4.append(var6);
47   - }
48   - }
49   -
50   - return String.format("%d total; %s", new Object[] {Integer.valueOf(var3), var4.toString()});
51   - }
52   -
53   - @Override
  14 + /** Reference to the CrashReport object. */
  15 + final CrashReport theCrashReport;
  16 +
  17 + CallableJVMFlags(CrashReport par1CrashReport)
  18 + {
  19 + this.theCrashReport = par1CrashReport;
  20 + par1CrashReport.getCategory().addCrashSectionCallable("Mod Pack", new CallableLiteLoaderBrand(par1CrashReport));
  21 + par1CrashReport.getCategory().addCrashSectionCallable("LiteLoader Mods", new CallableLiteLoaderMods(par1CrashReport));
  22 + }
  23 +
  24 + /**
  25 + * Returns the number of JVM Flags along with the passed JVM Flags.
  26 + */
  27 + public String getJVMFlagsAsString()
  28 + {
  29 + RuntimeMXBean var1 = ManagementFactory.getRuntimeMXBean();
  30 + List<String> var2 = var1.getInputArguments();
  31 + int var3 = 0;
  32 + StringBuilder var4 = new StringBuilder();
  33 + Iterator<String> var5 = var2.iterator();
  34 +
  35 + while (var5.hasNext())
  36 + {
  37 + String var6 = var5.next();
  38 +
  39 + if (var6.startsWith("-X"))
  40 + {
  41 + if (var3++ > 0)
  42 + {
  43 + var4.append(" ");
  44 + }
  45 +
  46 + var4.append(var6);
  47 + }
  48 + }
  49 +
  50 + return String.format("%d total; %s", new Object[] {Integer.valueOf(var3), var4.toString()});
  51 + }
  52 +
  53 + @Override
54 54 public String call()
55   - {
56   - return this.getJVMFlagsAsString();
57   - }
  55 + {
  56 + return this.getJVMFlagsAsString();
  57 + }
58 58 }
... ...
javadoc/jopt-simple-4.5-javadoc.jar 0 โ†’ 100644
No preview for this file type
lib/jopt-simple-4.5.jar 0 โ†’ 100644
No preview for this file type
lib/launchwrapper-1.7.jar 0 โ†’ 100644
No preview for this file type
run/com/mumfrey/liteloader/debug/Start.java 0 โ†’ 100644
  1 +package com.mumfrey.liteloader.debug;
  2 +import java.io.BufferedReader;
  3 +import java.io.DataInputStream;
  4 +import java.io.DataOutputStream;
  5 +import java.io.File;
  6 +import java.io.IOException;
  7 +import java.io.InputStreamReader;
  8 +import java.io.UnsupportedEncodingException;
  9 +import java.net.URL;
  10 +import java.net.URLEncoder;
  11 +import java.security.PublicKey;
  12 +import java.security.cert.Certificate;
  13 +
  14 +import javax.net.ssl.HttpsURLConnection;
  15 +
  16 +import com.mumfrey.liteloader.launch.LiteLoaderTweaker;
  17 +
  18 +import net.minecraft.launchwrapper.Launch;
  19 +
  20 +/**
  21 + * Wrapper class for LaunchWrapper Main class, which logs into minecraft.net first so that online shizzle can be tested
  22 + *
  23 + * @author Adam Mummery-Smith
  24 + * @version 0.4
  25 + */
  26 +public abstract class Start
  27 +{
  28 + /**
  29 + * Username specified on the command line
  30 + */
  31 + public static String userName = "";
  32 +
  33 + /**
  34 + * Latest minecraft version as recieved from minecraft.net
  35 + */
  36 + public static String latestVersion = "";
  37 +
  38 + /**
  39 + * Download ticket issued to us by minecraft.net
  40 + */
  41 + public static String downloadTicket = "";
  42 +
  43 + /**
  44 + * Session ID retrieved during login ("-" means no session, eg. offline)
  45 + */
  46 + public static String sessionId = "-";
  47 +
  48 + /**
  49 + * Encoded certificate data in case the user forgets to extract minecraft.key !
  50 + */
  51 + private static int[] certificateData = {
  52 + 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
  53 + 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc6, 0xf3, 0xde,
  54 + 0xfd, 0xef, 0xa9, 0x62, 0x9c, 0xe0, 0x51, 0x28, 0x9b, 0xfb, 0x46, 0xbc, 0xf4, 0x1a, 0x03, 0x0d, 0x6f, 0x69,
  55 + 0xf1, 0x98, 0x2a, 0xa6, 0x35, 0xb9, 0x62, 0xd6, 0x36, 0x6b, 0x64, 0x53, 0x87, 0x93, 0xd6, 0xa9, 0xd3, 0x46,
  56 + 0xd7, 0x93, 0x4f, 0x1d, 0x8e, 0x50, 0x50, 0x7d, 0x51, 0x80, 0xd1, 0x29, 0x8f, 0x83, 0x37, 0xb6, 0x67, 0xfd,
  57 + 0xde, 0xa3, 0xdf, 0x02, 0xda, 0x52, 0xba, 0x1c, 0x3a, 0x3e, 0x6f, 0xe4, 0xb6, 0xc8, 0x55, 0x75, 0x91, 0xf8,
  58 + 0x6b, 0x2a, 0x51, 0x5a, 0xad, 0xf6, 0x26, 0x9b, 0xff, 0xcf, 0x67, 0x15, 0xa0, 0xb9, 0x5a, 0xb8, 0xca, 0xaf,
  59 + 0x8f, 0xef, 0x9a, 0x15, 0x45, 0x9f, 0x87, 0xd0, 0x82, 0x89, 0x55, 0x45, 0x91, 0x7e, 0x90, 0x03, 0x84, 0x45,
  60 + 0x6b, 0xdf, 0xeb, 0xa4, 0x95, 0x71, 0x74, 0xbd, 0x0f, 0x8b, 0xf7, 0xa8, 0xc4, 0xfa, 0xd5, 0x7d, 0x6f, 0xff,
  61 + 0x01, 0xc0, 0x4a, 0x64, 0xd2, 0x73, 0x02, 0xf1, 0x4f, 0x72, 0x87, 0x48, 0x80, 0xa2, 0x0c, 0x9c, 0x3c, 0xd5,
  62 + 0xad, 0xbe, 0xfb, 0xf0, 0x38, 0x34, 0xaf, 0x25, 0x10, 0xef, 0x96, 0xaf, 0x8c, 0x3d, 0xfa, 0x48, 0x54, 0x5f,
  63 + 0xe4, 0x11, 0x43, 0xa2, 0x74, 0xe9, 0xc4, 0x28, 0xa9, 0x06, 0x3d, 0xcc, 0xbd, 0xc0, 0xbe, 0x48, 0xb4, 0x22,
  64 + 0xd6, 0xd2, 0x34, 0xee, 0x2f, 0x07, 0x76, 0xe7, 0x33, 0x9f, 0x0d, 0xe5, 0x9e, 0x34, 0x8a, 0xc6, 0xec, 0x2b,
  65 + 0x75, 0x15, 0x3a, 0x2f, 0xa8, 0xa6, 0x9a, 0x77, 0x68, 0x17, 0xf2, 0x90, 0x65, 0x5b, 0xef, 0x52, 0x33, 0xaa,
  66 + 0x4b, 0x05, 0xf3, 0x08, 0x80, 0x0e, 0xdf, 0x0d, 0xfb, 0x8b, 0x67, 0x0e, 0x17, 0x54, 0x25, 0x9f, 0x75, 0xa9,
  67 + 0xf8, 0x66, 0x28, 0xeb, 0x70, 0x31, 0x49, 0xac, 0xe3, 0x9d, 0xb1, 0x10, 0xc8, 0xfd, 0xfd, 0x8d, 0x23, 0x6c,
  68 + 0xef, 0x02, 0x03, 0x01, 0x00, 0x01
  69 + };
  70 +
  71 + /**
  72 + * Entry point. Validates the parameters and performs the login
  73 + *
  74 + * @param args
  75 + */
  76 + public static void main(String[] args)
  77 + {
  78 + // Check we have enough arguments
  79 + if (args.length < 2)
  80 + {
  81 + Start.showError("Invalid parameters specified for start, use: <username> <password> to log in to minecraft.net");
  82 + userName = args.length < 1 ? System.getProperty("user.name") : args[0];
  83 + }
  84 + else
  85 + {
  86 + // Assign username as the first argument
  87 + userName = args[0];
  88 +
  89 + // Perform the login if the second parameter is not "-" (indicating offline)
  90 + if (!args[1].equals("-") && login(args[0], args[1], 13, true))
  91 + {
  92 + Start.showMessage(String.format("Successfully logged in as %s with session ID %s", userName, sessionId));
  93 + args[0] = userName;
  94 + args[1] = sessionId;
  95 + }
  96 + }
  97 +
  98 + Start.showMessage(String.format("Launching game as %s", userName));
  99 +
  100 + File gameDir = new File(System.getProperty("user.dir"));
  101 + File assetsDir = new File(gameDir, "assets");
  102 +
  103 + args = new String[] {
  104 + "--tweakClass", LiteLoaderTweaker.class.getName(),
  105 + "--username", userName,
  106 + "--session", sessionId,
  107 + "--version", "mcp",
  108 + "--gameDir", gameDir.getAbsolutePath(),
  109 + "--assetsDir", assetsDir.getAbsolutePath()
  110 + };
  111 +
  112 + Launch.main(args);
  113 + }
  114 +
  115 + /**
  116 + * Do login to minecraft.net. Based on the login method in the Launcher
  117 + *
  118 + * @param user Username
  119 + * @param password Password
  120 + * @param masqueradeLauncher Version Launcher version to masquerade as
  121 + * @param validateCertificate True to validate the minecraft.net certificate. False if you can't be bothered or don't care :)
  122 + * @return True if the login succeeded
  123 + */
  124 + private static boolean login(String user, String password, int masqueradeLauncherVersion, boolean validateCertificate)
  125 + {
  126 + try
  127 + {
  128 + String parameters = String.format("user=%s&password=%s&version=%s",URLEncoder.encode(user, "UTF-8"), URLEncoder.encode(password, "UTF-8"), masqueradeLauncherVersion);
  129 +
  130 + Start.showMessage("Attempting to login to minecraft.net...");
  131 + String result = excutePost("https://login.minecraft.net/", parameters, validateCertificate);
  132 +
  133 + if (result == null)
  134 + {
  135 + Start.showError("Can't connect to minecraft.net");
  136 + return false;
  137 + }
  138 +
  139 + if (!result.contains(":"))
  140 + {
  141 + Start.showError(result);
  142 + return false;
  143 + }
  144 +
  145 + try
  146 + {
  147 + String values[] = result.split(":");
  148 +
  149 + latestVersion = values[0].trim();
  150 + downloadTicket = values[1].trim();
  151 + userName = values[2].trim();
  152 + sessionId = values[3].trim();
  153 +
  154 + return true;
  155 + }
  156 + catch(Exception e)
  157 + {
  158 + e.printStackTrace();
  159 + return false;
  160 + }
  161 + }
  162 + catch (UnsupportedEncodingException e)
  163 + {
  164 + Start.showError("Error encoding POST data, check your parameters");
  165 + return false;
  166 + }
  167 + }
  168 +
  169 + /**
  170 + * Execute a HTTPS POST. Based on code in the Minecraft launcher
  171 + *
  172 + * @param targetURL POST url
  173 + * @param postData POST query string
  174 + * @param validateCertificate True if the certificate should be validated against the local cache
  175 + * @return Response data or null if the query fails
  176 + */
  177 + private static String excutePost(String targetURL, String postData, boolean validateCertificate)
  178 + {
  179 + HttpsURLConnection https = null;
  180 + String responseData;
  181 +
  182 + try
  183 + {
  184 + URL url = new URL(targetURL);
  185 +
  186 + // Play that funky music white boy
  187 + https = (HttpsURLConnection)url.openConnection();
  188 + https.setRequestMethod("POST");
  189 + https.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
  190 + https.setRequestProperty("Content-Length", Integer.toString(postData.getBytes().length));
  191 + https.setRequestProperty("Content-Language", "en-US");
  192 + https.setUseCaches(false);
  193 + https.setDoInput(true);
  194 + https.setDoOutput(true);
  195 + https.setConnectTimeout(1000);
  196 + https.connect();
  197 +
  198 + // Validate the cert we received with the HTTPS response, if the user wants to
  199 + if (validateCertificate)
  200 + {
  201 + Certificate certificates[] = https.getServerCertificates();
  202 +
  203 + byte bytes[] = new byte[294];
  204 +
  205 + try
  206 + {
  207 + DataInputStream keyReaderStream = new DataInputStream(Start.class.getResourceAsStream("/minecraft.key"));
  208 + keyReaderStream.readFully(bytes);
  209 + keyReaderStream.close();
  210 + }
  211 + catch (NullPointerException ex)
  212 + {
  213 + // Error loading from the key file (probably the user forgot to put minecraft.key in the bin folder)
  214 + Start.showError("Missing minecraft.key, reverting to internal cache");
  215 +
  216 + for (int certIndex = 0; certIndex < 294; certIndex++)
  217 + bytes[certIndex] = (byte)(certificateData[certIndex] & 0xFF);
  218 + }
  219 +
  220 + PublicKey publicKey = certificates[0].getPublicKey();
  221 + byte data[] = publicKey.getEncoded();
  222 +
  223 + for (int i = 0; i < data.length; i++)
  224 + {
  225 + if(data[i] != bytes[i])
  226 + {
  227 + Start.showError("Public key mismatch on " + targetURL);
  228 + return null;
  229 + }
  230 + }
  231 +
  232 + Start.showMessage("Certificate validated ok for " + targetURL);
  233 + }
  234 +
  235 + // Write ze postdata to ze server
  236 + DataOutputStream postDataStream = new DataOutputStream(https.getOutputStream());
  237 + postDataStream.writeBytes(postData);
  238 + postDataStream.flush();
  239 + postDataStream.close();
  240 +
  241 + // Get and concat the response
  242 + BufferedReader reader = new BufferedReader(new InputStreamReader(https.getInputStream()));
  243 + StringBuffer responseBuffer = new StringBuffer();
  244 +
  245 + String readLine;
  246 + while((readLine = reader.readLine()) != null)
  247 + {
  248 + responseBuffer.append(readLine);
  249 + responseBuffer.append('\r');
  250 + }
  251 +
  252 + reader.close();
  253 + responseData = responseBuffer.toString();
  254 +
  255 + https.disconnect();
  256 + https = null;
  257 + }
  258 + catch (IOException e)
  259 + {
  260 + e.printStackTrace();
  261 +
  262 + if(https != null)
  263 + https.disconnect();
  264 +
  265 + return null;
  266 + }
  267 + finally
  268 + {
  269 + if(https != null)
  270 + {
  271 + https.disconnect();
  272 + }
  273 + }
  274 +
  275 + return responseData;
  276 + }
  277 +
  278 + /**
  279 + * Show a message on stdout
  280 + *
  281 + * @param message
  282 + */
  283 + private static void showMessage(String message)
  284 + {
  285 + System.out.println("[START] [INFO] " + message);
  286 + }
  287 +
  288 + /**
  289 + * Show a message on stderr
  290 + *
  291 + * @param message
  292 + */
  293 + private static void showError(String message)
  294 + {
  295 + System.err.println("[START] [ERROR] " + message);
  296 + }
  297 +}
... ...
run/minecraft.key 0 โ†’ 100644
No preview for this file type