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 3 <classpathentry kind="src" path="java"/>
4 4 <classpathentry kind="src" path="res"/>
5 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 9 <classpathentry kind="output" path="bin"/>
12 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 144 \ No newline at end of file
... ...
java/com/mumfrey/liteloader/ChatFilter.java
1 1 package com.mumfrey.liteloader;
2 2  
  3 +import net.minecraft.src.ChatMessageComponent;
3 4 import net.minecraft.src.Packet3Chat;
4 5  
5 6 /**
... ... @@ -13,7 +14,9 @@ public interface ChatFilter extends LiteMod
13 14 * Chat filter function, return false to filter this packet, true to pass the packet
14 15 *
15 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 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 1 package com.mumfrey.liteloader;
2 2  
  3 +import net.minecraft.src.ChatMessageComponent;
  4 +
3 5 /**
4 6 * Interface for mods which receive inbound chat
5 7 *
... ... @@ -10,7 +12,8 @@ public interface ChatListener extends LiteMod
10 12 /**
11 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 1 package com.mumfrey.liteloader;
2 2  
3   -import net.minecraft.client.Minecraft;
  3 +import net.minecraft.src.Minecraft;
4 4  
5 5 /**
6 6 * Interface for mods which want a frame notification every single game loop
... ...
java/com/mumfrey/liteloader/InitCompleteListener.java
1 1 package com.mumfrey.liteloader;
2 2  
3   -import net.minecraft.client.Minecraft;
  3 +import net.minecraft.src.Minecraft;
4 4  
5 5 import com.mumfrey.liteloader.core.LiteLoader;
6 6  
... ...
java/com/mumfrey/liteloader/LiteMod.java
1 1 package com.mumfrey.liteloader;
2 2  
  3 +import java.io.File;
  4 +
3 5 /**
4 6 * Base interface for mods
5 7 *
... ... @@ -24,6 +26,17 @@ public interface LiteMod
24 26 /**
25 27 * Do startup stuff here, minecraft is not fully initialised when this function is called so mods *must not*
26 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 1 package com.mumfrey.liteloader;
2 2  
3   -import net.minecraft.client.Minecraft;
  3 +import net.minecraft.src.Minecraft;
4 4  
5 5 /**
6 6 * Interface for mods which want tick events
... ...
java/com/mumfrey/liteloader/core/HookChat.java
1 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 5 import java.io.IOException;
6 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 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 83 }
81 84  
82 85 @Override
83   - public void readPacketData(DataInputStream datainputstream) throws IOException
  86 + public void readPacketData(DataInput datainputstream) throws IOException
84 87 {
85 88 if (proxyPacket != null)
86 89 {
... ... @@ -92,7 +95,7 @@ public class HookChat extends Packet3Chat
92 95 }
93 96  
94 97 @Override
95   - public void writePacketData(DataOutputStream dataoutputstream) throws IOException
  98 + public void writePacketData(DataOutput dataoutputstream) throws IOException
96 99 {
97 100 if (proxyPacket != null)
98 101 proxyPacket.writePacketData(dataoutputstream);
... ...
java/com/mumfrey/liteloader/core/HookPluginChannels.java
1 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 5 import java.io.IOException;
6 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 15 public class HookPluginChannels extends Packet250CustomPayload
13 16 {
... ... @@ -68,7 +71,7 @@ public class HookPluginChannels extends Packet250CustomPayload
68 71  
69 72  
70 73 @Override
71   - public void readPacketData(DataInputStream datainputstream) throws IOException
  74 + public void readPacketData(DataInput datainputstream) throws IOException
72 75 {
73 76 if (proxyPacket != null)
74 77 {
... ... @@ -82,7 +85,7 @@ public class HookPluginChannels extends Packet250CustomPayload
82 85 }
83 86  
84 87 @Override
85   - public void writePacketData(DataOutputStream dataoutputstream) throws IOException
  88 + public void writePacketData(DataOutput dataoutputstream) throws IOException
86 89 {
87 90 if (proxyPacket != null)
88 91 proxyPacket.writePacketData(dataoutputstream);
... ...
java/com/mumfrey/liteloader/core/HookProfiler.java
... ... @@ -6,7 +6,7 @@ import java.util.LinkedList;
6 6 import java.util.NoSuchElementException;
7 7 import java.util.logging.Logger;
8 8  
9   -import net.minecraft.client.Minecraft;
  9 +import net.minecraft.src.Minecraft;
10 10 import net.minecraft.src.GameSettings;
11 11 import net.minecraft.src.Profiler;
12 12  
... ...
java/com/mumfrey/liteloader/core/LiteLoader.java
1 1 package com.mumfrey.liteloader.core;
2 2  
3 3 import java.io.BufferedReader;
4   -import java.io.ByteArrayOutputStream;
5 4 import java.io.File;
6 5 import java.io.FileInputStream;
7 6 import java.io.FileNotFoundException;
... ... @@ -16,7 +15,6 @@ import java.net.URL;
16 15 import java.net.URLClassLoader;
17 16 import java.net.URLDecoder;
18 17 import java.nio.charset.Charset;
19   -import java.util.Arrays;
20 18 import java.util.HashMap;
21 19 import java.util.Iterator;
22 20 import java.util.LinkedList;
... ... @@ -33,7 +31,8 @@ import java.util.zip.ZipInputStream;
33 31  
34 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 36 import net.minecraft.src.GuiControls;
38 37 import net.minecraft.src.GuiNewChat;
39 38 import net.minecraft.src.GuiScreen;
... ... @@ -54,40 +53,31 @@ import com.mumfrey.liteloader.GameLoopListener;
54 53 import com.mumfrey.liteloader.InitCompleteListener;
55 54 import com.mumfrey.liteloader.LiteMod;
56 55 import com.mumfrey.liteloader.LoginListener;
  56 +import com.mumfrey.liteloader.Permissible;
57 57 import com.mumfrey.liteloader.PluginChannelListener;
58 58 import com.mumfrey.liteloader.PostRenderListener;
59 59 import com.mumfrey.liteloader.PreLoginListener;
60 60 import com.mumfrey.liteloader.RenderListener;
61 61 import com.mumfrey.liteloader.Tickable;
62 62 import com.mumfrey.liteloader.gui.GuiControlsPaginated;
  63 +import com.mumfrey.liteloader.permissions.PermissionsManagerClient;
63 64 import com.mumfrey.liteloader.util.ModUtilities;
64 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 71 * @author Adam Mummery-Smith
70   - * @version 1.5.2
  72 + * @version 1.6.2
71 73 */
72 74 @SuppressWarnings("rawtypes")
73 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 83 * Maximum recursion depth for mod discovery
... ... @@ -110,11 +100,42 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
110 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 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 139 * Reference to the Minecraft game instance
119 140 */
120 141 private Minecraft minecraft = Minecraft.getMinecraft();
... ... @@ -122,25 +143,27 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
122 143 /**
123 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 149 * Internal properties loaded from inside the jar
129 150 */
130 151 private Properties internalProperties = new Properties();
131   -
  152 +
