diff --git a/api/buildcraft/api/library/ILibraryTypeHandler.java b/api/buildcraft/api/library/ILibraryTypeHandler.java new file mode 100644 index 00000000..2aa03380 --- /dev/null +++ b/api/buildcraft/api/library/ILibraryTypeHandler.java @@ -0,0 +1,14 @@ +package buildcraft.api.library; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +public interface ILibraryTypeHandler { + boolean isHandler(ItemStack stack, boolean store); + String getFileExtension(); + int getTextColor(); + String getName(ItemStack stack); + + ItemStack load(ItemStack stack, NBTTagCompound compound); + boolean store(ItemStack stack, NBTTagCompound compound); +} diff --git a/api/buildcraft/api/library/LibraryAPI.java b/api/buildcraft/api/library/LibraryAPI.java new file mode 100644 index 00000000..590935a5 --- /dev/null +++ b/api/buildcraft/api/library/LibraryAPI.java @@ -0,0 +1,28 @@ +package buildcraft.api.library; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class LibraryAPI { + private static final Set handlers = new HashSet(); + private static final Map handlersByExt = new HashMap(); + + private LibraryAPI() { + + } + + public static Set getHandlerSet() { + return handlers; + } + + public static void registerHandler(ILibraryTypeHandler handler) { + handlers.add(handler); + handlersByExt.put(handler.getFileExtension(), handler); + } + + public static ILibraryTypeHandler getHandler(String ext) { + return handlersByExt.get(ext); + } +} diff --git a/api/buildcraft/api/library/package-info.java b/api/buildcraft/api/library/package-info.java new file mode 100644 index 00000000..d67f14a0 --- /dev/null +++ b/api/buildcraft/api/library/package-info.java @@ -0,0 +1,12 @@ +/** + * Copyright (c) 2011-2015, SpaceToad and the BuildCraft Team + * http://www.mod-buildcraft.com + * + * The BuildCraft API is distributed under the terms of the MIT License. + * Please check the contents of the license, which should be located + * as "LICENSE.API" in the BuildCraft source code distribution. + */ +@API(apiVersion = "1.0", owner = "BuildCraftAPI|core", provides = "BuildCraftAPI|library") +package buildcraft.api.library; +import cpw.mods.fml.common.API; + diff --git a/buildcraft_resources/assets/buildcraft/lang/en_US.lang b/buildcraft_resources/assets/buildcraft/lang/en_US.lang index f66512bb..20cf1b20 100644 --- a/buildcraft_resources/assets/buildcraft/lang/en_US.lang +++ b/buildcraft_resources/assets/buildcraft/lang/en_US.lang @@ -289,7 +289,7 @@ tile.floodGateBlock.name=Flood Gate tile.frameBlock.name=Frame tile.integrationTableBlock.name=Integration Table tile.laserBlock.name=Laser -tile.libraryBlock.name=Blueprint Library +tile.libraryBlock.name=Electronic Library tile.machineBlock.name=Quarry tile.markerBlock.name=Land Mark tile.miningWellBlock.name=Mining Well diff --git a/common/buildcraft/BuildCraftBuilders.java b/common/buildcraft/BuildCraftBuilders.java index f396d760..48582673 100644 --- a/common/buildcraft/BuildCraftBuilders.java +++ b/common/buildcraft/BuildCraftBuilders.java @@ -56,6 +56,7 @@ import buildcraft.api.core.BCLog; import buildcraft.api.core.JavaTools; import buildcraft.api.filler.FillerManager; import buildcraft.api.filler.IFillerPattern; +import buildcraft.api.library.LibraryAPI; import buildcraft.api.statements.StatementManager; import buildcraft.builders.BlockArchitect; import buildcraft.builders.BlockBlueprintLibrary; @@ -65,6 +66,7 @@ import buildcraft.builders.BlockConstructionMarker; import buildcraft.builders.BlockFiller; import buildcraft.builders.BlockMarker; import buildcraft.builders.BlockPathMarker; +import buildcraft.builders.BlueprintServerDatabase; import buildcraft.builders.BuilderProxy; import buildcraft.builders.EventHandlerBuilders; import buildcraft.builders.BuildersGuiHandler; @@ -72,6 +74,8 @@ import buildcraft.builders.HeuristicBlockDetection; import buildcraft.builders.ItemBlueprintStandard; import buildcraft.builders.ItemBlueprintTemplate; import buildcraft.builders.ItemConstructionMarker; +import buildcraft.builders.LibraryBlueprintTypeHandler; +import buildcraft.builders.LibraryBookTypeHandler; import buildcraft.builders.TileArchitect; import buildcraft.builders.TileBlueprintLibrary; import buildcraft.builders.TileBuilder; @@ -79,7 +83,7 @@ import buildcraft.builders.TileConstructionMarker; import buildcraft.builders.TileFiller; import buildcraft.builders.TileMarker; import buildcraft.builders.TilePathMarker; -import buildcraft.builders.blueprints.BlueprintDatabase; +import buildcraft.builders.LibraryDatabase; import buildcraft.builders.schematics.SchematicAir; import buildcraft.builders.schematics.SchematicBed; import buildcraft.builders.schematics.SchematicBlockCreative; @@ -167,23 +171,27 @@ public class BuildCraftBuilders extends BuildCraftMod { public static Achievement builderAchievement; public static Achievement templateAchievement; - public static BlueprintDatabase serverDB; - public static BlueprintDatabase clientDB; + public static BlueprintServerDatabase serverDB; + public static LibraryDatabase clientDB; public static boolean debugPrintSchematicList = false; public static boolean dropBrokenBlocks = false; - + + private String blueprintServerDir; + private String blueprintLibraryOutput; + private String[] blueprintLibraryInput; + @Mod.EventHandler public void loadConfiguration(FMLPreInitializationEvent evt) { - String blueprintServerDir = BuildCraftCore.mainConfiguration.get(Configuration.CATEGORY_GENERAL, + blueprintServerDir = BuildCraftCore.mainConfiguration.get(Configuration.CATEGORY_GENERAL, "blueprints.serverDir", "\"$MINECRAFT" + File.separator + "config" + File.separator + "buildcraft" + File.separator + "blueprints" + File.separator + "server\"").getString(); - String blueprintLibraryOutput = BuildCraftCore.mainConfiguration.get(Configuration.CATEGORY_GENERAL, + blueprintLibraryOutput = BuildCraftCore.mainConfiguration.get(Configuration.CATEGORY_GENERAL, "blueprints.libraryOutput", "\"$MINECRAFT" + File.separator + "blueprints\"").getString(); - String [] blueprintLibraryInput = BuildCraftCore.mainConfiguration.get(Configuration.CATEGORY_GENERAL, + blueprintLibraryInput = BuildCraftCore.mainConfiguration.get(Configuration.CATEGORY_GENERAL, "blueprints.libraryInput", new String [] { // expected location @@ -217,12 +225,6 @@ public class BuildCraftBuilders extends BuildCraftMod { if (BuildCraftCore.mainConfiguration.hasChanged()) { BuildCraftCore.mainConfiguration.save(); } - - serverDB = new BlueprintDatabase(); - clientDB = new BlueprintDatabase(); - - serverDB.init(new String[] {blueprintServerDir}, blueprintServerDir); - clientDB.init(blueprintLibraryInput, blueprintLibraryOutput); } private static String getDownloadsDir() { @@ -273,7 +275,13 @@ public class BuildCraftBuilders extends BuildCraftMod { @Mod.EventHandler public void postInit(FMLPostInitializationEvent evt) { HeuristicBlockDetection.start(); - + + serverDB = new BlueprintServerDatabase(); + clientDB = new LibraryDatabase(); + + serverDB.init(new String[] {blueprintServerDir}, blueprintServerDir); + clientDB.init(blueprintLibraryInput, blueprintLibraryOutput); + if (debugPrintSchematicList) { try { PrintWriter writer = new PrintWriter("SchematicDebug.txt", "UTF-8"); @@ -455,6 +463,10 @@ public class BuildCraftBuilders extends BuildCraftMod { SchematicFactory.registerSchematicFactory(SchematicMask.class, new SchematicFactoryMask()); SchematicFactory.registerSchematicFactory(SchematicEntity.class, new SchematicFactoryEntity()); + LibraryAPI.registerHandler(new LibraryBlueprintTypeHandler(false)); // Template + LibraryAPI.registerHandler(new LibraryBlueprintTypeHandler(true)); // Blueprint + LibraryAPI.registerHandler(new LibraryBookTypeHandler()); + BlueprintDeployer.instance = new RealBlueprintDeployer(); architectAchievement = BuildCraftCore.achievementManager.registerAchievement(new Achievement("achievement.architect", "architectAchievement", 11, 2, BuildCraftBuilders.architectBlock, BuildCraftCore.goldGearAchievement)); diff --git a/common/buildcraft/builders/BlueprintServerDatabase.java b/common/buildcraft/builders/BlueprintServerDatabase.java new file mode 100644 index 00000000..692479fa --- /dev/null +++ b/common/buildcraft/builders/BlueprintServerDatabase.java @@ -0,0 +1,14 @@ +package buildcraft.builders; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import net.minecraft.nbt.NBTTagCompound; +import buildcraft.api.core.BCLog; +import buildcraft.core.blueprints.BlueprintBase; +import buildcraft.core.blueprints.LibraryId; +import buildcraft.core.lib.utils.NBTUtils; + +public class BlueprintServerDatabase extends LibraryDatabase { + +} diff --git a/common/buildcraft/builders/ItemBlueprint.java b/common/buildcraft/builders/ItemBlueprint.java index 3e087874..13fd27d2 100644 --- a/common/buildcraft/builders/ItemBlueprint.java +++ b/common/buildcraft/builders/ItemBlueprint.java @@ -17,8 +17,10 @@ import net.minecraft.util.IIcon; import buildcraft.BuildCraftBuilders; import buildcraft.api.blueprints.BuildingPermission; -import buildcraft.core.blueprints.BlueprintId; +import buildcraft.core.blueprints.Blueprint; +import buildcraft.core.blueprints.LibraryId; import buildcraft.core.BCCreativeTab; +import buildcraft.core.blueprints.Template; import buildcraft.core.lib.items.ItemBuildCraft; import buildcraft.core.blueprints.BlueprintBase; import buildcraft.core.lib.utils.NBTUtils; @@ -72,12 +74,12 @@ public abstract class ItemBlueprint extends ItemBuildCraft { return NBTUtils.getItemData(stack).hasKey("name") ? 1 : 16; } - public static BlueprintId getId (ItemStack stack) { + public static LibraryId getId (ItemStack stack) { NBTTagCompound nbt = NBTUtils.getItemData(stack); if (nbt == null) { return null; } - BlueprintId id = new BlueprintId (); + LibraryId id = new LibraryId(); id.read (nbt); if (BuildCraftBuilders.serverDB.exists(id)) { @@ -88,7 +90,21 @@ public abstract class ItemBlueprint extends ItemBuildCraft { } public static BlueprintBase loadBlueprint(ItemStack stack) { - return BuildCraftBuilders.serverDB.load(getId(stack)); + if (stack == null) { + return null; + } + + LibraryId id = getId(stack); + NBTTagCompound nbt = BuildCraftBuilders.serverDB.load(id); + BlueprintBase base; + if (stack.getItem() instanceof ItemBlueprintTemplate) { + base = new Template(); + } else { + base = new Blueprint(); + } + base.readFromNBT(nbt); + base.id = id; + return base; } public abstract String getIconType(); diff --git a/common/buildcraft/builders/LibraryBlueprintTypeHandler.java b/common/buildcraft/builders/LibraryBlueprintTypeHandler.java new file mode 100644 index 00000000..bae88453 --- /dev/null +++ b/common/buildcraft/builders/LibraryBlueprintTypeHandler.java @@ -0,0 +1,59 @@ +package buildcraft.builders; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import buildcraft.BuildCraftBuilders; +import buildcraft.api.library.ILibraryTypeHandler; +import buildcraft.core.blueprints.BlueprintBase; + +public class LibraryBlueprintTypeHandler implements ILibraryTypeHandler { + private final boolean isBlueprint; + + public LibraryBlueprintTypeHandler(boolean isBlueprint) { + this.isBlueprint = isBlueprint; + } + + @Override + public boolean isHandler(ItemStack stack, boolean store) { + if (isBlueprint) { + return stack.getItem() instanceof ItemBlueprintStandard; + } else { + return stack.getItem() instanceof ItemBlueprintTemplate; + } + } + + @Override + public String getFileExtension() { + return isBlueprint ? "bpt" : "tpl"; + } + + @Override + public int getTextColor() { + return isBlueprint ? 0x305080 : 0; + } + + @Override + public String getName(ItemStack stack) { + return ItemBlueprint.getId(stack).name; + } + + @Override + public ItemStack load(ItemStack stack, NBTTagCompound compound) { + BlueprintBase blueprint = BlueprintBase.loadBluePrint(compound); + blueprint.id.name = compound.getString("__filename"); + blueprint.id.extension = getFileExtension(); + BuildCraftBuilders.serverDB.add(blueprint.id, compound); + return blueprint.getStack(); + } + + @Override + public boolean store(ItemStack stack, NBTTagCompound compound) { + BlueprintBase blueprint = ItemBlueprint.loadBlueprint(stack); + if (blueprint != null) { + blueprint.writeToNBT(compound); + blueprint.id.write(compound); + return true; + } + return false; + } +} diff --git a/common/buildcraft/builders/LibraryBookTypeHandler.java b/common/buildcraft/builders/LibraryBookTypeHandler.java new file mode 100644 index 00000000..54fa312c --- /dev/null +++ b/common/buildcraft/builders/LibraryBookTypeHandler.java @@ -0,0 +1,54 @@ +package buildcraft.builders; + +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import buildcraft.api.library.ILibraryTypeHandler; +import buildcraft.core.lib.utils.NBTUtils; + +public class LibraryBookTypeHandler implements ILibraryTypeHandler { + @Override + public boolean isHandler(ItemStack stack, boolean store) { + if (store) { + return stack.getItem() == Items.written_book; + } else { + return stack.getItem() == Items.writable_book || stack.getItem() == Items.written_book; + } + } + + @Override + public String getFileExtension() { + return "book"; + } + + @Override + public int getTextColor() { + return 0x684804; + } + + @Override + public String getName(ItemStack stack) { + String s = NBTUtils.getItemData(stack).getString("title"); + return s != null ? s : ""; + } + + @Override + public ItemStack load(ItemStack stack, NBTTagCompound compound) { + ItemStack out = new ItemStack(Items.written_book); + NBTTagCompound outNBT = new NBTTagCompound(); + outNBT.setString("title", compound.getString("title")); + outNBT.setString("author", compound.getString("author")); + outNBT.setTag("pages", compound.getTagList("pages", 8)); + out.setTagCompound(outNBT); + return out; + } + + @Override + public boolean store(ItemStack stack, NBTTagCompound compound) { + NBTTagCompound inNBT = NBTUtils.getItemData(stack); + compound.setString("title", inNBT.getString("title")); + compound.setString("author", inNBT.getString("author")); + compound.setTag("pages", inNBT.getTagList("pages", 8)); + return true; + } +} diff --git a/common/buildcraft/builders/blueprints/BlueprintDatabase.java b/common/buildcraft/builders/LibraryDatabase.java similarity index 55% rename from common/buildcraft/builders/blueprints/BlueprintDatabase.java rename to common/buildcraft/builders/LibraryDatabase.java index 95aa8d0c..117c8a18 100644 --- a/common/buildcraft/builders/blueprints/BlueprintDatabase.java +++ b/common/buildcraft/builders/LibraryDatabase.java @@ -6,7 +6,7 @@ * License 1.0, or MMPL. Please check the contents of the license located in * http://www.mod-buildcraft.com/MMPL-1.0.txt */ -package buildcraft.builders.blueprints; +package buildcraft.builders; import java.io.File; import java.io.FileInputStream; @@ -25,21 +25,19 @@ import net.minecraft.nbt.NBTTagCompound; import buildcraft.BuildCraftBuilders; import buildcraft.api.core.BCLog; -import buildcraft.core.blueprints.BlueprintId; -import buildcraft.core.blueprints.BlueprintId.Kind; +import buildcraft.api.library.LibraryAPI; +import buildcraft.core.blueprints.LibraryId; import buildcraft.core.blueprints.BlueprintBase; +import buildcraft.core.lib.utils.NBTUtils; -public class BlueprintDatabase { - private static final String BPT_EXTENSION = ".bpt"; - private static final String TPL_EXTENSION = ".tpl"; +public class LibraryDatabase { private static final int PAGE_SIZE = 12; - private final int bufferSize = 8192; private File outputDir; private File[] inputDirs; - private Set blueprintIds; - private BlueprintId [] pages = new BlueprintId [0]; + protected Set blueprintIds; + protected LibraryId[] pages = new LibraryId[0]; /** * Initialize the blueprint database. @@ -63,65 +61,23 @@ public class BlueprintDatabase { } public void refresh() { - blueprintIds = new TreeSet(); + blueprintIds = new TreeSet(); loadIndex(inputDirs); } - /** - * Add a blueprint to the database and save it to disk. - * - * @param blueprint blueprint to add - * @return id for the added blueprint - */ - public BlueprintId add(BlueprintBase blueprint) { - BlueprintId id = save(blueprint); - - if (!blueprintIds.contains(id)) { - blueprintIds.add(id); - pages = blueprintIds.toArray(pages); - } - - return id; - } - - public void deleteBlueprint (BlueprintId id) { + public void deleteBlueprint (LibraryId id) { File blueprintFile = getBlueprintFile(id); if (blueprintFile != null) { blueprintFile.delete(); blueprintIds.remove(id); - pages = new BlueprintId[blueprintIds.size()]; + pages = new LibraryId[blueprintIds.size()]; pages = blueprintIds.toArray(pages); } } - private BlueprintId save(BlueprintBase blueprint) { - blueprint.id.generateUniqueId(blueprint.getData()); - - BlueprintId id = blueprint.id; - File blueprintFile = getBlueprintFile(id, outputDir); - - if (!blueprintFile.exists()) { - try { - FileOutputStream f = new FileOutputStream(blueprintFile); - f.write(blueprint.getData()); - f.close(); - } catch (IOException ex) { - BCLog.logger.error(String.format("Failed to save Blueprint file: %s %s", blueprintFile.getName(), ex.getMessage())); - } - } - - return id; - } - - private File getBlueprintFile(BlueprintId id) { - String name = ""; - - if (id.kind == Kind.Blueprint) { - name = String.format(Locale.ENGLISH, "%s" + BPT_EXTENSION, id.toString()); - } else { - name = String.format(Locale.ENGLISH, "%s" + TPL_EXTENSION, id.toString()); - } + protected File getBlueprintFile(LibraryId id) { + String name = String.format(Locale.ENGLISH, "%s." + id.extension, id.toString()); for (File dir : inputDirs) { File f = new File(dir, name); @@ -134,16 +90,35 @@ public class BlueprintDatabase { return null; } - private File getBlueprintFile(BlueprintId id, File folder) { - String name = ""; + protected File getBlueprintOutputFile(LibraryId id) { + String name = String.format(Locale.ENGLISH, "%s." + id.extension, id.toString()); - if (id.kind == Kind.Blueprint) { - name = String.format(Locale.ENGLISH, "%s" + BPT_EXTENSION, id.toString()); - } else { - name = String.format(Locale.ENGLISH, "%s" + TPL_EXTENSION, id.toString()); + return new File(outputDir, name); + } + + public void add(LibraryId base, NBTTagCompound compound) { + save(base, compound); + + if (!blueprintIds.contains(base)) { + blueprintIds.add(base); + pages = blueprintIds.toArray(pages); } + } - return new File(folder, name); + private void save(LibraryId base, NBTTagCompound compound) { + byte[] data = NBTUtils.save(compound); + base.generateUniqueId(data); + File blueprintFile = getBlueprintOutputFile(base); + + if (!blueprintFile.exists()) { + try { + FileOutputStream f = new FileOutputStream(blueprintFile); + f.write(data); + f.close(); + } catch (IOException ex) { + BCLog.logger.error(String.format("Failed to save library file: %s %s", blueprintFile.getName(), ex.getMessage())); + } + } } private void loadIndex(File[] dirs) { @@ -158,7 +133,9 @@ public class BlueprintDatabase { FilenameFilter filter = new FilenameFilter() { @Override public boolean accept(File dir, String name) { - return name.endsWith(BPT_EXTENSION) || name.endsWith(TPL_EXTENSION); + int dotIndex = name.lastIndexOf('.') + 1; + String extension = name.substring(dotIndex); + return LibraryAPI.getHandler(extension) != null; } }; @@ -171,58 +148,48 @@ public class BlueprintDatabase { for (File blueprintFile : files) { String fileName = blueprintFile.getName(); - BlueprintId id = new BlueprintId(); + LibraryId id = new LibraryId(); int sepIndex = fileName.lastIndexOf(BuildCraftBuilders.BPT_SEP_CHARACTER); int dotIndex = fileName.lastIndexOf('.'); - String extension = fileName.substring(dotIndex); + String extension = fileName.substring(dotIndex + 1); if (sepIndex > 0) { String prefix = fileName.substring(0, sepIndex); String suffix = fileName.substring(sepIndex + 1); id.name = prefix; - id.uniqueId = BlueprintId.toBytes(suffix.substring(0, suffix.length() - 4)); + id.uniqueId = LibraryId.toBytes(suffix.substring(0, suffix.length() - 4)); } else { id.name = fileName.substring(0, dotIndex); id.uniqueId = new byte[0]; } - - if (extension.equals(BPT_EXTENSION)) { - id.kind = Kind.Blueprint; - } else { - id.kind = Kind.Template; - } + id.extension = extension; if (!blueprintIds.contains(id)) { blueprintIds.add(id); } } - pages = blueprintIds.toArray(new BlueprintId[blueprintIds.size()]); + pages = blueprintIds.toArray(new LibraryId[blueprintIds.size()]); } } - public boolean exists (BlueprintId id) { + public boolean exists (LibraryId id) { return blueprintIds.contains(id); } - public BlueprintBase load(final BlueprintId id) { + public NBTTagCompound load(final LibraryId id) { if (id == null) { return null; } - BlueprintBase bpt = load (getBlueprintFile(id)); - - if (bpt != null) { - bpt.id = id; - } - - return bpt; + NBTTagCompound compound = load(getBlueprintFile(id)); + return compound; } - public static BlueprintBase load (File blueprintFile) { + public static NBTTagCompound load (File blueprintFile) { if (blueprintFile != null && blueprintFile.exists()) { try { FileInputStream f = new FileInputStream(blueprintFile); @@ -230,7 +197,7 @@ public class BlueprintDatabase { f.read (data); f.close(); - return load(data); + return NBTUtils.load(data); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { @@ -241,23 +208,8 @@ public class BlueprintDatabase { return null; } - public static BlueprintBase load(byte[] data) { - try { - NBTTagCompound nbt = CompressedStreamTools.func_152457_a(data, NBTSizeTracker.field_152451_a); - - BlueprintBase blueprint = BlueprintBase.loadBluePrint(nbt); - blueprint.setData(data); - - return blueprint; - } catch (IOException e) { - e.printStackTrace(); - } - - return null; - } - - public ArrayList getPage (int pageId) { - ArrayList result = new ArrayList(); + public ArrayList getPage (int pageId) { + ArrayList result = new ArrayList(); if (pageId < 0) { return result; diff --git a/common/buildcraft/builders/TileBlueprintLibrary.java b/common/buildcraft/builders/TileBlueprintLibrary.java index e481faa4..43557352 100644 --- a/common/buildcraft/builders/TileBlueprintLibrary.java +++ b/common/buildcraft/builders/TileBlueprintLibrary.java @@ -24,14 +24,16 @@ import cpw.mods.fml.relauncher.Side; import buildcraft.BuildCraftBuilders; import buildcraft.BuildCraftCore; -import buildcraft.core.blueprints.BlueprintId; -import buildcraft.core.blueprints.BlueprintId.Kind; +import buildcraft.api.library.ILibraryTypeHandler; +import buildcraft.api.library.LibraryAPI; +import buildcraft.core.blueprints.LibraryId; import buildcraft.core.lib.block.TileBuildCraft; import buildcraft.core.blueprints.BlueprintBase; import buildcraft.core.lib.inventory.SimpleInventory; import buildcraft.core.lib.network.command.CommandWriter; import buildcraft.core.lib.network.command.ICommandReceiver; import buildcraft.core.lib.network.command.PacketCommand; +import buildcraft.core.lib.utils.NBTUtils; import buildcraft.core.lib.utils.NetworkUtils; /** @@ -43,12 +45,12 @@ public class TileBlueprintLibrary extends TileBuildCraft implements IInventory, private static final int PROGRESS_TIME = 100; private static final int CHUNK_SIZE = 16384; - public SimpleInventory inv = new SimpleInventory(4, "Blueprint Library", 1); + public SimpleInventory inv = new SimpleInventory(4, "Electronic Library", 1); public int progressIn = 0; public int progressOut = 0; - public ArrayList currentPage; + public ArrayList currentPage; public int selected = -1; @@ -57,7 +59,7 @@ public class TileBlueprintLibrary extends TileBuildCraft implements IInventory, public int pageId = 0; - private BlueprintId blueprintDownloadId; + private LibraryId blueprintDownloadId; private byte[] blueprintDownload; public TileBlueprintLibrary() { @@ -78,7 +80,7 @@ public class TileBlueprintLibrary extends TileBuildCraft implements IInventory, refresh(); } - public void setCurrentPage(ArrayList newPage) { + public void setCurrentPage(ArrayList newPage) { currentPage = newPage; selected = -1; } @@ -161,7 +163,7 @@ public class TileBlueprintLibrary extends TileBuildCraft implements IInventory, inv.setInventorySlotContents(i, itemstack); if (i == 0) { - if (getStackInSlot(0) != null && getStackInSlot(0).getItem() instanceof ItemBlueprint) { + if (getStackInSlot(0) != null && findHandler(0, true) != null) { progressIn = 1; } else { progressIn = 0; @@ -169,7 +171,7 @@ public class TileBlueprintLibrary extends TileBuildCraft implements IInventory, } if (i == 2) { - if (getStackInSlot(2) != null && getStackInSlot(2).getItem() instanceof ItemBlueprint) { + if (getStackInSlot(2) != null && findHandler(2, false) != null) { progressOut = 1; } else { progressOut = 0; @@ -210,6 +212,18 @@ public class TileBlueprintLibrary extends TileBuildCraft implements IInventory, public void closeInventory() { } + private ILibraryTypeHandler findHandler(int slot, boolean store) { + ItemStack stack = getStackInSlot(slot); + + for (ILibraryTypeHandler h : LibraryAPI.getHandlerSet()) { + if (h.isHandler(stack, store)) { + return h; + } + } + + return null; + } + @Override public void updateEntity() { super.updateEntity(); @@ -223,7 +237,7 @@ public class TileBlueprintLibrary extends TileBuildCraft implements IInventory, } if (progressOut > 0 && progressOut < PROGRESS_TIME) { - if (selected == -1) { + if (selected != -1) { progressOut++; } else { progressOut = 1; @@ -233,17 +247,34 @@ public class TileBlueprintLibrary extends TileBuildCraft implements IInventory, // On progress IN, we'll download the blueprint from the server to the // client, and then store it to the client. if (progressIn == 100 && getStackInSlot(1) == null) { + final NBTTagCompound nbt = new NBTTagCompound(); + ILibraryTypeHandler handler = findHandler(0, true); + + if (handler == null) { + uploadingPlayer = null; + return; + } + + if (!handler.store(getStackInSlot(0), nbt)) { + uploadingPlayer = null; + return; + } + setInventorySlotContents(1, getStackInSlot(0)); setInventorySlotContents(0, null); - final BlueprintBase bpt = ItemBlueprint.loadBlueprint(getStackInSlot(1)); + final LibraryId id = new LibraryId(); + id.name = handler.getName(getStackInSlot(1)); + id.extension = handler.getFileExtension(); - if (bpt != null && uploadingPlayer != null) { + if (uploadingPlayer != null) { BuildCraftCore.instance.sendToPlayer(uploadingPlayer, new PacketCommand(this, "downloadBlueprintToClient", new CommandWriter() { public void write(ByteBuf data) { - bpt.id.writeData(data); - NetworkUtils.writeByteArray(data, bpt.getData()); + byte[] bytes = NBTUtils.save(nbt); + id.generateUniqueId(bytes); + id.writeData(data); + NetworkUtils.writeByteArray(data, bytes); } })); uploadingPlayer = null; @@ -268,15 +299,16 @@ public class TileBlueprintLibrary extends TileBuildCraft implements IInventory, if (isOutputConsistent()) { if (selected > -1 && selected < currentPage.size()) { // Work around 32k max limit on client->server - final BlueprintBase bpt = BuildCraftBuilders.clientDB + final NBTTagCompound compound = BuildCraftBuilders.clientDB .load(currentPage.get(selected)); - final byte[] bptData = bpt.getData(); + compound.setString("__filename", currentPage.get(selected).name); + final byte[] bptData = NBTUtils.save(compound); final int chunks = (bptData.length + CHUNK_SIZE - 1) / CHUNK_SIZE; BuildCraftCore.instance.sendToServer(new PacketCommand(this, "uploadServerBegin", new CommandWriter() { public void write(ByteBuf data) { - bpt.id.writeData(data); + currentPage.get(selected).writeData(data); data.writeShort(chunks); } })); @@ -301,17 +333,18 @@ public class TileBlueprintLibrary extends TileBuildCraft implements IInventory, } } } else if ("downloadBlueprintToClient".equals(command)) { - BlueprintId id = new BlueprintId(); + LibraryId id = new LibraryId(); id.readData(stream); byte[] data = NetworkUtils.readByteArray(stream); try { - NBTTagCompound nbt = CompressedStreamTools.func_152457_a(data, NBTSizeTracker.field_152451_a); - BlueprintBase bpt = BlueprintBase.loadBluePrint(nbt); - bpt.setData(data); - bpt.id = id; + ILibraryTypeHandler handler = LibraryAPI.getHandler(id.extension); + if (handler == null) { + return; + } - BuildCraftBuilders.clientDB.add(bpt); + NBTTagCompound nbt = CompressedStreamTools.func_152457_a(data, NBTSizeTracker.field_152451_a); + BuildCraftBuilders.clientDB.add(id, nbt); setCurrentPage(BuildCraftBuilders.clientDB.getPage(pageId)); } catch (IOException e) { e.printStackTrace(); @@ -324,7 +357,7 @@ public class TileBlueprintLibrary extends TileBuildCraft implements IInventory, downloadingPlayer = null; } else if ("uploadServerBegin".equals(command)) { - blueprintDownloadId = new BlueprintId(); + blueprintDownloadId = new LibraryId(); blueprintDownloadId.readData(stream); blueprintDownload = new byte[CHUNK_SIZE * stream.readUnsignedShort()]; } else if ("uploadServerChunk".equals(command)) { @@ -338,12 +371,9 @@ public class TileBlueprintLibrary extends TileBuildCraft implements IInventory, } else if ("uploadServerEnd".equals(command)) { try { NBTTagCompound nbt = CompressedStreamTools.func_152457_a(blueprintDownload, NBTSizeTracker.field_152451_a); - BlueprintBase bpt = BlueprintBase.loadBluePrint(nbt); - bpt.setData(blueprintDownload); - bpt.id = blueprintDownloadId; - BuildCraftBuilders.serverDB.add(bpt); + ItemStack output = LibraryAPI.getHandler(blueprintDownloadId.extension).load(getStackInSlot(2), nbt); - setInventorySlotContents(3, bpt.getStack()); + setInventorySlotContents(3, output); setInventorySlotContents(2, null); } catch (IOException e) { e.printStackTrace(); @@ -352,12 +382,20 @@ public class TileBlueprintLibrary extends TileBuildCraft implements IInventory, blueprintDownloadId = null; blueprintDownload = null; downloadingPlayer = null; + } else if ("selectBlueprint".equals(command)) { + selected = stream.readInt(); } } } public void selectBlueprint (int index) { selected = index; + BuildCraftCore.instance.sendToServer(new PacketCommand(this, "selectBlueprint", new CommandWriter() { + @Override + public void write(ByteBuf data) { + data.writeInt(selected); + } + })); } private boolean isOutputConsistent () { @@ -365,9 +403,6 @@ public class TileBlueprintLibrary extends TileBuildCraft implements IInventory, return false; } - return (getStackInSlot(2).getItem() instanceof ItemBlueprintStandard - && currentPage.get(selected).kind == Kind.Blueprint) || - (getStackInSlot(2).getItem() instanceof ItemBlueprintTemplate - && currentPage.get(selected).kind == Kind.Template); + return LibraryAPI.getHandler(currentPage.get(selected).extension).isHandler(getStackInSlot(2), false); } } diff --git a/common/buildcraft/builders/TileBuilder.java b/common/buildcraft/builders/TileBuilder.java index f4d24d84..e81deee0 100644 --- a/common/buildcraft/builders/TileBuilder.java +++ b/common/buildcraft/builders/TileBuilder.java @@ -305,7 +305,6 @@ public class TileBuilder extends TileAbstractBuilder implements IHasWork, IFluid try { bpt = ItemBlueprint.loadBlueprint(getStackInSlot(0)); } catch (Throwable t) { - setInventorySlotContents(0, null); t.printStackTrace(); return null; } diff --git a/common/buildcraft/builders/blueprints/RealBlueprintDeployer.java b/common/buildcraft/builders/blueprints/RealBlueprintDeployer.java index 37c2e3c0..e2e26e2b 100755 --- a/common/buildcraft/builders/blueprints/RealBlueprintDeployer.java +++ b/common/buildcraft/builders/blueprints/RealBlueprintDeployer.java @@ -16,12 +16,13 @@ import net.minecraftforge.common.util.ForgeDirection; import buildcraft.api.blueprints.BlueprintDeployer; import buildcraft.api.blueprints.Translation; -import buildcraft.builders.blueprints.BlueprintDatabase; -import buildcraft.core.blueprints.BlueprintId; -import buildcraft.core.blueprints.BlueprintId.Kind; +import buildcraft.builders.LibraryDatabase; +import buildcraft.core.blueprints.BlueprintBase; +import buildcraft.core.blueprints.LibraryId; import buildcraft.core.blueprints.Blueprint; import buildcraft.core.blueprints.BptBuilderBlueprint; import buildcraft.core.blueprints.BptContext; +import buildcraft.core.lib.utils.NBTUtils; public class RealBlueprintDeployer extends BlueprintDeployer { @@ -29,19 +30,19 @@ public class RealBlueprintDeployer extends BlueprintDeployer { public void deployBlueprint(World world, int x, int y, int z, ForgeDirection dir, File file) { - deployBlueprint(world, x, y, z, dir, (Blueprint) BlueprintDatabase.load(file)); + deployBlueprint(world, x, y, z, dir, (Blueprint) BlueprintBase.loadBluePrint(LibraryDatabase.load(file))); } @Override public void deployBlueprintFromFileStream(World world, int x, int y, int z, ForgeDirection dir, byte [] data) { - deployBlueprint(world, x, y, z, dir, (Blueprint) BlueprintDatabase.load(data)); + deployBlueprint(world, x, y, z, dir, (Blueprint) BlueprintBase.loadBluePrint(NBTUtils.load(data))); } private void deployBlueprint(World world, int x, int y, int z, ForgeDirection dir, Blueprint bpt) { - bpt.id = new BlueprintId(); - bpt.id.kind = Kind.Blueprint; + bpt.id = new LibraryId(); + bpt.id.extension = "bpt"; BptContext context = bpt.getContext(world, bpt.getBoxForPos(x, y, z)); diff --git a/common/buildcraft/builders/blueprints/RecursiveBlueprintReader.java b/common/buildcraft/builders/blueprints/RecursiveBlueprintReader.java index a4edd2cd..5cbdfb82 100644 --- a/common/buildcraft/builders/blueprints/RecursiveBlueprintReader.java +++ b/common/buildcraft/builders/blueprints/RecursiveBlueprintReader.java @@ -9,6 +9,7 @@ package buildcraft.builders.blueprints; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.util.ForgeDirection; @@ -210,7 +211,9 @@ public class RecursiveBlueprintReader { public void createBlueprint() { writingBlueprint.id.name = architect.name; writingBlueprint.author = architect.currentAuthorName; - BuildCraftBuilders.serverDB.add(writingBlueprint); + NBTTagCompound nbt = new NBTTagCompound(); + writingBlueprint.writeToNBT(nbt); + BuildCraftBuilders.serverDB.add(writingBlueprint.id, nbt); if (parentBlueprint == null) { // TODO: This is hacky, should probably be done in the architect diff --git a/common/buildcraft/builders/gui/GuiBlueprintLibrary.java b/common/buildcraft/builders/gui/GuiBlueprintLibrary.java index ddc451d4..70743385 100644 --- a/common/buildcraft/builders/gui/GuiBlueprintLibrary.java +++ b/common/buildcraft/builders/gui/GuiBlueprintLibrary.java @@ -15,10 +15,9 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.ResourceLocation; import buildcraft.BuildCraftBuilders; +import buildcraft.api.library.LibraryAPI; import buildcraft.builders.TileBlueprintLibrary; -import buildcraft.core.blueprints.BlueprintId; -import buildcraft.core.blueprints.BlueprintId.Kind; -import buildcraft.core.DefaultProps; +import buildcraft.core.blueprints.LibraryId; import buildcraft.core.lib.gui.GuiBuildCraft; import buildcraft.core.lib.utils.StringUtils; @@ -64,7 +63,7 @@ public class GuiBlueprintLibrary extends GuiBuildCraft { fontRendererObj.drawString(title, getCenteredOffset(title), 6, 0x404040); int c = 0; - for (BlueprintId bpt : library.currentPage) { + for (LibraryId bpt : library.currentPage) { String name = bpt.name; if (name.length() > BuildCraftBuilders.MAX_BLUEPRINTS_NAME_SIZE) { @@ -75,18 +74,15 @@ public class GuiBlueprintLibrary extends GuiBuildCraft { int l1 = 8; int i2 = 24; - if (bpt.kind == Kind.Blueprint) { - drawGradientRect(l1, i2 + 9 * c, l1 + 146, i2 + 9 * (c + 1), 0xFFA0C0F0, 0xFFA0C0F0); - } else { + // TODO + //if (bpt.kind == Kind.Blueprint) { + // drawGradientRect(l1, i2 + 9 * c, l1 + 146, i2 + 9 * (c + 1), 0xFFA0C0F0, 0xFFA0C0F0); + //} else { drawGradientRect(l1, i2 + 9 * c, l1 + 146, i2 + 9 * (c + 1), 0x80ffffff, 0x80ffffff); - } + //} } - if (bpt.kind == Kind.Blueprint) { - fontRendererObj.drawString(name, 9, 25 + 9 * c, 0x305080); - } else { - fontRendererObj.drawString(name, 9, 25 + 9 * c, 0x000000); - } + fontRendererObj.drawString(name, 9, 25 + 9 * c, LibraryAPI.getHandler(bpt.extension).getTextColor()); c++; } diff --git a/common/buildcraft/core/blueprints/Blueprint.java b/common/buildcraft/core/blueprints/Blueprint.java index 8f4301aa..9aa1552a 100644 --- a/common/buildcraft/core/blueprints/Blueprint.java +++ b/common/buildcraft/core/blueprints/Blueprint.java @@ -27,7 +27,6 @@ import buildcraft.api.blueprints.SchematicBlock; import buildcraft.api.blueprints.SchematicEntity; import buildcraft.api.blueprints.Translation; import buildcraft.api.core.BCLog; -import buildcraft.core.blueprints.BlueprintId.Kind; import buildcraft.core.lib.utils.NBTUtils; public class Blueprint extends BlueprintBase { @@ -36,13 +35,13 @@ public class Blueprint extends BlueprintBase { public Blueprint() { super (); - id.kind = Kind.Blueprint; + id.extension = "bpt"; } public Blueprint(int sizeX, int sizeY, int sizeZ) { super(sizeX, sizeY, sizeZ); - id.kind = Kind.Blueprint; + id.extension = "bpt"; } @Override diff --git a/common/buildcraft/core/blueprints/BlueprintBase.java b/common/buildcraft/core/blueprints/BlueprintBase.java index b47dee42..a85fe11e 100644 --- a/common/buildcraft/core/blueprints/BlueprintBase.java +++ b/common/buildcraft/core/blueprints/BlueprintBase.java @@ -40,7 +40,7 @@ public abstract class BlueprintBase { public SchematicBlockBase[][][] contents; public int anchorX, anchorY, anchorZ; public int sizeX, sizeY, sizeZ; - public BlueprintId id = new BlueprintId(); + public LibraryId id = new LibraryId(); public String author; public boolean rotate = true; public boolean excavate = true; @@ -187,7 +187,7 @@ public abstract class BlueprintBase { BlueprintBase bpt; if ("template".equals(kind)) { - bpt = new Template (); + bpt = new Template(); } else { bpt = new Blueprint(); } diff --git a/common/buildcraft/core/blueprints/BlueprintId.java b/common/buildcraft/core/blueprints/LibraryId.java similarity index 84% rename from common/buildcraft/core/blueprints/BlueprintId.java rename to common/buildcraft/core/blueprints/LibraryId.java index 7819da24..5fa864da 100644 --- a/common/buildcraft/core/blueprints/BlueprintId.java +++ b/common/buildcraft/core/blueprints/LibraryId.java @@ -8,6 +8,8 @@ */ package buildcraft.core.blueprints; +import sun.nio.ch.Net; + import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; @@ -22,18 +24,14 @@ import buildcraft.BuildCraftBuilders; import buildcraft.api.core.ISerializable; import buildcraft.core.lib.utils.NetworkUtils; -public final class BlueprintId implements Comparable, ISerializable { - public enum Kind { - Template, Blueprint - } - +public final class LibraryId implements Comparable, ISerializable { public byte[] uniqueId; public String name = ""; - public Kind kind = Kind.Blueprint; + public String extension = "tpl"; public String completeId; - public BlueprintId() { + public LibraryId() { } public void generateUniqueId(byte[] data) { @@ -50,19 +48,23 @@ public final class BlueprintId implements Comparable, ISerializable public void write (NBTTagCompound nbt) { nbt.setByteArray("uniqueBptId", uniqueId); nbt.setString("name", name); - nbt.setByte("kind", (byte) kind.ordinal()); + nbt.setString("extension", extension); } public void read (NBTTagCompound nbt) { uniqueId = nbt.getByteArray("uniqueBptId"); name = nbt.getString("name"); - kind = Kind.values()[nbt.getByte("kind")]; + if (nbt.hasKey("kind")) { + extension = nbt.getByte("kind") > 0 ? "bpt" : "tpl"; + } else { + extension = nbt.getString("extension"); + } } @Override public boolean equals(Object obj) { - if (obj instanceof BlueprintId) { - return Arrays.equals(uniqueId, ((BlueprintId) obj).uniqueId); + if (obj instanceof LibraryId) { + return Arrays.equals(uniqueId, ((LibraryId) obj).uniqueId); } else { return false; } @@ -108,7 +110,7 @@ public final class BlueprintId implements Comparable, ISerializable } @Override - public int compareTo(BlueprintId o) { + public int compareTo(LibraryId o) { return getCompleteId().compareTo(o.getCompleteId()); } @@ -142,13 +144,13 @@ public final class BlueprintId implements Comparable, ISerializable public void readData(ByteBuf stream) { uniqueId = NetworkUtils.readByteArray(stream); name = NetworkUtils.readUTF(stream); - kind = Kind.values()[stream.readUnsignedByte()]; + extension = NetworkUtils.readUTF(stream); } @Override public void writeData(ByteBuf stream) { NetworkUtils.writeByteArray(stream, uniqueId); NetworkUtils.writeUTF(stream, name); - stream.writeByte(kind.ordinal()); + NetworkUtils.writeUTF(stream, extension); } } diff --git a/common/buildcraft/core/blueprints/Template.java b/common/buildcraft/core/blueprints/Template.java index 3b60a4a7..a06eb46b 100644 --- a/common/buildcraft/core/blueprints/Template.java +++ b/common/buildcraft/core/blueprints/Template.java @@ -16,7 +16,6 @@ import buildcraft.BuildCraftBuilders; import buildcraft.api.blueprints.IBuilderContext; import buildcraft.api.blueprints.SchematicMask; import buildcraft.api.core.BuildCraftAPI; -import buildcraft.core.blueprints.BlueprintId.Kind; import buildcraft.core.lib.utils.NBTUtils; /** @@ -25,13 +24,13 @@ import buildcraft.core.lib.utils.NBTUtils; public class Template extends BlueprintBase { public Template() { - id.kind = Kind.Template; + id.extension = "tpl"; } public Template(int sizeX, int sizeY, int sizeZ) { super(sizeX, sizeY, sizeZ); - id.kind = Kind.Template; + id.extension = "tpl"; } @Override diff --git a/common/buildcraft/core/lib/utils/NBTUtils.java b/common/buildcraft/core/lib/utils/NBTUtils.java index e23e06d0..fcc09324 100644 --- a/common/buildcraft/core/lib/utils/NBTUtils.java +++ b/common/buildcraft/core/lib/utils/NBTUtils.java @@ -8,10 +8,14 @@ */ package buildcraft.core.lib.utils; +import java.io.IOException; import java.util.UUID; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompressedStreamTools; +import net.minecraft.nbt.NBTSizeTracker; import net.minecraft.nbt.NBTTagCompound; +import buildcraft.core.blueprints.BlueprintBase; public final class NBTUtils { @@ -22,6 +26,18 @@ public final class NBTUtils { } + + public static NBTTagCompound load(byte[] data) { + try { + NBTTagCompound nbt = CompressedStreamTools.func_152457_a(data, NBTSizeTracker.field_152451_a); + return nbt; + } catch (IOException e) { + e.printStackTrace(); + } + + return null; + } + public static NBTTagCompound getItemData(ItemStack stack) { if (stack == null) { return null; @@ -51,4 +67,13 @@ public final class NBTUtils { } return null; } + + public static byte[] save(NBTTagCompound compound) { + try { + return CompressedStreamTools.compress(compound); + } catch (IOException e) { + e.printStackTrace(); + return new byte[0]; + } + } }