Commit 70fa603ad0a16430300cef89f3887e93caae30ce

Authored by Mumfrey
1 parent 4e3e54ae

merged changes from Permissions branch to Trunk

Showing 29 changed files with 2026 additions and 501 deletions
.classpath
@@ -3,10 +3,8 @@ @@ -3,10 +3,8 @@
3 <classpathentry kind="src" path="java"/> 3 <classpathentry kind="src" path="java"/>
4 <classpathentry kind="src" path="res"/> 4 <classpathentry kind="src" path="res"/>
5 <classpathentry combineaccessrules="false" kind="src" path="/Client"/> 5 <classpathentry combineaccessrules="false" kind="src" path="/Client"/>
6 - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jre6"/>  
7 - <classpathentry kind="lib" path="/Client/jars/bin/jinput.jar"/>  
8 - <classpathentry kind="lib" path="/Client/jars/bin/lwjgl_util.jar"/>  
9 - <classpathentry kind="lib" path="/Client/jars/bin/lwjgl.jar"/>  
10 - <classpathentry kind="lib" path="/Client/jars/bin/minecraft.jar"/> 6 + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
  7 + <classpathentry kind="lib" path="/Client/jars/libraries/org/lwjgl/lwjgl/lwjgl/2.9.0/lwjgl-2.9.0.jar"/>
  8 + <classpathentry kind="lib" path="/Client/jars/versions/1.6.2/1.6.2.jar"/>
11 <classpathentry kind="output" path="bin"/> 9 <classpathentry kind="output" path="bin"/>
12 </classpath> 10 </classpath>
ant/ant-contrib.jar 0 → 100644
No preview for this file type
ant/build_liteloader.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8" ?>
  2 +<project name="liteloader" basedir="." default="rebuild">
  3 +
  4 + <taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
  5 +
  6 + <!-- Versions !!IMPORTANT -->
  7 + <property name="version" value="1.6.2" />
  8 + <property name="mcversion" value="1.6.2" />
  9 + <property name="author" value="Mumfrey" />
  10 +
  11 + <!-- Project definitions and dependencies -->
  12 + <property name="upstream" value="LiteLoader,LegacyLauncher" />
  13 + <property name="project" value="LiteLoaderLauncher" />
  14 + <property name="md5set" value="legacylauncher" />
  15 + <property name="outmd5set" value="liteloader" />
  16 +
  17 + <property name="mcp.dir" location="../../.." />
  18 + <property name="build" location="${mcp.dir}/build" />
  19 + <property name="eclipse" location="${mcp.dir}/eclipse" />
  20 + <property name="src" location="${mcp.dir}/src/minecraft" />
  21 + <property name="temp" location="${mcp.dir}/temp" />
  22 + <property name="md5.dir" location="${mcp.dir}/md5" />
  23 + <property name="mc.src" location="${mcp.dir}/src/mcp" />
  24 +
  25 + <property name="dist.dir" location="${build}/dist" />
  26 + <property name="stage.dir" location="${build}/stage/${ant.project.name}/${version}" />
  27 + <property name="filetype" value="jar" />
  28 +
  29 + <property name="python" location="${mcp.dir}/runtime/bin/python/python_mcp.exe" />
  30 +
  31 + <!-- Main target -->
  32 + <target name="rebuild" description="Perform all tasks for a build" depends="init, recompile, reobfuscate, savemd5, stage, zip" />
  33 +
  34 + <target name="clean">
  35 + <delete dir="${src}" />
  36 + <delete dir="${mcp.dir}/reobf" />
  37 + </target>
  38 +
  39 + <target name="contributesource" description="Contribute an upstream project source code to the source path">
  40 + <echo level="info" message="Contributing project ${lib}" />
  41 + <copy todir="${src}" verbose="false" overwrite="true" failonerror="false">
  42 + <fileset dir="${eclipse}/${lib}/java" />
  43 + <fileset dir="${eclipse}/${lib}/src" />
  44 + </copy>
  45 + </target>
  46 +
  47 + <target name="contributeresources" description="Contribute resources to the staging path">
  48 + <echo level="info" message="Contributing project resources for ${lib}" />
  49 + <copy todir="${stage.dir}" verbose="false" failonerror="false">
  50 + <fileset dir="${eclipse}/${lib}/res" excludes=".svn/**">
  51 + <exclude name="**/Thumbs.db" />
  52 + </fileset>
  53 + </copy>
  54 + </target>
  55 +
  56 + <target name="preparemd5" description="Copy patched MD5 to the temp directory" depends="clean">
  57 + <echo level="info" message="Prepare exclusion MD5s, using exclusion set &quot;${md5set}&quot;" />
  58 +
  59 + <copy tofile="${temp}/client.md5" file="${md5.dir}/client_${md5set}.md5" failonerror="true" verbose="true" overwrite="true" />
  60 + </target>
  61 +
  62 + <target name="prepare" description="Prepare source for MCP" depends="preparemd5">
  63 + <echo level="info" message="Prepare sources for compile" />
  64 +
  65 + <copy todir="${src}" verbose="false" overwrite="true">
  66 + <fileset dir="${mc.src}" />
  67 + </copy>
  68 +
  69 + <foreach list="${upstream}" param="lib" target="contributesource" />
  70 +
  71 + <antcall target="contributesource">
  72 + <param name="lib" value="${project}" />
  73 + </antcall>
  74 + </target>
  75 +
  76 + <target name="init" description="Initialize build environment" depends="prepare">
  77 + <echo level="info" message="Cleaning old stage and dist, MCP reobf directories" />
  78 +
  79 + <delete dir="${stage.dir}" />
  80 +
  81 + <echo level="info" message="Creating stage and dist dirs" />
  82 + <mkdir dir="${stage.dir}" />
  83 + <mkdir dir="${dist.dir}" />
  84 + <mkdir dir="${md5.dir}" />
  85 + </target>
  86 +
  87 + <target name="recompile" description="MCP recompile">
  88 + <echo level="info" message="Compiling projects" />
  89 +
  90 + <exec executable="${python}" dir="${mcp.dir}">
  91 + <arg value="runtime/recompile.py" />
  92 + <arg value="--client" />
  93 + <arg value="%*" />
  94 + </exec>
  95 + </target>
  96 +
  97 + <target name="reobfuscate" description="MCP reobfuscate">
  98 + <echo level="info" message="Obfuscating classes" />
  99 +
  100 + <exec executable="${python}" dir="${mcp.dir}">
  101 + <arg value="runtime/reobfuscate.py" />
  102 + <arg value="--client" />
  103 + <arg value="%*" />
  104 + </exec>
  105 + </target>
  106 +
  107 + <target name="savemd5" description="Put post-obfuscation MD5 to stored md5 set" if="outmd5set">
  108 + <echo level="info" message="Storing obfuscated MD5s" />
  109 +
  110 + <copy file="${temp}/client_reobf.md5" tofile="${md5.dir}/client_${outmd5set}.md5" overwrite="true" verbose="true" />
  111 + </target>
  112 +
  113 + <target name="stage" description="Stage resources into staging directory">
  114 + <echo level="info" message="Staging resources" />
  115 +
  116 + <copy todir="${stage.dir}">
  117 + <fileset dir="${mcp.dir}/reobf/minecraft" excludes=".svn/**, *.txt" />
  118 + </copy>
  119 +
  120 + <foreach list="${upstream}" param="lib" target="contributeresources" />
  121 +
  122 + <antcall target="contributeresources">
  123 + <param name="lib" value="${project}" />
  124 + </antcall>
  125 +
  126 + </target>
  127 +
  128 + <target name="zip" description="Build the output zip file">
  129 + <echo level="info" message="Building final output" />
  130 +
  131 + <mkdir dir="${dist.dir}" />
  132 + <jar destfile="${dist.dir}/${ant.project.name}-${mcversion}.${filetype}" duplicate="preserve" index="true" manifestencoding="UTF-8">
  133 + <manifest>
  134 + <attribute name="Built-By" value="MCP (http://mcp.ocean-labs.de)" />
  135 + <attribute name="Implementation-Vendor" value="${author}" />
  136 + <attribute name="Implementation-Title" value="${ant.project.name}" />
  137 + <attribute name="Implementation-Version" value="${version}" />
  138 + </manifest>
  139 + <fileset dir="${stage.dir}" />
  140 + </jar>
  141 + </target>
  142 +
  143 +</project>
0 \ No newline at end of file 144 \ No newline at end of file
java/com/mumfrey/liteloader/ChatFilter.java
1 package com.mumfrey.liteloader; 1 package com.mumfrey.liteloader;
2 2
  3 +import net.minecraft.src.ChatMessageComponent;
3 import net.minecraft.src.Packet3Chat; 4 import net.minecraft.src.Packet3Chat;
4 5
5 /** 6 /**
@@ -13,7 +14,9 @@ public interface ChatFilter extends LiteMod @@ -13,7 +14,9 @@ public interface ChatFilter extends LiteMod
13 * Chat filter function, return false to filter this packet, true to pass the packet 14 * Chat filter function, return false to filter this packet, true to pass the packet
14 * 15 *
15 * @param chatPacket Chat packet to examine 16 * @param chatPacket Chat packet to examine
  17 + * @param chat ChatMessageComponent parsed from the chat packet
  18 + * @param message Chat message parsed from the chat message component
16 * @return True to keep the packet, false to discard 19 * @return True to keep the packet, false to discard
17 */ 20 */
18 - public abstract boolean onChat(Packet3Chat chatPacket); 21 + public abstract boolean onChat(Packet3Chat chatPacket, ChatMessageComponent chat, String message);
19 } 22 }
java/com/mumfrey/liteloader/ChatListener.java
1 package com.mumfrey.liteloader; 1 package com.mumfrey.liteloader;
2 2
  3 +import net.minecraft.src.ChatMessageComponent;
  4 +
3 /** 5 /**
4 * Interface for mods which receive inbound chat 6 * Interface for mods which receive inbound chat
5 * 7 *
@@ -10,7 +12,8 @@ public interface ChatListener extends LiteMod @@ -10,7 +12,8 @@ public interface ChatListener extends LiteMod
10 /** 12 /**
11 * Handle an inbound message 13 * Handle an inbound message
12 * 14 *
13 - * @param message 15 + * @param chat ChatMessageComponent parsed from the chat packet
  16 + * @param message Chat message parsed from the chat message component
14 */ 17 */
15 - public abstract void onChat(String message); 18 + public abstract void onChat(ChatMessageComponent chat, String message);
16 } 19 }
java/com/mumfrey/liteloader/GameLoopListener.java
1 package com.mumfrey.liteloader; 1 package com.mumfrey.liteloader;
2 2
3 -import net.minecraft.client.Minecraft; 3 +import net.minecraft.src.Minecraft;
4 4
5 /** 5 /**
6 * Interface for mods which want a frame notification every single game loop 6 * Interface for mods which want a frame notification every single game loop
java/com/mumfrey/liteloader/InitCompleteListener.java
1 package com.mumfrey.liteloader; 1 package com.mumfrey.liteloader;
2 2
3 -import net.minecraft.client.Minecraft; 3 +import net.minecraft.src.Minecraft;
4 4
5 import com.mumfrey.liteloader.core.LiteLoader; 5 import com.mumfrey.liteloader.core.LiteLoader;
6 6
java/com/mumfrey/liteloader/LiteMod.java
1 package com.mumfrey.liteloader; 1 package com.mumfrey.liteloader;
2 2
  3 +import java.io.File;
  4 +
3 /** 5 /**
4 * Base interface for mods 6 * Base interface for mods
5 * 7 *
@@ -24,6 +26,17 @@ public interface LiteMod @@ -24,6 +26,17 @@ public interface LiteMod
24 /** 26 /**
25 * Do startup stuff here, minecraft is not fully initialised when this function is called so mods *must not* 27 * Do startup stuff here, minecraft is not fully initialised when this function is called so mods *must not*
26 * interact with minecraft in any way here 28 * interact with minecraft in any way here
  29 + *
  30 + * @param configPath Configuration path to use
  31 + */
  32 + public abstract void init(File configPath);
  33 +
  34 + /**
  35 + * Called when the loader detects that a version change has happened since this mod was last loaded
  36 + *
  37 + * @param version new version
  38 + * @param configPath Path for the new version-specific config
  39 + * @param oldConfigPath Path for the old version-specific config
27 */ 40 */
28 - public abstract void init(); 41 + public abstract void upgradeSettings(String version, File configPath, File oldConfigPath);
29 } 42 }
java/com/mumfrey/liteloader/Permissible.java 0 → 100644
  1 +package com.mumfrey.liteloader;
  2 +
  3 +import com.mumfrey.liteloader.permissions.PermissionsManager;
  4 +import com.mumfrey.liteloader.permissions.PermissionsManagerClient;
  5 +
  6 +/**
  7 + * Interface for mods which use the ClientPermissions system
  8 + *
  9 + * @author Adam Mummery-Smith
  10 + */
  11 +public interface Permissible extends LiteMod
  12 +{
  13 + /**
  14 + * Returns the node name of the mod, replicated permissions will be of the form mod.<name>.permission.node so this
  15 + * method must return a valid name for use in permission nodes. This method must also return the same value every
  16 + * time it is called since permissible names are not necessarily cached.
  17 + *
  18 + * @return Permissible name
  19 + */
  20 + public abstract String getPermissibleModName();
  21 +
  22 + /**
  23 + * The mod version to replicate to the server
  24 + *
  25 + * @return Mod version as a float
  26 + */
  27 + public abstract float getPermissibleModVersion();
  28 +
  29 + /**
  30 + * Called by the permissions manager at initialisation to instruct the mod to populate the list of permissions it
  31 + * supports. This method should call back against the supplied permissions manager to register the permissions to
  32 + * be sent to the server when connecting.
  33 + *
  34 + * @param permissionsManager Client permissions manager
  35 + */
  36 + public abstract void registerPermissions(PermissionsManagerClient permissionsManager);
  37 +
  38 + /**
  39 + * Called when the permissions set is cleared
  40 + *
  41 + * @param manager
  42 + */
  43 + public abstract void onPermissionsCleared(PermissionsManager manager);
  44 +
  45 + /**
  46 + * Called when the permissions are changed (eg. when new permissions are received from the server)
  47 + *
  48 + * @param manager
  49 + */
  50 + public abstract void onPermissionsChanged(PermissionsManager manager);
  51 +}
