Commit 4e3e54ae64c23c62d860514b105283e96c61d780

Authored by Mumfrey
1 parent 95b3fc7d

LiteLoader 1.5.2

+ Added paginated "Controls" GUI based on the Macros one
 + Added new interfaces GameLoopListener and ChatRenderListener
 + Added sanity check for profiler hook
 + Added more descriptive exception for when mods screw up the profiler stack so that it's clearer that it's not LiteLoader's fault
java/com/mumfrey/liteloader/ChatRenderListener.java 0 → 100644
  1 +package com.mumfrey.liteloader;
  2 +
  3 +import net.minecraft.src.GuiNewChat;
  4 +
  5 +/**
  6 + * Interface for mods which want to alter the chat display
  7 + *
  8 + * @author Adam Mummery-Smith
  9 + */
  10 +public interface ChatRenderListener extends LiteMod
  11 +{
  12 + public abstract void onPreRenderChat(int screenWidth, int screenHeight, GuiNewChat chat);
  13 +
  14 + public abstract void onPostRenderChat(int screenWidth, int screenHeight, GuiNewChat chat);
  15 +}
java/com/mumfrey/liteloader/GameLoopListener.java 0 → 100644
  1 +package com.mumfrey.liteloader;
  2 +
  3 +import net.minecraft.client.Minecraft;
  4 +
  5 +/**
  6 + * Interface for mods which want a frame notification every single game loop
  7 + *
  8 + * @author Adam Mummery-Smith
  9 + */
  10 +public interface GameLoopListener
  11 +{
  12 + /**
  13 + * Called every frame, before the world is ticked
  14 + *
  15 + * @param minecraft
  16 + */
  17 + public abstract void onRunGameLoop(Minecraft minecraft);
  18 +}
java/com/mumfrey/liteloader/core/HookProfiler.java
@@ -3,6 +3,7 @@ package com.mumfrey.liteloader.core; @@ -3,6 +3,7 @@ package com.mumfrey.liteloader.core;
3 import java.lang.reflect.Field; 3 import java.lang.reflect.Field;
4 import java.lang.reflect.Method; 4 import java.lang.reflect.Method;
5 import java.util.LinkedList; 5 import java.util.LinkedList;
  6 +import java.util.NoSuchElementException;
