From c590609db20882e3772b3e2557b66ce4982eb055 Mon Sep 17 00:00:00 2001 From: DarkGuardsman Date: Mon, 23 Sep 2013 10:59:10 -0400 Subject: [PATCH] Working on a way to load mod dependencies Based off chicken bone's core mod. --- .../core/item/ItemElectric.java | 230 +++--- resources/MANIFEST.MF | 2 + resources/dependancies.info | 8 + src/dark/core/DarkCoreModContainer.java | 66 ++ src/dark/core/DarkCorePlugin.java | 65 ++ src/dark/core/DepLoader.java | 678 ++++++++++++++++++ .../common/machines/BlockBasicMachine.java | 50 +- .../core/prefab/machine/BlockMachine.java | 12 +- 8 files changed, 960 insertions(+), 151 deletions(-) create mode 100644 resources/MANIFEST.MF create mode 100644 resources/dependancies.info create mode 100644 src/dark/core/DarkCoreModContainer.java create mode 100644 src/dark/core/DarkCorePlugin.java create mode 100644 src/dark/core/DepLoader.java diff --git a/APIs/universalelectricity/core/item/ItemElectric.java b/APIs/universalelectricity/core/item/ItemElectric.java index 2d4d2b1a..a281c465 100644 --- a/APIs/universalelectricity/core/item/ItemElectric.java +++ b/APIs/universalelectricity/core/item/ItemElectric.java @@ -6,146 +6,144 @@ import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagDouble; +import net.minecraft.nbt.NBTTagFloat; import net.minecraft.world.World; import universalelectricity.core.electricity.ElectricityDisplay; import universalelectricity.core.electricity.ElectricityDisplay.ElectricUnit; -/** - * Extend from this class if your item requires electricity or to be charged. Optionally, you can +/** Extend from this class if your item requires electricity or to be charged. Optionally, you can * implement IItemElectric instead. - * - * @author Calclavia - * - */ + * + * @author Calclavia */ public abstract class ItemElectric extends Item implements IItemElectric { - public ItemElectric(int id) - { - super(id); - this.setMaxStackSize(1); - this.setMaxDamage(100); - this.setNoRepair(); - } + public ItemElectric(int id) + { + super(id); + this.setMaxStackSize(1); + this.setMaxDamage(100); + this.setNoRepair(); + } - @Override - public void addInformation(ItemStack itemStack, EntityPlayer entityPlayer, List list, boolean par4) - { - String color = ""; - float joules = this.getElectricityStored(itemStack); + @Override + public void addInformation(ItemStack itemStack, EntityPlayer entityPlayer, List list, boolean par4) + { + String color = ""; + float joules = this.getElectricityStored(itemStack); - if (joules <= this.getMaxElectricityStored(itemStack) / 3) - { - color = "\u00a74"; - } - else if (joules > this.getMaxElectricityStored(itemStack) * 2 / 3) - { - color = "\u00a72"; - } - else - { - color = "\u00a76"; - } + if (joules <= this.getMaxElectricityStored(itemStack) / 3) + { + color = "\u00a74"; + } + else if (joules > this.getMaxElectricityStored(itemStack) * 2 / 3) + { + color = "\u00a72"; + } + else + { + color = "\u00a76"; + } - list.add(color + ElectricityDisplay.getDisplayShort(joules, ElectricUnit.JOULES) + "/" + ElectricityDisplay.getDisplayShort(this.getMaxElectricityStored(itemStack), ElectricUnit.JOULES)); - } + list.add(color + ElectricityDisplay.getDisplayShort(joules, ElectricUnit.JOULES) + "/" + ElectricityDisplay.getDisplayShort(this.getMaxElectricityStored(itemStack), ElectricUnit.JOULES)); + } - /** - * Makes sure the item is uncharged when it is crafted and not charged. Change this if you do - * not want this to happen! - */ - @Override - public void onCreated(ItemStack itemStack, World par2World, EntityPlayer par3EntityPlayer) - { - this.setElectricity(itemStack, 0); - } + /** Makes sure the item is uncharged when it is crafted and not charged. Change this if you do + * not want this to happen! */ + @Override + public void onCreated(ItemStack itemStack, World par2World, EntityPlayer par3EntityPlayer) + { + this.setElectricity(itemStack, 0); + } - @Override - public float recharge(ItemStack itemStack, float energy, boolean doReceive) - { - float rejectedElectricity = Math.max((this.getElectricityStored(itemStack) + energy) - this.getMaxElectricityStored(itemStack), 0); - float energyToReceive = energy - rejectedElectricity; + @Override + public float recharge(ItemStack itemStack, float energy, boolean doReceive) + { + float rejectedElectricity = Math.max((this.getElectricityStored(itemStack) + energy) - this.getMaxElectricityStored(itemStack), 0); + float energyToReceive = energy - rejectedElectricity; - if (doReceive) - { - this.setElectricity(itemStack, this.getElectricityStored(itemStack) + energyToReceive); - } + if (doReceive) + { + this.setElectricity(itemStack, this.getElectricityStored(itemStack) + energyToReceive); + } - return energyToReceive; - } + return energyToReceive; + } - @Override - public float discharge(ItemStack itemStack, float energy, boolean doTransfer) - { - float energyToTransfer = Math.min(this.getElectricityStored(itemStack), energy); + @Override + public float discharge(ItemStack itemStack, float energy, boolean doTransfer) + { + float energyToTransfer = Math.min(this.getElectricityStored(itemStack), energy); - if (doTransfer) - { - this.setElectricity(itemStack, this.getElectricityStored(itemStack) - energyToTransfer); - } + if (doTransfer) + { + this.setElectricity(itemStack, this.getElectricityStored(itemStack) - energyToTransfer); + } - return energyToTransfer; - } + return energyToTransfer; + } - @Override - public float getVoltage(ItemStack itemStack) - { - return 120; - } + @Override + public float getVoltage(ItemStack itemStack) + { + return 0.120f; + } - @Override - public void setElectricity(ItemStack itemStack, float joules) - { - // Saves the frequency in the ItemStack - if (itemStack.getTagCompound() == null) - { - itemStack.setTagCompound(new NBTTagCompound()); - } + @Override + public void setElectricity(ItemStack itemStack, float joules) + { + // Saves the frequency in the ItemStack + if (itemStack.getTagCompound() == null) + { + itemStack.setTagCompound(new NBTTagCompound()); + } - float electricityStored = Math.max(Math.min(joules, this.getMaxElectricityStored(itemStack)), 0); - itemStack.getTagCompound().setFloat("electricity", electricityStored); + float electricityStored = Math.max(Math.min(joules, this.getMaxElectricityStored(itemStack)), 0); + itemStack.getTagCompound().setFloat("electricity", electricityStored); - /** - * Sets the damage as a percentage to render the bar properly. - */ - itemStack.setItemDamage((int) (100 - (electricityStored / getMaxElectricityStored(itemStack)) * 100)); - } + /** Sets the damage as a percentage to render the bar properly. */ + itemStack.setItemDamage((int) (100 - (electricityStored / getMaxElectricityStored(itemStack)) * 100)); + } - @Override - public float getTransfer(ItemStack itemStack) - { - return this.getMaxElectricityStored(itemStack) - this.getElectricityStored(itemStack); - } + @Override + public float getTransfer(ItemStack itemStack) + { + return this.getMaxElectricityStored(itemStack) - this.getElectricityStored(itemStack); + } - /** - * This function is called to get the electricity stored in this item - * - * @return - The amount of electricity stored in watts - */ - @Override - public float getElectricityStored(ItemStack itemStack) - { - if (itemStack.getTagCompound() == null) - { - itemStack.setTagCompound(new NBTTagCompound()); - } + /** Gets the energy stored in the item. Energy is stored using item NBT */ + @Override + public float getElectricityStored(ItemStack itemStack) + { + if (itemStack.getTagCompound() == null) + { + itemStack.setTagCompound(new NBTTagCompound()); + } + float energyStored = 0f; + if (itemStack.getTagCompound().hasKey("electricity")) + { + NBTBase obj = itemStack.getTagCompound().getTag("electricity"); + if (obj instanceof NBTTagDouble) + { + energyStored = (float) ((NBTTagDouble) obj).data; + } + else if (obj instanceof NBTTagFloat) + { + energyStored = ((NBTTagFloat) obj).data; + } + } - float electricityStored = itemStack.getTagCompound().getFloat("electricity"); + /** Sets the damage as a percentage to render the bar properly. */ + itemStack.setItemDamage((int) (100 - (energyStored / getMaxElectricityStored(itemStack)) * 100)); + return energyStored; + } - /** - * Sets the damage as a percentage to render the bar properly. - */ - itemStack.setItemDamage((int) (100 - (electricityStored / getMaxElectricityStored(itemStack)) * 100)); - return electricityStored; - } - - @Override - public void getSubItems(int par1, CreativeTabs par2CreativeTabs, List par3List) - { - // Add an uncharged version of the electric item - par3List.add(ElectricItemHelper.getUncharged(new ItemStack(this))); - // Add an electric item to the creative list that is fully charged - ItemStack chargedItem = new ItemStack(this); - par3List.add(ElectricItemHelper.getWithCharge(chargedItem, this.getMaxElectricityStored(chargedItem))); - } + @Override + public void getSubItems(int par1, CreativeTabs par2CreativeTabs, List par3List) + { + par3List.add(ElectricItemHelper.getUncharged(new ItemStack(this))); + par3List.add(ElectricItemHelper.getWithCharge(new ItemStack(this), this.getMaxElectricityStored(new ItemStack(this)))); + } } diff --git a/resources/MANIFEST.MF b/resources/MANIFEST.MF new file mode 100644 index 00000000..df250c58 --- /dev/null +++ b/resources/MANIFEST.MF @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 +FMLCorePlugin: dark.core.DarkCorePlugin diff --git a/resources/dependancies.info b/resources/dependancies.info new file mode 100644 index 00000000..7542d102 --- /dev/null +++ b/resources/dependancies.info @@ -0,0 +1,8 @@ +{ + "repo": "http://files.minecraftforge.net/ForgeMultipart/", + "file": "ForgeMultipart-universal-@MCVERSION@-@VERSION@.jar", + "dev": "ForgeMultipart-dev-@MCVERSION@-@VERSION@.jar", + "class": "codechicken.multipart.MultipartMod", + "version": "1.0.0.182", + "mcversion": "1.6.4" +} \ No newline at end of file diff --git a/src/dark/core/DarkCoreModContainer.java b/src/dark/core/DarkCoreModContainer.java new file mode 100644 index 00000000..cfbcff0c --- /dev/null +++ b/src/dark/core/DarkCoreModContainer.java @@ -0,0 +1,66 @@ +package dark.core; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.Subscribe; + +import cpw.mods.fml.common.DummyModContainer; +import cpw.mods.fml.common.LoadController; +import cpw.mods.fml.common.ModMetadata; +import cpw.mods.fml.common.event.FMLInitializationEvent; +import cpw.mods.fml.common.event.FMLPreInitializationEvent; +import cpw.mods.fml.common.versioning.ArtifactVersion; +import cpw.mods.fml.common.versioning.VersionParser; +import cpw.mods.fml.common.versioning.VersionRange; +import dark.core.common.DarkMain; + +public class DarkCoreModContainer extends DummyModContainer +{ + public DarkCoreModContainer() + { + super(new ModMetadata()); + ModMetadata meta = getMetadata(); + meta.modId = "DarkCoreLoader"; + meta.name = "Dark Core Loader"; + meta.version = DarkMain.VERSION; + meta.authorList = Arrays.asList("DarkGuardsman aka DarkCow"); + meta.description = "Core mod loader and asm transformer for Dark's Core Machine."; + meta.url = "www.BuiltBroken.com"; + } + + @Override + public List getDependants() + { + LinkedList deps = new LinkedList(); + deps.add(VersionParser.parseVersionReference("DarkCore@[0.2.0.85,)")); + return deps; + } + + @Override + public boolean registerBus(EventBus bus, LoadController controller) + { + bus.register(this); + return true; + } + + @Subscribe + public void preInit(FMLPreInitializationEvent event) + { + + } + + @Subscribe + public void init(FMLInitializationEvent event) + { + + } + + @Override + public VersionRange acceptableMinecraftVersionRange() + { + return VersionParser.parseRange("[1.6.2,)"); + } +} diff --git a/src/dark/core/DarkCorePlugin.java b/src/dark/core/DarkCorePlugin.java new file mode 100644 index 00000000..3c562e69 --- /dev/null +++ b/src/dark/core/DarkCorePlugin.java @@ -0,0 +1,65 @@ +package dark.core; + +import java.io.File; +import java.util.Map; + +import cpw.mods.fml.relauncher.FMLInjectionData; +import cpw.mods.fml.relauncher.IFMLCallHook; +import cpw.mods.fml.relauncher.IFMLLoadingPlugin; + +public class DarkCorePlugin implements IFMLLoadingPlugin, IFMLCallHook +{ + public static File minecraftDir; + + public DarkCorePlugin() + { + //get called twice, once for IFMLCallHook + if (minecraftDir != null) + { + return; + } + minecraftDir = (File) FMLInjectionData.data()[6]; + DepLoader.load(); + } + + @Override + public Void call() throws Exception + { + // TODO Auto-generated method stub + return null; + } + + @Override + public String[] getLibraryRequestClass() + { + // TODO Auto-generated method stub + return null; + } + + @Override + public String[] getASMTransformerClass() + { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getModContainerClass() + { + return "dark.core.DarkCoreModContainer"; + } + + @Override + public String getSetupClass() + { + return getClass().getName(); + } + + @Override + public void injectData(Map data) + { + // TODO Auto-generated method stub + + } + +} diff --git a/src/dark/core/DepLoader.java b/src/dark/core/DepLoader.java new file mode 100644 index 00000000..a845267d --- /dev/null +++ b/src/dark/core/DepLoader.java @@ -0,0 +1,678 @@ +package dark.core; + +import java.awt.Desktop; +import java.awt.Dimension; +import java.awt.Dialog.ModalityType; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +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.net.MalformedURLException; +import java.net.URL; +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.Map.Entry; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +import javax.swing.Box; +import javax.swing.JDialog; +import javax.swing.JEditorPane; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JProgressBar; +import javax.swing.WindowConstants; +import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; + +import argo.jdom.JdomParser; +import argo.jdom.JsonNode; +import argo.jdom.JsonRootNode; +import argo.jdom.JsonStringNode; +import argo.saj.InvalidSyntaxException; + +import net.minecraft.launchwrapper.LaunchClassLoader; + +import cpw.mods.fml.common.versioning.ComparableVersion; +import cpw.mods.fml.relauncher.FMLInjectionData; +import cpw.mods.fml.relauncher.FMLLaunchHandler; +import cpw.mods.fml.relauncher.IFMLCallHook; +import cpw.mods.fml.relauncher.IFMLLoadingPlugin; + +/** DepLoader from chickBonesCore */ +public class DepLoader implements IFMLLoadingPlugin, IFMLCallHook +{ + private static ByteBuffer downloadBuffer = ByteBuffer.allocateDirect(1 << 23); + private static final String owner = "DepLoader"; + private static DepLoadInst inst; + + public interface IDownloadDisplay + { + void resetProgress(int sizeGuess); + + void setPokeThread(Thread currentThread); + + void updateProgress(int fullLength); + + boolean shouldStopIt(); + + void updateProgressString(String string, Object... data); + + Object makeDialog(); + + void showErrorDialog(String name, String url); + } + + @SuppressWarnings("serial") + public static class Downloader extends JOptionPane implements IDownloadDisplay + { + private JDialog container; + private JLabel currentActivity; + private JProgressBar progress; + boolean stopIt; + Thread pokeThread; + + private Box makeProgressPanel() + { + Box box = Box.createVerticalBox(); + box.add(Box.createRigidArea(new Dimension(0, 10))); + JLabel welcomeLabel = new JLabel("" + owner + " is setting up your minecraft environment"); + box.add(welcomeLabel); + welcomeLabel.setAlignmentY(LEFT_ALIGNMENT); + welcomeLabel = new JLabel("Please wait, " + owner + " has some tasks to do before you can play"); + welcomeLabel.setAlignmentY(LEFT_ALIGNMENT); + box.add(welcomeLabel); + box.add(Box.createRigidArea(new Dimension(0, 10))); + currentActivity = new JLabel("Currently doing ..."); + box.add(currentActivity); + box.add(Box.createRigidArea(new Dimension(0, 10))); + progress = new JProgressBar(0, 100); + progress.setStringPainted(true); + box.add(progress); + box.add(Box.createRigidArea(new Dimension(0, 30))); + return box; + } + + @Override + public JDialog makeDialog() + { + if (container != null) + return container; + + setMessageType(JOptionPane.INFORMATION_MESSAGE); + setMessage(makeProgressPanel()); + setOptions(new Object[] { "Stop" }); + addPropertyChangeListener(new PropertyChangeListener() + { + @Override + public void propertyChange(PropertyChangeEvent evt) + { + if (evt.getSource() == Downloader.this && evt.getPropertyName() == VALUE_PROPERTY) + { + requestClose("This will stop minecraft from launching\nAre you sure you want to do this?"); + } + } + }); + container = new JDialog(null, "Hello", ModalityType.MODELESS); + container.setResizable(false); + container.setLocationRelativeTo(null); + container.add(this); + this.updateUI(); + container.pack(); + container.setMinimumSize(container.getPreferredSize()); + container.setVisible(true); + container.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); + container.addWindowListener(new WindowAdapter() + { + @Override + public void windowClosing(WindowEvent e) + { + requestClose("Closing this window will stop minecraft from launching\nAre you sure you wish to do this?"); + } + }); + return container; + } + + protected void requestClose(String message) + { + int shouldClose = JOptionPane.showConfirmDialog(container, message, "Are you sure you want to stop?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); + if (shouldClose == JOptionPane.YES_OPTION) + container.dispose(); + + stopIt = true; + if (pokeThread != null) + pokeThread.interrupt(); + } + + @Override + public void updateProgressString(String progressUpdate, Object... data) + { + //FMLLog.finest(progressUpdate, data); + if (currentActivity != null) + currentActivity.setText(String.format(progressUpdate, data)); + } + + @Override + public void resetProgress(int sizeGuess) + { + if (progress != null) + progress.getModel().setRangeProperties(0, 0, 0, sizeGuess, false); + } + + @Override + public void updateProgress(int fullLength) + { + if (progress != null) + progress.getModel().setValue(fullLength); + } + + @Override + public void setPokeThread(Thread currentThread) + { + this.pokeThread = currentThread; + } + + @Override + public boolean shouldStopIt() + { + return stopIt; + } + + @Override + public void showErrorDialog(String name, String url) + { + JEditorPane ep = new JEditorPane("text/html", "" + owner + " 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() + { + @Override + 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", JOptionPane.ERROR_MESSAGE); + } + } + + public static class DummyDownloader implements IDownloadDisplay + { + @Override + public void resetProgress(int sizeGuess) + { + } + + @Override + public void setPokeThread(Thread currentThread) + { + } + + @Override + public void updateProgress(int fullLength) + { + } + + @Override + public boolean shouldStopIt() + { + return false; + } + + @Override + public void updateProgressString(String string, Object... data) + { + } + + @Override + public Object makeDialog() + { + return null; + } + + @Override + public void showErrorDialog(String name, String url) + { + } + } + + public static class Dependancy + { + public String url; + public String[] filesplit; + public ComparableVersion version; + + public String existing; + /** Flag set to add this dep to the classpath immediately because it is required for a + * coremod. */ + public boolean coreLib; + + public Dependancy(String url, String[] filesplit, boolean coreLib) + { + this.url = url; + this.filesplit = filesplit; + this.coreLib = coreLib; + version = new ComparableVersion(filesplit[1]); + } + + public String getName() + { + return filesplit[0]; + } + + public String fileName() + { + return filesplit[0] + filesplit[1] + filesplit[2]; + } + } + + public static class DepLoadInst + { + private File modsDir; + private File v_modsDir; + private IDownloadDisplay downloadMonitor; + private JDialog popupWindow; + + private Map depMap = new HashMap(); + private HashSet depSet = new HashSet(); + + public DepLoadInst() + { + String mcVer = (String) FMLInjectionData.data()[4]; + File mcDir = (File) FMLInjectionData.data()[6]; + + modsDir = new File(mcDir, "mods"); + v_modsDir = new File(mcDir, "mods/" + mcVer); + if (!v_modsDir.exists()) + v_modsDir.mkdirs(); + } + + private void addClasspath(String name) + { + try + { + ((LaunchClassLoader) DepLoader.class.getClassLoader()).addURL(new File(v_modsDir, name).toURI().toURL()); + } + catch (MalformedURLException e) + { + throw new RuntimeException(e); + } + } + + private void download(Dependancy dep) + { + popupWindow = (JDialog) downloadMonitor.makeDialog(); + File libFile = new File(v_modsDir, dep.fileName()); + try + { + URL libDownload = new URL(dep.url + '/' + dep.fileName()); + 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", "" + owner + " Downloader"); + int sizeGuess = connection.getContentLength(); + download(connection.getInputStream(), sizeGuess, libFile); + downloadMonitor.updateProgressString("Download complete"); + System.out.println("Download complete"); + + scanDepInfo(libFile); + } + catch (Exception e) + { + libFile.delete(); + if (downloadMonitor.shouldStopIt()) + { + System.err.println("You have stopped the downloading operation before it could complete"); + System.exit(1); + return; + } + downloadMonitor.showErrorDialog(dep.fileName(), dep.url + '/' + dep.fileName()); + throw new RuntimeException("A download error occured", e); + } + } + + private void download(InputStream is, int sizeGuess, File target) throws Exception + { + if (sizeGuess > downloadBuffer.capacity()) + throw new Exception(String.format("The file %s is too large to be downloaded by " + owner + " - the download is invalid", target.getName())); + + downloadBuffer.clear(); + + int bytesRead, fullLength = 0; + + downloadMonitor.resetProgress(sizeGuess); + try + { + downloadMonitor.setPokeThread(Thread.currentThread()); + byte[] smallBuffer = new byte[1024]; + while ((bytesRead = is.read(smallBuffer)) >= 0) + { + downloadBuffer.put(smallBuffer, 0, bytesRead); + fullLength += bytesRead; + if (downloadMonitor.shouldStopIt()) + { + break; + } + downloadMonitor.updateProgress(fullLength); + } + is.close(); + downloadMonitor.setPokeThread(null); + downloadBuffer.limit(fullLength); + downloadBuffer.position(0); + } + catch (InterruptedIOException e) + { + // We were interrupted by the stop button. We're stopping now.. clear interruption flag. + Thread.interrupted(); + throw new Exception("Stop"); + } + catch (IOException e) + { + throw e; + } + + try + { + /*String cksum = generateChecksum(downloadBuffer); + if (cksum.equals(validationHash)) + {*/ + if (!target.exists()) + target.createNewFile(); + + downloadBuffer.position(0); + FileOutputStream fos = new FileOutputStream(target); + fos.getChannel().write(downloadBuffer); + fos.close(); + /*} + else + { + throw new RuntimeException(String.format("The downloaded file %s has an invalid checksum %s (expecting %s). The download did not succeed correctly and the file has been deleted. Please try launching again.", target.getName(), cksum, validationHash)); + }*/ + } + catch (Exception e) + { + throw e; + } + } + + private String checkExisting(String[] dependancy) + { + for (File f : modsDir.listFiles()) + { + String[] split = splitFileName(f.getName()); + if (split == null || !split[0].equals(dependancy[0])) + continue; + + if (f.renameTo(new File(v_modsDir, f.getName()))) + continue; + + if (f.delete()) + continue; + + f.deleteOnExit(); + } + + for (File f : v_modsDir.listFiles()) + { + String[] split = splitFileName(f.getName()); + if (split == null || !split[0].equals(dependancy[0])) + continue; + + ComparableVersion found = new ComparableVersion(split[1]); + ComparableVersion requested = new ComparableVersion(dependancy[1]); + + int cmp = found.compareTo(requested); + if (cmp < 0) + { + System.out.println("Deleted old version " + f.getName()); + f.delete(); + return null; + } + if (cmp > 0) + { + System.err.println("Warning: version of " + dependancy[0] + ", " + split[1] + " is newer than request " + dependancy[1]); + return f.getName(); + } + return f.getName();//found dependancy + } + return null; + } + + public void load() + { + scanDepInfos(); + if (depMap.isEmpty()) + return; + + loadDeps(); + activateDeps(); + } + + private void activateDeps() + { + for (Dependancy dep : depMap.values()) + if (dep.coreLib) + addClasspath(dep.existing); + } + + private void loadDeps() + { + downloadMonitor = FMLLaunchHandler.side().isClient() ? new Downloader() : new DummyDownloader(); + try + { + while (!depSet.isEmpty()) + { + Iterator it = depSet.iterator(); + Dependancy dep = depMap.get(it.next()); + it.remove(); + load(dep); + } + } + finally + { + if (popupWindow != null) + { + popupWindow.setVisible(false); + popupWindow.dispose(); + } + } + } + + private void load(Dependancy dep) + { + dep.existing = checkExisting(dep.filesplit); + if (dep.existing == null)//download dep + { + download(dep); + dep.existing = dep.fileName(); + } + } + + private List modFiles() + { + List list = new LinkedList(); + list.addAll(Arrays.asList(modsDir.listFiles())); + list.addAll(Arrays.asList(v_modsDir.listFiles())); + return list; + } + + private void scanDepInfos() + { + for (File file : modFiles()) + { + if (!file.getName().endsWith(".jar") && !file.getName().endsWith(".zip")) + continue; + + scanDepInfo(file); + } + } + + private void scanDepInfo(File file) + { + try + { + ZipFile zip = new ZipFile(file); + ZipEntry e = zip.getEntry("dependancies.info"); + if (e != null) + loadJSon(zip.getInputStream(e)); + zip.close(); + } + catch (Exception e) + { + System.err.println("Failed to load dependancies.info from " + file.getName() + " as JSON"); + e.printStackTrace(); + } + } + + private void loadJSon(InputStream input) throws IOException, InvalidSyntaxException + { + InputStreamReader reader = new InputStreamReader(input); + JsonRootNode root = new JdomParser().parse(reader); + if (root.hasElements()) + loadJSonArr(root); + else + loadJson(root); + reader.close(); + } + + private void loadJSonArr(JsonRootNode root) throws IOException + { + for (JsonNode node : root.getElements()) + loadJson(node); + } + + private void loadJson(JsonNode node) throws IOException + { + boolean obfuscated = ((LaunchClassLoader) DepLoader.class.getClassLoader()).getClassBytes("net.minecraft.world.World") == null; + + String testClass = node.getStringValue("class"); + if (DepLoader.class.getResource("/" + testClass.replace('.', '/') + ".class") != null) + return; + + String repo = node.getStringValue("repo"); + String file = node.getStringValue("file"); + if (!obfuscated && node.isNode("dev")) + file = node.getStringValue("dev"); + + boolean coreLib = node.isNode("coreLib") && node.getBooleanValue("coreLib"); + + List reserved = Arrays.asList("repo", "file", "class", "dev", "coreLib"); + for (Entry e : node.getFields().entrySet()) + { + String s = e.getKey().getText(); + if (!e.getValue().hasText() || reserved.contains(s)) + continue; + + file = file.replaceAll("@" + s.toUpperCase() + "@", e.getValue().getText()); + } + + String[] split = splitFileName(file); + if (split == null) + throw new RuntimeException("Invalid filename format for dependancy: " + file); + + addDep(new Dependancy(repo, split, coreLib)); + } + + private void addDep(Dependancy newDep) + { + if (mergeNew(depMap.get(newDep.getName()), newDep)) + { + depMap.put(newDep.getName(), newDep); + depSet.add(newDep.getName()); + } + } + + private boolean mergeNew(Dependancy oldDep, Dependancy newDep) + { + if (oldDep == null) + return true; + + Dependancy newest = newDep.version.compareTo(oldDep.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(); + } + } + + private static String[] splitFileName(String filename) + { + Pattern p = Pattern.compile("(.+?)([\\d\\.\\w]+)(\\.[^\\d]+)"); + Matcher m = p.matcher(filename); + if (!m.matches()) + return null; + + return new String[] { m.group(1), m.group(2), m.group(3) }; + } + + @Override + public String[] getASMTransformerClass() + { + return null; + } + + @Override + public String getModContainerClass() + { + return null; + } + + @Override + public String getSetupClass() + { + return getClass().getName(); + } + + @Override + public void injectData(Map data) + { + } + + @Override + public Void call() + { + load(); + + return null; + } + + @Override + public String[] getLibraryRequestClass() + { + return null; + } +} \ No newline at end of file diff --git a/src/dark/core/common/machines/BlockBasicMachine.java b/src/dark/core/common/machines/BlockBasicMachine.java index 5d56e609..71445adb 100644 --- a/src/dark/core/common/machines/BlockBasicMachine.java +++ b/src/dark/core/common/machines/BlockBasicMachine.java @@ -30,7 +30,7 @@ public class BlockBasicMachine extends BlockMachine } @Override - public void randomDisplayTick(World par1World, int x, int y, int z, Random par5Random) + public void randomDisplayTick(World par1World, int x, int y, int z, Random rand) { TileEntity tile = par1World.getBlockTileEntity(x, y, z); @@ -39,32 +39,32 @@ public class BlockBasicMachine extends BlockMachine TileEntityCoalGenerator tileEntity = (TileEntityCoalGenerator) tile; if (tileEntity.generateWatts > 0) { - int metadata = par1World.getBlockMetadata(x, y, z); - float var7 = x + 0.5F; - float var8 = y + 0.0F + par5Random.nextFloat() * 6.0F / 16.0F; - float var9 = z + 0.5F; - float var10 = 0.52F; - float var11 = par5Random.nextFloat() * 0.6F - 0.3F; + int face = par1World.getBlockMetadata(x, y, z) % 4; + float xx = x + 0.5F; + float yy = y + 0.0F + rand.nextFloat() * 6.0F / 16.0F; + float zz = z + 0.5F; + float posTooner = 0.52F; + float randPosChange = rand.nextFloat() * 0.6F - 0.3F; - if (metadata == 3) + if (face == 3) { - par1World.spawnParticle("smoke", var7 - var10, var8, var9 + var11, 0.0D, 0.0D, 0.0D); - par1World.spawnParticle("flame", var7 - var10, var8, var9 + var11, 0.0D, 0.0D, 0.0D); + par1World.spawnParticle("smoke", xx - posTooner, yy, zz + randPosChange, 0.0D, 0.0D, 0.0D); + par1World.spawnParticle("flame", xx - posTooner, yy, zz + randPosChange, 0.0D, 0.0D, 0.0D); } - else if (metadata == 2) + else if (face == 2) { - par1World.spawnParticle("smoke", var7 + var10, var8, var9 + var11, 0.0D, 0.0D, 0.0D); - par1World.spawnParticle("flame", var7 + var10, var8, var9 + var11, 0.0D, 0.0D, 0.0D); + par1World.spawnParticle("smoke", xx + posTooner, yy, zz + randPosChange, 0.0D, 0.0D, 0.0D); + par1World.spawnParticle("flame", xx + posTooner, yy, zz + randPosChange, 0.0D, 0.0D, 0.0D); } - else if (metadata == 1) + else if (face == 1) { - par1World.spawnParticle("smoke", var7 + var11, var8, var9 - var10, 0.0D, 0.0D, 0.0D); - par1World.spawnParticle("flame", var7 + var11, var8, var9 - var10, 0.0D, 0.0D, 0.0D); + par1World.spawnParticle("smoke", xx + randPosChange, yy, zz - posTooner, 0.0D, 0.0D, 0.0D); + par1World.spawnParticle("flame", xx + randPosChange, yy, zz - posTooner, 0.0D, 0.0D, 0.0D); } - else if (metadata == 0) + else if (face == 0) { - par1World.spawnParticle("smoke", var7 + var11, var8, var9 + var10, 0.0D, 0.0D, 0.0D); - par1World.spawnParticle("flame", var7 + var11, var8, var9 + var10, 0.0D, 0.0D, 0.0D); + par1World.spawnParticle("smoke", xx + randPosChange, yy, zz + posTooner, 0.0D, 0.0D, 0.0D); + par1World.spawnParticle("flame", xx + randPosChange, yy, zz + posTooner, 0.0D, 0.0D, 0.0D); } } } @@ -94,20 +94,10 @@ public class BlockBasicMachine extends BlockMachine } } - @Override - public boolean hasExtraConfigs() - { - return false; - } - @Override public void loadExtraConfigs(Configuration config) { - } - - @Override - public void loadOreNames() - { + super.loadExtraConfigs(config); } /** Called when the block is right clicked by the player */ diff --git a/src/dark/core/prefab/machine/BlockMachine.java b/src/dark/core/prefab/machine/BlockMachine.java index 6470650f..079c8c37 100644 --- a/src/dark/core/prefab/machine/BlockMachine.java +++ b/src/dark/core/prefab/machine/BlockMachine.java @@ -8,6 +8,7 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Icon; import net.minecraft.world.World; import net.minecraftforge.common.Configuration; +import net.minecraftforge.oredict.OreDictionary; import universalelectricity.prefab.block.BlockTile; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.relauncher.Side; @@ -20,11 +21,11 @@ import dark.core.prefab.helpers.Pair; import dark.core.registration.ModObjectRegistry.BlockBuildData; /** Basic TileEntity Container class designed to be used by generic machines. It is suggested that - * each mod using this create there own basic block extending this to reduce need to input config - * file each time - * + * each mod using this create there own basic block extending this to reduce need to use build + * data per block. + * * @author Darkguardsman */ -public abstract class BlockMachine extends BlockTile implements ITileEntityProvider, IExtraBlockInfo +public abstract class BlockMachine extends BlockTile implements IExtraBlockInfo { public boolean zeroAnimation, zeroSound, zeroRendering; @@ -33,6 +34,7 @@ public abstract class BlockMachine extends BlockTile implements ITileEntityProvi { super(data.config.getBlock(data.blockName, ModPrefab.getNextID()).getInt(), data.blockMaterial); this.setUnlocalizedName(data.blockName); + this.setResistance(100f); if (data.creativeTab != null) { this.setCreativeTab(data.creativeTab); @@ -113,7 +115,7 @@ public abstract class BlockMachine extends BlockTile implements ITileEntityProvi @Override public void loadOreNames() { - // TODO Auto-generated method stub + OreDictionary.registerOre(this.getUnlocalizedName().replace("tile.", ""), this); }