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,6 +480,7 @@ public class ClientEvents extends Events<Minecraft, IntegratedServer> | ||
480 | } | 480 | } |
481 | catch (Throwable th) | 481 | catch (Throwable th) |
482 | { | 482 | { |
483 | + this.mods.onLateInitFailed(initMod, th); | ||
483 | LiteLoaderLogger.warning(th, "Error initialising mod %s", initMod.getName()); | 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,6 +185,12 @@ public class LiteLoaderPanelManager implements PanelManager<GuiScreen> | ||
185 | this.minecraft.displayGuiScreen(this.panelHost); | 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 | private boolean isPanelSupportedOnScreen(GuiScreen guiScreen) | 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,7 +82,8 @@ public class LiteLoaderCoreAPIClient extends LiteLoaderCoreAPI | ||
82 | { | 82 | { |
83 | return ImmutableList.<CustomisationProvider>of | 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,10 +3,13 @@ package com.mumfrey.liteloader.client.gui; | ||
3 | import static org.lwjgl.opengl.GL11.*; | 3 | import static org.lwjgl.opengl.GL11.*; |
4 | 4 | ||
5 | import java.nio.DoubleBuffer; | 5 | import java.nio.DoubleBuffer; |
6 | +import java.util.ArrayList; | ||
7 | +import java.util.List; | ||
6 | 8 | ||
7 | import net.minecraft.client.Minecraft; | 9 | import net.minecraft.client.Minecraft; |
8 | import net.minecraft.client.gui.FontRenderer; | 10 | import net.minecraft.client.gui.FontRenderer; |
9 | import net.minecraft.client.gui.GuiButton; | 11 | import net.minecraft.client.gui.GuiButton; |
12 | +import net.minecraft.client.gui.GuiMainMenu; | ||
10 | import net.minecraft.client.gui.GuiScreen; | 13 | import net.minecraft.client.gui.GuiScreen; |
11 | import net.minecraft.client.renderer.Tessellator; | 14 | import net.minecraft.client.renderer.Tessellator; |
12 | import net.minecraft.client.resources.I18n; | 15 | import net.minecraft.client.resources.I18n; |
@@ -20,10 +23,12 @@ import org.lwjgl.input.Mouse; | @@ -20,10 +23,12 @@ import org.lwjgl.input.Mouse; | ||
20 | import com.mumfrey.liteloader.LiteMod; | 23 | import com.mumfrey.liteloader.LiteMod; |
21 | import com.mumfrey.liteloader.api.LiteAPI; | 24 | import com.mumfrey.liteloader.api.LiteAPI; |
22 | import com.mumfrey.liteloader.api.BrandingProvider; | 25 | import com.mumfrey.liteloader.api.BrandingProvider; |
26 | +import com.mumfrey.liteloader.api.ModInfoDecorator; | ||
23 | import com.mumfrey.liteloader.client.api.LiteLoaderBrandingProvider; | 27 | import com.mumfrey.liteloader.client.api.LiteLoaderBrandingProvider; |
24 | import com.mumfrey.liteloader.core.LiteLoader; | 28 | import com.mumfrey.liteloader.core.LiteLoader; |
25 | import com.mumfrey.liteloader.core.LiteLoaderVersion; | 29 | import com.mumfrey.liteloader.core.LiteLoaderVersion; |
26 | import com.mumfrey.liteloader.core.LiteLoaderMods; | 30 | import com.mumfrey.liteloader.core.LiteLoaderMods; |
31 | +import com.mumfrey.liteloader.core.ModInfo; | ||
27 | import com.mumfrey.liteloader.core.api.LiteLoaderCoreAPI; | 32 | import com.mumfrey.liteloader.core.api.LiteLoaderCoreAPI; |
28 | import com.mumfrey.liteloader.launch.LoaderEnvironment; | 33 | import com.mumfrey.liteloader.launch.LoaderEnvironment; |
29 | import com.mumfrey.liteloader.modconfig.ConfigManager; | 34 | import com.mumfrey.liteloader.modconfig.ConfigManager; |
@@ -55,6 +60,10 @@ public class GuiLiteLoaderPanel extends GuiScreen | @@ -55,6 +60,10 @@ public class GuiLiteLoaderPanel extends GuiScreen | ||
55 | */ | 60 | */ |
56 | private static DoubleBuffer doubleBuffer = BufferUtils.createByteBuffer(64).asDoubleBuffer(); | 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 | * Reference to the main menu which this screen is either overlaying or using as its background | 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,8 +117,12 @@ public class GuiLiteLoaderPanel extends GuiScreen | ||
108 | private ResourceLocation iconResource = LiteLoaderBrandingProvider.ABOUT_TEXTURE; | 117 | private ResourceLocation iconResource = LiteLoaderBrandingProvider.ABOUT_TEXTURE; |
109 | private IIcon iconCoords = LiteLoaderBrandingProvider.ICON_COORDS; | 118 | private IIcon iconCoords = LiteLoaderBrandingProvider.ICON_COORDS; |
110 | 119 | ||
120 | + private List<ModInfoDecorator> modInfoDecorators = new ArrayList<ModInfoDecorator>(); | ||
121 | + | ||
111 | private boolean mouseOverLogo = false; | 122 | private boolean mouseOverLogo = false; |
112 | 123 | ||
124 | + private int startupErrorCount = 0; | ||
125 | + | ||
113 | /** | 126 | /** |
114 | * @param minecraft | 127 | * @param minecraft |
115 | * @param parentScreen | 128 | * @param parentScreen |
@@ -127,8 +140,10 @@ public class GuiLiteLoaderPanel extends GuiScreen | @@ -127,8 +140,10 @@ public class GuiLiteLoaderPanel extends GuiScreen | ||
127 | 140 | ||
128 | this.initBranding(); | 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 | this.settingsPanel = new GuiPanelSettings(this, minecraft); | 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,31 +160,38 @@ public class GuiLiteLoaderPanel extends GuiScreen | ||
145 | for (LiteAPI api : LiteLoader.getAPIs()) | 160 | for (LiteAPI api : LiteLoader.getAPIs()) |
146 | { | 161 | { |
147 | BrandingProvider brandingProvider = LiteLoader.getCustomisationProvider(api, BrandingProvider.class); | 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,6 +240,9 @@ public class GuiLiteLoaderPanel extends GuiScreen | ||
218 | @Override | 240 | @Override |
219 | public void initGui() | 241 | public void initGui() |
220 | { | 242 | { |
243 | + // Hide the tooltip once the user opens the panel | ||
244 | + GuiLiteLoaderPanel.displayErrorToolTip = false; | ||
245 | + | ||
221 | this.currentPanel.setSize(this.width - LEFT_EDGE, this.height); | 246 | this.currentPanel.setSize(this.width - LEFT_EDGE, this.height); |
222 | 247 | ||
223 | this.buttonList.add(new GuiHoverLabel(2, LEFT_EDGE + MARGIN, this.height - PANEL_BOTTOM + 9, this.fontRendererObj, I18n.format("gui.about.taboptions"), this.brandColour)); | 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,16 +337,11 @@ public class GuiLiteLoaderPanel extends GuiScreen | ||
312 | this.handleMouseClick(offsetMouseX, mouseY, partialTicks, active, mouseOverTab); | 337 | this.handleMouseClick(offsetMouseX, mouseY, partialTicks, active, mouseOverTab); |
313 | 338 | ||
314 | // Calculate the tab opacity, not framerate adjusted because we don't really care | 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 | // Draw the panel contents | 342 | // Draw the panel contents |
318 | this.drawPanel(offsetMouseX, mouseY, partialTicks, active, xOffset); | 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,6 +368,10 @@ public class GuiLiteLoaderPanel extends GuiScreen | ||
348 | 368 | ||
349 | this.mc.getTextureManager().bindTexture(LiteLoaderBrandingProvider.ABOUT_TEXTURE); | 369 | this.mc.getTextureManager().bindTexture(LiteLoaderBrandingProvider.ABOUT_TEXTURE); |
350 | glDrawTexturedRect(LEFT_EDGE - TAB_WIDTH, TAB_TOP, TAB_WIDTH + 1, TAB_HEIGHT, 80, 80, 122, 160, 0.5F + this.tabOpacity); | 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 | else | 376 | else |
353 | { | 377 | { |
@@ -420,7 +444,30 @@ public class GuiLiteLoaderPanel extends GuiScreen | @@ -420,7 +444,30 @@ public class GuiLiteLoaderPanel extends GuiScreen | ||
420 | this.mouseOverLogo = (mouseY > MARGIN && mouseY < MARGIN + this.logoCoords.getIconHeight() && mouseX > left && mouseX < left + this.logoCoords.getIconWidth()); | 444 | this.mouseOverLogo = (mouseY > MARGIN && mouseY < MARGIN + this.logoCoords.getIconHeight() && mouseX > left && mouseX < left + this.logoCoords.getIconWidth()); |
421 | return this.mouseOverLogo; | 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 | /* (non-Javadoc) | 471 | /* (non-Javadoc) |
425 | * @see net.minecraft.client.gui.GuiScreen#actionPerformed(net.minecraft.client.gui.GuiButton) | 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,6 +510,11 @@ public class GuiLiteLoaderPanel extends GuiScreen | ||
463 | this.setCurrentPanel(new GuiPanelAbout(this.mc, this)); | 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 | /* (non-Javadoc) | 518 | /* (non-Javadoc) |
467 | * @see net.minecraft.client.gui.GuiScreen#mouseClicked(int, int, int) | 519 | * @see net.minecraft.client.gui.GuiScreen#mouseClicked(int, int, int) |
468 | */ | 520 | */ |
@@ -688,6 +740,8 @@ public class GuiLiteLoaderPanel extends GuiScreen | @@ -688,6 +740,8 @@ public class GuiLiteLoaderPanel extends GuiScreen | ||
688 | */ | 740 | */ |
689 | final static void glEnableClipping(int xLeft, int xRight, int yTop, int yBottom) | 741 | final static void glEnableClipping(int xLeft, int xRight, int yTop, int yBottom) |
690 | { | 742 | { |
743 | + clippingPlaneFlags = 0; | ||
744 | + | ||
691 | // Apply left edge clipping if specified | 745 | // Apply left edge clipping if specified |
692 | if (xLeft != -1) | 746 | if (xLeft != -1) |
693 | { | 747 | { |
@@ -695,6 +749,7 @@ public class GuiLiteLoaderPanel extends GuiScreen | @@ -695,6 +749,7 @@ public class GuiLiteLoaderPanel extends GuiScreen | ||
695 | doubleBuffer.put(1).put(0).put(0).put(-xLeft).flip(); | 749 | doubleBuffer.put(1).put(0).put(0).put(-xLeft).flip(); |
696 | glClipPlane(GL_CLIP_PLANE2, doubleBuffer); | 750 | glClipPlane(GL_CLIP_PLANE2, doubleBuffer); |
697 | glEnable(GL_CLIP_PLANE2); | 751 | glEnable(GL_CLIP_PLANE2); |
752 | + clippingPlaneFlags |= GL_CLIP_PLANE2; | ||
698 | } | 753 | } |
699 | 754 | ||
700 | // Apply right edge clipping if specified | 755 | // Apply right edge clipping if specified |
@@ -704,6 +759,7 @@ public class GuiLiteLoaderPanel extends GuiScreen | @@ -704,6 +759,7 @@ public class GuiLiteLoaderPanel extends GuiScreen | ||
704 | doubleBuffer.put(-1).put(0).put(0).put(xRight).flip(); | 759 | doubleBuffer.put(-1).put(0).put(0).put(xRight).flip(); |
705 | glClipPlane(GL_CLIP_PLANE3, doubleBuffer); | 760 | glClipPlane(GL_CLIP_PLANE3, doubleBuffer); |
706 | glEnable(GL_CLIP_PLANE3); | 761 | glEnable(GL_CLIP_PLANE3); |
762 | + clippingPlaneFlags |= GL_CLIP_PLANE3; | ||
707 | } | 763 | } |
708 | 764 | ||
709 | // Apply top edge clipping if specified | 765 | // Apply top edge clipping if specified |
@@ -713,6 +769,7 @@ public class GuiLiteLoaderPanel extends GuiScreen | @@ -713,6 +769,7 @@ public class GuiLiteLoaderPanel extends GuiScreen | ||
713 | doubleBuffer.put(0).put(1).put(0).put(-yTop).flip(); | 769 | doubleBuffer.put(0).put(1).put(0).put(-yTop).flip(); |
714 | glClipPlane(GL_CLIP_PLANE4, doubleBuffer); | 770 | glClipPlane(GL_CLIP_PLANE4, doubleBuffer); |
715 | glEnable(GL_CLIP_PLANE4); | 771 | glEnable(GL_CLIP_PLANE4); |
772 | + clippingPlaneFlags |= GL_CLIP_PLANE4; | ||
716 | } | 773 | } |
717 | 774 | ||
718 | // Apply bottom edge clipping if specified | 775 | // Apply bottom edge clipping if specified |
@@ -722,10 +779,22 @@ public class GuiLiteLoaderPanel extends GuiScreen | @@ -722,10 +779,22 @@ public class GuiLiteLoaderPanel extends GuiScreen | ||
722 | doubleBuffer.put(0).put(-1).put(0).put(yBottom).flip(); | 779 | doubleBuffer.put(0).put(-1).put(0).put(yBottom).flip(); |
723 | glClipPlane(GL_CLIP_PLANE5, doubleBuffer); | 780 | glClipPlane(GL_CLIP_PLANE5, doubleBuffer); |
724 | glEnable(GL_CLIP_PLANE5); | 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 | * Disable OpenGL clipping planes (uses planes 2, 3, 4 and 5) | 798 | * Disable OpenGL clipping planes (uses planes 2, 3, 4 and 5) |
730 | */ | 799 | */ |
731 | final static void glDisableClipping() | 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,16 +11,16 @@ import net.minecraft.client.gui.FontRenderer; | ||
11 | import net.minecraft.client.gui.Gui; | 11 | import net.minecraft.client.gui.Gui; |
12 | import net.minecraft.client.resources.I18n; | 12 | import net.minecraft.client.resources.I18n; |
13 | 13 | ||
14 | -import com.google.common.collect.ImmutableSet; | 14 | +import com.google.common.base.Strings; |
15 | import com.mumfrey.liteloader.LiteMod; | 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 | import com.mumfrey.liteloader.core.LiteLoaderMods; | 17 | import com.mumfrey.liteloader.core.LiteLoaderMods; |
18 | +import com.mumfrey.liteloader.core.ModInfo; | ||
20 | import com.mumfrey.liteloader.interfaces.Loadable; | 19 | import com.mumfrey.liteloader.interfaces.Loadable; |
21 | import com.mumfrey.liteloader.interfaces.LoadableMod; | 20 | import com.mumfrey.liteloader.interfaces.LoadableMod; |
22 | -import com.mumfrey.liteloader.interfaces.TweakContainer; | ||
23 | import com.mumfrey.liteloader.launch.LoaderEnvironment; | 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 | * Represents a mod in the mod info screen, keeps track of mod information and provides methods | 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,6 +41,9 @@ public class GuiModListEntry extends Gui | ||
41 | private static final int API_COLOUR = 0xFFAA00AA; | 41 | private static final int API_COLOUR = 0xFFAA00AA; |
42 | private static final int EXTERNAL_ENTRY_COLOUR = 0xFF47D1AA; | 42 | private static final int EXTERNAL_ENTRY_COLOUR = 0xFF47D1AA; |
43 | private static final int MISSING_DEPENDENCY_COLOUR = 0xFFFFAA00; | 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 | private static final int TITLE_COLOUR = GuiModListEntry.WHITE; | 48 | private static final int TITLE_COLOUR = GuiModListEntry.WHITE; |
46 | private static final int VERSION_TEXT_COLOUR = GuiModListEntry.GREY; | 49 | private static final int VERSION_TEXT_COLOUR = GuiModListEntry.GREY; |
@@ -54,8 +57,6 @@ public class GuiModListEntry extends Gui | @@ -54,8 +57,6 @@ public class GuiModListEntry extends Gui | ||
54 | private static final int PANEL_HEIGHT = 32; | 57 | private static final int PANEL_HEIGHT = 32; |
55 | private static final int PANEL_SPACING = 4; | 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 | * For text display | 61 | * For text display |
61 | */ | 62 | */ |
@@ -63,12 +64,12 @@ public class GuiModListEntry extends Gui | @@ -63,12 +64,12 @@ public class GuiModListEntry extends Gui | ||
63 | 64 | ||
64 | private final int brandColour; | 65 | private final int brandColour; |
65 | 66 | ||
67 | + private final List<ModInfoDecorator> decorators; | ||
68 | + | ||
66 | private final LiteLoaderMods mods; | 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 | * The identifier of the mod, used as the enablement/disablement key | 74 | * The identifier of the mod, used as the enablement/disablement key |
74 | */ | 75 | */ |
@@ -108,6 +109,8 @@ public class GuiModListEntry extends Gui | @@ -108,6 +109,8 @@ public class GuiModListEntry extends Gui | ||
108 | 109 | ||
109 | private boolean isMissingAPIs; | 110 | private boolean isMissingAPIs; |
110 | 111 | ||
112 | + private boolean isErrored; | ||
113 | + | ||
111 | /** | 114 | /** |
112 | * True if the mod is missing a dependency which has caused it not to load | 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,12 +137,14 @@ public class GuiModListEntry extends Gui | ||
134 | */ | 137 | */ |
135 | private boolean mouseOverListEntry, mouseOverInfo, mouseOverScrollBar; | 138 | private boolean mouseOverListEntry, mouseOverInfo, mouseOverScrollBar; |
136 | 139 | ||
140 | + private IconClickable mouseOverIcon = null; | ||
141 | + | ||
137 | /** | 142 | /** |
138 | * True if this is not a mod but an external jar | 143 | * True if this is not a mod but an external jar |
139 | */ | 144 | */ |
140 | private boolean external; | 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 | * Scroll bar control for the mod info | 150 | * Scroll bar control for the mod info |
@@ -149,125 +154,49 @@ public class GuiModListEntry extends Gui | @@ -149,125 +154,49 @@ public class GuiModListEntry extends Gui | ||
149 | /** | 154 | /** |
150 | * Mod list entry for an ACTIVE mod | 155 | * Mod list entry for an ACTIVE mod |
151 | * @param fontRenderer | 156 | * @param fontRenderer |
152 | - * @param modInstance | 157 | + * @param modInfo |
153 | * @param enabledMods | 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,7 +234,9 @@ public class GuiModListEntry extends Gui | ||
305 | xPosition += (width - 14); | 234 | xPosition += (width - 14); |
306 | yPosition += (GuiModListEntry.PANEL_HEIGHT - 14); | 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 | xPosition = this.drawPropertyIcon(xPosition, yPosition, icon, mouseX, mouseY); | 241 | xPosition = this.drawPropertyIcon(xPosition, yPosition, icon, mouseX, mouseY); |
311 | } | 242 | } |
@@ -313,7 +244,7 @@ public class GuiModListEntry extends Gui | @@ -313,7 +244,7 @@ public class GuiModListEntry extends Gui | ||
313 | return GuiModListEntry.PANEL_HEIGHT + GuiModListEntry.PANEL_SPACING; | 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 | glColor4f(1.0F, 1.0F, 1.0F, 1.0F); | 249 | glColor4f(1.0F, 1.0F, 1.0F, 1.0F); |
319 | Minecraft.getMinecraft().getTextureManager().bindTexture(icon.getTextureResource()); | 250 | Minecraft.getMinecraft().getTextureManager().bindTexture(icon.getTextureResource()); |
@@ -324,7 +255,15 @@ public class GuiModListEntry extends Gui | @@ -324,7 +255,15 @@ public class GuiModListEntry extends Gui | ||
324 | 255 | ||
325 | if (mouseX >= xPosition && mouseX <= xPosition + 12 && mouseY >= yPosition && mouseY <= yPosition + 12) | 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 | return xPosition - 14; | 269 | return xPosition - 14; |
@@ -353,7 +292,7 @@ public class GuiModListEntry extends Gui | @@ -353,7 +292,7 @@ public class GuiModListEntry extends Gui | ||
353 | drawRect(xPosition + 5, yPos, xPosition + width, yPos + 1, GuiModListEntry.DIVIDER_COLOUR); yPos += 4; // divider | 292 | drawRect(xPosition + 5, yPos, xPosition + width, yPos + 1, GuiModListEntry.DIVIDER_COLOUR); yPos += 4; // divider |
354 | 293 | ||
355 | this.fontRenderer.drawString(I18n.format("gui.about.authors") + ": \2477" + this.author, xPosition + 5, yPos, GuiModListEntry.AUTHORS_COLOUR); yPos += 10; | 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 | this.fontRenderer.drawString(this.url, xPosition + 5, yPos, GuiModListEntry.BLEND_2THRDS & this.brandColour); yPos += 10; | 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,7 +362,7 @@ public class GuiModListEntry extends Gui | ||
423 | */ | 362 | */ |
424 | protected int getGradientColour(boolean selected) | 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,6 +376,7 @@ public class GuiModListEntry extends Gui | ||
437 | { | 376 | { |
438 | if (this.isMissingDependencies) return GuiModListEntry.MISSING_DEPENDENCY_COLOUR; | 377 | if (this.isMissingDependencies) return GuiModListEntry.MISSING_DEPENDENCY_COLOUR; |
439 | if (this.isMissingAPIs) return GuiModListEntry.API_COLOUR; | 378 | if (this.isMissingAPIs) return GuiModListEntry.API_COLOUR; |
379 | + if (this.isErrored) return GuiModListEntry.ERROR_COLOUR; | ||
440 | if (!this.enabled) return GuiModListEntry.GREY; | 380 | if (!this.enabled) return GuiModListEntry.GREY; |
441 | return this.external ? GuiModListEntry.EXTERNAL_ENTRY_COLOUR : GuiModListEntry.WHITE; | 381 | return this.external ? GuiModListEntry.EXTERNAL_ENTRY_COLOUR : GuiModListEntry.WHITE; |
442 | } | 382 | } |
@@ -497,17 +437,17 @@ public class GuiModListEntry extends Gui | @@ -497,17 +437,17 @@ public class GuiModListEntry extends Gui | ||
497 | 437 | ||
498 | public String getKey() | 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 | public LiteMod getModInstance() | 443 | public LiteMod getModInstance() |
504 | { | 444 | { |
505 | - return this.modInstance; | 445 | + return this.modInfo.getMod(); |
506 | } | 446 | } |
507 | 447 | ||
508 | public Class<? extends LiteMod> getModClass() | 448 | public Class<? extends LiteMod> getModClass() |
509 | { | 449 | { |
510 | - return this.modClass; | 450 | + return this.modInfo.getModClass(); |
511 | } | 451 | } |
512 | 452 | ||
513 | public String getName() | 453 | public String getName() |
@@ -545,11 +485,24 @@ public class GuiModListEntry extends Gui | @@ -545,11 +485,24 @@ public class GuiModListEntry extends Gui | ||
545 | return this.willBeEnabled; | 485 | return this.willBeEnabled; |
546 | } | 486 | } |
547 | 487 | ||
488 | + public boolean isMouseOverIcon() | ||
489 | + { | ||
490 | + return this.mouseOverListEntry && this.mouseOverIcon != null; | ||
491 | + } | ||
492 | + | ||
548 | public boolean isMouseOver() | 493 | public boolean isMouseOver() |
549 | { | 494 | { |
550 | return this.mouseOverListEntry; | 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 | public boolean mouseWheelScrolled(int mouseWheelDelta) | 506 | public boolean mouseWheelScrolled(int mouseWheelDelta) |
554 | { | 507 | { |
555 | if (this.mouseOverInfo) | 508 | if (this.mouseOverInfo) |
java/client/com/mumfrey/liteloader/client/gui/GuiPanelConfigContainer.java
@@ -109,7 +109,14 @@ class GuiPanelConfigContainer extends GuiPanel implements ConfigPanelHost | @@ -109,7 +109,14 @@ class GuiPanelConfigContainer extends GuiPanel implements ConfigPanelHost | ||
109 | @Override | 109 | @Override |
110 | void onShown() | 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,7 +125,14 @@ class GuiPanelConfigContainer extends GuiPanel implements ConfigPanelHost | ||
118 | @Override | 125 | @Override |
119 | void onHidden() | 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,8 +10,11 @@ import java.util.TreeMap; | ||
10 | import org.lwjgl.input.Keyboard; | 10 | import org.lwjgl.input.Keyboard; |
11 | 11 | ||
12 | import com.mumfrey.liteloader.LiteMod; | 12 | import com.mumfrey.liteloader.LiteMod; |
13 | +import com.mumfrey.liteloader.api.ModInfoDecorator; | ||
13 | import com.mumfrey.liteloader.core.LiteLoaderMods; | 14 | import com.mumfrey.liteloader.core.LiteLoaderMods; |
15 | +import com.mumfrey.liteloader.core.ModInfo; | ||
14 | import com.mumfrey.liteloader.interfaces.Loadable; | 16 | import com.mumfrey.liteloader.interfaces.Loadable; |
17 | +import com.mumfrey.liteloader.interfaces.LoadableMod; | ||
15 | import com.mumfrey.liteloader.launch.LoaderEnvironment; | 18 | import com.mumfrey.liteloader.launch.LoaderEnvironment; |
16 | import com.mumfrey.liteloader.modconfig.ConfigManager; | 19 | import com.mumfrey.liteloader.modconfig.ConfigManager; |
17 | import com.mumfrey.liteloader.modconfig.ConfigPanel; | 20 | import com.mumfrey.liteloader.modconfig.ConfigPanel; |
@@ -70,7 +73,7 @@ public class GuiPanelMods extends GuiPanel | @@ -70,7 +73,7 @@ public class GuiPanelMods extends GuiPanel | ||
70 | 73 | ||
71 | private int brandColour; | 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 | super(minecraft); | 78 | super(minecraft); |
76 | 79 | ||
@@ -78,7 +81,7 @@ public class GuiPanelMods extends GuiPanel | @@ -78,7 +81,7 @@ public class GuiPanelMods extends GuiPanel | ||
78 | this.configManager = configManager; | 81 | this.configManager = configManager; |
79 | this.brandColour = brandColour; | 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,29 +90,29 @@ public class GuiPanelMods extends GuiPanel | ||
87 | * @param mods | 90 | * @param mods |
88 | * @param environment | 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 | // Add mods to this treeset first, in order to sort them | 95 | // Add mods to this treeset first, in order to sort them |
93 | Map<String, GuiModListEntry> sortedMods = new TreeMap<String, GuiModListEntry>(); | 96 | Map<String, GuiModListEntry> sortedMods = new TreeMap<String, GuiModListEntry>(); |
94 | 97 | ||
95 | // Active mods | 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 | sortedMods.put(modListEntry.getKey(), modListEntry); | 102 | sortedMods.put(modListEntry.getKey(), modListEntry); |
100 | } | 103 | } |
101 | 104 | ||
102 | // Disabled mods | 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 | sortedMods.put(modListEntry.getKey(), modListEntry); | 109 | sortedMods.put(modListEntry.getKey(), modListEntry); |
107 | } | 110 | } |
108 | 111 | ||
109 | // Injected tweaks | 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 | sortedMods.put(modListEntry.getKey(), modListEntry); | 116 | sortedMods.put(modListEntry.getKey(), modListEntry); |
114 | } | 117 | } |
115 | 118 | ||
@@ -178,10 +181,17 @@ public class GuiPanelMods extends GuiPanel | @@ -178,10 +181,17 @@ public class GuiPanelMods extends GuiPanel | ||
178 | { | 181 | { |
179 | this.selectMod(mod); | 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 | this.doubleClickTime = 5; | 197 | this.doubleClickTime = 5; |
java/client/com/mumfrey/liteloader/client/util/render/IconAbsolute.java
1 | package com.mumfrey.liteloader.client.util.render; | 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 | import net.minecraft.util.ResourceLocation; | 5 | import net.minecraft.util.ResourceLocation; |
5 | 6 | ||
6 | -public class IconAbsolute implements IIcon | 7 | +public class IconAbsolute implements IconTextured |
7 | { | 8 | { |
8 | private ResourceLocation textureResource; | 9 | private ResourceLocation textureResource; |
9 | 10 | ||
10 | - private String name; | 11 | + private String displayText; |
11 | 12 | ||
12 | private int texMapSize = 256; | 13 | private int texMapSize = 256; |
13 | 14 | ||
@@ -21,15 +22,15 @@ public class IconAbsolute implements IIcon | @@ -21,15 +22,15 @@ public class IconAbsolute implements IIcon | ||
21 | private float vCoord; | 22 | private float vCoord; |
22 | private float vCoord2; | 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 | this.textureResource = textureResource; | 32 | this.textureResource = textureResource; |
32 | - this.name = name; | 33 | + this.displayText = displayText; |
33 | this.width = width; | 34 | this.width = width; |
34 | this.height = height; | 35 | this.height = height; |
35 | 36 | ||
@@ -42,7 +43,14 @@ public class IconAbsolute implements IIcon | @@ -42,7 +43,14 @@ public class IconAbsolute implements IIcon | ||
42 | this.vCoord = vCoord / this.texMapSize; | 43 | this.vCoord = vCoord / this.texMapSize; |
43 | this.vCoord2 = vCoord2 / this.texMapSize; | 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 | public ResourceLocation getTextureResource() | 54 | public ResourceLocation getTextureResource() |
47 | { | 55 | { |
48 | return this.textureResource; | 56 | return this.textureResource; |
@@ -60,11 +68,13 @@ public class IconAbsolute implements IIcon | @@ -60,11 +68,13 @@ public class IconAbsolute implements IIcon | ||
60 | return this.height; | 68 | return this.height; |
61 | } | 69 | } |
62 | 70 | ||
71 | + @Override | ||
63 | public int getUPos() | 72 | public int getUPos() |
64 | { | 73 | { |
65 | return this.uPos; | 74 | return this.uPos; |
66 | } | 75 | } |
67 | 76 | ||
77 | + @Override | ||
68 | public int getVPos() | 78 | public int getVPos() |
69 | { | 79 | { |
70 | return this.vPos; | 80 | return this.vPos; |
@@ -111,6 +121,6 @@ public class IconAbsolute implements IIcon | @@ -111,6 +121,6 @@ public class IconAbsolute implements IIcon | ||
111 | @Override | 121 | @Override |
112 | public String getIconName() | 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,7 +55,8 @@ public abstract class Events<TClient, TServer extends MinecraftServer> implement | ||
55 | * Profiler | 55 | * Profiler |
56 | */ | 56 | */ |
57 | protected final Profiler profiler; | 57 | protected final Profiler profiler; |
58 | - | 58 | + |
59 | + protected LiteLoaderMods mods; | ||
59 | 60 | ||
60 | /** | 61 | /** |
61 | * List of mods which can filter server chat | 62 | * List of mods which can filter server chat |
@@ -84,6 +85,14 @@ public abstract class Events<TClient, TServer extends MinecraftServer> implement | @@ -84,6 +85,14 @@ public abstract class Events<TClient, TServer extends MinecraftServer> implement | ||
84 | this.engine = engine; | 85 | this.engine = engine; |
85 | this.profiler = engine.getProfiler(); | 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,6 +2,7 @@ package com.mumfrey.liteloader.core; | ||
2 | 2 | ||
3 | import java.io.File; | 3 | import java.io.File; |
4 | import java.io.PrintStream; | 4 | import java.io.PrintStream; |
5 | +import java.util.ArrayList; | ||
5 | import java.util.Collection; | 6 | import java.util.Collection; |
6 | import java.util.LinkedList; | 7 | import java.util.LinkedList; |
7 | import java.util.List; | 8 | import java.util.List; |
@@ -602,7 +603,14 @@ public final class LiteLoader | @@ -602,7 +603,14 @@ public final class LiteLoader | ||
602 | */ | 603 | */ |
603 | public List<LiteMod> getLoadedMods() | 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,15 +618,30 @@ public final class LiteLoader | ||
610 | */ | 618 | */ |
611 | public List<Loadable<?>> getDisabledMods() | 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 | * Get the list of injected tweak containers | 632 | * Get the list of injected tweak containers |
618 | */ | 633 | */ |
634 | + @SuppressWarnings("unchecked") | ||
619 | public Collection<Loadable<File>> getInjectedTweaks() | 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,6 +863,10 @@ public final class LiteLoader | ||
840 | 863 | ||
841 | // Create the event broker | 864 | // Create the event broker |
842 | this.events = this.objectFactory.getEventBroker(); | 865 | this.events = this.objectFactory.getEventBroker(); |
866 | + if (this.events != null) | ||
867 | + { | ||
868 | + this.events.setMods(this.mods); | ||
869 | + } | ||
843 | 870 | ||
844 | // Get the mod panel manager | 871 | // Get the mod panel manager |
845 | this.modPanelManager = this.objectFactory.getModPanelManager(); | 872 | this.modPanelManager = this.objectFactory.getModPanelManager(); |
java/common/com/mumfrey/liteloader/core/LiteLoaderEnumerator.java
@@ -5,8 +5,10 @@ import java.net.MalformedURLException; | @@ -5,8 +5,10 @@ import java.net.MalformedURLException; | ||
5 | import java.net.URL; | 5 | import java.net.URL; |
6 | import java.util.ArrayList; | 6 | import java.util.ArrayList; |
7 | import java.util.Collection; | 7 | import java.util.Collection; |
8 | +import java.util.Collections; | ||
8 | import java.util.HashMap; | 9 | import java.util.HashMap; |
9 | import java.util.HashSet; | 10 | import java.util.HashSet; |
11 | +import java.util.LinkedHashSet; | ||
10 | import java.util.LinkedList; | 12 | import java.util.LinkedList; |
11 | import java.util.List; | 13 | import java.util.List; |
12 | import java.util.Map; | 14 | import java.util.Map; |
@@ -76,17 +78,17 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | @@ -76,17 +78,17 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | ||
76 | /** | 78 | /** |
77 | * Classes to load, mapped by class name | 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 | * Mod containers which are disabled | 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 | * Mapping of identifiers to mod containers | 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 | * Containers which have already been checked for potential mod candidates | 94 | * Containers which have already been checked for potential mod candidates |
@@ -94,11 +96,6 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | @@ -94,11 +96,6 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | ||
94 | private final Set<LoadableMod<?>> enumeratedContainers = new HashSet<LoadableMod<?>>(); | 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 | * Tweaks to inject | 99 | * Tweaks to inject |
103 | */ | 100 | */ |
104 | private final List<TweakContainer<File>> tweakContainers = new ArrayList<TweakContainer<File>>(); | 101 | private final List<TweakContainer<File>> tweakContainers = new ArrayList<TweakContainer<File>>(); |
@@ -106,7 +103,7 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | @@ -106,7 +103,7 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | ||
106 | /** | 103 | /** |
107 | * Other tweak-containing jars which we have injected | 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,18 +233,18 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | ||
236 | * Get the list of all enumerated mod classes to load | 233 | * Get the list of all enumerated mod classes to load |
237 | */ | 234 | */ |
238 | @Override | 235 | @Override |
239 | - public Collection<Class<? extends LiteMod>> getModsToLoad() | 236 | + public Collection<? extends ModInfo<LoadableMod<?>>> getModsToLoad() |
240 | { | 237 | { |
241 | this.checkState(EnumeratorState.FINALISED, "getModsToLoad"); | 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 | * @return | 244 | * @return |
248 | */ | 245 | */ |
249 | @Override | 246 | @Override |
250 | - public Collection<LoadableMod<?>> getDisabledContainers() | 247 | + public Collection<? extends ModInfo<Loadable<?>>> getDisabledContainers() |
251 | { | 248 | { |
252 | this.checkState(EnumeratorState.FINALISED, "getDisabledContainers"); | 249 | this.checkState(EnumeratorState.FINALISED, "getDisabledContainers"); |
253 | 250 | ||
@@ -258,7 +255,7 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | @@ -258,7 +255,7 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | ||
258 | * Get the list of injected tweak containers | 255 | * Get the list of injected tweak containers |
259 | */ | 256 | */ |
260 | @Override | 257 | @Override |
261 | - public List<Loadable<File>> getInjectedTweaks() | 258 | + public List<? extends ModInfo<Loadable<?>>> getInjectedTweaks() |
262 | { | 259 | { |
263 | this.checkState(EnumeratorState.FINALISED, "getInjectedTweaks"); | 260 | this.checkState(EnumeratorState.FINALISED, "getInjectedTweaks"); |
264 | 261 | ||
@@ -299,7 +296,7 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | @@ -299,7 +296,7 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | ||
299 | { | 296 | { |
300 | this.checkState(EnumeratorState.FINALISED, "getContainer"); | 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,7 +308,13 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | ||
311 | { | 308 | { |
312 | this.checkState(EnumeratorState.FINALISED, "getContainer"); | 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,8 +327,14 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | ||
324 | public String getIdentifier(Class<? extends LiteMod> modClass) | 327 | public String getIdentifier(Class<? extends LiteMod> modClass) |
325 | { | 328 | { |
326 | String modClassName = modClass.getSimpleName(); | 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 | @Override | 340 | @Override |
@@ -447,7 +456,7 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | @@ -447,7 +456,7 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | ||
447 | this.checkState(EnumeratorState.DISCOVER, "registerEnabledContainer"); | 456 | this.checkState(EnumeratorState.DISCOVER, "registerEnabledContainer"); |
448 | 457 | ||
449 | this.disabledContainers.remove(container.getIdentifier()); | 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,8 +466,8 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | ||
457 | { | 466 | { |
458 | this.checkState(EnumeratorState.DISCOVER, "registerDisabledContainer"); | 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 | /* (non-Javadoc) | 473 | /* (non-Javadoc) |
@@ -514,7 +523,7 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | @@ -514,7 +523,7 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | ||
514 | 523 | ||
515 | if (container.isExternalJar()) | 524 | if (container.isExternalJar()) |
516 | { | 525 | { |
517 | - this.injectedTweaks.add(container); | 526 | + this.injectedTweaks.add(new NonMod(container, true)); |
518 | } | 527 | } |
519 | 528 | ||
520 | String[] classPathEntries = container.getClassPathEntries(); | 529 | String[] classPathEntries = container.getClassPathEntries(); |
@@ -582,9 +591,10 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | @@ -582,9 +591,10 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | ||
582 | this.enumeratedContainers.add(container); | 591 | this.enumeratedContainers.add(container); |
583 | 592 | ||
584 | LinkedList<Class<? extends LiteMod>> modClasses = LiteLoaderEnumerator.<LiteMod>getSubclassesFor(container, this.classLoader, LiteMod.class, this.supportedPrefixes); | 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 | if (modClasses.size() > 0) | 600 | if (modClasses.size() > 0) |
@@ -592,29 +602,24 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | @@ -592,29 +602,24 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | ||
592 | LiteLoaderLogger.info("Found %d potential matches", modClasses.size()); | 602 | LiteLoaderLogger.info("Found %d potential matches", modClasses.size()); |
593 | 603 | ||
594 | this.disabledContainers.remove(container.getIdentifier()); | 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 | /* (non-Javadoc) | 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 | @Override | 612 | @Override |
603 | - public void registerMod(Class<? extends LiteMod> mod, LoadableMod<?> container) | 613 | + public void registerMod(ModInfo<LoadableMod<?>> mod) |
604 | { | 614 | { |
605 | this.checkState(EnumeratorState.REGISTER, "registerMod"); | 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,22 +71,24 @@ public class LiteLoaderMods | ||
71 | /** | 71 | /** |
72 | * Global list of mods which we can load | 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 | * Global list of mods which are still waiting for initialisiation | 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 | * Global list of mods which we have loaded | 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 | * Mods which are loaded but disabled | 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 | LiteLoaderMods(LiteLoader loader, LoaderEnvironment environment, LoaderProperties properties, ConfigManager configManager) | 93 | LiteLoaderMods(LiteLoader loader, LoaderEnvironment environment, LoaderProperties properties, ConfigManager configManager) |
92 | { | 94 | { |
@@ -97,12 +99,13 @@ public class LiteLoaderMods | @@ -97,12 +99,13 @@ public class LiteLoaderMods | ||
97 | this.configManager = configManager; | 99 | this.configManager = configManager; |
98 | } | 100 | } |
99 | 101 | ||
102 | + @SuppressWarnings("unchecked") | ||
100 | void init(List<ModLoadObserver> observers) | 103 | void init(List<ModLoadObserver> observers) |
101 | { | 104 | { |
102 | this.observers = observers; | 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 | void onPostInit() | 109 | void onPostInit() |
107 | { | 110 | { |
108 | this.updateSharedModList(); | 111 | this.updateSharedModList(); |
@@ -115,9 +118,9 @@ public class LiteLoaderMods | @@ -115,9 +118,9 @@ public class LiteLoaderMods | ||
115 | return this.environment.getEnabledModsList(); | 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,25 +136,41 @@ public class LiteLoaderMods | ||
133 | /** | 136 | /** |
134 | * Get a list containing all loaded mods | 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 | * Get a list containing all mod files which were NOT loaded | 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 | * Get the list of injected tweak containers | 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,13 +205,10 @@ public class LiteLoaderMods | ||
186 | throw new IllegalArgumentException("Attempted to get a reference to a mod without specifying a mod name"); | 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 | return null; | 214 | return null; |
@@ -207,9 +223,9 @@ public class LiteLoaderMods | @@ -207,9 +223,9 @@ public class LiteLoaderMods | ||
207 | @SuppressWarnings("unchecked") | 223 | @SuppressWarnings("unchecked") |
208 | public <T extends LiteMod> T getMod(Class<T> modClass) | 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 | return (T)mod; | 229 | return (T)mod; |
214 | } | 230 | } |
215 | 231 | ||
@@ -226,12 +242,10 @@ public class LiteLoaderMods | @@ -226,12 +242,10 @@ public class LiteLoaderMods | ||
226 | { | 242 | { |
227 | if (identifier == null) return null; | 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 | return null; | 251 | return null; |
@@ -368,16 +382,14 @@ public class LiteLoaderMods | @@ -368,16 +382,14 @@ public class LiteLoaderMods | ||
368 | * @param modName | 382 | * @param modName |
369 | * @return | 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 | return true; | 392 | return true; |
380 | - } | ||
381 | } | 393 | } |
382 | 394 | ||
383 | return false; | 395 | return false; |
@@ -392,14 +404,14 @@ public class LiteLoaderMods | @@ -392,14 +404,14 @@ public class LiteLoaderMods | ||
392 | { | 404 | { |
393 | LoadingProgress.incTotalLiteLoaderProgress(this.enumerator.getModsToLoad().size()); | 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 | try | 412 | try |
401 | { | 413 | { |
402 | - String identifier = this.enumerator.getIdentifier(mod); | 414 | + String identifier = mod.getIdentifier(); |
403 | if (identifier == null || this.environment.getEnabledModsList().isEnabled(this.environment.getProfile(), identifier)) | 415 | if (identifier == null || this.environment.getEnabledModsList().isEnabled(this.environment.getProfile(), identifier)) |
404 | { | 416 | { |
405 | if (!this.enumerator.checkDependencies(container)) | 417 | if (!this.enumerator.checkDependencies(container)) |
@@ -408,7 +420,14 @@ public class LiteLoaderMods | @@ -408,7 +420,14 @@ public class LiteLoaderMods | ||
408 | continue; | 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 | else | 432 | else |
414 | { | 433 | { |
@@ -417,33 +436,44 @@ public class LiteLoaderMods | @@ -417,33 +436,44 @@ public class LiteLoaderMods | ||
417 | } | 436 | } |
418 | catch (Throwable th) | 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 | * @param identifier | 445 | * @param identifier |
427 | - * @param mod | 446 | + * @param modClass |
428 | * @param container | 447 | * @param container |
429 | * @throws InstantiationException | 448 | * @throws InstantiationException |
430 | * @throws IllegalAccessException | 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 | LiteMod newMod = mod.newInstance(); | 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 | LiteLoaderLogger.info("Successfully added mod %s version %s", modName, newMod.getVersion()); | 471 | LiteLoaderLogger.info("Successfully added mod %s version %s", modName, newMod.getVersion()); |
443 | 472 | ||
444 | // Register the mod as a resource pack if the container exists | 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 | LiteLoaderLogger.info("Adding \"%s\" to active resource pack set", container.getLocation()); | 477 | LiteLoaderLogger.info("Adding \"%s\" to active resource pack set", container.getLocation()); |
448 | if (modName != null) | 478 | if (modName != null) |
449 | { | 479 | { |
@@ -460,11 +490,11 @@ public class LiteLoaderMods | @@ -460,11 +490,11 @@ public class LiteLoaderMods | ||
460 | /** | 490 | /** |
461 | * @param mod | 491 | * @param mod |
462 | */ | 492 | */ |
463 | - void onModLoaded(LiteMod mod) | 493 | + void onModLoaded(Mod mod) |
464 | { | 494 | { |
465 | for (ModLoadObserver observer : this.observers) | 495 | for (ModLoadObserver observer : this.observers) |
466 | { | 496 | { |
467 | - observer.onModLoaded(mod); | 497 | + observer.onModLoaded(mod.getMod()); |
468 | } | 498 | } |
469 | 499 | ||
470 | this.allMods.add(mod); | 500 | this.allMods.add(mod); |
@@ -485,7 +515,7 @@ public class LiteLoaderMods | @@ -485,7 +515,7 @@ public class LiteLoaderMods | ||
485 | 515 | ||
486 | if (container != LoadableMod.NONE && !this.disabledMods.contains(container)) | 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 | for (ModLoadObserver observer : this.observers) | 521 | for (ModLoadObserver observer : this.observers) |
@@ -504,7 +534,7 @@ public class LiteLoaderMods | @@ -504,7 +534,7 @@ public class LiteLoaderMods | ||
504 | 534 | ||
505 | while (this.initMods.size() > 0) | 535 | while (this.initMods.size() > 0) |
506 | { | 536 | { |
507 | - LiteMod mod = this.initMods.removeFirst(); | 537 | + Mod mod = this.initMods.removeFirst(); |
508 | 538 | ||
509 | try | 539 | try |
510 | { | 540 | { |
@@ -513,8 +543,8 @@ public class LiteLoaderMods | @@ -513,8 +543,8 @@ public class LiteLoaderMods | ||
513 | } | 543 | } |
514 | catch (Throwable th) | 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,70 +554,73 @@ public class LiteLoaderMods | ||
524 | /** | 554 | /** |
525 | * @param mod | 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 | // initialise the mod | 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 | for (ModLoadObserver observer : this.observers) | 580 | for (ModLoadObserver observer : this.observers) |
546 | { | 581 | { |
547 | - observer.onPreInitMod(mod); | 582 | + observer.onPreInitMod(instance); |
548 | } | 583 | } |
549 | 584 | ||
550 | // register mod config panel if configurable | 585 | // register mod config panel if configurable |
551 | - this.configManager.registerMod(mod); | 586 | + this.configManager.registerMod(instance); |
552 | 587 | ||
553 | try | 588 | try |
554 | { | 589 | { |
555 | - this.handleModVersionUpgrade(mod); | 590 | + this.handleModVersionUpgrade(instance); |
556 | } | 591 | } |
557 | catch (Throwable th) | 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 | // Init mod config if there is any | 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 | for (ModLoadObserver observer : this.observers) | 607 | for (ModLoadObserver observer : this.observers) |
572 | { | 608 | { |
573 | - observer.onPostInitMod(mod); | 609 | + observer.onPostInitMod(instance); |
574 | } | 610 | } |
575 | 611 | ||
576 | // add the mod to all relevant listener queues | 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 | int currentRevision = LiteLoaderVersion.CURRENT.getLoaderRevision(); | 625 | int currentRevision = LiteLoaderVersion.CURRENT.getLoaderRevision(); |
593 | int lastKnownRevision = this.properties.getLastKnownModRevision(modKey); | 626 | int lastKnownRevision = this.properties.getLastKnownModRevision(modKey); |
@@ -598,25 +631,25 @@ public class LiteLoaderMods | @@ -598,25 +631,25 @@ public class LiteLoaderMods | ||
598 | File newConfigPath = LiteLoader.getConfigFolder(); | 631 | File newConfigPath = LiteLoader.getConfigFolder(); |
599 | File oldConfigPath = this.environment.inflectVersionedConfigPath(lastModVersion); | 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 | for (ModLoadObserver observer : this.observers) | 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 | // Migrate versioned config if any is present | 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 | // Let the mod upgrade | 644 | // Let the mod upgrade |
612 | - mod.upgradeSettings(LiteLoaderVersion.CURRENT.getMinecraftVersion(), newConfigPath, oldConfigPath); | 645 | + instance.upgradeSettings(LiteLoaderVersion.CURRENT.getMinecraftVersion(), newConfigPath, oldConfigPath); |
613 | 646 | ||
614 | this.properties.storeLastKnownModRevision(modKey); | 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,30 +670,49 @@ public class LiteLoaderMods | ||
637 | return String.format("version.%s", modName.toLowerCase().replaceAll("[^a-z0-9_\\-\\.]", "")); | 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 | void updateSharedModList() | 693 | void updateSharedModList() |
641 | { | 694 | { |
642 | Map<String, Map<String, String>> modList = this.enumerator.getSharedModList(); | 695 | Map<String, Map<String, String>> modList = this.enumerator.getSharedModList(); |
643 | if (modList == null) return; | 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 | modList.put(modKey, this.packModInfoToMap(mod)); | 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 | Map<String, String> modInfo = new HashMap<String, String>(); | 707 | Map<String, String> modInfo = new HashMap<String, String>(); |
655 | - LoadableMod<?> container = this.loader.getModContainer(mod); | ||
656 | 708 | ||
657 | modInfo.put("modsystem", LiteLoaderMods.MOD_SYSTEM); | 709 | modInfo.put("modsystem", LiteLoaderMods.MOD_SYSTEM); |
658 | - modInfo.put("id", this.loader.getModIdentifier(mod)); | 710 | + modInfo.put("id", mod.getIdentifier()); |
659 | modInfo.put("version", mod.getVersion()); | 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 | return modInfo; | 717 | return modInfo; |
666 | } | 718 | } |
java/common/com/mumfrey/liteloader/core/LiteLoaderVersion.java
@@ -9,7 +9,7 @@ import com.mumfrey.liteloader.update.UpdateSite; | @@ -9,7 +9,7 @@ import com.mumfrey.liteloader.update.UpdateSite; | ||
9 | * LiteLoader version table | 9 | * LiteLoader version table |
10 | * | 10 | * |
11 | * @author Adam Mummery-Smith | 11 | * @author Adam Mummery-Smith |
12 | - * @version 1.7.10_02 | 12 | + * @version 1.7.10_03 |
13 | */ | 13 | */ |
14 | public enum LiteLoaderVersion | 14 | public enum LiteLoaderVersion |
15 | { | 15 | { |
@@ -37,7 +37,8 @@ public enum LiteLoaderVersion | @@ -37,7 +37,8 @@ public enum LiteLoaderVersion | ||
37 | MC_1_7_2_R6(26, 0, "1.7.2", "1.7.2_06", "1.7.2_06"), | 37 | MC_1_7_2_R6(26, 0, "1.7.2", "1.7.2_06", "1.7.2_06"), |
38 | MC_1_7_10_R0(27, 1404330030, "1.7.10", "1.7.10", "1.7.10"), | 38 | MC_1_7_10_R0(27, 1404330030, "1.7.10", "1.7.10", "1.7.10"), |
39 | MC_1_7_10_R1(28, 1404673785, "1.7.10", "1.7.10_01", "1.7.10"), | 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 | * Current loader version | 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 | package com.mumfrey.liteloader.interfaces; | 1 | package com.mumfrey.liteloader.interfaces; |
2 | 2 | ||
3 | -import java.io.File; | ||
4 | import java.util.Collection; | 3 | import java.util.Collection; |
5 | import java.util.List; | 4 | import java.util.List; |
6 | import java.util.Map; | 5 | import java.util.Map; |
7 | 6 | ||
8 | import com.mumfrey.liteloader.LiteMod; | 7 | import com.mumfrey.liteloader.LiteMod; |
8 | +import com.mumfrey.liteloader.core.ModInfo; | ||
9 | 9 | ||
10 | /** | 10 | /** |
11 | * Interface for the enumerator | 11 | * Interface for the enumerator |
@@ -69,7 +69,7 @@ public interface LoaderEnumerator extends ModularEnumerator | @@ -69,7 +69,7 @@ public interface LoaderEnumerator extends ModularEnumerator | ||
69 | * | 69 | * |
70 | * @return | 70 | * @return |
71 | */ | 71 | */ |
72 | - public abstract Collection<LoadableMod<?>> getDisabledContainers(); | 72 | + public abstract Collection<? extends ModInfo<Loadable<?>>> getDisabledContainers(); |
73 | 73 | ||
74 | /** | 74 | /** |
75 | * @param modClass | 75 | * @param modClass |
@@ -87,12 +87,12 @@ public interface LoaderEnumerator extends ModularEnumerator | @@ -87,12 +87,12 @@ public interface LoaderEnumerator extends ModularEnumerator | ||
87 | /** | 87 | /** |
88 | * @return | 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 | * @return | 93 | * @return |
94 | */ | 94 | */ |
95 | - public abstract List<Loadable<File>> getInjectedTweaks(); | 95 | + public abstract List<? extends ModInfo<Loadable<?>>> getInjectedTweaks(); |
96 | 96 | ||
97 | /** | 97 | /** |
98 | * @return | 98 | * @return |
java/common/com/mumfrey/liteloader/interfaces/ModularEnumerator.java
@@ -2,8 +2,8 @@ package com.mumfrey.liteloader.interfaces; | @@ -2,8 +2,8 @@ package com.mumfrey.liteloader.interfaces; | ||
2 | 2 | ||
3 | import java.io.File; | 3 | import java.io.File; |
4 | 4 | ||
5 | -import com.mumfrey.liteloader.LiteMod; | ||
6 | import com.mumfrey.liteloader.api.EnumeratorModule; | 5 | import com.mumfrey.liteloader.api.EnumeratorModule; |
6 | +import com.mumfrey.liteloader.core.ModInfo; | ||
7 | 7 | ||
8 | /** | 8 | /** |
9 | * Interface for the mod enumerator | 9 | * Interface for the mod enumerator |
@@ -39,7 +39,6 @@ public interface ModularEnumerator | @@ -39,7 +39,6 @@ public interface ModularEnumerator | ||
39 | 39 | ||
40 | /** | 40 | /** |
41 | * @param mod | 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 | \ No newline at end of file | 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,4 +49,9 @@ public interface PanelManager<TParentScreen> extends TickObserver, PostRenderObs | ||
49 | * @param parentScreen | 49 | * @param parentScreen |
50 | */ | 50 | */ |
51 | public abstract void displayLiteLoaderPanel(TParentScreen parentScreen); | 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,6 +37,7 @@ gui.description.missingapis=Missing APIs: %s | ||
37 | gui.mod.providestweak=Provides Tweak | 37 | gui.mod.providestweak=Provides Tweak |
38 | gui.mod.providestransformer=Provides Transformer | 38 | gui.mod.providestransformer=Provides Transformer |
39 | gui.mod.usingapi=Uses additional API | 39 | gui.mod.usingapi=Uses additional API |
40 | +gui.mod.startuperror=%d startup error(s) | ||
40 | 41 | ||
41 | gui.settings.title=%s Settings | 42 | gui.settings.title=%s Settings |
42 | gui.saveandclose=Save & Close | 43 | gui.saveandclose=Save & Close |
@@ -64,4 +65,8 @@ gui.log.postlog=Upload Log | @@ -64,4 +65,8 @@ gui.log.postlog=Upload Log | ||
64 | gui.log.uploading=Uploading log to pastebin... | 65 | gui.log.uploading=Uploading log to pastebin... |
65 | gui.log.uploadfailed=Upload failed | 66 | gui.log.uploadfailed=Upload failed |
66 | gui.log.uploadsuccess=Upload succeeded, log available at | 67 | gui.log.uploadsuccess=Upload succeeded, log available at |
67 | -gui.log.closedialog=Close | ||
68 | \ No newline at end of file | 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 | \ No newline at end of file | 74 | \ No newline at end of file |
resources/assets/liteloader/textures/gui/about.png