diff --git a/common/buildcraft/BuildCraftCore.java b/common/buildcraft/BuildCraftCore.java index 6b2676c5..e026e847 100644 --- a/common/buildcraft/BuildCraftCore.java +++ b/common/buildcraft/BuildCraftCore.java @@ -122,15 +122,15 @@ public class BuildCraftCore { @SideOnly(Side.CLIENT) public static Icon redLaserTexture; - @SideOnly(Side.CLIENT) + @SideOnly(Side.CLIENT) public static Icon blueLaserTexture; - @SideOnly(Side.CLIENT) + @SideOnly(Side.CLIENT) public static Icon stripesLaserTexture; - @SideOnly(Side.CLIENT) + @SideOnly(Side.CLIENT) public static Icon transparentTexture; - @SideOnly(Side.CLIENT) - public static IIconProvider iconProvider; + @SideOnly(Side.CLIENT) + public static IIconProvider iconProvider; public static int blockByEntityModel; public static int legacyPipeModel; @@ -149,7 +149,7 @@ public class BuildCraftCore { public static BCTrigger triggerFullFluid = new TriggerFluidContainer(DefaultProps.TRIGGER_FULL_LIQUID, TriggerFluidContainer.State.Full); public static BCTrigger triggerRedstoneActive = new TriggerRedstoneInput(DefaultProps.TRIGGER_REDSTONE_ACTIVE, true); public static BCTrigger triggerRedstoneInactive = new TriggerRedstoneInput(DefaultProps.TRIGGER_REDSTONE_INACTIVE, false); - + public static BCTrigger triggerInventoryBelow25 = new TriggerInventoryLevel(TriggerInventoryLevel.TriggerType.BELOW_25); public static BCTrigger triggerInventoryBelow50 = new TriggerInventoryLevel(TriggerInventoryLevel.TriggerType.BELOW_50); public static BCTrigger triggerInventoryBelow75 = new TriggerInventoryLevel(TriggerInventoryLevel.TriggerType.BELOW_75); @@ -168,16 +168,17 @@ public class BuildCraftCore { @Instance("BuildCraft|Core") public static BuildCraftCore instance; - @EventHandler + @EventHandler public void loadConfiguration(FMLPreInitializationEvent evt) { BCLog.initLog(); - - BlueprintDatabase.configFolder = evt.getModConfigurationDirectory(); + + BlueprintDatabase.init(evt.getModConfigurationDirectory()); + mainConfiguration = new BuildCraftConfiguration(new File(evt.getModConfigurationDirectory(), "buildcraft/main.conf")); try { mainConfiguration.load(); - + Property updateCheck = BuildCraftCore.mainConfiguration.get(Configuration.CATEGORY_GENERAL, "update.check", true); updateCheck.comment = "set to true for version check on startup"; if (updateCheck.getBoolean(true)) { @@ -254,7 +255,7 @@ public class BuildCraftCore { LanguageRegistry.addName(ironGearItem, "Iron Gear"); CoreProxy.proxy.registerItem(ironGearItem); OreDictionary.registerOre("gearIron", new ItemStack(ironGearItem)); - + goldGearItem = (new ItemBuildCraft(goldenGearId.getInt())).setUnlocalizedName("goldGearItem"); LanguageRegistry.addName(goldGearItem, "Gold Gear"); CoreProxy.proxy.registerItem(goldGearItem); @@ -268,7 +269,7 @@ public class BuildCraftCore { Property colorBlindProp = BuildCraftCore.mainConfiguration.get(Configuration.CATEGORY_GENERAL, "client.colorblindmode", false); colorBlindProp.comment = "Set to true to enable alternate textures"; colorBlindMode = colorBlindProp.getBoolean(false); - + MinecraftForge.EVENT_BUS.register(this); } finally { @@ -278,8 +279,8 @@ public class BuildCraftCore { } } - @EventHandler - public void initialize(FMLInitializationEvent evt) { + @EventHandler + public void initialize(FMLInitializationEvent evt) { // MinecraftForge.registerConnectionHandler(new ConnectionHandler()); ActionManager.registerTriggerProvider(new DefaultTriggerProvider()); ActionManager.registerActionProvider(new DefaultActionProvider()); @@ -323,8 +324,8 @@ public class BuildCraftCore { } - @EventHandler - public void serverStarting(FMLServerStartingEvent event) { + @EventHandler + public void serverStarting(FMLServerStartingEvent event) { event.registerServerCommand(new CommandBuildCraft()); } @@ -336,16 +337,16 @@ public class BuildCraftCore { iconProvider.registerIcons(event.map); ActionTriggerIconProvider.INSTANCE.registerIcons(event.map); } else if (event.map.textureType == 0) { - BuildCraftCore.redLaserTexture = event.map.registerIcon("buildcraft:blockRedLaser"); - BuildCraftCore.blueLaserTexture = event.map.registerIcon("buildcraft:blockBlueLaser"); - BuildCraftCore.stripesLaserTexture = event.map.registerIcon("buildcraft:blockStripesLaser"); - BuildCraftCore.transparentTexture = event.map.registerIcon("buildcraft:blockTransparentLaser"); + BuildCraftCore.redLaserTexture = event.map.registerIcon("buildcraft:blockRedLaser"); + BuildCraftCore.blueLaserTexture = event.map.registerIcon("buildcraft:blockBlueLaser"); + BuildCraftCore.stripesLaserTexture = event.map.registerIcon("buildcraft:blockStripesLaser"); + BuildCraftCore.transparentTexture = event.map.registerIcon("buildcraft:blockTransparentLaser"); } } public void loadRecipes() { - CoreProxy.proxy.addCraftingRecipe(new ItemStack(wrenchItem), "I I", " G ", " I ", 'I', Item.ingotIron, 'G', stoneGearItem); + CoreProxy.proxy.addCraftingRecipe(new ItemStack(wrenchItem), "I I", " G ", " I ", 'I', Item.ingotIron, 'G', stoneGearItem); CoreProxy.proxy.addCraftingRecipe(new ItemStack(woodenGearItem), " S ", "S S", " S ", 'S', "stickWood"); CoreProxy.proxy.addCraftingRecipe(new ItemStack(stoneGearItem), " I ", "IGI", " I ", 'I', "cobblestone", 'G', woodenGearItem); @@ -353,9 +354,9 @@ public class BuildCraftCore { CoreProxy.proxy.addCraftingRecipe(new ItemStack(goldGearItem), " I ", "IGI", " I ", 'I', Item.ingotGold, 'G', ironGearItem); CoreProxy.proxy.addCraftingRecipe(new ItemStack(diamondGearItem), " I ", "IGI", " I ", 'I', Item.diamond, 'G', goldGearItem); } - + @EventHandler - public void processIMCRequests(FMLInterModComms.IMCEvent event) { - InterModComms.processIMC(event); - } + public void processIMCRequests(FMLInterModComms.IMCEvent event) { + InterModComms.processIMC(event); + } } diff --git a/common/buildcraft/builders/ItemBlueprint.java b/common/buildcraft/builders/ItemBlueprint.java index 7d5eaea3..c9adc9a7 100644 --- a/common/buildcraft/builders/ItemBlueprint.java +++ b/common/buildcraft/builders/ItemBlueprint.java @@ -13,12 +13,14 @@ import buildcraft.core.CreativeTabBuildCraft; import buildcraft.core.ItemBuildCraft; import buildcraft.core.utils.NBTUtils; import buildcraft.core.utils.StringUtils; + import java.util.List; -import java.util.UUID; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import buildcraft.builders.blueprints.BlueprintId; + public abstract class ItemBlueprint extends ItemBuildCraft { public ItemBlueprint(int i) { @@ -39,11 +41,14 @@ public abstract class ItemBlueprint extends ItemBuildCraft { } public static Blueprint getBlueprint(ItemStack stack) { - if (stack != null && stack.getItem() instanceof ItemBlueprint) { - NBTTagCompound nbt = NBTUtils.getItemData(stack); - UUID uuid = NBTUtils.readUUID(nbt, "blueprint"); - return BlueprintDatabase.getBlueprint(uuid); + NBTTagCompound nbt = NBTUtils.getItemData(stack); + byte[] idRaw = nbt.getByteArray("blueprint"); + BlueprintId id = BlueprintId.fromRawId(idRaw); + + if (id == null) { + return null; + } else { + return BlueprintDatabase.get(id); } - return null; } } diff --git a/common/buildcraft/builders/TileArchitect.java b/common/buildcraft/builders/TileArchitect.java index b02ef48a..0d6bd324 100644 --- a/common/buildcraft/builders/TileArchitect.java +++ b/common/buildcraft/builders/TileArchitect.java @@ -93,14 +93,14 @@ public class TileArchitect extends TileBuildCraft implements IInventory { blueprint.anchorOrientation = ForgeDirection.getOrientation(worldObj.getBlockMetadata(xCoord, yCoord, zCoord)); - BlueprintDatabase.addBlueprint(blueprint); - + BlueprintDatabase.add(blueprint); + setInventorySlotContents(1, blueprint.getBlueprintItem()); setInventorySlotContents(0, null); } private Blueprint createMaskBlueprint(Box box) { - Blueprint blueprint = new Blueprint(box.sizeX(), box.sizeY(), box.sizeZ()); + Blueprint blueprint = Blueprint.create(box.sizeX(), box.sizeY(), box.sizeZ()); for (int x = box.xMin; x <= box.xMax; ++x) { for (int y = box.yMin; y <= box.yMax; ++y) { @@ -120,7 +120,7 @@ public class TileArchitect extends TileBuildCraft implements IInventory { } private Blueprint createStandardBlueprint(Box box) { - Blueprint blueprint = new Blueprint(box.sizeX(), box.sizeY(), box.sizeZ()); + Blueprint blueprint = Blueprint.create(box.sizeX(), box.sizeY(), box.sizeZ()); for (int x = box.xMin; x <= box.xMax; ++x) { for (int y = box.yMin; y <= box.yMax; ++y) { diff --git a/common/buildcraft/builders/blueprints/Blueprint.java b/common/buildcraft/builders/blueprints/Blueprint.java index 4f983818..cc155578 100644 --- a/common/buildcraft/builders/blueprints/Blueprint.java +++ b/common/buildcraft/builders/blueprints/Blueprint.java @@ -13,16 +13,18 @@ import buildcraft.core.inventory.StackHelper; import buildcraft.core.utils.BCLog; import buildcraft.core.utils.NBTUtils; import buildcraft.factory.TileQuarry; + import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; import java.util.List; -import java.util.UUID; + import net.minecraft.block.Block; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.world.World; + import net.minecraftforge.common.ForgeDirection; /** @@ -30,42 +32,82 @@ import net.minecraftforge.common.ForgeDirection; * world. * * @author CovertJaguar + * @author Player */ public class Blueprint { - - private final String version = "Blueprint-2.0"; - private final UUID uuid; - private String name; - private String creator; + private BlueprintMeta meta; private final Schematic[][][] schematics; public final int sizeX, sizeY, sizeZ; public int anchorX, anchorY, anchorZ; public ForgeDirection anchorOrientation = ForgeDirection.NORTH; private List costs; - public Blueprint(int sizeX, int sizeY, int sizeZ) { - this(sizeX, sizeY, sizeZ, UUID.randomUUID()); + public static Blueprint create(int sizeX, int sizeY, int sizeZ) { + return new Blueprint(new BlueprintMeta(), sizeX, sizeY, sizeZ); } - private Blueprint(int sizeX, int sizeY, int sizeZ, UUID uuid) { - this.uuid = uuid; + private Blueprint(BlueprintMeta meta, int sizeX, int sizeY, int sizeZ) { + this.meta = meta; + this.sizeX = sizeX; this.sizeY = sizeY; this.sizeZ = sizeZ; + schematics = new Schematic[sizeX][sizeY][sizeZ]; } + protected Blueprint(BlueprintMeta meta, NBTTagCompound nbt) { + this(meta, nbt.getInteger("sizeX"), + nbt.getInteger("sizeY"), + nbt.getInteger("sizeZ")); + + anchorX = nbt.getInteger("anchorX"); + anchorY = nbt.getInteger("anchorY"); + anchorZ = nbt.getInteger("anchorZ"); + + anchorOrientation = ForgeDirection.getOrientation(nbt.getByte("anchorOrientation")); + + NBTTagList blockList = nbt.getTagList("blocks"); + for (int i = 0; i < blockList.tagCount(); i++) { + NBTTagCompound blockNBT = (NBTTagCompound) blockList.tagAt(i); + Schematic schematic = Schematic.createSchematicFromNBT(blockNBT); + schematics[schematic.x][schematic.y][schematic.z] = schematic; + } + } + + public BlueprintId getId() { + return meta.getId(); + } + + protected void setId(BlueprintId id) { + meta.setId(id); + } + public String getName() { - return name; + return meta.getName(); } public void setName(String name) { - this.name = name; + meta.setName(name); + } + + /** + * @return the creator + */ + public String getCreator() { + return meta.getCreator(); + } + + /** + * @param creator the creator to set + */ + public void setCreator(String creator) { + meta.setCreator(creator); } private void setSchematic(int x, int y, int z, Schematic schematic) { - if (schematic == null) - return; + if (getId() != null) throw new IllegalStateException("modifying finalized blueprint"); + schematic.x = x; schematic.y = y; schematic.z = z; @@ -124,10 +166,6 @@ public class Blueprint { return schematics[x][y][z]; } - public UUID getUUID() { - return uuid; - } - /** * Returns a list of all blocks in the Blueprint in the order they should be * built. @@ -174,7 +212,10 @@ public class Blueprint { } public void writeToNBT(NBTTagCompound nbt) { + meta.writeToNBT(nbt); + NBTTagList blockList = new NBTTagList(); + for (int y = 0; y < sizeY; y++) { for (int x = 0; x < sizeX; x++) { for (int z = 0; z < sizeZ; z++) { @@ -186,12 +227,8 @@ public class Blueprint { } } } + nbt.setTag("blocks", blockList); - nbt.setLong("uuidMost", uuid.getMostSignificantBits()); - nbt.setLong("uuidLeast", uuid.getLeastSignificantBits()); - nbt.setString("name", name); - nbt.setString("version", version); - nbt.setString("creator", creator); nbt.setInteger("sizeX", sizeX); nbt.setInteger("sizeY", sizeY); nbt.setInteger("sizeZ", sizeZ); @@ -201,46 +238,7 @@ public class Blueprint { nbt.setByte("anchorOrientation", (byte) anchorOrientation.ordinal()); } - public static Blueprint readFromNBT(NBTTagCompound nbt) { - long most = nbt.getLong("uuidMost"); - long least = nbt.getLong("uuidLeast"); - int sizeX = nbt.getInteger("sizeX"); - int sizeY = nbt.getInteger("sizeY"); - int sizeZ = nbt.getInteger("sizeZ"); - Blueprint blueprint = new Blueprint(sizeX, sizeY, sizeZ, new UUID(most, least)); - - blueprint.name = nbt.getString("name"); - blueprint.creator = nbt.getString("creator"); - - blueprint.anchorX = nbt.getInteger("anchorX"); - blueprint.anchorY = nbt.getInteger("anchorY"); - blueprint.anchorZ = nbt.getInteger("anchorZ"); - - blueprint.anchorOrientation = ForgeDirection.getOrientation(nbt.getByte("anchorOrientation")); - - NBTTagList blockList = nbt.getTagList("blocks"); - for (int i = 0; i < blockList.tagCount(); i++) { - NBTTagCompound blockNBT = (NBTTagCompound) blockList.tagAt(i); - Schematic schematic = Schematic.createSchematicFromNBT(blockNBT); - blueprint.schematics[schematic.x][schematic.y][schematic.z] = schematic; - } - return blueprint; - } - - /** - * @return the creator - */ - public String getCreator() { - return creator; - } - - /** - * @param creator the creator to set - */ - public void setCreator(String creator) { - this.creator = creator; - } public void rotateLeft() { anchorOrientation = anchorOrientation.getRotation(ForgeDirection.DOWN); @@ -249,7 +247,7 @@ public class Blueprint { public ItemStack getBlueprintItem() { ItemStack blueprint = new ItemStack(BuildCraftBuilders.blueprintItem, 1, 1); NBTTagCompound nbt = NBTUtils.getItemData(blueprint); - NBTUtils.writeUUID(nbt, "blueprint", uuid); + nbt.setByteArray("blueprint", getId().toRawId()); return blueprint; } } diff --git a/common/buildcraft/builders/blueprints/BlueprintDatabase.java b/common/buildcraft/builders/blueprints/BlueprintDatabase.java index 5b70dd81..72b56212 100644 --- a/common/buildcraft/builders/blueprints/BlueprintDatabase.java +++ b/common/buildcraft/builders/blueprints/BlueprintDatabase.java @@ -8,127 +8,225 @@ */ package buildcraft.builders.blueprints; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.HashMap; import java.util.Locale; import java.util.Map; -import java.util.UUID; +import java.util.WeakHashMap; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + import net.minecraft.nbt.CompressedStreamTools; +import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; /** * + * @author Player * @author CovertJaguar */ public class BlueprintDatabase { + public static void init(File configDir) { + blueprintFolder = new File(new File(configDir, "buildcraft"), "blueprints"); - public static File configFolder; - private static Map blueprints = new HashMap(); + if (!blueprintFolder.exists()) blueprintFolder.mkdirs(); - public static Blueprint getBlueprint(UUID uuid) { - if(uuid == null) - return null; - Blueprint blueprint = blueprints.get(uuid); - if (blueprint == null) { - blueprint = loadBlueprint(uuid); - addBlueprint(blueprint); + loadIndex(); + } + + public static Blueprint get(BlueprintId id) { + Blueprint ret = blueprints.get(id); + + if (ret == null) { + BlueprintMeta meta = blueprintMetas.get(id); + if (meta == null) return null; // no meta -> no bpt as well + + ret = load(meta); } - return blueprint; + + return ret; } - public static void addBlueprint(Blueprint blueprint) { - if (blueprint == null) - return; - blueprints.put(blueprint.getUUID(), blueprint); + public static BlueprintId add(Blueprint blueprint) { + BlueprintId id = save(blueprint); + + blueprint.setId(id); + + blueprints.put(id, blueprint); + + return id; } - private static File getBlueprintFolder() { - File blueprintFolder = new File(configFolder, "buildcraft/blueprints/"); - if (!blueprintFolder.exists()) { - blueprintFolder.mkdirs(); - } - return blueprintFolder; - } - - private static String uuidToString(UUID uuid) { - return String.format(Locale.ENGLISH, "%x%x", uuid.getMostSignificantBits(), uuid.getLeastSignificantBits()); - } - - public static void saveBlueprint(Blueprint blueprint) { + private static BlueprintId save(Blueprint blueprint) { NBTTagCompound nbt = new NBTTagCompound(); blueprint.writeToNBT(nbt); - File blueprintFile = new File(getBlueprintFolder(), String.format(Locale.ENGLISH, "%x%x-%s.nbt", uuidToString(blueprint.getUUID()), blueprint.getName())); - - if (blueprintFile.exists()) - return; + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + DataOutputStream os = new DataOutputStream(bos); try { - CompressedStreamTools.write(nbt, blueprintFile); - } catch (IOException ex) { - Logger.getLogger("Buildcraft").log(Level.SEVERE, String.format("Failed to save Blueprint file: %s %s", blueprintFile.getName(), ex.getMessage())); + NBTBase.writeNamedTag(nbt, os); + } catch (IOException e) { + throw new RuntimeException(e); } + + byte[] data = bos.toByteArray(); + + BlueprintId id = BlueprintId.generate(data); + + File blueprintFile = new File(blueprintFolder, String.format(Locale.ENGLISH, "%s-%s.nbt", id.toString(), blueprint.getName())); + + if (!blueprintFile.exists()) { + OutputStream gzOs = null; + try { + gzOs = new GZIPOutputStream(new FileOutputStream(blueprintFile)); + + gzOs.write(data); + + CompressedStreamTools.write(nbt, blueprintFile); + } catch (IOException ex) { + Logger.getLogger("Buildcraft").log(Level.SEVERE, String.format("Failed to save Blueprint file: %s %s", blueprintFile.getName(), ex.getMessage())); + } finally { + try { + if (gzOs != null) gzOs.close(); + } catch (IOException e) { } + } + } + + return id; } - public static void saveBlueprints() { - for (Blueprint blueprint : blueprints.values()) { - saveBlueprint(blueprint); - } - } - - private static Blueprint loadBlueprint(final UUID uuid) { + private static void loadIndex() { FilenameFilter filter = new FilenameFilter() { - private String uuidString = uuidToString(uuid); - @Override public boolean accept(File dir, String name) { - return name.startsWith(uuidString); + return name.endsWith(fileExt); } }; - NBTTagCompound nbt = null; - File blueprintFolder = getBlueprintFolder(); for (File blueprintFile : blueprintFolder.listFiles(filter)) { + RawBlueprint rawBlueprint = load(blueprintFile); + + if (rawBlueprint == null) { + // TODO: delete? + continue; + } + + BlueprintMeta meta; + try { - nbt = CompressedStreamTools.read(blueprintFile); - break; - } catch (IOException ex) { - Logger.getLogger("Buildcraft").log(Level.SEVERE, String.format("Failed to load Blueprint file: %s %s", blueprintFile.getName(), ex.getMessage())); + meta = new BlueprintMeta(rawBlueprint.id, rawBlueprint.nbt); + } catch (Exception e) { + // TODO: delete? + continue; + } + + // TODO: check if the filename is matching id+name + + BlueprintMeta prevValue = blueprintMetas.put(meta.getId(), meta); + + if (prevValue != null) { + // TODO: duplicate entry, handle } } + } - if (nbt == null) { + private static Blueprint load(final BlueprintMeta meta) { + FilenameFilter filter = new FilenameFilter() { + String prefix = meta.getId().toString(); + + @Override + public boolean accept(File dir, String name) { + return name.endsWith(fileExt) && name.startsWith(prefix); + } + }; + + for (File blueprintFile : blueprintFolder.listFiles(filter)) { + RawBlueprint rawBlueprint = load(blueprintFile); + + if (rawBlueprint == null) { + continue; + } + + Blueprint blueprint; + + try { + blueprint = new Blueprint(meta, rawBlueprint.nbt); + } catch (Exception e) { + // TODO: delete? + continue; + } + + blueprints.put(blueprint.getId(), blueprint); + + return blueprint; + } + + return null; + } + + private static RawBlueprint load(File file) { + InputStream fileIs = null; + ByteArrayOutputStream decompressedStream; + + try { + fileIs = new GZIPInputStream(new FileInputStream(file), bufferSize); + decompressedStream = new ByteArrayOutputStream(bufferSize * 4); + byte buffer[] = new byte[bufferSize]; + int len; + + while ((len = fileIs.read(buffer)) != -1) { + decompressedStream.write(buffer, 0, len); + } + } catch (IOException e) { + Logger.getLogger("Buildcraft").log(Level.SEVERE, String.format("Failed to load Blueprint file: %s %s", file.getName(), e.getMessage())); + return null; + } finally { + try { + fileIs.close(); + } catch (IOException e) {} + } + + byte[] data = decompressedStream.toByteArray(); + BlueprintId id = BlueprintId.generate(data); + + DataInputStream dataIs = new DataInputStream(new ByteArrayInputStream(data)); + NBTTagCompound nbt; + + try { + nbt = CompressedStreamTools.read(dataIs); + } catch (IOException e) { return null; } - return Blueprint.readFromNBT(nbt); + + return new RawBlueprint(id, nbt); } - public static void loadBlueprints() { - FilenameFilter filter = new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return name.endsWith(".nbt"); - } - }; - File blueprintFolder = getBlueprintFolder(); - for (File blueprintFile : blueprintFolder.listFiles(filter)) { - try { - NBTTagCompound nbt = CompressedStreamTools.read(blueprintFile); - addBlueprint(Blueprint.readFromNBT(nbt)); - } catch (IOException ex) { - Logger.getLogger("Buildcraft").log(Level.SEVERE, String.format("Failed to load Blueprint file: %s %s", blueprintFile.getName(), ex.getMessage())); - } + private static class RawBlueprint { + RawBlueprint(BlueprintId id, NBTTagCompound nbt) { + this.id = id; + this.nbt = nbt; } + + final BlueprintId id; + final NBTTagCompound nbt; } - @SideOnly(Side.CLIENT) - public static void sendBlueprintsToServer() { - // TODO - } + private static final int bufferSize = 8192; + private static final String fileExt = ".bpt"; + private static File blueprintFolder; + private static Map blueprintMetas = new HashMap(); + private static Map blueprints = new WeakHashMap(); } diff --git a/common/buildcraft/builders/blueprints/BlueprintId.java b/common/buildcraft/builders/blueprints/BlueprintId.java new file mode 100644 index 00000000..7792d618 --- /dev/null +++ b/common/buildcraft/builders/blueprints/BlueprintId.java @@ -0,0 +1,64 @@ +package buildcraft.builders.blueprints; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; + +public final class BlueprintId { + public static BlueprintId generate(byte[] data) { + try { + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + byte[] id = digest.digest(data); + + return new BlueprintId(id); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + } + + public static BlueprintId fromRawId(byte[] id) { + if (id.length != 32) return null; + + return new BlueprintId(id); + } + + private BlueprintId(byte[] id) { + this.id = id; + } + + public byte[] toRawId() { + return id; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof BlueprintId) { + return Arrays.equals(id, ((BlueprintId) obj).id); + } else { + return false; + } + } + + @Override + public int hashCode() { + return Arrays.hashCode(id); + } + + @Override + public String toString() { + char[] ret = new char[id.length * 2]; + + for (int i = 0; i < id.length; i++) { + ret[i * 2] = toHex(id[i] >>> 4); + ret[i * 2 + 1] = toHex(id[i] & 0xf); + } + + return new String(ret); + } + + private char toHex(int i) { + return (char) (i < 10 ? '0' + i : 'a' - 10 + i); + } + + private final byte[] id; +} diff --git a/common/buildcraft/builders/blueprints/BlueprintMeta.java b/common/buildcraft/builders/blueprints/BlueprintMeta.java new file mode 100644 index 00000000..67c3e5d4 --- /dev/null +++ b/common/buildcraft/builders/blueprints/BlueprintMeta.java @@ -0,0 +1,60 @@ +package buildcraft.builders.blueprints; + +import net.minecraft.nbt.NBTTagCompound; + +public class BlueprintMeta { + private final String version = "Blueprint-2.0"; + private BlueprintId id; + private String name; + private String creator; + + protected BlueprintMeta() { + } + + protected BlueprintMeta(BlueprintId id, NBTTagCompound nbt) { + this.id = id; + + name = nbt.getString("name"); + creator = nbt.getString("creator"); + } + + protected BlueprintId getId() { + return id; + } + + protected void setId(BlueprintId id) { + this.id = id; + } + + protected String getName() { + return name; + } + + protected void setName(String name) { + if (getId() != null) throw new IllegalStateException("modifying finalized blueprint"); + + this.name = name; + } + + /** + * @return the creator + */ + protected String getCreator() { + return creator; + } + + /** + * @param creator the creator to set + */ + protected void setCreator(String creator) { + if (getId() != null) throw new IllegalStateException("modifying finalized blueprint"); + + this.creator = creator; + } + + protected void writeToNBT(NBTTagCompound nbt) { + nbt.setString("name", name); + nbt.setString("version", version); + nbt.setString("creator", creator); + } +} \ No newline at end of file diff --git a/common/buildcraft/factory/TileQuarry.java b/common/buildcraft/factory/TileQuarry.java index 8ff61649..a9ff29aa 100644 --- a/common/buildcraft/factory/TileQuarry.java +++ b/common/buildcraft/factory/TileQuarry.java @@ -51,7 +51,6 @@ import net.minecraftforge.common.ForgeChunkManager; import net.minecraftforge.common.ForgeChunkManager.Ticket; import net.minecraftforge.common.ForgeChunkManager.Type; import net.minecraftforge.common.ForgeDirection; -import static net.minecraftforge.common.ForgeDirection.*; public class TileQuarry extends TileBuildCraft implements IMachine, IPowerReceptor, IBuilderInventory { @@ -274,14 +273,14 @@ public class TileQuarry extends TileBuildCraft implements IMachine, IPowerRecept } } } - if (columnVisitListIsUpdated && nextTarget == null && !visitList.isEmpty()) - { - nextTarget = visitList.removeFirst(); - } - else if (columnVisitListIsUpdated && nextTarget == null) - { - return false; - } + if (columnVisitListIsUpdated && nextTarget == null && !visitList.isEmpty()) + { + nextTarget = visitList.removeFirst(); + } + else if (columnVisitListIsUpdated && nextTarget == null) + { + return false; + } setTarget(nextTarget[0], nextTarget[1] + 1, nextTarget[2]); @@ -332,7 +331,7 @@ public class TileQuarry extends TileBuildCraft implements IMachine, IPowerRecept if (height > 0 && height < by && worldObj.provider.dimensionId != -1) { - continue; + continue; } int blockID = worldObj.getBlockId(bx, by, bz); @@ -342,11 +341,11 @@ public class TileQuarry extends TileBuildCraft implements IMachine, IPowerRecept } else if (!BlockUtil.isSoftBlock(blockID, worldObj, bx, by, bz)) { visitList.add(new int[]{bx, by, bz}); } - if (height == 0 && !worldObj.isAirBlock(bx, by, bz)) - { - columnHeights[searchX][searchZ] = by; - } - + if (height == 0 && !worldObj.isAirBlock(bx, by, bz)) + { + columnHeights[searchX][searchZ] = by; + } + // Stop at two planes - generally any obstructions will have been found and will force a recompute prior to this if (visitList.size() > blueprintBuilder.blueprint.sizeZ * blueprintBuilder.blueprint.sizeX * 2) return; @@ -539,7 +538,7 @@ public class TileQuarry extends TileBuildCraft implements IMachine, IPowerRecept if (placedBy != null && CoreProxy.proxy.isSimulating(worldObj)) { PacketDispatcher.sendPacketToPlayer( new Packet3Chat(ChatMessageComponent.createFromText(String.format("[BUILDCRAFT] The quarry at %d, %d, %d will not work because there are no more chunkloaders available", - xCoord, yCoord, zCoord))), (Player) placedBy); + xCoord, yCoord, zCoord))), (Player) placedBy); } sendNetworkUpdate(); return; @@ -568,7 +567,7 @@ public class TileQuarry extends TileBuildCraft implements IMachine, IPowerRecept if (placedBy != null) { PacketDispatcher.sendPacketToPlayer( new Packet3Chat(ChatMessageComponent.createFromText(String.format("Quarry size is outside of chunkloading bounds or too small %d %d (%d)", xSize, zSize, - chunkTicket.getMaxChunkListDepth()))), (Player) placedBy); + chunkTicket.getMaxChunkListDepth()))), (Player) placedBy); } a = new DefaultAreaProvider(xCoord, yCoord, zCoord, xCoord + 10, yCoord + 4, zCoord + 10); @@ -592,23 +591,23 @@ public class TileQuarry extends TileBuildCraft implements IMachine, IPowerRecept ForgeDirection o = ForgeDirection.values()[worldObj.getBlockMetadata(xCoord, yCoord, zCoord)].getOpposite(); switch (o) { - case EAST: - xMin = xCoord + 1; - zMin = zCoord - 4 - 1; - break; - case WEST: - xMin = xCoord - 9 - 2; - zMin = zCoord - 4 - 1; - break; - case SOUTH: - xMin = xCoord - 4 - 1; - zMin = zCoord + 1; - break; - case NORTH: - default: - xMin = xCoord - 4 - 1; - zMin = zCoord - 9 - 2; - break; + case EAST: + xMin = xCoord + 1; + zMin = zCoord - 4 - 1; + break; + case WEST: + xMin = xCoord - 9 - 2; + zMin = zCoord - 4 - 1; + break; + case SOUTH: + xMin = xCoord - 4 - 1; + zMin = zCoord + 1; + break; + case NORTH: + default: + xMin = xCoord - 4 - 1; + zMin = zCoord - 9 - 2; + break; } box.initialize(xMin, yCoord, zMin, xMin + xSize - 1, yCoord + ySize - 1, zMin + zSize - 1); @@ -619,7 +618,7 @@ public class TileQuarry extends TileBuildCraft implements IMachine, IPowerRecept } private void initializeBlueprintBuilder() { - Blueprint blueprint = new Blueprint(box.sizeX(), box.sizeY(), box.sizeZ()); + Blueprint blueprint = Blueprint.create(box.sizeX(), box.sizeY(), box.sizeZ()); for (int it = 0; it < 2; it++) { for (int i = 0; i < blueprint.sizeX; ++i) {