Commit 181d76f766096fff24e1872468311ca6b0953931

Authored by Mumfrey
1 parent 64ec9596

support for baking listener lists to classes

java/client/com/mumfrey/liteloader/client/ClientEvents.java
1 1 package com.mumfrey.liteloader.client;
2 2  
3   -import java.util.LinkedList;
4   -
5 3 import net.minecraft.client.Minecraft;
6 4 import net.minecraft.client.entity.EntityClientPlayerMP;
7 5 import net.minecraft.client.gui.GuiNewChat;
... ... @@ -29,6 +27,7 @@ import com.mumfrey.liteloader.core.ClientPluginChannels;
29 27 import com.mumfrey.liteloader.core.Events;
30 28 import com.mumfrey.liteloader.core.InterfaceRegistrationDelegate;
31 29 import com.mumfrey.liteloader.core.LiteLoader;
  30 +import com.mumfrey.liteloader.core.event.HandlerList;
32 31 import com.mumfrey.liteloader.launch.LoaderProperties;
33 32 import com.mumfrey.liteloader.transformers.event.EventInfo;
34 33 import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
... ... @@ -76,95 +75,6 @@ public class ClientEvents extends Events<Minecraft, IntegratedServer>
76 75 *
77 76 */
78 77 private boolean wasFullScreen = false;
79   -
80   - /**
81   - * List of mods which implement Tickable interface and will receive tick
82   - * events
83   - */
84   - private LinkedList<Tickable> tickListeners = new LinkedList<Tickable>();
85   -
86   - /**
87   - * List of mods which implement the GameLoopListener interface and will
88   - * receive loop events
89   - */
90   - private LinkedList<GameLoopListener> loopListeners = new LinkedList<GameLoopListener>();
91   -
92   - /**
93   - *
94   - */
95   - private LinkedList<InitCompleteListener> initListeners = new LinkedList<InitCompleteListener>();
96   -
97   - /**
98   - * List of mods which implement RenderListener interface and will receive
99   - * render events events
100   - */
101   - private LinkedList<RenderListener> renderListeners = new LinkedList<RenderListener>();
102   -
103   - /**
104   - * List of mods which implement the PostRenderListener interface and want to
105   - * render entities
106   - */
107   - private LinkedList<PostRenderListener> postRenderListeners = new LinkedList<PostRenderListener>();
108   -
109   - /**
110   - * List of mods which implement HUDRenderListener and want callbacks when HUD is rendered
111   - */
112   - private LinkedList<HUDRenderListener> hudRenderListeners = new LinkedList<HUDRenderListener>();
113   -
114   - /**
115   - * List of mods which implement ChatRenderListener and want to know when
116   - * chat is rendered
117   - */
118   - private LinkedList<ChatRenderListener> chatRenderListeners = new LinkedList<ChatRenderListener>();
119   -
120   - /**
121   - * List of mods which implement ChatListener interface and will receive chat
122   - * events
123   - */
124   - private LinkedList<ChatListener> chatListeners = new LinkedList<ChatListener>();
125   -
126   - /**
127   - * List of mods which implement ChatFilter interface and will receive chat
128   - * filter events
129   - */
130   - private LinkedList<ChatFilter> chatFilters = new LinkedList<ChatFilter>();
131   -
132   - /**
133   - * List of mods which implement PostLoginListener and want to be notified post login
134   - */
135   - private LinkedList<PostLoginListener> postLoginListeners = new LinkedList<PostLoginListener>();
136   -
137   - /**
138   - * List of mods which implement LoginListener interface and will receive
139   - * client login events
140   - */
141   - private LinkedList<JoinGameListener> joinGameListeners = new LinkedList<JoinGameListener>();
142   -
143   - /**
144   - * List of mods which implement LoginListener interface and will receive
145   - * client login events
146   - */
147   - private LinkedList<PreJoinGameListener> preJoinGameListeners = new LinkedList<PreJoinGameListener>();
148   -
149   - /**
150   - * List of mods which monitor outbound chat
151   - */
152   - private LinkedList<OutboundChatListener> outboundChatListeners = new LinkedList<OutboundChatListener>();
153   -
154   - /**
155   - * List of mods which filter outbound chat
156   - */
157   - private LinkedList<OutboundChatFilter> outboundChatFilters = new LinkedList<OutboundChatFilter>();
158   -
159   - /**
160   - * List of mods which monitor changes in the viewport
161   - */
162   - private LinkedList<ViewportListener> viewportListeners = new LinkedList<ViewportListener>();
163   -
164   - /**
165   - * List of mods which interact with the main minecraft FBO
166   - */
167   - private LinkedList<FrameBufferListener> frameBufferListeners = new LinkedList<FrameBufferListener>();
168 78  
169 79 /**
170 80 * Hash code of the current world. We don't store the world reference here because we don't want
... ... @@ -172,6 +82,23 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
172 82 */
173 83 private int worldHashCode = 0;
174 84  
  85 + private HandlerList<Tickable> tickListeners = new HandlerList<Tickable>(Tickable.class);
  86 + private HandlerList<GameLoopListener> loopListeners = new HandlerList<GameLoopListener>(GameLoopListener.class);
  87 + private HandlerList<RenderListener> renderListeners = new HandlerList<RenderListener>(RenderListener.class);
  88 + private HandlerList<PostRenderListener> postRenderListeners = new HandlerList<PostRenderListener>(PostRenderListener.class);
  89 + private HandlerList<HUDRenderListener> hudRenderListeners = new HandlerList<HUDRenderListener>(HUDRenderListener.class);
  90 + private HandlerList<ChatRenderListener> chatRenderListeners = new HandlerList<ChatRenderListener>(ChatRenderListener.class);
  91 + private HandlerList<ChatListener> chatListeners = new HandlerList<ChatListener>(ChatListener.class);
  92 + private HandlerList<PostLoginListener> postLoginListeners = new HandlerList<PostLoginListener>(PostLoginListener.class);
  93 + private HandlerList<JoinGameListener> joinGameListeners = new HandlerList<JoinGameListener>(JoinGameListener.class);
  94 + private HandlerList<OutboundChatListener> outboundChatListeners = new HandlerList<OutboundChatListener>(OutboundChatListener.class);
  95 + private HandlerList<ViewportListener> viewportListeners = new HandlerList<ViewportListener>(ViewportListener.class);
  96 + private HandlerList<FrameBufferListener> frameBufferListeners = new HandlerList<FrameBufferListener>(FrameBufferListener.class);
  97 + private HandlerList<InitCompleteListener> initListeners = new HandlerList<InitCompleteListener>(InitCompleteListener.class);
  98 + private HandlerList<ChatFilter> chatFilters = new HandlerList<ChatFilter>(ChatFilter.class);
  99 + private HandlerList<PreJoinGameListener> preJoinGameListeners = new HandlerList<PreJoinGameListener>(PreJoinGameListener.class);
  100 + private HandlerList<OutboundChatFilter> outboundChatFilters = new HandlerList<OutboundChatFilter>(OutboundChatFilter.class);
  101 +