6 import java.util.logging.Logger; 7 import java.util.logging.Logger;
7 8
8 import net.minecraft.client.Minecraft; 9 import net.minecraft.client.Minecraft;
@@ -65,7 +66,7 @@ public class HookProfiler extends Profiler @@ -65,7 +66,7 @@ public class HookProfiler extends Profiler
65 this.logger = logger; 66 this.logger = logger;
66 67
67 // Detect optifine (duh!) 68 // Detect optifine (duh!)
68 - detectOptifine(); 69 + this.detectOptifine();
69 } 70 }
70 71
71 /** 72 /**
@@ -77,18 +78,18 @@ public class HookProfiler extends Profiler @@ -77,18 +78,18 @@ public class HookProfiler extends Profiler
77 { 78 {
78 try 79 try
79 { 80 {
80 - ofProfiler = GameSettings.class.getDeclaredField("ofProfiler"); 81 + this.ofProfiler = GameSettings.class.getDeclaredField("ofProfiler");
81 } 82 }
82 catch (SecurityException ex) {} 83 catch (SecurityException ex) {}
83 catch (NoSuchFieldException ex) 84 catch (NoSuchFieldException ex)
84 { 85 {
85 - logger.info("Optifine not detected"); 86 + this.logger.info("Optifine not detected");
86 } 87 }
87 finally 88 finally
88 { 89 {
89 - if (ofProfiler != null) 90 + if (this.ofProfiler != null)
90 { 91 {
91 - logger.info(String.format("Optifine version %s detected, enabling compatibility check", getOptifineVersion())); 92 + this.logger.info(String.format("Optifine version %s detected, enabling compatibility check", this.getOptifineVersion()));
92 } 93 }
93 } 94 }
94 } 95 }
@@ -125,44 +126,54 @@ public class HookProfiler extends Profiler @@ -125,44 +126,54 @@ public class HookProfiler extends Profiler
125 @Override 126 @Override
126 public void startSection(String sectionName) 127 public void startSection(String sectionName)
127 { 128 {
128 - if (!initDone) 129 + if (!this.initDone)
129 { 130 {
130 - initDone = true;  
131 - loader.onInit(); 131 + this.initDone = true;
  132 + this.loader.onInit();
132 } 133 }
133 134
134 - if ("gameRenderer".equals(sectionName) && "root".equals(sectionStack.getLast())) 135 + if ("gameRenderer".equals(sectionName) && "root".equals(this.sectionStack.getLast()))
135 { 136 {
136 - loader.onRender(); 137 + this.loader.onRender();
137 } 138 }
138 139
139 - if ("frustrum".equals(sectionName) && "level".equals(sectionStack.getLast())) 140 + if ("frustrum".equals(sectionName) && "level".equals(this.sectionStack.getLast()))
140 { 141 {
141 - loader.onSetupCameraTransform(); 142 + this.loader.onSetupCameraTransform();
142 } 143 }
143 144
144 if ("litParticles".equals(sectionName)) 145 if ("litParticles".equals(sectionName))
145 { 146 {
146 - loader.postRenderEntities(); 147 + this.loader.postRenderEntities();
147 } 148 }
148 149
149 - if ("animateTick".equals(sectionName)) tick = true;  
150 - sectionStack.add(sectionName); 150 + if ("tick".equals(sectionName) && "root".equals(this.sectionStack.getLast()))
  151 + {
  152 + this.loader.onTimerUpdate();
  153 + }
  154 +
  155 + if ("chat".equals(sectionName))
  156 + {
  157 + this.loader.onBeforeChatRender();
  158 + }
  159 +
  160 + if ("animateTick".equals(sectionName)) this.tick = true;
  161 + this.sectionStack.add(sectionName);
151 super.startSection(sectionName); 162 super.startSection(sectionName);
152 163
153 - if (ofProfiler != null) 164 + if (this.ofProfiler != null)
154 { 165 {
155 try 166 try
156 { 167 {
157 - ofProfiler.set(mc.gameSettings, true); 168 + this.ofProfiler.set(this.mc.gameSettings, true);
158 } 169 }
159 catch (IllegalArgumentException ex) 170 catch (IllegalArgumentException ex)
160 { 171 {
161 - ofProfiler = null; 172 + this.ofProfiler = null;
162 } 173 }
163 catch (IllegalAccessException ex) 174 catch (IllegalAccessException ex)
164 { 175 {
165 - ofProfiler = null; 176 + this.ofProfiler = null;
166 } 177 }
167 } 178 }
168 } 179 }
@@ -175,25 +186,37 @@ public class HookProfiler extends Profiler @@ -175,25 +186,37 @@ public class HookProfiler extends Profiler
175 { 186 {
176 super.endSection(); 187 super.endSection();
177 188
178 - String endingSection = sectionStack.size() > 0 ? sectionStack.removeLast() : null;  
179 - String nextSection = sectionStack.size() > 0 ? sectionStack.getLast() : null;  
180 -  
181 - if ("gameRenderer".equals(endingSection) && "root".equals(sectionStack.getLast())) 189 + try
182 { 190 {
183 - super.startSection("litetick");  
184 -  
185 - loader.onTick(this, tick);  
186 - tick = false; 191 + String endingSection = this.sectionStack.size() > 0 ? this.sectionStack.removeLast() : null;
  192 + String nextSection = this.sectionStack.size() > 0 ? this.sectionStack.getLast() : null;
187 193
188 - super.endSection();  
189 - }  
190 - else if (("mouse".equals(endingSection) && "gameRenderer".equals(nextSection) && (mc.skipRenderWorld || mc.theWorld == null)) || ("gui".equals(endingSection) && "gameRenderer".equals(nextSection) && mc.theWorld != null))  
191 - {  
192 - loader.onBeforeGuiRender(); 194 + if ("gameRenderer".equals(endingSection) && "root".equals(this.sectionStack.getLast()))
  195 + {
  196 + super.startSection("litetick");
  197 +
  198 + this.loader.onTick(this, this.tick);
  199 + this.tick = false;
  200 +
  201 + super.endSection();
  202 + }
  203 + else if (("mouse".equals(endingSection) && "gameRenderer".equals(nextSection) && (this.mc.skipRenderWorld || this.mc.theWorld == null)) || ("gui".equals(endingSection) && "gameRenderer".equals(nextSection) && this.mc.theWorld != null))
  204 + {
  205 + this.loader.onBeforeGuiRender();
  206 + }
  207 + else if ("hand".equals(endingSection) && "level".equals(this.sectionStack.getLast()))
  208 + {
  209 + this.loader.postRender();
  210 + }
  211 + else if ("chat".equals(endingSection))
  212 + {
  213 + this.loader.onAfterChatRender();
  214 + }
193 } 215 }
194 - else if ("hand".equals(endingSection) && "level".equals(sectionStack.getLast())) 216 + catch (NoSuchElementException ex)
195 { 217 {
196 - loader.postRender(); 218 + this.logger.severe("Corrupted Profiler stack detected, this indicates an error with one of your mods.");
  219 + throw new ProfilerStackCorruptionException("Corrupted Profiler stack detected");
197 } 220 }
198 } 221 }
199 } 222 }
java/com/mumfrey/liteloader/core/LiteLoader.java
@@ -34,14 +34,23 @@ import java.util.zip.ZipInputStream; @@ -34,14 +34,23 @@ import java.util.zip.ZipInputStream;
34 import javax.activity.InvalidActivityException; 34 import javax.activity.InvalidActivityException;
35 35
36 import net.minecraft.client.Minecraft; 36 import net.minecraft.client.Minecraft;
  37 +import net.minecraft.src.GuiControls;
  38 +import net.minecraft.src.GuiNewChat;
  39 +import net.minecraft.src.GuiScreen;
  40 +import net.minecraft.src.ILogAgent;
  41 +import net.minecraft.src.IPlayerUsage;
37 import net.minecraft.src.NetHandler; 42 import net.minecraft.src.NetHandler;
38 import net.minecraft.src.Packet1Login; 43 import net.minecraft.src.Packet1Login;
39 import net.minecraft.src.Packet3Chat; 44 import net.minecraft.src.Packet3Chat;
  45 +import net.minecraft.src.PlayerUsageSnooper;
40 import net.minecraft.src.Profiler; 46 import net.minecraft.src.Profiler;
  47 +import net.minecraft.src.ScaledResolution;
41 import net.minecraft.src.Timer; 48 import net.minecraft.src.Timer;
42 49
43 import com.mumfrey.liteloader.ChatFilter; 50 import com.mumfrey.liteloader.ChatFilter;
44 import com.mumfrey.liteloader.ChatListener; 51 import com.mumfrey.liteloader.ChatListener;
  52 +import com.mumfrey.liteloader.ChatRenderListener;
  53 +import com.mumfrey.liteloader.GameLoopListener;
45 import com.mumfrey.liteloader.InitCompleteListener; 54 import com.mumfrey.liteloader.InitCompleteListener;
46 import com.mumfrey.liteloader.LiteMod; 55 import com.mumfrey.liteloader.LiteMod;
47 import com.mumfrey.liteloader.LoginListener; 56 import com.mumfrey.liteloader.LoginListener;
@@ -50,34 +59,35 @@ import com.mumfrey.liteloader.PostRenderListener; @@ -50,34 +59,35 @@ import com.mumfrey.liteloader.PostRenderListener;
50 import com.mumfrey.liteloader.PreLoginListener; 59 import com.mumfrey.liteloader.PreLoginListener;
51 import com.mumfrey.liteloader.RenderListener; 60 import com.mumfrey.liteloader.RenderListener;
52 import com.mumfrey.liteloader.Tickable; 61 import com.mumfrey.liteloader.Tickable;
  62 +import com.mumfrey.liteloader.gui.GuiControlsPaginated;
53 import com.mumfrey.liteloader.util.ModUtilities; 63 import com.mumfrey.liteloader.util.ModUtilities;
54 import com.mumfrey.liteloader.util.PrivateFields; 64 import com.mumfrey.liteloader.util.PrivateFields;
55 65
56 /** 66 /**
57 - * LiteLoader is a simple loader which provides tick events to loaded mods 67 + * LiteLoader is a simple loader which loads and provides useful callbacks to lightweight mods
58 * 68 *
59 * @author Adam Mummery-Smith 69 * @author Adam Mummery-Smith
60 - * @version 1.5.1 70 + * @version 1.5.2
61 */ 71 */
62 @SuppressWarnings("rawtypes") 72 @SuppressWarnings("rawtypes")
63 -public final class LiteLoader implements FilenameFilter 73 +public final class LiteLoader implements FilenameFilter, IPlayerUsage
64 { 74 {
65 /** 75 /**
66 * Liteloader version 76 * Liteloader version
67 */ 77 */
68 - private static final String LOADER_VERSION = "1.5.1"; 78 + private static final String LOADER_VERSION = "1.5.2";
69 79
70 /** 80 /**
71 * Loader revision, can be used by mods to determine whether the loader is sufficiently up-to-date 81 * Loader revision, can be used by mods to determine whether the loader is sufficiently up-to-date
72 */ 82 */
73 - private static final int LOADER_REVISION = 8; 83 + private static final int LOADER_REVISION = 9;
74 84
75 /** 85 /**
76 * Minecraft versions that we will load mods for, this will be compared 86 * Minecraft versions that we will load mods for, this will be compared
77 * against the version.txt value in mod files to prevent outdated mods being 87 * against the version.txt value in mod files to prevent outdated mods being
78 * loaded!!! 88 * loaded!!!
79 */ 89 */
80 - private static final String[] SUPPORTED_VERSIONS = { "1.5.1", "1.5.r2" }; 90 + private static final String[] SUPPORTED_VERSIONS = { "1.5.2", "1.5.r1" };
81 91
82 /** 92 /**
83 * Maximum recursion depth for mod discovery 93 * Maximum recursion depth for mod discovery
@@ -130,6 +140,11 @@ public final class LiteLoader implements FilenameFilter @@ -130,6 +140,11 @@ public final class LiteLoader implements FilenameFilter
130 private String branding = null; 140 private String branding = null;
131 141
132 /** 142 /**
  143 + * Setting value, if true we will swap out the MC "Controls" GUI for our custom, paginated one
  144 + */
  145 + private boolean paginateControls = true;
  146 +
  147 + /**
133 * Reference to the minecraft timer 148 * Reference to the minecraft timer
134 */ 149 */
135 private Timer minecraftTimer; 150 private Timer minecraftTimer;
@@ -151,6 +166,11 @@ public final class LiteLoader implements FilenameFilter @@ -151,6 +166,11 @@ public final class LiteLoader implements FilenameFilter
151 private LinkedList<Tickable> tickListeners = new LinkedList<Tickable>(); 166 private LinkedList<Tickable> tickListeners = new LinkedList<Tickable>();
152 167
153 /** 168 /**
  169 + * List of mods which implement the GameLoopListener interface and will receive loop events
  170 + */
  171 + private LinkedList<GameLoopListener> loopListeners = new LinkedList<GameLoopListener>();
  172 +
  173 + /**
154 * 174 *
155 */ 175 */
156 private LinkedList<InitCompleteListener> initListeners = new LinkedList<InitCompleteListener>(); 176 private LinkedList<InitCompleteListener> initListeners = new LinkedList<InitCompleteListener>();
@@ -167,6 +187,11 @@ public final class LiteLoader implements FilenameFilter @@ -167,6 +187,11 @@ public final class LiteLoader implements FilenameFilter
167 private LinkedList<PostRenderListener> postRenderListeners = new LinkedList<PostRenderListener>(); 187 private LinkedList<PostRenderListener> postRenderListeners = new LinkedList<PostRenderListener>();
168 188
169 /** 189 /**
  190 + * List of mods which implement ChatRenderListener and want to know when chat is rendered
  191 + */
  192 + private LinkedList<ChatRenderListener> chatRenderListeners = new LinkedList<ChatRenderListener>();
  193 +
  194 + /**
170 * List of mods which implement ChatListener interface and will receive chat 195 * List of mods which implement ChatListener interface and will receive chat
171 * events 196 * events
172 */ 197 */
@@ -212,6 +237,16 @@ public final class LiteLoader implements FilenameFilter @@ -212,6 +237,16 @@ public final class LiteLoader implements FilenameFilter
212 * Flags which keep track of whether hooks have been applied 237 * Flags which keep track of whether hooks have been applied
213 */ 238 */
214 private boolean chatHooked, loginHooked, pluginChannelHooked, tickHooked; 239 private boolean chatHooked, loginHooked, pluginChannelHooked, tickHooked;
  240 +
  241 + /**
  242 + * Profiler hook objects
  243 + */
  244 + private HookProfiler profilerHook = new HookProfiler(this, logger);
  245 +
  246 + /**
  247 + * ScaledResolution used by the pre-chat and post-chat render callbacks
  248 + */
  249 + private ScaledResolution currentResolution;
215 250
216 /** 251 /**
217 * Get the singleton instance of LiteLoader, initialises the loader if necessary 252 * Get the singleton instance of LiteLoader, initialises the loader if necessary
@@ -399,6 +434,9 @@ public final class LiteLoader implements FilenameFilter @@ -399,6 +434,9 @@ public final class LiteLoader implements FilenameFilter
399 // Prepare the log writer 434 // Prepare the log writer
400 this.prepareLogger(); 435 this.prepareLogger();
401 436
  437 + this.paginateControls = this.localProperties.getProperty("controls.pages", "true").equalsIgnoreCase("true");
  438 + this.localProperties.setProperty("controls.pages", String.valueOf(this.paginateControls));
  439 +
402 this.branding = this.internalProperties.getProperty("brand", null); 440 this.branding = this.internalProperties.getProperty("brand", null);
403 if (this.branding != null && this.branding.length() < 1) this.branding = null; 441 if (this.branding != null && this.branding.length() < 1) this.branding = null;
404 442
@@ -652,7 +690,7 @@ public final class LiteLoader implements FilenameFilter @@ -652,7 +690,7 @@ public final class LiteLoader implements FilenameFilter
652 versionReader.close(); 690 versionReader.close();
653 691
654 // Only add the mod if the version matches and we were able to successfully add it to the class path 692 // Only add the mod if the version matches and we were able to successfully add it to the class path
655 - if (supportedVerions.contains(strVersion) && addURLToClassPath(modFile.toURI().toURL())) 693 + if (supportedVerions.contains(strVersion) && this.addURLToClassPath(modFile.toURI().toURL()))
656 { 694 {
657 modFiles.add(modFile); 695 modFiles.add(modFile);
658 } 696 }
@@ -834,7 +872,7 @@ public final class LiteLoader implements FilenameFilter @@ -834,7 +872,7 @@ public final class LiteLoader implements FilenameFilter
834 this.loadedModsList = ""; 872 this.loadedModsList = "";
835 int loadedModsCount = 0; 873 int loadedModsCount = 0;
836 874
837 - for (Iterator<LiteMod> iter = mods.iterator(); iter.hasNext();) 875 + for (Iterator<LiteMod> iter = this.mods.iterator(); iter.hasNext();)
838 { 876 {
839 LiteMod mod = iter.next(); 877 LiteMod mod = iter.next();
840 878
@@ -848,6 +886,11 @@ public final class LiteLoader implements FilenameFilter @@ -848,6 +886,11 @@ public final class LiteLoader implements FilenameFilter
848 { 886 {
849 this.addTickListener((Tickable)mod); 887 this.addTickListener((Tickable)mod);
850 } 888 }
  889 +
  890 + if (mod instanceof GameLoopListener)
  891 + {
  892 + this.addLoopListener((GameLoopListener)mod);
  893 + }
851 894
852 if (mod instanceof InitCompleteListener) 895 if (mod instanceof InitCompleteListener)
853 { 896 {
@@ -881,6 +924,11 @@ public final class LiteLoader implements FilenameFilter @@ -881,6 +924,11 @@ public final class LiteLoader implements FilenameFilter
881 } 924 }
882 } 925 }
883 926
  927 + if (mod instanceof ChatRenderListener)
  928 + {
  929 + this.addChatRenderListener((ChatRenderListener)mod);
  930 + }
  931 +
884 if (mod instanceof PreLoginListener) 932 if (mod instanceof PreLoginListener)
885 { 933 {
886 this.addPreLoginListener((PreLoginListener)mod); 934 this.addPreLoginListener((PreLoginListener)mod);
@@ -944,8 +992,12 @@ public final class LiteLoader implements FilenameFilter @@ -944,8 +992,12 @@ public final class LiteLoader implements FilenameFilter
944 if (!this.tickHooked) 992 if (!this.tickHooked)
945 { 993 {
946 this.tickHooked = true; 994 this.tickHooked = true;
947 - PrivateFields.minecraftProfiler.setFinal(this.minecraft, new HookProfiler(this, logger)); 995 + PrivateFields.minecraftProfiler.setFinal(this.minecraft, this.profilerHook);
948 } 996 }
  997 +
  998 + // Sanity hook
  999 + PlayerUsageSnooper snooper = this.minecraft.getPlayerUsageSnooper();
  1000 + PrivateFields.playerStatsCollector.setFinal(snooper, this);
949 } 1001 }
950 catch (Exception ex) 1002 catch (Exception ex)
951 { 1003 {
@@ -967,6 +1019,18 @@ public final class LiteLoader implements FilenameFilter @@ -967,6 +1019,18 @@ public final class LiteLoader implements FilenameFilter
967 } 1019 }
968 1020
969 /** 1021 /**
  1022 + * @param loopListener
  1023 + */
  1024 + public void addLoopListener(GameLoopListener loopListener)
  1025 + {
  1026 + if (!this.loopListeners.contains(loopListener))
  1027 + {
  1028 + this.loopListeners.add(loopListener);
  1029 + if (this.loaderStartupComplete) this.initHooks();
  1030 + }
  1031 + }
  1032 +
  1033 + /**
970 * @param initCompleteListener 1034 * @param initCompleteListener
971 */ 1035 */
972 public void addInitListener(InitCompleteListener initCompleteListener) 1036 public void addInitListener(InitCompleteListener initCompleteListener)
@@ -1025,6 +1089,18 @@ public final class LiteLoader implements FilenameFilter @@ -1025,6 +1089,18 @@ public final class LiteLoader implements FilenameFilter
1025 if (this.loaderStartupComplete) this.initHooks(); 1089 if (this.loaderStartupComplete) this.initHooks();
1026 } 1090 }
1027 } 1091 }
  1092 +
  1093 + /**
  1094 + * @param chatRenderListener
  1095 + */
  1096 + public void addChatRenderListener(ChatRenderListener chatRenderListener)
  1097 + {
  1098 + if (!this.chatRenderListeners.contains(chatRenderListener))
  1099 + {
  1100 + this.chatRenderListeners.add(chatRenderListener);
  1101 + if (this.loaderStartupComplete) this.initHooks();
  1102 + }
  1103 + }
