From 569e3e2e1bef7183c49df5d492ee76fcdee02d26 Mon Sep 17 00:00:00 2001 From: Lunatrius Date: Tue, 2 Feb 2016 21:23:08 +0100 Subject: [PATCH] 1.8.9 update Update .git* files Update gradle script and wrapper Replace version checking with Forge version checking Remove deprecated/unused classes (BSConfiguration, ModVersionCheck) --- .gitattributes | 26 ++ .gitignore | 32 +- build.gradle | 78 ++--- build.properties | 7 - gradle.properties | 10 + gradle/wrapper/gradle-wrapper.jar | Bin 51017 -> 53636 bytes gradle/wrapper/gradle-wrapper.properties | 4 +- gradlew | 10 +- .../bspkrscore/fml/BSCClientTicker.java | 61 ---- .../bspkrs/bspkrscore/fml/ClientProxy.java | 5 +- .../java/bspkrs/bspkrscore/fml/CommandBS.java | 81 ----- .../bspkrs/bspkrscore/fml/bspkrsCoreMod.java | 39 +-- .../java/bspkrs/client/util/HUDUtils.java | 26 +- .../fml/util/DelayedGuiDisplayTicker.java | 5 +- .../bspkrs/fml/util/InputEventListener.java | 3 +- .../java/bspkrs/util/BSConfiguration.java | 227 ------------- src/main/java/bspkrs/util/BlockID.java | 298 +++++++++--------- src/main/java/bspkrs/util/Const.java | 5 +- .../java/bspkrs/util/ModVersionChecker.java | 232 -------------- src/main/java/bspkrs/util/ModulusBlockID.java | 1 + .../bspkrs/util/UniqueNameListGenerator.java | 2 +- src/test/java/bspkrs/testmod/ClientProxy.java | 9 + .../java}/bspkrs/testmod/CommonProxy.java | 0 .../bspkrs/testmod/GuiTestModConfig.java | 0 .../bspkrs/testmod/ModGuiFactoryHandler.java | 0 .../test/java}/bspkrs/testmod/TMTicker.java | 24 +- .../test/java}/bspkrs/testmod/TestMod.java | 24 +- .../bspkrs/testmod/TestModSimpleConfig.java | 0 testmod/bspkrs/testmod/ClientProxy.java | 13 - 29 files changed, 302 insertions(+), 920 deletions(-) create mode 100644 .gitattributes delete mode 100644 build.properties create mode 100644 gradle.properties delete mode 100644 src/main/java/bspkrs/bspkrscore/fml/BSCClientTicker.java delete mode 100644 src/main/java/bspkrs/bspkrscore/fml/CommandBS.java delete mode 100644 src/main/java/bspkrs/util/BSConfiguration.java delete mode 100644 src/main/java/bspkrs/util/ModVersionChecker.java create mode 100644 src/test/java/bspkrs/testmod/ClientProxy.java rename {testmod => src/test/java}/bspkrs/testmod/CommonProxy.java (100%) rename {testmod => src/test/java}/bspkrs/testmod/GuiTestModConfig.java (100%) rename {testmod => src/test/java}/bspkrs/testmod/ModGuiFactoryHandler.java (100%) rename {testmod => src/test/java}/bspkrs/testmod/TMTicker.java (56%) rename {testmod => src/test/java}/bspkrs/testmod/TestMod.java (62%) rename {testmod => src/test/java}/bspkrs/testmod/TestModSimpleConfig.java (100%) delete mode 100644 testmod/bspkrs/testmod/ClientProxy.java diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..a8e787c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,26 @@ +# default +* text eol=auto + +# git +.gitattributes text eol=lf +.gitignore text eol=lf + +# sources +*.java text eol=lf + +# resources +*.lang text eol=lf +*.cfg text eol=lf +*.info text eol=lf +*.mcmeta text eol=lf +*.md text eol=lf +*.xml text eol=lf + +# scripts +*.bat text eol=crlf +*.gradle text eol=lf +*.properties text eol=lf + +# binaries +*.png binary +*.jar binary diff --git a/.gitignore b/.gitignore index b9e8d82..418781a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,23 @@ -/.settings/ -/bin/ -/release/ -/build/ -/.gradle/ -/run/ -.project -.classpath -build.properties.old \ No newline at end of file +## gradle +/.gradle +/build + +## ForgeGradle +/run + +## eclipse +/.settings +/.metadata +/.classpath +/.project +/bin + +## intellij +/out +/.idea +/*.iml +/*.ipr +/*.iws + +## custom +/release diff --git a/build.gradle b/build.gradle index bee783c..b6b8158 100644 --- a/build.gradle +++ b/build.gradle @@ -1,44 +1,37 @@ buildscript { repositories { mavenCentral() + jcenter() maven { - name = "forge" - url = "http://files.minecraftforge.net/maven" + name = 'forge' + url = 'http://files.minecraftforge.net/maven' } maven { - name = "sonatype" - url = "https://oss.sonatype.org/content/repositories/snapshots/" + name = 'sonatype' + url = 'https://oss.sonatype.org/content/repositories/snapshots/' } } dependencies { - classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT' + classpath 'net.minecraftforge.gradle:ForgeGradle:2.1-SNAPSHOT' + classpath 'com.matthewprenger:CurseGradle:1.0-SNAPSHOT' } } -apply plugin: "forge" +apply plugin: 'net.minecraftforge.gradle.forge' +apply plugin: 'com.matthewprenger.cursegradle' compileJava.options.encoding = 'UTF-8' -// define the properties file -ext.configFile = file "build.properties" - -configFile.withReader { - // read config. it shall from now on be referenced as simply config or as project.config - def prop = new Properties() - prop.load(it) - project.ext.config = new ConfigSlurper().parse prop -} - -group = config.group_name -version = config.mod_version -archivesBaseName = "[${config.minecraft_version}]${config.mod_id}" +group = project.group_name +version = project.mod_version +archivesBaseName = "[${project.minecraft_version}]${project.mod_id}" minecraft { - version = config.minecraft_version + "-" + config.forge_version // grab latest forge - mappings = config.mappings_version - runDir = "run" - replace '@MOD_VERSION@', config.mod_version - replace '@MINECRAFT_VERSION@', config.minecraft_version + version = project.minecraft_version + '-' + project.forge_version // grab latest forge + mappings = project.mappings_version + runDir = 'run' + replace '@MOD_VERSION@', project.mod_version + replace '@MINECRAFT_VERSION@', project.minecraft_version } processResources { @@ -49,9 +42,9 @@ processResources { // replaces expand ([ - 'mod_version': config.mod_version, - 'forge_version': config.forge_version, - 'minecraft_version': config.minecraft_version, + 'mod_version': project.mod_version, + 'forge_version': project.forge_version, + 'minecraft_version': project.minecraft_version, ]) } @@ -64,22 +57,29 @@ processResources { // change the name of my obfuscated jar jar { - appendix = config.appendix + appendix = project.appendix } -// add a source jar -task sourceJar(type: Jar) { - from sourceSets.main.allSource +sourceJar { appendix = 'src' -} - -// because the normal output has been made to be obfuscated -task deobfJar(type: Jar) { - from sourceSets.main.output - appendix = 'deobf' + classifier = '' } artifacts { archives sourceJar - archives deobfJar -} \ No newline at end of file +} + +if (project.hasProperty('api_key_curse') && project.hasProperty('extra_curse_id')) { + tasks.curseforge.dependsOn signJars + curseforge { + apiKey = project.api_key_curse + + project { + id = project.extra_curse_id + changelog = '' + releaseType = project.hasProperty('extra_curse_releasetype') ? project.extra_curse_releasetype : 'release' + + addArtifact sourceJar + } + } +} diff --git a/build.properties b/build.properties deleted file mode 100644 index 5d78ac2..0000000 --- a/build.properties +++ /dev/null @@ -1,7 +0,0 @@ -minecraft_version=1.8 -forge_version=11.14.1.1334 -mappings_version=stable_16 -mod_version=7.01 -mod_id=bspkrsCore -group_name=bspkrscore -appendix=universal \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..3718fcf --- /dev/null +++ b/gradle.properties @@ -0,0 +1,10 @@ +minecraft_version=1.8.9 +forge_version=11.15.0.1719 +mappings_version=snapshot_20160125 +mod_version=1.8.9.1 +mod_id=bspkrsCore +group_name=bspkrscore +appendix=universal + +# extra_curse_id=-1 +# extra_curse_releasetype=release diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index b7612167031001b7b84baf2a959e8ea8ad03c011..941144813d241db74e1bf25b6804c679fbe7f0a3 100644 GIT binary patch delta 27722 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 Dt49Vb delta 25274 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 678d9d8..baf5d7e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Jul 02 15:54:47 CDT 2014 +#Tue Feb 02 17:03:16 CET 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.9-bin.zip diff --git a/gradlew b/gradlew index 91a7e26..9d82f78 100644 --- a/gradlew +++ b/gradlew @@ -42,11 +42,6 @@ case "`uname`" in ;; esac -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - # Attempt to set APP_HOME # Resolve links: $0 may be a link PRG="$0" @@ -61,9 +56,9 @@ while [ -h "$PRG" ] ; do fi done SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- +cd "`dirname \"$PRG\"`/" >/dev/null APP_HOME="`pwd -P`" -cd "$SAVED" >&- +cd "$SAVED" >/dev/null CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -114,6 +109,7 @@ fi if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` diff --git a/src/main/java/bspkrs/bspkrscore/fml/BSCClientTicker.java b/src/main/java/bspkrs/bspkrscore/fml/BSCClientTicker.java deleted file mode 100644 index 3e7dc46..0000000 --- a/src/main/java/bspkrs/bspkrscore/fml/BSCClientTicker.java +++ /dev/null @@ -1,61 +0,0 @@ -package bspkrs.bspkrscore.fml; - -import net.minecraft.client.Minecraft; -import net.minecraft.util.ChatComponentText; -import net.minecraftforge.fml.client.FMLClientHandler; -import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent; -import net.minecraftforge.fml.common.gameevent.TickEvent.Phase; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -public class BSCClientTicker -{ - public static boolean allowUpdateCheck = bspkrsCoreMod.instance.allowUpdateCheck; - private Minecraft mcClient; - public static boolean isRegistered = false; - - public BSCClientTicker() - { - if (!isRegistered) - { - mcClient = FMLClientHandler.instance().getClient(); - FMLCommonHandler.instance().bus().register(this); - isRegistered = true; - } - } - - @SubscribeEvent - public void onTick(ClientTickEvent event) - { - if (!event.phase.equals(Phase.START)) - { - boolean keepTicking = !(mcClient != null && mcClient.thePlayer != null && mcClient.theWorld != null); - - if (!keepTicking && isRegistered) - { - if (bspkrsCoreMod.instance.allowUpdateCheck && bspkrsCoreMod.instance.versionChecker != null) - if (!bspkrsCoreMod.instance.versionChecker.isCurrentVersion()) - for (String msg : bspkrsCoreMod.instance.versionChecker.getInGameMessage()) - mcClient.thePlayer.addChatMessage(new ChatComponentText(msg)); - - allowUpdateCheck = false; - - if (bspkrsCoreMod.instance.allowDebugOutput && !keepTicking && mcClient.theWorld.isRemote) - { - //EntityPlayerHelper.addChatMessage(mcClient.thePlayer, new ChatComponentText("\2470\2470\2471\2472\2473\2474\2475\2476\2477\247e\247f")); - } - - FMLCommonHandler.instance().bus().unregister(this); - isRegistered = false; - } - } - } - - public static boolean isRegistered() - { - return isRegistered; - } -} diff --git a/src/main/java/bspkrs/bspkrscore/fml/ClientProxy.java b/src/main/java/bspkrs/bspkrscore/fml/ClientProxy.java index 498b65f..1c8f479 100644 --- a/src/main/java/bspkrs/bspkrscore/fml/ClientProxy.java +++ b/src/main/java/bspkrs/bspkrscore/fml/ClientProxy.java @@ -8,8 +8,5 @@ public class ClientProxy extends CommonProxy { @Override protected void registerGameTickHandler() - { - if (BSCClientTicker.allowUpdateCheck) - new BSCClientTicker(); - } + {} } diff --git a/src/main/java/bspkrs/bspkrscore/fml/CommandBS.java b/src/main/java/bspkrs/bspkrscore/fml/CommandBS.java deleted file mode 100644 index 0d31993..0000000 --- a/src/main/java/bspkrs/bspkrscore/fml/CommandBS.java +++ /dev/null @@ -1,81 +0,0 @@ -package bspkrs.bspkrscore.fml; - -import java.util.ArrayList; -import java.util.List; - -import net.minecraft.command.CommandBase; -import net.minecraft.command.ICommandSender; -import net.minecraft.command.WrongUsageException; -import net.minecraft.util.BlockPos; -import net.minecraft.util.ChatComponentText; -import bspkrs.util.ModVersionChecker; - -@SuppressWarnings("unchecked") -public class CommandBS extends CommandBase -{ - @SuppressWarnings("rawtypes") - private static List version = new ArrayList(); - - static - { - version.add("version"); - } - - @Override - public String getCommandName() - { - return "bs"; - } - - @Override - public String getCommandUsage(ICommandSender sender) - { - return "commands.bs.usage"; - } - - @Override - public boolean canCommandSenderUseCommand(ICommandSender par1ICommandSender) - { - return true; - } - - @Override - public int getRequiredPermissionLevel() - { - return 1; - } - - @Override - public void processCommand(ICommandSender sender, String[] args) throws WrongUsageException - { - if (!bspkrsCoreMod.instance.allowUpdateCheck) - throw new WrongUsageException("commands.bs.disabled"); - - if (args.length != 2) - throw new WrongUsageException("commands.bs.usage"); - - if (!args[0].equalsIgnoreCase("version")) - throw new WrongUsageException("commands.bs.usage"); - - String[] message = ModVersionChecker.checkVersionForMod(args[1]); - - for (String s : message) - sender.addChatMessage(new ChatComponentText(s)); - } - - @SuppressWarnings("rawtypes") - @Override - public List addTabCompletionOptions(ICommandSender sender, String[] args, BlockPos pos) - { - return args.length == 2 ? getListOfStringsMatchingLastWord(args, ModVersionChecker.getVersionCheckerMap().keySet().toArray(new String[] {})) : args.length == 1 ? version : null; - } - - @Override - public int compareTo(Object object) - { - if (object instanceof CommandBase) - return this.getCommandName().compareTo(((CommandBase) object).getCommandName()); - - return 0; - } -} diff --git a/src/main/java/bspkrs/bspkrscore/fml/bspkrsCoreMod.java b/src/main/java/bspkrs/bspkrscore/fml/bspkrsCoreMod.java index cc19559..652b626 100644 --- a/src/main/java/bspkrs/bspkrscore/fml/bspkrsCoreMod.java +++ b/src/main/java/bspkrs/bspkrscore/fml/bspkrsCoreMod.java @@ -4,10 +4,9 @@ import java.util.ArrayList; import java.util.List; -import net.minecraftforge.client.ClientCommandHandler; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.config.Configuration; import net.minecraftforge.fml.client.event.ConfigChangedEvent.OnConfigChangedEvent; -import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.Mod.Instance; @@ -19,14 +18,11 @@ import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.event.FMLServerStartingEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; import bspkrs.util.CommonUtils; import bspkrs.util.Const; -import bspkrs.util.ModVersionChecker; import bspkrs.util.UniqueNameListGenerator; -@Mod(modid = Reference.MODID, name = Reference.NAME, version = "@MOD_VERSION@", useMetadata = true, guiFactory = Reference.GUI_FACTORY) +@Mod(modid = Reference.MODID, name = Reference.NAME, version = "@MOD_VERSION@", useMetadata = true, guiFactory = Reference.GUI_FACTORY, updateJSON = Const.VERSION_URL_BASE + Reference.MODID + Const.VERSION_URL_EXT) public class bspkrsCoreMod { // config stuff @@ -48,19 +44,9 @@ public class bspkrsCoreMod @SidedProxy(clientSide = Reference.PROXY_CLIENT, serverSide = Reference.PROXY_COMMON) public static CommonProxy proxy; - protected ModVersionChecker versionChecker; - protected final String versionURL = Const.VERSION_URL + "/Minecraft/" + Const.MCVERSION + "/bspkrsCore.version"; - protected final String mcfTopic = "http://www.minecraftforum.net/topic/1114612-"; - - @SideOnly(Side.CLIENT) - protected BSCClientTicker ticker; - private boolean isCommandRegistered; - @EventHandler public void preInit(FMLPreInitializationEvent event) { - metadata = event.getModMetadata(); - File file = event.getSuggestedConfigurationFile(); if (!CommonUtils.isObfuscatedEnv()) @@ -108,27 +94,12 @@ public void syncConfig() @EventHandler public void init(FMLInitializationEvent event) { - if (allowUpdateCheck) - { - versionChecker = new ModVersionChecker(Reference.MODID, metadata.version, versionURL, mcfTopic); - versionChecker.checkVersionWithLogging(); - } - if (event.getSide().isClient()) { - FMLCommonHandler.instance().bus().register(new NetworkHandler()); - try - { - ClientCommandHandler.instance.registerCommand(new CommandBS()); - isCommandRegistered = true; - } - catch (Throwable e) - { - isCommandRegistered = false; - } + MinecraftForge.EVENT_BUS.register(new NetworkHandler()); } - FMLCommonHandler.instance().bus().register(instance); + MinecraftForge.EVENT_BUS.register(instance); } @EventHandler @@ -141,8 +112,6 @@ public void postInit(FMLPostInitializationEvent event) @EventHandler public void serverStarting(FMLServerStartingEvent event) { - if (!isCommandRegistered) - event.registerServerCommand(new CommandBS()); } @SubscribeEvent diff --git a/src/main/java/bspkrs/client/util/HUDUtils.java b/src/main/java/bspkrs/client/util/HUDUtils.java index a7cc89e..1ac32f4 100644 --- a/src/main/java/bspkrs/client/util/HUDUtils.java +++ b/src/main/java/bspkrs/client/util/HUDUtils.java @@ -6,6 +6,7 @@ import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.WorldRenderer; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; import net.minecraft.item.Item; @@ -170,11 +171,11 @@ public static void drawTexturedModalRect(int x, int y, int u, int v, int width, float var8 = 0.00390625F; Tessellator tessellator = Tessellator.getInstance(); WorldRenderer worldRenderer = tessellator.getWorldRenderer(); - worldRenderer.startDrawingQuads(); - worldRenderer.addVertexWithUV((x + 0), (y + height), zLevel, ((u + 0) * var7), ((v + height) * var8)); - worldRenderer.addVertexWithUV((x + width), (y + height), zLevel, ((u + width) * var7), ((v + height) * var8)); - worldRenderer.addVertexWithUV((x + width), (y + 0), zLevel, ((u + width) * var7), ((v + 0) * var8)); - worldRenderer.addVertexWithUV((x + 0), (y + 0), zLevel, ((u + 0) * var7), ((v + 0) * var8)); + worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + worldRenderer.pos((x + 0), (y + height), zLevel).tex(((u + 0) * var7), ((v + height) * var8)).endVertex(); + worldRenderer.pos((x + width), (y + height), zLevel).tex(((u + width) * var7), ((v + height) * var8)).endVertex(); + worldRenderer.pos((x + width), (y + 0), zLevel).tex(((u + width) * var7), ((v + 0) * var8)).endVertex(); + worldRenderer.pos((x + 0), (y + 0), zLevel).tex(((u + 0) * var7), ((v + 0) * var8)).endVertex(); tessellator.draw(); } @@ -245,12 +246,15 @@ else if (itemStack.getItem().equals(Items.bow)) public static void renderQuad(Tessellator tessellator, int x, int y, int width, int height, int color) { WorldRenderer worldRenderer = tessellator.getWorldRenderer(); - worldRenderer.startDrawingQuads(); - worldRenderer.setColorOpaque_I(color); - worldRenderer.addVertex((x + 0), (y + 0), 0.0D); - worldRenderer.addVertex((x + 0), (y + height), 0.0D); - worldRenderer.addVertex((x + width), (y + height), 0.0D); - worldRenderer.addVertex((x + width), (y + 0), 0.0D); + worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR); + int a = (color >> 24) & 0xFF; + int r = (color >> 16) & 0xFF; + int g = (color >> 8) & 0xFF; + int b = (color >> 0) & 0xFF; + worldRenderer.pos(x + 0, y + 0, 0.0D).color(r, g, b, a).endVertex(); + worldRenderer.pos(x + 0, y + height, 0.0D).color(r, g, b, a).endVertex(); + worldRenderer.pos(x + width, y + height, 0.0D).color(r, g, b, a).endVertex(); + worldRenderer.pos(x + width, y + 0, 0.0D).color(r, g, b, a).endVertex(); tessellator.draw(); } diff --git a/src/main/java/bspkrs/fml/util/DelayedGuiDisplayTicker.java b/src/main/java/bspkrs/fml/util/DelayedGuiDisplayTicker.java index b8e2e76..da8d7c5 100644 --- a/src/main/java/bspkrs/fml/util/DelayedGuiDisplayTicker.java +++ b/src/main/java/bspkrs/fml/util/DelayedGuiDisplayTicker.java @@ -2,6 +2,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.client.FMLClientHandler; import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -19,7 +20,7 @@ public DelayedGuiDisplayTicker(int delayTicks, GuiScreen screen) this.delayTicks = delayTicks; this.mcClient = FMLClientHandler.instance().getClient(); this.screen = screen; - FMLCommonHandler.instance().bus().register(this); + MinecraftForge.EVENT_BUS.register(this); } @SubscribeEvent @@ -31,7 +32,7 @@ public void onTick(ClientTickEvent event) if (--delayTicks <= 0) { mcClient.displayGuiScreen(screen); - FMLCommonHandler.instance().bus().unregister(this); + MinecraftForge.EVENT_BUS.unregister(this); } } } diff --git a/src/main/java/bspkrs/fml/util/InputEventListener.java b/src/main/java/bspkrs/fml/util/InputEventListener.java index 1545ff5..a714cdc 100644 --- a/src/main/java/bspkrs/fml/util/InputEventListener.java +++ b/src/main/java/bspkrs/fml/util/InputEventListener.java @@ -4,6 +4,7 @@ import net.minecraft.client.settings.KeyBinding; +import net.minecraftforge.common.MinecraftForge; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; @@ -79,7 +80,7 @@ public static void unRegister(KeyBinding kb) { if (isRegistered(kb)) { - FMLCommonHandler.instance().bus().unregister(instances.get(kb)); + MinecraftForge.EVENT_BUS.unregister(instances.get(kb)); instances.remove(kb); } } diff --git a/src/main/java/bspkrs/util/BSConfiguration.java b/src/main/java/bspkrs/util/BSConfiguration.java deleted file mode 100644 index 96a8ea8..0000000 --- a/src/main/java/bspkrs/util/BSConfiguration.java +++ /dev/null @@ -1,227 +0,0 @@ -package bspkrs.util; - -import java.io.File; - -import net.minecraftforge.common.config.Configuration; -import net.minecraftforge.common.config.Property; - -/** - * This class offers advanced configurations capabilities, allowing to provide various categories for configuration variables. - */ -@Deprecated -public class BSConfiguration extends Configuration -{ - private final File fileRef; - - public BSConfiguration(File file) - { - super(file); - fileRef = file; - } - - @Override - public File getConfigFile() - { - return fileRef; - } - - /** - * Renames a property in a given category. - * - * @param category the category in which the property resides - * @param oldPropName the existing property name - * @param newPropName the - * @return true if the category and property exist, false otherwise - */ - @Override - public boolean renameProperty(String category, String oldPropName, String newPropName) - { - if (hasCategory(category)) - { - if (getCategory(category).containsKey(oldPropName) && !oldPropName.equalsIgnoreCase(newPropName)) - { - get(category, newPropName, getCategory(category).get(oldPropName).getString()); - getCategory(category).remove(oldPropName); - return true; - } - } - return false; - } - - /** - * Moves a property from one category to another. - * - * @param oldCategory the category the property currently resides in - * @param propName the name of the property to move - * @param newCategory the category the property should be moved to - * @return true if the old category and property exist, false otherwise - */ - @Override - public boolean moveProperty(String oldCategory, String propName, String newCategory) - { - if (hasCategory(oldCategory)) - { - if (getCategory(oldCategory).containsKey(propName)) - { - getCategory(newCategory).put(propName, getCategory(oldCategory).get(propName)); - return true; - } - } - return false; - } - - // public static void renameCtgy(Configuration config, String oldCtgy, String newCtgy) - // { - // if (!oldCtgy.equalsIgnoreCase(newCtgy)) - // { - // for (String prop : config.getCategory(oldCtgy).keySet()) - // config.get(newCtgy, prop, config.getCategory(oldCtgy).get(prop).getString()); - // - // Map> toAdd = new HashMap>(); - // - // for (String key : config.getCategoryNames()) - // if (key.contains(oldCtgy + ".")) - // { - // HashMap props = new HashMap(); - // for (String prop : config.getCategory(key).keySet()) - // props.put(prop, config.getCategory(key).get(prop).getString()); - // - // toAdd.put(newCtgy + key.substring(key.indexOf(".")), props); - // } - // - // for (String newName : toAdd.keySet()) - // for (String newProp : toAdd.get(newName).keySet()) - // config.get(newName, newProp, toAdd.get(newName).get(newProp)); - // - // //config.categories.remove(oldCtgy); - // } - // } - - /** - * Creates a string property. - * - * @param name Name of the property. - * @param category Category of the property. - * @param defaultValue Default value of the property. - * @param comment A brief description what the property does. - * @return The value of the new string property. - */ - @Override - public String getString(String name, String category, String defaultValue, String comment) - { - return getString(name, category, defaultValue, comment, new String[0]); - } - - /** - * Creates a string property. - * - * @param name Name of the property. - * @param category Category of the property. - * @param defaultValue Default value of the property. - * @param comment A brief description what the property does. - * @param validValues A list of valid values that this property can be set to. - * @return The value of the new string property. - */ - @Override - public String getString(String name, String category, String defaultValue, String comment, String[] validValues) - { - Property prop = this.get(category, name, defaultValue); - prop.comment = comment + " [default: " + defaultValue + "]"; - return prop.getString(); - } - - /** - * Creates a string list property. - * - * @param name Name of the property. - * @param category Category of the property. - * @param defaultValue Default value of the property. - * @param comment A brief description what the property does. - * @return The value of the new string property. - */ - @Override - public String[] getStringList(String name, String category, String[] defaultValues, String comment) - { - return getStringList(name, category, defaultValues, comment, new String[0]); - } - - /** - * Creates a string list property. - * - * @param name Name of the property. - * @param category Category of the property. - * @param defaultValue Default value of the property. - * @param comment A brief description what the property does. - * @return The value of the new string property. - */ - @Override - public String[] getStringList(String name, String category, String[] defaultValue, String comment, String[] validValues) - { - Property prop = this.get(category, name, defaultValue); - prop.comment = comment + " [default: " + defaultValue + "]"; - return prop.getStringList(); - } - - /** - * Creates a boolean property. - * - * @param name Name of the property. - * @param category Category of the property. - * @param defaultValue Default value of the property. - * @param comment A brief description what the property does. - * @return The value of the new boolean property. - */ - @Override - public boolean getBoolean(String name, String category, boolean defaultValue, String comment) - { - Property prop = this.get(category, name, defaultValue); - prop.comment = comment + " [default: " + defaultValue + "]"; - return prop.getBoolean(defaultValue); - } - - /** - * Creates a integer property. - * - * @param name Name of the property. - * @param category Category of the property. - * @param defaultValue Default value of the property. - * @param minValue Minimum value of the property. - * @param maxValue Maximum value of the property. - * @param comment A brief description what the property does. - * @return The value of the new integer property. - */ - @Override - public int getInt(String name, String category, int defaultValue, int minValue, int maxValue, String comment) - { - Property prop = this.get(category, name, defaultValue); - prop.comment = comment + " [range: " + minValue + " ~ " + maxValue + ", default: " + defaultValue + "]"; - return prop.getInt(defaultValue) < minValue ? minValue : (prop.getInt(defaultValue) > maxValue ? maxValue : prop.getInt(defaultValue)); - } - - /** - * Creates a float property. - * - * @param name Name of the property. - * @param category Category of the property. - * @param defaultValue Default value of the property. - * @param minValue Minimum value of the property. - * @param maxValue Maximum value of the property. - * @param comment A brief description what the property does. - * @return The value of the new float property. - */ - @Override - public float getFloat(String name, String category, float defaultValue, float minValue, float maxValue, String comment) - { - Property prop = this.get(category, name, Float.toString(defaultValue)); - prop.comment = comment + " [range: " + minValue + " ~ " + maxValue + ", default: " + defaultValue + "]"; - try - { - return Float.parseFloat(prop.getString()) < minValue ? minValue : (Float.parseFloat(prop.getString()) > maxValue ? maxValue : Float.parseFloat(prop.getString())); - } - catch (Exception e) - { - e.printStackTrace(); - } - return defaultValue; - } -} diff --git a/src/main/java/bspkrs/util/BlockID.java b/src/main/java/bspkrs/util/BlockID.java index 2983a05..85ca316 100644 --- a/src/main/java/bspkrs/util/BlockID.java +++ b/src/main/java/bspkrs/util/BlockID.java @@ -1,148 +1,150 @@ -package bspkrs.util; - -import net.minecraft.block.Block; -import net.minecraft.block.state.IBlockState; -import net.minecraft.util.BlockPos; -import net.minecraft.world.World; -import net.minecraftforge.fml.common.registry.GameData; - -public class BlockID -{ - public final String id; - public final int metadata; - - public BlockID(String id, int metadata) - { - this.id = id; - this.metadata = metadata; - } - - public BlockID(String block) - { - this(block, -1); - } - - public BlockID(Block block, int metadata) - { - this(GameData.getBlockRegistry().getNameForObject(block).toString(), metadata); - } - - public BlockID(Block block) - { - this(GameData.getBlockRegistry().getNameForObject(block).toString(), -1); - } - - public BlockID(Block block, IBlockState state) - { - this(block, block.getMetaFromState(state)); - } - - public BlockID(IBlockState state) - { - this(state.getBlock(), state); - } - - public BlockID(World world, BlockPos pos) - { - this(world.getBlockState(pos)); - } - - public BlockID(World world, BlockPos pos, int metadata) - { - this(world.getBlockState(pos).getBlock(), metadata); - } - - public boolean isValid() - { - return getBlock() != null; - } - - public Block getBlock() - { - return GameData.getBlockRegistry().getObject(id); - } - - public static BlockID parse(String format) - { - String id; - int metadata; - int metadataModulus = 0; - format = format.trim(); - int comma = format.indexOf(","); - int tilde = format.indexOf("~"); - if (tilde == -1) - tilde = format.indexOf("%"); - - if ((comma == -1) && (tilde != -1)) - throw new RuntimeException(String.format("ModulusBlockID format error: a \"~\" or \"%1$s\" was found, but no \",\" in format \"%2$s\". " + - "Expected format is \", %1$s \". EG: \"minecraft:log, 0 %1$s 4\".", "%", format)); - - if ((tilde != -1) && (comma > tilde)) - throw new RuntimeException(String.format("ModulusBlockID format error: a \"~\" or \"%1$s\" was found before a \",\" in format \"%2$s\". " + - "Expected format is \", %1$s \". EG: \"minecraft:log, 0 %1$s 4\".", "%", format)); - - if (tilde == -1) - tilde = format.length(); - - if (comma != -1) - id = format.substring(0, comma).trim(); - else - id = format.trim(); - - metadata = CommonUtils.parseInt(format.substring(comma + 1, tilde).trim(), -1); - if (tilde != format.length()) - metadataModulus = CommonUtils.parseInt(format.substring(tilde + 1, format.length()).trim(), 0); - - if ((metadata != -1) && (metadataModulus > 0)) - return new ModulusBlockID(id, metadata, metadataModulus); - else - return new BlockID(id, metadata); - } - - @Override - public BlockID clone() - { - return new BlockID(id, metadata); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) - return true; - - if (!(obj instanceof BlockID)) - return false; - - if ((((BlockID) obj).id != null) && !((BlockID) obj).id.equals(id)) - return false; - else if ((((BlockID) obj).id == null) && (id != null)) - return false; - - if (obj instanceof ModulusBlockID) - { - ModulusBlockID o = (ModulusBlockID) obj; - return (metadata % o.metadataModulus) == (o.metadata % o.metadataModulus); - } - else - { - BlockID o = (BlockID) obj; - if ((o.metadata == -1) || (metadata == -1)) - return true; - else - return metadata == o.metadata; - } - } - - @Override - public int hashCode() - { - return id.hashCode() * 37; - } - - @Override - public String toString() - { - return (metadata == -1 ? id : id + ", " + metadata); - } -} +package bspkrs.util; + +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.BlockPos; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; +import net.minecraftforge.fml.common.registry.GameData; + +@Deprecated // TODO: replace with a IBlockState implementation +public class BlockID +{ + public final String id; + public final int metadata; + + public BlockID(String id, int metadata) + { + this.id = id; + this.metadata = metadata; + } + + public BlockID(String block) + { + this(block, -1); + } + + public BlockID(Block block, int metadata) + { + this(GameData.getBlockRegistry().getNameForObject(block).toString(), metadata); + } + + public BlockID(Block block) + { + this(GameData.getBlockRegistry().getNameForObject(block).toString(), -1); + } + + public BlockID(Block block, IBlockState state) + { + this(block, block.getMetaFromState(state)); + } + + public BlockID(IBlockState state) + { + this(state.getBlock(), state); + } + + public BlockID(World world, BlockPos pos) + { + this(world.getBlockState(pos)); + } + + public BlockID(World world, BlockPos pos, int metadata) + { + this(world.getBlockState(pos).getBlock(), metadata); + } + + public boolean isValid() + { + return getBlock() != null; + } + + public Block getBlock() + { + return GameData.getBlockRegistry().getObject(new ResourceLocation(id)); + } + + public static BlockID parse(String format) + { + String id; + int metadata; + int metadataModulus = 0; + format = format.trim(); + int comma = format.indexOf(","); + int tilde = format.indexOf("~"); + if (tilde == -1) + tilde = format.indexOf("%"); + + if ((comma == -1) && (tilde != -1)) + throw new RuntimeException(String.format("ModulusBlockID format error: a \"~\" or \"%1$s\" was found, but no \",\" in format \"%2$s\". " + + "Expected format is \", %1$s \". EG: \"minecraft:log, 0 %1$s 4\".", "%", format)); + + if ((tilde != -1) && (comma > tilde)) + throw new RuntimeException(String.format("ModulusBlockID format error: a \"~\" or \"%1$s\" was found before a \",\" in format \"%2$s\". " + + "Expected format is \", %1$s \". EG: \"minecraft:log, 0 %1$s 4\".", "%", format)); + + if (tilde == -1) + tilde = format.length(); + + if (comma != -1) + id = format.substring(0, comma).trim(); + else + id = format.trim(); + + metadata = CommonUtils.parseInt(format.substring(comma + 1, tilde).trim(), -1); + if (tilde != format.length()) + metadataModulus = CommonUtils.parseInt(format.substring(tilde + 1, format.length()).trim(), 0); + + if ((metadata != -1) && (metadataModulus > 0)) + return new ModulusBlockID(id, metadata, metadataModulus); + else + return new BlockID(id, metadata); + } + + @Override + public BlockID clone() + { + return new BlockID(id, metadata); + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + + if (!(obj instanceof BlockID)) + return false; + + if ((((BlockID) obj).id != null) && !((BlockID) obj).id.equals(id)) + return false; + else if ((((BlockID) obj).id == null) && (id != null)) + return false; + + if (obj instanceof ModulusBlockID) + { + ModulusBlockID o = (ModulusBlockID) obj; + return (metadata % o.metadataModulus) == (o.metadata % o.metadataModulus); + } + else + { + BlockID o = (BlockID) obj; + if ((o.metadata == -1) || (metadata == -1)) + return true; + else + return metadata == o.metadata; + } + } + + @Override + public int hashCode() + { + return id.hashCode() * 37; + } + + @Override + public String toString() + { + return (metadata == -1 ? id : id + ", " + metadata); + } +} diff --git a/src/main/java/bspkrs/util/Const.java b/src/main/java/bspkrs/util/Const.java index ec70f0a..010bdd5 100644 --- a/src/main/java/bspkrs/util/Const.java +++ b/src/main/java/bspkrs/util/Const.java @@ -2,6 +2,7 @@ public class Const { - public static String MCVERSION = "@MINECRAFT_VERSION@"; - public static String VERSION_URL = "http://bspk.rs"; + public static final String MCVERSION = "@MINECRAFT_VERSION@"; + public static final String VERSION_URL_BASE = "http://bspk.rs/Minecraft/"; + public static final String VERSION_URL_EXT = ".json"; } diff --git a/src/main/java/bspkrs/util/ModVersionChecker.java b/src/main/java/bspkrs/util/ModVersionChecker.java deleted file mode 100644 index a4b603c..0000000 --- a/src/main/java/bspkrs/util/ModVersionChecker.java +++ /dev/null @@ -1,232 +0,0 @@ -package bspkrs.util; - -import java.io.File; -import java.net.URL; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.prefs.Preferences; - -import net.minecraft.util.StatCollector; -import bspkrs.bspkrscore.fml.bspkrsCoreMod; - -import com.google.common.collect.Ordering; - -/** - * This class retrieves a version string from a text file at a given URL and compares it against the locally provided version string. It - * uses a natural order comparator to determine if the remote version is newer than our local version. - * - * @author bspkrs - */ - -public class ModVersionChecker -{ - private static final Map versionCheckerMap = new HashMap(); - private URL versionURL; - private final String modID; - private String newVersion; - private final String currentVersion; - private String updateURL; - private String[] loadMsg; - private String[] inGameMsg; - private File trackerFile; - private File trackerDir; - private static Preferences versionCheckTracker; - private String lastNewVersionFound; - private final String CHECK_ERROR = "check_error"; - private final boolean errorDetected; - private int runsSinceLastMessage; - - public ModVersionChecker(String modID, String curVer, String versionURL, String updateURL, String[] loadMsg, String[] inGameMsg) - { - this(modID, curVer, versionURL, updateURL, loadMsg, inGameMsg, bspkrsCoreMod.instance.updateTimeoutMilliseconds); - } - - public ModVersionChecker(String modID, String curVer, String versionURL, String updateURL, String[] loadMsg, String[] inGameMsg, int timeoutMS) - { - this.modID = modID; - this.currentVersion = curVer; - this.updateURL = updateURL; - this.loadMsg = loadMsg; - this.inGameMsg = inGameMsg; - - try - { - if (versionURL.startsWith("http://dl.dropboxusercontent.com")) - versionURL = versionURL.replaceFirst("http", "https"); - - this.versionURL = new URL(versionURL); - BSLog.info("Initializing ModVersionChecker for mod %s", modID); - } - catch (Throwable e) - { - BSLog.warning("Error initializing ModVersionChecker for mod %s: %s", modID, e.getMessage()); - } - - String[] versionLines = CommonUtils.loadTextFromURL(this.versionURL, BSLog.INSTANCE.getLogger(), new String[] { CHECK_ERROR }, timeoutMS); - - if (versionLines.length == 0 || versionLines[0].trim().equals("")) - newVersion = CHECK_ERROR; - else - newVersion = versionLines[0].trim(); - - errorDetected = newVersion.equals(CHECK_ERROR); - - // Keep track of the versions we've seen to keep from nagging players with new version notifications beyond the first one - if (trackerDir == null) - { - trackerDir = new File(CommonUtils.getConfigDir() + "/bspkrsCore/"); - if (trackerDir.exists()) - { - trackerFile = new File(trackerDir, "ModVersionCheckerTracking.txt"); - trackerFile.delete(); - trackerDir.delete(); - } - - trackerDir = new File(CommonUtils.getConfigDir()); - trackerFile = new File(trackerDir, "bspkrs_ModVersionCheckerTracking.txt"); - if ((trackerFile.exists())) - trackerFile.delete(); - } - - if (versionCheckTracker == null) - versionCheckTracker = Preferences.userNodeForPackage(this.getClass()).node("modversiontracker" + Const.MCVERSION); - - if (!(new StringBuilder("@").append("MOD_VERSION@")).toString().equals(currentVersion) && !"${mod_version}".equals(currentVersion)) - { - lastNewVersionFound = versionCheckTracker.get(modID, currentVersion); - - if (lastNewVersionFound.equals("")) - lastNewVersionFound = currentVersion; - - runsSinceLastMessage = versionCheckTracker.node("runs_since_last_message").getInt(modID, 0); - - if (errorDetected) - newVersion = lastNewVersionFound; - - if (!errorDetected && !isCurrentVersion(lastNewVersionFound, newVersion)) - { - runsSinceLastMessage = 0; - lastNewVersionFound = newVersion; - } - else - runsSinceLastMessage = runsSinceLastMessage % 10; - - versionCheckTracker.node("runs_since_last_message").putInt(modID, runsSinceLastMessage + 1); - versionCheckTracker.put(modID, lastNewVersionFound); - } - - // Override instantiated updateURL with second line of version file if it exists and is non-blank - if (versionLines.length > 1 && versionLines[1].trim().length() != 0) - this.updateURL = versionLines[1]; - - setLoadMessage(loadMsg); - setInGameMessage(inGameMsg); - - versionCheckerMap.put(modID.toLowerCase(Locale.US), this); - } - - public ModVersionChecker(String modName, String oldVer, String versionURL, String updateURL) - { - this(modName, oldVer, versionURL, updateURL, - new String[] { "{modID} {oldVer} is out of date! Visit {updateURL} to download the latest release ({newVer})." }, - new String[] { "\247c{modID} {newVer} \247ris out! Download the latest from \247a{updateURL}\247r" }); - } - - public void checkVersionWithLogging() - { - if (!isCurrentVersion(currentVersion, newVersion)) - for (String msg : loadMsg) - BSLog.info(msg); - } - - public void setLoadMessage(String[] loadMsg) - { - this.loadMsg = loadMsg; - - for (int i = 0; i < this.loadMsg.length; i++) - this.loadMsg[i] = replaceAllTags(this.loadMsg[i]); - } - - public void setInGameMessage(String[] inGameMsg) - { - this.inGameMsg = inGameMsg; - - for (int i = 0; i < this.inGameMsg.length; i++) - this.inGameMsg[i] = replaceAllTags(this.inGameMsg[i]); - - } - - public String[] getLoadMessage() - { - return loadMsg; - } - - public String[] getInGameMessage() - { - return inGameMsg; - } - - public URL getVersionURL() - { - return versionURL; - } - - public String getNewVersion() - { - return newVersion; - } - - public String getCurrentVersion() - { - return currentVersion; - } - - public String getUpdateURL() - { - return updateURL; - } - - public static Map getVersionCheckerMap() - { - return versionCheckerMap; - } - - public boolean isCurrentVersion() - { - return errorDetected || isCurrentVersion(runsSinceLastMessage == 0 ? currentVersion : lastNewVersionFound, newVersion); - } - - public static boolean isCurrentVersion(String oldVer, String newVer) - { - return Ordering.natural().compare(oldVer, newVer) >= 0; - } - - private String replaceAllTags(String s) - { - return s.replace("{oldVer}", currentVersion).replace("{newVer}", newVersion).replace("{modID}", modID).replace("{updateURL}", updateURL); - } - - public static String[] checkVersionForMod(String modID) - { - String[] r = { "" }; - - if (versionCheckerMap.containsKey(modID.toLowerCase(Locale.US))) - { - ModVersionChecker versionChecker = versionCheckerMap.get(modID.toLowerCase(Locale.US)); - if (!versionChecker.errorDetected) - { - if (!isCurrentVersion(versionChecker.currentVersion, versionChecker.newVersion)) - r = versionChecker.getInGameMessage(); - else - r = new String[] { StatCollector.translateToLocalFormatted("bspkrs.modversionchecker.uptodate", versionChecker.modID) }; - } - else - r = new String[] { StatCollector.translateToLocalFormatted("bspkrs.modversionchecker.error", versionChecker.modID) }; - } - else - r = new String[] { StatCollector.translateToLocal("bspkrs.modversionchecker.invalidmodid") }; - - return r; - } -} diff --git a/src/main/java/bspkrs/util/ModulusBlockID.java b/src/main/java/bspkrs/util/ModulusBlockID.java index 187d4b6..dd9e8d0 100644 --- a/src/main/java/bspkrs/util/ModulusBlockID.java +++ b/src/main/java/bspkrs/util/ModulusBlockID.java @@ -5,6 +5,7 @@ import net.minecraft.util.BlockPos; import net.minecraft.world.World; +@Deprecated // TODO: replace with a IBlockState implementation public class ModulusBlockID extends BlockID { public final int metadataModulus; diff --git a/src/main/java/bspkrs/util/UniqueNameListGenerator.java b/src/main/java/bspkrs/util/UniqueNameListGenerator.java index 3c43426..cd22fed 100644 --- a/src/main/java/bspkrs/util/UniqueNameListGenerator.java +++ b/src/main/java/bspkrs/util/UniqueNameListGenerator.java @@ -45,7 +45,7 @@ public void run() listFile.createNewFile(); - PrintWriter out = new PrintWriter(new FileWriter(listFile)); + PrintWriter out = new PrintWriter(listFile, "UTF-8"); out.println("# generated by bspkrsCore " + new SimpleDateFormat("yyyyMMdd HH:mm:ss").format(new Date())); out.println(); diff --git a/src/test/java/bspkrs/testmod/ClientProxy.java b/src/test/java/bspkrs/testmod/ClientProxy.java new file mode 100644 index 0000000..c42bdd1 --- /dev/null +++ b/src/test/java/bspkrs/testmod/ClientProxy.java @@ -0,0 +1,9 @@ +package bspkrs.testmod; + +public class ClientProxy extends CommonProxy +{ + @Override + protected void registerTickHandler() + { + } +} diff --git a/testmod/bspkrs/testmod/CommonProxy.java b/src/test/java/bspkrs/testmod/CommonProxy.java similarity index 100% rename from testmod/bspkrs/testmod/CommonProxy.java rename to src/test/java/bspkrs/testmod/CommonProxy.java diff --git a/testmod/bspkrs/testmod/GuiTestModConfig.java b/src/test/java/bspkrs/testmod/GuiTestModConfig.java similarity index 100% rename from testmod/bspkrs/testmod/GuiTestModConfig.java rename to src/test/java/bspkrs/testmod/GuiTestModConfig.java diff --git a/testmod/bspkrs/testmod/ModGuiFactoryHandler.java b/src/test/java/bspkrs/testmod/ModGuiFactoryHandler.java similarity index 100% rename from testmod/bspkrs/testmod/ModGuiFactoryHandler.java rename to src/test/java/bspkrs/testmod/ModGuiFactoryHandler.java diff --git a/testmod/bspkrs/testmod/TMTicker.java b/src/test/java/bspkrs/testmod/TMTicker.java similarity index 56% rename from testmod/bspkrs/testmod/TMTicker.java rename to src/test/java/bspkrs/testmod/TMTicker.java index 1f63a8f..1b11289 100644 --- a/testmod/bspkrs/testmod/TMTicker.java +++ b/src/test/java/bspkrs/testmod/TMTicker.java @@ -3,6 +3,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.util.ChatComponentText; import bspkrs.bspkrscore.fml.bspkrsCoreMod; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.client.FMLClientHandler; import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -16,34 +17,19 @@ public class TMTicker { private Minecraft mcClient; private static boolean isRegistered = false; - + public TMTicker() { mcClient = FMLClientHandler.instance().getClient(); isRegistered = true; } - + @SubscribeEvent public void onTick(ClientTickEvent event) { - boolean keepTicking = !(mcClient != null && mcClient.thePlayer != null && mcClient.theWorld != null); - - if (!event.phase.equals(Phase.START)) - { - if (bspkrsCoreMod.instance.allowUpdateCheck && !keepTicking) - if (TestMod.instance.versionChecker != null) - if (!TestMod.instance.versionChecker.isCurrentVersion()) - for (String msg : TestMod.instance.versionChecker.getInGameMessage()) - mcClient.thePlayer.addChatMessage(new ChatComponentText(msg)); - - if (!keepTicking) - { - FMLCommonHandler.instance().bus().unregister(this); - isRegistered = false; - } - } + } - + public static boolean isRegistered() { return isRegistered; diff --git a/testmod/bspkrs/testmod/TestMod.java b/src/test/java/bspkrs/testmod/TestMod.java similarity index 62% rename from testmod/bspkrs/testmod/TestMod.java rename to src/test/java/bspkrs/testmod/TestMod.java index ae28180..8debe1b 100644 --- a/testmod/bspkrs/testmod/TestMod.java +++ b/src/test/java/bspkrs/testmod/TestMod.java @@ -1,8 +1,6 @@ package bspkrs.testmod; -import bspkrs.bspkrscore.fml.bspkrsCoreMod; import bspkrs.util.Const; -import bspkrs.util.ModVersionChecker; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.Mod.Instance; @@ -13,39 +11,27 @@ import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; @Mod(modid = "TestMod", name = "TestMod", version = "2.0", dependencies = "required-after:bspkrsCore", - guiFactory = "bspkrs.testmod.ModGuiFactoryHandler") + guiFactory = "bspkrs.testmod.ModGuiFactoryHandler", updateJSON = Const.VERSION_URL_BASE + "TestMod" + Const.VERSION_URL_EXT) public class TestMod { @Metadata(value = "TestMod") public static ModMetadata metadata; - + @Instance(value = "TestMod") public static TestMod instance; - + @SidedProxy(clientSide = "bspkrs.testmod.ClientProxy", serverSide = "bspkrs.testmod.CommonProxy") public static CommonProxy proxy; - - protected ModVersionChecker versionChecker; - private final String versionURL = Const.VERSION_URL + "/Minecraft/TestMod/testMod.version"; - private final String mcfTopic = "http://www.minecraftforum.net/topic/1114612-"; - + @EventHandler public void preInit(FMLPreInitializationEvent event) { - metadata = event.getModMetadata(); - TestModSimpleConfig.initConfig(event.getSuggestedConfigurationFile()); } - + @EventHandler public void init(FMLInitializationEvent event) { - if (bspkrsCoreMod.instance.allowUpdateCheck) - { - versionChecker = new ModVersionChecker(metadata.name, metadata.version, versionURL, mcfTopic); - versionChecker.checkVersionWithLogging(); - } - proxy.registerTickHandler(); } } diff --git a/testmod/bspkrs/testmod/TestModSimpleConfig.java b/src/test/java/bspkrs/testmod/TestModSimpleConfig.java similarity index 100% rename from testmod/bspkrs/testmod/TestModSimpleConfig.java rename to src/test/java/bspkrs/testmod/TestModSimpleConfig.java diff --git a/testmod/bspkrs/testmod/ClientProxy.java b/testmod/bspkrs/testmod/ClientProxy.java deleted file mode 100644 index 68ca03f..0000000 --- a/testmod/bspkrs/testmod/ClientProxy.java +++ /dev/null @@ -1,13 +0,0 @@ -package bspkrs.testmod; - -import net.minecraftforge.fml.common.FMLCommonHandler; - -public class ClientProxy extends CommonProxy -{ - @Override - protected void registerTickHandler() - { - if (!TMTicker.isRegistered()) - FMLCommonHandler.instance().bus().register(new TMTicker()); - } -}