175 102 @SuppressWarnings("cast")
176 103 public ClientEvents(LiteLoader loader, GameEngineClient engine, LoaderProperties properties)
177 104 {
... ... @@ -208,19 +135,20 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
208 135  
209 136 delegate.registerInterface(Tickable.class);
210 137 delegate.registerInterface(GameLoopListener.class);
211   - delegate.registerInterface(InitCompleteListener.class);
212 138 delegate.registerInterface(RenderListener.class);
213 139 delegate.registerInterface(PostRenderListener.class);
214   - delegate.registerInterface(ChatFilter.class);
215   - delegate.registerInterface(ChatListener.class);
216   - delegate.registerInterface(ChatRenderListener.class);
217 140 delegate.registerInterface(HUDRenderListener.class);
218   - delegate.registerInterface(PreJoinGameListener.class);
  141 + delegate.registerInterface(ChatRenderListener.class);
  142 + delegate.registerInterface(ChatListener.class);
  143 + delegate.registerInterface(PostLoginListener.class);
219 144 delegate.registerInterface(JoinGameListener.class);
220 145 delegate.registerInterface(OutboundChatListener.class);
221   - delegate.registerInterface(OutboundChatFilter.class);
222 146 delegate.registerInterface(ViewportListener.class);
223 147 delegate.registerInterface(FrameBufferListener.class);
  148 + delegate.registerInterface(InitCompleteListener.class);
  149 + delegate.registerInterface(ChatFilter.class);
  150 + delegate.registerInterface(PreJoinGameListener.class);
  151 + delegate.registerInterface(OutboundChatFilter.class);
224 152 }
225 153  
226 154 /**
... ... @@ -269,10 +197,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
269 197 */
270 198 public void addTickListener(Tickable tickable)
271 199 {
272   - if (!this.tickListeners.contains(tickable))
273   - {
274   - this.tickListeners.add(tickable);
275   - }
  200 + this.tickListeners.add(tickable);
276 201 }
277 202  
278 203 /**
... ... @@ -280,10 +205,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
280 205 */
281 206 public void addLoopListener(GameLoopListener loopListener)
282 207 {
283   - if (!this.loopListeners.contains(loopListener))
284   - {
285   - this.loopListeners.add(loopListener);
286   - }
  208 + this.loopListeners.add(loopListener);
287 209 }
288 210  
289 211 /**
... ... @@ -291,10 +213,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
291 213 */
292 214 public void addInitListener(InitCompleteListener initCompleteListener)
293 215 {
294   - if (!this.initListeners.contains(initCompleteListener))
295   - {
296   - this.initListeners.add(initCompleteListener);
297   - }
  216 + this.initListeners.add(initCompleteListener);
298 217 }
299 218  
300 219 /**
... ... @@ -302,10 +221,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
302 221 */
303 222 public void addRenderListener(RenderListener renderListener)
304 223 {
305   - if (!this.renderListeners.contains(renderListener))
306   - {
307   - this.renderListeners.add(renderListener);
308   - }
  224 + this.renderListeners.add(renderListener);
309 225 }
310 226  
311 227 /**
... ... @@ -313,10 +229,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
313 229 */
314 230 public void addPostRenderListener(PostRenderListener postRenderListener)
315 231 {
316   - if (!this.postRenderListeners.contains(postRenderListener))
317   - {
318   - this.postRenderListeners.add(postRenderListener);
319   - }
  232 + this.postRenderListeners.add(postRenderListener);
320 233 }
321 234  
322 235 /**
... ... @@ -353,7 +266,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
353 266 {
354 267 LiteLoaderLogger.warning("Interface error initialising mod '%1s'. A mod implementing ChatFilter and ChatListener is not supported! Remove one of these interfaces", chatListener.getName());
355 268 }
356   - else if (!this.chatListeners.contains(chatListener))
  269 + else
357 270 {
358 271 this.chatListeners.add(chatListener);
359 272 }
... ... @@ -364,10 +277,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
364 277 */
365 278 public void addChatRenderListener(ChatRenderListener chatRenderListener)
366 279 {
367   - if (!this.chatRenderListeners.contains(chatRenderListener))
368   - {
369   - this.chatRenderListeners.add(chatRenderListener);
370   - }
  280 + this.chatRenderListeners.add(chatRenderListener);
371 281 }
372 282  
373 283 /**
... ... @@ -375,10 +285,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
375 285 */
376 286 public void addHUDRenderListener(HUDRenderListener hudRenderListener)
377 287 {
378   - if (!this.hudRenderListeners.contains(hudRenderListener))
379   - {
380   - this.hudRenderListeners.add(hudRenderListener);
381   - }
  288 + this.hudRenderListeners.add(hudRenderListener);
382 289 }
383 290  
384 291 /**
... ... @@ -386,10 +293,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
386 293 */
387 294 public void addPreJoinGameListener(PostLoginListener postLoginListener)
388 295 {
389   - if (!this.postLoginListeners.contains(postLoginListener))
390   - {
391   - this.postLoginListeners.add(postLoginListener);
392   - }
  296 + this.postLoginListeners.add(postLoginListener);
393 297 }
394 298  
395 299 /**
... ... @@ -397,10 +301,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
397 301 */
398 302 public void addPreJoinGameListener(PreJoinGameListener joinGameListener)
399 303 {
400   - if (!this.preJoinGameListeners.contains(joinGameListener))
401   - {
402   - this.preJoinGameListeners.add(joinGameListener);
403   - }
  304 + this.preJoinGameListeners.add(joinGameListener);
404 305 }
405 306  
406 307 /**
... ... @@ -408,10 +309,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
408 309 */
409 310 public void addJoinGameListener(JoinGameListener joinGameListener)
410 311 {
411   - if (!this.joinGameListeners.contains(joinGameListener))
412   - {
413   - this.joinGameListeners.add(joinGameListener);
414   - }
  312 + this.joinGameListeners.add(joinGameListener);
415 313 }
416 314  
417 315 /**
... ... @@ -419,10 +317,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
419 317 */
420 318 public void addOutboundChatListener(OutboundChatListener outboundChatListener)
421 319 {
422   - if (!this.outboundChatListeners.contains(outboundChatListener))
423   - {
424   - this.outboundChatListeners.add(outboundChatListener);
425   - }
  320 + this.outboundChatListeners.add(outboundChatListener);
426 321 }
427 322  
428 323 /**
... ... @@ -430,10 +325,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
430 325 */
431 326 public void addOutboundChatFiler(OutboundChatFilter outboundChatFilter)
432 327 {
433   - if (!this.outboundChatFilters.contains(outboundChatFilter))
434   - {
435   - this.outboundChatFilters.add(outboundChatFilter);
436   - }
  328 + this.outboundChatFilters.add(outboundChatFilter);
437 329 }
438 330  
439 331 /**
... ... @@ -441,10 +333,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
441 333 */
442 334 public void addViewportListener(ViewportListener viewportListener)
443 335 {
444   - if (!this.viewportListeners.contains(viewportListener))
445   - {
446   - this.viewportListeners.add(viewportListener);
447   - }
  336 + this.viewportListeners.add(viewportListener);
448 337 }
449 338  
450 339 /**
... ... @@ -452,10 +341,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
452 341 */
453 342 public void addFrameBufferListener(FrameBufferListener frameBufferListener)
454 343 {
455   - if (!this.frameBufferListeners.contains(frameBufferListener))
456   - {
457   - this.frameBufferListeners.add(frameBufferListener);
458   - }
  344 + this.frameBufferListeners.add(frameBufferListener);
459 345 }
460 346  
461 347 /**
... ... @@ -499,14 +385,11 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
499 385  
500 386 if (this.wasFullScreen != minecraft.isFullScreen())
501 387 {
502   - for (ViewportListener viewportListener : this.viewportListeners)
503   - viewportListener.onFullScreenToggled(minecraft.isFullScreen());
  388 + this.viewportListeners.all().onFullScreenToggled(minecraft.isFullScreen());
504 389 }
505 390  
506 391 this.wasFullScreen = minecraft.isFullScreen();
507   -
508   - for (ViewportListener viewportListener : this.viewportListeners)
509   - viewportListener.onViewportResized(this.currentResolution, minecraft.displayWidth, minecraft.displayHeight);
  392 + this.viewportListeners.all().onViewportResized(this.currentResolution, minecraft.displayWidth, minecraft.displayHeight);
510 393 }
511 394  
512 395 /**
... ... @@ -514,8 +397,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
514 397 */
515 398 void onRender()
516 399 {
517   - for (RenderListener renderListener : this.renderListeners)
518   - renderListener.onRender();
  400 + this.renderListeners.all().onRender();
519 401 }
520 402  
521 403 /**
... ... @@ -524,9 +406,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
524 406 void postRenderEntities()
525 407 {
526 408 float partialTicks = (this.minecraftTimer != null) ? this.minecraftTimer.elapsedPartialTicks : 0.0F;
527   -
528   - for (PostRenderListener renderListener : this.postRenderListeners)
529   - renderListener.onPostRenderEntities(partialTicks);
  409 + this.postRenderListeners.all().onPostRenderEntities(partialTicks);
530 410 }
531 411  
532 412 /**
... ... @@ -535,9 +415,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
535 415 void postRender()
536 416 {
537 417 float partialTicks = (this.minecraftTimer != null) ? this.minecraftTimer.elapsedPartialTicks : 0.0F;
538   -
539   - for (PostRenderListener renderListener : this.postRenderListeners)
540   - renderListener.onPostRender(partialTicks);
  418 + this.postRenderListeners.all().onPostRender(partialTicks);
541 419 }
542 420  
543 421 /**
... ... @@ -549,8 +427,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
549 427  
550 428 if (!minecraft.skipRenderWorld && ref == (minecraft.theWorld == null ? 1 : 2))
551 429 {
552   - for (RenderListener renderListener : this.renderListeners)
553   - renderListener.onRenderGui(this.engineClient.getCurrentScreen());
  430 + this.renderListeners.all().onRenderGui(this.engineClient.getCurrentScreen());
554 431 }
555 432 }
556 433  
... ... @@ -559,8 +436,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
559 436 */
560 437 void onSetupCameraTransform()
561 438 {
562   - for (RenderListener renderListener : this.renderListeners)
563   - renderListener.onSetupCameraTransform();
  439 + this.renderListeners.all().onSetupCameraTransform();
564 440 }
565 441  
566 442 /**
... ... @@ -569,9 +445,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
569 445 void onRenderChat()
570 446 {
571 447 GuiNewChat chat = this.engineClient.getChatGUI();
572   -
573   - for (ChatRenderListener chatRenderListener : this.chatRenderListeners)
574   - chatRenderListener.onPreRenderChat(this.screenWidth, this.screenHeight, chat);
  448 + this.chatRenderListeners.all().onPreRenderChat(this.screenWidth, this.screenHeight, chat);
575 449 }
576 450  
577 451 /**
... ... @@ -580,9 +454,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
580 454 void postRenderChat()
581 455 {
582 456 GuiNewChat chat = this.engineClient.getChatGUI();
583   -
584   - for (ChatRenderListener chatRenderListener : this.chatRenderListeners)
585   - chatRenderListener.onPostRenderChat(this.screenWidth, this.screenHeight, chat);
  457 + this.chatRenderListeners.all().onPostRenderChat(this.screenWidth, this.screenHeight, chat);
586 458 }
587 459  
588 460 /**
... ... @@ -592,8 +464,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
592 464 {
593 465 if (!this.engineClient.hideGUI() || this.engineClient.getCurrentScreen() != null)
594 466 {
595   - for (HUDRenderListener hudRenderListener : this.hudRenderListeners)
596   - hudRenderListener.onPreRenderHUD(this.screenWidth, this.screenHeight);
  467 + this.hudRenderListeners.all().onPreRenderHUD(this.screenWidth, this.screenHeight);
597 468 }
598 469 }
599 470  
... ... @@ -604,8 +475,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
604 475 {
605 476 if (!this.engineClient.hideGUI() || this.engineClient.getCurrentScreen() != null)
606 477 {
607   - for (HUDRenderListener hudRenderListener : this.hudRenderListeners)
608   - hudRenderListener.onPostRenderHUD(this.screenWidth, this.screenHeight);
  478 + this.hudRenderListeners.all().onPostRenderHUD(this.screenWidth, this.screenHeight);
609 479 }
610 480 }
611 481  
... ... @@ -615,9 +485,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
615 485 void onTimerUpdate()
616 486 {
617 487 Minecraft minecraft = this.engine.getClient();
618   -
619   - for (GameLoopListener loopListener : this.loopListeners)
620   - loopListener.onRunGameLoop(minecraft);
  488 + this.loopListeners.all().onRunGameLoop(minecraft);
621 489 }
622 490  
623 491 /**
... ... @@ -659,12 +527,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
659 527 this.profiler.endSection();
660 528  
661 529 // Iterate tickable mods
662   - for (Tickable tickable : this.tickListeners)
663   - {
664   - this.profiler.startSection(tickable.getClass().getSimpleName().toLowerCase());
665   - tickable.onTick(minecraft, partialTicks, inGame, clock);
666   - this.profiler.endSection();
667   - }
  530 + this.tickListeners.all().onTick(minecraft, partialTicks, inGame, clock);
668 531  
669 532 // Detected world change
670 533 if (minecraft.theWorld != null)
... ... @@ -714,8 +577,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
714 577 }
715 578  
716 579 // Chat listeners get the chat if no filter removed it
717   - for (ChatListener chatListener : this.chatListeners)
718   - chatListener.onChat(chat, message);
  580 + this.chatListeners.all().onChat(chat, message);
719 581  
720 582 return true;
721 583 }
... ... @@ -726,10 +588,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
726 588 */
727 589 void onSendChatMessage(C01PacketChatMessage packet, String message)
728 590 {
729   - for (OutboundChatListener outboundChatListener : this.outboundChatListeners)
730   - {
731   - outboundChatListener.onSendChatMessage(packet, message);
732   - }
  591 + this.outboundChatListeners.all().onSendChatMessage(packet, message);
733 592 }
734 593  
735 594 /**
... ... @@ -756,8 +615,7 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
756 615 ((ClientPluginChannelsClient)clientPluginChannels).onPostLogin(netHandler, loginPacket);
757 616 }
758 617  
759   - for (PostLoginListener loginListener : this.postLoginListeners)
760   - loginListener.onPostLogin(netHandler, loginPacket);
  618 + this.postLoginListeners.all().onPostLogin(netHandler, loginPacket);
761 619 }
762 620  
763 621 /**
... ... @@ -796,25 +654,32 @@ public class ClientEvents extends Events&lt;Minecraft, IntegratedServer&gt;
796 654 ((ClientPluginChannelsClient)clientPluginChannels).onJoinGame(netHandler, loginPacket);
797 655 }
798 656  
799   - for (JoinGameListener joinGameListener : this.joinGameListeners)
800   - joinGameListener.onJoinGame(netHandler, loginPacket);
  657 + this.joinGameListeners.all().onJoinGame(netHandler, loginPacket);
801 658 }
802 659  
  660 + /**
  661 + * @param framebuffer
  662 + */