1028 1104
1029 /** 1105 /**
1030 * @param loginListener 1106 * @param loginListener
@@ -1261,6 +1337,17 @@ public final class LiteLoader implements FilenameFilter @@ -1261,6 +1337,17 @@ public final class LiteLoader implements FilenameFilter
1261 */ 1337 */
1262 public void onRender() 1338 public void onRender()
1263 { 1339 {
  1340 + if (this.paginateControls && this.minecraft.currentScreen != null && this.minecraft.currentScreen.getClass().equals(GuiControls.class))
  1341 + {
  1342 + try
  1343 + {
  1344 + // Try to get the parent screen entry from the existing screen
  1345 + GuiScreen parentScreen = PrivateFields.guiControlsParentScreen.get((GuiControls)this.minecraft.currentScreen);
  1346 + this.minecraft.displayGuiScreen(new GuiControlsPaginated(parentScreen, this.minecraft.gameSettings));
  1347 + }
  1348 + catch (Exception ex) { }
  1349 + }
  1350 +
1264 for (RenderListener renderListener : this.renderListeners) 1351 for (RenderListener renderListener : this.renderListeners)
1265 renderListener.onRender(); 1352 renderListener.onRender();
1266 } 1353 }
@@ -1304,6 +1391,44 @@ public final class LiteLoader implements FilenameFilter @@ -1304,6 +1391,44 @@ public final class LiteLoader implements FilenameFilter
1304 for (RenderListener renderListener : this.renderListeners) 1391 for (RenderListener renderListener : this.renderListeners)
1305 renderListener.onSetupCameraTransform(); 1392 renderListener.onSetupCameraTransform();
1306 } 1393 }
  1394 +
  1395 + /**
  1396 + * Called immediately before the chat log is rendered
  1397 + */
  1398 + public void onBeforeChatRender()
  1399 + {
  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();
  1405 +
  1406 + for (ChatRenderListener chatRenderListener : this.chatRenderListeners)
  1407 + chatRenderListener.onPreRenderChat(screenWidth, screenHeight, chat);
  1408 + }
  1409 +
  1410 + /**
  1411 + * Called immediately after the chat log is rendered
  1412 + */
  1413 + public void onAfterChatRender()
  1414 + {
  1415 + int screenWidth = this.currentResolution.getScaledWidth();
  1416 + int screenHeight = this.currentResolution.getScaledHeight();
  1417 +
  1418 + GuiNewChat chat = this.minecraft.ingameGUI.getChatGUI();
  1419 +
  1420 + for (ChatRenderListener chatRenderListener : this.chatRenderListeners)
  1421 + chatRenderListener.onPostRenderChat(screenWidth, screenHeight, chat);
  1422 + }
  1423 +
  1424 + /**
  1425 + * Callback from the tick hook, called every frame when the timer is updated
  1426 + */
  1427 + public void onTimerUpdate()
  1428 + {
  1429 + for (GameLoopListener loopListener : this.loopListeners)
  1430 + loopListener.onRunGameLoop(this.minecraft);
  1431 + }