132 153 /**
133   - * LiteLoader properties
  154 + * LiteLoader properties
134 155 */
135 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 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 168 private boolean paginateControls = true;
146 169  
... ... @@ -148,7 +171,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
148 171 * Reference to the minecraft timer
149 172 */
150 173 private Timer minecraftTimer;
151   -
  174 +
152 175 /**
153 176 * List of loaded mods, for crash reporting
154 177 */
... ... @@ -166,7 +189,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
166 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 195 private LinkedList<GameLoopListener> loopListeners = new LinkedList<GameLoopListener>();
172 196  
... ... @@ -176,18 +200,20 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
176 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 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 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 218 private LinkedList<ChatRenderListener> chatRenderListeners = new LinkedList<ChatRenderListener>();
193 219  
... ... @@ -204,12 +230,14 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
204 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 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 242 private LinkedList<PreLoginListener> preLoginListeners = new LinkedList<PreLoginListener>();
215 243  
... ... @@ -217,11 +245,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
217 245 * List of mods which implement PluginChannelListener interface
218 246 */
219 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 255 * Reference to the addUrl method on URLClassLoader
... ... @@ -232,37 +260,50 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
232 260 * Flag which keeps track of whether late initialisation has been done
233 261 */
234 262 private boolean loaderStartupDone, loaderStartupComplete, lateInitDone;
235   -
  263 +