803 663 void preRenderFBO(Framebuffer framebuffer)
804 664 {
805   - for (FrameBufferListener frameBufferListener : this.frameBufferListeners)
806   - frameBufferListener.preRenderFBO(framebuffer);
  665 + this.frameBufferListeners.all().preRenderFBO(framebuffer);
807 666 }
808 667  
  668 + /**
  669 + * @param framebuffer
  670 + * @param width
  671 + * @param height
  672 + */
809 673 void onRenderFBO(Framebuffer framebuffer, int width, int height)
810 674 {
811   - for (FrameBufferListener frameBufferListener : this.frameBufferListeners)
812   - frameBufferListener.onRenderFBO(framebuffer, width, height);
  675 + this.frameBufferListeners.all().onRenderFBO(framebuffer, width, height);
813 676 }
814 677  
  678 + /**
  679 + * @param framebuffer
  680 + */
815 681 void postRenderFBO(Framebuffer framebuffer)
816 682 {
817   - for (FrameBufferListener frameBufferListener : this.frameBufferListeners)
818   - frameBufferListener.postRenderFBO(framebuffer);
  683 + this.frameBufferListeners.all().postRenderFBO(framebuffer);
819 684 }
820 685 }
... ...
java/common/com/mumfrey/liteloader/core/Events.java
1 1 package com.mumfrey.liteloader.core;
2 2  
3   -import java.util.LinkedList;
4   -
5 3 import net.minecraft.client.resources.IResourceManager;
6 4 import net.minecraft.client.resources.IResourceManagerReloadListener;
7 5 import net.minecraft.command.ICommandManager;
... ... @@ -30,6 +28,7 @@ import com.mumfrey.liteloader.api.InterfaceProvider;
30 28 import com.mumfrey.liteloader.api.Listener;
31 29 import com.mumfrey.liteloader.common.GameEngine;
32 30 import com.mumfrey.liteloader.common.LoadingProgress;
  31 +import com.mumfrey.liteloader.core.event.HandlerList;
