Commit 1782552f6e30982177b67f95efe69326c79614a5
1 parent
634b0659
wrap mod instances for better handling for startup errors, report startup errors to the user
Showing
27 changed files
with
1261 additions
and
322 deletions
java/client/com/mumfrey/liteloader/client/ClientEvents.java
... | ... | @@ -480,6 +480,7 @@ public class ClientEvents extends Events<Minecraft, IntegratedServer> |
480 | 480 | } |
481 | 481 | catch (Throwable th) |
482 | 482 | { |
483 | + this.mods.onLateInitFailed(initMod, th); | |
483 | 484 | LiteLoaderLogger.warning(th, "Error initialising mod %s", initMod.getName()); |
484 | 485 | } |
485 | 486 | } | ... | ... |
java/client/com/mumfrey/liteloader/client/LiteLoaderPanelManager.java
... | ... | @@ -185,6 +185,12 @@ public class LiteLoaderPanelManager implements PanelManager<GuiScreen> |
185 | 185 | this.minecraft.displayGuiScreen(this.panelHost); |
186 | 186 | } |
187 | 187 | } |
188 | + | |
189 | + @Override | |
190 | + public int getStartupErrorCount() | |
191 | + { | |
192 | + return this.mods.getStartupErrorCount(); | |
193 | + } | |
188 | 194 | |
189 | 195 | private boolean isPanelSupportedOnScreen(GuiScreen guiScreen) |
190 | 196 | { | ... | ... |
java/client/com/mumfrey/liteloader/client/api/LiteLoaderCoreAPIClient.java
... | ... | @@ -82,7 +82,8 @@ public class LiteLoaderCoreAPIClient extends LiteLoaderCoreAPI |
82 | 82 | { |
83 | 83 | return ImmutableList.<CustomisationProvider>of |
84 | 84 | ( |
85 | - new LiteLoaderBrandingProvider() | |
85 | + new LiteLoaderBrandingProvider(), | |
86 | + new LiteLoaderModInfoDecorator() | |
86 | 87 | ); |
87 | 88 | } |
88 | 89 | ... | ... |
java/client/com/mumfrey/liteloader/client/api/LiteLoaderModInfoDecorator.java
0 → 100644
1 | +package com.mumfrey.liteloader.client.api; | |
2 | + | |
3 | +import java.util.List; | |
4 | + | |
5 | +import net.minecraft.client.resources.I18n; | |
6 | + | |
7 | +import com.mumfrey.liteloader.api.ModInfoDecorator; | |
8 | +import com.mumfrey.liteloader.client.gui.GuiLiteLoaderPanel; | |
9 | +import com.mumfrey.liteloader.client.util.render.IconAbsolute; | |
10 | +import com.mumfrey.liteloader.client.util.render.IconAbsoluteClickable; | |
11 | +import com.mumfrey.liteloader.core.ModInfo; | |
12 | +import com.mumfrey.liteloader.util.render.IconTextured; | |
13 | + | |
14 | +/** | |
15 | + * ModInfo decorator | |
16 | + * | |
17 | + * @author Adam Mummery-Smith | |
18 | + */ | |
19 | +public class LiteLoaderModInfoDecorator implements ModInfoDecorator | |
20 | +{ | |
21 | + /* (non-Javadoc) | |
22 | + * @see com.mumfrey.liteloader.api.ModInfoDecorator#addIcons(com.mumfrey.liteloader.core.ModInfo, java.util.List) | |
23 | + */ | |
24 | + @Override | |
25 | + public void addIcons(final ModInfo<?> mod, List<IconTextured> icons) | |
26 | + { | |
27 | + if (mod.hasTweakClass()) | |
28 | + { | |
29 | + icons.add(new IconAbsolute(LiteLoaderBrandingProvider.ABOUT_TEXTURE, I18n.format("gui.mod.providestweak"), 12, 12, 158, 80, 170, 92)); | |
30 | + } | |
31 | + | |
32 | + if (mod.hasClassTransformers()) | |
33 | + { | |
34 | + icons.add(new IconAbsolute(LiteLoaderBrandingProvider.ABOUT_TEXTURE, I18n.format("gui.mod.providestransformer"), 12, 12, 170, 80, 182, 92)); | |
35 | + } | |
36 | + | |
37 | + if (mod.usesAPI()) | |
38 | + { | |
39 | + icons.add(new IconAbsolute(LiteLoaderBrandingProvider.ABOUT_TEXTURE, I18n.format("gui.mod.usingapi"), 12, 12, 122, 92, 134, 104)); | |
40 | + } | |
41 | + | |
42 | + List<Throwable> startupErrors = mod.getStartupErrors(); | |
43 | + if (startupErrors != null && startupErrors.size() > 0) | |
44 | + { | |
45 | + icons.add(new IconAbsoluteClickable(LiteLoaderBrandingProvider.ABOUT_TEXTURE, I18n.format("gui.mod.startuperror", startupErrors.size()), 12, 12, 134, 92, 146, 104){ | |
46 | + @Override | |
47 | + public void onClicked(Object source, Object container) | |
48 | + { | |
49 | + if (source instanceof GuiLiteLoaderPanel) | |
50 | + { | |
51 | + ((GuiLiteLoaderPanel)source).showErrorPanel(mod); | |
52 | + } | |
53 | + } | |
54 | + }); | |
55 | + } | |
56 | + } | |
57 | +} | ... | ... |
java/client/com/mumfrey/liteloader/client/gui/GuiLiteLoaderPanel.java
... | ... | @@ -3,10 +3,13 @@ package com.mumfrey.liteloader.client.gui; |
3 | 3 | import static org.lwjgl.opengl.GL11.*; |
4 | 4 | |
5 | 5 | import java.nio.DoubleBuffer; |
6 | +import java.util.ArrayList; | |
7 | +import java.util.List; | |
6 | 8 | |
7 | 9 | import net.minecraft.client.Minecraft; |
8 | 10 | import net.minecraft.client.gui.FontRenderer; |
9 | 11 | import net.minecraft.client.gui.GuiButton; |
12 | +import net.minecraft.client.gui.GuiMainMenu; | |
10 | 13 | import net.minecraft.client.gui.GuiScreen; |
11 | 14 | import net.minecraft.client.renderer.Tessellator; |
12 | 15 | import net.minecraft.client.resources.I18n; |
... | ... | @@ -20,10 +23,12 @@ import org.lwjgl.input.Mouse; |
20 | 23 | import com.mumfrey.liteloader.LiteMod; |
21 | 24 | import com.mumfrey.liteloader.api.LiteAPI; |
22 | 25 | import com.mumfrey.liteloader.api.BrandingProvider; |
26 | +import com.mumfrey.liteloader.api.ModInfoDecorator; | |
23 | 27 | import com.mumfrey.liteloader.client.api.LiteLoaderBrandingProvider; |
24 | 28 | import com.mumfrey.liteloader.core.LiteLoader; |
25 | 29 | import com.mumfrey.liteloader.core.LiteLoaderVersion; |
26 | 30 | import com.mumfrey.liteloader.core.LiteLoaderMods; |
31 | +import com.mumfrey.liteloader.core.ModInfo; | |
27 | 32 | import com.mumfrey.liteloader.core.api.LiteLoaderCoreAPI; |
28 | 33 | import com.mumfrey.liteloader.launch.LoaderEnvironment; |
29 | 34 | import com.mumfrey.liteloader.modconfig.ConfigManager; |
... | ... | @@ -55,6 +60,10 @@ public class GuiLiteLoaderPanel extends GuiScreen |
55 | 60 | */ |
56 | 61 | private static DoubleBuffer doubleBuffer = BufferUtils.createByteBuffer(64).asDoubleBuffer(); |
57 | 62 | |
63 | + private static int clippingPlaneFlags = 0; | |
64 | + | |
65 | + private static boolean displayErrorToolTip = true; | |
66 | + | |
58 | 67 | /** |
59 | 68 | * Reference to the main menu which this screen is either overlaying or using as its background |
60 | 69 | */ |
... | ... | @@ -108,8 +117,12 @@ public class GuiLiteLoaderPanel extends GuiScreen |
108 | 117 | private ResourceLocation iconResource = LiteLoaderBrandingProvider.ABOUT_TEXTURE; |
109 | 118 | private IIcon iconCoords = LiteLoaderBrandingProvider.ICON_COORDS; |
110 | 119 | |
120 | + private List<ModInfoDecorator> modInfoDecorators = new ArrayList<ModInfoDecorator>(); | |
121 | + | |
111 | 122 | private boolean mouseOverLogo = false; |
112 | 123 | |
124 | + private int startupErrorCount = 0; | |
125 | + | |
113 | 126 | /** |
114 | 127 | * @param minecraft |
115 | 128 | * @param parentScreen |
... | ... | @@ -127,8 +140,10 @@ public class GuiLiteLoaderPanel extends GuiScreen |
127 | 140 | |
128 | 141 | this.initBranding(); |
129 | 142 | |
130 | - this.currentPanel = this.modsPanel = new GuiPanelMods(this, minecraft, mods, environment, configManager, this.brandColour); | |
143 | + this.currentPanel = this.modsPanel = new GuiPanelMods(this, minecraft, mods, environment, configManager, this.brandColour, this.modInfoDecorators); | |
131 | 144 | this.settingsPanel = new GuiPanelSettings(this, minecraft); |
145 | + | |
146 | + this.startupErrorCount = mods.getStartupErrorCount(); | |
132 | 147 | } |
133 | 148 | |
134 | 149 | /** |
... | ... | @@ -145,31 +160,38 @@ public class GuiLiteLoaderPanel extends GuiScreen |
145 | 160 | for (LiteAPI api : LiteLoader.getAPIs()) |
146 | 161 | { |
147 | 162 | BrandingProvider brandingProvider = LiteLoader.getCustomisationProvider(api, BrandingProvider.class); |
148 | - if (brandingProvider == null) continue; | |
149 | - | |
150 | - if (brandingProvider.getBrandingColour() != 0 && brandingProvider.getPriority() > brandingColourProviderPriority) | |
163 | + if (brandingProvider != null) | |
151 | 164 | { |
152 | - brandingColourProviderPriority = brandingProvider.getPriority(); | |
153 | - this.brandColour = 0xFF000000 | brandingProvider.getBrandingColour(); | |
165 | + if (brandingProvider.getBrandingColour() != 0 && brandingProvider.getPriority() > brandingColourProviderPriority) | |
166 | + { | |
167 | + brandingColourProviderPriority = brandingProvider.getPriority(); | |
168 | + this.brandColour = 0xFF000000 | brandingProvider.getBrandingColour(); | |
169 | + } | |
170 | + | |
171 | + ResourceLocation logoResource = brandingProvider.getLogoResource(); | |
172 | + IIcon logoCoords = brandingProvider.getLogoCoords(); | |
173 | + if (logoResource != null && logoCoords != null && brandingProvider.getPriority() > logoProviderPriority) | |
174 | + { | |
175 | + logoProvider = api; | |
176 | + logoProviderPriority = brandingProvider.getPriority(); | |
177 | + this.logoResource = logoResource; | |
178 | + this.logoCoords = logoCoords; | |
179 | + } | |
180 | + | |
181 | + ResourceLocation iconResource = brandingProvider.getIconResource(); | |
182 | + IIcon iconCoords = brandingProvider.getIconCoords(); | |
183 | + if (iconResource != null && iconCoords != null && brandingProvider.getPriority() > iconProviderPriority) | |
184 | + { | |
185 | + iconProviderPriority = brandingProvider.getPriority(); | |
186 | + this.iconResource = iconResource; | |
187 | + this.iconCoords = iconCoords; | |
188 | + } | |
154 | 189 | } |
155 | 190 | |
156 | - ResourceLocation logoResource = brandingProvider.getLogoResource(); | |
157 | - IIcon logoCoords = brandingProvider.getLogoCoords(); | |
158 | - if (logoResource != null && logoCoords != null && brandingProvider.getPriority() > logoProviderPriority) | |
191 | + ModInfoDecorator modInfoDecorator = LiteLoader.getCustomisationProvider(api, ModInfoDecorator.class); | |
192 | + if (modInfoDecorator != null) | |
159 | 193 | { |
160 | - logoProvider = api; | |
161 | - logoProviderPriority = brandingProvider.getPriority(); | |
162 | - this.logoResource = logoResource; | |
163 | - this.logoCoords = logoCoords; | |
164 | - } | |
165 | - | |
166 | - ResourceLocation iconResource = brandingProvider.getIconResource(); | |
167 | - IIcon iconCoords = brandingProvider.getIconCoords(); | |
168 | - if (iconResource != null && iconCoords != null && brandingProvider.getPriority() > iconProviderPriority) | |
169 | - { | |
170 | - iconProviderPriority = brandingProvider.getPriority(); | |
171 | - this.iconResource = iconResource; | |
172 | - this.iconCoords = iconCoords; | |
194 | + this.modInfoDecorators.add(modInfoDecorator); | |
173 | 195 | } |
174 | 196 | } |
175 | 197 | |
... | ... | @@ -218,6 +240,9 @@ public class GuiLiteLoaderPanel extends GuiScreen |
218 | 240 | @Override |
219 | 241 | public void initGui() |
220 | 242 | { |
243 | + // Hide the tooltip once the user opens the panel | |
244 | + GuiLiteLoaderPanel.displayErrorToolTip = false; | |
245 | + | |
221 | 246 | this.currentPanel.setSize(this.width - LEFT_EDGE, this.height); |
222 | 247 | |
223 | 248 | this.buttonList.add(new GuiHoverLabel(2, LEFT_EDGE + MARGIN, this.height - PANEL_BOTTOM + 9, this.fontRendererObj, I18n.format("gui.about.taboptions"), this.brandColour)); |
... | ... | @@ -312,16 +337,11 @@ public class GuiLiteLoaderPanel extends GuiScreen |
312 | 337 | this.handleMouseClick(offsetMouseX, mouseY, partialTicks, active, mouseOverTab); |
313 | 338 | |
314 | 339 | // Calculate the tab opacity, not framerate adjusted because we don't really care |
315 | - this.tabOpacity = mouseOverTab || alwaysExpandTab || this.isOpen() ? 0.5F : Math.max(0.0F, this.tabOpacity - partialTicks * 0.1F); | |
340 | + this.tabOpacity = mouseOverTab || alwaysExpandTab || this.startupErrorCount > 0 || this.isOpen() ? 0.5F : Math.max(0.0F, this.tabOpacity - partialTicks * 0.1F); | |
316 | 341 | |
317 | 342 | // Draw the panel contents |
318 | 343 | this.drawPanel(offsetMouseX, mouseY, partialTicks, active, xOffset); |
319 | - | |
320 | - if (mouseOverTab && this.tweenAmount < 0.01) | |
321 | - { | |
322 | - GuiLiteLoaderPanel.drawTooltip(this.fontRendererObj, LiteLoader.getVersionDisplayString(), mouseX, mouseY, this.width, this.height, 0xFFFFFF, 0xB0000000); | |
323 | - GuiLiteLoaderPanel.drawTooltip(this.fontRendererObj, this.activeModText, mouseX, mouseY + 13, this.width, this.height, 0xCCCCCC, 0xB0000000); | |
324 | - } | |
344 | + this.drawTooltips(mouseX, mouseY, partialTicks, active, xOffset, mouseOverTab); | |
325 | 345 | } |
326 | 346 | |
327 | 347 | /** |
... | ... | @@ -348,6 +368,10 @@ public class GuiLiteLoaderPanel extends GuiScreen |
348 | 368 | |
349 | 369 | this.mc.getTextureManager().bindTexture(LiteLoaderBrandingProvider.ABOUT_TEXTURE); |
350 | 370 | glDrawTexturedRect(LEFT_EDGE - TAB_WIDTH, TAB_TOP, TAB_WIDTH + 1, TAB_HEIGHT, 80, 80, 122, 160, 0.5F + this.tabOpacity); |
371 | + if (this.startupErrorCount > 0) | |
372 | + { | |
373 | + glDrawTexturedRect(LEFT_EDGE - TAB_WIDTH + 7, TAB_TOP + 2, 12, 12, 134, 92, 134 + 12, 92 + 12, 0.5F + this.tabOpacity); | |
374 | + } | |
351 | 375 | } |
352 | 376 | else |
353 | 377 | { |
... | ... | @@ -420,7 +444,30 @@ public class GuiLiteLoaderPanel extends GuiScreen |
420 | 444 | this.mouseOverLogo = (mouseY > MARGIN && mouseY < MARGIN + this.logoCoords.getIconHeight() && mouseX > left && mouseX < left + this.logoCoords.getIconWidth()); |
421 | 445 | return this.mouseOverLogo; |
422 | 446 | } |
423 | - | |
447 | + | |
448 | + private void drawTooltips(int mouseX, int mouseY, float partialTicks, boolean active, float xOffset, boolean mouseOverTab) | |
449 | + { | |
450 | + if (mouseOverTab && this.tweenAmount < 0.01) | |
451 | + { | |
452 | + GuiLiteLoaderPanel.drawTooltip(this.fontRendererObj, LiteLoader.getVersionDisplayString(), mouseX, mouseY, this.width, this.height, 0xFFFFFF, 0xB0000000); | |
453 | + GuiLiteLoaderPanel.drawTooltip(this.fontRendererObj, this.activeModText, mouseX, mouseY + 13, this.width, this.height, 0xCCCCCC, 0xB0000000); | |
454 | + | |
455 | + if (this.startupErrorCount > 0) | |
456 | + { | |
457 | + this.drawErrorTooltip(mouseX, mouseY - 13); | |
458 | + } | |
459 | + } | |
460 | + else if (GuiLiteLoaderPanel.displayErrorToolTip && this.startupErrorCount > 0 && !active && this.parentScreen instanceof GuiMainMenu) | |
461 | + { | |
462 | + this.drawErrorTooltip((int)xOffset + LEFT_EDGE - 12, TAB_TOP + 2); | |
463 | + } | |
464 | + } | |
465 | + | |
466 | + private void drawErrorTooltip(int left, int top) | |
467 | + { | |
468 | + GuiLiteLoaderPanel.drawTooltip(this.fontRendererObj, I18n.format("gui.error.tooltip", this.startupErrorCount), left, top, this.width, this.height, 0xFF5555, 0xB0330000); | |
469 | + } | |
470 | + | |
424 | 471 | /* (non-Javadoc) |
425 | 472 | * @see net.minecraft.client.gui.GuiScreen#actionPerformed(net.minecraft.client.gui.GuiButton) |
426 | 473 | */ |
... | ... | @@ -463,6 +510,11 @@ public class GuiLiteLoaderPanel extends GuiScreen |
463 | 510 | this.setCurrentPanel(new GuiPanelAbout(this.mc, this)); |
464 | 511 | } |
465 | 512 | |
513 | + public void showErrorPanel(ModInfo<?> mod) | |
514 | + { | |
515 | + this.setCurrentPanel(new GuiPanelError(this.mc, this, mod)); | |
516 | + } | |
517 | + | |
466 | 518 | /* (non-Javadoc) |
467 | 519 | * @see net.minecraft.client.gui.GuiScreen#mouseClicked(int, int, int) |
468 | 520 | */ |
... | ... | @@ -688,6 +740,8 @@ public class GuiLiteLoaderPanel extends GuiScreen |
688 | 740 | */ |
689 | 741 | final static void glEnableClipping(int xLeft, int xRight, int yTop, int yBottom) |
690 | 742 | { |
743 | + clippingPlaneFlags = 0; | |
744 | + | |
691 | 745 | // Apply left edge clipping if specified |
692 | 746 | if (xLeft != -1) |
693 | 747 | { |
... | ... | @@ -695,6 +749,7 @@ public class GuiLiteLoaderPanel extends GuiScreen |
695 | 749 | doubleBuffer.put(1).put(0).put(0).put(-xLeft).flip(); |
696 | 750 | glClipPlane(GL_CLIP_PLANE2, doubleBuffer); |
697 | 751 | glEnable(GL_CLIP_PLANE2); |
752 | + clippingPlaneFlags |= GL_CLIP_PLANE2; | |
698 | 753 | } |
699 | 754 | |
700 | 755 | // Apply right edge clipping if specified |
... | ... | @@ -704,6 +759,7 @@ public class GuiLiteLoaderPanel extends GuiScreen |
704 | 759 | doubleBuffer.put(-1).put(0).put(0).put(xRight).flip(); |
705 | 760 | glClipPlane(GL_CLIP_PLANE3, doubleBuffer); |
706 | 761 | glEnable(GL_CLIP_PLANE3); |
762 | + clippingPlaneFlags |= GL_CLIP_PLANE3; | |
707 | 763 | } |
708 | 764 | |
709 | 765 | // Apply top edge clipping if specified |
... | ... | @@ -713,6 +769,7 @@ public class GuiLiteLoaderPanel extends GuiScreen |
713 | 769 | doubleBuffer.put(0).put(1).put(0).put(-yTop).flip(); |
714 | 770 | glClipPlane(GL_CLIP_PLANE4, doubleBuffer); |
715 | 771 | glEnable(GL_CLIP_PLANE4); |
772 | + clippingPlaneFlags |= GL_CLIP_PLANE4; | |
716 | 773 | } |
717 | 774 | |
718 | 775 | // Apply bottom edge clipping if specified |
... | ... | @@ -722,10 +779,22 @@ public class GuiLiteLoaderPanel extends GuiScreen |
722 | 779 | doubleBuffer.put(0).put(-1).put(0).put(yBottom).flip(); |
723 | 780 | glClipPlane(GL_CLIP_PLANE5, doubleBuffer); |
724 | 781 | glEnable(GL_CLIP_PLANE5); |
782 | + clippingPlaneFlags |= GL_CLIP_PLANE5; | |
725 | 783 | } |
726 | 784 | } |
727 | 785 | |
728 | 786 | /** |
787 | + * Enable clipping planes which were previously enabled | |
788 | + */ | |
789 | + final static void glEnableClipping() | |
790 | + { | |
791 | + if ((clippingPlaneFlags & GL_CLIP_PLANE2) == GL_CLIP_PLANE2) glEnable(GL_CLIP_PLANE2); | |
792 | + if ((clippingPlaneFlags & GL_CLIP_PLANE3) == GL_CLIP_PLANE3) glEnable(GL_CLIP_PLANE3); | |
793 | + if ((clippingPlaneFlags & GL_CLIP_PLANE4) == GL_CLIP_PLANE4) glEnable(GL_CLIP_PLANE4); | |
794 | + if ((clippingPlaneFlags & GL_CLIP_PLANE5) == GL_CLIP_PLANE5) glEnable(GL_CLIP_PLANE5); | |
795 | + } | |
796 | + | |
797 | + /** | |
729 | 798 | * Disable OpenGL clipping planes (uses planes 2, 3, 4 and 5) |
730 | 799 | */ |
731 | 800 | final static void glDisableClipping() | ... | ... |
java/client/com/mumfrey/liteloader/client/gui/GuiModListEntry.java
... | ... | @@ -11,16 +11,16 @@ import net.minecraft.client.gui.FontRenderer; |
11 | 11 | import net.minecraft.client.gui.Gui; |
12 | 12 | import net.minecraft.client.resources.I18n; |
13 | 13 | |
14 | -import com.google.common.collect.ImmutableSet; | |
14 | +import com.google.common.base.Strings; | |
15 | 15 | import com.mumfrey.liteloader.LiteMod; |
16 | -import com.mumfrey.liteloader.client.api.LiteLoaderBrandingProvider; | |
17 | -import com.mumfrey.liteloader.client.util.render.IconAbsolute; | |
18 | -import com.mumfrey.liteloader.core.LiteLoaderEnumerator; | |
16 | +import com.mumfrey.liteloader.api.ModInfoDecorator; | |
19 | 17 | import com.mumfrey.liteloader.core.LiteLoaderMods; |
18 | +import com.mumfrey.liteloader.core.ModInfo; | |
20 | 19 | import com.mumfrey.liteloader.interfaces.Loadable; |
21 | 20 | import com.mumfrey.liteloader.interfaces.LoadableMod; |
22 | -import com.mumfrey.liteloader.interfaces.TweakContainer; | |
23 | 21 | import com.mumfrey.liteloader.launch.LoaderEnvironment; |
22 | +import com.mumfrey.liteloader.util.render.IconClickable; | |
23 | +import com.mumfrey.liteloader.util.render.IconTextured; | |
24 | 24 | |
25 | 25 | /** |
26 | 26 | * Represents a mod in the mod info screen, keeps track of mod information and provides methods |
... | ... | @@ -41,6 +41,9 @@ public class GuiModListEntry extends Gui |
41 | 41 | private static final int API_COLOUR = 0xFFAA00AA; |
42 | 42 | private static final int EXTERNAL_ENTRY_COLOUR = 0xFF47D1AA; |
43 | 43 | private static final int MISSING_DEPENDENCY_COLOUR = 0xFFFFAA00; |
44 | + private static final int ERROR_COLOUR = 0xFFFF5555; | |
45 | + private static final int ERROR_GRADIENT_COLOUR = 0xFFAA0000; | |
46 | + private static final int ERROR_GRADIENT_COLOUR2 = 0xFF550000; | |
44 | 47 | |
45 | 48 | private static final int TITLE_COLOUR = GuiModListEntry.WHITE; |
46 | 49 | private static final int VERSION_TEXT_COLOUR = GuiModListEntry.GREY; |
... | ... | @@ -54,8 +57,6 @@ public class GuiModListEntry extends Gui |
54 | 57 | private static final int PANEL_HEIGHT = 32; |
55 | 58 | private static final int PANEL_SPACING = 4; |
56 | 59 | |
57 | - private static final Set<String> BUILT_IN_APIS = ImmutableSet.of("liteloader"); | |
58 | - | |
59 | 60 | /** |
60 | 61 | * For text display |
61 | 62 | */ |
... | ... | @@ -63,12 +64,12 @@ public class GuiModListEntry extends Gui |
63 | 64 | |
64 | 65 | private final int brandColour; |
65 | 66 | |
67 | + private final List<ModInfoDecorator> decorators; | |
68 | + | |
66 | 69 | private final LiteLoaderMods mods; |
67 | 70 | |
68 | - private LiteMod modInstance; | |
71 | + private ModInfo<?> modInfo; | |
69 | 72 | |
70 | - private Class<? extends LiteMod> modClass; | |
71 | - | |
72 | 73 | /** |
73 | 74 | * The identifier of the mod, used as the enablement/disablement key |
74 | 75 | */ |
... | ... | @@ -108,6 +109,8 @@ public class GuiModListEntry extends Gui |
108 | 109 | |
109 | 110 | private boolean isMissingAPIs; |
110 | 111 | |
112 | + private boolean isErrored; | |
113 | + | |
111 | 114 | /** |
112 | 115 | * True if the mod is missing a dependency which has caused it not to load |
113 | 116 | */ |
... | ... | @@ -134,12 +137,14 @@ public class GuiModListEntry extends Gui |
134 | 137 | */ |
135 | 138 | private boolean mouseOverListEntry, mouseOverInfo, mouseOverScrollBar; |
136 | 139 | |
140 | + private IconClickable mouseOverIcon = null; | |
141 | + | |
137 | 142 | /** |
138 | 143 | * True if this is not a mod but an external jar |
139 | 144 | */ |
140 | 145 | private boolean external; |
141 | 146 | |
142 | - private List<IconAbsolute> modIcons = new ArrayList<IconAbsolute>(); | |
147 | + private List<IconTextured> modIcons = new ArrayList<IconTextured>(); | |
143 | 148 | |
144 | 149 | /** |
145 | 150 | * Scroll bar control for the mod info |
... | ... | @@ -149,125 +154,49 @@ public class GuiModListEntry extends Gui |
149 | 154 | /** |
150 | 155 | * Mod list entry for an ACTIVE mod |
151 | 156 | * @param fontRenderer |
152 | - * @param modInstance | |
157 | + * @param modInfo | |
153 | 158 | * @param enabledMods |
154 | 159 | */ |
155 | - GuiModListEntry(LiteLoaderMods mods, LoaderEnvironment environment, FontRenderer fontRenderer, int brandColour, LiteMod modInstance) | |
160 | + GuiModListEntry(LiteLoaderMods mods, LoaderEnvironment environment, FontRenderer fontRenderer, int brandColour, List<ModInfoDecorator> decorators, ModInfo<?> modInfo) | |
156 | 161 | { |
157 | - this.mods = mods; | |
158 | - this.fontRenderer = fontRenderer; | |
159 | - this.brandColour = brandColour; | |
160 | - | |
161 | - this.modInstance = modInstance; | |
162 | - this.modClass = modInstance.getClass(); | |
163 | - this.identifier = mods.getModIdentifier(this.modClass); | |
164 | - this.name = modInstance.getName(); | |
165 | - this.version = modInstance.getVersion(); | |
166 | - this.enabled = true; | |
167 | - this.canBeToggled = this.identifier != null && mods.getEnabledModsList().saveAllowed(); | |
168 | - this.willBeEnabled = this.identifier == null || mods.isModEnabled(this.identifier);; | |
169 | - | |
170 | - LoadableMod<?> modContainer = mods.getModContainer(this.modClass); | |
162 | + this.mods = mods; | |
163 | + this.fontRenderer = fontRenderer; | |
164 | + this.brandColour = brandColour; | |
165 | + this.decorators = decorators; | |
166 | + this.modInfo = modInfo; | |
171 | 167 | |
172 | - this.author = modContainer.getAuthor(); | |
173 | - this.url = modContainer.getMetaValue("url", null); | |
174 | - this.description = modContainer.getDescription(LiteLoaderEnumerator.getModClassName(modInstance)); | |
168 | + this.identifier = modInfo.getIdentifier(); | |
169 | + this.name = modInfo.getDisplayName(); | |
170 | + this.version = modInfo.getVersion(); | |
171 | + this.author = modInfo.getAuthor(); | |
172 | + this.enabled = modInfo.isActive(); | |
173 | + this.canBeToggled = modInfo.isToggleable() && mods.getEnabledModsList().saveAllowed(); | |
174 | + this.willBeEnabled = mods.isModEnabled(this.identifier);; | |
175 | + this.external = modInfo.getContainer().isExternalJar(); | |
176 | + this.description = modInfo.getDescription(); | |
177 | + this.url = modInfo.getURL(); | |
178 | + this.isErrored = modInfo.getStartupErrors() != null && modInfo.getStartupErrors().size() > 0; | |
175 | 179 | |
176 | - boolean providesTweak = false; | |
177 | - boolean providesTransformer = false; | |
178 | - boolean usingAPI = this.checkUsingAPI(modContainer); | |
179 | - | |
180 | - if (modContainer instanceof TweakContainer) | |
180 | + if (!modInfo.isActive()) | |
181 | 181 | { |
182 | - providesTweak = ((TweakContainer<?>)modContainer).hasTweakClass(); | |
183 | - providesTransformer = ((TweakContainer<?>)modContainer).hasClassTransformers(); | |
182 | + this.enabled = modInfo.getContainer().isEnabled(environment); | |
183 | + | |
184 | + Loadable<?> modContainer = modInfo.getContainer(); | |
185 | + if (modContainer instanceof LoadableMod<?>) | |
186 | + { | |
187 | + LoadableMod<?> loadableMod = (LoadableMod<?>)modContainer; | |
188 | + | |
189 | + this.missingDependencies = loadableMod.getMissingDependencies(); | |
190 | + this.missingAPIs = loadableMod.getMissingAPIs(); | |
191 | + this.isMissingDependencies = this.missingDependencies.size() > 0; | |
192 | + this.isMissingAPIs = this.missingAPIs.size() > 0; | |
193 | + } | |
184 | 194 | } |
185 | - | |
186 | - this.initIcons(providesTweak, providesTransformer, usingAPI); | |
187 | - } | |
188 | - | |
189 | - /** | |
190 | - * Mod list entry for a currently disabled mod | |
191 | - * @param mods | |
192 | - * @param fontRenderer | |
193 | - * @param modContainer | |
194 | - */ | |
195 | - GuiModListEntry(LiteLoaderMods mods, LoaderEnvironment environment, FontRenderer fontRenderer, int brandColour, Loadable<?> modContainer) | |
196 | - { | |
197 | - this.mods = mods; | |
198 | - this.fontRenderer = fontRenderer; | |
199 | - this.brandColour = brandColour; | |
200 | - | |
201 | - this.identifier = modContainer.getIdentifier().toLowerCase(); | |
202 | - this.name = modContainer.getDisplayName(); | |
203 | - this.version = modContainer.getVersion(); | |
204 | - this.author = modContainer.getAuthor(); | |
205 | - this.enabled = modContainer.isEnabled(environment); | |
206 | - this.canBeToggled = modContainer.isToggleable() && mods.getEnabledModsList().saveAllowed(); | |
207 | - this.willBeEnabled = mods.isModEnabled(this.identifier); | |
208 | - this.external = modContainer.isExternalJar(); | |
209 | - this.description = modContainer.getDescription(null); | |
210 | - | |
211 | - boolean providesTweak = false; | |
212 | - boolean providesTransformer = false; | |
213 | - boolean usingAPI = false; | |
214 | 195 | |
215 | - if (modContainer instanceof LoadableMod<?>) | |
196 | + for (ModInfoDecorator decorator : this.decorators) | |
216 | 197 | { |
217 | - LoadableMod<?> loadableMod = (LoadableMod<?>)modContainer; | |
218 | - | |
219 | - this.url = loadableMod.getMetaValue("url", null); | |
220 | - this.missingDependencies = loadableMod.getMissingDependencies(); | |
221 | - this.missingAPIs = loadableMod.getMissingAPIs(); | |
222 | - this.isMissingDependencies = this.missingDependencies.size() > 0; | |
223 | - this.isMissingAPIs = this.missingAPIs.size() > 0; | |
224 | - | |
225 | - usingAPI = this.checkUsingAPI(loadableMod); | |
198 | + decorator.addIcons(modInfo, this.modIcons); | |
226 | 199 | } |
227 | - | |
228 | - if (modContainer instanceof TweakContainer) | |
229 | - { | |
230 | - TweakContainer<?> tweakContainer = (TweakContainer<?>)modContainer; | |
231 | - | |
232 | - providesTweak = tweakContainer.hasTweakClass(); | |
233 | - providesTransformer = tweakContainer.hasClassTransformers(); | |
234 | - } | |
235 | - | |
236 | - this.initIcons(providesTweak, providesTransformer, usingAPI); | |
237 | - } | |
238 | - | |
239 | - /** | |
240 | - * @param providesTweak | |
241 | - * @param providesTransformer | |
242 | - * @param usingAPI | |
243 | - */ | |
244 | - protected void initIcons(boolean providesTweak, boolean providesTransformer, boolean usingAPI) | |
245 | - { | |
246 | - if (providesTweak) | |
247 | - { | |
248 | - this.modIcons.add(new IconAbsolute(LiteLoaderBrandingProvider.ABOUT_TEXTURE, I18n.format("gui.mod.providestweak"), 12, 12, 158, 80, 158 + 12, 80 + 12)); | |
249 | - } | |
250 | - | |
251 | - if (providesTransformer) | |
252 | - { | |
253 | - this.modIcons.add(new IconAbsolute(LiteLoaderBrandingProvider.ABOUT_TEXTURE, I18n.format("gui.mod.providestransformer"), 12, 12, 170, 80, 170 + 12, 80 + 12)); | |
254 | - } | |
255 | - | |
256 | - if (usingAPI) | |
257 | - { | |
258 | - this.modIcons.add(new IconAbsolute(LiteLoaderBrandingProvider.ABOUT_TEXTURE, I18n.format("gui.mod.usingapi"), 12, 12, 122, 92, 122 + 12, 92 + 12)); | |
259 | - } | |
260 | - } | |
261 | - | |
262 | - private boolean checkUsingAPI(LoadableMod<?> loadableMod) | |
263 | - { | |
264 | - for (String requiredAPI : loadableMod.getRequiredAPIs()) | |
265 | - { | |
266 | - if (!GuiModListEntry.BUILT_IN_APIS.contains(requiredAPI)) | |
267 | - return true; | |
268 | - } | |
269 | - | |
270 | - return false; | |
271 | 200 | } |
272 | 201 | |
273 | 202 | /** |
... | ... | @@ -305,7 +234,9 @@ public class GuiModListEntry extends Gui |
305 | 234 | xPosition += (width - 14); |
306 | 235 | yPosition += (GuiModListEntry.PANEL_HEIGHT - 14); |
307 | 236 | |
308 | - for (IconAbsolute icon : this.modIcons) | |
237 | + this.mouseOverIcon = null; | |
238 | + | |
239 | + for (IconTextured icon : this.modIcons) | |
309 | 240 | { |
310 | 241 | xPosition = this.drawPropertyIcon(xPosition, yPosition, icon, mouseX, mouseY); |
311 | 242 | } |
... | ... | @@ -313,7 +244,7 @@ public class GuiModListEntry extends Gui |
313 | 244 | return GuiModListEntry.PANEL_HEIGHT + GuiModListEntry.PANEL_SPACING; |
314 | 245 | } |
315 | 246 | |
316 | - protected int drawPropertyIcon(int xPosition, int yPosition, IconAbsolute icon, int mouseX, int mouseY) | |
247 | + protected int drawPropertyIcon(int xPosition, int yPosition, IconTextured icon, int mouseX, int mouseY) | |
317 | 248 | { |
318 | 249 | glColor4f(1.0F, 1.0F, 1.0F, 1.0F); |
319 | 250 | Minecraft.getMinecraft().getTextureManager().bindTexture(icon.getTextureResource()); |
... | ... | @@ -324,7 +255,15 @@ public class GuiModListEntry extends Gui |
324 | 255 | |
325 | 256 | if (mouseX >= xPosition && mouseX <= xPosition + 12 && mouseY >= yPosition && mouseY <= yPosition + 12) |
326 | 257 | { |
327 | - GuiLiteLoaderPanel.drawTooltip(this.fontRenderer, icon.getIconName(), mouseX, mouseY, 4096, 4096, GuiModListEntry.WHITE, GuiModListEntry.BLEND_HALF & GuiModListEntry.BLACK); | |
258 | + String tooltipText = icon.getDisplayText(); | |
259 | + if (tooltipText != null) | |
260 | + { | |
261 | + GuiLiteLoaderPanel.glDisableClipping(); | |
262 | + GuiLiteLoaderPanel.drawTooltip(this.fontRenderer, tooltipText, mouseX, mouseY, 4096, 4096, GuiModListEntry.WHITE, GuiModListEntry.BLEND_HALF & GuiModListEntry.BLACK); | |
263 | + GuiLiteLoaderPanel.glEnableClipping(); | |
264 | + } | |
265 | + | |
266 | + if (icon instanceof IconClickable) this.mouseOverIcon = (IconClickable)icon; | |
328 | 267 | } |
329 | 268 | |
330 | 269 | return xPosition - 14; |
... | ... | @@ -353,7 +292,7 @@ public class GuiModListEntry extends Gui |
353 | 292 | drawRect(xPosition + 5, yPos, xPosition + width, yPos + 1, GuiModListEntry.DIVIDER_COLOUR); yPos += 4; // divider |
354 | 293 | |
355 | 294 | this.fontRenderer.drawString(I18n.format("gui.about.authors") + ": \2477" + this.author, xPosition + 5, yPos, GuiModListEntry.AUTHORS_COLOUR); yPos += 10; |
356 | - if (this.url != null) | |
295 | + if (!Strings.isNullOrEmpty(this.url)) | |
357 | 296 | { |
358 | 297 | this.fontRenderer.drawString(this.url, xPosition + 5, yPos, GuiModListEntry.BLEND_2THRDS & this.brandColour); yPos += 10; |
359 | 298 | } |
... | ... | @@ -423,7 +362,7 @@ public class GuiModListEntry extends Gui |
423 | 362 | */ |
424 | 363 | protected int getGradientColour(boolean selected) |
425 | 364 | { |
426 | - return GuiModListEntry.BLEND_2THRDS & (selected ? (this.external ? GuiModListEntry.EXTERNAL_ENTRY_COLOUR : this.brandColour) : GuiModListEntry.BLACK); | |
365 | + return GuiModListEntry.BLEND_2THRDS & (this.isErrored ? (selected ? GuiModListEntry.ERROR_GRADIENT_COLOUR : GuiModListEntry.ERROR_GRADIENT_COLOUR2) : (selected ? (this.external ? GuiModListEntry.EXTERNAL_ENTRY_COLOUR : this.brandColour) : GuiModListEntry.BLACK)); | |
427 | 366 | } |
428 | 367 | |
429 | 368 | /** |
... | ... | @@ -437,6 +376,7 @@ public class GuiModListEntry extends Gui |
437 | 376 | { |
438 | 377 | if (this.isMissingDependencies) return GuiModListEntry.MISSING_DEPENDENCY_COLOUR; |
439 | 378 | if (this.isMissingAPIs) return GuiModListEntry.API_COLOUR; |
379 | + if (this.isErrored) return GuiModListEntry.ERROR_COLOUR; | |
440 | 380 | if (!this.enabled) return GuiModListEntry.GREY; |
441 | 381 | return this.external ? GuiModListEntry.EXTERNAL_ENTRY_COLOUR : GuiModListEntry.WHITE; |
442 | 382 | } |
... | ... | @@ -497,17 +437,17 @@ public class GuiModListEntry extends Gui |
497 | 437 | |
498 | 438 | public String getKey() |
499 | 439 | { |
500 | - return this.identifier + Integer.toHexString(this.hashCode()); | |
440 | + return (this.isErrored ? "0000" : "") + this.identifier + Integer.toHexString(this.hashCode()); | |
501 | 441 | } |
502 | 442 | |
503 | 443 | public LiteMod getModInstance() |
504 | 444 | { |
505 | - return this.modInstance; | |
445 | + return this.modInfo.getMod(); | |
506 | 446 | } |
507 | 447 | |
508 | 448 | public Class<? extends LiteMod> getModClass() |
509 | 449 | { |
510 | - return this.modClass; | |
450 | + return this.modInfo.getModClass(); | |
511 | 451 | } |
512 | 452 | |
513 | 453 | public String getName() |
... | ... | @@ -545,11 +485,24 @@ public class GuiModListEntry extends Gui |
545 | 485 | return this.willBeEnabled; |
546 | 486 | } |
547 | 487 | |
488 | + public boolean isMouseOverIcon() | |
489 | + { | |
490 | + return this.mouseOverListEntry && this.mouseOverIcon != null; | |
491 | + } | |
492 | + | |
548 | 493 | public boolean isMouseOver() |
549 | 494 | { |
550 | 495 | return this.mouseOverListEntry; |
551 | 496 | } |
552 | - | |
497 | + | |
498 | + public void iconClick(Object source) | |
499 | + { | |
500 | + if (this.mouseOverIcon != null) | |
501 | + { | |
502 | + this.mouseOverIcon.onClicked(source, this); | |
503 | + } | |
504 | + } | |
505 | + | |
553 | 506 | public boolean mouseWheelScrolled(int mouseWheelDelta) |
554 | 507 | { |
555 | 508 | if (this.mouseOverInfo) | ... | ... |
java/client/com/mumfrey/liteloader/client/gui/GuiPanelConfigContainer.java
... | ... | @@ -109,7 +109,14 @@ class GuiPanelConfigContainer extends GuiPanel implements ConfigPanelHost |
109 | 109 | @Override |
110 | 110 | void onShown() |
111 | 111 | { |
112 | - this.panel.onPanelShown(this); | |
112 | + try | |
113 | + { | |
114 | + this.panel.onPanelShown(this); | |
115 | + } | |
116 | + catch (Exception ex) | |
117 | + { | |
118 | + ex.printStackTrace(); | |
119 | + } | |
113 | 120 | } |
114 | 121 | |
115 | 122 | /** |
... | ... | @@ -118,7 +125,14 @@ class GuiPanelConfigContainer extends GuiPanel implements ConfigPanelHost |
118 | 125 | @Override |
119 | 126 | void onHidden() |
120 | 127 | { |
121 | - this.panel.onPanelHidden(); | |
128 | + try | |
129 | + { | |
130 | + this.panel.onPanelHidden(); | |
131 | + } | |
132 | + catch (Exception ex) | |
133 | + { | |
134 | + ex.printStackTrace(); | |
135 | + } | |
122 | 136 | } |
123 | 137 | |
124 | 138 | /** | ... | ... |
java/client/com/mumfrey/liteloader/client/gui/GuiPanelError.java
0 → 100644
1 | +package com.mumfrey.liteloader.client.gui; | |
2 | + | |
3 | +import java.io.PrintWriter; | |
4 | +import java.io.StringWriter; | |
5 | +import java.util.ArrayList; | |
6 | +import java.util.List; | |
7 | + | |
8 | +import org.lwjgl.input.Keyboard; | |
9 | + | |
10 | +import com.mumfrey.liteloader.core.ModInfo; | |
11 | + | |
12 | +import net.minecraft.client.Minecraft; | |
13 | +import net.minecraft.client.gui.GuiButton; | |
14 | +import net.minecraft.client.resources.I18n; | |
15 | + | |
16 | +public class GuiPanelError extends GuiPanel implements ScrollPanelContent | |
17 | +{ | |
18 | + private final ModInfo<?> mod; | |
19 | + | |
20 | + private GuiScrollPanel scrollPane; | |
21 | + | |
22 | + private List<String> scrollPaneContent = new ArrayList<String>(); | |
23 | + | |
24 | + public GuiPanelError(Minecraft minecraft, GuiLiteLoaderPanel parent, ModInfo<?> mod) | |
25 | + { | |
26 | + super(minecraft); | |
27 | + | |
28 | + this.mod = mod; | |
29 | + this.scrollPane = new GuiScrollPanel(minecraft, this, MARGIN, TOP, this.width - (MARGIN * 2), this.height - TOP - BOTTOM); | |
30 | + | |
31 | + this.populateScrollPaneContent(); | |
32 | + } | |
33 | + | |
34 | + private void populateScrollPaneContent() | |
35 | + { | |
36 | + for (Throwable th : this.mod.getStartupErrors()) | |
37 | + { | |
38 | + StringWriter sw = new StringWriter(); | |
39 | + th.printStackTrace(new PrintWriter(sw, true)); | |
40 | + for (String line : sw.toString().split("\\r?\\n")) | |
41 | + { | |
42 | + this.scrollPaneContent.add(line.replace("\t", " ")); | |
43 | + } | |
44 | + | |
45 | + this.scrollPaneContent.add("!"); | |
46 | + } | |
47 | + | |
48 | + this.scrollPaneContent.remove(this.scrollPaneContent.size() - 1); | |
49 | + } | |
50 | + | |
51 | + @Override | |
52 | + public int getScrollPanelContentHeight(GuiScrollPanel source) | |
53 | + { | |
54 | + return this.scrollPaneContent.size() * 10; | |
55 | + } | |
56 | + | |
57 | + @Override | |
58 | + public void drawScrollPanelContent(GuiScrollPanel source, int mouseX, int mouseY, float partialTicks, int scrollAmount, int visibleHeight) | |
59 | + { | |
60 | + int yPos = -10; | |
61 | + | |
62 | + for (String line : this.scrollPaneContent) | |
63 | + { | |
64 | + if ("!".equals(line)) | |
65 | + { | |
66 | + yPos += 10; | |
67 | + drawRect(0, yPos + 4, this.width, yPos + 5, 0xFF555555); | |
68 | + } | |
69 | + else | |
70 | + { | |
71 | + boolean indented = line.startsWith(" "); | |
72 | + line = line.replaceAll("\\((.+?\\.java:[0-9]+)\\)", "(\247f$1\247r)"); | |
73 | + line = line.replaceAll("at ([^\\(]+)\\(", "at \2476$1\247r("); | |
74 | + this.mc.fontRendererObj.drawString(line, 2, yPos += 10, indented ? 0xFF999999 : 0xFFFF5555); | |
75 | + } | |
76 | + } | |
77 | + } | |
78 | + | |
79 | + @Override | |
80 | + public void scrollPanelActionPerformed(GuiScrollPanel source, GuiButton control) | |
81 | + { | |
82 | + } | |
83 | + | |
84 | + @Override | |
85 | + public void scrollPanelMousePressed(GuiScrollPanel source, int mouseX, int mouseY, int mouseButton) | |
86 | + { | |
87 | + } | |
88 | + | |
89 | + @Override | |
90 | + void setSize(int width, int height) | |
91 | + { | |
92 | + super.setSize(width, height); | |
93 | + | |
94 | + this.scrollPane.setSizeAndPosition(MARGIN, TOP, this.width - (MARGIN * 2), this.height - TOP - BOTTOM); | |
95 | + this.controls.add(new GuiButton(0, this.width - 59 - MARGIN, this.height - BOTTOM + 9, 60, 20, I18n.format("gui.done"))); | |
96 | + } | |
97 | + | |
98 | + @Override | |
99 | + void draw(int mouseX, int mouseY, float partialTicks) | |
100 | + { | |
101 | + this.mc.fontRendererObj.drawString(I18n.format("gui.error.title", this.mod.getDisplayName()), MARGIN, TOP - 14, 0xFFFFFFFF); | |
102 | + | |
103 | + drawRect(MARGIN, TOP - 4, this.width - MARGIN, TOP - 3, 0xFF999999); | |
104 | + drawRect(MARGIN, this.height - BOTTOM + 2, this.width - MARGIN, this.height - BOTTOM + 3, 0xFF999999); | |
105 | + | |
106 | + this.scrollPane.draw(mouseX, mouseY, partialTicks); | |
107 | + | |
108 | + super.draw(mouseX, mouseY, partialTicks); | |
109 | + } | |
110 | + | |
111 | + @Override | |
112 | + void onTick() | |
113 | + { | |
114 | + } | |
115 | + | |
116 | + @Override | |
117 | + void onHidden() | |
118 | + { | |
119 | + } | |
120 | + | |
121 | + @Override | |
122 | + void onShown() | |
123 | + { | |
124 | + } | |
125 | + | |
126 | + @Override | |
127 | + void keyPressed(char keyChar, int keyCode) | |
128 | + { | |
129 | + if (keyCode == Keyboard.KEY_ESCAPE) this.close(); | |
130 | + } | |
131 | + | |
132 | + @Override | |
133 | + void mousePressed(int mouseX, int mouseY, int mouseButton) | |
134 | + { | |
135 | + this.scrollPane.mousePressed(mouseX, mouseY, mouseButton); | |
136 | + super.mousePressed(mouseX, mouseY, mouseButton); | |
137 | + } | |
138 | + | |
139 | + @Override | |
140 | + void mouseMoved(int mouseX, int mouseY) | |
141 | + { | |
142 | + } | |
143 | + | |
144 | + @Override | |
145 | + void mouseReleased(int mouseX, int mouseY, int mouseButton) | |
146 | + { | |
147 | + this.scrollPane.mouseReleased(mouseX, mouseY, mouseButton); | |
148 | + } | |
149 | + | |
150 | + @Override | |
151 | + void mouseWheelScrolled(int mouseWheelDelta) | |
152 | + { | |
153 | + this.scrollPane.mouseWheelScrolled(mouseWheelDelta); | |
154 | + } | |
155 | + | |
156 | + @Override | |
157 | + void actionPerformed(GuiButton control) | |
158 | + { | |
159 | + if (control.id == 0) this.close(); | |
160 | + } | |
161 | +} | ... | ... |
java/client/com/mumfrey/liteloader/client/gui/GuiPanelMods.java
... | ... | @@ -10,8 +10,11 @@ import java.util.TreeMap; |
10 | 10 | import org.lwjgl.input.Keyboard; |
11 | 11 | |
12 | 12 | import com.mumfrey.liteloader.LiteMod; |
13 | +import com.mumfrey.liteloader.api.ModInfoDecorator; | |
13 | 14 | import com.mumfrey.liteloader.core.LiteLoaderMods; |
15 | +import com.mumfrey.liteloader.core.ModInfo; | |
14 | 16 | import com.mumfrey.liteloader.interfaces.Loadable; |
17 | +import com.mumfrey.liteloader.interfaces.LoadableMod; | |
15 | 18 | import com.mumfrey.liteloader.launch.LoaderEnvironment; |
16 | 19 | import com.mumfrey.liteloader.modconfig.ConfigManager; |
17 | 20 | import com.mumfrey.liteloader.modconfig.ConfigPanel; |
... | ... | @@ -70,7 +73,7 @@ public class GuiPanelMods extends GuiPanel |
70 | 73 | |
71 | 74 | private int brandColour; |
72 | 75 | |
73 | - public GuiPanelMods(GuiLiteLoaderPanel parentScreen, Minecraft minecraft, LiteLoaderMods mods, LoaderEnvironment environment, ConfigManager configManager, int brandColour) | |
76 | + public GuiPanelMods(GuiLiteLoaderPanel parentScreen, Minecraft minecraft, LiteLoaderMods mods, LoaderEnvironment environment, ConfigManager configManager, int brandColour, List<ModInfoDecorator> decorators) | |
74 | 77 | { |
75 | 78 | super(minecraft); |
76 | 79 | |
... | ... | @@ -78,7 +81,7 @@ public class GuiPanelMods extends GuiPanel |
78 | 81 | this.configManager = configManager; |
79 | 82 | this.brandColour = brandColour; |
80 | 83 | |
81 | - this.populateModList(mods, environment); | |
84 | + this.populateModList(mods, environment, decorators); | |
82 | 85 | } |
83 | 86 | |
84 | 87 | /** |
... | ... | @@ -87,29 +90,29 @@ public class GuiPanelMods extends GuiPanel |
87 | 90 | * @param mods |
88 | 91 | * @param environment |
89 | 92 | */ |
90 | - private void populateModList(LiteLoaderMods mods, LoaderEnvironment environment) | |
93 | + private void populateModList(LiteLoaderMods mods, LoaderEnvironment environment, List<ModInfoDecorator> decorators) | |
91 | 94 | { |
92 | 95 | // Add mods to this treeset first, in order to sort them |
93 | 96 | Map<String, GuiModListEntry> sortedMods = new TreeMap<String, GuiModListEntry>(); |
94 | 97 | |
95 | 98 | // Active mods |
96 | - for (LiteMod mod : mods.getLoadedMods()) | |
99 | + for (ModInfo<LoadableMod<?>> mod : mods.getLoadedMods()) | |
97 | 100 | { |
98 | - GuiModListEntry modListEntry = new GuiModListEntry(mods, environment, this.mc.fontRendererObj, this.brandColour, mod); | |
101 | + GuiModListEntry modListEntry = new GuiModListEntry(mods, environment, this.mc.fontRendererObj, this.brandColour, decorators, mod); | |
99 | 102 | sortedMods.put(modListEntry.getKey(), modListEntry); |
100 | 103 | } |
101 | 104 | |
102 | 105 | // Disabled mods |
103 | - for (Loadable<?> disabledMod : mods.getDisabledMods()) | |
106 | + for (ModInfo<Loadable<?>> disabledMod : mods.getDisabledMods()) | |
104 | 107 | { |
105 | - GuiModListEntry modListEntry = new GuiModListEntry(mods, environment, this.mc.fontRendererObj, this.brandColour, disabledMod); | |
108 | + GuiModListEntry modListEntry = new GuiModListEntry(mods, environment, this.mc.fontRendererObj, this.brandColour, decorators, disabledMod); | |
106 | 109 | sortedMods.put(modListEntry.getKey(), modListEntry); |
107 | 110 | } |
108 | 111 | |
109 | 112 | // Injected tweaks |
110 | - for (Loadable<?> injectedTweak : mods.getInjectedTweaks()) | |
113 | + for (ModInfo<Loadable<?>> injectedTweak : mods.getInjectedTweaks()) | |
111 | 114 | { |
112 | - GuiModListEntry modListEntry = new GuiModListEntry(mods, environment, this.mc.fontRendererObj, this.brandColour, injectedTweak); | |
115 | + GuiModListEntry modListEntry = new GuiModListEntry(mods, environment, this.mc.fontRendererObj, this.brandColour, decorators, injectedTweak); | |
113 | 116 | sortedMods.put(modListEntry.getKey(), modListEntry); |
114 | 117 | } |
115 | 118 | |
... | ... | @@ -178,10 +181,17 @@ public class GuiPanelMods extends GuiPanel |
178 | 181 | { |
179 | 182 | this.selectMod(mod); |
180 | 183 | |
181 | - // handle double-click | |
182 | - if (mod == lastSelectedMod && this.doubleClickTime > 0 && this.btnConfig.visible) | |
184 | + if (mod.isMouseOverIcon()) | |
183 | 185 | { |
184 | - this.actionPerformed(this.btnConfig); | |
186 | + mod.iconClick(this.parentScreen); | |
187 | + } | |
188 | + else | |
189 | + { | |
190 | + // handle double-click | |
191 | + if (mod == lastSelectedMod && this.doubleClickTime > 0 && this.btnConfig.visible) | |
192 | + { | |
193 | + this.actionPerformed(this.btnConfig); | |
194 | + } | |
185 | 195 | } |
186 | 196 | |
187 | 197 | this.doubleClickTime = 5; | ... | ... |
java/client/com/mumfrey/liteloader/client/util/render/IconAbsolute.java
1 | 1 | package com.mumfrey.liteloader.client.util.render; |
2 | 2 | |
3 | -import net.minecraft.util.IIcon; | |
3 | +import com.mumfrey.liteloader.util.render.IconTextured; | |
4 | + | |
4 | 5 | import net.minecraft.util.ResourceLocation; |
5 | 6 | |
6 | -public class IconAbsolute implements IIcon | |
7 | +public class IconAbsolute implements IconTextured | |
7 | 8 | { |
8 | 9 | private ResourceLocation textureResource; |
9 | 10 | |
10 | - private String name; | |
11 | + private String displayText; | |
11 | 12 | |
12 | 13 | private int texMapSize = 256; |
13 | 14 | |
... | ... | @@ -21,15 +22,15 @@ public class IconAbsolute implements IIcon |
21 | 22 | private float vCoord; |
22 | 23 | private float vCoord2; |
23 | 24 | |
24 | - public IconAbsolute(ResourceLocation textureResource, String name, int width, int height, float uCoord, float vCoord, float uCoord2, float vCoord2) | |
25 | + public IconAbsolute(ResourceLocation textureResource, String displayText, int width, int height, float uCoord, float vCoord, float uCoord2, float vCoord2) | |
25 | 26 | { |
26 | - this(textureResource, name, width, height, uCoord, vCoord, uCoord2, vCoord2, 256); | |
27 | + this(textureResource, displayText, width, height, uCoord, vCoord, uCoord2, vCoord2, 256); | |
27 | 28 | } |
28 | 29 | |
29 | - public IconAbsolute(ResourceLocation textureResource, String name, int width, int height, float uCoord, float vCoord, float uCoord2, float vCoord2, int texMapSize) | |
30 | + public IconAbsolute(ResourceLocation textureResource, String displayText, int width, int height, float uCoord, float vCoord, float uCoord2, float vCoord2, int texMapSize) | |
30 | 31 | { |
31 | 32 | this.textureResource = textureResource; |
32 | - this.name = name; | |
33 | + this.displayText = displayText; | |
33 | 34 | this.width = width; |
34 | 35 | this.height = height; |
35 | 36 | |
... | ... | @@ -42,7 +43,14 @@ public class IconAbsolute implements IIcon |
42 | 43 | this.vCoord = vCoord / this.texMapSize; |
43 | 44 | this.vCoord2 = vCoord2 / this.texMapSize; |
44 | 45 | } |
46 | + | |
47 | + @Override | |
48 | + public String getDisplayText() | |
49 | + { | |
50 | + return this.displayText; | |
51 | + } | |
45 | 52 | |
53 | + @Override | |
46 | 54 | public ResourceLocation getTextureResource() |
47 | 55 | { |
48 | 56 | return this.textureResource; |
... | ... | @@ -60,11 +68,13 @@ public class IconAbsolute implements IIcon |
60 | 68 | return this.height; |
61 | 69 | } |
62 | 70 | |
71 | + @Override | |
63 | 72 | public int getUPos() |
64 | 73 | { |
65 | 74 | return this.uPos; |
66 | 75 | } |
67 | 76 | |
77 | + @Override | |
68 | 78 | public int getVPos() |
69 | 79 | { |
70 | 80 | return this.vPos; |
... | ... | @@ -111,6 +121,6 @@ public class IconAbsolute implements IIcon |
111 | 121 | @Override |
112 | 122 | public String getIconName() |
113 | 123 | { |
114 | - return this.name; | |
124 | + return this.displayText; | |
115 | 125 | } |
116 | 126 | } | ... | ... |
java/client/com/mumfrey/liteloader/client/util/render/IconAbsoluteClickable.java
0 → 100644
1 | +package com.mumfrey.liteloader.client.util.render; | |
2 | + | |
3 | +import net.minecraft.util.ResourceLocation; | |
4 | + | |
5 | +import com.mumfrey.liteloader.util.render.IconClickable; | |
6 | + | |
7 | +public abstract class IconAbsoluteClickable extends IconAbsolute implements IconClickable | |
8 | +{ | |
9 | + public IconAbsoluteClickable(ResourceLocation textureResource, String displayText, int width, int height, float uCoord, float vCoord, float uCoord2, float vCoord2) | |
10 | + { | |
11 | + super(textureResource, displayText, width, height, uCoord, vCoord, uCoord2, vCoord2); | |
12 | + } | |
13 | + | |
14 | + public IconAbsoluteClickable(ResourceLocation textureResource, String displayText, int width, int height, float uCoord, float vCoord, float uCoord2, float vCoord2, int texMapSize) | |
15 | + { | |
16 | + super(textureResource, displayText, width, height, uCoord, vCoord, uCoord2, vCoord2, texMapSize); | |
17 | + } | |
18 | +} | ... | ... |
java/common/com/mumfrey/liteloader/api/ModInfoDecorator.java
0 → 100644
1 | +package com.mumfrey.liteloader.api; | |
2 | + | |
3 | +import java.util.List; | |
4 | + | |
5 | +import com.mumfrey.liteloader.core.ModInfo; | |
6 | +import com.mumfrey.liteloader.util.render.IconTextured; | |
7 | + | |
8 | +/** | |
9 | + * LiteLoader Extensible API - Branding Provider | |
10 | + * | |
11 | + * Decorator for ModInfo classes, to alter the appearance of ModInfo entries in the mod list | |
12 | + * | |
13 | + * @author Adam Mummery-Smith | |
14 | + */ | |
15 | +public interface ModInfoDecorator extends CustomisationProvider | |
16 | +{ | |
17 | + /** | |
18 | + * Add icons to the mod list entry for this mod | |
19 | + * | |
20 | + * @param mod | |
21 | + * @param icons | |
22 | + */ | |
23 | + public abstract void addIcons(ModInfo<?> mod, List<IconTextured> icons); | |
24 | +} | ... | ... |
java/common/com/mumfrey/liteloader/core/Events.java
... | ... | @@ -55,7 +55,8 @@ public abstract class Events<TClient, TServer extends MinecraftServer> implement |
55 | 55 | * Profiler |
56 | 56 | */ |
57 | 57 | protected final Profiler profiler; |
58 | - | |
58 | + | |
59 | + protected LiteLoaderMods mods; | |
59 | 60 | |
60 | 61 | /** |
61 | 62 | * List of mods which can filter server chat |
... | ... | @@ -84,6 +85,14 @@ public abstract class Events<TClient, TServer extends MinecraftServer> implement |
84 | 85 | this.engine = engine; |
85 | 86 | this.profiler = engine.getProfiler(); |
86 | 87 | } |
88 | + | |
89 | + /** | |
90 | + * @param mods | |
91 | + */ | |
92 | + void setMods(LiteLoaderMods mods) | |
93 | + { | |
94 | + this.mods = mods; | |
95 | + } | |
87 | 96 | |
88 | 97 | /** |
89 | 98 | * | ... | ... |
java/common/com/mumfrey/liteloader/core/LiteLoader.java
... | ... | @@ -2,6 +2,7 @@ package com.mumfrey.liteloader.core; |
2 | 2 | |
3 | 3 | import java.io.File; |
4 | 4 | import java.io.PrintStream; |
5 | +import java.util.ArrayList; | |
5 | 6 | import java.util.Collection; |
6 | 7 | import java.util.LinkedList; |
7 | 8 | import java.util.List; |
... | ... | @@ -602,7 +603,14 @@ public final class LiteLoader |
602 | 603 | */ |
603 | 604 | public List<LiteMod> getLoadedMods() |
604 | 605 | { |
605 | - return this.mods.getLoadedMods(); | |
606 | + List<LiteMod> loadedMods = new ArrayList<LiteMod>(); | |
607 | + | |
608 | + for (ModInfo<LoadableMod<?>> loadedMod : this.mods.getLoadedMods()) | |
609 | + { | |
610 | + loadedMods.add(loadedMod.getMod()); | |
611 | + } | |
612 | + | |
613 | + return loadedMods; | |
606 | 614 | } |
607 | 615 | |
608 | 616 | /** |
... | ... | @@ -610,15 +618,30 @@ public final class LiteLoader |
610 | 618 | */ |
611 | 619 | public List<Loadable<?>> getDisabledMods() |
612 | 620 | { |
613 | - return this.mods.getDisabledMods(); | |
621 | + List<Loadable<?>> disabledMods = new ArrayList<Loadable<?>>(); | |
622 | + | |
623 | + for (ModInfo<Loadable<?>> disabledMod : this.mods.getDisabledMods()) | |
624 | + { | |
625 | + disabledMods.add(disabledMod.getContainer()); | |
626 | + } | |
627 | + | |
628 | + return disabledMods; | |
614 | 629 | } |
615 | 630 | |
616 | 631 | /** |
617 | 632 | * Get the list of injected tweak containers |
618 | 633 | */ |
634 | + @SuppressWarnings("unchecked") | |
619 | 635 | public Collection<Loadable<File>> getInjectedTweaks() |
620 | 636 | { |
621 | - return this.mods.getInjectedTweaks(); | |
637 | + Collection<Loadable<File>> tweaks = new ArrayList<Loadable<File>>(); | |
638 | + | |
639 | + for (ModInfo<Loadable<?>> tweak : this.mods.getInjectedTweaks()) | |
640 | + { | |
641 | + tweaks.add((Loadable<File>)tweak.getContainer()); | |
642 | + } | |
643 | + | |
644 | + return tweaks; | |
622 | 645 | } |
623 | 646 | |
624 | 647 | /** |
... | ... | @@ -840,6 +863,10 @@ public final class LiteLoader |
840 | 863 | |
841 | 864 | // Create the event broker |
842 | 865 | this.events = this.objectFactory.getEventBroker(); |
866 | + if (this.events != null) | |
867 | + { | |
868 | + this.events.setMods(this.mods); | |
869 | + } | |
843 | 870 | |
844 | 871 | // Get the mod panel manager |
845 | 872 | this.modPanelManager = this.objectFactory.getModPanelManager(); | ... | ... |
java/common/com/mumfrey/liteloader/core/LiteLoaderEnumerator.java
... | ... | @@ -5,8 +5,10 @@ import java.net.MalformedURLException; |
5 | 5 | import java.net.URL; |
6 | 6 | import java.util.ArrayList; |
7 | 7 | import java.util.Collection; |
8 | +import java.util.Collections; | |
8 | 9 | import java.util.HashMap; |
9 | 10 | import java.util.HashSet; |
11 | +import java.util.LinkedHashSet; | |
10 | 12 | import java.util.LinkedList; |
11 | 13 | import java.util.List; |
12 | 14 | import java.util.Map; |
... | ... | @@ -76,17 +78,17 @@ public class LiteLoaderEnumerator implements LoaderEnumerator |
76 | 78 | /** |
77 | 79 | * Classes to load, mapped by class name |
78 | 80 | */ |
79 | - private final Map<String, Class<? extends LiteMod>> modsToLoad = new HashMap<String, Class<? extends LiteMod>>(); | |
81 | + private final Set<ModInfo<LoadableMod<?>>> modsToLoad = new LinkedHashSet<ModInfo<LoadableMod<?>>>(); | |
80 | 82 | |
81 | 83 | /** |
82 | 84 | * Mod containers which are disabled |
83 | 85 | */ |
84 | - private final Map<String, LoadableMod<?>> disabledContainers = new HashMap<String, LoadableMod<?>>(); | |
86 | + private final Map<String, ModInfo<Loadable<?>>> disabledContainers = new HashMap<String, ModInfo<Loadable<?>>>(); | |
85 | 87 | |
86 | 88 | /** |
87 | 89 | * Mapping of identifiers to mod containers |
88 | 90 | */ |
89 | - private final Map<String, LoadableMod<?>> containers = new HashMap<String, LoadableMod<?>>(); | |
91 | + private final Map<String, LoadableMod<?>> enabledContainers = new HashMap<String, LoadableMod<?>>(); | |
90 | 92 | |
91 | 93 | /** |
92 | 94 | * Containers which have already been checked for potential mod candidates |
... | ... | @@ -94,11 +96,6 @@ public class LiteLoaderEnumerator implements LoaderEnumerator |
94 | 96 | private final Set<LoadableMod<?>> enumeratedContainers = new HashSet<LoadableMod<?>>(); |
95 | 97 | |
96 | 98 | /** |
97 | - * Mapping of mods to mod containers | |
98 | - */ | |
99 | - private final Map<String, LoadableMod<?>> modContainers = new HashMap<String, LoadableMod<?>>(); | |
100 | - | |
101 | - /** | |
102 | 99 | * Tweaks to inject |
103 | 100 | */ |
104 | 101 | private final List<TweakContainer<File>> tweakContainers = new ArrayList<TweakContainer<File>>(); |
... | ... | @@ -106,7 +103,7 @@ public class LiteLoaderEnumerator implements LoaderEnumerator |
106 | 103 | /** |
107 | 104 | * Other tweak-containing jars which we have injected |
108 | 105 | */ |
109 | - private final List<Loadable<File>> injectedTweaks = new ArrayList<Loadable<File>>(); | |
106 | + private final List<ModInfo<Loadable<?>>> injectedTweaks = new ArrayList<ModInfo<Loadable<?>>>(); | |
110 | 107 | |
111 | 108 | /** |
112 | 109 | * |
... | ... | @@ -236,18 +233,18 @@ public class LiteLoaderEnumerator implements LoaderEnumerator |
236 | 233 | * Get the list of all enumerated mod classes to load |
237 | 234 | */ |
238 | 235 | @Override |
239 | - public Collection<Class<? extends LiteMod>> getModsToLoad() | |
236 | + public Collection<? extends ModInfo<LoadableMod<?>>> getModsToLoad() | |
240 | 237 | { |
241 | 238 | this.checkState(EnumeratorState.FINALISED, "getModsToLoad"); |
242 | 239 | |
243 | - return this.modsToLoad.values(); | |
240 | + return Collections.unmodifiableSet(this.modsToLoad); | |
244 | 241 | } |
245 | 242 | |
246 | 243 | /** |
247 | 244 | * @return |
248 | 245 | */ |
249 | 246 | @Override |
250 | - public Collection<LoadableMod<?>> getDisabledContainers() | |
247 | + public Collection<? extends ModInfo<Loadable<?>>> getDisabledContainers() | |
251 | 248 | { |
252 | 249 | this.checkState(EnumeratorState.FINALISED, "getDisabledContainers"); |
253 | 250 | |
... | ... | @@ -258,7 +255,7 @@ public class LiteLoaderEnumerator implements LoaderEnumerator |
258 | 255 | * Get the list of injected tweak containers |
259 | 256 | */ |
260 | 257 | @Override |
261 | - public List<Loadable<File>> getInjectedTweaks() | |
258 | + public List<? extends ModInfo<Loadable<?>>> getInjectedTweaks() | |
262 | 259 | { |
263 | 260 | this.checkState(EnumeratorState.FINALISED, "getInjectedTweaks"); |
264 | 261 | |
... | ... | @@ -299,7 +296,7 @@ public class LiteLoaderEnumerator implements LoaderEnumerator |
299 | 296 | { |
300 | 297 | this.checkState(EnumeratorState.FINALISED, "getContainer"); |
301 | 298 | |
302 | - return this.containers.get(identifier); | |
299 | + return this.enabledContainers.get(identifier); | |
303 | 300 | } |
304 | 301 | |
305 | 302 | /** |
... | ... | @@ -311,7 +308,13 @@ public class LiteLoaderEnumerator implements LoaderEnumerator |
311 | 308 | { |
312 | 309 | this.checkState(EnumeratorState.FINALISED, "getContainer"); |
313 | 310 | |
314 | - return this.modContainers.containsKey(modClass.getSimpleName()) ? this.modContainers.get(modClass.getSimpleName()) : LoadableMod.NONE; | |
311 | + for (ModInfo<LoadableMod<?>> mod : this.modsToLoad) | |
312 | + { | |
313 | + if (modClass.equals(mod.getModClass())) | |
314 | + return mod.getContainer(); | |
315 | + } | |
316 | + | |
317 | + return LoadableMod.NONE; | |
315 | 318 | } |
316 | 319 | |
317 | 320 | /** |
... | ... | @@ -324,8 +327,14 @@ public class LiteLoaderEnumerator implements LoaderEnumerator |
324 | 327 | public String getIdentifier(Class<? extends LiteMod> modClass) |
325 | 328 | { |
326 | 329 | String modClassName = modClass.getSimpleName(); |
327 | - if (!this.modContainers.containsKey(modClassName)) return LiteLoaderEnumerator.getModClassName(modClass); | |
328 | - return this.modContainers.get(modClassName).getIdentifier(); | |
330 | + | |
331 | + for (ModInfo<LoadableMod<?>> mod : this.modsToLoad) | |
332 | + { | |
333 | + if (modClassName.equals(mod.getModClassSimpleName())) | |
334 | + return mod.getIdentifier(); | |
335 | + } | |
336 | + | |
337 | + return LiteLoaderEnumerator.getModClassName(modClass); | |
329 | 338 | } |
330 | 339 | |
331 | 340 | @Override |
... | ... | @@ -447,7 +456,7 @@ public class LiteLoaderEnumerator implements LoaderEnumerator |
447 | 456 | this.checkState(EnumeratorState.DISCOVER, "registerEnabledContainer"); |
448 | 457 | |
449 | 458 | this.disabledContainers.remove(container.getIdentifier()); |
450 | - this.containers.put(container.getIdentifier(), container); | |
459 | + this.enabledContainers.put(container.getIdentifier(), container); | |
451 | 460 | } |
452 | 461 | |
453 | 462 | /** |
... | ... | @@ -457,8 +466,8 @@ public class LiteLoaderEnumerator implements LoaderEnumerator |
457 | 466 | { |
458 | 467 | this.checkState(EnumeratorState.DISCOVER, "registerDisabledContainer"); |
459 | 468 | |
460 | - this.containers.remove(container.getIdentifier()); | |
461 | - this.disabledContainers.put(container.getIdentifier(), container); | |
469 | + this.enabledContainers.remove(container.getIdentifier()); | |
470 | + this.disabledContainers.put(container.getIdentifier(), new NonMod(container, false)); | |
462 | 471 | } |
463 | 472 | |
464 | 473 | /* (non-Javadoc) |
... | ... | @@ -514,7 +523,7 @@ public class LiteLoaderEnumerator implements LoaderEnumerator |
514 | 523 | |
515 | 524 | if (container.isExternalJar()) |
516 | 525 | { |
517 | - this.injectedTweaks.add(container); | |
526 | + this.injectedTweaks.add(new NonMod(container, true)); | |
518 | 527 | } |
519 | 528 | |
520 | 529 | String[] classPathEntries = container.getClassPathEntries(); |
... | ... | @@ -582,9 +591,10 @@ public class LiteLoaderEnumerator implements LoaderEnumerator |
582 | 591 | this.enumeratedContainers.add(container); |
583 | 592 | |
584 | 593 | LinkedList<Class<? extends LiteMod>> modClasses = LiteLoaderEnumerator.<LiteMod>getSubclassesFor(container, this.classLoader, LiteMod.class, this.supportedPrefixes); |
585 | - for (Class<? extends LiteMod> mod : modClasses) | |
594 | + for (Class<? extends LiteMod> modClass : modClasses) | |
586 | 595 | { |
587 | - this.registerMod(mod, registerContainer ? container : null); | |
596 | + Mod mod = new Mod(container, modClass); | |
597 | + this.registerMod(mod); | |
588 | 598 | } |
589 | 599 | |
590 | 600 | if (modClasses.size() > 0) |
... | ... | @@ -592,29 +602,24 @@ public class LiteLoaderEnumerator implements LoaderEnumerator |
592 | 602 | LiteLoaderLogger.info("Found %d potential matches", modClasses.size()); |
593 | 603 | |
594 | 604 | this.disabledContainers.remove(container.getIdentifier()); |
595 | - this.containers.put(container.getIdentifier(), container); | |
605 | + this.enabledContainers.put(container.getIdentifier(), container); | |
596 | 606 | } |
597 | 607 | } |
598 | 608 | |
599 | 609 | /* (non-Javadoc) |
600 | - * @see com.mumfrey.liteloader.core.PluggableEnumerator#addMod(java.lang.Class, com.mumfrey.liteloader.core.LoadableMod) | |
610 | + * @see com.mumfrey.liteloader.interfaces.ModularEnumerator#registerMod(com.mumfrey.liteloader.interfaces.ModInfo) | |
601 | 611 | */ |
602 | 612 | @Override |
603 | - public void registerMod(Class<? extends LiteMod> mod, LoadableMod<?> container) | |
613 | + public void registerMod(ModInfo<LoadableMod<?>> mod) | |
604 | 614 | { |
605 | 615 | this.checkState(EnumeratorState.REGISTER, "registerMod"); |
606 | 616 | |
607 | - if (this.modsToLoad.containsKey(mod.getSimpleName())) | |
617 | + if (this.modsToLoad.contains(mod)) | |
608 | 618 | { |
609 | - LiteLoaderLogger.warning("Mod name collision for mod with class '%s', maybe you have more than one copy?", mod.getSimpleName()); | |
619 | + LiteLoaderLogger.warning("Mod name collision for mod with class '%s', maybe you have more than one copy?", mod.getModClassSimpleName()); | |
610 | 620 | } |
611 | 621 | |
612 | - this.modsToLoad.put(mod.getSimpleName(), mod); | |
613 | - if (container != null) | |
614 | - { | |
615 | - this.modContainers.put(mod.getSimpleName(), container); | |
616 | - container.addContainedMod(LiteLoaderEnumerator.getModClassName(mod)); | |
617 | - } | |
622 | + this.modsToLoad.add(mod); | |
618 | 623 | } |
619 | 624 | |
620 | 625 | /** | ... | ... |
java/common/com/mumfrey/liteloader/core/LiteLoaderMods.java
... | ... | @@ -71,22 +71,24 @@ public class LiteLoaderMods |
71 | 71 | /** |
72 | 72 | * Global list of mods which we can load |
73 | 73 | */ |
74 | - protected final LinkedList<LiteMod> allMods = new LinkedList<LiteMod>(); | |
74 | + protected final LinkedList<Mod> allMods = new LinkedList<Mod>(); | |
75 | 75 | |
76 | 76 | /** |
77 | 77 | * Global list of mods which are still waiting for initialisiation |
78 | 78 | */ |
79 | - protected final LinkedList<LiteMod> initMods = new LinkedList<LiteMod>(); | |
79 | + protected final LinkedList<Mod> initMods = new LinkedList<Mod>(); | |
80 | 80 | |
81 | 81 | /** |
82 | 82 | * Global list of mods which we have loaded |
83 | 83 | */ |
84 | - protected final LinkedList<LiteMod> loadedMods = new LinkedList<LiteMod>(); | |
84 | + protected final LinkedList<Mod> loadedMods = new LinkedList<Mod>(); | |
85 | 85 | |
86 | 86 | /** |
87 | 87 | * Mods which are loaded but disabled |
88 | 88 | */ |
89 | - protected final LinkedList<Loadable<?>> disabledMods = new LinkedList<Loadable<?>>(); | |
89 | + protected final LinkedList<NonMod> disabledMods = new LinkedList<NonMod>(); | |
90 | + | |
91 | + private int startupErrorCount; | |
90 | 92 | |
91 | 93 | LiteLoaderMods(LiteLoader loader, LoaderEnvironment environment, LoaderProperties properties, ConfigManager configManager) |
92 | 94 | { |
... | ... | @@ -97,12 +99,13 @@ public class LiteLoaderMods |
97 | 99 | this.configManager = configManager; |
98 | 100 | } |
99 | 101 | |
102 | + @SuppressWarnings("unchecked") | |
100 | 103 | void init(List<ModLoadObserver> observers) |
101 | 104 | { |
102 | 105 | this.observers = observers; |
103 | - this.disabledMods.addAll(this.enumerator.getDisabledContainers()); | |
106 | + this.disabledMods.addAll((Collection<? extends NonMod>)this.enumerator.getDisabledContainers()); | |
104 | 107 | } |
105 | - | |
108 | + | |
106 | 109 | void onPostInit() |
107 | 110 | { |
108 | 111 | this.updateSharedModList(); |
... | ... | @@ -115,9 +118,9 @@ public class LiteLoaderMods |
115 | 118 | return this.environment.getEnabledModsList(); |
116 | 119 | } |
117 | 120 | |
118 | - public LinkedList<LiteMod> getAllMods() | |
121 | + public List<Mod> getAllMods() | |
119 | 122 | { |
120 | - return this.allMods; | |
123 | + return Collections.unmodifiableList(this.allMods); | |
121 | 124 | } |
122 | 125 | |
123 | 126 | /** |
... | ... | @@ -133,25 +136,41 @@ public class LiteLoaderMods |
133 | 136 | /** |
134 | 137 | * Get a list containing all loaded mods |
135 | 138 | */ |
136 | - public List<LiteMod> getLoadedMods() | |
139 | + public List<? extends ModInfo<LoadableMod<?>>> getLoadedMods() | |
137 | 140 | { |
138 | - return Collections.unmodifiableList(this.loadedMods); | |
141 | + return this.loadedMods; | |
139 | 142 | } |
140 | 143 | |
141 | 144 | /** |
142 | 145 | * Get a list containing all mod files which were NOT loaded |
143 | 146 | */ |
144 | - public List<Loadable<?>> getDisabledMods() | |
147 | + public List<? extends ModInfo<Loadable<?>>> getDisabledMods() | |
145 | 148 | { |
146 | - return Collections.unmodifiableList(this.disabledMods); | |
149 | + return this.disabledMods; | |
147 | 150 | } |
148 | 151 | |
149 | 152 | /** |
150 | 153 | * Get the list of injected tweak containers |
151 | 154 | */ |
152 | - public Collection<Loadable<File>> getInjectedTweaks() | |
155 | + public List<? extends ModInfo<Loadable<?>>> getInjectedTweaks() | |
156 | + { | |
157 | + return this.enumerator.getInjectedTweaks(); | |
158 | + } | |
159 | + | |
160 | + public int getStartupErrorCount() | |
153 | 161 | { |
154 | - return Collections.unmodifiableCollection(this.enumerator.getInjectedTweaks()); | |
162 | + return this.startupErrorCount; | |
163 | + } | |
164 | + | |
165 | + public ModInfo<?> getModInfo(LiteMod instance) | |
166 | + { | |
167 | + for (Mod mod : this.allMods) | |
168 | + { | |
169 | + if (instance == mod.getMod()) | |
170 | + return mod; | |
171 | + } | |
172 | + | |
173 | + return null; | |
155 | 174 | } |
156 | 175 | |
157 | 176 | /** |
... | ... | @@ -186,13 +205,10 @@ public class LiteLoaderMods |
186 | 205 | throw new IllegalArgumentException("Attempted to get a reference to a mod without specifying a mod name"); |
187 | 206 | } |
188 | 207 | |
189 | - for (LiteMod mod : this.allMods) | |
208 | + for (Mod mod : this.allMods) | |
190 | 209 | { |
191 | - Class<? extends LiteMod> modClass = mod.getClass(); | |
192 | - String modId = this.enumerator.getIdentifier(modClass); | |
193 | - | |
194 | - if (modName.equalsIgnoreCase(mod.getName()) || modName.equalsIgnoreCase(modId) || modName.equalsIgnoreCase(modClass.getSimpleName())) | |
195 | - return (T)mod; | |
210 | + if (mod.matchesName(modName)) | |
211 | + return (T)mod.getMod(); | |
196 | 212 | } |
197 | 213 | |
198 | 214 | return null; |
... | ... | @@ -207,9 +223,9 @@ public class LiteLoaderMods |
207 | 223 | @SuppressWarnings("unchecked") |
208 | 224 | public <T extends LiteMod> T getMod(Class<T> modClass) |
209 | 225 | { |
210 | - for (LiteMod mod : this.allMods) | |
226 | + for (Mod mod : this.allMods) | |
211 | 227 | { |
212 | - if (mod.getClass().equals(modClass)) | |
228 | + if (mod.getModClass().equals(modClass)) | |
213 | 229 | return (T)mod; |
214 | 230 | } |
215 | 231 | |
... | ... | @@ -226,12 +242,10 @@ public class LiteLoaderMods |
226 | 242 | { |
227 | 243 | if (identifier == null) return null; |
228 | 244 | |
229 | - for (LiteMod mod : this.allMods) | |
245 | + for (Mod mod : this.allMods) | |
230 | 246 | { |
231 | - if (identifier.equalsIgnoreCase(this.enumerator.getIdentifier(mod.getClass()))) | |
232 | - { | |
233 | - return mod.getClass(); | |
234 | - } | |
247 | + if (mod.matchesIdentifier(identifier)) | |
248 | + return mod.getModClass(); | |
235 | 249 | } |
236 | 250 | |
237 | 251 | return null; |
... | ... | @@ -368,16 +382,14 @@ public class LiteLoaderMods |
368 | 382 | * @param modName |
369 | 383 | * @return |
370 | 384 | */ |
371 | - public boolean isModActive(String modName) | |
385 | + public boolean isModActive(String identifier) | |
372 | 386 | { |
373 | - if (modName == null) return false; | |
387 | + if (identifier == null) return false; | |
374 | 388 | |
375 | - for (LiteMod mod : this.loadedMods) | |
389 | + for (Mod mod : this.loadedMods) | |
376 | 390 | { |
377 | - if (modName.equalsIgnoreCase(this.enumerator.getIdentifier(mod.getClass()))) | |
378 | - { | |
391 | + if (mod.matchesIdentifier(identifier)) | |
379 | 392 | return true; |
380 | - } | |
381 | 393 | } |
382 | 394 | |
383 | 395 | return false; |
... | ... | @@ -392,14 +404,14 @@ public class LiteLoaderMods |
392 | 404 | { |
393 | 405 | LoadingProgress.incTotalLiteLoaderProgress(this.enumerator.getModsToLoad().size()); |
394 | 406 | |
395 | - for (Class<? extends LiteMod> mod : this.enumerator.getModsToLoad()) | |
407 | + for (ModInfo<LoadableMod<?>> mod : this.enumerator.getModsToLoad()) | |
396 | 408 | { |
397 | - LoadingProgress.incLiteLoaderProgress("Loading mod from %s...", mod.getName()); | |
398 | - LoadableMod<?> container = this.enumerator.getContainer(mod); | |
409 | + LoadingProgress.incLiteLoaderProgress("Loading mod from %s...", mod.getModClassSimpleName()); | |
410 | + LoadableMod<?> container = mod.getContainer(); | |
399 | 411 | |
400 | 412 | try |
401 | 413 | { |
402 | - String identifier = this.enumerator.getIdentifier(mod); | |
414 | + String identifier = mod.getIdentifier(); | |
403 | 415 | if (identifier == null || this.environment.getEnabledModsList().isEnabled(this.environment.getProfile(), identifier)) |
404 | 416 | { |
405 | 417 | if (!this.enumerator.checkDependencies(container)) |
... | ... | @@ -408,7 +420,14 @@ public class LiteLoaderMods |
408 | 420 | continue; |
409 | 421 | } |
410 | 422 | |
411 | - this.loadMod(identifier, mod, container); | |
423 | + if (mod instanceof Mod) | |
424 | + { | |
425 | + this.loadMod((Mod)mod); | |
426 | + } | |
427 | + else | |
428 | + { | |
429 | + this.loadMod(identifier, mod.getModClass(), container); | |
430 | + } | |
412 | 431 | } |
413 | 432 | else |
414 | 433 | { |
... | ... | @@ -417,33 +436,44 @@ public class LiteLoaderMods |
417 | 436 | } |
418 | 437 | catch (Throwable th) |
419 | 438 | { |
420 | - this.onModLoadFailed(container, mod.getName(), "an error occurred", th); | |
439 | + this.onModLoadFailed(container, mod.getModClassName(), "an error occurred", th); | |
421 | 440 | } |
422 | 441 | } |
423 | 442 | } |
424 | 443 | |
425 | 444 | /** |
426 | 445 | * @param identifier |
427 | - * @param mod | |
446 | + * @param modClass | |
428 | 447 | * @param container |
429 | 448 | * @throws InstantiationException |
430 | 449 | * @throws IllegalAccessException |
431 | 450 | */ |
432 | - void loadMod(String identifier, Class<? extends LiteMod> mod, LoadableMod<?> container) throws InstantiationException, IllegalAccessException | |
451 | + void loadMod(String identifier, Class<? extends LiteMod> modClass, LoadableMod<?> container) throws InstantiationException, IllegalAccessException | |
433 | 452 | { |
434 | - LiteLoaderLogger.info("Loading mod from %s", mod.getName()); | |
453 | + Mod mod = new Mod(container, modClass, identifier); | |
454 | + this.loadMod(mod); | |
455 | + } | |
456 | + | |
457 | + /** | |
458 | + * @param mod | |
459 | + * @throws InstantiationException | |
460 | + * @throws IllegalAccessException | |
461 | + */ | |
462 | + void loadMod(Mod mod) throws InstantiationException, IllegalAccessException | |
463 | + { | |
464 | + LiteLoaderLogger.info("Loading mod from %s", mod.getModClassName()); | |
435 | 465 | |
436 | 466 | LiteMod newMod = mod.newInstance(); |
437 | 467 | |
438 | - this.onModLoaded(newMod); | |
468 | + this.onModLoaded(mod); | |
439 | 469 | |
440 | - String modName = newMod.getName(); | |
441 | - if (modName == null && identifier != null) modName = identifier; | |
470 | + String modName = mod.getDisplayName(); | |
442 | 471 | LiteLoaderLogger.info("Successfully added mod %s version %s", modName, newMod.getVersion()); |
443 | 472 | |
444 | 473 | // Register the mod as a resource pack if the container exists |
445 | - if (container != null) | |
474 | + if (mod.hasContainer()) | |
446 | 475 | { |
476 | + LoadableMod<?> container = mod.getContainer(); | |
447 | 477 | LiteLoaderLogger.info("Adding \"%s\" to active resource pack set", container.getLocation()); |
448 | 478 | if (modName != null) |
449 | 479 | { |
... | ... | @@ -460,11 +490,11 @@ public class LiteLoaderMods |
460 | 490 | /** |
461 | 491 | * @param mod |
462 | 492 | */ |
463 | - void onModLoaded(LiteMod mod) | |
493 | + void onModLoaded(Mod mod) | |
464 | 494 | { |
465 | 495 | for (ModLoadObserver observer : this.observers) |
466 | 496 | { |
467 | - observer.onModLoaded(mod); | |
497 | + observer.onModLoaded(mod.getMod()); | |
468 | 498 | } |
469 | 499 | |
470 | 500 | this.allMods.add(mod); |
... | ... | @@ -485,7 +515,7 @@ public class LiteLoaderMods |
485 | 515 | |
486 | 516 | if (container != LoadableMod.NONE && !this.disabledMods.contains(container)) |
487 | 517 | { |
488 | - this.disabledMods.add(container); | |
518 | + this.disabledMods.add(new NonMod(container, false)); | |
489 | 519 | } |
490 | 520 | |
491 | 521 | for (ModLoadObserver observer : this.observers) |
... | ... | @@ -504,7 +534,7 @@ public class LiteLoaderMods |
504 | 534 | |
505 | 535 | while (this.initMods.size() > 0) |
506 | 536 | { |
507 | - LiteMod mod = this.initMods.removeFirst(); | |
537 | + Mod mod = this.initMods.removeFirst(); | |
508 | 538 | |
509 | 539 | try |
510 | 540 | { |
... | ... | @@ -513,8 +543,8 @@ public class LiteLoaderMods |
513 | 543 | } |
514 | 544 | catch (Throwable th) |
515 | 545 | { |
516 | - LiteLoaderLogger.warning(th, "Error initialising mod '%s'", mod.getName()); | |
517 | - this.allMods.remove(mod); | |
546 | + this.registerModStartupError(mod, th); | |
547 | + LiteLoaderLogger.warning(th, "Error initialising mod '%s'", mod.getDisplayName()); | |
518 | 548 | } |
519 | 549 | } |
520 | 550 | |
... | ... | @@ -524,70 +554,73 @@ public class LiteLoaderMods |
524 | 554 | /** |
525 | 555 | * @param mod |
526 | 556 | */ |
527 | - private void initMod(LiteMod mod) | |
557 | + private void initMod(Mod mod) | |
528 | 558 | { |
529 | - LiteLoaderLogger.info("Initialising mod %s version %s", mod.getName(), mod.getVersion()); | |
530 | - LoadingProgress.incLiteLoaderProgress("Initialising mod %s version %s...", mod.getName(), mod.getVersion()); | |
559 | + LiteMod instance = mod.getMod(); | |
531 | 560 | |
532 | - this.onPreInitMod(mod); | |
561 | + LiteLoaderLogger.info("Initialising mod %s version %s", instance.getName(), instance.getVersion()); | |
562 | + LoadingProgress.incLiteLoaderProgress("Initialising mod %s version %s...", instance.getName(), instance.getVersion()); | |
563 | + | |
564 | + this.onPreInitMod(instance); | |
533 | 565 | |
534 | 566 | // initialise the mod |
535 | - mod.init(LiteLoader.getCommonConfigFolder()); | |
567 | + instance.init(LiteLoader.getCommonConfigFolder()); | |
568 | + | |
569 | + this.onPostInitMod(instance); | |
536 | 570 | |
537 | - this.onPostInitMod(mod); | |
571 | + this.loadedMods.add(mod); | |
572 | + this.loadedModsList += String.format("\n - %s version %s", mod.getDisplayName(), mod.getVersion()); | |
538 | 573 | } |
539 | 574 | |
540 | 575 | /** |
541 | - * @param mod | |
576 | + * @param instance | |
542 | 577 | */ |
543 | - private void onPreInitMod(LiteMod mod) | |
578 | + private void onPreInitMod(LiteMod instance) | |
544 | 579 | { |
545 | 580 | for (ModLoadObserver observer : this.observers) |
546 | 581 | { |
547 | - observer.onPreInitMod(mod); | |
582 | + observer.onPreInitMod(instance); | |
548 | 583 | } |
549 | 584 | |
550 | 585 | // register mod config panel if configurable |
551 | - this.configManager.registerMod(mod); | |
586 | + this.configManager.registerMod(instance); | |
552 | 587 | |
553 | 588 | try |
554 | 589 | { |
555 | - this.handleModVersionUpgrade(mod); | |
590 | + this.handleModVersionUpgrade(instance); | |
556 | 591 | } |
557 | 592 | catch (Throwable th) |
558 | 593 | { |
559 | - LiteLoaderLogger.warning("Error performing settings upgrade for %s. Settings may not be properly migrated", mod.getName()); | |
594 | + LiteLoaderLogger.warning("Error performing settings upgrade for %s. Settings may not be properly migrated", instance.getName()); | |
560 | 595 | } |
561 | 596 | |
562 | 597 | // Init mod config if there is any |
563 | - this.configManager.initConfig(mod); | |
598 | + this.configManager.initConfig(instance); | |
564 | 599 | } |
565 | 600 | |
566 | 601 | /** |
567 | - * @param mod | |
602 | + * @param instance | |
568 | 603 | */ |
569 | - private void onPostInitMod(LiteMod mod) | |
604 | + private void onPostInitMod(LiteMod instance) | |
570 | 605 | { |
606 | + System.err.println("on post init mod " + instance.getName()); | |
571 | 607 | for (ModLoadObserver observer : this.observers) |
572 | 608 | { |
573 | - observer.onPostInitMod(mod); | |
609 | + observer.onPostInitMod(instance); | |
574 | 610 | } |
575 | 611 | |
576 | 612 | // add the mod to all relevant listener queues |
577 | - LiteLoader.getInterfaceManager().offer(mod); | |
613 | + LiteLoader.getInterfaceManager().offer(instance); | |
578 | 614 | |
579 | - this.loader.onPostInitMod(mod); | |
580 | - | |
581 | - this.loadedMods.add(mod); | |
582 | - this.loadedModsList += String.format("\n - %s version %s", mod.getName(), mod.getVersion()); | |
615 | + this.loader.onPostInitMod(instance); | |
583 | 616 | } |
584 | 617 | |
585 | 618 | /** |
586 | - * @param mod | |
619 | + * @param instance | |
587 | 620 | */ |
588 | - private void handleModVersionUpgrade(LiteMod mod) | |
621 | + private void handleModVersionUpgrade(LiteMod instance) | |
589 | 622 | { |
590 | - String modKey = this.getModNameForConfig(mod.getClass(), mod.getName()); | |
623 | + String modKey = this.getModNameForConfig(instance.getClass(), instance.getName()); | |
591 | 624 | |
592 | 625 | int currentRevision = LiteLoaderVersion.CURRENT.getLoaderRevision(); |
593 | 626 | int lastKnownRevision = this.properties.getLastKnownModRevision(modKey); |
... | ... | @@ -598,25 +631,25 @@ public class LiteLoaderMods |
598 | 631 | File newConfigPath = LiteLoader.getConfigFolder(); |
599 | 632 | File oldConfigPath = this.environment.inflectVersionedConfigPath(lastModVersion); |
600 | 633 | |
601 | - LiteLoaderLogger.info("Performing config upgrade for mod %s. Upgrading %s to %s...", mod.getName(), lastModVersion, LiteLoaderVersion.CURRENT); | |
634 | + LiteLoaderLogger.info("Performing config upgrade for mod %s. Upgrading %s to %s...", instance.getName(), lastModVersion, LiteLoaderVersion.CURRENT); | |
602 | 635 | |
603 | 636 | for (ModLoadObserver observer : this.observers) |
604 | 637 | { |
605 | - observer.onMigrateModConfig(mod, newConfigPath, oldConfigPath); | |
638 | + observer.onMigrateModConfig(instance, newConfigPath, oldConfigPath); | |
606 | 639 | } |
607 | 640 | |
608 | 641 | // Migrate versioned config if any is present |
609 | - this.configManager.migrateModConfig(mod, newConfigPath, oldConfigPath); | |
642 | + this.configManager.migrateModConfig(instance, newConfigPath, oldConfigPath); | |
610 | 643 | |
611 | 644 | // Let the mod upgrade |
612 | - mod.upgradeSettings(LiteLoaderVersion.CURRENT.getMinecraftVersion(), newConfigPath, oldConfigPath); | |
645 | + instance.upgradeSettings(LiteLoaderVersion.CURRENT.getMinecraftVersion(), newConfigPath, oldConfigPath); | |
613 | 646 | |
614 | 647 | this.properties.storeLastKnownModRevision(modKey); |
615 | - LiteLoaderLogger.info("Config upgrade succeeded for mod %s", mod.getName()); | |
648 | + LiteLoaderLogger.info("Config upgrade succeeded for mod %s", instance.getName()); | |
616 | 649 | } |
617 | - else if (currentRevision < lastKnownRevision && ConfigManager.getConfigStrategy(mod) == ConfigStrategy.Unversioned) | |
650 | + else if (currentRevision < lastKnownRevision && ConfigManager.getConfigStrategy(instance) == ConfigStrategy.Unversioned) | |
618 | 651 | { |
619 | - LiteLoaderLogger.warning("Mod %s has config from unknown loader revision %d. This may cause unexpected behaviour.", mod.getName(), lastKnownRevision); | |
652 | + LiteLoaderLogger.warning("Mod %s has config from unknown loader revision %d. This may cause unexpected behaviour.", instance.getName(), lastKnownRevision); | |
620 | 653 | } |
621 | 654 | } |
622 | 655 | |
... | ... | @@ -637,30 +670,49 @@ public class LiteLoaderMods |
637 | 670 | return String.format("version.%s", modName.toLowerCase().replaceAll("[^a-z0-9_\\-\\.]", "")); |
638 | 671 | } |
639 | 672 | |
673 | + /** | |
674 | + * @param instance | |
675 | + * @param th | |
676 | + */ | |
677 | + public void onLateInitFailed(LiteMod instance, Throwable th) | |
678 | + { | |
679 | + ModInfo<?> mod = this.getModInfo(instance); | |
680 | + if (mod != null) | |
681 | + { | |
682 | + this.registerModStartupError(mod, th); | |
683 | + this.registerModStartupError(mod, th); | |
684 | + } | |
685 | + } | |
686 | + | |
687 | + private void registerModStartupError(ModInfo<?> mod, Throwable th) | |
688 | + { | |
689 | + this.startupErrorCount++; | |
690 | + mod.registerStartupError(th); | |
691 | + } | |
692 | + | |
640 | 693 | void updateSharedModList() |
641 | 694 | { |
642 | 695 | Map<String, Map<String, String>> modList = this.enumerator.getSharedModList(); |
643 | 696 | if (modList == null) return; |
644 | 697 | |
645 | - for (LiteMod mod : this.allMods) | |
698 | + for (Mod mod : this.allMods) | |
646 | 699 | { |
647 | - String modKey = String.format("%s:%s", LiteLoaderMods.MOD_SYSTEM, this.loader.getModIdentifier(mod)); | |
700 | + String modKey = String.format("%s:%s", LiteLoaderMods.MOD_SYSTEM, mod.getIdentifier()); | |
648 | 701 | modList.put(modKey, this.packModInfoToMap(mod)); |
649 | 702 | } |
650 | 703 | } |
651 | 704 | |
652 | - private Map<String, String> packModInfoToMap(LiteMod mod) | |
705 | + private Map<String, String> packModInfoToMap(Mod mod) | |
653 | 706 | { |
654 | 707 | Map<String, String> modInfo = new HashMap<String, String>(); |
655 | - LoadableMod<?> container = this.loader.getModContainer(mod); | |
656 | 708 | |
657 | 709 | modInfo.put("modsystem", LiteLoaderMods.MOD_SYSTEM); |
658 | - modInfo.put("id", this.loader.getModIdentifier(mod)); | |
710 | + modInfo.put("id", mod.getIdentifier()); | |
659 | 711 | modInfo.put("version", mod.getVersion()); |
660 | - modInfo.put("name", mod.getName()); | |
661 | - modInfo.put("url", container.getMetaValue("url", "")); | |
662 | - modInfo.put("authors", container.getAuthor()); | |
663 | - modInfo.put("description", container.getDescription(LiteLoaderEnumerator.getModClassName(mod))); | |
712 | + modInfo.put("name", mod.getDisplayName()); | |
713 | + modInfo.put("url", mod.getURL()); | |
714 | + modInfo.put("authors", mod.getAuthor()); | |
715 | + modInfo.put("description", mod.getDescription()); | |
664 | 716 | |
665 | 717 | return modInfo; |
666 | 718 | } | ... | ... |
java/common/com/mumfrey/liteloader/core/LiteLoaderVersion.java
... | ... | @@ -9,7 +9,7 @@ import com.mumfrey.liteloader.update.UpdateSite; |
9 | 9 | * LiteLoader version table |
10 | 10 | * |
11 | 11 | * @author Adam Mummery-Smith |
12 | - * @version 1.7.10_02 | |
12 | + * @version 1.7.10_03 | |
13 | 13 | */ |
14 | 14 | public enum LiteLoaderVersion |
15 | 15 | { |
... | ... | @@ -37,7 +37,8 @@ public enum LiteLoaderVersion |
37 | 37 | MC_1_7_2_R6(26, 0, "1.7.2", "1.7.2_06", "1.7.2_06"), |
38 | 38 | MC_1_7_10_R0(27, 1404330030, "1.7.10", "1.7.10", "1.7.10"), |
39 | 39 | MC_1_7_10_R1(28, 1404673785, "1.7.10", "1.7.10_01", "1.7.10"), |
40 | - MC_1_7_10_R2(29, 1405369406, "1.7.10", "1.7.10_02", "1.7.10"); | |
40 | + MC_1_7_10_R2(29, 1405369406, "1.7.10", "1.7.10_02", "1.7.10"), | |
41 | + MC_1_7_10_R3(30, 0, "1.7.10", "1.7.10_03", "1.7.10"); | |
41 | 42 | |
42 | 43 | /** |
43 | 44 | * Current loader version | ... | ... |
java/common/com/mumfrey/liteloader/core/Mod.java
0 → 100644
1 | +package com.mumfrey.liteloader.core; | |
2 | + | |
3 | +import com.mumfrey.liteloader.LiteMod; | |
4 | +import com.mumfrey.liteloader.interfaces.LoadableMod; | |
5 | + | |
6 | +/** | |
7 | + * ModInfo for an active mod instance | |
8 | + * | |
9 | + * @author Adam Mummery-Smith | |
10 | + */ | |
11 | +class Mod extends ModInfo<LoadableMod<?>> | |
12 | +{ | |
13 | + /** | |
14 | + * Mod class | |
15 | + */ | |
16 | + private final Class<? extends LiteMod> modClass; | |
17 | + | |
18 | + /** | |
19 | + * Mod's key identifier, usually the class simplename | |
20 | + */ | |
21 | + private final String key; | |
22 | + | |
23 | + /** | |
24 | + * Mod's identifier (from metadata) | |
25 | + */ | |
26 | + private final String identifier; | |
27 | + | |
28 | + /** | |
29 | + * Mod instance | |
30 | + */ | |
31 | + private LiteMod instance; | |
32 | + | |
33 | + /** | |
34 | + * Mod display name, initially read from metadata then replaced with real name once instanced | |
35 | + */ | |
36 | + private String name; | |
37 | + | |
38 | + /** | |
39 | + * Mod display name, initially read from version then replaced with real version once instanced | |
40 | + */ | |
41 | + private String version; | |
42 | + | |
43 | + /** | |
44 | + * @param container | |
45 | + * @param modClass | |
46 | + */ | |
47 | + public Mod(LoadableMod<?> container, Class<? extends LiteMod> modClass) | |
48 | + { | |
49 | + this(container, modClass, container != null ? container.getIdentifier() : LiteLoaderEnumerator.getModClassName(modClass)); | |
50 | + } | |
51 | + | |
52 | + /** | |
53 | + * @param container | |
54 | + * @param modClass | |
55 | + * @param identifier | |
56 | + */ | |
57 | + public Mod(LoadableMod<?> container, Class<? extends LiteMod> modClass, String identifier) | |
58 | + { | |
59 | + super(container != null ? container : LoadableMod.NONE, true); | |
60 | + | |
61 | + this.modClass = modClass; | |
62 | + this.key = modClass.getSimpleName(); | |
63 | + this.identifier = identifier.toLowerCase(); | |
64 | + this.name = this.container.getDisplayName(); | |
65 | + this.version = this.container.getVersion(); | |
66 | + } | |
67 | + | |
68 | + /** | |
69 | + * Called by the mod manager to instance the mod | |
70 | + * | |
71 | + * @return | |
72 | + * @throws InstantiationException | |
73 | + * @throws IllegalAccessException | |
74 | + */ | |
75 | + LiteMod newInstance() throws InstantiationException, IllegalAccessException | |
76 | + { | |
77 | + if (this.instance != null) | |
78 | + { | |
79 | + throw new InstantiationException("Attempted to create an instance of " + this.key + " but the instance was already created"); | |
80 | + } | |
81 | + | |
82 | + this.instance = this.modClass.newInstance(); | |
83 | + | |
84 | + String name = this.instance.getName(); | |
85 | + if (name != null) this.name = name; | |
86 | + | |
87 | + String version = this.instance.getVersion(); | |
88 | + if (version != null) this.version = version; | |
89 | + | |
90 | + return this.instance; | |
91 | + } | |
92 | + | |
93 | + /* (non-Javadoc) | |
94 | + * @see com.mumfrey.liteloader.core.ModInfo#isToggleable() | |
95 | + */ | |
96 | + @Override | |
97 | + public boolean isToggleable() | |
98 | + { | |
99 | + return true; | |
100 | + } | |
101 | + | |
102 | + /* (non-Javadoc) | |
103 | + * @see com.mumfrey.liteloader.core.ModInfo#getMod() | |
104 | + */ | |
105 | + @Override | |
106 | + public LiteMod getMod() | |
107 | + { | |
108 | + return this.instance; | |
109 | + } | |
110 | + | |
111 | + /* (non-Javadoc) | |
112 | + * @see com.mumfrey.liteloader.core.ModInfo#getModClass() | |
113 | + */ | |
114 | + @Override | |
115 | + public Class<? extends LiteMod> getModClass() | |
116 | + { | |
117 | + return this.modClass; | |
118 | + } | |
119 | + | |
120 | + /* (non-Javadoc) | |
121 | + * @see com.mumfrey.liteloader.core.ModInfo#getDisplayName() | |
122 | + */ | |
123 | + @Override | |
124 | + public String getDisplayName() | |
125 | + { | |
126 | + return this.name; | |
127 | + } | |
128 | + | |
129 | + /* (non-Javadoc) | |
130 | + * @see com.mumfrey.liteloader.core.ModInfo#getVersion() | |
131 | + */ | |
132 | + @Override | |
133 | + public String getVersion() | |
134 | + { | |
135 | + return this.version; | |
136 | + } | |
137 | + | |
138 | + /* (non-Javadoc) | |
139 | + * @see com.mumfrey.liteloader.core.ModInfo#getModClassName() | |
140 | + */ | |
141 | + @Override | |
142 | + public String getModClassName() | |
143 | + { | |
144 | + return this.modClass.getName(); | |
145 | + } | |
146 | + | |
147 | + /* (non-Javadoc) | |
148 | + * @see com.mumfrey.liteloader.core.ModInfo#getModClassSimpleName() | |
149 | + */ | |
150 | + @Override | |
151 | + public String getModClassSimpleName() | |
152 | + { | |
153 | + return this.key; | |
154 | + } | |
155 | + | |
156 | + /* (non-Javadoc) | |
157 | + * @see com.mumfrey.liteloader.core.ModInfo#getIdentifier() | |
158 | + */ | |
159 | + @Override | |
160 | + public String getIdentifier() | |
161 | + { | |
162 | + return this.identifier; | |
163 | + } | |
164 | + | |
165 | + /** | |
166 | + * Get whether any of the valid identifiers match the supplied name | |
167 | + * | |
168 | + * @param name | |
169 | + * @return | |
170 | + */ | |
171 | + public boolean matchesName(String name) | |
172 | + { | |
173 | + return (name.equalsIgnoreCase(this.instance.getName()) || name.equalsIgnoreCase(this.identifier) || name.equalsIgnoreCase(this.key)); | |
174 | + } | |
175 | + | |
176 | + /** | |
177 | + * Get whether ths mod identifier matches the supplied identifier | |
178 | + * | |
179 | + * @param identifier | |
180 | + * @return | |
181 | + */ | |
182 | + public boolean matchesIdentifier(String identifier) | |
183 | + { | |
184 | + return identifier.equalsIgnoreCase(this.identifier); | |
185 | + } | |
186 | + | |
187 | + /* (non-Javadoc) | |
188 | + * @see java.lang.Object#equals(java.lang.Object) | |
189 | + */ | |
190 | + @Override | |
191 | + public boolean equals(Object other) | |
192 | + { | |
193 | + if (other == null) return false; | |
194 | + if (!(other instanceof Mod)) return false; | |
195 | + return ((Mod)other).key.equals(this.key); | |
196 | + } | |
197 | + | |
198 | + /* (non-Javadoc) | |
199 | + * @see java.lang.Object#hashCode() | |
200 | + */ | |
201 | + @Override | |
202 | + public int hashCode() | |
203 | + { | |
204 | + return this.key.hashCode(); | |
205 | + } | |
206 | +} | ... | ... |
java/common/com/mumfrey/liteloader/core/ModInfo.java
0 → 100644
1 | +package com.mumfrey.liteloader.core; | |
2 | + | |
3 | +import java.util.ArrayList; | |
4 | +import java.util.Collections; | |
5 | +import java.util.List; | |
6 | +import java.util.Set; | |
7 | + | |
8 | +import com.google.common.collect.ImmutableSet; | |
9 | +import com.mumfrey.liteloader.LiteMod; | |
10 | +import com.mumfrey.liteloader.interfaces.Loadable; | |
11 | +import com.mumfrey.liteloader.interfaces.LoadableMod; | |
12 | +import com.mumfrey.liteloader.interfaces.TweakContainer; | |
13 | + | |
14 | +/** | |
15 | + * ModInfo is used to keep runtime information about a mod (or other injectable) together with relevant | |
16 | + * environmental information (such as startup errors) and its container. | |
17 | + * | |
18 | + * @author Adam Mummery-Smith | |
19 | + * | |
20 | + * @param <TContainer> type of container | |
21 | + */ | |
22 | +public abstract class ModInfo<TContainer extends Loadable<?>> | |
23 | +{ | |
24 | + /** | |
25 | + * List of built-in APIs, used to filter for 3rd-party APIs | |
26 | + */ | |
27 | + protected static final Set<String> BUILT_IN_APIS = ImmutableSet.of("liteloader"); | |
28 | + | |
29 | + /** | |
30 | + * Container instance | |
31 | + */ | |
32 | + protected final TContainer container; | |
33 | + | |
34 | + /** | |
35 | + * True if this mod is active/injected or not active/errored | |
36 | + */ | |
37 | + protected final boolean active; | |
38 | + | |
39 | + /** | |
40 | + * Startup errors encountered whilst loading this mod | |
41 | + */ | |
42 | + private final List<Throwable> startupErrors = new ArrayList<Throwable>(); | |
43 | + | |
44 | + /** | |
45 | + * @param container | |
46 | + * @param active | |
47 | + */ | |
48 | + protected ModInfo(TContainer container, boolean active) | |
49 | + { | |
50 | + this.container = container; | |
51 | + this.active = active; | |
52 | + } | |
53 | + | |
54 | + /** | |
55 | + * Get whether this mod is currently active | |
56 | + */ | |
57 | + public final boolean isActive() | |
58 | + { | |
59 | + return this.active; | |
60 | + } | |
61 | + | |
62 | + /** | |
63 | + * Get whether this mod can be toggled | |
64 | + */ | |
65 | + public boolean isToggleable() | |
66 | + { | |
67 | + return this.container.isToggleable(); | |
68 | + } | |
69 | + | |
70 | + /** | |
71 | + * Get whether this mod has a container | |
72 | + */ | |
73 | + public final boolean hasContainer() | |
74 | + { | |
75 | + return this.container != LoadableMod.NONE; | |
76 | + } | |
77 | + | |
78 | + /** | |
79 | + * Get the container for this mod | |
80 | + */ | |
81 | + public final TContainer getContainer() | |
82 | + { | |
83 | + return this.container; | |
84 | + } | |
85 | + | |
86 | + /** | |
87 | + * Callback to allow the mod manager to register a startup error | |
88 | + */ | |
89 | + void registerStartupError(Throwable th) | |
90 | + { | |
91 | + this.startupErrors.add(th); | |
92 | + } | |
93 | + | |
94 | + /** | |
95 | + * Get startup errors for this instance | |
96 | + */ | |
97 | + public List<Throwable> getStartupErrors() | |
98 | + { | |
99 | + return Collections.unmodifiableList(this.startupErrors); | |
100 | + } | |
101 | + | |
102 | + /** | |
103 | + * Get the display name for this mod | |
104 | + */ | |
105 | + public String getDisplayName() | |
106 | + { | |
107 | + return this.container.getDisplayName(); | |
108 | + } | |
109 | + | |
110 | + /** | |
111 | + * Get the mod version | |
112 | + */ | |
113 | + public String getVersion() | |
114 | + { | |
115 | + return this.container.getVersion(); | |
116 | + } | |
117 | + | |
118 | + /** | |
119 | + * Get the nod identifier | |
120 | + */ | |
121 | + public String getIdentifier() | |
122 | + { | |
123 | + return this.container.getIdentifier(); | |
124 | + } | |
125 | + | |
126 | + /** | |
127 | + * Get the mod URL | |
128 | + */ | |
129 | + public String getURL() | |
130 | + { | |
131 | + return this.container instanceof LoadableMod<?> ? ((LoadableMod<?>)this.container).getMetaValue("url", "") : null; | |
132 | + } | |
133 | + | |
134 | + /** | |
135 | + * Get the mod author(s) | |
136 | + */ | |
137 | + public String getAuthor() | |
138 | + { | |
139 | + return this.container.getAuthor(); | |
140 | + } | |
141 | + | |
142 | + /** | |
143 | + * Get the mod description | |
144 | + */ | |
145 | + public String getDescription() | |
146 | + { | |
147 | + return this.container.getDescription(null); | |
148 | + } | |
149 | + | |
150 | + /** | |
151 | + * If this container has a tweak | |
152 | + */ | |
153 | + public boolean hasTweakClass() | |
154 | + { | |
155 | + return (this.container instanceof TweakContainer && ((TweakContainer<?>)this.container).hasTweakClass()); | |
156 | + } | |
157 | + | |
158 | + /** | |
159 | + * If this has transformers (NOT robots in disguise, the other kind) | |
160 | + */ | |
161 | + public boolean hasClassTransformers() | |
162 | + { | |
163 | + return (this.container instanceof TweakContainer && ((TweakContainer<?>)this.container).hasClassTransformers()); | |
164 | + } | |
165 | + | |
166 | + /** | |
167 | + * Get whether this mod uses external (3rd-party) API | |
168 | + */ | |
169 | + public boolean usesAPI() | |
170 | + { | |
171 | + if (this.container instanceof LoadableMod<?>) | |
172 | + { | |
173 | + for (String requiredAPI : ((LoadableMod<?>)this.container).getRequiredAPIs()) | |
174 | + { | |
175 | + if (!ModInfo.BUILT_IN_APIS.contains(requiredAPI)) | |
176 | + return true; | |
177 | + } | |
178 | + } | |
179 | + | |
180 | + return false; | |
181 | + } | |
182 | + | |
183 | + /** | |
184 | + * Get the mod instance | |
185 | + */ | |
186 | + public abstract LiteMod getMod(); | |
187 | + | |
188 | + /** | |
189 | + * Get the mod class | |
190 | + */ | |
191 | + public abstract Class<? extends LiteMod> getModClass(); | |
192 | + | |
193 | + /** | |
194 | + * Get the mod class full name | |
195 | + */ | |
196 | + public abstract String getModClassName(); | |
197 | + | |
198 | + /** | |
199 | + * Get the mod class simple name | |
200 | + */ | |
201 | + public abstract String getModClassSimpleName(); | |
202 | +} | ... | ... |
java/common/com/mumfrey/liteloader/core/NonMod.java
0 → 100644
1 | +package com.mumfrey.liteloader.core; | |
2 | + | |
3 | +import com.mumfrey.liteloader.LiteMod; | |
4 | +import com.mumfrey.liteloader.interfaces.Loadable; | |
5 | + | |
6 | +/** | |
7 | + * ModInfo for unloaded containers and injected tweaks | |
8 | + * | |
9 | + * @author Adam Mummery-Smith | |
10 | + */ | |
11 | +public class NonMod extends ModInfo<Loadable<?>> | |
12 | +{ | |
13 | + /** | |
14 | + * @param container | |
15 | + * @param active | |
16 | + */ | |
17 | + public NonMod(Loadable<?> container, boolean active) | |
18 | + { | |
19 | + super(container, active); | |
20 | + } | |
21 | + | |
22 | + /* (non-Javadoc) | |
23 | + * @see com.mumfrey.liteloader.core.ModInfo#getMod() | |
24 | + */ | |
25 | + @Override | |
26 | + public LiteMod getMod() | |
27 | + { | |
28 | + return null; | |
29 | + } | |
30 | + | |
31 | + /* (non-Javadoc) | |
32 | + * @see com.mumfrey.liteloader.core.ModInfo#getModClass() | |
33 | + */ | |
34 | + @Override | |
35 | + public Class<? extends LiteMod> getModClass() | |
36 | + { | |
37 | + return null; | |
38 | + } | |
39 | + | |
40 | + /* (non-Javadoc) | |
41 | + * @see com.mumfrey.liteloader.core.ModInfo#getModClassName() | |
42 | + */ | |
43 | + @Override | |
44 | + public String getModClassName() | |
45 | + { | |
46 | + return null; | |
47 | + } | |
48 | + | |
49 | + /* (non-Javadoc) | |
50 | + * @see com.mumfrey.liteloader.core.ModInfo#getModClassSimpleName() | |
51 | + */ | |
52 | + @Override | |
53 | + public String getModClassSimpleName() | |
54 | + { | |
55 | + return null; | |
56 | + } | |
57 | +} | ... | ... |
java/common/com/mumfrey/liteloader/interfaces/LoaderEnumerator.java
1 | 1 | package com.mumfrey.liteloader.interfaces; |
2 | 2 | |
3 | -import java.io.File; | |
4 | 3 | import java.util.Collection; |
5 | 4 | import java.util.List; |
6 | 5 | import java.util.Map; |
7 | 6 | |
8 | 7 | import com.mumfrey.liteloader.LiteMod; |
8 | +import com.mumfrey.liteloader.core.ModInfo; | |
9 | 9 | |
10 | 10 | /** |
11 | 11 | * Interface for the enumerator |
... | ... | @@ -69,7 +69,7 @@ public interface LoaderEnumerator extends ModularEnumerator |
69 | 69 | * |
70 | 70 | * @return |
71 | 71 | */ |
72 | - public abstract Collection<LoadableMod<?>> getDisabledContainers(); | |
72 | + public abstract Collection<? extends ModInfo<Loadable<?>>> getDisabledContainers(); | |
73 | 73 | |
74 | 74 | /** |
75 | 75 | * @param modClass |
... | ... | @@ -87,12 +87,12 @@ public interface LoaderEnumerator extends ModularEnumerator |
87 | 87 | /** |
88 | 88 | * @return |
89 | 89 | */ |
90 | - public abstract Collection<Class<? extends LiteMod>> getModsToLoad(); | |
90 | + public abstract Collection<? extends ModInfo<LoadableMod<?>>> getModsToLoad(); | |
91 | 91 | |
92 | 92 | /** |
93 | 93 | * @return |
94 | 94 | */ |
95 | - public abstract List<Loadable<File>> getInjectedTweaks(); | |
95 | + public abstract List<? extends ModInfo<Loadable<?>>> getInjectedTweaks(); | |
96 | 96 | |
97 | 97 | /** |
98 | 98 | * @return | ... | ... |
java/common/com/mumfrey/liteloader/interfaces/ModularEnumerator.java
... | ... | @@ -2,8 +2,8 @@ package com.mumfrey.liteloader.interfaces; |
2 | 2 | |
3 | 3 | import java.io.File; |
4 | 4 | |
5 | -import com.mumfrey.liteloader.LiteMod; | |
6 | 5 | import com.mumfrey.liteloader.api.EnumeratorModule; |
6 | +import com.mumfrey.liteloader.core.ModInfo; | |
7 | 7 | |
8 | 8 | /** |
9 | 9 | * Interface for the mod enumerator |
... | ... | @@ -39,7 +39,6 @@ public interface ModularEnumerator |
39 | 39 | |
40 | 40 | /** |
41 | 41 | * @param mod |
42 | - * @param container | |
43 | 42 | */ |
44 | - public abstract void registerMod(Class<? extends LiteMod> mod, LoadableMod<?> container); | |
43 | + public abstract void registerMod(ModInfo<LoadableMod<?>> mod); | |
45 | 44 | } |
46 | 45 | \ No newline at end of file | ... | ... |
java/common/com/mumfrey/liteloader/interfaces/PanelManager.java
... | ... | @@ -49,4 +49,9 @@ public interface PanelManager<TParentScreen> extends TickObserver, PostRenderObs |
49 | 49 | * @param parentScreen |
50 | 50 | */ |
51 | 51 | public abstract void displayLiteLoaderPanel(TParentScreen parentScreen); |
52 | + | |
53 | + /** | |
54 | + * @return | |
55 | + */ | |
56 | + public abstract int getStartupErrorCount(); | |
52 | 57 | } | ... | ... |
java/common/com/mumfrey/liteloader/util/render/IconClickable.java
0 → 100644
1 | +package com.mumfrey.liteloader.util.render; | |
2 | + | |
3 | +/** | |
4 | + * Icon with an onClicked handler | |
5 | + * | |
6 | + * @author Adam Mummery-Smith | |
7 | + */ | |
8 | +public interface IconClickable extends IconTextured | |
9 | +{ | |
10 | + /** | |
11 | + * @param source Source of the event, usually the outermost gui screen | |
12 | + * @param container Container of this icon, the actual component hosting the icon | |
13 | + */ | |
14 | + public void onClicked(Object source, Object container); | |
15 | +} | ... | ... |
java/common/com/mumfrey/liteloader/util/render/IconTextured.java
0 → 100644
1 | +package com.mumfrey.liteloader.util.render; | |
2 | + | |
3 | +import net.minecraft.util.IIcon; | |
4 | +import net.minecraft.util.ResourceLocation; | |
5 | + | |
6 | +/** | |
7 | + * Icon with a texture and tooltip allocated to it | |
8 | + * | |
9 | + * @author Adam Mummery-Smith | |
10 | + */ | |
11 | +public interface IconTextured extends IIcon | |
12 | +{ | |
13 | + /** | |
14 | + * Get tooltip text, return null for no tooltip | |
15 | + */ | |
16 | + public abstract String getDisplayText(); | |
17 | + | |
18 | + /** | |
19 | + * Get the texture resource for this icon | |
20 | + */ | |
21 | + public abstract ResourceLocation getTextureResource(); | |
22 | + | |
23 | + /** | |
24 | + * Get the U coordinate on the texture for this icon | |
25 | + */ | |
26 | + public abstract int getUPos(); | |
27 | + | |
28 | + /** | |
29 | + * Get the V coordinate on the texture for this icon | |
30 | + */ | |
31 | + public abstract int getVPos(); | |
32 | +} | ... | ... |
resources/assets/liteloader/lang/en_US.lang
... | ... | @@ -37,6 +37,7 @@ gui.description.missingapis=Missing APIs: %s |
37 | 37 | gui.mod.providestweak=Provides Tweak |
38 | 38 | gui.mod.providestransformer=Provides Transformer |
39 | 39 | gui.mod.usingapi=Uses additional API |
40 | +gui.mod.startuperror=%d startup error(s) | |
40 | 41 | |
41 | 42 | gui.settings.title=%s Settings |
42 | 43 | gui.saveandclose=Save & Close |
... | ... | @@ -64,4 +65,8 @@ gui.log.postlog=Upload Log |
64 | 65 | gui.log.uploading=Uploading log to pastebin... |
65 | 66 | gui.log.uploadfailed=Upload failed |
66 | 67 | gui.log.uploadsuccess=Upload succeeded, log available at |
67 | -gui.log.closedialog=Close | |
68 | 68 | \ No newline at end of file |
69 | +gui.log.closedialog=Close | |
70 | + | |
71 | +gui.error.title=Startup errors for %s | |
72 | + | |
73 | +gui.error.tooltip=%d mod startup error(s) detected | |
69 | 74 | \ No newline at end of file | ... | ... |
resources/assets/liteloader/textures/gui/about.png