From 8d2ab7aa7af774ff5d9584490863187bdabf569c Mon Sep 17 00:00:00 2001 From: Arcaratus Date: Fri, 12 Jun 2015 14:53:28 -0400 Subject: [PATCH 1/5] Small stuff --- .../api/items/interfaces/ILPGauge.java | 2 +- .../client/renderer/RitualDivinerRender.java | 3 +++ .../common/commands/CommandSN.java | 13 ++++++++++-- .../common/items/sigil/SigilOfMagnetism.java | 21 +++++++++++++++++-- .../tileEntity/TEImperfectRitualStone.java | 10 --------- .../assets/alchemicalwizardry/lang/en_US.lang | 1 + 6 files changed, 35 insertions(+), 15 deletions(-) delete mode 100644 src/main/java/WayofTime/alchemicalWizardry/common/tileEntity/TEImperfectRitualStone.java diff --git a/src/main/java/WayofTime/alchemicalWizardry/api/items/interfaces/ILPGauge.java b/src/main/java/WayofTime/alchemicalWizardry/api/items/interfaces/ILPGauge.java index 7607023f..b75815ca 100644 --- a/src/main/java/WayofTime/alchemicalWizardry/api/items/interfaces/ILPGauge.java +++ b/src/main/java/WayofTime/alchemicalWizardry/api/items/interfaces/ILPGauge.java @@ -4,5 +4,5 @@ import net.minecraft.item.ItemStack; public interface ILPGauge { - public boolean canSeeLPBar(ItemStack itemStack); + boolean canSeeLPBar(ItemStack itemStack); } diff --git a/src/main/java/WayofTime/alchemicalWizardry/client/renderer/RitualDivinerRender.java b/src/main/java/WayofTime/alchemicalWizardry/client/renderer/RitualDivinerRender.java index 31211814..94b0cfc1 100644 --- a/src/main/java/WayofTime/alchemicalWizardry/client/renderer/RitualDivinerRender.java +++ b/src/main/java/WayofTime/alchemicalWizardry/client/renderer/RitualDivinerRender.java @@ -1,5 +1,7 @@ package WayofTime.alchemicalWizardry.client.renderer; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import org.lwjgl.opengl.GL11; import WayofTime.alchemicalWizardry.ModBlocks; @@ -21,6 +23,7 @@ import net.minecraftforge.client.event.RenderWorldLastEvent; * Created in Scala by Alex-Hawks * Translated and implemented by Arcaratus */ +@SideOnly(Side.CLIENT) public class RitualDivinerRender { @SubscribeEvent diff --git a/src/main/java/WayofTime/alchemicalWizardry/common/commands/CommandSN.java b/src/main/java/WayofTime/alchemicalWizardry/common/commands/CommandSN.java index 8d7368e6..58451a17 100644 --- a/src/main/java/WayofTime/alchemicalWizardry/common/commands/CommandSN.java +++ b/src/main/java/WayofTime/alchemicalWizardry/common/commands/CommandSN.java @@ -71,8 +71,17 @@ public class CommandSN extends CommandBase } else if ("get".equalsIgnoreCase(astring[1])) { - int amount = SoulNetworkHandler.getCurrentEssence(owner); - func_152373_a(icommandsender, this, "commands.soulnetwork.get.success", amount, owner); + int currentEssence = SoulNetworkHandler.getCurrentEssence(owner); + func_152373_a(icommandsender, this, "commands.soulnetwork.get.success", currentEssence, owner); + } + else if ("fillMax".equalsIgnoreCase(astring[1])) + { + int currentEssence = SoulNetworkHandler.getCurrentEssence(owner); + int orbTier = SoulNetworkHandler.getCurrentMaxOrb(owner); + int maxForOrb = SoulNetworkHandler.getMaximumForOrbTier(orbTier); + int fillAmount = maxForOrb - currentEssence; + SoulNetworkHandler.addCurrentEssenceToMaximum(owner, fillAmount, fillAmount); + func_152373_a(icommandsender, this, "commands.soulnetwork.fillMax.success", owner); } else { diff --git a/src/main/java/WayofTime/alchemicalWizardry/common/items/sigil/SigilOfMagnetism.java b/src/main/java/WayofTime/alchemicalWizardry/common/items/sigil/SigilOfMagnetism.java index 2d152898..b0a899e1 100644 --- a/src/main/java/WayofTime/alchemicalWizardry/common/items/sigil/SigilOfMagnetism.java +++ b/src/main/java/WayofTime/alchemicalWizardry/common/items/sigil/SigilOfMagnetism.java @@ -6,6 +6,7 @@ import WayofTime.alchemicalWizardry.api.items.interfaces.ISigil; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.Entity; import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.item.EntityXPOrb; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -153,6 +154,7 @@ public class SigilOfMagnetism extends EnergyItems implements ArmourUpgrade, IHol float posY = (float) (par3Entity.posY - par3Entity.getEyeHeight()); float posZ = Math.round(par3Entity.posZ); List entities = par3EntityPlayer.worldObj.getEntitiesWithinAABB(EntityItem.class, AxisAlignedBB.getBoundingBox(posX - 0.5f, posY - 0.5f, posZ - 0.5f, posX + 0.5f, posY + 0.5f, posZ + 0.5f).expand(range, verticalRange, range)); + List xpOrbs = par3EntityPlayer.worldObj.getEntitiesWithinAABB(EntityXPOrb.class, AxisAlignedBB.getBoundingBox(posX - 0.5f, posY - 0.5f, posZ - 0.5f, posX + 0.5f, posY + 0.5f, posZ + 0.5f).expand(range, verticalRange, range)); for (EntityItem entity : entities) { @@ -161,9 +163,15 @@ public class SigilOfMagnetism extends EnergyItems implements ArmourUpgrade, IHol entity.onCollideWithPlayer(par3EntityPlayer); } } - } - return; + for (EntityXPOrb xpOrb : xpOrbs) + { + if (xpOrb != null && !par2World.isRemote) + { + xpOrb.onCollideWithPlayer(par3EntityPlayer); + } + } + } } @Override @@ -175,6 +183,7 @@ public class SigilOfMagnetism extends EnergyItems implements ArmourUpgrade, IHol float posY = (float) (player.posY - player.getEyeHeight()); float posZ = Math.round(player.posZ); List entities = player.worldObj.getEntitiesWithinAABB(EntityItem.class, AxisAlignedBB.getBoundingBox(posX - 0.5f, posY - 0.5f, posZ - 0.5f, posX + 0.5f, posY + 0.5f, posZ + 0.5f).expand(range, verticalRange, range)); + List xpOrbs = player.worldObj.getEntitiesWithinAABB(EntityXPOrb.class, AxisAlignedBB.getBoundingBox(posX - 0.5f, posY - 0.5f, posZ - 0.5f, posX + 0.5f, posY + 0.5f, posZ + 0.5f).expand(range, verticalRange, range)); for (EntityItem entity : entities) { @@ -183,6 +192,14 @@ public class SigilOfMagnetism extends EnergyItems implements ArmourUpgrade, IHol entity.onCollideWithPlayer(player); } } + + for (EntityXPOrb xpOrb : xpOrbs) + { + if (xpOrb != null && !world.isRemote) + { + xpOrb.onCollideWithPlayer(player); + } + } } @Override diff --git a/src/main/java/WayofTime/alchemicalWizardry/common/tileEntity/TEImperfectRitualStone.java b/src/main/java/WayofTime/alchemicalWizardry/common/tileEntity/TEImperfectRitualStone.java deleted file mode 100644 index a6b0404c..00000000 --- a/src/main/java/WayofTime/alchemicalWizardry/common/tileEntity/TEImperfectRitualStone.java +++ /dev/null @@ -1,10 +0,0 @@ -package WayofTime.alchemicalWizardry.common.tileEntity; - -import net.minecraft.tileentity.TileEntity; - -public class TEImperfectRitualStone extends TileEntity -{ - public TEImperfectRitualStone() - { - } -} diff --git a/src/main/resources/assets/alchemicalwizardry/lang/en_US.lang b/src/main/resources/assets/alchemicalwizardry/lang/en_US.lang index a3afbcd8..5436c4bc 100644 --- a/src/main/resources/assets/alchemicalwizardry/lang/en_US.lang +++ b/src/main/resources/assets/alchemicalwizardry/lang/en_US.lang @@ -296,6 +296,7 @@ commands.soulnetwork.get.success=There is %dLP in %s's Soul Network! commands.soulnetwork.noPlayer=There is no player specified commands.soulnetwork.noCommand=There is no command specified commands.soulnetwork.notACommand=That is not a valid command +commands.soulnetwork.fillMax.success=Successfully filled %s's Soul Network to their orb max! #Tooltips tooltip.activationcrystal.creativeonly=Creative Only - activates any ritual From 90b34056c108969aefe469b561acba5894f348b6 Mon Sep 17 00:00:00 2001 From: Arcaratus Date: Fri, 12 Jun 2015 15:11:56 -0400 Subject: [PATCH 2/5] Shtuff --- .../alchemicalWizardry/common/block/BlockTeleposer.java | 3 --- .../alchemicalWizardry/common/tileEntity/TETeleposer.java | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/WayofTime/alchemicalWizardry/common/block/BlockTeleposer.java b/src/main/java/WayofTime/alchemicalWizardry/common/block/BlockTeleposer.java index e969f1ba..de861321 100644 --- a/src/main/java/WayofTime/alchemicalWizardry/common/block/BlockTeleposer.java +++ b/src/main/java/WayofTime/alchemicalWizardry/common/block/BlockTeleposer.java @@ -78,7 +78,6 @@ public class BlockTeleposer extends BlockContainer @Override public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int idk, float what, float these, float are) { - TETeleposer tileEntity = (TETeleposer) world.getTileEntity(x, y, z); ItemStack playerItem = player.getCurrentEquippedItem(); if (playerItem != null) @@ -169,8 +168,6 @@ public class BlockTeleposer extends BlockContainer { TileEntity tileEntityI = worldI.getTileEntity(xi, yi, zi); TileEntity tileEntityF = worldF.getTileEntity(xf, yf, zf); - TileEntity tileI; - TileEntity tileF; NBTTagCompound nbttag1 = new NBTTagCompound(); NBTTagCompound nbttag2 = new NBTTagCompound(); diff --git a/src/main/java/WayofTime/alchemicalWizardry/common/tileEntity/TETeleposer.java b/src/main/java/WayofTime/alchemicalWizardry/common/tileEntity/TETeleposer.java index 1aacdfc5..57959fe8 100644 --- a/src/main/java/WayofTime/alchemicalWizardry/common/tileEntity/TETeleposer.java +++ b/src/main/java/WayofTime/alchemicalWizardry/common/tileEntity/TETeleposer.java @@ -94,7 +94,7 @@ public class TETeleposer extends TEInventory int zf = focusItem.zCoord(focus); World worldF = focusItem.getWorld(focus); int damage = (int) (0.5f * Math.sqrt((xCoord - xf) * (xCoord - xf) + (yCoord - yf + 1) * (yCoord - yf + 1) + (zCoord - zf) * (zCoord - zf))); - int focusLevel = ((TelepositionFocus) focusItem).getFocusLevel(); + int focusLevel = focusItem.getFocusLevel(); int transportCount = 0; int entityCount = 0; From 3efabb4e26e4f7c18e020520288170710a024c59 Mon Sep 17 00:00:00 2001 From: Arcaratus Date: Fri, 12 Jun 2015 21:37:40 -0400 Subject: [PATCH 3/5] Added in an auto-magic downloader for Guide-API --- build.properties | 8 +- .../AlchemicalWizardry.java | 5 +- .../common/thread/DepLoader.java | 608 ++++++++++++++++++ .../assets/alchemicalwizardry/lang/en_US.lang | 8 + src/main/resources/dependancies.info | 7 + 5 files changed, 628 insertions(+), 8 deletions(-) create mode 100644 src/main/java/WayofTime/alchemicalWizardry/common/thread/DepLoader.java create mode 100644 src/main/resources/dependancies.info diff --git a/build.properties b/build.properties index 5f9be8ce..1c9465d4 100644 --- a/build.properties +++ b/build.properties @@ -1,13 +1,13 @@ # -#Sat May 30 11:48:23 EDT 2015 +#Fri Jun 12 18:56:12 EDT 2015 mod_name=BloodMagic -forge_version=10.13.3.1374-1.7.10 +forge_version=10.13.4.1448-1.7.10 ccc_version=1.0.4.29 nei_version=1.0.3.64 //=Dependency Information -guideapi_version=1.0.1-19 +guideapi_version=1.0.1-20 package_group=com.wayoftime.bloodmagic mod_version=1.3.3 minetweaker_version=Dev-1.7.10-3.0.9B mc_version=1.7.10 -build_number=3 +build_number=5 diff --git a/src/main/java/WayofTime/alchemicalWizardry/AlchemicalWizardry.java b/src/main/java/WayofTime/alchemicalWizardry/AlchemicalWizardry.java index 51bb7759..926683f3 100644 --- a/src/main/java/WayofTime/alchemicalWizardry/AlchemicalWizardry.java +++ b/src/main/java/WayofTime/alchemicalWizardry/AlchemicalWizardry.java @@ -296,7 +296,6 @@ import cpw.mods.fml.common.registry.EntityRegistry; import cpw.mods.fml.common.registry.GameRegistry; @Mod(modid = "AWWayofTime", name = "AlchemicalWizardry", version = "v1.3.3", guiFactory = "WayofTime.alchemicalWizardry.client.gui.ConfigGuiFactory") - public class AlchemicalWizardry { public static boolean parseTextFiles = false; @@ -497,9 +496,7 @@ public class AlchemicalWizardry @EventHandler public void preInit(FMLPreInitializationEvent event) - { - - + { File bmDirectory = new File("config/BloodMagic/schematics"); if (!bmDirectory.exists() && bmDirectory.mkdirs()) diff --git a/src/main/java/WayofTime/alchemicalWizardry/common/thread/DepLoader.java b/src/main/java/WayofTime/alchemicalWizardry/common/thread/DepLoader.java new file mode 100644 index 00000000..20cdc3cc --- /dev/null +++ b/src/main/java/WayofTime/alchemicalWizardry/common/thread/DepLoader.java @@ -0,0 +1,608 @@ +package WayofTime.alchemicalWizardry.common.thread; + + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import cpw.mods.fml.common.versioning.ComparableVersion; +import cpw.mods.fml.relauncher.FMLLaunchHandler; +import cpw.mods.fml.relauncher.IFMLCallHook; +import cpw.mods.fml.relauncher.IFMLLoadingPlugin; + +import java.awt.*; +import java.io.Closeable; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.InterruptedIOException; +import java.lang.reflect.Field; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.net.URLConnection; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import javax.swing.JDialog; +import javax.swing.JEditorPane; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JProgressBar; +import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; +import net.minecraft.launchwrapper.LaunchClassLoader; +import sun.misc.URLClassPath; +import sun.net.util.URLUtil; + +public class DepLoader implements IFMLLoadingPlugin, IFMLCallHook +{ + private static ByteBuffer downloadBuffer = ByteBuffer.allocateDirect(8388608); + private static DepLoadInst inst; + + public interface IDownloadDisplay + { + void resetProgress(int paramInt); + + void setPokeThread(Thread paramThread); + + void updateProgress(int paramInt); + + boolean shouldStopIt(); + + void updateProgressString(String paramString, Object... paramVarArgs); + + Object makeDialog(); + + void showErrorDialog(String paramString1, String paramString2); + } + + public static class Downloader extends JOptionPane implements DepLoader.IDownloadDisplay + { + private JDialog container; + private JLabel currentActivity; + private JProgressBar progress; + boolean stopIt; + Thread pokeThread; + + public JDialog makeDialog() + { + return this.container; + } + + public void updateProgressString(String progressUpdate, Object... data) + { + if (this.currentActivity != null) { + this.currentActivity.setText(String.format(progressUpdate, data)); + } + } + + public void resetProgress(int sizeGuess) + { + if (this.progress != null) { + this.progress.getModel().setRangeProperties(0, 0, 0, sizeGuess, false); + } + } + + public void updateProgress(int fullLength) + { + if (this.progress != null) { + this.progress.getModel().setValue(fullLength); + } + } + + public void setPokeThread(Thread currentThread) + { + this.pokeThread = currentThread; + } + + public boolean shouldStopIt() + { + return this.stopIt; + } + + public void showErrorDialog(String name, String url) + { + JEditorPane ep = new JEditorPane("text/html", "CB's DepLoader was unable to download required library " + name + "
Check your internet connection and try restarting or download it manually from" + "
" + url + " and put it in your mods folder" + ""); + + ep.setEditable(false); + ep.setOpaque(false); + ep.addHyperlinkListener(new HyperlinkListener() + { + public void hyperlinkUpdate(HyperlinkEvent event) + { + try + { + if (event.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) { + Desktop.getDesktop().browse(event.getURL().toURI()); + } + } + catch (Exception e) {} + } + }); + JOptionPane.showMessageDialog(null, ep, "A download error has occured", 0); + } + } + + public static class DummyDownloader implements DepLoader.IDownloadDisplay + { + public void resetProgress(int sizeGuess) {} + + public void setPokeThread(Thread currentThread) {} + + public void updateProgress(int fullLength) {} + + public boolean shouldStopIt() + { + return false; + } + + public void updateProgressString(String string, Object... data) {} + + public Object makeDialog() + { + return null; + } + + public void showErrorDialog(String name, String url) {} + } + + public static class VersionedFile + { + public final Pattern pattern; + public final String filename; + public final ComparableVersion version; + public final String name; + + public VersionedFile(String filename, Pattern pattern) + { + this.pattern = pattern; + this.filename = filename; + Matcher m = pattern.matcher(filename); + if (m.matches()) + { + this.name = m.group(1); + this.version = new ComparableVersion(m.group(2)); + } + else + { + this.name = null; + this.version = null; + } + } + + public boolean matches() + { + return this.name != null; + } + } + + public static class Dependency + { + public String url; + public DepLoader.VersionedFile file; + public String existing; + public boolean coreLib; + + public Dependency(String url, DepLoader.VersionedFile file, boolean coreLib) + { + this.url = url; + this.file = file; + this.coreLib = coreLib; + } + } + + public static class DepLoadInst + { + private File modsDir; + private File v_modsDir; + private DepLoader.IDownloadDisplay downloadMonitor; + private JDialog popupWindow; + private Map depMap = new HashMap(); + private HashSet depSet = new HashSet(); + + public DepLoadInst() + { + String mcVer = (String)cpw.mods.fml.relauncher.FMLInjectionData.data()[4]; + File mcDir = (File)cpw.mods.fml.relauncher.FMLInjectionData.data()[6]; + + this.modsDir = new File(mcDir, "mods"); + this.v_modsDir = new File(mcDir, "mods/" + mcVer); + if (!this.v_modsDir.exists()) { + this.v_modsDir.mkdirs(); + } + } + + private void addClasspath(String name) + { + try + { + ((LaunchClassLoader)DepLoader.class.getClassLoader()).addURL(new File(this.v_modsDir, name).toURI().toURL()); + } + catch (MalformedURLException e) + { + throw new RuntimeException(e); + } + } + + private void deleteMod(File mod) + { + if (mod.delete()) { + return; + } + try + { + ClassLoader cl = DepLoader.class.getClassLoader(); + URL url = mod.toURI().toURL(); + Field f_ucp = URLClassLoader.class.getDeclaredField("ucp"); + Field f_loaders = URLClassPath.class.getDeclaredField("loaders"); + Field f_lmap = URLClassPath.class.getDeclaredField("lmap"); + f_ucp.setAccessible(true); + f_loaders.setAccessible(true); + f_lmap.setAccessible(true); + + URLClassPath ucp = (URLClassPath)f_ucp.get(cl); + Closeable loader = (Closeable)((Map)f_lmap.get(ucp)).remove(URLUtil.urlNoFragString(url)); + if (loader != null) + { + loader.close(); + ((List)f_loaders.get(ucp)).remove(loader); + } + } + catch (Exception e) + { + e.printStackTrace(); + } + if (!mod.delete()) + { + mod.deleteOnExit(); + String msg = "CB's DepLoader was unable to delete file " + mod.getPath() + " the game will now try to delete it on exit. If this dialog appears again, delete it manually."; + System.err.println(msg); + if (!GraphicsEnvironment.isHeadless()) { + JOptionPane.showMessageDialog(null, msg, "An update error has occured", 0); + } + System.exit(1); + } + } + + private void download(DepLoader.Dependency dep) + { + this.popupWindow = ((JDialog)this.downloadMonitor.makeDialog()); + File libFile = new File(this.v_modsDir, dep.file.filename); + try + { + URL libDownload = new URL(dep.url + '/' + dep.file.filename); + this.downloadMonitor.updateProgressString("Downloading file %s", libDownload.toString()); + System.out.format("Downloading file %s\n", libDownload.toString()); + URLConnection connection = libDownload.openConnection(); + connection.setConnectTimeout(5000); + connection.setReadTimeout(5000); + connection.setRequestProperty("User-Agent", "CB's DepLoader Downloader"); + int sizeGuess = connection.getContentLength(); + download(connection.getInputStream(), sizeGuess, libFile); + this.downloadMonitor.updateProgressString("Download complete", 0); + System.out.println("Download complete"); + + scanDepInfo(libFile); + } + catch (Exception e) + { + libFile.delete(); + if (this.downloadMonitor.shouldStopIt()) + { + System.err.println("You have stopped the downloading operation before it could complete"); + System.exit(1); + return; + } + this.downloadMonitor.showErrorDialog(dep.file.filename, dep.url + '/' + dep.file.filename); + throw new RuntimeException("A download error occured", e); + } + } + + private void download(InputStream is, int sizeGuess, File target) throws Exception + { + if (sizeGuess > DepLoader.downloadBuffer.capacity()) { + throw new Exception(String.format("The file %s is too large to be downloaded by CB's DepLoader - the download is invalid", new Object[] { target.getName() })); + } + DepLoader.downloadBuffer.clear(); + + int fullLength = 0; + + this.downloadMonitor.resetProgress(sizeGuess); + try + { + this.downloadMonitor.setPokeThread(Thread.currentThread()); + byte[] smallBuffer = new byte[1024]; + int bytesRead; + while ((bytesRead = is.read(smallBuffer)) >= 0) + { + DepLoader.downloadBuffer.put(smallBuffer, 0, bytesRead); + fullLength += bytesRead; + if (this.downloadMonitor.shouldStopIt()) { + break; + } + this.downloadMonitor.updateProgress(fullLength); + } + is.close(); + this.downloadMonitor.setPokeThread(null); + DepLoader.downloadBuffer.limit(fullLength); + DepLoader.downloadBuffer.position(0); + } + catch (InterruptedIOException e) + { + Thread.interrupted(); + throw new Exception("Stop"); + } + catch (IOException e) + { + throw e; + } + try + { + if (!target.exists()) { + target.createNewFile(); + } + DepLoader.downloadBuffer.position(0); + FileOutputStream fos = new FileOutputStream(target); + fos.getChannel().write(DepLoader.downloadBuffer); + fos.close(); + } + catch (Exception e) + { + throw e; + } + } + + private String checkExisting(DepLoader.Dependency dep) + { + for (File f : this.modsDir.listFiles()) + { + DepLoader.VersionedFile vfile = new DepLoader.VersionedFile(f.getName(), dep.file.pattern); + if ((vfile.matches()) && (vfile.name.equals(dep.file.name))) { + if (!f.renameTo(new File(this.v_modsDir, f.getName()))) { + deleteMod(f); + } + } + } + for (File f : this.v_modsDir.listFiles()) + { + DepLoader.VersionedFile vfile = new DepLoader.VersionedFile(f.getName(), dep.file.pattern); + if ((vfile.matches()) && (vfile.name.equals(dep.file.name))) + { + int cmp = vfile.version.compareTo(dep.file.version); + if (cmp < 0) + { + System.out.println("Deleted old version " + f.getName()); + deleteMod(f); + return null; + } + if (cmp > 0) + { + System.err.println("Warning: version of " + dep.file.name + ", " + vfile.version + " is newer than request " + dep.file.version); + return f.getName(); + } + return f.getName(); + } + } + return null; + } + + public void load() + { + scanDepInfos(); + if (this.depMap.isEmpty()) { + return; + } + loadDeps(); + activateDeps(); + } + + private void activateDeps() + { + for (DepLoader.Dependency dep : this.depMap.values()) { + if (dep.coreLib) { + addClasspath(dep.existing); + } + } + } + + private void loadDeps() + { + this.downloadMonitor = (FMLLaunchHandler.side().isClient() ? new DepLoader.Downloader() : new DepLoader.DummyDownloader()); + try + { + while (!this.depSet.isEmpty()) + { + Iterator it = this.depSet.iterator(); + DepLoader.Dependency dep = this.depMap.get(it.next()); + it.remove(); + load(dep); + } + } + finally + { + if (this.popupWindow != null) + { + this.popupWindow.setVisible(false); + this.popupWindow.dispose(); + } + } + } + + private void load(DepLoader.Dependency dep) + { + dep.existing = checkExisting(dep); + if ((dep.existing == null) && (dep.file.name.equalsIgnoreCase("guide-api"))) + { + download(dep); + dep.existing = dep.file.filename; + } + } + + private List modFiles() + { + List list = new LinkedList(); + list.addAll(Arrays.asList(this.modsDir.listFiles())); + list.addAll(Arrays.asList(this.v_modsDir.listFiles())); + return list; + } + + private void scanDepInfos() + { + for (File file : modFiles()) { + if ((file.getName().endsWith(".jar")) || (file.getName().endsWith(".zip"))) { + scanDepInfo(file); + } + } + } + + private void scanDepInfo(File file) + { + try + { + ZipFile zip = new ZipFile(file); + ZipEntry e = zip.getEntry("dependancies.info"); + if (e == null) { + e = zip.getEntry("dependencies.info"); + } + if (e != null) { + loadJSon(zip.getInputStream(e)); + } + zip.close(); + } + catch (Exception e) + { + System.err.println("Failed to load dependencies.info from " + file.getName() + " as JSON"); + e.printStackTrace(); + } + } + + private void loadJSon(InputStream input) throws IOException + { + InputStreamReader reader = new InputStreamReader(input); + JsonElement root = new JsonParser().parse(reader); + if (root.isJsonArray()) { + loadJSonArr(root); + } else { + loadJson(root.getAsJsonObject()); + } + reader.close(); + } + + private void loadJSonArr(JsonElement root) throws IOException + { + for (JsonElement node : root.getAsJsonArray()) { + loadJson(node.getAsJsonObject()); + } + } + + private void loadJson(JsonObject node) throws IOException + { + boolean obfuscated = ((LaunchClassLoader)DepLoader.class.getClassLoader()).getClassBytes("net.minecraft.world.World") == null; + + + + String testClass = node.get("class").getAsString(); + if (DepLoader.class.getResource("/" + testClass.replace('.', '/') + ".class") != null) { + return; + } + String repo = node.get("repo").getAsString(); + String filename = node.get("file").getAsString(); + if ((!obfuscated) && (node.has("dev"))) { + filename = node.get("dev").getAsString(); + } + boolean coreLib = (node.has("coreLib")) && (node.get("coreLib").getAsBoolean()); + + + Pattern pattern = null; + try + { + if (node.has("pattern")) { + pattern = Pattern.compile(node.get("pattern").getAsString()); + } + } + catch (PatternSyntaxException e) + { + System.err.println("Invalid filename pattern: " + node.get("pattern")); + e.printStackTrace(); + } + if (pattern == null) { + pattern = Pattern.compile("(\\w+).*?([\\d\\.]+)[-\\w]*\\.[^\\d]+"); + } + DepLoader.VersionedFile file = new DepLoader.VersionedFile(filename, pattern); + if (!file.matches()) { + throw new RuntimeException("Invalid filename format for dependency: " + filename); + } + addDep(new DepLoader.Dependency(repo, file, coreLib)); + } + + private void addDep(DepLoader.Dependency newDep) + { + if (mergeNew(this.depMap.get(newDep.file.name), newDep)) + { + this.depMap.put(newDep.file.name, newDep); + this.depSet.add(newDep.file.name); + } + } + + private boolean mergeNew(DepLoader.Dependency oldDep, DepLoader.Dependency newDep) + { + if (oldDep == null) { + return true; + } + DepLoader.Dependency newest = newDep.file.version.compareTo(oldDep.file.version) > 0 ? newDep : oldDep; + newest.coreLib = ((newDep.coreLib) || (oldDep.coreLib)); + + return newest == newDep; + } + } + + public static void load() + { + if (inst == null) + { + inst = new DepLoadInst(); + inst.load(); + } + } + + public String[] getASMTransformerClass() + { + return null; + } + + public String getModContainerClass() + { + return null; + } + + public String getSetupClass() + { + return getClass().getName(); + } + + public void injectData(Map data) {} + + public Void call() + { + load(); + + return null; + } + + public String getAccessTransformerClass() + { + return null; + } +} diff --git a/src/main/resources/assets/alchemicalwizardry/lang/en_US.lang b/src/main/resources/assets/alchemicalwizardry/lang/en_US.lang index e047c30c..e4e671fa 100644 --- a/src/main/resources/assets/alchemicalwizardry/lang/en_US.lang +++ b/src/main/resources/assets/alchemicalwizardry/lang/en_US.lang @@ -468,3 +468,11 @@ achievement.alchemicalwizardry:firstPrick=Your First Prick! achievement.alchemicalwizardry:firstPrick.desc=The first drop of life into the Altar... achievement.alchemicalwizardry:weakOrb=Faintly Glowing Red... achievement.alchemicalwizardry:weakOrb.desc=This orb will suffice...for now... + +#G-API Thread +bm.versioning.startingDownload=[{"text":"Starting download of %s Please do not remove your hard disk.", "color":"orange"}] +bm.versioning.doneDownloading=Finished downloading %s. Reload your game to update +bm.versioning.downloadMessage=[",{"text":"Download Guide-API","color":"red","hoverEvent":{"action":"show_text","value":{"text":"Click this to auto-magically download the latest version","color":"red"}},"clickEvent":{"action":"run_command","value":"/bloodmagic-download-g-api %version%"}},"] +bm.versioning.downloadedAlready=You have the latest version already, reload your game to update! +bm.versioning.downloadingAlready=It's downloading! Be patient! +bm.versioning.disabled=This feature is disabled. diff --git a/src/main/resources/dependancies.info b/src/main/resources/dependancies.info new file mode 100644 index 00000000..a47e1dbb --- /dev/null +++ b/src/main/resources/dependancies.info @@ -0,0 +1,7 @@ +{ + "repo": "http://tehnut.info/jenkins/job/Guide-API/lastSuccessfulBuild/artifact/build/libs/", + "file": "Guide-API-1.7.10-1.0.1-20.jar", + "dev": "Guide-API-1.7.10-1.0.1-20-deobf.jar", + "class": "amerifrance.guideapi.GuideAPI", + "version": "1.0.1.20" +} \ No newline at end of file From 4a3268332258629b9887fcfa75a466ca28ef1b96 Mon Sep 17 00:00:00 2001 From: Arcaratus Date: Fri, 12 Jun 2015 21:42:38 -0400 Subject: [PATCH 4/5] Update .lang --- .../resources/assets/alchemicalwizardry/lang/en_US.lang | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/main/resources/assets/alchemicalwizardry/lang/en_US.lang b/src/main/resources/assets/alchemicalwizardry/lang/en_US.lang index e4e671fa..e047c30c 100644 --- a/src/main/resources/assets/alchemicalwizardry/lang/en_US.lang +++ b/src/main/resources/assets/alchemicalwizardry/lang/en_US.lang @@ -468,11 +468,3 @@ achievement.alchemicalwizardry:firstPrick=Your First Prick! achievement.alchemicalwizardry:firstPrick.desc=The first drop of life into the Altar... achievement.alchemicalwizardry:weakOrb=Faintly Glowing Red... achievement.alchemicalwizardry:weakOrb.desc=This orb will suffice...for now... - -#G-API Thread -bm.versioning.startingDownload=[{"text":"Starting download of %s Please do not remove your hard disk.", "color":"orange"}] -bm.versioning.doneDownloading=Finished downloading %s. Reload your game to update -bm.versioning.downloadMessage=[",{"text":"Download Guide-API","color":"red","hoverEvent":{"action":"show_text","value":{"text":"Click this to auto-magically download the latest version","color":"red"}},"clickEvent":{"action":"run_command","value":"/bloodmagic-download-g-api %version%"}},"] -bm.versioning.downloadedAlready=You have the latest version already, reload your game to update! -bm.versioning.downloadingAlready=It's downloading! Be patient! -bm.versioning.disabled=This feature is disabled. From cf5a445fbb5bce22354280954197bf277c735c6d Mon Sep 17 00:00:00 2001 From: Arcaratus Date: Sat, 13 Jun 2015 17:46:48 -0400 Subject: [PATCH 5/5] Added in a Guide-API download command --- build.properties | 4 +- .../AlchemicalWizardry.java | 5 +- .../client/ClientProxy.java | 2 + .../common/thread/CommandDownloadGAPI.java | 38 ++ .../common/thread/DepLoader.java | 608 ------------------ .../common/thread/GAPIChecker.java | 113 ++++ .../common/thread/ThreadDownloadGAPI.java | 96 +++ src/main/resources/Guide-API-Version.info | 1 + .../assets/alchemicalwizardry/lang/en_US.lang | 9 + src/main/resources/dependancies.info | 7 - 10 files changed, 263 insertions(+), 620 deletions(-) create mode 100644 src/main/java/WayofTime/alchemicalWizardry/common/thread/CommandDownloadGAPI.java delete mode 100644 src/main/java/WayofTime/alchemicalWizardry/common/thread/DepLoader.java create mode 100644 src/main/java/WayofTime/alchemicalWizardry/common/thread/GAPIChecker.java create mode 100644 src/main/java/WayofTime/alchemicalWizardry/common/thread/ThreadDownloadGAPI.java create mode 100644 src/main/resources/Guide-API-Version.info delete mode 100644 src/main/resources/dependancies.info diff --git a/build.properties b/build.properties index 1c9465d4..a0bb5147 100644 --- a/build.properties +++ b/build.properties @@ -1,5 +1,3 @@ -# -#Fri Jun 12 18:56:12 EDT 2015 mod_name=BloodMagic forge_version=10.13.4.1448-1.7.10 ccc_version=1.0.4.29 @@ -9,5 +7,5 @@ guideapi_version=1.0.1-20 package_group=com.wayoftime.bloodmagic mod_version=1.3.3 minetweaker_version=Dev-1.7.10-3.0.9B -mc_version=1.7.10 build_number=5 +mc_version=1.7.10 diff --git a/src/main/java/WayofTime/alchemicalWizardry/AlchemicalWizardry.java b/src/main/java/WayofTime/alchemicalWizardry/AlchemicalWizardry.java index 926683f3..9f8800d0 100644 --- a/src/main/java/WayofTime/alchemicalWizardry/AlchemicalWizardry.java +++ b/src/main/java/WayofTime/alchemicalWizardry/AlchemicalWizardry.java @@ -11,6 +11,8 @@ import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; +import WayofTime.alchemicalWizardry.common.thread.CommandDownloadGAPI; +import WayofTime.alchemicalWizardry.common.thread.GAPIChecker; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.init.Blocks; import net.minecraft.init.Items; @@ -1266,8 +1268,6 @@ public class AlchemicalWizardry isBotaniaLoaded = Loader.isModLoaded("Botania"); isPneumaticCraftLoaded = Loader.isModLoaded("PneumaticCraft"); isFMPLoaded = Loader.isModLoaded("ForgeMultipart"); - - BloodMagicConfiguration.loadBlacklist(); BloodMagicConfiguration.blacklistRituals(); @@ -1918,5 +1918,6 @@ public class AlchemicalWizardry event.registerServerCommand(new CommandBind()); event.registerServerCommand(new CommandUnbind()); event.registerServerCommand(new CommandSN()); + event.registerServerCommand(new CommandDownloadGAPI()); } } diff --git a/src/main/java/WayofTime/alchemicalWizardry/client/ClientProxy.java b/src/main/java/WayofTime/alchemicalWizardry/client/ClientProxy.java index c0d488d2..0cb1c207 100644 --- a/src/main/java/WayofTime/alchemicalWizardry/client/ClientProxy.java +++ b/src/main/java/WayofTime/alchemicalWizardry/client/ClientProxy.java @@ -1,5 +1,6 @@ package WayofTime.alchemicalWizardry.client; +import WayofTime.alchemicalWizardry.common.thread.GAPIChecker; import net.minecraft.item.ItemBlock; import net.minecraft.world.World; import net.minecraftforge.client.MinecraftForgeClient; @@ -194,5 +195,6 @@ public class ClientProxy extends CommonProxy MinecraftForge.EVENT_BUS.register(ob); KeyBindings.init(); MinecraftForge.EVENT_BUS.register(new ScrollHelper()); + new GAPIChecker().init(); } } diff --git a/src/main/java/WayofTime/alchemicalWizardry/common/thread/CommandDownloadGAPI.java b/src/main/java/WayofTime/alchemicalWizardry/common/thread/CommandDownloadGAPI.java new file mode 100644 index 00000000..0c57dc79 --- /dev/null +++ b/src/main/java/WayofTime/alchemicalWizardry/common/thread/CommandDownloadGAPI.java @@ -0,0 +1,38 @@ +package WayofTime.alchemicalWizardry.common.thread; + +import net.minecraft.command.CommandBase; +import net.minecraft.command.ICommandSender; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.ChatStyle; +import net.minecraft.util.EnumChatFormatting; + +public class CommandDownloadGAPI extends CommandBase +{ + private static final boolean ENABLED = true; + + @Override + public String getCommandName() + { + return "bloodmagic-download-g-api"; + } + + @Override + public String getCommandUsage(ICommandSender var1) + { + return "/bloodmagic-download-g-api"; + } + + @Override + public void processCommand(ICommandSender var1, String[] var2) + { + if (!ENABLED) + var1.addChatMessage(new ChatComponentTranslation("bm.versioning.disabled").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); + + else + if (GAPIChecker.downloadedFile) + var1.addChatMessage(new ChatComponentTranslation("bm.versioning.downloadedAlready").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); + else if (GAPIChecker.startedDownload) + var1.addChatMessage(new ChatComponentTranslation("bm.versioning.downloadingAlready").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); + else new ThreadDownloadGAPI("Guide-API-1.7.10-" + GAPIChecker.onlineVersion + ".jar"); + } +} diff --git a/src/main/java/WayofTime/alchemicalWizardry/common/thread/DepLoader.java b/src/main/java/WayofTime/alchemicalWizardry/common/thread/DepLoader.java deleted file mode 100644 index 20cdc3cc..00000000 --- a/src/main/java/WayofTime/alchemicalWizardry/common/thread/DepLoader.java +++ /dev/null @@ -1,608 +0,0 @@ -package WayofTime.alchemicalWizardry.common.thread; - - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import cpw.mods.fml.common.versioning.ComparableVersion; -import cpw.mods.fml.relauncher.FMLLaunchHandler; -import cpw.mods.fml.relauncher.IFMLCallHook; -import cpw.mods.fml.relauncher.IFMLLoadingPlugin; - -import java.awt.*; -import java.io.Closeable; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.InterruptedIOException; -import java.lang.reflect.Field; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.net.URLConnection; -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; -import javax.swing.JDialog; -import javax.swing.JEditorPane; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JProgressBar; -import javax.swing.event.HyperlinkEvent; -import javax.swing.event.HyperlinkListener; -import net.minecraft.launchwrapper.LaunchClassLoader; -import sun.misc.URLClassPath; -import sun.net.util.URLUtil; - -public class DepLoader implements IFMLLoadingPlugin, IFMLCallHook -{ - private static ByteBuffer downloadBuffer = ByteBuffer.allocateDirect(8388608); - private static DepLoadInst inst; - - public interface IDownloadDisplay - { - void resetProgress(int paramInt); - - void setPokeThread(Thread paramThread); - - void updateProgress(int paramInt); - - boolean shouldStopIt(); - - void updateProgressString(String paramString, Object... paramVarArgs); - - Object makeDialog(); - - void showErrorDialog(String paramString1, String paramString2); - } - - public static class Downloader extends JOptionPane implements DepLoader.IDownloadDisplay - { - private JDialog container; - private JLabel currentActivity; - private JProgressBar progress; - boolean stopIt; - Thread pokeThread; - - public JDialog makeDialog() - { - return this.container; - } - - public void updateProgressString(String progressUpdate, Object... data) - { - if (this.currentActivity != null) { - this.currentActivity.setText(String.format(progressUpdate, data)); - } - } - - public void resetProgress(int sizeGuess) - { - if (this.progress != null) { - this.progress.getModel().setRangeProperties(0, 0, 0, sizeGuess, false); - } - } - - public void updateProgress(int fullLength) - { - if (this.progress != null) { - this.progress.getModel().setValue(fullLength); - } - } - - public void setPokeThread(Thread currentThread) - { - this.pokeThread = currentThread; - } - - public boolean shouldStopIt() - { - return this.stopIt; - } - - public void showErrorDialog(String name, String url) - { - JEditorPane ep = new JEditorPane("text/html", "CB's DepLoader was unable to download required library " + name + "
Check your internet connection and try restarting or download it manually from" + "
" + url + " and put it in your mods folder" + ""); - - ep.setEditable(false); - ep.setOpaque(false); - ep.addHyperlinkListener(new HyperlinkListener() - { - public void hyperlinkUpdate(HyperlinkEvent event) - { - try - { - if (event.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) { - Desktop.getDesktop().browse(event.getURL().toURI()); - } - } - catch (Exception e) {} - } - }); - JOptionPane.showMessageDialog(null, ep, "A download error has occured", 0); - } - } - - public static class DummyDownloader implements DepLoader.IDownloadDisplay - { - public void resetProgress(int sizeGuess) {} - - public void setPokeThread(Thread currentThread) {} - - public void updateProgress(int fullLength) {} - - public boolean shouldStopIt() - { - return false; - } - - public void updateProgressString(String string, Object... data) {} - - public Object makeDialog() - { - return null; - } - - public void showErrorDialog(String name, String url) {} - } - - public static class VersionedFile - { - public final Pattern pattern; - public final String filename; - public final ComparableVersion version; - public final String name; - - public VersionedFile(String filename, Pattern pattern) - { - this.pattern = pattern; - this.filename = filename; - Matcher m = pattern.matcher(filename); - if (m.matches()) - { - this.name = m.group(1); - this.version = new ComparableVersion(m.group(2)); - } - else - { - this.name = null; - this.version = null; - } - } - - public boolean matches() - { - return this.name != null; - } - } - - public static class Dependency - { - public String url; - public DepLoader.VersionedFile file; - public String existing; - public boolean coreLib; - - public Dependency(String url, DepLoader.VersionedFile file, boolean coreLib) - { - this.url = url; - this.file = file; - this.coreLib = coreLib; - } - } - - public static class DepLoadInst - { - private File modsDir; - private File v_modsDir; - private DepLoader.IDownloadDisplay downloadMonitor; - private JDialog popupWindow; - private Map depMap = new HashMap(); - private HashSet depSet = new HashSet(); - - public DepLoadInst() - { - String mcVer = (String)cpw.mods.fml.relauncher.FMLInjectionData.data()[4]; - File mcDir = (File)cpw.mods.fml.relauncher.FMLInjectionData.data()[6]; - - this.modsDir = new File(mcDir, "mods"); - this.v_modsDir = new File(mcDir, "mods/" + mcVer); - if (!this.v_modsDir.exists()) { - this.v_modsDir.mkdirs(); - } - } - - private void addClasspath(String name) - { - try - { - ((LaunchClassLoader)DepLoader.class.getClassLoader()).addURL(new File(this.v_modsDir, name).toURI().toURL()); - } - catch (MalformedURLException e) - { - throw new RuntimeException(e); - } - } - - private void deleteMod(File mod) - { - if (mod.delete()) { - return; - } - try - { - ClassLoader cl = DepLoader.class.getClassLoader(); - URL url = mod.toURI().toURL(); - Field f_ucp = URLClassLoader.class.getDeclaredField("ucp"); - Field f_loaders = URLClassPath.class.getDeclaredField("loaders"); - Field f_lmap = URLClassPath.class.getDeclaredField("lmap"); - f_ucp.setAccessible(true); - f_loaders.setAccessible(true); - f_lmap.setAccessible(true); - - URLClassPath ucp = (URLClassPath)f_ucp.get(cl); - Closeable loader = (Closeable)((Map)f_lmap.get(ucp)).remove(URLUtil.urlNoFragString(url)); - if (loader != null) - { - loader.close(); - ((List)f_loaders.get(ucp)).remove(loader); - } - } - catch (Exception e) - { - e.printStackTrace(); - } - if (!mod.delete()) - { - mod.deleteOnExit(); - String msg = "CB's DepLoader was unable to delete file " + mod.getPath() + " the game will now try to delete it on exit. If this dialog appears again, delete it manually."; - System.err.println(msg); - if (!GraphicsEnvironment.isHeadless()) { - JOptionPane.showMessageDialog(null, msg, "An update error has occured", 0); - } - System.exit(1); - } - } - - private void download(DepLoader.Dependency dep) - { - this.popupWindow = ((JDialog)this.downloadMonitor.makeDialog()); - File libFile = new File(this.v_modsDir, dep.file.filename); - try - { - URL libDownload = new URL(dep.url + '/' + dep.file.filename); - this.downloadMonitor.updateProgressString("Downloading file %s", libDownload.toString()); - System.out.format("Downloading file %s\n", libDownload.toString()); - URLConnection connection = libDownload.openConnection(); - connection.setConnectTimeout(5000); - connection.setReadTimeout(5000); - connection.setRequestProperty("User-Agent", "CB's DepLoader Downloader"); - int sizeGuess = connection.getContentLength(); - download(connection.getInputStream(), sizeGuess, libFile); - this.downloadMonitor.updateProgressString("Download complete", 0); - System.out.println("Download complete"); - - scanDepInfo(libFile); - } - catch (Exception e) - { - libFile.delete(); - if (this.downloadMonitor.shouldStopIt()) - { - System.err.println("You have stopped the downloading operation before it could complete"); - System.exit(1); - return; - } - this.downloadMonitor.showErrorDialog(dep.file.filename, dep.url + '/' + dep.file.filename); - throw new RuntimeException("A download error occured", e); - } - } - - private void download(InputStream is, int sizeGuess, File target) throws Exception - { - if (sizeGuess > DepLoader.downloadBuffer.capacity()) { - throw new Exception(String.format("The file %s is too large to be downloaded by CB's DepLoader - the download is invalid", new Object[] { target.getName() })); - } - DepLoader.downloadBuffer.clear(); - - int fullLength = 0; - - this.downloadMonitor.resetProgress(sizeGuess); - try - { - this.downloadMonitor.setPokeThread(Thread.currentThread()); - byte[] smallBuffer = new byte[1024]; - int bytesRead; - while ((bytesRead = is.read(smallBuffer)) >= 0) - { - DepLoader.downloadBuffer.put(smallBuffer, 0, bytesRead); - fullLength += bytesRead; - if (this.downloadMonitor.shouldStopIt()) { - break; - } - this.downloadMonitor.updateProgress(fullLength); - } - is.close(); - this.downloadMonitor.setPokeThread(null); - DepLoader.downloadBuffer.limit(fullLength); - DepLoader.downloadBuffer.position(0); - } - catch (InterruptedIOException e) - { - Thread.interrupted(); - throw new Exception("Stop"); - } - catch (IOException e) - { - throw e; - } - try - { - if (!target.exists()) { - target.createNewFile(); - } - DepLoader.downloadBuffer.position(0); - FileOutputStream fos = new FileOutputStream(target); - fos.getChannel().write(DepLoader.downloadBuffer); - fos.close(); - } - catch (Exception e) - { - throw e; - } - } - - private String checkExisting(DepLoader.Dependency dep) - { - for (File f : this.modsDir.listFiles()) - { - DepLoader.VersionedFile vfile = new DepLoader.VersionedFile(f.getName(), dep.file.pattern); - if ((vfile.matches()) && (vfile.name.equals(dep.file.name))) { - if (!f.renameTo(new File(this.v_modsDir, f.getName()))) { - deleteMod(f); - } - } - } - for (File f : this.v_modsDir.listFiles()) - { - DepLoader.VersionedFile vfile = new DepLoader.VersionedFile(f.getName(), dep.file.pattern); - if ((vfile.matches()) && (vfile.name.equals(dep.file.name))) - { - int cmp = vfile.version.compareTo(dep.file.version); - if (cmp < 0) - { - System.out.println("Deleted old version " + f.getName()); - deleteMod(f); - return null; - } - if (cmp > 0) - { - System.err.println("Warning: version of " + dep.file.name + ", " + vfile.version + " is newer than request " + dep.file.version); - return f.getName(); - } - return f.getName(); - } - } - return null; - } - - public void load() - { - scanDepInfos(); - if (this.depMap.isEmpty()) { - return; - } - loadDeps(); - activateDeps(); - } - - private void activateDeps() - { - for (DepLoader.Dependency dep : this.depMap.values()) { - if (dep.coreLib) { - addClasspath(dep.existing); - } - } - } - - private void loadDeps() - { - this.downloadMonitor = (FMLLaunchHandler.side().isClient() ? new DepLoader.Downloader() : new DepLoader.DummyDownloader()); - try - { - while (!this.depSet.isEmpty()) - { - Iterator it = this.depSet.iterator(); - DepLoader.Dependency dep = this.depMap.get(it.next()); - it.remove(); - load(dep); - } - } - finally - { - if (this.popupWindow != null) - { - this.popupWindow.setVisible(false); - this.popupWindow.dispose(); - } - } - } - - private void load(DepLoader.Dependency dep) - { - dep.existing = checkExisting(dep); - if ((dep.existing == null) && (dep.file.name.equalsIgnoreCase("guide-api"))) - { - download(dep); - dep.existing = dep.file.filename; - } - } - - private List modFiles() - { - List list = new LinkedList(); - list.addAll(Arrays.asList(this.modsDir.listFiles())); - list.addAll(Arrays.asList(this.v_modsDir.listFiles())); - return list; - } - - private void scanDepInfos() - { - for (File file : modFiles()) { - if ((file.getName().endsWith(".jar")) || (file.getName().endsWith(".zip"))) { - scanDepInfo(file); - } - } - } - - private void scanDepInfo(File file) - { - try - { - ZipFile zip = new ZipFile(file); - ZipEntry e = zip.getEntry("dependancies.info"); - if (e == null) { - e = zip.getEntry("dependencies.info"); - } - if (e != null) { - loadJSon(zip.getInputStream(e)); - } - zip.close(); - } - catch (Exception e) - { - System.err.println("Failed to load dependencies.info from " + file.getName() + " as JSON"); - e.printStackTrace(); - } - } - - private void loadJSon(InputStream input) throws IOException - { - InputStreamReader reader = new InputStreamReader(input); - JsonElement root = new JsonParser().parse(reader); - if (root.isJsonArray()) { - loadJSonArr(root); - } else { - loadJson(root.getAsJsonObject()); - } - reader.close(); - } - - private void loadJSonArr(JsonElement root) throws IOException - { - for (JsonElement node : root.getAsJsonArray()) { - loadJson(node.getAsJsonObject()); - } - } - - private void loadJson(JsonObject node) throws IOException - { - boolean obfuscated = ((LaunchClassLoader)DepLoader.class.getClassLoader()).getClassBytes("net.minecraft.world.World") == null; - - - - String testClass = node.get("class").getAsString(); - if (DepLoader.class.getResource("/" + testClass.replace('.', '/') + ".class") != null) { - return; - } - String repo = node.get("repo").getAsString(); - String filename = node.get("file").getAsString(); - if ((!obfuscated) && (node.has("dev"))) { - filename = node.get("dev").getAsString(); - } - boolean coreLib = (node.has("coreLib")) && (node.get("coreLib").getAsBoolean()); - - - Pattern pattern = null; - try - { - if (node.has("pattern")) { - pattern = Pattern.compile(node.get("pattern").getAsString()); - } - } - catch (PatternSyntaxException e) - { - System.err.println("Invalid filename pattern: " + node.get("pattern")); - e.printStackTrace(); - } - if (pattern == null) { - pattern = Pattern.compile("(\\w+).*?([\\d\\.]+)[-\\w]*\\.[^\\d]+"); - } - DepLoader.VersionedFile file = new DepLoader.VersionedFile(filename, pattern); - if (!file.matches()) { - throw new RuntimeException("Invalid filename format for dependency: " + filename); - } - addDep(new DepLoader.Dependency(repo, file, coreLib)); - } - - private void addDep(DepLoader.Dependency newDep) - { - if (mergeNew(this.depMap.get(newDep.file.name), newDep)) - { - this.depMap.put(newDep.file.name, newDep); - this.depSet.add(newDep.file.name); - } - } - - private boolean mergeNew(DepLoader.Dependency oldDep, DepLoader.Dependency newDep) - { - if (oldDep == null) { - return true; - } - DepLoader.Dependency newest = newDep.file.version.compareTo(oldDep.file.version) > 0 ? newDep : oldDep; - newest.coreLib = ((newDep.coreLib) || (oldDep.coreLib)); - - return newest == newDep; - } - } - - public static void load() - { - if (inst == null) - { - inst = new DepLoadInst(); - inst.load(); - } - } - - public String[] getASMTransformerClass() - { - return null; - } - - public String getModContainerClass() - { - return null; - } - - public String getSetupClass() - { - return getClass().getName(); - } - - public void injectData(Map data) {} - - public Void call() - { - load(); - - return null; - } - - public String getAccessTransformerClass() - { - return null; - } -} diff --git a/src/main/java/WayofTime/alchemicalWizardry/common/thread/GAPIChecker.java b/src/main/java/WayofTime/alchemicalWizardry/common/thread/GAPIChecker.java new file mode 100644 index 00000000..7b6da761 --- /dev/null +++ b/src/main/java/WayofTime/alchemicalWizardry/common/thread/GAPIChecker.java @@ -0,0 +1,113 @@ +package WayofTime.alchemicalWizardry.common.thread; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.TickEvent; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.*; + +import java.io.*; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +public class GAPIChecker +{ + public static boolean doneChecking = false; + public static String onlineVersion = ""; + public static boolean triedToWarnPlayer = false; + + public static boolean startedDownload = false; + public static boolean downloadedFile = false; + + private File modsDir; + + public void init() + { + FMLCommonHandler.instance().bus().register(this); + File mcDir = (File)cpw.mods.fml.relauncher.FMLInjectionData.data()[6]; + + this.modsDir = new File(mcDir, "mods"); + + scanDepInfos(); + } + + private void scanDepInfos() + { + for (File file : modFiles()) + { + if ((file.getName().endsWith(".jar")) && file.getName().contains("BloodMagic")) + { + scanDepInfo(file); + } + } + } + + private void scanDepInfo(File file) + { + try + { + ZipFile zip = new ZipFile(file); + ZipEntry e = zip.getEntry("Guide-API-Version.info"); + if (e == null) + { + e = zip.getEntry("Guide-API-Version.info"); + } + if (e != null) + { + readConfigFile(zip.getInputStream(e)); + } + zip.close(); + } + catch (Exception e) + { + System.err.println("Failed to load dependencies.info from " + file.getName() + " as JSON"); + e.printStackTrace(); + } + } + + private List modFiles() + { + List list = new LinkedList(); + list.addAll(Arrays.asList(this.modsDir.listFiles())); + return list; + } + + private void readConfigFile(InputStream inputStream) throws IOException + { + if (inputStream != null) + { + try + { + BufferedReader r = new BufferedReader(new InputStreamReader(inputStream)); + onlineVersion = r.readLine(); + doneChecking = true; + r.close(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + } + + @SubscribeEvent + public void onTick(TickEvent.ClientTickEvent event) + { + if (!Loader.isModLoaded("guideapi")) + { + if (event.phase == TickEvent.Phase.END && Minecraft.getMinecraft().thePlayer != null && !triedToWarnPlayer) + { + EntityPlayer player = Minecraft.getMinecraft().thePlayer; + IChatComponent component = IChatComponent.Serializer.func_150699_a(StatCollector.translateToLocal("bm.versioning.getGAPI")); + player.addChatComponentMessage(component); + } + + triedToWarnPlayer = true; + } + } +} diff --git a/src/main/java/WayofTime/alchemicalWizardry/common/thread/ThreadDownloadGAPI.java b/src/main/java/WayofTime/alchemicalWizardry/common/thread/ThreadDownloadGAPI.java new file mode 100644 index 00000000..cb390250 --- /dev/null +++ b/src/main/java/WayofTime/alchemicalWizardry/common/thread/ThreadDownloadGAPI.java @@ -0,0 +1,96 @@ +package WayofTime.alchemicalWizardry.common.thread; + +import net.minecraft.client.Minecraft; +import net.minecraft.util.*; +import net.minecraftforge.common.MinecraftForge; + +import java.awt.*; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +public class ThreadDownloadGAPI extends Thread +{ + String fileName; + + byte[] buffer = new byte[10240]; + + int totalBytesDownloaded; + int bytesJustDownloaded; + + InputStream webReader; + + public ThreadDownloadGAPI(String fileName) + { + setName("Blood Magic Download Guide-API Thread"); + this.fileName = fileName; + setDaemon(true); + start(); + } + + @Override + public void run() + { + try + { + IChatComponent component = IChatComponent.Serializer.func_150699_a(String.format(StatCollector.translateToLocal("bm.versioning.startingDownload"), fileName)); + + if (Minecraft.getMinecraft().thePlayer != null) + { + Minecraft.getMinecraft().thePlayer.addChatMessage(component); + } + + GAPIChecker.startedDownload = true; + + String base = "http://minecraft.curseforge.com/mc-mods/228832-guide-api"; + URL url = new URL(base + "/files/latest"); + + try + { + url.openStream().close(); // Add to DL Counter + } + catch(IOException e) {} + + webReader = url.openStream(); + + File dir = new File(".", "mods"); + File f = new File(dir, "Guide-API-" + MinecraftForge.MC_VERSION + "-" + GAPIChecker.onlineVersion + ".jar"); + f.createNewFile(); + + FileOutputStream outputStream = new FileOutputStream(f.getAbsolutePath()); + + while ((bytesJustDownloaded = webReader.read(buffer)) > 0) + { + outputStream.write(buffer, 0, bytesJustDownloaded); + buffer = new byte[10240]; + totalBytesDownloaded += bytesJustDownloaded; + } + + if (Minecraft.getMinecraft().thePlayer != null) + { + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentTranslation("bm.versioning.doneDownloading", fileName).setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GREEN))); + } + + Desktop.getDesktop().open(dir); + GAPIChecker.downloadedFile = true; + + outputStream.close(); + webReader.close(); + finalize(); + } + catch (Throwable e) + { + e.printStackTrace(); + } + } + + private void sendError() + { + if (Minecraft.getMinecraft().thePlayer != null) + { + Minecraft.getMinecraft().thePlayer.addChatComponentMessage(new ChatComponentTranslation("bm.versioning.error").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); + } + } +} diff --git a/src/main/resources/Guide-API-Version.info b/src/main/resources/Guide-API-Version.info new file mode 100644 index 00000000..457dcccf --- /dev/null +++ b/src/main/resources/Guide-API-Version.info @@ -0,0 +1 @@ +1.0.1-20 \ No newline at end of file diff --git a/src/main/resources/assets/alchemicalwizardry/lang/en_US.lang b/src/main/resources/assets/alchemicalwizardry/lang/en_US.lang index e047c30c..3dbec0b8 100644 --- a/src/main/resources/assets/alchemicalwizardry/lang/en_US.lang +++ b/src/main/resources/assets/alchemicalwizardry/lang/en_US.lang @@ -468,3 +468,12 @@ achievement.alchemicalwizardry:firstPrick=Your First Prick! achievement.alchemicalwizardry:firstPrick.desc=The first drop of life into the Altar... achievement.alchemicalwizardry:weakOrb=Faintly Glowing Red... achievement.alchemicalwizardry:weakOrb.desc=This orb will suffice...for now... + +#G-API Downloading +bm.versioning.getGAPI=["[BM] You don't have Guide-API installed! Install it to get it to unlock the book! [",{"text":"Download","color":"red","hoverEvent":{"action":"show_text","value":{"text":"Click this to auto-magically download the latest version","color":"red"}},"clickEvent":{"action":"run_command","value":"/bloodmagic-download-g-api"}},"]"] +bm.versioning.startingDownload=[{"text":"Starting download of %s Please do not remove your hard disk.", "color":"orange"}] +bm.versioning.doneDownloading=Finished downloading %s Reload your game to update. +bm.versioning.error=An error has occurred while downloading the mod! +bm.versioning.downloadedAlready=You have the latest version already, reload your game to update! +bm.versioning.downloadingAlready=It's downloading! Be patient! +bm.versioning.disabled=This feature is disabled. diff --git a/src/main/resources/dependancies.info b/src/main/resources/dependancies.info deleted file mode 100644 index a47e1dbb..00000000 --- a/src/main/resources/dependancies.info +++ /dev/null @@ -1,7 +0,0 @@ -{ - "repo": "http://tehnut.info/jenkins/job/Guide-API/lastSuccessfulBuild/artifact/build/libs/", - "file": "Guide-API-1.7.10-1.0.1-20.jar", - "dev": "Guide-API-1.7.10-1.0.1-20-deobf.jar", - "class": "amerifrance.guideapi.GuideAPI", - "version": "1.0.1.20" -} \ No newline at end of file