33 32 import com.mumfrey.liteloader.launch.LoaderProperties;
34 33 import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
35 34  
... ... @@ -61,17 +60,17 @@ public abstract class Events&lt;TClient, TServer extends MinecraftServer&gt; implement
61 60 /**
62 61 * List of mods which can filter server chat
63 62 */
64   - private LinkedList<ServerChatFilter> serverChatFilters = new LinkedList<ServerChatFilter>();
  63 + private HandlerList<ServerChatFilter> serverChatFilters = new HandlerList<ServerChatFilter>(ServerChatFilter.class);
65 64  
66 65 /**
67 66 * List of mods which provide server commands
68 67 */
69   - private LinkedList<ServerCommandProvider> serverCommandProviders = new LinkedList<ServerCommandProvider>();
  68 + private HandlerList<ServerCommandProvider> serverCommandProviders = new HandlerList<ServerCommandProvider>(ServerCommandProvider.class);
70 69  
71 70 /**
72 71 * List of mods which monitor server player events
73 72 */
74   - private LinkedList<ServerPlayerListener> serverPlayerListeners = new LinkedList<ServerPlayerListener>();
  73 + private HandlerList<ServerPlayerListener> serverPlayerListeners = new HandlerList<ServerPlayerListener>(ServerPlayerListener.class);