java/com/mumfrey/liteloader/Tickable.java
1 package com.mumfrey.liteloader; 1 package com.mumfrey.liteloader;
2 2
3 -import net.minecraft.client.Minecraft; 3 +import net.minecraft.src.Minecraft;
4 4
5 /** 5 /**
6 * Interface for mods which want tick events 6 * Interface for mods which want tick events
java/com/mumfrey/liteloader/core/HookChat.java
1 package com.mumfrey.liteloader.core; 1 package com.mumfrey.liteloader.core;
2 2
3 -import java.io.DataInputStream;  
4 -import java.io.DataOutputStream; 3 +import java.io.DataInput;
  4 +import java.io.DataOutput;
5 import java.io.IOException; 5 import java.io.IOException;
6 import java.util.Map; 6 import java.util.Map;
7 7
8 -import com.mumfrey.liteloader.util.PrivateFields; 8 +import net.minecraft.src.IntHashMap;
  9 +import net.minecraft.src.NetHandler;
  10 +import net.minecraft.src.Packet;
  11 +import net.minecraft.src.Packet3Chat;
9 12
10 -import net.minecraft.src.*; 13 +import com.mumfrey.liteloader.util.PrivateFields;
11 14
12 /** 15 /**
13 * Proxy packet which we will register in place of the original chat packet. The class will proxy the function calls 16 * Proxy packet which we will register in place of the original chat packet. The class will proxy the function calls
@@ -80,7 +83,7 @@ public class HookChat extends Packet3Chat @@ -80,7 +83,7 @@ public class HookChat extends Packet3Chat
80 } 83 }
81 84
82 @Override 85 @Override
83 - public void readPacketData(DataInputStream datainputstream) throws IOException 86 + public void readPacketData(DataInput datainputstream) throws IOException
84 { 87 {
85 if (proxyPacket != null) 88 if (proxyPacket != null)
86 { 89 {
@@ -92,7 +95,7 @@ public class HookChat extends Packet3Chat @@ -92,7 +95,7 @@ public class HookChat extends Packet3Chat
92 } 95 }
93 96
94 @Override 97 @Override
95 - public void writePacketData(DataOutputStream dataoutputstream) throws IOException 98 + public void writePacketData(DataOutput dataoutputstream) throws IOException
96 { 99 {
97 if (proxyPacket != null) 100 if (proxyPacket != null)
98 proxyPacket.writePacketData(dataoutputstream); 101 proxyPacket.writePacketData(dataoutputstream);
java/com/mumfrey/liteloader/core/HookPluginChannels.java
1 package com.mumfrey.liteloader.core; 1 package com.mumfrey.liteloader.core;
2 2
3 -import java.io.DataInputStream;  
4 -import java.io.DataOutputStream; 3 +import java.io.DataInput;
  4 +import java.io.DataOutput;
5 import java.io.IOException; 5 import java.io.IOException;
6 import java.util.Map; 6 import java.util.Map;
7 7
8 -import com.mumfrey.liteloader.util.PrivateFields; 8 +import net.minecraft.src.IntHashMap;
  9 +import net.minecraft.src.NetHandler;
  10 +import net.minecraft.src.Packet;
  11 +import net.minecraft.src.Packet250CustomPayload;
9 12
10 -import net.minecraft.src.*; 13 +import com.mumfrey.liteloader.util.PrivateFields;
11 14
12 public class HookPluginChannels extends Packet250CustomPayload 15 public class HookPluginChannels extends Packet250CustomPayload
13 { 16 {
@@ -68,7 +71,7 @@ public class HookPluginChannels extends Packet250CustomPayload @@ -68,7 +71,7 @@ public class HookPluginChannels extends Packet250CustomPayload
68 71
69 72
70 @Override 73 @Override
71 - public void readPacketData(DataInputStream datainputstream) throws IOException 74 + public void readPacketData(DataInput datainputstream) throws IOException
72 { 75 {
73 if (proxyPacket != null) 76 if (proxyPacket != null)
74 { 77 {
@@ -82,7 +85,7 @@ public class HookPluginChannels extends Packet250CustomPayload @@ -82,7 +85,7 @@ public class HookPluginChannels extends Packet250CustomPayload
82 } 85 }
83 86
84 @Override 87 @Override
85 - public void writePacketData(DataOutputStream dataoutputstream) throws IOException 88 + public void writePacketData(DataOutput dataoutputstream) throws IOException
86 { 89 {
87 if (proxyPacket != null) 90 if (proxyPacket != null)
88 proxyPacket.writePacketData(dataoutputstream); 91 proxyPacket.writePacketData(dataoutputstream);
java/com/mumfrey/liteloader/core/HookProfiler.java
@@ -6,7 +6,7 @@ import java.util.LinkedList; @@ -6,7 +6,7 @@ import java.util.LinkedList;
6 import java.util.NoSuchElementException; 6 import java.util.NoSuchElementException;
7 import java.util.logging.Logger; 7 import java.util.logging.Logger;
8 8
9 -import net.minecraft.client.Minecraft; 9 +import net.minecraft.src.Minecraft;
10 import net.minecraft.src.GameSettings; 10 import net.minecraft.src.GameSettings;
11 import net.minecraft.src.Profiler; 11 import net.minecraft.src.Profiler;
12 12
java/com/mumfrey/liteloader/core/LiteLoader.java
1 package com.mumfrey.liteloader.core; 1 package com.mumfrey.liteloader.core;
2 2
3 import java.io.BufferedReader; 3 import java.io.BufferedReader;
4 -import java.io.ByteArrayOutputStream;  
5 import java.io.File; 4 import java.io.File;
6 import java.io.FileInputStream; 5 import java.io.FileInputStream;
7 import java.io.FileNotFoundException; 6 import java.io.FileNotFoundException;
@@ -16,7 +15,6 @@ import java.net.URL; @@ -16,7 +15,6 @@ import java.net.URL;
16 import java.net.URLClassLoader; 15 import java.net.URLClassLoader;
17 import java.net.URLDecoder; 16 import java.net.URLDecoder;
18 import java.nio.charset.Charset; 17 import java.nio.charset.Charset;
19 -import java.util.Arrays;  
20 import java.util.HashMap; 18 import java.util.HashMap;
21 import java.util.Iterator; 19 import java.util.Iterator;
22 import java.util.LinkedList; 20 import java.util.LinkedList;
@@ -33,7 +31,8 @@ import java.util.zip.ZipInputStream; @@ -33,7 +31,8 @@ import java.util.zip.ZipInputStream;
33 31
34 import javax.activity.InvalidActivityException; 32 import javax.activity.InvalidActivityException;
35 33
36 -import net.minecraft.client.Minecraft; 34 +import net.minecraft.src.ChatMessageComponent;
  35 +import net.minecraft.src.Minecraft;
37 import net.minecraft.src.GuiControls; 36 import net.minecraft.src.GuiControls;
38 import net.minecraft.src.GuiNewChat; 37 import net.minecraft.src.GuiNewChat;
39 import net.minecraft.src.GuiScreen; 38 import net.minecraft.src.GuiScreen;
@@ -54,40 +53,31 @@ import com.mumfrey.liteloader.GameLoopListener; @@ -54,40 +53,31 @@ import com.mumfrey.liteloader.GameLoopListener;
54 import com.mumfrey.liteloader.InitCompleteListener; 53 import com.mumfrey.liteloader.InitCompleteListener;
55 import com.mumfrey.liteloader.LiteMod; 54 import com.mumfrey.liteloader.LiteMod;
56 import com.mumfrey.liteloader.LoginListener; 55 import com.mumfrey.liteloader.LoginListener;
  56 +import com.mumfrey.liteloader.Permissible;
57 import com.mumfrey.liteloader.PluginChannelListener; 57 import com.mumfrey.liteloader.PluginChannelListener;
58 import com.mumfrey.liteloader.PostRenderListener; 58 import com.mumfrey.liteloader.PostRenderListener;
59 import com.mumfrey.liteloader.PreLoginListener; 59 import com.mumfrey.liteloader.PreLoginListener;
60 import com.mumfrey.liteloader.RenderListener; 60 import com.mumfrey.liteloader.RenderListener;
61 import com.mumfrey.liteloader.Tickable; 61 import com.mumfrey.liteloader.Tickable;
62 import com.mumfrey.liteloader.gui.GuiControlsPaginated; 62 import com.mumfrey.liteloader.gui.GuiControlsPaginated;
  63 +import com.mumfrey.liteloader.permissions.PermissionsManagerClient;
63 import com.mumfrey.liteloader.util.ModUtilities; 64 import com.mumfrey.liteloader.util.ModUtilities;
64 import com.mumfrey.liteloader.util.PrivateFields; 65 import com.mumfrey.liteloader.util.PrivateFields;
65 66
66 /** 67 /**
67 - * LiteLoader is a simple loader which loads and provides useful callbacks to lightweight mods  
68 - * 68 + * LiteLoader is a simple loader which loads and provides useful callbacks to
  69 + * lightweight mods
  70 + *
69 * @author Adam Mummery-Smith 71 * @author Adam Mummery-Smith
70 - * @version 1.5.2 72 + * @version 1.6.2
71 */ 73 */
72 @SuppressWarnings("rawtypes") 74 @SuppressWarnings("rawtypes")
73 public final class LiteLoader implements FilenameFilter, IPlayerUsage 75 public final class LiteLoader implements FilenameFilter, IPlayerUsage
74 { 76 {
75 /** 77 /**
76 - * Liteloader version 78 + * Liteloader version
77 */ 79 */
78 - private static final String LOADER_VERSION = "1.5.2";  
79 -  
80 - /**  
81 - * Loader revision, can be used by mods to determine whether the loader is sufficiently up-to-date  
82 - */  
83 - private static final int LOADER_REVISION = 9;  
84 -  
85 - /**  
86 - * Minecraft versions that we will load mods for, this will be compared  
87 - * against the version.txt value in mod files to prevent outdated mods being  
88 - * loaded!!!  
89 - */  
90 - private static final String[] SUPPORTED_VERSIONS = { "1.5.2", "1.5.r1" }; 80 + private static final LiteLoaderVersion VERSION = LiteLoaderVersion.MC_1_6_2_R0;
91 81
92 /** 82 /**
93 * Maximum recursion depth for mod discovery 83 * Maximum recursion depth for mod discovery
@@ -110,11 +100,42 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -110,11 +100,42 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
110 private static boolean useStdOut = false; 100 private static boolean useStdOut = false;
111 101
112 /** 102 /**
113 - * "mods" folder which contains mods and config files 103 + * Game dir from launcher
  104 + */
  105 + private static File gameDirectory;
  106 +
  107 + /**
  108 + * Assets dir from launcher
  109 + */
  110 + private static File assetsDirectory;
  111 +
  112 + /**
  113 + * Profile name from launcher
  114 + */
  115 + private static String profile = "";
  116 +
  117 + /**
  118 + * Mods folder which contains mods and legacy config files
114 */ 119 */
115 private File modsFolder; 120 private File modsFolder;
116 121
117 /** 122 /**
  123 + * Base config folder which contains LiteLoader config files and versioned
  124 + * subfolders
  125 + */
  126 + private File configBaseFolder;
  127 +
  128 + /**
  129 + * Folder containing version-independent configuration
  130 + */
  131 + private File commonConfigFolder;
  132 +
  133 + /**
  134 + * Folder containing version-specific configuration
  135 + */
  136 + private File versionConfigFolder;
  137 +
  138 + /**
118 * Reference to the Minecraft game instance 139 * Reference to the Minecraft game instance
119 */ 140 */
120 private Minecraft minecraft = Minecraft.getMinecraft(); 141 private Minecraft minecraft = Minecraft.getMinecraft();
@@ -122,25 +143,27 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -122,25 +143,27 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
122 /** 143 /**
123 * File containing the properties 144 * File containing the properties
124 */ 145 */
125 - private File propertiesFile = new File(Minecraft.getMinecraftDir(), "liteloader.properties");  
126 - 146 + private File propertiesFile;
  147 +
127 /** 148 /**
128 * Internal properties loaded from inside the jar 149 * Internal properties loaded from inside the jar
129 */ 150 */
130 private Properties internalProperties = new Properties(); 151 private Properties internalProperties = new Properties();
131 - 152 +
132 /** 153 /**
133 - * LiteLoader properties 154 + * LiteLoader properties
134 */ 155 */
135 private Properties localProperties = new Properties(); 156 private Properties localProperties = new Properties();
136 157
137 /** 158 /**
138 - * Pack brand from properties, used to put the modpack/compilation name in crash reports 159 + * Pack brand from properties, used to put the modpack/compilation name in
  160 + * crash reports
139 */ 161 */
140 private String branding = null; 162 private String branding = null;
141 163
142 /** 164 /**
143 - * Setting value, if true we will swap out the MC "Controls" GUI for our custom, paginated one 165 + * Setting value, if true we will swap out the MC "Controls" GUI for our
  166 + * custom, paginated one
144 */ 167 */
145 private boolean paginateControls = true; 168 private boolean paginateControls = true;
146 169
@@ -148,7 +171,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -148,7 +171,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
148 * Reference to the minecraft timer 171 * Reference to the minecraft timer
149 */ 172 */
150 private Timer minecraftTimer; 173 private Timer minecraftTimer;
151 - 174 +
152 /** 175 /**
153 * List of loaded mods, for crash reporting 176 * List of loaded mods, for crash reporting
154 */ 177 */
@@ -166,7 +189,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -166,7 +189,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
166 private LinkedList<Tickable> tickListeners = new LinkedList<Tickable>(); 189 private LinkedList<Tickable> tickListeners = new LinkedList<Tickable>();
167 190
168 /** 191 /**
169 - * List of mods which implement the GameLoopListener interface and will receive loop events 192 + * List of mods which implement the GameLoopListener interface and will
  193 + * receive loop events
170 */ 194 */
171 private LinkedList<GameLoopListener> loopListeners = new LinkedList<GameLoopListener>(); 195 private LinkedList<GameLoopListener> loopListeners = new LinkedList<GameLoopListener>();
172 196
@@ -176,18 +200,20 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -176,18 +200,20 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
176 private LinkedList<InitCompleteListener> initListeners = new LinkedList<InitCompleteListener>(); 200 private LinkedList<InitCompleteListener> initListeners = new LinkedList<InitCompleteListener>();
177 201
178 /** 202 /**
179 - * List of mods which implement RenderListener interface and will receive render events  
180 - * events 203 + * List of mods which implement RenderListener interface and will receive
  204 + * render events events
181 */ 205 */
182 private LinkedList<RenderListener> renderListeners = new LinkedList<RenderListener>(); 206 private LinkedList<RenderListener> renderListeners = new LinkedList<RenderListener>();
183 207
184 /** 208 /**
185 - * List of mods which implement the PostRenderListener interface and want to render entities 209 + * List of mods which implement the PostRenderListener interface and want to
  210 + * render entities
186 */ 211 */
187 private LinkedList<PostRenderListener> postRenderListeners = new LinkedList<PostRenderListener>(); 212 private LinkedList<PostRenderListener> postRenderListeners = new LinkedList<PostRenderListener>();
188 213
189 /** 214 /**
190 - * List of mods which implement ChatRenderListener and want to know when chat is rendered 215 + * List of mods which implement ChatRenderListener and want to know when
  216 + * chat is rendered
191 */ 217 */
192 private LinkedList<ChatRenderListener> chatRenderListeners = new LinkedList<ChatRenderListener>(); 218 private LinkedList<ChatRenderListener> chatRenderListeners = new LinkedList<ChatRenderListener>();
193 219
@@ -204,12 +230,14 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -204,12 +230,14 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
204 private LinkedList<ChatFilter> chatFilters = new LinkedList<ChatFilter>(); 230 private LinkedList<ChatFilter> chatFilters = new LinkedList<ChatFilter>();
205 231
206 /** 232 /**
207 - * List of mods which implement LoginListener interface and will receive client login events 233 + * List of mods which implement LoginListener interface and will receive
  234 + * client login events
208 */ 235 */
209 private LinkedList<LoginListener> loginListeners = new LinkedList<LoginListener>(); 236 private LinkedList<LoginListener> loginListeners = new LinkedList<LoginListener>();
210 237
211 /** 238 /**
212 - * List of mods which implement LoginListener interface and will receive client login events 239 + * List of mods which implement LoginListener interface and will receive
  240 + * client login events
213 */ 241 */
214 private LinkedList<PreLoginListener> preLoginListeners = new LinkedList<PreLoginListener>(); 242 private LinkedList<PreLoginListener> preLoginListeners = new LinkedList<PreLoginListener>();
215 243
@@ -217,11 +245,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -217,11 +245,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
217 * List of mods which implement PluginChannelListener interface 245 * List of mods which implement PluginChannelListener interface
218 */ 246 */
219 private LinkedList<PluginChannelListener> pluginChannelListeners = new LinkedList<PluginChannelListener>(); 247 private LinkedList<PluginChannelListener> pluginChannelListeners = new LinkedList<PluginChannelListener>();
220 - 248 +
221 /** 249 /**
222 - * Mapping of plugin channel names to listeners 250 + * Mapping of plugin channel names to listeners
223 */ 251 */
224 - private HashMap<String,LinkedList<PluginChannelListener>> pluginChannels = new HashMap<String, LinkedList<PluginChannelListener>>(); 252 + private HashMap<String, LinkedList<PluginChannelListener>> pluginChannels = new HashMap<String, LinkedList<PluginChannelListener>>();
225 253
226 /** 254 /**
227 * Reference to the addUrl method on URLClassLoader 255 * Reference to the addUrl method on URLClassLoader
@@ -232,37 +260,50 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -232,37 +260,50 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
232 * Flag which keeps track of whether late initialisation has been done 260 * Flag which keeps track of whether late initialisation has been done
233 */ 261 */
234 private boolean loaderStartupDone, loaderStartupComplete, lateInitDone; 262 private boolean loaderStartupDone, loaderStartupComplete, lateInitDone;
235 - 263 +
236 /** 264 /**
237 * Flags which keep track of whether hooks have been applied 265 * Flags which keep track of whether hooks have been applied
238 */ 266 */
239 private boolean chatHooked, loginHooked, pluginChannelHooked, tickHooked; 267 private boolean chatHooked, loginHooked, pluginChannelHooked, tickHooked;
240 - 268 +
241 /** 269 /**
242 * Profiler hook objects 270 * Profiler hook objects
243 */ 271 */
244 private HookProfiler profilerHook = new HookProfiler(this, logger); 272 private HookProfiler profilerHook = new HookProfiler(this, logger);
245 - 273 +
246 /** 274 /**
247 * ScaledResolution used by the pre-chat and post-chat render callbacks 275 * ScaledResolution used by the pre-chat and post-chat render callbacks
248 */ 276 */
249 private ScaledResolution currentResolution; 277 private ScaledResolution currentResolution;
250 278
251 /** 279 /**
252 - * Get the singleton instance of LiteLoader, initialises the loader if necessary  
253 - *  
254 - * @return LiteLoader instance 280 + * Permission Manager
255 */ 281 */
256 - public static final LiteLoader getInstance() 282 + private static PermissionsManagerClient permissionsManager = PermissionsManagerClient.getInstance();
  283 +
  284 + public static final void init(File gameDirectory, File assetsDirectory, String profile)
257 { 285 {
258 if (instance == null) 286 if (instance == null)
259 { 287 {
260 - // Return immediately to stop calls to getInstance causing re-init if they arrive  
261 - // before init is completed 288 + LiteLoader.gameDirectory = gameDirectory;
  289 + LiteLoader.assetsDirectory = assetsDirectory;
  290 + LiteLoader.profile = profile;
  291 +
262 instance = new LiteLoader(); 292 instance = new LiteLoader();
263 instance.initLoader(); 293 instance.initLoader();
264 } 294 }
265 295
  296 + }
  297 +
  298 + /**
  299 + * Get the singleton instance of LiteLoader, initialises the loader if
  300 + * necessary
  301 + *
  302 + * @param locationProvider
  303 + * @return LiteLoader instance
  304 + */
  305 + public static final LiteLoader getInstance()
  306 + {
266 return instance; 307 return instance;
267 } 308 }
268 309
@@ -293,7 +334,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -293,7 +334,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
293 */ 334 */
294 public static final String getVersion() 335 public static final String getVersion()
295 { 336 {
296 - return LOADER_VERSION; 337 + return VERSION.getLoaderVersion();
297 } 338 }
298 339
299 /** 340 /**
@@ -303,7 +344,12 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -303,7 +344,12 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
303 */ 344 */
304 public static final int getRevision() 345 public static final int getRevision()
305 { 346 {
306 - return LOADER_REVISION; 347 + return VERSION.getLoaderRevision();
  348 + }
  349 +
  350 + public static final PermissionsManagerClient getPermissionsManager()
  351 + {
  352 + return permissionsManager;
307 } 353 }
308 354
309 /** 355 /**
@@ -311,20 +357,59 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -311,20 +357,59 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
311 */ 357 */
312 private LiteLoader() 358 private LiteLoader()
313 { 359 {
  360 + this.initPaths();
  361 + }
  362 +
  363 + /**
  364 + * Set up paths used by the loader
  365 + */
  366 + private void initPaths()
  367 + {
  368 + this.modsFolder = new File(LiteLoader.gameDirectory, "mods");
  369 + this.configBaseFolder = new File(LiteLoader.gameDirectory, "liteconfig");
  370 +
  371 + this.commonConfigFolder = new File(this.configBaseFolder, "common");
  372 + this.versionConfigFolder = this.inflectVersionedConfigPath(LiteLoader.VERSION);
  373 +
  374 + if (!this.modsFolder.exists())
  375 + this.modsFolder.mkdirs();
  376 + if (!this.configBaseFolder.exists())
  377 + this.configBaseFolder.mkdirs();
  378 + if (!this.commonConfigFolder.exists())
  379 + this.commonConfigFolder.mkdirs();
  380 + if (!this.versionConfigFolder.exists())
  381 + this.versionConfigFolder.mkdirs();
  382 +
  383 + this.propertiesFile = new File(this.configBaseFolder, "liteloader.properties");
  384 + }
  385 +
  386 + /**
  387 + * @param version
  388 + * @return
  389 + */
  390 + protected File inflectVersionedConfigPath(LiteLoaderVersion version)
  391 + {
  392 + if (version.equals(LiteLoaderVersion.LEGACY))
  393 + {
  394 + return this.modsFolder;
  395 + }
  396 +
  397 + return new File(this.configBaseFolder, String.format("config.%s", version.getLoaderVersion()));
314 } 398 }
315 399
  400 + /**
  401 + * Loader initialisation
  402 + */
316 private void initLoader() 403 private void initLoader()
317 { 404 {
318 - if (this.loaderStartupDone) return; 405 + if (this.loaderStartupDone)
  406 + return;
319 this.loaderStartupDone = true; 407 this.loaderStartupDone = true;
320 408
321 - // Set up base class overrides  
322 - this.prepareClassOverrides();  
323 -  
324 // Set up loader, initialises any reflection methods needed 409 // Set up loader, initialises any reflection methods needed
325 if (this.prepareLoader()) 410 if (this.prepareLoader())
326 { 411 {
327 - logger.info(String.format("LiteLoader %s starting up...", LOADER_VERSION)); 412 + logger.info(String.format("LiteLoader %s starting up...", VERSION));
328 413
329 // Print the branding version if any was provided 414 // Print the branding version if any was provided
330 if (this.branding != null) 415 if (this.branding != null)
@@ -334,23 +419,23 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -334,23 +419,23 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
334 419
335 logger.info(String.format("Java reports OS=\"%s\"", System.getProperty("os.name").toLowerCase())); 420 logger.info(String.format("Java reports OS=\"%s\"", System.getProperty("os.name").toLowerCase()));
336 421
337 - boolean searchMods = this.localProperties.getProperty("search.mods", "true").equalsIgnoreCase("true");  
338 - boolean searchProtectionDomain = this.localProperties.getProperty("search.jar", "true").equalsIgnoreCase("true");  
339 - boolean searchClassPath = this.localProperties.getProperty("search.classpath", "true").equalsIgnoreCase("true"); 422 + boolean searchMods = this.localProperties.getProperty("search.mods", "true").equalsIgnoreCase("true");
  423 + boolean searchProtectionDomain = this.localProperties.getProperty("search.jar", "true").equalsIgnoreCase("true");
  424 + boolean searchClassPath = this.localProperties.getProperty("search.classpath", "true").equalsIgnoreCase("true");
340 425
341 if (!searchMods && !searchProtectionDomain && !searchClassPath) 426 if (!searchMods && !searchProtectionDomain && !searchClassPath)
342 { 427 {
343 logger.warning("Invalid configuration, no search locations defined. Enabling all search locations."); 428 logger.warning("Invalid configuration, no search locations defined. Enabling all search locations.");
344 429
345 - this.localProperties.setProperty("search.mods", "true");  
346 - this.localProperties.setProperty("search.jar", "true"); 430 + this.localProperties.setProperty("search.mods", "true");
  431 + this.localProperties.setProperty("search.jar", "true");
347 this.localProperties.setProperty("search.classpath", "true"); 432 this.localProperties.setProperty("search.classpath", "true");
348 433
349 - searchMods = true; 434 + searchMods = true;
350 searchProtectionDomain = true; 435 searchProtectionDomain = true;
351 - searchClassPath = true; 436 + searchClassPath = true;
352 } 437 }
353 - 438 +
354 // Examines the class path and mods folder and locates loadable mods 439 // Examines the class path and mods folder and locates loadable mods
355 this.prepareMods(searchMods, searchProtectionDomain, searchClassPath); 440 this.prepareMods(searchMods, searchProtectionDomain, searchClassPath);
356 441
@@ -367,64 +452,13 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -367,64 +452,13 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
367 } 452 }
368 453
369 /** 454 /**
370 - * Do dirty non-base-clean overrides  
371 - */  
372 - private void prepareClassOverrides()  
373 - {  
374 - this.registerBaseClassOverride(ModUtilities.getObfuscatedFieldName("net.minecraft.src.CallableJVMFlags", "h", "h"), "h");  
375 - }  
376 -  
377 - /**  
378 - * Reads a base class overrride from a resource file  
379 - *  
380 - * @param binaryClassName  
381 - * @param fileName  
382 - */  
383 - private void registerBaseClassOverride(String binaryClassName, String fileName)  
384 - {  
385 - try  
386 - {  
387 - Method mDefineClass = ClassLoader.class.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class);  
388 - mDefineClass.setAccessible(true);  
389 -  
390 - InputStream resourceInputStream = LiteLoader.class.getResourceAsStream("/classes/" + fileName + ".bin");  
391 -  
392 - if (resourceInputStream != null)  
393 - {  
394 - ByteArrayOutputStream outputStream = new ByteArrayOutputStream();  
395 -  
396 - for (int readBytes = resourceInputStream.read(); readBytes >= 0; readBytes = resourceInputStream.read())  
397 - {  
398 - outputStream.write(readBytes);  
399 - }  
400 -  
401 - byte[] data = outputStream.toByteArray();  
402 -  
403 - outputStream.close();  
404 - resourceInputStream.close();  
405 -  
406 - logger.info("Defining class override for " + binaryClassName);  
407 - mDefineClass.invoke(Minecraft.class.getClassLoader(), binaryClassName, data, 0, data.length);  
408 - }  
409 - else  
410 - {  
411 - logger.info("Error defining class override for " + binaryClassName + ", file not found");  
412 - }  
413 - }  
414 - catch (Throwable th)  
415 - {  
416 - logger.log(Level.WARNING, "Error defining class override for " + binaryClassName, th);  
417 - }  
418 - }  
419 -  
420 - /**  
421 * Set up reflection methods required by the loader 455 * Set up reflection methods required by the loader
422 */ 456 */
423 private boolean prepareLoader() 457 private boolean prepareLoader()
424 { 458 {
425 try 459 try
426 { 460 {
427 - // addURL method is used by the class loader to 461 + // addURL method is used by the class loader to
428 this.mAddUrl = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); 462 this.mAddUrl = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
429 this.mAddUrl.setAccessible(true); 463 this.mAddUrl.setAccessible(true);
430 464
@@ -438,7 +472,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -438,7 +472,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
438 this.localProperties.setProperty("controls.pages", String.valueOf(this.paginateControls)); 472 this.localProperties.setProperty("controls.pages", String.valueOf(this.paginateControls));
439 473
440 this.branding = this.internalProperties.getProperty("brand", null); 474 this.branding = this.internalProperties.getProperty("brand", null);
441 - if (this.branding != null && this.branding.length() < 1) this.branding = null; 475 + if (this.branding != null && this.branding.length() < 1)
  476 + this.branding = null;
442 477
443 // Save appropriate branding in the local properties file 478 // Save appropriate branding in the local properties file
444 if (this.branding != null) 479 if (this.branding != null)
@@ -455,7 +490,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -455,7 +490,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
455 490
456 return true; 491 return true;
457 } 492 }
458 - 493 +
459 /** 494 /**
460 * @throws SecurityException 495 * @throws SecurityException
461 * @throws IOException 496 * @throws IOException
@@ -471,7 +506,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -471,7 +506,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
471 consoleHandler.setFormatter(logFormatter); 506 consoleHandler.setFormatter(logFormatter);
472 logger.addHandler(consoleHandler); 507 logger.addHandler(consoleHandler);
473 508
474 - FileHandler logFileHandler = new FileHandler(new File(Minecraft.getMinecraftDir(), "LiteLoader.txt").getAbsolutePath()); 509 + FileHandler logFileHandler = new FileHandler(new File(this.configBaseFolder, "LiteLoader.txt").getAbsolutePath());
475 logFileHandler.setFormatter(logFormatter); 510 logFileHandler.setFormatter(logFormatter);
476 logger.addHandler(logFileHandler); 511 logger.addHandler(logFileHandler);
477 } 512 }
@@ -495,7 +530,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -495,7 +530,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
495 { 530 {
496 this.internalProperties = new Properties(); 531 this.internalProperties = new Properties();
497 } 532 }
498 - 533 +
499 try 534 try
500 { 535 {
501 this.localProperties = new Properties(this.internalProperties); 536 this.localProperties = new Properties(this.internalProperties);
@@ -514,10 +549,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -514,10 +549,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
514 } 549 }
515 550
516 /** 551 /**
517 - * Get the properties stream either from the jar or from the properties file in the minecraft folder 552 + * Get the properties stream either from the jar or from the properties file
  553 + * in the minecraft folder
518 * 554 *
519 * @return 555 * @return
520 - * @throws FileNotFoundException 556 + * @throws FileNotFoundException
521 */ 557 */
522 private InputStream getLocalPropertiesStream() throws FileNotFoundException 558 private InputStream getLocalPropertiesStream() throws FileNotFoundException
523 { 559 {
@@ -525,7 +561,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -525,7 +561,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
525 { 561 {
526 return new FileInputStream(this.propertiesFile); 562 return new FileInputStream(this.propertiesFile);
527 } 563 }
528 - 564 +
529 // Otherwise read settings from the config 565 // Otherwise read settings from the config
530 return LiteLoader.class.getResourceAsStream("/liteloader.properties"); 566 return LiteLoader.class.getResourceAsStream("/liteloader.properties");
531 } 567 }
@@ -537,38 +573,63 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -537,38 +573,63 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
537 { 573 {
538 try 574 try
539 { 575 {
540 - this.localProperties.store(new FileWriter(this.propertiesFile), String.format("Properties for LiteLoader %s", LOADER_VERSION)); 576 + this.localProperties.store(new FileWriter(this.propertiesFile), String.format("Properties for LiteLoader %s", VERSION));
541 } 577 }
542 catch (Throwable th) 578 catch (Throwable th)
543 { 579 {
544 logger.log(Level.WARNING, "Error writing liteloader properties", th); 580 logger.log(Level.WARNING, "Error writing liteloader properties", th);
545 } 581 }
546 } 582 }
547 - 583 +
548 /** 584 /**
549 * Get the "mods" folder 585 * Get the "mods" folder
550 */ 586 */
551 public File getModsFolder() 587 public File getModsFolder()
552 { 588 {
553 - if (this.modsFolder == null)  
554 - {  
555 - this.modsFolder = new File(Minecraft.getMinecraftDir(), "mods");  
556 -  
557 - if (!this.modsFolder.exists() || !this.modsFolder.isDirectory())  
558 - {  
559 - try  
560 - {  
561 - // Attempt to create the "mods" folder if it does not already exist  
562 - this.modsFolder.mkdirs();  
563 - }  
564 - catch (Exception ex) {}  
565 - }  
566 - }  
567 -  
568 return this.modsFolder; 589 return this.modsFolder;
569 } 590 }
570 591
571 /** 592 /**
  593 + * Get the common (version-independent) config folder
  594 + */
  595 + public File getCommonConfigFolder()
  596 + {
  597 + return this.commonConfigFolder;
  598 + }
  599 +
  600 + /**
  601 + * Get the config folder for this version
  602 + */
  603 + public File getConfigFolder()
  604 + {
  605 + return this.versionConfigFolder;
  606 + }
  607 +
  608 + /**
  609 + * @return
  610 + */
  611 + public static File getGameDirectory()
  612 + {
  613 + return LiteLoader.gameDirectory;
  614 + }
  615 +
  616 + /**
  617 + * @return
  618 + */
  619 + public static File getAssetsDirectory()
  620 + {
  621 + return LiteLoader.assetsDirectory;
  622 + }
  623 +
  624 + /**
  625 + * @return
  626 + */
  627 + public static String getProfile()
  628 + {
  629 + return LiteLoader.profile;
  630 + }
  631 +
  632 + /**
572 * Used for crash reporting 633 * Used for crash reporting
573 * 634 *
574 * @return List of loaded mods as a string 635 * @return List of loaded mods as a string
@@ -589,9 +650,58 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -589,9 +650,58 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
589 } 650 }
590 651
591 /** 652 /**
  653 + * Used by the version upgrade code, gets a version of the mod name suitable
  654 + * for inclusion in the properties file
  655 + *
  656 + * @param modName
  657 + * @return
  658 + */
  659 + private String getModNameForConfig(Class<? extends LiteMod> modClass, String modName)
  660 + {
  661 + if (modName == null || modName.isEmpty())
  662 + {
  663 + modName = modClass.getSimpleName().toLowerCase();
  664 + }
  665 +
  666 + return String.format("version.%s", modName.toLowerCase().replaceAll("[^a-z0-9_\\-\\.]", ""));
  667 + }
  668 +
  669 + /**
  670 + * Store current revision for mod in the config file
  671 + *
  672 + * @param modKey
  673 + */
  674 + private void storeLastKnownModRevision(String modKey)
  675 + {
  676 + if (this.localProperties != null)
  677 + {
  678 + this.localProperties.setProperty(modKey, String.valueOf(LiteLoader.VERSION.getLoaderRevision()));
  679 + this.writeProperties();
  680 + }
  681 + }
  682 +
  683 + /**
  684 + * Get last know revision for mod from the config file
  685 + *
  686 + * @param modKey
  687 + * @return
  688 + */
  689 + private int getLastKnownModRevision(String modKey)
  690 + {
  691 + if (this.localProperties != null)
  692 + {
  693 + String storedRevision = this.localProperties.getProperty(modKey, "0");
  694 + return Integer.parseInt(storedRevision);
  695 + }
  696 +
  697 + return 0;
  698 + }
  699 +
  700 + /**
592 * Get a reference to a loaded mod, if the mod exists 701 * Get a reference to a loaded mod, if the mod exists
593 * 702 *
594 - * @param modName Mod's name or class name 703 + * @param modName
  704 + * Mod's name or class name
595 * @return 705 * @return
596 * @throws InvalidActivityException 706 * @throws InvalidActivityException
597 */ 707 */
@@ -607,17 +717,19 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -607,17 +717,19 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
607 { 717 {
608 throw new IllegalArgumentException("Attempted to get a reference to a mod without specifying a mod name"); 718 throw new IllegalArgumentException("Attempted to get a reference to a mod without specifying a mod name");
609 } 719 }
610 - 720 +
611 for (LiteMod mod : this.mods) 721 for (LiteMod mod : this.mods)
612 { 722 {
613 - if (modName.equalsIgnoreCase(mod.getName()) || modName.equalsIgnoreCase(mod.getClass().getSimpleName())) return (T)mod; 723 + if (modName.equalsIgnoreCase(mod.getName()) || modName.equalsIgnoreCase(mod.getClass().getSimpleName()))
  724 + return (T)mod;
614 } 725 }
615 726
616 return null; 727 return null;
617 } 728 }
618 729
619 /** 730 /**
620 - * Enumerate the java class path and "mods" folder to find mod classes, then load the classes 731 + * Enumerate the java class path and "mods" folder to find mod classes, then
  732 + * load the classes
621 */ 733 */
622 private void prepareMods(boolean searchMods, boolean searchProtectionDomain, boolean searchClassPath) 734 private void prepareMods(boolean searchMods, boolean searchProtectionDomain, boolean searchClassPath)
623 { 735 {
@@ -635,13 +747,13 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -635,13 +747,13 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
635 logger.info("Found " + modFiles.size() + " mod file(s)"); 747 logger.info("Found " + modFiles.size() + " mod file(s)");
636 } 748 }
637 } 749 }
638 - 750 +
639 // Find and enumerate classes on the class path 751 // Find and enumerate classes on the class path
640 HashMap<String, Class> modsToLoad = null; 752 HashMap<String, Class> modsToLoad = null;
641 try 753 try
642 { 754 {
643 logger.info("Enumerating class path..."); 755 logger.info("Enumerating class path...");
644 - 756 +
645 String classPath = System.getProperty("java.class.path"); 757 String classPath = System.getProperty("java.class.path");
646 String classPathSeparator = System.getProperty("path.separator"); 758 String classPathSeparator = System.getProperty("path.separator");
647 String[] classPathEntries = classPath.split(classPathSeparator); 759 String[] classPathEntries = classPath.split(classPathSeparator);
@@ -649,9 +761,10 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -649,9 +761,10 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
649 logger.info(String.format("Class path separator=\"%s\"", classPathSeparator)); 761 logger.info(String.format("Class path separator=\"%s\"", classPathSeparator));
650 logger.info(String.format("Class path entries=(\n classpathEntry=%s\n)", classPath.replace(classPathSeparator, "\n classpathEntry="))); 762 logger.info(String.format("Class path entries=(\n classpathEntry=%s\n)", classPath.replace(classPathSeparator, "\n classpathEntry=")));
651 763
652 - if (searchProtectionDomain || searchClassPath) logger.info("Discovering mods on class path..."); 764 + if (searchProtectionDomain || searchClassPath)
  765 + logger.info("Discovering mods on class path...");
653 modsToLoad = this.findModClasses(classPathEntries, modFiles, searchProtectionDomain, searchClassPath); 766 modsToLoad = this.findModClasses(classPathEntries, modFiles, searchProtectionDomain, searchClassPath);
654 - 767 +
655 logger.info("Mod class discovery completed"); 768 logger.info("Mod class discovery completed");
656 } 769 }
657 catch (Throwable th) 770 catch (Throwable th)
@@ -666,13 +779,13 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -666,13 +779,13 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
666 /** 779 /**
667 * Find mod files in the "mods" folder 780 * Find mod files in the "mods" folder
668 * 781 *
669 - * @param modFolder Folder to search  
670 - * @param modFiles List of mod files to load 782 + * @param modFolder
  783 + * Folder to search
  784 + * @param modFiles
  785 + * List of mod files to load
671 */ 786 */
672 protected void findModFiles(File modFolder, LinkedList<File> modFiles) 787 protected void findModFiles(File modFolder, LinkedList<File> modFiles)
673 { 788 {
674 - List<String> supportedVerions = Arrays.asList(SUPPORTED_VERSIONS);  
675 -  
676 for (File modFile : modFolder.listFiles(this)) 789 for (File modFile : modFolder.listFiles(this))
677 { 790 {
678 try 791 try
@@ -689,14 +802,15 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -689,14 +802,15 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
689 String strVersion = versionReader.readLine(); 802 String strVersion = versionReader.readLine();
690 versionReader.close(); 803 versionReader.close();
691 804
692 - // Only add the mod if the version matches and we were able to successfully add it to the class path  
693 - if (supportedVerions.contains(strVersion) && this.addURLToClassPath(modFile.toURI().toURL())) 805 + // Only add the mod if the version matches and we were able
  806 + // to successfully add it to the class path
  807 + if (LiteLoader.VERSION.isVersionSupported(strVersion) && this.addURLToClassPath(modFile.toURI().toURL()))
694 { 808 {
695 modFiles.add(modFile); 809 modFiles.add(modFile);
696 } 810 }
697 else 811 else
698 { 812 {
699 - logger.info("Not adding invalid or outdated mod file: " + modFile.getAbsolutePath()); 813 + logger.info("Not adding invalid or outdated mod file: " + modFile.getAbsolutePath());
700 } 814 }
701 } 815 }
702 816
@@ -709,7 +823,9 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -709,7 +823,9 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
709 } 823 }
710 } 824 }
711 825
712 - /* (non-Javadoc) 826 + /*
  827 + * (non-Javadoc)
  828 + *
713 * @see java.io.FilenameFilter#accept(java.io.File, java.lang.String) 829 * @see java.io.FilenameFilter#accept(java.io.File, java.lang.String)
714 */ 830 */
715 @Override 831 @Override
@@ -721,15 +837,18 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -721,15 +837,18 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
721 /** 837 /**
722 * Find mod classes in the class path and enumerated mod files list 838 * Find mod classes in the class path and enumerated mod files list
723 * 839 *
724 - * @param classPathEntries Java class path split into string entries 840 + * @param classPathEntries
  841 + * Java class path split into string entries
725 * @return map of classes to load 842 * @return map of classes to load
726 */ 843 */
727 private HashMap<String, Class> findModClasses(String[] classPathEntries, LinkedList<File> modFiles, boolean searchProtectionDomain, boolean searchClassPath) 844 private HashMap<String, Class> findModClasses(String[] classPathEntries, LinkedList<File> modFiles, boolean searchProtectionDomain, boolean searchClassPath)
728 { 845 {
729 - // To try to avoid loading the same mod multiple times if it appears in more than one entry in the class path, we index  
730 - // the mods by name and hopefully match only a single instance of a particular mod 846 + // To try to avoid loading the same mod multiple times if it appears in
  847 + // more than one entry in the class path, we index
  848 + // the mods by name and hopefully match only a single instance of a
  849 + // particular mod
731 HashMap<String, Class> modsToLoad = new HashMap<String, Class>(); 850 HashMap<String, Class> modsToLoad = new HashMap<String, Class>();
732 - 851 +
733 if (searchProtectionDomain) 852 if (searchProtectionDomain)
734 { 853 {
735 try 854 try
@@ -745,12 +864,13 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -745,12 +864,13 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
745 { 864 {
746 protectionDomainLocation = new URL(protectionDomainLocation.toString().substring(4, protectionDomainLocation.toString().indexOf('!'))); 865 protectionDomainLocation = new URL(protectionDomainLocation.toString().substring(4, protectionDomainLocation.toString().indexOf('!')));
747 } 866 }
748 - 867 +
749 packagePath = new File(protectionDomainLocation.toURI()); 868 packagePath = new File(protectionDomainLocation.toURI());
750 } 869 }
751 else 870 else
752 { 871 {
753 - // Fix (?) for forge and other mods which screw up the protection domain 872 + // Fix (?) for forge and other mods which screw up the
  873 + // protection domain
754 String reflectionClassPath = LiteLoader.class.getResource("/com/mumfrey/liteloader/core/LiteLoader.class").getPath(); 874 String reflectionClassPath = LiteLoader.class.getResource("/com/mumfrey/liteloader/core/LiteLoader.class").getPath();
755 875
756 if (reflectionClassPath.indexOf('!') > -1) 876 if (reflectionClassPath.indexOf('!') > -1)
@@ -774,7 +894,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -774,7 +894,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
774 modsToLoad.put(mod.getSimpleName(), mod); 894 modsToLoad.put(mod.getSimpleName(), mod);
775 } 895 }
776 896
777 - if (modClasses.size() > 0) logger.info(String.format("Found %s potential matches", modClasses.size())); 897 + if (modClasses.size() > 0)
  898 + logger.info(String.format("Found %s potential matches", modClasses.size()));
778 } 899 }
779 } 900 }
780 catch (Throwable th) 901 catch (Throwable th)
@@ -782,7 +903,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -782,7 +903,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
782 logger.warning("Error loading from local class path: " + th.getMessage()); 903 logger.warning("Error loading from local class path: " + th.getMessage());
783 } 904 }
784 } 905 }
785 - 906 +
786 if (searchClassPath) 907 if (searchClassPath)
787 { 908 {
788 // Search through the class path and find mod classes 909 // Search through the class path and find mod classes
@@ -803,7 +924,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -803,7 +924,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
803 modsToLoad.put(mod.getSimpleName(), mod); 924 modsToLoad.put(mod.getSimpleName(), mod);
804 } 925 }
805 926
806 - if (modClasses.size() > 0) logger.info(String.format("Found %s potential matches", modClasses.size())); 927 + if (modClasses.size() > 0)
  928 + logger.info(String.format("Found %s potential matches", modClasses.size()));