236 264 /**
237 265 * Flags which keep track of whether hooks have been applied
238 266 */
239 267 private boolean chatHooked, loginHooked, pluginChannelHooked, tickHooked;
240   -
  268 +
241 269 /**
242 270 * Profiler hook objects
243 271 */
244 272 private HookProfiler profilerHook = new HookProfiler(this, logger);
245   -
  273 +
246 274 /**
247 275 * ScaledResolution used by the pre-chat and post-chat render callbacks
248 276 */
249 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 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 292 instance = new LiteLoader();
263 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 307 return instance;
267 308 }
268 309  
... ... @@ -293,7 +334,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
293 334 */
294 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 344 */
304 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 357 */
312 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 403 private void initLoader()
317 404 {
318   - if (this.loaderStartupDone) return;
  405 + if (this.loaderStartupDone)
  406 + return;
319 407 this.loaderStartupDone = true;
320 408  
321   - // Set up base class overrides
322   - this.prepareClassOverrides();
323   -
324 409 // Set up loader, initialises any reflection methods needed
325 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 414 // Print the branding version if any was provided
330 415 if (this.branding != null)
... ... @@ -334,23 +419,23 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
334 419  
335 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 426 if (!searchMods && !searchProtectionDomain && !searchClassPath)
342 427 {
343 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 432 this.localProperties.setProperty("search.classpath", "true");
348 433  
349   - searchMods = true;
  434 + searchMods = true;
350 435 searchProtectionDomain = true;
351   - searchClassPath = true;
  436 + searchClassPath = true;
352 437 }
353   -
  438 +
354 439 // Examines the class path and mods folder and locates loadable mods
355 440 this.prepareMods(searchMods, searchProtectionDomain, searchClassPath);
356 441  
... ... @@ -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 455 * Set up reflection methods required by the loader
422 456 */
423 457 private boolean prepareLoader()
424 458 {
425 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 462 this.mAddUrl = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
429 463 this.mAddUrl.setAccessible(true);
430 464  
... ... @@ -438,7 +472,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
438 472 this.localProperties.setProperty("controls.pages", String.valueOf(this.paginateControls));
439 473  
440 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 478 // Save appropriate branding in the local properties file
444 479 if (this.branding != null)
... ... @@ -455,7 +490,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
455 490  
456 491 return true;
457 492 }
458   -
  493 +
459 494 /**
460 495 * @throws SecurityException
461 496 * @throws IOException
... ... @@ -471,7 +506,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
471 506 consoleHandler.setFormatter(logFormatter);
472 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 510 logFileHandler.setFormatter(logFormatter);
476 511 logger.addHandler(logFileHandler);
477 512 }
... ... @@ -495,7 +530,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
495 530 {
496 531 this.internalProperties = new Properties();
497 532 }
498   -
  533 +
499 534 try
500 535 {
501 536 this.localProperties = new Properties(this.internalProperties);
... ... @@ -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 555 * @return
520   - * @throws FileNotFoundException
  556 + * @throws FileNotFoundException
521 557 */
522 558 private InputStream getLocalPropertiesStream() throws FileNotFoundException
523 559 {
... ... @@ -525,7 +561,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
525 561 {
526 562 return new FileInputStream(this.propertiesFile);
527 563 }
528   -
  564 +
529 565 // Otherwise read settings from the config
530 566 return LiteLoader.class.getResourceAsStream("/liteloader.properties");
531 567 }
... ... @@ -537,38 +573,63 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
537 573 {
538 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 578 catch (Throwable th)
543 579 {
544 580 logger.log(Level.WARNING, "Error writing liteloader properties", th);
545 581 }
546 582 }
547   -
  583 +
548 584 /**
549 585 * Get the "mods" folder
550 586 */
551 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 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 633 * Used for crash reporting
573 634 *
574 635 * @return List of loaded mods as a string
... ... @@ -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 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 705 * @return
596 706 * @throws InvalidActivityException
597 707 */
... ... @@ -607,17 +717,19 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
607 717 {
608 718 throw new IllegalArgumentException("Attempted to get a reference to a mod without specifying a mod name");
609 719 }
610   -
  720 +
611 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 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 734 private void prepareMods(boolean searchMods, boolean searchProtectionDomain, boolean searchClassPath)
623 735 {
... ... @@ -635,13 +747,13 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
635 747 logger.info("Found " + modFiles.size() + " mod file(s)");
636 748 }
637 749 }
638   -
  750 +