1307 1432
1308 /** 1433 /**
1309 * Callback from the tick hook, ticks all tickable mods 1434 * Callback from the tick hook, ticks all tickable mods
@@ -1323,7 +1448,7 @@ public final class LiteLoader implements FilenameFilter @@ -1323,7 +1448,7 @@ public final class LiteLoader implements FilenameFilter
1323 // Hooray, we got the timer reference 1448 // Hooray, we got the timer reference
1324 if (this.minecraftTimer != null) 1449 if (this.minecraftTimer != null)
1325 { 1450 {
1326 - partialTicks = this.minecraftTimer.elapsedPartialTicks; 1451 + partialTicks = this.minecraftTimer.renderPartialTicks;
1327 tick = this.minecraftTimer.elapsedTicks > 0; 1452 tick = this.minecraftTimer.elapsedTicks > 0;
1328 } 1453 }
1329 1454
@@ -1389,7 +1514,7 @@ public final class LiteLoader implements FilenameFilter @@ -1389,7 +1514,7 @@ public final class LiteLoader implements FilenameFilter
1389 for (LoginListener loginListener : this.loginListeners) 1514 for (LoginListener loginListener : this.loginListeners)
1390 loginListener.onLogin(netHandler, loginPacket); 1515 loginListener.onLogin(netHandler, loginPacket);
1391 1516
1392 - setupPluginChannels(); 1517 + this.setupPluginChannels();
1393 } 1518 }
1394 1519
1395 /** 1520 /**
@@ -1468,7 +1593,55 @@ public final class LiteLoader implements FilenameFilter @@ -1468,7 +1593,55 @@ public final class LiteLoader implements FilenameFilter
1468 1593
1469 byte[] registrationData = channelList.toString().getBytes(Charset.forName("UTF8")); 1594 byte[] registrationData = channelList.toString().getBytes(Charset.forName("UTF8"));
1470 1595
1471 - sendPluginChannelMessage("REGISTER", registrationData); 1596 + this.sendPluginChannelMessage("REGISTER", registrationData);
  1597 + }
  1598 + }
  1599 +
  1600 + /* (non-Javadoc)
  1601 + * @see net.minecraft.src.IPlayerUsage#addServerStatsToSnooper(net.minecraft.src.PlayerUsageSnooper)
  1602 + */
  1603 + @Override
  1604 + public void addServerStatsToSnooper(PlayerUsageSnooper var1)
  1605 + {
  1606 + this.minecraft.addServerStatsToSnooper(var1);
  1607 + }
  1608 +
  1609 + /* (non-Javadoc)
  1610 + * @see net.minecraft.src.IPlayerUsage#addServerTypeToSnooper(net.minecraft.src.PlayerUsageSnooper)
  1611 + */
  1612 + @Override
  1613 + public void addServerTypeToSnooper(PlayerUsageSnooper var1)
  1614 + {
  1615 + this.sanityCheck();
  1616 + this.minecraft.addServerTypeToSnooper(var1);
  1617 + }
  1618 +
  1619 + /* (non-Javadoc)
  1620 + * @see net.minecraft.src.IPlayerUsage#isSnooperEnabled()
  1621 + */
  1622 + @Override
  1623 + public boolean isSnooperEnabled()
  1624 + {
  1625 + return this.minecraft.isSnooperEnabled();
  1626 + }
  1627 +
  1628 + /* (non-Javadoc)
  1629 + * @see net.minecraft.src.IPlayerUsage#getLogAgent()
  1630 + */
  1631 + @Override
  1632 + public ILogAgent getLogAgent()
  1633 + {
  1634 + return this.minecraft.getLogAgent();
  1635 + }
  1636 +
  1637 + /**
  1638 + * Check that the profiler hook hasn't been overridden by something else
  1639 + */
  1640 + private void sanityCheck()
  1641 + {
  1642 + if (this.tickHooked && this.minecraft.mcProfiler != this.profilerHook)
  1643 + {
  1644 + PrivateFields.minecraftProfiler.setFinal(this.minecraft, this.profilerHook);
1472 } 1645 }
1473 } 1646 }
1474 } 1647 }
1475 \ No newline at end of file 1648 \ No newline at end of file
java/com/mumfrey/liteloader/core/ProfilerStackCorruptionException.java 0 → 100644
  1 +package com.mumfrey.liteloader.core;
  2 +
  3 +/**
  4 + * Exception to throw when a mod corrupts the profiler stack, this avoids throwing a
  5 + * (somewhat cryptic) NoSuchElementException inside HookProfiler
  6 + *
  7 + * @author Adam Mummery-Smith
  8 + */
  9 +public class ProfilerStackCorruptionException extends RuntimeException
  10 +{
  11 + /**
  12 + *
  13 + */
  14 + private static final long serialVersionUID = -7745831270297368169L;
  15 +
  16 + public ProfilerStackCorruptionException(String message)
  17 + {
  18 + super(message);
  19 + }
  20 +}