807 } 929 }
808 } 930 }
809 931
@@ -823,8 +945,9 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -823,8 +945,9 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
823 945
824 modsToLoad.put(mod.getSimpleName(), mod); 946 modsToLoad.put(mod.getSimpleName(), mod);
825 } 947 }
826 -  
827 - if (modClasses.size() > 0) logger.info(String.format("Found %s potential matches", modClasses.size())); 948 +
  949 + if (modClasses.size() > 0)
  950 + logger.info(String.format("Found %s potential matches", modClasses.size()));
828 } 951 }
829 952
830 return modsToLoad; 953 return modsToLoad;
@@ -833,7 +956,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -833,7 +956,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
833 /** 956 /**
834 * Create mod instances from the enumerated classes 957 * Create mod instances from the enumerated classes
835 * 958 *
836 - * @param modsToLoad List of mods to load 959 + * @param modsToLoad
  960 + * List of mods to load
837 */ 961 */
838 private void loadMods(HashMap<String, Class> modsToLoad) 962 private void loadMods(HashMap<String, Class> modsToLoad)
839 { 963 {
@@ -880,7 +1004,26 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -880,7 +1004,26 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
880 { 1004 {
881 logger.info("Initialising mod " + mod.getName() + " version " + mod.getVersion()); 1005 logger.info("Initialising mod " + mod.getName() + " version " + mod.getVersion());
882 1006
883 - mod.init(); 1007 + try
  1008 + {
  1009 + String modKey = this.getModNameForConfig(mod.getClass(), mod.getName());
  1010 + LiteLoaderVersion lastModVersion = LiteLoaderVersion.getVersionFromRevision(this.getLastKnownModRevision(modKey));
  1011 +
  1012 + if (LiteLoader.VERSION.getLoaderRevision() > lastModVersion.getLoaderRevision())
  1013 + {
  1014 + logger.info("Performing config upgrade for mod " + mod.getName() + ". Upgrading " + lastModVersion + " to " + LiteLoader.VERSION + "...");
  1015 + mod.upgradeSettings(LiteLoader.getVersion(), this.versionConfigFolder, this.inflectVersionedConfigPath(lastModVersion));
  1016 +
  1017 + this.storeLastKnownModRevision(modKey);
  1018 + logger.info("Config upgrade succeeded for mod " + mod.getName());
  1019 + }
  1020 + }
  1021 + catch (Throwable th)
  1022 + {
  1023 + logger.warning("Error performing settings upgrade for " + mod.getName() + ". Settings may not be properly migrated");
  1024 + }
  1025 +
  1026 + mod.init(this.modsFolder);
884 1027
885 if (mod instanceof Tickable) 1028 if (mod instanceof Tickable)
886 { 1029 {
@@ -891,7 +1034,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -891,7 +1034,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
891 { 1034 {
892 this.addLoopListener((GameLoopListener)mod); 1035 this.addLoopListener((GameLoopListener)mod);
893 } 1036 }
894 - 1037 +
895 if (mod instanceof InitCompleteListener) 1038 if (mod instanceof InitCompleteListener)
896 { 1039 {
897 this.addInitListener((InitCompleteListener)mod); 1040 this.addInitListener((InitCompleteListener)mod);
@@ -944,6 +1087,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -944,6 +1087,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
944 this.addPluginChannelListener((PluginChannelListener)mod); 1087 this.addPluginChannelListener((PluginChannelListener)mod);
945 } 1088 }
946 1089
  1090 + if (mod instanceof Permissible)
  1091 + {
  1092 + permissionsManager.registerPermissible((Permissible)mod);
  1093 + }
  1094 +
947 this.loadedModsList += String.format("\n - %s version %s", mod.getName(), mod.getVersion()); 1095 this.loadedModsList += String.format("\n - %s version %s", mod.getName(), mod.getVersion());
948 loadedModsCount++; 1096 loadedModsCount++;
949 } 1097 }
@@ -956,7 +1104,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -956,7 +1104,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
956 1104
957 this.loadedModsList = String.format("%s loaded mod(s)%s", loadedModsCount, this.loadedModsList); 1105 this.loadedModsList = String.format("%s loaded mod(s)%s", loadedModsCount, this.loadedModsList);
958 } 1106 }
959 - 1107 +
960 /** 1108 /**
961 * Initialise mod hooks 1109 * Initialise mod hooks
962 */ 1110 */
@@ -1005,7 +1153,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1005,7 +1153,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1005 ex.printStackTrace(); 1153 ex.printStackTrace();
1006 } 1154 }
1007 } 1155 }
1008 - 1156 +
1009 /** 1157 /**
1010 * @param tickable 1158 * @param tickable
1011 */ 1159 */
@@ -1014,7 +1162,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1014,7 +1162,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1014 if (!this.tickListeners.contains(tickable)) 1162 if (!this.tickListeners.contains(tickable))
1015 { 1163 {
1016 this.tickListeners.add(tickable); 1164 this.tickListeners.add(tickable);
1017 - if (this.loaderStartupComplete) this.initHooks(); 1165 + if (this.loaderStartupComplete)
  1166 + this.initHooks();
1018 } 1167 }
1019 } 1168 }
1020 1169
@@ -1026,7 +1175,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1026,7 +1175,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1026 if (!this.loopListeners.contains(loopListener)) 1175 if (!this.loopListeners.contains(loopListener))
1027 { 1176 {
1028 this.loopListeners.add(loopListener); 1177 this.loopListeners.add(loopListener);
1029 - if (this.loaderStartupComplete) this.initHooks(); 1178 + if (this.loaderStartupComplete)
  1179 + this.initHooks();
1030 } 1180 }
1031 } 1181 }
1032 1182
@@ -1038,10 +1188,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1038,10 +1188,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1038 if (!this.initListeners.contains(initCompleteListener)) 1188 if (!this.initListeners.contains(initCompleteListener))
1039 { 1189 {
1040 this.initListeners.add(initCompleteListener); 1190 this.initListeners.add(initCompleteListener);
1041 - if (this.loaderStartupComplete) this.initHooks(); 1191 + if (this.loaderStartupComplete)
  1192 + this.initHooks();
1042 } 1193 }
1043 } 1194 }
1044 - 1195 +
1045 /** 1196 /**
1046 * @param tickable 1197 * @param tickable
1047 */ 1198 */
@@ -1050,10 +1201,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1050,10 +1201,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1050 if (!this.renderListeners.contains(tickable)) 1201 if (!this.renderListeners.contains(tickable))
1051 { 1202 {
1052 this.renderListeners.add(tickable); 1203 this.renderListeners.add(tickable);
1053 - if (this.loaderStartupComplete) this.initHooks(); 1204 + if (this.loaderStartupComplete)
  1205 + this.initHooks();
1054 } 1206 }
1055 } 1207 }
1056 - 1208 +
1057 /** 1209 /**
1058 * @param tickable 1210 * @param tickable
1059 */ 1211 */
@@ -1062,10 +1214,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1062,10 +1214,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1062 if (!this.postRenderListeners.contains(tickable)) 1214 if (!this.postRenderListeners.contains(tickable))
1063 { 1215 {
1064 this.postRenderListeners.add(tickable); 1216 this.postRenderListeners.add(tickable);
1065 - if (this.loaderStartupComplete) this.initHooks(); 1217 + if (this.loaderStartupComplete)
  1218 + this.initHooks();
1066 } 1219 }
1067 } 1220 }
1068 - 1221 +
1069 /** 1222 /**
1070 * @param chatFilter 1223 * @param chatFilter
1071 */ 1224 */
@@ -1074,10 +1227,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1074,10 +1227,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1074 if (!this.chatFilters.contains(chatFilter)) 1227 if (!this.chatFilters.contains(chatFilter))
1075 { 1228 {
1076 this.chatFilters.add(chatFilter); 1229 this.chatFilters.add(chatFilter);
1077 - if (this.loaderStartupComplete) this.initHooks(); 1230 + if (this.loaderStartupComplete)
  1231 + this.initHooks();
1078 } 1232 }
1079 } 1233 }
1080 - 1234 +
1081 /** 1235 /**
1082 * @param chatListener 1236 * @param chatListener
1083 */ 1237 */
@@ -1086,7 +1240,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1086,7 +1240,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1086 if (!this.chatListeners.contains(chatListener)) 1240 if (!this.chatListeners.contains(chatListener))
1087 { 1241 {
1088 this.chatListeners.add(chatListener); 1242 this.chatListeners.add(chatListener);
1089 - if (this.loaderStartupComplete) this.initHooks(); 1243 + if (this.loaderStartupComplete)
  1244 + this.initHooks();
1090 } 1245 }
1091 } 1246 }
1092 1247
@@ -1098,10 +1253,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1098,10 +1253,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1098 if (!this.chatRenderListeners.contains(chatRenderListener)) 1253 if (!this.chatRenderListeners.contains(chatRenderListener))
1099 { 1254 {
1100 this.chatRenderListeners.add(chatRenderListener); 1255 this.chatRenderListeners.add(chatRenderListener);
1101 - if (this.loaderStartupComplete) this.initHooks(); 1256 + if (this.loaderStartupComplete)
  1257 + this.initHooks();
1102 } 1258 }
1103 } 1259 }
1104 - 1260 +
1105 /** 1261 /**
1106 * @param loginListener 1262 * @param loginListener
1107 */ 1263 */
@@ -1110,10 +1266,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1110,10 +1266,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1110 if (!this.preLoginListeners.contains(loginListener)) 1266 if (!this.preLoginListeners.contains(loginListener))
1111 { 1267 {
1112 this.preLoginListeners.add(loginListener); 1268 this.preLoginListeners.add(loginListener);
1113 - if (this.loaderStartupComplete) this.initHooks(); 1269 + if (this.loaderStartupComplete)
  1270 + this.initHooks();
1114 } 1271 }
1115 } 1272 }
1116 - 1273 +
1117 /** 1274 /**
1118 * @param loginListener 1275 * @param loginListener
1119 */ 1276 */
@@ -1122,10 +1279,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1122,10 +1279,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1122 if (!this.loginListeners.contains(loginListener)) 1279 if (!this.loginListeners.contains(loginListener))
1123 { 1280 {
1124 this.loginListeners.add(loginListener); 1281 this.loginListeners.add(loginListener);
1125 - if (this.loaderStartupComplete) this.initHooks(); 1282 + if (this.loaderStartupComplete)
  1283 + this.initHooks();
1126 } 1284 }
1127 } 1285 }
1128 - 1286 +
1129 /** 1287 /**
1130 * @param pluginChannelListener 1288 * @param pluginChannelListener
1131 */ 1289 */
@@ -1134,10 +1292,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1134,10 +1292,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1134 if (!this.pluginChannelListeners.contains(pluginChannelListener)) 1292 if (!this.pluginChannelListeners.contains(pluginChannelListener))
1135 { 1293 {
1136 this.pluginChannelListeners.add(pluginChannelListener); 1294 this.pluginChannelListeners.add(pluginChannelListener);
1137 - if (this.loaderStartupComplete) this.initHooks(); 1295 + if (this.loaderStartupComplete)
  1296 + this.initHooks();
1138 } 1297 }
1139 } 1298 }
1140 - 1299 +
1141 /** 1300 /**
1142 * Enumerate classes on the classpath which are subclasses of the specified 1301 * Enumerate classes on the classpath which are subclasses of the specified
1143 * class 1302 * class
@@ -1235,7 +1394,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1235,7 +1394,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1235 private static void enumerateDirectory(String prefix, Class superClass, ClassLoader classloader, LinkedList<Class> classes, File packagePath, String packageName, int depth) 1394 private static void enumerateDirectory(String prefix, Class superClass, ClassLoader classloader, LinkedList<Class> classes, File packagePath, String packageName, int depth)
1236 { 1395 {
1237 // Prevent crash due to broken recursion 1396 // Prevent crash due to broken recursion
1238 - if (depth > MAX_DISCOVERY_DEPTH) return; 1397 + if (depth > MAX_DISCOVERY_DEPTH)
  1398 + return;
1239 1399
1240 File[] classFiles = packagePath.listFiles(); 1400 File[] classFiles = packagePath.listFiles();
1241 1401
@@ -1287,7 +1447,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1287,7 +1447,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1287 /** 1447 /**
1288 * Add a URL to the Minecraft classloader class path 1448 * Add a URL to the Minecraft classloader class path
1289 * 1449 *
1290 - * @param classUrl URL of the resource to add 1450 + * @param classUrl
  1451 + * URL of the resource to add
1291 */ 1452 */
1292 private boolean addURLToClassPath(URL classUrl) 1453 private boolean addURLToClassPath(URL classUrl)
1293 { 1454 {
@@ -1307,7 +1468,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1307,7 +1468,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1307 1468
1308 return false; 1469 return false;
1309 } 1470 }
1310 - 1471 +
1311 /** 1472 /**
1312 * Late initialisation callback 1473 * Late initialisation callback
1313 */ 1474 */
@@ -1331,7 +1492,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1331,7 +1492,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1331 } 1492 }
1332 } 1493 }
1333 } 1494 }
1334 - 1495 +
1335 /** 1496 /**
1336 * Callback from the tick hook, pre render 1497 * Callback from the tick hook, pre render
1337 */ 1498 */
@@ -1345,31 +1506,33 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1345,31 +1506,33 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1345 GuiScreen parentScreen = PrivateFields.guiControlsParentScreen.get((GuiControls)this.minecraft.currentScreen); 1506 GuiScreen parentScreen = PrivateFields.guiControlsParentScreen.get((GuiControls)this.minecraft.currentScreen);
1346 this.minecraft.displayGuiScreen(new GuiControlsPaginated(parentScreen, this.minecraft.gameSettings)); 1507 this.minecraft.displayGuiScreen(new GuiControlsPaginated(parentScreen, this.minecraft.gameSettings));
1347 } 1508 }
1348 - catch (Exception ex) { } 1509 + catch (Exception ex)
  1510 + {
  1511 + }
