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