java/com/mumfrey/liteloader/gui/GuiControlsPaginated.java 0 → 100644
  1 +package com.mumfrey.liteloader.gui;
  2 +
  3 +import java.util.List;
  4 +
  5 +import net.minecraft.src.GameSettings;
  6 +import net.minecraft.src.GuiButton;
  7 +import net.minecraft.src.GuiScreen;
  8 +import net.minecraft.src.GuiSmallButton;
  9 +import net.minecraft.src.KeyBinding;
  10 +import net.minecraft.src.StringTranslate;
  11 +
  12 +/**
  13 + * Extended "Controls" screen with pages
  14 + *
  15 + * @author Adam Mummery-Smith
  16 + */
  17 +public class GuiControlsPaginated extends GuiScreen
  18 +{
  19 + /**
  20 + * Pagination variables
  21 + */
  22 + protected int controlsPerPage, startIndex, endIndex;
  23 +
  24 + /**
  25 + * Parent screen which will be displayed when this screen is closed
  26 + */
  27 + protected GuiScreen parentScreen;
  28 +
  29 + /**
  30 + * Game settings
  31 + */
  32 + protected GameSettings gameSettings;
  33 +
  34 + /**
  35 + * Additional buttons
  36 + */
  37 + protected GuiButton btnNext, btnPrevious;
  38 +
  39 + /**
  40 + * Title to display
  41 + */
  42 + protected String screenTitle = "Controls";
  43 +
  44 + /**
  45 + * ID of the button currently being edited
  46 + */
  47 + protected int activeButtonId = -1;
  48 +
  49 + public GuiControlsPaginated(GuiScreen parentScreen, GameSettings gameSettings)
  50 + {
  51 + this.parentScreen = parentScreen;
  52 + this.gameSettings = gameSettings;
  53 +
  54 + // Pagination defaults
  55 + this.controlsPerPage = 14;
  56 + this.endIndex = this.gameSettings.keyBindings.length - (this.gameSettings.keyBindings.length % this.controlsPerPage == 0 ? this.controlsPerPage : this.gameSettings.keyBindings.length % this.controlsPerPage);
  57 + }
  58 +
  59 + @SuppressWarnings("unchecked")
  60 + protected List<GuiButton> getLegacyControlList()
  61 + {
  62 + return this.buttonList;
  63 + }
  64 +
  65 + protected final int getHeight()
  66 + {
  67 + return this.height;
  68 + }
  69 +
  70 + protected final int getWidth()
  71 + {
  72 + return this.width;
  73 + }
  74 +
  75 + public GuiScreen getParentScreen()
  76 + {
  77 + return this.parentScreen;
  78 + }
  79 +
  80 + /**
  81 + * Initialise this GUI, called when the GUI is created
  82 + */
  83 + @Override
  84 + public void initGui()
  85 + {
  86 + StringTranslate stringtranslate = StringTranslate.getInstance();
  87 + this.getLegacyControlList().clear();
  88 +
  89 + int oldControlsPerPage = this.controlsPerPage;
  90 + this.controlsPerPage = ((this.getHeight() - 70) / 24) * 2;
  91 + this.endIndex = this.gameSettings.keyBindings.length - (this.gameSettings.keyBindings.length % this.controlsPerPage == 0 ? this.controlsPerPage : this.gameSettings.keyBindings.length % this.controlsPerPage);
  92 + if (oldControlsPerPage != this.controlsPerPage) this.startIndex = 0;
  93 +
  94 + for (int controlId = 0; controlId < this.gameSettings.keyBindings.length; controlId++)
  95 + {
  96 + boolean buttonVisible = controlId >= this.startIndex && controlId < this.startIndex + this.controlsPerPage;
  97 + int left = buttonVisible ? this.getWidth() / 2 - 155 : this.getWidth() + 10000;
  98 + int top = this.getHeight() / 6 + 24 * ((controlId - this.startIndex) >> 1);
  99 + this.getLegacyControlList().add(new GuiSmallButton(controlId, left + ((controlId - this.startIndex) % 2) * 160, top, 70, 20, this.gameSettings.getOptionDisplayString(controlId)));
  100 + }
  101 +
  102 + int buttonY = this.getHeight() / 6 + (this.controlsPerPage >> 1) * 24;
  103 +
  104 + // Only bother paginating if there are too many controls to display
  105 + if (this.gameSettings.keyBindings.length > this.controlsPerPage)
  106 + {
  107 + this.getLegacyControlList().add(this.btnNext = new GuiButton(201, this.getWidth() / 2 - 51, buttonY, 50, 20, ">>"));
  108 + this.getLegacyControlList().add(this.btnPrevious = new GuiButton(202, this.getWidth() / 2 - 103, buttonY, 50, 20, "<<"));
  109 + this.getLegacyControlList().add(new GuiButton(200, this.getWidth() / 2 + 1, buttonY, 100, 20, stringtranslate.translateKey("gui.done")));
  110 +
  111 + this.btnNext.enabled = this.startIndex < this.endIndex;
  112 + this.btnPrevious.enabled = this.startIndex > 0;
  113 + }
  114 + else
  115 + {
  116 + this.getLegacyControlList().add(new GuiButton(200, this.getWidth() / 2 - 100, buttonY, stringtranslate.translateKey("gui.done")));
  117 + }
  118 +
  119 + this.screenTitle = stringtranslate.translateKey("controls.title");
  120 + }
  121 +
  122 + /**
  123 + * @param controlId
  124 + * @return
  125 + */
  126 + protected String getKeybindDescription(int controlId)
  127 + {
  128 + return this.gameSettings.getKeyBindingDescription(controlId);
  129 + }
  130 +
  131 + /**
  132 + * A button was clicked, deal with it
  133 + *
  134 + * @param guibutton Button which was clicked
  135 + */
  136 + @Override
  137 + protected void actionPerformed(GuiButton guibutton)
  138 + {
  139 + // Update the button labels with the appropriate key names
  140 + for(int i = 0; i < this.gameSettings.keyBindings.length; i++)
  141 + {
  142 + this.getLegacyControlList().get(i).displayString = this.gameSettings.getOptionDisplayString(i);
  143 + }
  144 +
  145 + if (guibutton.id == 200) // Done button
  146 + {
  147 + this.mc.displayGuiScreen(this.parentScreen);
  148 + }
  149 + else if (guibutton.id == 201) // Next button
  150 + {
  151 + this.startIndex += this.controlsPerPage;
  152 + this.startIndex = Math.min(this.endIndex, this.startIndex);
  153 + this.initGui();
  154 + }
  155 + else if (guibutton.id == 202) // Previous button
  156 + {
  157 + this.startIndex -= this.controlsPerPage;
  158 + this.startIndex = Math.max(0, this.startIndex);
  159 + this.initGui();
  160 + }
  161 + else
  162 + {
  163 + this.activeButtonId = guibutton.id;
  164 + guibutton.displayString = String.format("> %s <", this.gameSettings.getOptionDisplayString(guibutton.id));
  165 + }
  166 + }
  167 +
  168 + @Override
  169 + protected void mouseClicked(int mouseX, int mouseY, int mouseButton)
  170 + {
  171 + if (this.activeButtonId >= 0)
  172 + {
  173 + this.gameSettings.setKeyBinding(this.activeButtonId, -100 + mouseButton);
  174 + this.getLegacyControlList().get(this.activeButtonId).displayString = this.gameSettings.getOptionDisplayString(this.activeButtonId);
  175 + this.activeButtonId = -1;
  176 + KeyBinding.resetKeyBindingArrayAndHash();
  177 + }
  178 + else
  179 + {
  180 + super.mouseClicked(mouseX, mouseY, mouseButton);
  181 + }
  182 + }
  183 +
  184 + @Override
  185 + protected void keyTyped(char keyChar, int keyCode)
  186 + {
  187 + if (this.activeButtonId >= 0)
  188 + {
  189 + this.gameSettings.setKeyBinding(this.activeButtonId, keyCode);
  190 + this.getLegacyControlList().get(this.activeButtonId).displayString = this.gameSettings.getOptionDisplayString(this.activeButtonId);
  191 + this.activeButtonId = -1;
  192 + KeyBinding.resetKeyBindingArrayAndHash();
  193 + }
  194 + else
  195 + {
  196 + super.keyTyped(keyChar, keyCode);
  197 + }
  198 + }
  199 +
  200 + @Override
  201 + public void drawScreen(int mouseX, int mouseY, float partialTick)
  202 + {
  203 + this.drawDefaultBackground();
  204 + this.drawCenteredString(this.fontRenderer, this.screenTitle, this.width / 2, 20, 0xffffff);
  205 +
  206 + // Draw key labels
  207 + for (int controlId = 0; controlId < this.gameSettings.keyBindings.length; controlId++)
  208 + {
  209 + boolean conflict = false;
  210 +
  211 + for (int id = 0; id < this.gameSettings.keyBindings.length; id++)
  212 + {
  213 + if (id != controlId && this.gameSettings.keyBindings[controlId].keyCode == this.gameSettings.keyBindings[id].keyCode)
  214 + {
  215 + conflict = true;
  216 + break;
  217 + }
  218 + }
  219 +
  220 + if (this.activeButtonId == controlId)
  221 + {
  222 + this.getLegacyControlList().get(controlId).displayString = "\247f> \247e??? \247f<";
  223 + }
  224 + else if (conflict)
  225 + {
  226 + this.getLegacyControlList().get(controlId).displayString = "\247c" + this.gameSettings.getOptionDisplayString(controlId);
  227 + }
  228 + else
  229 + {
  230 + this.getLegacyControlList().get(controlId).displayString = this.gameSettings.getOptionDisplayString(controlId);
  231 + }
  232 +
  233 + int left = (controlId >= this.startIndex && controlId < this.startIndex + this.controlsPerPage) ? this.getWidth() / 2 - 155 : this.getWidth() + 10000;
  234 + this.drawString(this.fontRenderer, this.getKeybindDescription(controlId), left + ((controlId - this.startIndex) % 2) * 160 + 70 + 6, this.getHeight() / 6 + 24 * ((controlId - this.startIndex) >> 1) + 7, 0xFFFFFF);
  235 + }
  236 +
  237 + super.drawScreen(mouseX, mouseY, partialTick);
  238 + }
  239 +}