75 74  
76 75 /**
77 76 * Package private ctor
... ... @@ -169,10 +168,7 @@ public abstract class Events&lt;TClient, TServer extends MinecraftServer&gt; implement
169 168 */
170 169 public void addServerCommandProvider(ServerCommandProvider serverCommandProvider)
171 170 {
172   - if (!this.serverCommandProviders.contains(serverCommandProvider))
173   - {
174   - this.serverCommandProviders.add(serverCommandProvider);
175   - }
  171 + this.serverCommandProviders.add(serverCommandProvider);
176 172 }
177 173  
178 174 /**
... ... @@ -180,10 +176,7 @@ public abstract class Events&lt;TClient, TServer extends MinecraftServer&gt; implement
180 176 */
181 177 public void addServerPlayerListener(ServerPlayerListener serverPlayerListener)
182 178 {
183   - if (!this.serverPlayerListeners.contains(serverPlayerListener))
184   - {
185   - this.serverPlayerListeners.add(serverPlayerListener);
186   - }
  179 + this.serverPlayerListeners.add(serverPlayerListener);
187 180 }
188 181  
189 182 @Override
... ... @@ -227,9 +220,7 @@ public abstract class Events&lt;TClient, TServer extends MinecraftServer&gt; implement
227 220 if (commandManager instanceof ServerCommandManager)
228 221 {
229 222 ServerCommandManager serverCommandManager = (ServerCommandManager)commandManager;
230   -
231   - for (ServerCommandProvider commandProvider : this.serverCommandProviders)
232   - commandProvider.provideCommands(serverCommandManager);
  223 + this.serverCommandProviders.all().provideCommands(serverCommandManager);
233 224 }
234 225  
235 226 LiteLoader.getServerPluginChannels().onServerStartup();
... ... @@ -242,8 +233,7 @@ public abstract class Events&lt;TClient, TServer extends MinecraftServer&gt; implement
242 233 */
243 234 public void onSpawnPlayer(ServerConfigurationManager scm, EntityPlayerMP player, GameProfile profile)
244 235 {
245   - for (ServerPlayerListener serverPlayerListener : this.serverPlayerListeners)
246   - serverPlayerListener.onPlayerConnect(player, profile);
  236 + this.serverPlayerListeners.all().onPlayerConnect(player, profile);
247 237 }
248 238  
249 239 /**
... ... @@ -262,8 +252,7 @@ public abstract class Events&lt;TClient, TServer extends MinecraftServer&gt; implement
262 252 */
263 253 public void onInitializePlayerConnection(ServerConfigurationManager scm, NetworkManager netManager, EntityPlayerMP player)
264 254 {
265   - for (ServerPlayerListener serverPlayerListener : this.serverPlayerListeners)
266   - serverPlayerListener.onPlayerLoggedIn(player);
  255 + this.serverPlayerListeners.all().onPlayerLoggedIn(player);
267 256 }
268 257  
269 258 /**
... ... @@ -275,8 +264,7 @@ public abstract class Events&lt;TClient, TServer extends MinecraftServer&gt; implement
275 264 */
276 265 public void onRespawnPlayer(ServerConfigurationManager scm, EntityPlayerMP player, EntityPlayerMP oldPlayer, int dimension, boolean won)
277 266 {
278   - for (ServerPlayerListener serverPlayerListener : this.serverPlayerListeners)
279   - serverPlayerListener.onPlayerRespawn(player, oldPlayer, dimension, won);
  267 + this.serverPlayerListeners.all().onPlayerRespawn(player, oldPlayer, dimension, won);
280 268 }
281 269  
282 270 /**
... ... @@ -285,15 +273,24 @@ public abstract class Events&lt;TClient, TServer extends MinecraftServer&gt; implement
285 273 */
286 274 public void onPlayerLogout(ServerConfigurationManager scm, EntityPlayerMP player)
287 275 {
288   - for (ServerPlayerListener serverPlayerListener : this.serverPlayerListeners)
289   - serverPlayerListener.onPlayerLogout(player);
  276 + this.serverPlayerListeners.all().onPlayerLogout(player);
290 277 }
291 278  
  279 + /**
  280 + * @param clock
  281 + * @param partialTicks
  282 + * @param inGame
  283 + */