639 751 // Find and enumerate classes on the class path
640 752 HashMap<String, Class> modsToLoad = null;
641 753 try
642 754 {
643 755 logger.info("Enumerating class path...");
644   -
  756 +
645 757 String classPath = System.getProperty("java.class.path");
646 758 String classPathSeparator = System.getProperty("path.separator");
647 759 String[] classPathEntries = classPath.split(classPathSeparator);
... ... @@ -649,9 +761,10 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
649 761 logger.info(String.format("Class path separator=\"%s\"", classPathSeparator));
650 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 766 modsToLoad = this.findModClasses(classPathEntries, modFiles, searchProtectionDomain, searchClassPath);
654   -
  767 +
655 768 logger.info("Mod class discovery completed");
656 769 }
657 770 catch (Throwable th)
... ... @@ -666,13 +779,13 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
666 779 /**
667 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 787 protected void findModFiles(File modFolder, LinkedList<File> modFiles)
673 788 {
674   - List<String> supportedVerions = Arrays.asList(SUPPORTED_VERSIONS);
675   -
676 789 for (File modFile : modFolder.listFiles(this))
677 790 {
678 791 try
... ... @@ -689,14 +802,15 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
689 802 String strVersion = versionReader.readLine();
690 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 809 modFiles.add(modFile);
696 810 }
697 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 823 }
710 824 }
711 825  
712   - /* (non-Javadoc)
  826 + /*
  827 + * (non-Javadoc)
  828 + *
713 829 * @see java.io.FilenameFilter#accept(java.io.File, java.lang.String)
714 830 */
715 831 @Override
... ... @@ -721,15 +837,18 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
721 837 /**
722 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 842 * @return map of classes to load
726 843 */
727 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 850 HashMap<String, Class> modsToLoad = new HashMap<String, Class>();
732   -
  851 +
733 852 if (searchProtectionDomain)
734 853 {
735 854 try
... ... @@ -745,12 +864,13 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
745 864 {
746 865 protectionDomainLocation = new URL(protectionDomainLocation.toString().substring(4, protectionDomainLocation.toString().indexOf('!')));
747 866 }
748   -
  867 +
749 868 packagePath = new File(protectionDomainLocation.toURI());
750 869 }
751 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 874 String reflectionClassPath = LiteLoader.class.getResource("/com/mumfrey/liteloader/core/LiteLoader.class").getPath();
755 875  
756 876 if (reflectionClassPath.indexOf('!') > -1)
... ... @@ -774,7 +894,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
774 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 901 catch (Throwable th)
... ... @@ -782,7 +903,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
782 903 logger.warning("Error loading from local class path: " + th.getMessage());
783 904 }
784 905 }
785   -
  906 +