1349 } 1512 }
1350 1513
1351 for (RenderListener renderListener : this.renderListeners) 1514 for (RenderListener renderListener : this.renderListeners)
1352 renderListener.onRender(); 1515 renderListener.onRender();
1353 } 1516 }
1354 - 1517 +
1355 /** 1518 /**
1356 * Callback from the tick hook, post render entities 1519 * Callback from the tick hook, post render entities
1357 */ 1520 */
1358 public void postRenderEntities() 1521 public void postRenderEntities()
1359 { 1522 {
1360 float partialTicks = (this.minecraftTimer != null) ? this.minecraftTimer.elapsedPartialTicks : 0.0F; 1523 float partialTicks = (this.minecraftTimer != null) ? this.minecraftTimer.elapsedPartialTicks : 0.0F;
1361 - 1524 +
1362 for (PostRenderListener renderListener : this.postRenderListeners) 1525 for (PostRenderListener renderListener : this.postRenderListeners)
1363 renderListener.onPostRenderEntities(partialTicks); 1526 renderListener.onPostRenderEntities(partialTicks);
1364 } 1527 }
1365 - 1528 +
1366 /** 1529 /**
1367 * Callback from the tick hook, post render 1530 * Callback from the tick hook, post render
1368 */ 1531 */
1369 public void postRender() 1532 public void postRender()
1370 { 1533 {
1371 float partialTicks = (this.minecraftTimer != null) ? this.minecraftTimer.elapsedPartialTicks : 0.0F; 1534 float partialTicks = (this.minecraftTimer != null) ? this.minecraftTimer.elapsedPartialTicks : 0.0F;
1372 - 1535 +
1373 for (PostRenderListener renderListener : this.postRenderListeners) 1536 for (PostRenderListener renderListener : this.postRenderListeners)
1374 renderListener.onPostRender(partialTicks); 1537 renderListener.onPostRender(partialTicks);
1375 } 1538 }
@@ -1382,7 +1545,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1382,7 +1545,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1382 for (RenderListener renderListener : this.renderListeners) 1545 for (RenderListener renderListener : this.renderListeners)
1383 renderListener.onRenderGui(this.minecraft.currentScreen); 1546 renderListener.onRenderGui(this.minecraft.currentScreen);
1384 } 1547 }
1385 - 1548 +
1386 /** 1549 /**
1387 * Called immediately after the world/camera transform is initialised 1550 * Called immediately after the world/camera transform is initialised
1388 */ 1551 */
@@ -1397,64 +1560,70 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1397,64 +1560,70 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1397 */ 1560 */
1398 public void onBeforeChatRender() 1561 public void onBeforeChatRender()
1399 { 1562 {
1400 - this.currentResolution = new ScaledResolution(this.minecraft.gameSettings, this.minecraft.displayWidth, this.minecraft.displayHeight);  
1401 - int screenWidth = this.currentResolution.getScaledWidth();  
1402 - int screenHeight = this.currentResolution.getScaledHeight();  
1403 -  
1404 - GuiNewChat chat = this.minecraft.ingameGUI.getChatGUI(); 1563 + this.currentResolution = new ScaledResolution(this.minecraft.gameSettings, this.minecraft.displayWidth, this.minecraft.displayHeight);
  1564 + int screenWidth = this.currentResolution.getScaledWidth();
  1565 + int screenHeight = this.currentResolution.getScaledHeight();
  1566 +
  1567 + GuiNewChat chat = this.minecraft.ingameGUI.getChatGUI();
1405 1568
1406 for (ChatRenderListener chatRenderListener : this.chatRenderListeners) 1569 for (ChatRenderListener chatRenderListener : this.chatRenderListeners)
1407 chatRenderListener.onPreRenderChat(screenWidth, screenHeight, chat); 1570 chatRenderListener.onPreRenderChat(screenWidth, screenHeight, chat);
1408 } 1571 }
1409 - 1572 +
1410 /** 1573 /**
1411 * Called immediately after the chat log is rendered 1574 * Called immediately after the chat log is rendered
1412 */ 1575 */
1413 public void onAfterChatRender() 1576 public void onAfterChatRender()
1414 { 1577 {
1415 - int screenWidth = this.currentResolution.getScaledWidth();  
1416 - int screenHeight = this.currentResolution.getScaledHeight();  
1417 -  
1418 - GuiNewChat chat = this.minecraft.ingameGUI.getChatGUI(); 1578 + int screenWidth = this.currentResolution.getScaledWidth();
  1579 + int screenHeight = this.currentResolution.getScaledHeight();
  1580 +
  1581 + GuiNewChat chat = this.minecraft.ingameGUI.getChatGUI();
1419 1582
1420 for (ChatRenderListener chatRenderListener : this.chatRenderListeners) 1583 for (ChatRenderListener chatRenderListener : this.chatRenderListeners)
1421 chatRenderListener.onPostRenderChat(screenWidth, screenHeight, chat); 1584 chatRenderListener.onPostRenderChat(screenWidth, screenHeight, chat);
1422 } 1585 }
1423 - 1586 +
1424 /** 1587 /**
1425 - * Callback from the tick hook, called every frame when the timer is updated 1588 + * Callback from the tick hook, called every frame when the timer is updated
1426 */ 1589 */
1427 public void onTimerUpdate() 1590 public void onTimerUpdate()
1428 { 1591 {
1429 for (GameLoopListener loopListener : this.loopListeners) 1592 for (GameLoopListener loopListener : this.loopListeners)
1430 loopListener.onRunGameLoop(this.minecraft); 1593 loopListener.onRunGameLoop(this.minecraft);
1431 } 1594 }
1432 - 1595 +
1433 /** 1596 /**
1434 * Callback from the tick hook, ticks all tickable mods 1597 * Callback from the tick hook, ticks all tickable mods
1435 * 1598 *
1436 - * @param tick True if this is a new tick (otherwise it's just a new frame) 1599 + * @param tick
  1600 + * True if this is a new tick (otherwise it's just a new frame)
1437 */ 1601 */
1438 public void onTick(Profiler profiler, boolean tick) 1602 public void onTick(Profiler profiler, boolean tick)
1439 { 1603 {
1440 float partialTicks = 0.0F; 1604 float partialTicks = 0.0F;
1441 1605
1442 - // Try to get the minecraft timer object and determine the value of the partialTicks 1606 + // Try to get the minecraft timer object and determine the value of the
  1607 + // partialTicks
1443 if (tick || this.minecraftTimer == null) 1608 if (tick || this.minecraftTimer == null)
1444 { 1609 {
1445 this.minecraftTimer = PrivateFields.minecraftTimer.get(this.minecraft); 1610 this.minecraftTimer = PrivateFields.minecraftTimer.get(this.minecraft);
1446 } 1611 }
1447 - 1612 +
1448 // Hooray, we got the timer reference 1613 // Hooray, we got the timer reference
1449 if (this.minecraftTimer != null) 1614 if (this.minecraftTimer != null)
1450 { 1615 {
1451 partialTicks = this.minecraftTimer.renderPartialTicks; 1616 partialTicks = this.minecraftTimer.renderPartialTicks;
1452 tick = this.minecraftTimer.elapsedTicks > 0; 1617 tick = this.minecraftTimer.elapsedTicks > 0;
1453 } 1618 }
1454 - 1619 +
1455 // Flag indicates whether we are in game at the moment 1620 // Flag indicates whether we are in game at the moment
1456 boolean inGame = this.minecraft.renderViewEntity != null && this.minecraft.renderViewEntity.worldObj != null; 1621 boolean inGame = this.minecraft.renderViewEntity != null && this.minecraft.renderViewEntity.worldObj != null;
1457 1622
  1623 + // Tick the permissions manager
  1624 + if (tick)
  1625 + permissionsManager.onTick(this.minecraft, partialTicks, inGame);
  1626 +
1458 // Iterate tickable mods 1627 // Iterate tickable mods
1459 for (Tickable tickable : this.tickListeners) 1628 for (Tickable tickable : this.tickListeners)
1460 { 1629 {
@@ -1472,18 +1641,25 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1472,18 +1641,25 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1472 */ 1641 */
1473 public boolean onChat(Packet3Chat chatPacket) 1642 public boolean onChat(Packet3Chat chatPacket)
1474 { 1643 {
1475 - // Chat filters get a stab at the chat first, if any filter returns false the chat is discarded 1644 + if (chatPacket.message == null)
  1645 + return true;
  1646 +
  1647 + ChatMessageComponent chat = ChatMessageComponent.func_111078_c(chatPacket.message);
  1648 + String message = chat.func_111068_a(true);
  1649 +
  1650 + // Chat filters get a stab at the chat first, if any filter returns
  1651 + // false the chat is discarded
1476 for (ChatFilter chatFilter : this.chatFilters) 1652 for (ChatFilter chatFilter : this.chatFilters)
1477 - if (!chatFilter.onChat(chatPacket)) 1653 + if (!chatFilter.onChat(chatPacket, chat, message))
1478 return false; 1654 return false;
1479 1655
1480 // Chat listeners get the chat if no filter removed it 1656 // Chat listeners get the chat if no filter removed it
1481 for (ChatListener chatListener : this.chatListeners) 1657 for (ChatListener chatListener : this.chatListeners)
1482 - chatListener.onChat(chatPacket.message); 1658 + chatListener.onChat(chat, message);
1483 1659
1484 return true; 1660 return true;
1485 } 1661 }
1486 - 1662 +
1487 /** 1663 /**
1488 * Pre-login callback from the login hook 1664 * Pre-login callback from the login hook
1489 * 1665 *
@@ -1511,6 +1687,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1511,6 +1687,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1511 */ 1687 */
1512 public void onConnectToServer(NetHandler netHandler, Packet1Login loginPacket) 1688 public void onConnectToServer(NetHandler netHandler, Packet1Login loginPacket)
1513 { 1689 {
  1690 + permissionsManager.onLogin(netHandler, loginPacket);
  1691 +
1514 for (LoginListener loginListener : this.loginListeners) 1692 for (LoginListener loginListener : this.loginListeners)
1515 loginListener.onLogin(netHandler, loginPacket); 1693 loginListener.onLogin(netHandler, loginPacket);
1516 1694
@@ -1526,13 +1704,23 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1526,13 +1704,23 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1526 { 1704 {
1527 if (hookPluginChannels != null && hookPluginChannels.channel != null && this.pluginChannels.containsKey(hookPluginChannels.channel)) 1705 if (hookPluginChannels != null && hookPluginChannels.channel != null && this.pluginChannels.containsKey(hookPluginChannels.channel))
1528 { 1706 {
  1707 + try
  1708 + {
  1709 + permissionsManager.onCustomPayload(hookPluginChannels.channel, hookPluginChannels.length, hookPluginChannels.data);
  1710 + }
  1711 + catch (Exception ex)
  1712 + {
  1713 + }
  1714 +
1529 for (PluginChannelListener pluginChannelListener : this.pluginChannels.get(hookPluginChannels.channel)) 1715 for (PluginChannelListener pluginChannelListener : this.pluginChannels.get(hookPluginChannels.channel))
1530 { 1716 {
1531 try 1717 try
1532 { 1718 {
1533 pluginChannelListener.onCustomPayload(hookPluginChannels.channel, hookPluginChannels.length, hookPluginChannels.data); 1719 pluginChannelListener.onCustomPayload(hookPluginChannels.channel, hookPluginChannels.length, hookPluginChannels.data);
1534 } 1720 }
1535 - catch (Exception ex) {} 1721 + catch (Exception ex)
  1722 + {
  1723 + }
1536 } 1724 }
1537 } 1725 }
1538 } 1726 }
@@ -1540,8 +1728,10 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1540,8 +1728,10 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1540 /** 1728 /**
1541 * Delegate to ModUtilities.sendPluginChannelMessage 1729 * Delegate to ModUtilities.sendPluginChannelMessage
1542 * 1730 *
1543 - * @param channel Channel to send data to  
1544 - * @param data Data to send 1731 + * @param channel
  1732 + * Channel to send data to
  1733 + * @param data
  1734 + * Data to send
1545 */ 1735 */
1546 public void sendPluginChannelMessage(String channel, byte[] data) 1736 public void sendPluginChannelMessage(String channel, byte[] data)
1547 { 1737 {
@@ -1549,35 +1739,22 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1549,35 +1739,22 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1549 } 1739 }
1550 1740
1551 /** 1741 /**
1552 - * Query loaded mods for registered channels 1742 + * Query loaded mods for registered channels
1553 */ 1743 */
1554 protected void setupPluginChannels() 1744 protected void setupPluginChannels()
1555 { 1745 {
1556 // Clear any channels from before 1746 // Clear any channels from before
1557 this.pluginChannels.clear(); 1747 this.pluginChannels.clear();
1558 1748
  1749 + // Add the permissions manager channels
  1750 + this.addPluginChannelsFor(permissionsManager);
  1751 +
1559 // Enumerate mods for plugin channels 1752 // Enumerate mods for plugin channels
1560 for (PluginChannelListener pluginChannelListener : this.pluginChannelListeners) 1753 for (PluginChannelListener pluginChannelListener : this.pluginChannelListeners)
1561 { 1754 {
1562 - List<String> channels = pluginChannelListener.getChannels();  
1563 -  
1564 - if (channels != null)  
1565 - {  
1566 - for (String channel : channels)  
1567 - {  
1568 - if (channel.length() > 16 || channel.toUpperCase().equals("REGISTER") || channel.toUpperCase().equals("UNREGISTER"))  
1569 - continue;  
1570 -  
1571 - if (!this.pluginChannels.containsKey(channel))  
1572 - {  
1573 - this.pluginChannels.put(channel, new LinkedList<PluginChannelListener>());  
1574 - }  
1575 -  
1576 - this.pluginChannels.get(channel).add(pluginChannelListener);  
1577 - }  
1578 - } 1755 + this.addPluginChannelsFor(pluginChannelListener);
1579 } 1756 }
1580 - 1757 +
1581 // If any mods have registered channels, send the REGISTER packet 1758 // If any mods have registered channels, send the REGISTER packet
1582 if (this.pluginChannels.keySet().size() > 0) 1759 if (this.pluginChannels.keySet().size() > 0)
1583 { 1760 {
@@ -1586,7 +1763,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1586,7 +1763,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1586 1763
1587 for (String channel : this.pluginChannels.keySet()) 1764 for (String channel : this.pluginChannels.keySet())
1588 { 1765 {
1589 - if (separator) channelList.append("\u0000"); 1766 + if (separator)
  1767 + channelList.append("\u0000");
1590 channelList.append(channel); 1768 channelList.append(channel);
1591 separator = true; 1769 separator = true;
1592 } 1770 }
@@ -1596,18 +1774,53 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1596,18 +1774,53 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1596 this.sendPluginChannelMessage("REGISTER", registrationData); 1774 this.sendPluginChannelMessage("REGISTER", registrationData);
1597 } 1775 }
1598 } 1776 }
1599 -  
1600 - /* (non-Javadoc)  
1601 - * @see net.minecraft.src.IPlayerUsage#addServerStatsToSnooper(net.minecraft.src.PlayerUsageSnooper) 1777 +
  1778 + /**
  1779 + * Adds plugin channels for the specified listener to the local channels
  1780 + * collection
  1781 + *
  1782 + * @param pluginChannelListener
  1783 + */
  1784 + private void addPluginChannelsFor(PluginChannelListener pluginChannelListener)
  1785 + {
  1786 + List<String> channels = pluginChannelListener.getChannels();
  1787 +
  1788 + if (channels != null)
  1789 + {
  1790 + for (String channel : channels)
  1791 + {
  1792 + if (channel.length() > 16 || channel.toUpperCase().equals("REGISTER") || channel.toUpperCase().equals("UNREGISTER"))
  1793 + continue;
  1794 +
  1795 + if (!this.pluginChannels.containsKey(channel))
  1796 + {
  1797 + this.pluginChannels.put(channel, new LinkedList<PluginChannelListener>());
  1798 + }
  1799 +
  1800 + this.pluginChannels.get(channel).add(pluginChannelListener);
  1801 + }
  1802 + }
  1803 + }
  1804 +
  1805 + /*
  1806 + * (non-Javadoc)
  1807 + *
  1808 + * @see
  1809 + * net.minecraft.src.IPlayerUsage#addServerStatsToSnooper(net.minecraft.
  1810 + * src.PlayerUsageSnooper)
1602 */ 1811 */
1603 @Override 1812 @Override
1604 public void addServerStatsToSnooper(PlayerUsageSnooper var1) 1813 public void addServerStatsToSnooper(PlayerUsageSnooper var1)
1605 { 1814 {
1606 this.minecraft.addServerStatsToSnooper(var1); 1815 this.minecraft.addServerStatsToSnooper(var1);
1607 } 1816 }
1608 -  
1609 - /* (non-Javadoc)  
1610 - * @see net.minecraft.src.IPlayerUsage#addServerTypeToSnooper(net.minecraft.src.PlayerUsageSnooper) 1817 +
  1818 + /*
  1819 + * (non-Javadoc)
  1820 + *
  1821 + * @see
  1822 + * net.minecraft.src.IPlayerUsage#addServerTypeToSnooper(net.minecraft.src
  1823 + * .PlayerUsageSnooper)
1611 */ 1824 */
1612 @Override 1825 @Override
1613 public void addServerTypeToSnooper(PlayerUsageSnooper var1) 1826 public void addServerTypeToSnooper(PlayerUsageSnooper var1)
@@ -1615,8 +1828,10 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1615,8 +1828,10 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1615 this.sanityCheck(); 1828 this.sanityCheck();
1616 this.minecraft.addServerTypeToSnooper(var1); 1829 this.minecraft.addServerTypeToSnooper(var1);
1617 } 1830 }
1618 -  
1619 - /* (non-Javadoc) 1831 +
  1832 + /*
  1833 + * (non-Javadoc)
  1834 + *
1620 * @see net.minecraft.src.IPlayerUsage#isSnooperEnabled() 1835 * @see net.minecraft.src.IPlayerUsage#isSnooperEnabled()
1621 */ 1836 */
1622 @Override 1837 @Override
@@ -1624,8 +1839,10 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage @@ -1624,8 +1839,10 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1624 { 1839 {
1625 return this.minecraft.isSnooperEnabled(); 1840 return this.minecraft.isSnooperEnabled();
1626 } 1841 }
1627 -  
1628 - /* (non-Javadoc) 1842 +
  1843 + /*
  1844 + * (non-Javadoc)
  1845 + *
1629 * @see net.minecraft.src.IPlayerUsage#getLogAgent() 1846 * @see net.minecraft.src.IPlayerUsage#getLogAgent()
1630 */ 1847 */
1631 @Override 1848 @Override
java/com/mumfrey/liteloader/core/LiteLoaderVersion.java 0 → 100644
  1 +package com.mumfrey.liteloader.core;
  2 +
  3 +import java.util.HashSet;
  4 +import java.util.Set;
  5 +
  6 +/**
  7 + * LiteLoader version table
  8 + *
  9 + * @author Adam Mummery-Smith
  10 + * @version 1.6.2
  11 + */
  12 +public enum LiteLoaderVersion
  13 +{
  14 + LEGACY(0, "-", "-", "-"),
  15 + MC_1_6_1_R0(11, "1.6.1", "1.6.1", "1.6.1", "1.6.r1"),
  16 + MC_1_6_2_R0(12, "1.6.2", "1.6.2", "1.6.2", "1.6.r2");
  17 +
  18 + private int revision;
  19 +
  20 + private String minecraftVersion;
  21 +
  22 + private String loaderVersion;
  23 +
  24 + private Set<String> supportedVersions = new HashSet<String>();
  25 +
  26 + private LiteLoaderVersion(int revision, String minecraftVersion, String loaderVersion, String... supportedVersions)
  27 + {
  28 + this.revision = revision;
  29 + this.minecraftVersion = minecraftVersion;
  30 + this.loaderVersion = loaderVersion;
  31 +
  32 + for (String supportedVersion : supportedVersions)
  33 + this.supportedVersions.add(supportedVersion);
  34 + }
  35 +
  36 + public int getLoaderRevision()
  37 + {
  38 + return this.revision;
  39 + }
  40 +
  41 + public String getMinecraftVersion()
  42 + {
  43 + return this.minecraftVersion;
  44 + }
  45 +
  46 + public String getLoaderVersion()
  47 + {
  48 + return this.loaderVersion;
  49 + }
  50 +
  51 + public static LiteLoaderVersion getVersionFromRevision(int revision)
  52 + {
  53 + for (LiteLoaderVersion version : LiteLoaderVersion.values())
  54 + {
  55 + if (version.getLoaderRevision() == revision)
  56 + return version;
  57 + }
  58 +
  59 + return LiteLoaderVersion.LEGACY;
  60 + }
  61 +
  62 + public boolean isVersionSupported(String version)
  63 + {
  64 + return this.supportedVersions.contains(version);
  65 + }
  66 +
  67 + @Override
  68 + public String toString()
  69 + {
  70 + return this == LiteLoaderVersion.LEGACY ? "Unknown" : this.loaderVersion;
  71 + }
  72 +}
java/com/mumfrey/liteloader/gui/GuiControlsPaginated.java
@@ -6,8 +6,8 @@ import net.minecraft.src.GameSettings; @@ -6,8 +6,8 @@ import net.minecraft.src.GameSettings;
6 import net.minecraft.src.GuiButton; 6 import net.minecraft.src.GuiButton;
7 import net.minecraft.src.GuiScreen; 7 import net.minecraft.src.GuiScreen;
8 import net.minecraft.src.GuiSmallButton; 8 import net.minecraft.src.GuiSmallButton;
  9 +import net.minecraft.src.I18n;
9 import net.minecraft.src.KeyBinding; 10 import net.minecraft.src.KeyBinding;
10 -import net.minecraft.src.StringTranslate;  
11 11
12 /** 12 /**
13 * Extended "Controls" screen with pages 13 * Extended "Controls" screen with pages
@@ -83,7 +83,6 @@ public class GuiControlsPaginated extends GuiScreen @@ -83,7 +83,6 @@ public class GuiControlsPaginated extends GuiScreen
83 @Override 83 @Override
84 public void initGui() 84 public void initGui()
85 { 85 {
86 - StringTranslate stringtranslate = StringTranslate.getInstance();  
87 this.getLegacyControlList().clear(); 86 this.getLegacyControlList().clear();
88 87
89 int oldControlsPerPage = this.controlsPerPage; 88 int oldControlsPerPage = this.controlsPerPage;
@@ -106,17 +105,17 @@ public class GuiControlsPaginated extends GuiScreen @@ -106,17 +105,17 @@ public class GuiControlsPaginated extends GuiScreen
106 { 105 {
107 this.getLegacyControlList().add(this.btnNext = new GuiButton(201, this.getWidth() / 2 - 51, buttonY, 50, 20, ">>")); 106 this.getLegacyControlList().add(this.btnNext = new GuiButton(201, this.getWidth() / 2 - 51, buttonY, 50, 20, ">>"));
108 this.getLegacyControlList().add(this.btnPrevious = new GuiButton(202, this.getWidth() / 2 - 103, buttonY, 50, 20, "<<")); 107 this.getLegacyControlList().add(this.btnPrevious = new GuiButton(202, this.getWidth() / 2 - 103, buttonY, 50, 20, "<<"));
109 - this.getLegacyControlList().add(new GuiButton(200, this.getWidth() / 2 + 1, buttonY, 100, 20, stringtranslate.translateKey("gui.done"))); 108 + this.getLegacyControlList().add(new GuiButton(200, this.getWidth() / 2 + 1, buttonY, 100, 20, I18n.func_135053_a("gui.done")));
110 109
111 this.btnNext.enabled = this.startIndex < this.endIndex; 110 this.btnNext.enabled = this.startIndex < this.endIndex;
112 this.btnPrevious.enabled = this.startIndex > 0; 111 this.btnPrevious.enabled = this.startIndex > 0;
113 } 112 }
114 else 113 else
115 { 114 {
116 - this.getLegacyControlList().add(new GuiButton(200, this.getWidth() / 2 - 100, buttonY, stringtranslate.translateKey("gui.done"))); 115 + this.getLegacyControlList().add(new GuiButton(200, this.getWidth() / 2 - 100, buttonY, I18n.func_135053_a("gui.done")));
117 } 116 }
118 117
119 - this.screenTitle = stringtranslate.translateKey("controls.title"); 118 + this.screenTitle = I18n.func_135053_a("controls.title");
120 } 119 }
121 120
122 /** 121 /**
java/com/mumfrey/liteloader/permissions/LocalPermissions.java 0 → 100644
  1 +package com.mumfrey.liteloader.permissions;
  2 +
  3 +
  4 +public class LocalPermissions implements Permissions
  5 +{
  6 + @Override
  7 + public boolean getPermissionSet(String permission)
  8 + {
  9 + return true;
  10 + }
  11 +
  12 + @Override
  13 + public boolean getHasPermission(String permission)
  14 + {
  15 + return true;
  16 + }
  17 +
  18 + @Override
  19 + public boolean getHasPermission(String permission, boolean defaultValue)
  20 + {
  21 + return defaultValue;
  22 + }
  23 +
  24 +}
java/com/mumfrey/liteloader/permissions/PermissibleAllMods.java 0 → 100644
  1 +package com.mumfrey.liteloader.permissions;
  2 +
  3 +import java.io.File;
  4 +import java.util.HashSet;
  5 +import java.util.Set;
  6 +
  7 +import com.mumfrey.liteloader.Permissible;
  8 +
  9 +public class PermissibleAllMods implements Permissible
  10 +{
  11 + private Set<Permissible> permissibles = new HashSet<Permissible>();
  12 +
  13 + public void addPermissible(Permissible permissible)
  14 + {
  15 + this.permissibles.add(permissible);
  16 + }
  17 +
  18 + @Override
  19 + public String getName()
  20 + {
  21 + return "All Mods";
  22 + }
  23 +
  24 + @Override
  25 + public String getVersion()
  26 + {
  27 + return "0.0";
  28 + }
  29 +
  30 + @Override
  31 + public void init(File configPath)
  32 + {
  33 + }
  34 +
  35 + @Override
  36 + public void upgradeSettings(String version, File configPath, File oldConfigPath)
  37 + {
  38 + }
  39 +
  40 + @Override
  41 + public String getPermissibleModName()
  42 + {
  43 + return "all";
  44 + }
  45 +
  46 + @Override
  47 + public float getPermissibleModVersion()
  48 + {
  49 + return 0.0F;
  50 + }
  51 +
  52 + @Override
  53 + public void registerPermissions(PermissionsManagerClient permissionsManager)
  54 + {
  55 + }
  56 +
  57 + @Override
  58 + public void onPermissionsCleared(PermissionsManager manager)
  59 + {
  60 + for (Permissible permissible : this.permissibles)
  61 + permissible.onPermissionsCleared(manager);
  62 + }
  63 +
  64 + @Override
  65 + public void onPermissionsChanged(PermissionsManager manager)
  66 + {
  67 + for (Permissible permissible : this.permissibles)
  68 + permissible.onPermissionsChanged(manager);
  69 + }
  70 +}
java/com/mumfrey/liteloader/permissions/Permission.java 0 → 100644
  1 +package com.mumfrey.liteloader.permissions;
  2 +
  3 +import java.util.Hashtable;
  4 +import java.util.Map;
  5 +
  6 +/**
  7 + * Class which represents a permission node
  8 + *
  9 + * @author Adam Mummery-Smith
  10 + */
  11 +public class Permission
  12 +{
  13 + /**
  14 + * True if this node is the root of the permission tree
  15 + */
  16 + private final boolean isRootNode;
  17 +
  18 + /**
  19 + * True if this node is a wildcard node (can match any query)
  20 + */
  21 + private final boolean isWildcardNode;
  22 +
  23 + /**
  24 + * Node name
  25 + */
  26 + private final String nodeName;
  27 +
  28 + /**
  29 + * Nodes which are children of this node
  30 + */
  31 + private final Map<String, Permission> childNodes = new Hashtable<String, Permission>();
  32 +
  33 + /**
  34 + * Node value
  35 + */
  36 + private boolean value;
  37 +
  38 + /**
  39 + * Create a new root node
  40 + */
  41 + public Permission()
  42 + {
  43 + this.isRootNode = true;
  44 + this.isWildcardNode = false;
  45 + this.value = true;
  46 + this.nodeName = "root";
  47 + }
  48 +
  49 + /**
  50 + * Create a new child node with the specified name and value
  51 + *
  52 + * @param permissionName Name of the permission node
  53 + * @param value Initial value for the permission node
  54 + */
  55 + public Permission(String permissionName, boolean value)
  56 + {
  57 + this.isRootNode = false;
  58 + this.isWildcardNode = permissionName.equals("*");
  59 + this.value = value;
  60 + this.nodeName = permissionName;
  61 + }
  62 +
  63 + /**
  64 + * Create a new child node with the specified name
  65 + *
  66 + * @param permissionName Name of the permission node
  67 + */
  68 + public Permission(String permissionName)
  69 + {
  70 + this(permissionName, true);
  71 + }
  72 +
  73 + /**
  74 + * Get whether this node is a root node (read only)
  75 + *
  76 + * @return
  77 + */
  78 + public boolean isRoot()
  79 + {
  80 + return this.isRootNode;
  81 + }
  82 +
  83 + /**
  84 + * Get whether this node is a wildcard node
  85 + *
  86 + * @return
  87 + */
  88 + public boolean isWildcard()
  89 + {
  90 + return this.isWildcardNode;
  91 + }
  92 +
  93 + /**
  94 + * Get the name of this permission node
  95 + *
  96 + * @return
  97 + */
  98 + public String getName()
  99 + {
  100 + return this.nodeName;
  101 + }
  102 +
  103 + /**
  104 + * Get the value of this permission node
  105 + *
  106 + * @return
  107 + */
  108 + public boolean getValue()
  109 + {
  110 + return this.value;
  111 + }
  112 +
  113 + /**
  114 + * Set the value of this permission node
  115 + *
  116 + * @param newValue
  117 + */
  118 + public void setValue(boolean newValue)
  119 + {
  120 + this.value = newValue;
  121 + }
  122 +
  123 + /**
  124 + * Get the specified node name
  125 + *
  126 + * @param name
  127 + * @return
  128 + */
  129 + public Permission getPermission(String name)
  130 + {
  131 + Permission fallback = (this.isWildcardNode) ? this : null;
  132 +
  133 + if (name.indexOf('.') > -1)
  134 + {
  135 + String head = name.substring(0, name.indexOf('.'));
  136 + String tail = name.substring(name.indexOf('.') + 1);
  137 +
  138 + Permission child = this.getPermission(head);
  139 +
  140 + if (child != null)
  141 + {
  142 + return child.getPermission(tail);
  143 + }
  144 + }
  145 + else if (this.childNodes.containsKey(name))
  146 + {
  147 + return this.childNodes.get(name);
  148 + }
  149 +
  150 + for (Permission childPermission : this.childNodes.values())
  151 + {
  152 + if (childPermission.isWildcard())
  153 + {
  154 + return childPermission;
  155 + }
  156 + }
  157 +
  158 + return fallback;
  159 + }
  160 +
  161 + /**
  162 + * Set the specified node name
  163 + *
  164 + * @param name
  165 + * @return
  166 + */
  167 + public Permission setPermission(String name)
  168 + {
  169 + return this.setPermission(name, true);
  170 + }
  171 +
  172 + /**
  173 + * Set the specified permission to the specified value
  174 + *
  175 + * @param name
  176 + * @param value
  177 + * @return
  178 + */
  179 + public Permission setPermission(String name, boolean value)
  180 + {
  181 + if (name.indexOf('.') > -1)
  182 + {
  183 + String head = name.substring(0, name.indexOf('.'));
  184 + String tail = name.substring(name.indexOf('.') + 1);
  185 +
  186 + Permission child = this.setPermission(head, false);
  187 + return child.setPermission(tail, value);
  188 + }
  189 +
  190 + Permission child = this.getPermission(name);
  191 +
  192 + if (child == null || child.isWildcard())
  193 + {
  194 + child = new Permission(name, value);
  195 + this.childNodes.put(child.getName(), child);
  196 + }
  197 + else
  198 + {
  199 + child.setValue(value | child.value);
  200 + }
  201 +
  202 + return child;
  203 + }
  204 +
  205 + /**
  206 + * Sets a permission and also explicitly sets the permission value, this allows negated permissions to be set
  207 + *
  208 + * @param name
  209 + * @param value
  210 + * @return
  211 + */
  212 + public Permission setPermissionAndValue(String name, boolean value)
  213 + {
  214 + Permission permission = this.setPermission(name, value);
  215 + permission.setValue(value);
  216 + return permission;
  217 + }
  218 +
  219 + /**
  220 + * Check whether the specified permission is set
  221 + *
  222 + * @param name
  223 + * @param value
  224 + * @return
  225 + */
  226 + public boolean isSet(String name, boolean value)
  227 + {
  228 + Permission child = this.getPermission(name);
  229 + return child == null ? value : child.getValue();
  230 + }
  231 +}
java/com/mumfrey/liteloader/permissions/Permissions.java 0 → 100644
  1 +package com.mumfrey.liteloader.permissions;
  2 +
  3 +/**
  4 + * Represents a set of permissions assigned by an authority
  5 + *
  6 + * @author Adam Mummery-Smith
  7 + */
  8 +public interface Permissions
  9 +{
  10 + /**
  11 + * Returns true if the specified permission is set in this permission container
  12 + *
  13 + * @param permission Name of the permission to test for
  14 + * @return True if the permission exists in this set
  15 + */
  16 + public abstract boolean getPermissionSet(String permission);
  17 +
  18 + /**
  19 + * Returns true if the authority says we have this permission or false if the permission is denied or not set
  20 + *
  21 + * @param permission Name of the permission to test for
  22 + * @return
  23 + */
  24 + public abstract boolean getHasPermission(String permission);
  25 +
  26 + /**
  27 + * Returns true if the authority says we have this permission or if the permission is not specified by the authority returns the default value
  28 + *
  29 + * @param permission Name of the permission to test for
  30 + * @param defaultValue Value to return if the permission is NOT specified by the authority
  31 + *
  32 + * @return State of the authority permission or default value if not specified
  33 + */
  34 + public abstract boolean getHasPermission(String permission, boolean defaultValue);
  35 +}
java/com/mumfrey/liteloader/permissions/PermissionsManager.java 0 → 100644
  1 +package com.mumfrey.liteloader.permissions;
  2 +
  3 +import java.util.List;
  4 +
  5 +import com.mumfrey.liteloader.Permissible;
  6 +
  7 +import net.minecraft.src.Minecraft;
  8 +import net.minecraft.src.NetHandler;
  9 +import net.minecraft.src.Packet1Login;
  10 +
  11 +/**
  12 + * Interface for permissions manager implementations
  13 + *
  14 + * @author Adam Mummery-Smith
  15 + */
  16 +public interface PermissionsManager
  17 +{
  18 + /**
  19 + * Get the underlying permissions node for this manager for the specified mod
  20 + *
  21 + * @param modName Mod to fetch permissions for
  22 + * @return
  23 + */
  24 + public abstract Permissions getPermissions(Permissible mod);
  25 +
  26 + /**
  27 + * Get the time the permissions for the specified mod were last updated
  28 + *
  29 + * @param mod Mod to check for
  30 + * @return Timestamp when the permissions were last updated
  31 + */
  32 + public abstract Long getPermissionUpdateTime(Permissible mod);
  33 +
  34 + /**
  35 + * Handler for login event, should be called when connecting to a new server. Clears the replicated
  36 + * permissions ready to receive new permissions from the server
  37 + *
  38 + * @param netHandler
  39 + * @param loginPacket
  40 + */
  41 + public abstract void onLogin(NetHandler netHandler, Packet1Login loginPacket);
  42 +
  43 + /**
  44 + * Handler for tick event
  45 + *
  46 + * @param minecraft
  47 + * @param partialTicks
  48 + * @param inGame
  49 + */
  50 + public abstract void onTick(Minecraft minecraft, float partialTicks, boolean inGame);
  51 +
  52 + /**
  53 + * Handler for custom payload
  54 + *
  55 + * @param channel
  56 + * @param length
  57 + * @param data
  58 + */
  59 + public abstract void onCustomPayload(String channel, int length, byte[] data);
  60 +
  61 + /**
  62 + * LiteLoader support, gets the list of plugin channels to listen on
  63 + *
  64 + * @return
  65 + */
  66 + public abstract List<String> getChannels();
  67 +
  68 + /**
  69 + * Register a new event listener, the registered object will receive callbacks for permissions events
  70 + *
  71 + * @param permissible
  72 + */
  73 + public abstract void registerPermissible(Permissible permissible);
  74 +
  75 + /**
  76 + * Perform any necessary validation to check for a tamper condition, can and should be called from as
  77 + * many places as possible
  78 + */
  79 + public abstract void tamperCheck();
  80 +}
java/com/mumfrey/liteloader/permissions/PermissionsManagerClient.java 0 → 100644
  1 +package com.mumfrey.liteloader.permissions;
  2 +
  3 +import java.io.File;
  4 +import java.util.Arrays;
  5 +import java.util.HashMap;
  6 +import java.util.HashSet;
  7 +import java.util.List;
  8 +import java.util.Map;
  9 +import java.util.Set;
  10 +import java.util.TreeSet;
  11 +
  12 +import net.eq2online.permissions.ReplicatedPermissionsContainer;
  13 +import net.minecraft.src.Minecraft;
  14 +import net.minecraft.src.NetHandler;
  15 +import net.minecraft.src.Packet1Login;
  16 +
  17 +import com.mumfrey.liteloader.Permissible;
  18 +import com.mumfrey.liteloader.PluginChannelListener;
  19 +import com.mumfrey.liteloader.util.ModUtilities;
  20 +
  21 +/**
  22 + * This class manages permissions on the client, it is a singleton class which can manage permissions for multiple
  23 + * client mods. It manages the client/server communication used to replicate permissions and serves as a hub for
  24 + * permissions objects which keep track of the permissions available on the client
  25 + *
  26 + * @author Adam Mummery-Smith
  27 + */
  28 +public class PermissionsManagerClient implements PermissionsManager, PluginChannelListener
  29 +{
  30 + /**
  31 + * Singleton instance of the client permissions manager
  32 + */
  33 + private static PermissionsManagerClient instance;
  34 +
  35 + /**
  36 + * Permissions permissible which is a proxy for permissions that are common to all mods
  37 + */
  38 + private static Permissible allMods = new PermissibleAllMods();
  39 +
  40 + /**
  41 + * Minecraft instance
  42 + */
  43 + private Minecraft minecraft;
  44 +
  45 + /**
  46 + * List of registered client mods supporting permissions
  47 + */
  48 + private Map<String, Permissible> registeredClientMods = new HashMap<String, Permissible>();
  49 +
  50 + /**
  51 + * List of registered client permissions, grouped by mod
  52 + */
  53 + private Map<Permissible, TreeSet<String>> registeredClientPermissions = new HashMap<Permissible, TreeSet<String>>();
  54 +
  55 + /**
  56 + * Objects which listen to events generated by this object
  57 + */
  58 + private Set<Permissible> permissibles = new HashSet<Permissible>();
  59 +
  60 + /**
  61 + * Local permissions, used when server permissions are not available
  62 + */
  63 + private LocalPermissions localPermissions = new LocalPermissions();
  64 +
  65 + /**
  66 + * Server permissions, indexed by mod
  67 + */
  68 + private Map<String, ServerPermissions> serverPermissions = new HashMap<String, ServerPermissions>();
  69 +
  70 + /**
  71 + * Last time onTick was called, used to detect tamper condition if no ticks are being received
  72 + */
  73 + private long lastTickTime = System.currentTimeMillis();
  74 +
  75 + /**
  76 + * Delay counter for when joining a server
  77 + */
  78 + private int loginRegisterTicks = 0;
  79 +
  80 + private int menuTicks = 0;
  81 +
  82 + /**
  83 + * Get a reference to the singleton instance of the client permissions manager
  84 + *
  85 + * @return
  86 + */
  87 + public static PermissionsManagerClient getInstance()
  88 + {
  89 + if (instance == null)
  90 + {
  91 + instance = new PermissionsManagerClient();
  92 + }
  93 +
  94 + return instance;
  95 + }
  96 +
  97 + /**
  98 + * Private .ctor, for singleton pattern
  99 + */
  100 + private PermissionsManagerClient()
  101 + {
  102 + this.registerClientMod("all", allMods);
  103 + }
  104 +
  105 + /* (non-Javadoc)
  106 + * @see net.eq2online.permissions.PermissionsManager#getPermissions(java.lang.String)
  107 + */
  108 + @Override
  109 + public Permissions getPermissions(Permissible mod)
  110 + {
  111 + if (mod == null) mod = allMods;
  112 + String modName = mod.getPermissibleModName();
  113 +
  114 + ServerPermissions modPermissions = this.serverPermissions.get(modName);
  115 + return modPermissions != null ? modPermissions : this.localPermissions;
  116 + }
  117 +
  118 + /* (non-Javadoc)
  119 + * @see net.eq2online.permissions.PermissionsManager#getPermissionUpdateTime(java.lang.String)
  120 + */
  121 + @Override
  122 + public Long getPermissionUpdateTime(Permissible mod)
  123 + {
  124 + if (mod == null) mod = allMods;
  125 + String modName = mod.getPermissibleModName();
  126 +
  127 + ServerPermissions modPermissions = this.serverPermissions.get(modName);
  128 + return modPermissions != null ? modPermissions.getReplicationTime() : 0;
  129 + }
  130 +
  131 + /* (non-Javadoc)
  132 + * @see net.eq2online.permissions.PermissionsManager#registerListener(net.eq2online.permissions.PermissionsListener)
  133 + */
  134 + @Override
  135 + public void registerPermissible(Permissible permissible)
  136 + {
  137 + if (!this.permissibles.contains(permissible) && permissible.getPermissibleModName() != null)
  138 + {
  139 + this.registerClientMod(permissible.getPermissibleModName(), permissible);
  140 + permissible.registerPermissions(this);
  141 + }
  142 +
  143 + this.permissibles.add(permissible);
  144 + }
  145 +
  146 + /**
  147 + * Register a new client mod with this manager
  148 + *
  149 + * @param modName Mod name
  150 + * @param modVersion Mod version
  151 + */
  152 + private void registerClientMod(String modName, Permissible mod)
  153 + {
  154 + if (this.registeredClientMods.containsKey(modName))
  155 + {
  156 + throw new IllegalArgumentException("Cannot register mod \"" + modName + "\"! The mod was already registered with the permissions manager.");
  157 + }
  158 +
  159 + this.registeredClientMods.put(modName, mod);
  160 + this.registeredClientPermissions.put(mod, new TreeSet<String>());
  161 + }
  162 +
  163 + /* (non-Javadoc)
  164 + * @see net.eq2online.permissions.PermissionsManager#onLogin(net.minecraft.src.NetHandler, net.minecraft.src.Packet1Login)
  165 + */
  166 + @Override
  167 + public void onLogin(NetHandler netHandler, Packet1Login loginPacket)
  168 + {
  169 + this.loginRegisterTicks = 2;
  170 + this.clearServerPermissions();
  171 + }
  172 +
  173 + /**
  174 + * Clears the current replicated server permissions
  175 + */
  176 + protected void clearServerPermissions()
  177 + {
  178 + this.serverPermissions.clear();
  179 +
  180 + for (Permissible permissible : this.permissibles)
  181 + permissible.onPermissionsCleared(this);
  182 + }
  183 +
  184 + /**
  185 + * Send permission query packets to the server for all registered mods
  186 + *
  187 + * @param minecraft Minecraft instance
  188 + */
  189 + protected void sendPermissionQueries()
  190 + {
  191 + for (Permissible mod : this.registeredClientMods.values())
  192 + this.sendPermissionQuery(mod);
  193 + }
  194 +
  195 + /**
  196 + * Send a permission query packet to the server for the specified mod. You do not need to call this method because it is
  197 + * issued automatically by the client permissions manager when connecting to a new server. However you can call use this
  198 + * method to "force" a refresh of permissions when needed.
  199 + *
  200 + * @param modName name of the mod to send a query packet for
  201 + */
  202 + public void sendPermissionQuery(Permissible mod)
  203 + {
  204 + String modName = mod.getPermissibleModName();
  205 +
  206 + if (this.minecraft != null && this.minecraft.thePlayer != null && this.minecraft.theWorld != null && this.minecraft.theWorld.isRemote)
  207 + {
  208 + if (!this.registeredClientMods.containsValue(mod))
  209 + {
  210 + throw new IllegalArgumentException("The specified mod \"" + modName + "\" was not registered with the permissions system");
  211 + }
  212 +
  213 + Float modVersion = mod.getPermissibleModVersion();
  214 + Set<String> modPermissions = this.registeredClientPermissions.get(mod);
  215 +
  216 + if (modPermissions != null)
  217 + {
  218 + ReplicatedPermissionsContainer query = new ReplicatedPermissionsContainer(modName, modVersion, modPermissions);
  219 +
  220 + if (!query.modName.equals("all") || query.permissions.size() > 0)
  221 + {
  222 + byte[] data = query.getBytes();
  223 + ModUtilities.sendPluginChannelMessage(ReplicatedPermissionsContainer.CHANNEL, data);
  224 + }
  225 + }
  226 + }
  227 + else
  228 + {
  229 + this.serverPermissions.remove(modName);
  230 + }
  231 + }
  232 +
  233 + /* (non-Javadoc)
  234 + * @see net.eq2online.permissions.PermissionsManager#onTick(net.minecraft.src.Minecraft, float, boolean)
  235 + */
  236 + @Override
  237 + public void onTick(Minecraft minecraft, float partialTicks, boolean inGame)
  238 + {
  239 + this.minecraft = minecraft;
  240 + this.lastTickTime = System.currentTimeMillis();
  241 +
  242 + if (this.loginRegisterTicks > 0)
  243 + {
  244 + this.loginRegisterTicks--;
  245 +
  246 + if (this.loginRegisterTicks == 0 && inGame)
  247 + {
  248 + this.sendPermissionQueries();
  249 + return;
  250 + }
  251 + }
  252 +
  253 + for (Map.Entry<String, ServerPermissions> modPermissions : this.serverPermissions.entrySet())
  254 + {
  255 + if (!modPermissions.getValue().isValid())
  256 + {
  257 + modPermissions.getValue().notifyRefreshPending();
  258 + this.sendPermissionQuery(this.registeredClientMods.get(modPermissions.getKey()));
  259 + }
  260 + }
  261 +
  262 + if (inGame) this.menuTicks = 0; else this.menuTicks++;
  263 +
  264 + if (this.menuTicks == 200)
  265 + {
  266 + this.clearServerPermissions();
  267 + }
  268 + }
  269 +
  270 + /* (non-Javadoc)
  271 + * @see net.eq2online.permissions.PermissionsManager#tamperCheck()
  272 + */
  273 + @Override
  274 + public void tamperCheck()
  275 + {
  276 + if (System.currentTimeMillis() - this.lastTickTime > 60000L)
  277 + {
  278 + throw new IllegalStateException("Client permissions manager was not ticked for 60 seconds, tamper.");
  279 + }
  280 + }
  281 +
  282 + /* (non-Javadoc)
  283 + * @see net.eq2online.permissions.PermissionsManager#onCustomPayload(java.lang.String, int, byte[])
  284 + */
  285 + @Override
  286 + public void onCustomPayload(String channel, int length, byte[] data)
  287 + {
  288 + if (channel.equals(ReplicatedPermissionsContainer.CHANNEL) && !Minecraft.getMinecraft().isSingleplayer())
  289 + {
  290 + ServerPermissions modPermissions = null;
  291 + try
  292 + {
  293 + modPermissions = new ServerPermissions(data);
  294 + }
  295 + catch (Exception ex) {}
  296 +
  297 + if (modPermissions != null && modPermissions.getModName() != null)
  298 + {
  299 + this.serverPermissions.put(modPermissions.getModName(), modPermissions);
  300 +
  301 + Permissible permissible = this.registeredClientMods.get(modPermissions.getModName());
  302 + if (permissible != null) permissible.onPermissionsChanged(this);
  303 + }
  304 + }
  305 + }
  306 +
  307 + /* (non-Javadoc)
  308 + * @see net.eq2online.permissions.PermissionsManager#getChannels()
  309 + */
  310 + @Override
  311 + public List<String> getChannels()
  312 + {
  313 + return Arrays.asList(new String[] { ReplicatedPermissionsContainer.CHANNEL });
  314 + }
  315 +
  316 + /**
  317 + * Register a permission for all mods, the permission will be prefixed with "mod.all." to provide
  318 + * a common namespace for client mods when permissions are replicated to the server
  319 + *
  320 + * @param permission
  321 + */
  322 + public void registerPermission(String permission)
  323 + {
  324 + this.registerModPermission(allMods, permission);
  325 + }
  326 +
  327 + /**
  328 + * Register a permission for the specified mod, the permission will be prefixed with "mod.<modname>." to provide
  329 + * a common namespace for client mods when permissions are replicated to the server
  330 + *
  331 + * @param mod
  332 + * @param permission
  333 + */
  334 + public void registerModPermission(Permissible mod, String permission)
  335 + {
  336 + if (mod == null) mod = allMods;
  337 + String modName = mod.getPermissibleModName();
  338 +
  339 + if (!this.registeredClientMods.containsValue(mod))
  340 + {
  341 + throw new IllegalArgumentException("Cannot register a mod permission for mod \"" + modName + "\"! The mod was not registered with the permissions manager.");
  342 + }
  343 +
  344 + permission = formatModPermission(modName, permission);
  345 +
  346 + Set<String> modPermissions = this.registeredClientPermissions.get(mod);
  347 + if (modPermissions != null && !modPermissions.contains(permission))
  348 + {
  349 + modPermissions.add(permission);
  350 + }
  351 + }
  352 +
  353 + /**
  354 + * Get the value of the specified permission for all mods.
  355 + *
  356 + * @param permission Permission to check for
  357 + * @return
  358 + */
  359 + public boolean getPermission(String permission)
  360 + {
  361 + return this.getModPermission(allMods, permission);
  362 + }
  363 +
  364 + /**
  365 + * Get the value of the specified permission for all mods and return the default value if the permission is not set
  366 + *
  367 + * @param permission Permission to check for
  368 + * @param defaultValue Value to return if the permission is not set
  369 + * @return
  370 + */
  371 + public boolean getPermission(String permission, boolean defaultValue)
  372 + {
  373 + return this.getModPermission(allMods, permission, defaultValue);
  374 + }
  375 +
  376 + /**
  377 + * Get the value of the specified permission for the specified mod. The permission will be prefixed with "mod.<modname>."
  378 + * in keeping with registerModPermission as a convenience.
  379 + *
  380 + * @param mod
  381 + * @param permission
  382 + * @return
  383 + */
  384 + public boolean getModPermission(Permissible mod, String permission)
  385 + {
  386 + if (mod == null) mod = this.allMods;
  387 + permission = formatModPermission(mod.getPermissibleModName(), permission);
  388 + Permissions permissions = this.getPermissions(mod);
  389 +
  390 + if (permissions != null)
  391 + {
  392 + return permissions.getHasPermission(permission);
  393 + }
  394 +
  395 + return true;
  396 + }
  397 +
  398 + /**
  399 + * Get the value of the specified permission for the specified mod. The permission will be prefixed with "mod.<modname>."
  400 + * in keeping with registerModPermission as a convenience.
  401 + *
  402 + * @param modName
  403 + * @param permission
  404 + * @return
  405 + */
  406 + public boolean getModPermission(String modName, String permission)
  407 + {
  408 + Permissible mod = this.registeredClientMods.get(modName);
  409 + return mod != null ? this.getModPermission(mod, permission) : false;
  410 + }
  411 +
  412 + /**
  413 + * Get the value of the specified permission for the specified mod. The permission will be prefixed with "mod.<modname>."
  414 + * in keeping with registerModPermission as a convenience. If the permission does not exist, the specified default value
  415 + * will be returned.
  416 + *
  417 + * @param mod
  418 + * @param permission
  419 + * @param defaultValue
  420 + * @return
  421 + */
  422 + public boolean getModPermission(Permissible mod, String permission, boolean defaultValue)
  423 + {
  424 + if (mod == null) mod = allMods;
  425 + permission = formatModPermission(mod.getPermissibleModName(), permission);
  426 + Permissions permissions = this.getPermissions(mod);
  427 +
  428 + if (permissions != null && permissions.getPermissionSet(permission))
  429 + {
  430 + return permissions.getHasPermission(permission);
  431 + }
  432 +
  433 + return defaultValue;
  434 + }
  435 +
  436 + /**
  437 + * Get the value of the specified permission for the specified mod. The permission will be prefixed with "mod.<modname>."
  438 + * in keeping with registerModPermission as a convenience.
  439 + *
  440 + * @param modName
  441 + * @param permission
  442 + * @return
  443 + */
  444 + public boolean getModPermission(String modName, String permission, boolean defaultValue)
  445 + {
  446 + Permissible mod = this.registeredClientMods.get(modName);
  447 + return mod != null ? this.getModPermission(mod, permission, defaultValue) : defaultValue;
  448 + }
  449 +
  450 + /**
  451 + * @param modName
  452 + * @param permission
  453 + * @return
  454 + */
  455 + protected static String formatModPermission(String modName, String permission)
  456 + {
  457 + return String.format("mod.%s.%s", modName, permission);
  458 + }
  459 +
  460 + /* (non-Javadoc)
  461 + * @see com.mumfrey.liteloader.LiteMod#getName()
  462 + */
  463 + @Override
  464 + public String getName()
  465 + {
  466 + // Stub for PluginChannelListener interface
  467 + return null;
  468 + }
  469 +
  470 + /* (non-Javadoc)
  471 + * @see com.mumfrey.liteloader.LiteMod#getVersion()
  472 + */
  473 + @Override
  474 + public String getVersion()
  475 + {
  476 + // Stub for PluginChannelListener interface
  477 + return null;
  478 + }
  479 +
  480 + /* (non-Javadoc)
  481 + * @see com.mumfrey.liteloader.LiteMod#init()
  482 + */
  483 + @Override
  484 + public void init(File configPath)
  485 + {
  486 + // Stub for PluginChannelListener interface
  487 + }
  488 +
  489 + @Override
  490 + public void upgradeSettings(String version, File configPath, File oldConfigPath)
  491 + {
  492 + }
  493 +}
java/com/mumfrey/liteloader/permissions/ReplicatedPermissions.java 0 → 100644
  1 +package com.mumfrey.liteloader.permissions;
  2 +
  3 +/**
  4 + * Represents a set of permissions assigned by a remote authority such as a server
  5 + *
  6 + * @author Adam Mummery-Smith
  7 + */
  8 +public interface ReplicatedPermissions extends Permissions
  9 +{
  10 + /**
  11 + * Get the time that this object was received from the remote authority
  12 + *
  13 + * @return
  14 + */
  15 + public abstract long getReplicationTime();
  16 +
  17 + /**
  18 + * True if this permissions object is valid (within cache period)
  19 + *
  20 + * @return
  21 + */
  22 + public abstract boolean isValid();
  23 +
  24 + /**
  25 + * Forcibly invalidate this permission container, forces update at the next opportunity
  26 + */
  27 + public abstract void invalidate();
  28 +
  29 + /**
  30 + * Temporarily forces the permissions object to be valid to prevent repeated revalidation
  31 + */
  32 + public abstract void notifyRefreshPending();
  33 +}
java/com/mumfrey/liteloader/permissions/ServerPermissions.java 0 → 100644
  1 +package com.mumfrey.liteloader.permissions;
  2 +
  3 +import java.util.regex.Matcher;
  4 +import java.util.regex.Pattern;
  5 +
  6 +import net.eq2online.permissions.ReplicatedPermissionsContainer;
  7 +
  8 +
  9 +/**
  10 + * Replicated permissions implementation
  11 + *
  12 + * @author Adam Mummery-Smith
  13 + */
  14 +public class ServerPermissions implements ReplicatedPermissions
  15 +{
  16 + /**
  17 + * Pattern for recognising valid permissions in the server feed
  18 + */
  19 + private static final Pattern permissionPattern = Pattern.compile("^([\\+\\-])(([a-z0-9]+\\.)*[a-z0-9\\*]+)$", Pattern.CASE_INSENSITIVE);
  20 +
  21 + protected String modName;
  22 +
  23 + /**
  24 + * Root permission node
  25 + */
  26 + protected Permission permissions = new Permission();
  27 +
  28 + /**
  29 + * Time the permissions were updated
  30 + */
  31 + protected long createdTime = 0L;
  32 +
  33 + /**
  34 + * Expiry time of the current data cache
  35 + */
  36 + protected long validUntil = 0L;
  37 +
  38 + /**
  39 + * Time to cache server responses by default
  40 + */
  41 + protected long cacheTime = 10L * 60L * 1000L; // 10 minutes
  42 +
  43 + /**
  44 + * Time to wait when refreshing server permissions before trying again
  45 + */
  46 + protected long refreshTime = 15L * 1000L; // 15 seconds
  47 +
  48 + /**
  49 + * @param data
  50 + */
  51 + public ServerPermissions(byte[] data)
  52 + {
  53 + this.createdTime = System.currentTimeMillis();
  54 + this.validUntil = this.createdTime + this.cacheTime;
  55 +
  56 + ReplicatedPermissionsContainer response = ReplicatedPermissionsContainer.fromBytes(data);
  57 +
  58 + if (response != null)
  59 + {
  60 + response.sanitise();
  61 +
  62 + this.modName = response.modName;
  63 + this.validUntil = System.currentTimeMillis() + response.remoteCacheTimeSeconds * 1000L;
  64 +
  65 + for (String permissionString : response.permissions)
  66 + {
  67 + Matcher permissionMatcher = permissionPattern.matcher(permissionString);
  68 +
  69 + if (permissionMatcher.matches())
  70 + {
  71 + String name = permissionMatcher.group(2);
  72 + boolean value = permissionMatcher.group(1).equals("+");
  73 +
  74 + this.permissions.setPermissionAndValue(name, value);
  75 + }
  76 + }
  77 + }
  78 + }
  79 +
  80 + /**
  81 + * @return
  82 + */
  83 + public String getModName()
  84 + {
  85 + return this.modName;
  86 + }
  87 +
  88 + /* (non-Javadoc)
  89 + * @see net.eq2online.permissions.Permissions#getPermissionSet(java.lang.String)
  90 + */
  91 + @Override
  92 + public boolean getPermissionSet(String permission)
  93 + {
  94 + return this.permissions.getPermission(permission) != null;
  95 + }
  96 +
  97 + /* (non-Javadoc)
  98 + * @see net.eq2online.permissions.Permissions#getHasPermission(java.lang.String)
  99 + */
  100 + @Override
  101 + public boolean getHasPermission(String permission)
  102 + {
  103 + Permission perm = this.permissions.getPermission(permission);
  104 + return perm != null && perm.getValue();
  105 + }
  106 +
  107 + /* (non-Javadoc)
  108 + * @see net.eq2online.permissions.Permissions#getHasPermission(java.lang.String, boolean)
  109 + */
  110 + @Override
  111 + public boolean getHasPermission(String permission, boolean defaultValue)
  112 + {
  113 + Permission perm = this.permissions.getPermission(permission);
  114 +
  115 + return perm != null ? perm.getValue() : defaultValue;
  116 + }
  117 +
  118 + /* (non-Javadoc)
  119 + * @see net.eq2online.permissions.ReplicatedPermissions#getReplicationTime()
  120 + */
  121 + @Override
  122 + public long getReplicationTime()
  123 + {
  124 + return this.createdTime;
  125 + }
  126 +
  127 + /* (non-Javadoc)
  128 + * @see net.eq2online.permissions.ReplicatedPermissions#isValid()
  129 + */
  130 + @Override
  131 + public boolean isValid()
  132 + {
  133 + return System.currentTimeMillis() < this.validUntil;
  134 + }
  135 +
  136 + /* (non-Javadoc)
  137 + * @see net.eq2online.permissions.ReplicatedPermissions#invalidate()
  138 + */
  139 + @Override
  140 + public void invalidate()
  141 + {
  142 + this.validUntil = 0L;
  143 + }
  144 +
  145 + @Override
  146 + public void notifyRefreshPending()
  147 + {
  148 + this.validUntil = System.currentTimeMillis() + this.refreshTime;
  149 + }
  150 +}
java/com/mumfrey/liteloader/util/ModUtilities.java
@@ -9,7 +9,7 @@ import java.util.Set; @@ -9,7 +9,7 @@ import java.util.Set;
9 import com.mumfrey.liteloader.core.LiteLoader; 9 import com.mumfrey.liteloader.core.LiteLoader;
10 10
11 import net.minecraft.client.ClientBrandRetriever; 11 import net.minecraft.client.ClientBrandRetriever;
12 -import net.minecraft.client.Minecraft; 12 +import net.minecraft.src.Minecraft;
13 import net.minecraft.src.*; 13 import net.minecraft.src.*;
14 14
15 public abstract class ModUtilities 15 public abstract class ModUtilities
java/com/mumfrey/liteloader/util/PrivateFields.java
@@ -4,7 +4,7 @@ import java.lang.reflect.Field; @@ -4,7 +4,7 @@ import java.lang.reflect.Field;
4 import java.lang.reflect.Modifier; 4 import java.lang.reflect.Modifier;
5 import java.util.Map; 5 import java.util.Map;
6 6
7 -import net.minecraft.client.Minecraft; 7 +import net.minecraft.src.Minecraft;
8 import net.minecraft.src.*; 8 import net.minecraft.src.*;
9 9
10 /** 10 /**
@@ -15,7 +15,7 @@ import net.minecraft.src.*; @@ -15,7 +15,7 @@ import net.minecraft.src.*;
15 * @param <P> Parent class type, the type of the class that owns the field 15 * @param <P> Parent class type, the type of the class that owns the field
16 * @param <T> Field type, the type of the field value 16 * @param <T> Field type, the type of the field value
17 * 17 *
18 - * TODO Obfuscation - updated 1.5.2 18 + * TODO Obfuscation - updated 1.6.2
19 */ 19 */
20 @SuppressWarnings("rawtypes") 20 @SuppressWarnings("rawtypes")
21 public class PrivateFields<P, T> 21 public class PrivateFields<P, T>
@@ -70,7 +70,7 @@ public class PrivateFields&lt;P, T&gt; @@ -70,7 +70,7 @@ public class PrivateFields&lt;P, T&gt;
70 { 70 {
71 try 71 try
72 { 72 {
73 - Field field = parentClass.getDeclaredField(fieldName); 73 + Field field = this.parentClass.getDeclaredField(this.fieldName);
74 field.setAccessible(true); 74 field.setAccessible(true);
75 return (T)field.get(instance); 75 return (T)field.get(instance);
76 } 76 }
@@ -79,7 +79,7 @@ public class PrivateFields&lt;P, T&gt; @@ -79,7 +79,7 @@ public class PrivateFields&lt;P, T&gt;
79 return null; 79 return null;
80 } 80 }
81 } 81 }
82 - 82 +
83 /** 83 /**
84 * Set the value of this field on the instance class supplied 84 * Set the value of this field on the instance class supplied
85 * 85 *
@@ -91,11 +91,11 @@ public class PrivateFields&lt;P, T&gt; @@ -91,11 +91,11 @@ public class PrivateFields&lt;P, T&gt;
91 { 91 {
92 try 92 try
93 { 93 {
94 - Field field = parentClass.getDeclaredField(fieldName); 94 + Field field = this.parentClass.getDeclaredField(this.fieldName);
95 field.setAccessible(true); 95 field.setAccessible(true);
96 field.set(instance, value); 96 field.set(instance, value);
97 } 97 }
98 - catch (Exception ex) {} 98 + catch (Exception ex) { }
99 99
100 return value; 100 return value;
101 } 101 }
@@ -114,12 +114,12 @@ public class PrivateFields&lt;P, T&gt; @@ -114,12 +114,12 @@ public class PrivateFields&lt;P, T&gt;
114 Field modifiers = Field.class.getDeclaredField("modifiers"); 114 Field modifiers = Field.class.getDeclaredField("modifiers");
115 modifiers.setAccessible(true); 115 modifiers.setAccessible(true);
116 116
117 - Field field = parentClass.getDeclaredField(fieldName); 117 + Field field = this.parentClass.getDeclaredField(fieldName);
118 modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL); 118 modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
119 field.setAccessible(true); 119 field.setAccessible(true);
120 field.set(instance, value); 120 field.set(instance, value);
121 } 121 }
122 - catch (Exception ex) {} 122 + catch (Exception ex) { }
123 123
124 return value; 124 return value;
125 } 125 }
@@ -141,8 +141,8 @@ public class PrivateFields&lt;P, T&gt; @@ -141,8 +141,8 @@ public class PrivateFields&lt;P, T&gt;
141 public static final StaticFields<TileEntity, Map> tileEntityNameToClassMap = new StaticFields<TileEntity, Map> (TileEntity.class, "nameToClassMap", "a", "field_70326_a"); // TileEntity/nameToClassMap 141 public static final StaticFields<TileEntity, Map> tileEntityNameToClassMap = new StaticFields<TileEntity, Map> (TileEntity.class, "nameToClassMap", "a", "field_70326_a"); // TileEntity/nameToClassMap
142 } 142 }
143 143
144 - public static final PrivateFields<Minecraft, Timer> minecraftTimer = new PrivateFields<Minecraft, Timer> (Minecraft.class, "timer", "V", "field_71428_T"); // Minecraft/timer  
145 - public static final PrivateFields<Minecraft, Profiler> minecraftProfiler = new PrivateFields<Minecraft, Profiler> (Minecraft.class, "mcProfiler", "J", "field_71424_I"); // Minecraft/mcProfiler 144 + public static final PrivateFields<Minecraft, Timer> minecraftTimer = new PrivateFields<Minecraft, Timer> (Minecraft.class, "timer", "S", "field_71428_T"); // Minecraft/timer
  145 + public static final PrivateFields<Minecraft, Profiler> minecraftProfiler = new PrivateFields<Minecraft, Profiler> (Minecraft.class, "mcProfiler", "C", "field_71424_I"); // Minecraft/mcProfiler
146 public static final PrivateFields<RenderManager, Map> entityRenderMap = new PrivateFields<RenderManager, Map> (RenderManager.class, "entityRenderMap", "q", "field_78729_o"); // RenderManager/entityRenderMap 146 public static final PrivateFields<RenderManager, Map> entityRenderMap = new PrivateFields<RenderManager, Map> (RenderManager.class, "entityRenderMap", "q", "field_78729_o"); // RenderManager/entityRenderMap
147 public static final PrivateFields<GuiControls, GuiScreen> guiControlsParentScreen = new PrivateFields<GuiControls, GuiScreen> (GuiControls.class, "parentScreen", "b", "field_73909_b"); // GuiControls/parentScreen 147 public static final PrivateFields<GuiControls, GuiScreen> guiControlsParentScreen = new PrivateFields<GuiControls, GuiScreen> (GuiControls.class, "parentScreen", "b", "field_73909_b"); // GuiControls/parentScreen
148 public static final PrivateFields<PlayerUsageSnooper, IPlayerUsage> playerStatsCollector = new PrivateFields<PlayerUsageSnooper, IPlayerUsage>(PlayerUsageSnooper.class, "playerStatsCollector", "d", "field_76478_d"); // PlayerUsageSnooper/playerStatsCollector 148 public static final PrivateFields<PlayerUsageSnooper, IPlayerUsage> playerStatsCollector = new PrivateFields<PlayerUsageSnooper, IPlayerUsage>(PlayerUsageSnooper.class, "playerStatsCollector", "d", "field_76478_d"); // PlayerUsageSnooper/playerStatsCollector
java/net/eq2online/permissions/ReplicatedPermissionsContainer.java 0 → 100644
  1 +package net.eq2online.permissions;
  2 +
  3 +import java.io.*;
  4 +import java.util.Collection;
  5 +import java.util.Set;
  6 +import java.util.TreeSet;
  7 +
  8 +/**
  9 + * Serializable container object
  10 + *
  11 + * @author Adam Mummery-Smith
  12 + */
  13 +public class ReplicatedPermissionsContainer implements Serializable
  14 +{
  15 + /**
  16 + * Serial version UID to suppoer Serializable interface
  17 + */
  18 + private static final long serialVersionUID = -764940324881984960L;
  19 +
  20 + /**
  21 + * Mod name
  22 + */
  23 + public String modName = "all";
  24 +
  25 + /**
  26 + * Mod version
  27 + */
  28 + public Float modVersion = 0.0F;
  29 +
  30 + /**
  31 + * List of permissions to replicate, prepend "-" for a negated permission and "+" for a granted permission
  32 + */
  33 + public Set<String> permissions = new TreeSet<String>();
  34 +
  35 + /**
  36 + * Amount of time in seconds that the client will trust these permissions for before requesting an update
  37 + */
  38 + public long remoteCacheTimeSeconds = 600L; // 10 minutes
  39 +
  40 + public static final String CHANNEL = "PERMISSIONSREPL";
  41 +
  42 + public ReplicatedPermissionsContainer()
  43 + {
  44 + }
  45 +
  46 + public ReplicatedPermissionsContainer(String modName, Float modVersion, Collection<String> permissions)
  47 + {
  48 + this.modName = modName;
  49 + this.modVersion = modVersion;
  50 + this.permissions.addAll(permissions);
  51 + }
  52 +
  53 + /**
  54 + * Add all of the listed permissions to this container
  55 + *
  56 + * @param permissions
  57 + */
  58 + public void addAll(Collection<String> permissions)
  59 + {
  60 + this.permissions.addAll(permissions);
  61 + }
  62 +
  63 + /**
  64 + * Check and correct
  65 + */
  66 + public void sanitise()
  67 + {
  68 + if (this.modName == null || this.modName.length() < 1) this.modName = "all";
  69 + if (this.modVersion == null || this.modVersion < 0.0F) this.modVersion = 0.0F;
  70 + if (this.remoteCacheTimeSeconds < 0) this.remoteCacheTimeSeconds = 600L;
  71 + }
  72 +
  73 + /**
  74 + * Serialise this container to a byte array for transmission to a remote host
  75 + *
  76 + * @return
  77 + */
  78 + public byte[] getBytes()
  79 + {
  80 + try
  81 + {
  82 + ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
  83 + new ObjectOutputStream(byteStream).writeObject(this);
  84 + return byteStream.toByteArray();
  85 + }
  86 + catch (IOException e) {}
  87 +
  88 + return new byte[0];
  89 + }
  90 +
  91 + /**
  92 + * Deserialises a replicated permissions container from a byte array
  93 + *
  94 + * @param data Byte array containing the serialised data
  95 + * @return new container or null if deserialisation failed
  96 + */
  97 + public static ReplicatedPermissionsContainer fromBytes(byte[] data)
  98 + {
  99 + try
  100 + {
  101 + ObjectInputStream inputStream = new ObjectInputStream(new ByteArrayInputStream(data));
  102 + ReplicatedPermissionsContainer object = (ReplicatedPermissionsContainer)inputStream.readObject();
  103 + return object;
  104 + }
  105 + catch (IOException e) { }
  106 + catch (ClassNotFoundException e) { }
  107 + catch (ClassCastException e) { }
  108 +
  109 + return null;
  110 + }
  111 +}
java/net/minecraft/src/CallableJVMFlags.java deleted 100644 → 0
1 -package net.minecraft.src;  
2 -  
3 -import java.lang.management.ManagementFactory;  
4 -import java.lang.management.RuntimeMXBean;  
5 -import java.util.Iterator;  
6 -import java.util.List;  
7 -import java.util.concurrent.Callable;  
8 -  
9 -import com.mumfrey.liteloader.core.CallableLiteLoaderBrand;  
10 -import com.mumfrey.liteloader.core.CallableLiteLoaderMods;  
11 -  
12 -class CallableJVMFlags implements Callable<String>  
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  
54 - public String call()  
55 - {  
56 - return this.getJVMFlagsAsString();  
57 - }  
58 -}  
java/net/minecraft/src/RenderLightningBolt.java deleted 100644 → 0
1 -package net.minecraft.src;  
2 -  
3 -import java.util.Random;  
4 -import org.lwjgl.opengl.GL11;  
5 -  
6 -import com.mumfrey.liteloader.core.LiteLoader;  
7 -  
8 -public class RenderLightningBolt extends Render  
9 -{  
10 - static  
11 - {  
12 - // LiteLoader init  
13 - LiteLoader.getInstance();  
14 - }  
15 -  
16 - /**  
17 - * Actually renders the lightning bolt. This method is called through the doRender method.  
18 - */  
19 - @SuppressWarnings("cast")  
20 - public void doRenderLightningBolt(EntityLightningBolt par1EntityLightningBolt, double par2, double par4, double par6, float par8, float par9)  
21 - {  
22 - Tessellator var10 = Tessellator.instance;  
23 - GL11.glDisable(GL11.GL_TEXTURE_2D);  
24 - GL11.glDisable(GL11.GL_LIGHTING);  
25 - GL11.glEnable(GL11.GL_BLEND);  
26 - GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);  
27 - double[] var11 = new double[8];  
28 - double[] var12 = new double[8];  
29 - double var13 = 0.0D;  
30 - double var15 = 0.0D;  
31 - Random var17 = new Random(par1EntityLightningBolt.boltVertex);  
32 -  
33 - for (int var18 = 7; var18 >= 0; --var18)  
34 - {  
35 - var11[var18] = var13;  
36 - var12[var18] = var15;  
37 - var13 += (double)(var17.nextInt(11) - 5);  
38 - var15 += (double)(var17.nextInt(11) - 5);  
39 - }  
40 -  
41 - for (int var45 = 0; var45 < 4; ++var45)  
42 - {  
43 - Random var46 = new Random(par1EntityLightningBolt.boltVertex);  
44 -  
45 - for (int var19 = 0; var19 < 3; ++var19)  
46 - {  
47 - int var20 = 7;  
48 - int var21 = 0;  
49 -  
50 - if (var19 > 0)  
51 - {  
52 - var20 = 7 - var19;  
53 - }  
54 -  
55 - if (var19 > 0)  
56 - {  
57 - var21 = var20 - 2;  
58 - }  
59 -  
60 - double var22 = var11[var20] - var13;  
61 - double var24 = var12[var20] - var15;  
62 -  
63 - for (int var26 = var20; var26 >= var21; --var26)  
64 - {  
65 - double var27 = var22;  
66 - double var29 = var24;  
67 -  
68 - if (var19 == 0)  
69 - {  
70 - var22 += (double)(var46.nextInt(11) - 5);  
71 - var24 += (double)(var46.nextInt(11) - 5);  
72 - }  
73 - else  
74 - {  
75 - var22 += (double)(var46.nextInt(31) - 15);  
76 - var24 += (double)(var46.nextInt(31) - 15);  
77 - }  
78 -  
79 - var10.startDrawing(5);  
80 - float var31 = 0.5F;  
81 - var10.setColorRGBA_F(0.9F * var31, 0.9F * var31, 1.0F * var31, 0.3F);  
82 - double var32 = 0.1D + (double)var45 * 0.2D;  
83 -  
84 - if (var19 == 0)  
85 - {  
86 - var32 *= (double)var26 * 0.1D + 1.0D;  
87 - }  
88 -  
89 - double var34 = 0.1D + (double)var45 * 0.2D;  
90 -  
91 - if (var19 == 0)  
92 - {  
93 - var34 *= (double)(var26 - 1) * 0.1D + 1.0D;  
94 - }  
95 -  
96 - for (int var36 = 0; var36 < 5; ++var36)  
97 - {  
98 - double var37 = par2 + 0.5D - var32;  
99 - double var39 = par6 + 0.5D - var32;  
100 -  
101 - if (var36 == 1 || var36 == 2)  
102 - {  
103 - var37 += var32 * 2.0D;  
104 - }  
105 -  
106 - if (var36 == 2 || var36 == 3)  
107 - {  
108 - var39 += var32 * 2.0D;  
109 - }  
110 -  
111 - double var41 = par2 + 0.5D - var34;  
112 - double var43 = par6 + 0.5D - var34;  
113 -  
114 - if (var36 == 1 || var36 == 2)  
115 - {  
116 - var41 += var34 * 2.0D;  
117 - }  
118 -  
119 - if (var36 == 2 || var36 == 3)  
120 - {  
121 - var43 += var34 * 2.0D;  
122 - }  
123 -  
124 - var10.addVertex(var41 + var22, par4 + (double)(var26 * 16), var43 + var24);  
125 - var10.addVertex(var37 + var27, par4 + (double)((var26 + 1) * 16), var39 + var29);  
126 - }  
127 -  
128 - var10.draw();  
129 - }  
130 - }  
131 - }  
132 -  
133 - GL11.glDisable(GL11.GL_BLEND);  
134 - GL11.glEnable(GL11.GL_LIGHTING);  
135 - GL11.glEnable(GL11.GL_TEXTURE_2D);  
136 - }  
137 -  
138 - /**  
139 - * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then  
140 - * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic  
141 - * (Render<T extends Entity) and this method has signature public void doRender(T entity, double d, double d1,  
142 - * double d2, float f, float f1). But JAD is pre 1.5 so doesn't do that.  
143 - */  
144 - @Override  
145 - public void doRender(Entity par1Entity, double par2, double par4, double par6, float par8, float par9)  
146 - {  
147 - this.doRenderLightningBolt((EntityLightningBolt)par1Entity, par2, par4, par6, par8, par9);  
148 - }  
149 -}