292 284 protected void onTick(boolean clock, float partialTicks, boolean inGame)
293 285 {
294 286 this.loader.onTick(clock, partialTicks, inGame);
295 287 }
296 288  
  289 + /**
  290 + * @param mouseX
  291 + * @param mouseY
  292 + * @param partialTicks
  293 + */
297 294 protected void onPostRender(int mouseX, int mouseY, float partialTicks)
298 295 {
299 296 this.loader.onPostRender(mouseX, mouseY, partialTicks);
... ...
java/common/com/mumfrey/liteloader/core/event/HandlerList.java 0 โ†’ 100644
  1 +package com.mumfrey.liteloader.core.event;
  2 +
  3 +import java.io.IOException;
  4 +import java.lang.reflect.Constructor;
  5 +import java.net.URL;
  6 +import java.net.URLClassLoader;
  7 +import java.util.Collection;
  8 +import java.util.Iterator;
  9 +import java.util.LinkedList;
  10 +import java.util.List;
  11 +
  12 +import net.minecraft.launchwrapper.IClassTransformer;
  13 +import net.minecraft.launchwrapper.Launch;
  14 +
  15 +import org.objectweb.asm.ClassReader;
  16 +import org.objectweb.asm.ClassWriter;
  17 +import org.objectweb.asm.Label;
  18 +import org.objectweb.asm.Type;
  19 +import org.objectweb.asm.tree.*;
  20 +
  21 +import com.mumfrey.liteloader.core.runtime.Obf;
  22 +import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
  23 +import com.sun.xml.internal.ws.org.objectweb.asm.Opcodes;
  24 +
  25 +/**
  26 + * HandlerList is a generic class which supports baking a list of event handlers into a dynamic inner
  27 + * class for invokation at runtime.
  28 + *
  29 + * @author Adam Mummery-Smith
  30 + *
  31 + * @param <T>
  32 + */
  33 +public class HandlerList<T> extends LinkedList<T>
  34 +{
  35 + private static final long serialVersionUID = 1L;
  36 +
  37 + private static final int MAX_UNCOLLECTED_CLASSES = 5000;
  38 +
  39 + private static int uncollectedHandlerLists = 0;
  40 +
  41 + /**
  42 + * Type of the interface for objects in this handler list
  43 + */
  44 + private Class<T> type;
  45 +
  46 + /**
  47 + * Current baked handler list, we cook them at gas mark 5 for 30 minutes in a disposable classloader whic
  48 + * also handles the transformation for us
  49 + */
  50 + private BakedHandlerList<T> bakedHandler;
  51 +
  52 + /**
  53 + * @param type
  54 + */
  55 + public HandlerList(Class<T> type)
  56 + {
  57 + if (!type.isInterface())
  58 + {
  59 + throw new IllegalArgumentException("HandlerList type argument must be an interface");
  60 + }
  61 +
  62 + this.type = type;
  63 + }
  64 +
  65 + /* (non-Javadoc)
  66 + * @see java.util.LinkedList#add(java.lang.Object)
  67 + */
  68 + @Override
  69 + public boolean add(T listener)
  70 + {
  71 + if (!this.contains(listener))
  72 + {
  73 + super.add(listener);
  74 + this.invalidate();
  75 + }
  76 +
  77 + return true;
  78 + }
  79 +
  80 + /**
  81 + * Invalidate current baked list
  82 + */
  83 + public void invalidate()
  84 + {
  85 + this.bakedHandler = null;
  86 + HandlerList.uncollectedHandlerLists++;
  87 + if (HandlerList.uncollectedHandlerLists > HandlerList.MAX_UNCOLLECTED_CLASSES)
  88 + {
  89 + System.gc();
  90 + HandlerList.uncollectedHandlerLists = 0;
  91 + }
  92 + }
  93 +
  94 + /**
  95 + * Returns the baked list of all listeners
  96 + *
  97 + * @return
  98 + */
  99 + public T all()
  100 + {
  101 + if (this.bakedHandler == null)
  102 + {
  103 + HandlerListClassLoader<T> classLoader = new HandlerListClassLoader<T>(this.type, this.size());
  104 + this.bakedHandler = classLoader.newHandler();
  105 + this.bakedHandler.populate(this);
  106 + }
  107 +
  108 + return this.bakedHandler.get();
  109 + }
  110 +
  111 + /* (non-Javadoc)
  112 + * @see java.util.LinkedList#remove()
  113 + */
  114 + @Override
  115 + public T remove()
  116 + {
  117 + throw new UnsupportedOperationException("'remove' is not supported for HandlerList");
  118 + }
  119 +
  120 + /* (non-Javadoc)
  121 + * @see java.util.LinkedList#remove(int)
  122 + */
  123 + @Override
  124 + public T remove(int index)
  125 + {
  126 + throw new UnsupportedOperationException("'remove' is not supported for HandlerList");
  127 + }
  128 +
  129 + /* (non-Javadoc)
  130 + * @see java.util.LinkedList#remove(java.lang.Object)
  131 + */
  132 + @Override
  133 + public boolean remove(Object o)
  134 + {
  135 + throw new UnsupportedOperationException("'remove' is not supported for HandlerList");
  136 + }
  137 +
  138 + /* (non-Javadoc)
  139 + * @see java.util.AbstractCollection#removeAll(java.util.Collection)
  140 + */
  141 + @Override
  142 + public boolean removeAll(Collection<?> c)
  143 + {
  144 + throw new UnsupportedOperationException("'removeAll' is not supported for HandlerList");
  145 + }
  146 +
  147 + /* (non-Javadoc)
  148 + * @see java.util.LinkedList#removeFirst()
  149 + */
  150 + @Override
  151 + public T removeFirst()
  152 + {
  153 + throw new UnsupportedOperationException("'removeFirst' is not supported for HandlerList");
  154 + }
  155 +
  156 + /* (non-Javadoc)
  157 + * @see java.util.LinkedList#removeFirstOccurrence(java.lang.Object)
  158 + */
  159 + @Override
  160 + public boolean removeFirstOccurrence(Object o)
  161 + {
  162 + throw new UnsupportedOperationException("'removeFirstOccurrence' is not supported for HandlerList");
  163 + }
  164 +
  165 + /* (non-Javadoc)
  166 + * @see java.util.LinkedList#removeLast()
  167 + */
  168 + @Override
  169 + public T removeLast()
  170 + {
  171 + throw new UnsupportedOperationException("'removeLast' is not supported for HandlerList");
  172 + }
  173 +
  174 + /* (non-Javadoc)
  175 + * @see java.util.LinkedList#removeLastOccurrence(java.lang.Object)
  176 + */
  177 + @Override
  178 + public boolean removeLastOccurrence(Object o)
  179 + {
  180 + throw new UnsupportedOperationException("'removeLastOccurrence' is not supported for HandlerList");
  181 + }
  182 +
  183 + /**
  184 + * Base class for baked handler lists
  185 + *
  186 + * @author Adam Mummery-Smith
  187 + *
  188 + * @param <T>
  189 + */
  190 + public static abstract class BakedHandlerList<T>
  191 + {
  192 + public abstract T get();
  193 +
  194 + public abstract void populate(List<T> listeners);
  195 + }
  196 +
  197 + /**
  198 + * ClassLoader which generates the baked handler list
  199 + *
  200 + * @author Adam Mummery-Smith
  201 + * @param <T>
  202 + */
  203 + static class HandlerListClassLoader<T> extends URLClassLoader
  204 + {
  205 + /**
  206 + * Unique index number, just to ensure no name clashes
  207 + */
  208 + private static int handlerIndex;
  209 +
  210 + private int lineNumber = 1;
  211 +
  212 + private final Class<T> type;
  213 +
  214 + private final String typeRef;
  215 +
  216 + private int size;
  217 +
  218 + /**
  219 + * @param type
  220 + * @param size
  221 + */
  222 + HandlerListClassLoader(Class<T> type, int size)
  223 + {
  224 + super(new URL[0], Launch.classLoader);
  225 + this.type = type;
  226 + this.typeRef = type.getName().replace('.', '/');
  227 + this.size = size;
  228 + }
  229 +
  230 + /**
  231 + * Create and return a new baked handler list
  232 + */
  233 + @SuppressWarnings("unchecked")
  234 + public BakedHandlerList<T> newHandler()
  235 + {
  236 + try
  237 + {
  238 + String className = this.getNextClassName();
  239 + Class<BakedHandlerList<T>> handlerClass = (Class<BakedHandlerList<T>>)this.loadClass(className);
  240 + Constructor<BakedHandlerList<T>> ctor = handlerClass.getDeclaredConstructor();
  241 + ctor.setAccessible(true);
  242 + return ctor.newInstance();
  243 + }
  244 + catch (Exception ex)
  245 + {
  246 + throw new RuntimeException(ex);
  247 + }
  248 + }
  249 +
  250 + @Override
  251 + protected Class<?> findClass(String name) throws ClassNotFoundException
  252 + {
  253 + try
  254 + {
  255 + byte[] bytes = Launch.classLoader.getClassBytes(Obf.BakedHandlerList.name);
  256 + ClassReader classReader = new ClassReader(bytes);
  257 + ClassNode classNode = new ClassNode();
  258 + classReader.accept(classNode, ClassReader.EXPAND_FRAMES);
  259 +
  260 + this.transform(name, classNode);
  261 +
  262 + ClassWriter classWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
  263 + classNode.accept(classWriter);
  264 + bytes = classWriter.toByteArray();
  265 + return this.defineClass(name, bytes, 0, bytes.length);
  266 + }
  267 + catch (Throwable th)
  268 + {
  269 + th.printStackTrace();
  270 + return null;
  271 + }
  272 + }
  273 +
  274 + private void transform(String name, ClassNode classNode)
  275 + {
  276 + LiteLoaderLogger.info("Baking listener list for %s with %d listeners", this.type.getSimpleName(), this.size);
  277 + LiteLoaderLogger.debug("Generating: %s", name);
  278 +
  279 + this.populateClass(name, classNode);
  280 + this.transformMethods(name, classNode);
  281 + this.injectInterfaceMethods(name, classNode);
  282 + }
  283 +
  284 + private void populateClass(String name, ClassNode classNode)
  285 + {
  286 + classNode.access = classNode.access & ~Opcodes.ACC_ABSTRACT;
  287 + classNode.name = name.replace('.', '/');
  288 + classNode.superName = Obf.BakedHandlerList.ref;
  289 + classNode.interfaces.add(this.type.getName().replace('.', '/'));
  290 + classNode.sourceFile = "Dynamic";
  291 +
  292 + for (int i = 0; i < this.size; i++)
  293 + {
  294 + classNode.fields.add(new FieldNode(Opcodes.ACC_PRIVATE, "handler$" + i, "L" + this.typeRef + ";", null, null));
  295 + }
  296 + }
  297 +
  298 + private void transformMethods(String name, ClassNode classNode)
  299 + {
  300 + for (Iterator<MethodNode> methodIterator = classNode.methods.iterator(); methodIterator.hasNext();)
  301 + {
  302 + MethodNode method = methodIterator.next();
  303 + if (Obf.constructor.name.equals(method.name))
  304 + {
  305 + this.processCtor(classNode, method);
  306 + }
  307 + else if ("get".equals(method.name))
  308 + {
  309 + this.processGet(classNode, method);
  310 + }
  311 + else if ("populate".equals(method.name))
  312 + {
  313 + this.processPopulate(classNode, method);
  314 + }
  315 + }
  316 + }
  317 +
  318 + private void processCtor(ClassNode classNode, MethodNode method)
  319 + {
  320 + for (Iterator<AbstractInsnNode> iter = method.instructions.iterator(); iter.hasNext();)
  321 + {
  322 + AbstractInsnNode insn = iter.next();
  323 + if (insn instanceof MethodInsnNode)
  324 + {
  325 + MethodInsnNode methodInsn = (MethodInsnNode)insn;
  326 + if (methodInsn.owner.equals("java/lang/Object"))
  327 + {
  328 + methodInsn.owner = Obf.BakedHandlerList.ref;
  329 + }
  330 + }
  331 + }
  332 + }
  333 +
  334 + private void processGet(ClassNode classNode, MethodNode method)
  335 + {
  336 + method.access = method.access & ~Opcodes.ACC_ABSTRACT;
  337 + method.instructions.clear();
  338 +
  339 + method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
  340 + method.instructions.add(new InsnNode(Opcodes.ARETURN));
  341 + }
  342 +
  343 + private void processPopulate(ClassNode classNode, MethodNode method)
  344 + {
  345 + method.access = method.access & ~Opcodes.ACC_ABSTRACT;
  346 + method.instructions.clear();
  347 +
  348 + for (int i = 0; i < this.size; i++)
  349 + {
  350 + method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
  351 + method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1));
  352 + method.instructions.add(new IntInsnNode(Opcodes.BIPUSH, i));
  353 + method.instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;", true));
  354 + method.instructions.add(new TypeInsnNode(Opcodes.CHECKCAST, this.typeRef));
  355 + method.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, classNode.name, "handler$" + i, "L" + this.typeRef + ";"));
  356 + }
  357 +
  358 + method.instructions.add(new InsnNode(Opcodes.RETURN));
  359 + }
  360 +
  361 + private void injectInterfaceMethods(String name, ClassNode classNode)
  362 + {
  363 + try
  364 + {
  365 + String interfaceName = this.type.getName();
  366 + this.injectInterfaceMethods(classNode, interfaceName);
  367 + }
  368 + catch (IOException ex)
  369 + {
  370 + ex.printStackTrace();
  371 + }
  372 + }
  373 +
  374 + private void injectInterfaceMethods(ClassNode classNode, String interfaceName) throws IOException
  375 + {
  376 + ClassReader interfaceReader = new ClassReader(this.getInterfaceBytes(interfaceName));
  377 + ClassNode interfaceNode = new ClassNode();
  378 + interfaceReader.accept(interfaceNode, 0);
  379 +
  380 + for (MethodNode interfaceMethod : interfaceNode.methods)
  381 + {
  382 + classNode.methods.add(interfaceMethod);
  383 + this.populateInterfaceMethod(classNode, interfaceMethod);
  384 + }
  385 +
  386 + for (String parentInterface : interfaceNode.interfaces)
  387 + {
  388 + this.injectInterfaceMethods(classNode, parentInterface.replace('/', '.'));
  389 + }
  390 + }
  391 +
  392 + private void populateInterfaceMethod(ClassNode classNode, MethodNode method)
  393 + {
  394 + Type returnType = Type.getReturnType(method.desc);
  395 +
  396 + if (returnType.equals(Type.VOID_TYPE))
  397 + {
  398 + Type[] args = Type.getArgumentTypes(method.desc);
  399 + method.access = Opcodes.ACC_PUBLIC;
  400 +
  401 + for (int i = 0; i < this.size; i++)
  402 + {
  403 + LabelNode lineNumberLabel = new LabelNode(new Label());
  404 + method.instructions.add(lineNumberLabel);
  405 + method.instructions.add(new LineNumberNode(++this.lineNumber, lineNumberLabel));
  406 + method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
  407 + method.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, "handler$" + i, "L" + this.typeRef + ";"));
  408 + this.invokeInterfaceMethod(method, args);
  409 + }
  410 +
  411 + method.instructions.add(new InsnNode(Opcodes.RETURN));
  412 + }
  413 + }
  414 +
  415 + private void invokeInterfaceMethod(MethodNode method, Type[] args)
  416 + {
  417 + int argNumber = 1;
  418 + for (Type type : args)
  419 + {
  420 + method.instructions.add(new VarInsnNode(type.getOpcode(Opcodes.ILOAD), argNumber));
  421 + argNumber += type.getSize();
  422 + }
  423 +
  424 + method.instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE, this.typeRef, method.name, method.desc, true));
  425 + }
  426 +
  427 + private String getNextClassName()
  428 + {
  429 + return String.format("%s$%s$%s", Obf.HandlerList.name, this.type.getSimpleName(), HandlerListClassLoader.handlerIndex++);
  430 + }
  431 +
  432 + private byte[] getInterfaceBytes(String name) throws IOException
  433 + {
  434 + byte[] bytes = Launch.classLoader.getClassBytes(name);
  435 +
  436 + final List<IClassTransformer> transformers = Launch.classLoader.getTransformers();
  437 +
  438 + for (final IClassTransformer transformer : transformers)
  439 + {
  440 + try
  441 + {
  442 + bytes = transformer.transform(name, name, bytes);
  443 + }
  444 + catch (Exception ex)
  445 + {
  446 + ex.printStackTrace();
  447 + }
  448 + }
  449 +
  450 + return bytes;
  451 + }
  452 + }
  453 +}
... ...
java/common/com/mumfrey/liteloader/core/runtime/Obf.java
... ... @@ -17,6 +17,8 @@ public class Obf
17 17 public static final Obf CallbackProxyClient = new Obf("com.mumfrey.liteloader.client.CallbackProxyClient" );
18 18 public static final Obf CallbackProxyServer = new Obf("com.mumfrey.liteloader.server.CallbackProxyServer" );
19 19 public static final Obf EventProxy = new Obf("com.mumfrey.liteloader.core.event.EventProxy" );
  20 + public static final Obf HandlerList = new Obf("com.mumfrey.liteloader.core.event.HandlerList" );
  21 + public static final Obf BakedHandlerList = new Obf("com.mumfrey.liteloader.core.event.HandlerList$BakedHandlerList" );
20 22 public static final Obf LoadingBar = new Obf("com.mumfrey.liteloader.client.gui.startup.LoadingBar" );
21 23 public static final Obf GameProfile = new Obf("com.mojang.authlib.GameProfile" );
22 24 public static final Obf MinecraftMain = new Obf("net.minecraft.client.main.Main" );
... ...