786 907 if (searchClassPath)
787 908 {
788 909 // Search through the class path and find mod classes
... ... @@ -803,7 +924,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
803 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 945  
824 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 953 return modsToLoad;
... ... @@ -833,7 +956,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
833 956 /**
834 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 962 private void loadMods(HashMap<String, Class> modsToLoad)
839 963 {
... ... @@ -880,7 +1004,26 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
880 1004 {
881 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 1028 if (mod instanceof Tickable)
886 1029 {
... ... @@ -891,7 +1034,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
891 1034 {
892 1035 this.addLoopListener((GameLoopListener)mod);
893 1036 }
894   -
  1037 +
895 1038 if (mod instanceof InitCompleteListener)
896 1039 {
897 1040 this.addInitListener((InitCompleteListener)mod);
... ... @@ -944,6 +1087,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
944 1087 this.addPluginChannelListener((PluginChannelListener)mod);
945 1088 }
946 1089  
  1090 + if (mod instanceof Permissible)
  1091 + {
  1092 + permissionsManager.registerPermissible((Permissible)mod);
  1093 + }
  1094 +
947 1095 this.loadedModsList += String.format("\n - %s version %s", mod.getName(), mod.getVersion());
948 1096 loadedModsCount++;
949 1097 }
... ... @@ -956,7 +1104,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
956 1104  
957 1105 this.loadedModsList = String.format("%s loaded mod(s)%s", loadedModsCount, this.loadedModsList);
958 1106 }
959   -
  1107 +
960 1108 /**
961 1109 * Initialise mod hooks
962 1110 */
... ... @@ -1005,7 +1153,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1005 1153 ex.printStackTrace();
1006 1154 }
1007 1155 }
1008   -
  1156 +