0 \ No newline at end of file 240 \ No newline at end of file
java/com/mumfrey/liteloader/util/PrivateFields.java
@@ -15,7 +15,7 @@ import net.minecraft.src.*; @@ -15,7 +15,7 @@ import net.minecraft.src.*;
15 * @param <P> Parent class type, the type of the class that owns the field 15 * @param <P> Parent class type, the type of the class that owns the field
16 * @param <T> Field type, the type of the field value 16 * @param <T> Field type, the type of the field value
17 * 17 *
18 - * TODO Obfuscation - updated 1.5.1 18 + * TODO Obfuscation - updated 1.5.2
19 */ 19 */
20 @SuppressWarnings("rawtypes") 20 @SuppressWarnings("rawtypes")
21 public class PrivateFields<P, T> 21 public class PrivateFields<P, T>
@@ -132,6 +132,7 @@ public class PrivateFields&lt;P, T&gt; @@ -132,6 +132,7 @@ public class PrivateFields&lt;P, T&gt;
132 */ 132 */
133 public static final class StaticFields<P, T> extends PrivateFields<P, T> 133 public static final class StaticFields<P, T> extends PrivateFields<P, T>
134 { 134 {
  135 + @SuppressWarnings("synthetic-access")
135 public StaticFields(Class<P> owner, String mcpName, String name, String fmlName) { super(owner, mcpName, name, fmlName); } 136 public StaticFields(Class<P> owner, String mcpName, String name, String fmlName) { super(owner, mcpName, name, fmlName); }
136 public T get() { return get(null); } 137 public T get() { return get(null); }
137 public void set(T value) { set(null, value); } 138 public void set(T value) { set(null, value); }
@@ -140,8 +141,10 @@ public class PrivateFields&lt;P, T&gt; @@ -140,8 +141,10 @@ public class PrivateFields&lt;P, T&gt;
140 public static final StaticFields<TileEntity, Map> tileEntityNameToClassMap = new StaticFields<TileEntity, Map> (TileEntity.class, "nameToClassMap", "a", "field_70326_a"); // TileEntity/nameToClassMap 141 public static final StaticFields<TileEntity, Map> tileEntityNameToClassMap = new StaticFields<TileEntity, Map> (TileEntity.class, "nameToClassMap", "a", "field_70326_a"); // TileEntity/nameToClassMap
141 } 142 }
142 143
143 - public static final PrivateFields<Minecraft, Timer> minecraftTimer = new PrivateFields<Minecraft, Timer> (Minecraft.class, "timer", "V", "field_71428_T"); // Minecraft/timer  
144 - public static final PrivateFields<Minecraft, Profiler> minecraftProfiler = new PrivateFields<Minecraft, Profiler> (Minecraft.class, "mcProfiler", "J", "field_71424_I"); // Minecraft/mcProfiler  
145 - public static final PrivateFields<RenderManager, Map> entityRenderMap = new PrivateFields<RenderManager, Map> (RenderManager.class, "entityRenderMap", "q", "field_78729_o"); // RenderManager/entityRenderMap 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
  146 + public static final PrivateFields<RenderManager, Map> entityRenderMap = new PrivateFields<RenderManager, Map> (RenderManager.class, "entityRenderMap", "q", "field_78729_o"); // RenderManager/entityRenderMap
  147 + public static final PrivateFields<GuiControls, GuiScreen> guiControlsParentScreen = new PrivateFields<GuiControls, GuiScreen> (GuiControls.class, "parentScreen", "b", "field_73909_b"); // GuiControls/parentScreen
  148 + public static final PrivateFields<PlayerUsageSnooper, IPlayerUsage> playerStatsCollector = new PrivateFields<PlayerUsageSnooper, IPlayerUsage>(PlayerUsageSnooper.class, "playerStatsCollector", "d", "field_76478_d"); // PlayerUsageSnooper/playerStatsCollector
146 } 149 }
147 150
res/liteloader.properties
@@ -2,5 +2,6 @@ search.mods=true @@ -2,5 +2,6 @@ search.mods=true
2 search.jar=true 2 search.jar=true
3 search.classpath=true 3 search.classpath=true
4 log=stderr 4 log=stderr
  5 +controls.pages=true
5 brand=The Voxel Modpack 6 brand=The Voxel Modpack
6 7