1009 1157 /**
1010 1158 * @param tickable
1011 1159 */
... ... @@ -1014,7 +1162,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1014 1162 if (!this.tickListeners.contains(tickable))
1015 1163 {
1016 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 1175 if (!this.loopListeners.contains(loopListener))
1027 1176 {
1028 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 1188 if (!this.initListeners.contains(initCompleteListener))
1039 1189 {
1040 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 1197 * @param tickable
1047 1198 */
... ... @@ -1050,10 +1201,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1050 1201 if (!this.renderListeners.contains(tickable))
1051 1202 {
1052 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 1210 * @param tickable
1059 1211 */
... ... @@ -1062,10 +1214,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1062 1214 if (!this.postRenderListeners.contains(tickable))
1063 1215 {
1064 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 1223 * @param chatFilter
1071 1224 */
... ... @@ -1074,10 +1227,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1074 1227 if (!this.chatFilters.contains(chatFilter))
1075 1228 {
1076 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 1236 * @param chatListener
1083 1237 */
... ... @@ -1086,7 +1240,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1086 1240 if (!this.chatListeners.contains(chatListener))
1087 1241 {
1088 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 1253 if (!this.chatRenderListeners.contains(chatRenderListener))
1099 1254 {
1100 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 1262 * @param loginListener
1107 1263 */
... ... @@ -1110,10 +1266,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1110 1266 if (!this.preLoginListeners.contains(loginListener))
1111 1267 {
1112 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 1275 * @param loginListener
1119 1276 */
... ... @@ -1122,10 +1279,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1122 1279 if (!this.loginListeners.contains(loginListener))
1123 1280 {
1124 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 1288 * @param pluginChannelListener
1131 1289 */
... ... @@ -1134,10 +1292,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1134 1292 if (!this.pluginChannelListeners.contains(pluginChannelListener))
1135 1293 {
1136 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 1301 * Enumerate classes on the classpath which are subclasses of the specified
1143 1302 * class
... ... @@ -1235,7 +1394,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1235 1394 private static void enumerateDirectory(String prefix, Class superClass, ClassLoader classloader, LinkedList<Class> classes, File packagePath, String packageName, int depth)
1236 1395 {
1237 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 1400 File[] classFiles = packagePath.listFiles();
1241 1401  
... ... @@ -1287,7 +1447,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1287 1447 /**
1288 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 1453 private boolean addURLToClassPath(URL classUrl)
1293 1454 {
... ... @@ -1307,7 +1468,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1307 1468  
1308 1469 return false;
1309 1470 }
1310   -
  1471 +
1311 1472 /**
1312 1473 * Late initialisation callback
1313 1474 */
... ... @@ -1331,7 +1492,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1331 1492 }
1332 1493 }
1333 1494 }
1334   -
  1495 +
1335 1496 /**
1336 1497 * Callback from the tick hook, pre render
1337 1498 */
... ... @@ -1345,31 +1506,33 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1345 1506 GuiScreen parentScreen = PrivateFields.guiControlsParentScreen.get((GuiControls)this.minecraft.currentScreen);
1346 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 1514 for (RenderListener renderListener : this.renderListeners)
1352 1515 renderListener.onRender();
1353 1516 }
1354   -
  1517 +
1355 1518 /**
1356 1519 * Callback from the tick hook, post render entities
1357 1520 */
1358 1521 public void postRenderEntities()
1359 1522 {
1360 1523 float partialTicks = (this.minecraftTimer != null) ? this.minecraftTimer.elapsedPartialTicks : 0.0F;
1361   -
  1524 +
1362 1525 for (PostRenderListener renderListener : this.postRenderListeners)
1363 1526 renderListener.onPostRenderEntities(partialTicks);
1364 1527 }
1365   -
  1528 +
1366 1529 /**
1367 1530 * Callback from the tick hook, post render
1368 1531 */
1369 1532 public void postRender()
1370 1533 {
1371 1534 float partialTicks = (this.minecraftTimer != null) ? this.minecraftTimer.elapsedPartialTicks : 0.0F;
1372   -
  1535 +
1373 1536 for (PostRenderListener renderListener : this.postRenderListeners)
1374 1537 renderListener.onPostRender(partialTicks);
1375 1538 }
... ... @@ -1382,7 +1545,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1382 1545 for (RenderListener renderListener : this.renderListeners)
1383 1546 renderListener.onRenderGui(this.minecraft.currentScreen);
1384 1547 }
1385   -
  1548 +
1386 1549 /**
1387 1550 * Called immediately after the world/camera transform is initialised
1388 1551 */
... ... @@ -1397,64 +1560,70 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1397 1560 */
1398 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 1569 for (ChatRenderListener chatRenderListener : this.chatRenderListeners)
1407 1570 chatRenderListener.onPreRenderChat(screenWidth, screenHeight, chat);
1408 1571 }
1409   -
  1572 +
1410 1573 /**
1411 1574 * Called immediately after the chat log is rendered
1412 1575 */
1413 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 1583 for (ChatRenderListener chatRenderListener : this.chatRenderListeners)
1421 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 1590 public void onTimerUpdate()
1428 1591 {
1429 1592 for (GameLoopListener loopListener : this.loopListeners)
1430 1593 loopListener.onRunGameLoop(this.minecraft);
1431 1594 }
1432   -
  1595 +
1433 1596 /**
1434 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 1602 public void onTick(Profiler profiler, boolean tick)
1439 1603 {
1440 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 1608 if (tick || this.minecraftTimer == null)
1444 1609 {
1445 1610 this.minecraftTimer = PrivateFields.minecraftTimer.get(this.minecraft);
1446 1611 }
1447   -
  1612 +
1448 1613 // Hooray, we got the timer reference
1449 1614 if (this.minecraftTimer != null)
1450 1615 {
1451 1616 partialTicks = this.minecraftTimer.renderPartialTicks;
1452 1617 tick = this.minecraftTimer.elapsedTicks > 0;
1453 1618 }
1454   -
  1619 +
1455 1620 // Flag indicates whether we are in game at the moment
1456 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 1627 // Iterate tickable mods
1459 1628 for (Tickable tickable : this.tickListeners)
1460 1629 {
... ... @@ -1472,18 +1641,25 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1472 1641 */
1473 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 1652 for (ChatFilter chatFilter : this.chatFilters)
1477   - if (!chatFilter.onChat(chatPacket))
  1653 + if (!chatFilter.onChat(chatPacket, chat, message))
1478 1654 return false;
1479 1655  
1480 1656 // Chat listeners get the chat if no filter removed it
1481 1657 for (ChatListener chatListener : this.chatListeners)
1482   - chatListener.onChat(chatPacket.message);
  1658 + chatListener.onChat(chat, message);
1483 1659  
1484 1660 return true;
1485 1661 }
1486   -
  1662 +
1487 1663 /**
1488 1664 * Pre-login callback from the login hook
1489 1665 *
... ... @@ -1511,6 +1687,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1511 1687 */
1512 1688 public void onConnectToServer(NetHandler netHandler, Packet1Login loginPacket)
1513 1689 {
  1690 + permissionsManager.onLogin(netHandler, loginPacket);
  1691 +
1514 1692 for (LoginListener loginListener : this.loginListeners)
1515 1693 loginListener.onLogin(netHandler, loginPacket);
1516 1694  
... ... @@ -1526,13 +1704,23 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1526 1704 {
1527 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 1715 for (PluginChannelListener pluginChannelListener : this.pluginChannels.get(hookPluginChannels.channel))
1530 1716 {
1531 1717 try
1532 1718 {
1533 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 1728 /**
1541 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 1736 public void sendPluginChannelMessage(String channel, byte[] data)
1547 1737 {
... ... @@ -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 1744 protected void setupPluginChannels()
1555 1745 {
1556 1746 // Clear any channels from before
1557 1747 this.pluginChannels.clear();
1558 1748  
  1749 + // Add the permissions manager channels
  1750 + this.addPluginChannelsFor(permissionsManager);
  1751 +
1559 1752 // Enumerate mods for plugin channels
1560 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 1758 // If any mods have registered channels, send the REGISTER packet
1582 1759 if (this.pluginChannels.keySet().size() > 0)
1583 1760 {
... ... @@ -1586,7 +1763,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1586 1763  
1587 1764 for (String channel : this.pluginChannels.keySet())
1588 1765 {
1589   - if (separator) channelList.append("\u0000");
  1766 + if (separator)
  1767 + channelList.append("\u0000");
1590 1768 channelList.append(channel);
1591 1769 separator = true;
1592 1770 }
... ... @@ -1596,18 +1774,53 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1596 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 1812 @Override
1604 1813 public void addServerStatsToSnooper(PlayerUsageSnooper var1)
1605 1814 {
1606 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 1825 @Override
1613 1826 public void addServerTypeToSnooper(PlayerUsageSnooper var1)
... ... @@ -1615,8 +1828,10 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1615 1828 this.sanityCheck();
1616 1829 this.minecraft.addServerTypeToSnooper(var1);
1617 1830 }
1618   -
1619   - /* (non-Javadoc)
  1831 +
  1832 + /*
  1833 + * (non-Javadoc)
  1834 + *
1620 1835 * @see net.minecraft.src.IPlayerUsage#isSnooperEnabled()
1621 1836 */
1622 1837 @Override
... ... @@ -1624,8 +1839,10 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage
1624 1839 {
1625 1840 return this.minecraft.isSnooperEnabled();
1626 1841 }
1627   -
1628   - /* (non-Javadoc)
  1842 +
  1843 + /*
  1844 + * (non-Javadoc)
  1845 + *
1629 1846 * @see net.minecraft.src.IPlayerUsage#getLogAgent()
1630 1847 */
1631 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 6 import net.minecraft.src.GuiButton;
7 7 import net.minecraft.src.GuiScreen;
8 8 import net.minecraft.src.GuiSmallButton;
  9 +import net.minecraft.src.I18n;
9 10 import net.minecraft.src.KeyBinding;
10   -import net.minecraft.src.StringTranslate;
11 11  
12 12 /**
13 13 * Extended "Controls" screen with pages
... ... @@ -83,7 +83,6 @@ public class GuiControlsPaginated extends GuiScreen
83 83 @Override
84 84 public void initGui()
85 85 {
86   - StringTranslate stringtranslate = StringTranslate.getInstance();
87 86 this.getLegacyControlList().clear();
88 87  
89 88 int oldControlsPerPage = this.controlsPerPage;
... ... @@ -106,17 +105,17 @@ public class GuiControlsPaginated extends GuiScreen
106 105 {
107 106 this.getLegacyControlList().add(this.btnNext = new GuiButton(201, this.getWidth() / 2 - 51, buttonY, 50, 20, ">>"));
108 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 110 this.btnNext.enabled = this.startIndex < this.endIndex;
112 111 this.btnPrevious.enabled = this.startIndex > 0;
113 112 }
114 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 9 import com.mumfrey.liteloader.core.LiteLoader;
10 10  
11 11 import net.minecraft.client.ClientBrandRetriever;
12   -import net.minecraft.client.Minecraft;
  12 +import net.minecraft.src.Minecraft;
13 13 import net.minecraft.src.*;
14 14  
15 15 public abstract class ModUtilities
... ...
java/com/mumfrey/liteloader/util/PrivateFields.java
... ... @@ -4,7 +4,7 @@ import java.lang.reflect.Field;
4 4 import java.lang.reflect.Modifier;
5 5 import java.util.Map;
6 6  
7   -import net.minecraft.client.Minecraft;
  7 +import net.minecraft.src.Minecraft;
8 8 import net.minecraft.src.*;
9 9  
10 10 /**
... ... @@ -15,7 +15,7 @@ import net.minecraft.src.*;
15 15 * @param <P> Parent class type, the type of the class that owns the field
16 16 * @param <T> Field type, the type of the field value
17 17 *
18   - * TODO Obfuscation - updated 1.5.2
  18 + * TODO Obfuscation - updated 1.6.2
19 19 */
20 20 @SuppressWarnings("rawtypes")
21 21 public class PrivateFields<P, T>
... ... @@ -70,7 +70,7 @@ public class PrivateFields&lt;P, T&gt;
70 70 {
71 71 try
72 72 {
73   - Field field = parentClass.getDeclaredField(fieldName);
  73 + Field field = this.parentClass.getDeclaredField(this.fieldName);
74 74 field.setAccessible(true);
75 75 return (T)field.get(instance);
76 76 }
... ... @@ -79,7 +79,7 @@ public class PrivateFields&lt;P, T&gt;
79 79 return null;
80 80 }
81 81 }
82   -
  82 +
83 83 /**
84 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 91 {
92 92 try
93 93 {
94   - Field field = parentClass.getDeclaredField(fieldName);
  94 + Field field = this.parentClass.getDeclaredField(this.fieldName);
95 95 field.setAccessible(true);
96 96 field.set(instance, value);
97 97 }
98   - catch (Exception ex) {}
  98 + catch (Exception ex) { }
99 99  
100 100 return value;
101 101 }
... ... @@ -114,12 +114,12 @@ public class PrivateFields&lt;P, T&gt;
114 114 Field modifiers = Field.class.getDeclaredField("modifiers");
115 115 modifiers.setAccessible(true);
116 116  
117   - Field field = parentClass.getDeclaredField(fieldName);
  117 + Field field = this.parentClass.getDeclaredField(fieldName);
118 118 modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
119 119 field.setAccessible(true);
120 120 field.set(instance, value);
121 121 }
122   - catch (Exception ex) {}
  122 + catch (Exception ex) { }
123 123  
124 124 return value;
125 125 }
... ... @@ -141,8 +141,8 @@ public class PrivateFields&lt;P, T&gt;
141 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 146 public static final PrivateFields<RenderManager, Map> entityRenderMap = new PrivateFields<RenderManager, Map> (RenderManager.class, "entityRenderMap", "q", "field_78729_o"); // RenderManager/entityRenderMap
147 147 public static final PrivateFields<GuiControls, GuiScreen> guiControlsParentScreen = new PrivateFields<GuiControls, GuiScreen> (GuiControls.class, "parentScreen", "b", "field_73909_b"); // GuiControls/parentScreen
148 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   -}