some work on the blueprint database, new unique id concept

This commit is contained in:
Player 2013-11-18 16:06:38 +01:00
parent 7594b70a2e
commit a035a15632
8 changed files with 432 additions and 207 deletions

View file

@ -122,15 +122,15 @@ public class BuildCraftCore {
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public static Icon redLaserTexture; public static Icon redLaserTexture;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public static Icon blueLaserTexture; public static Icon blueLaserTexture;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public static Icon stripesLaserTexture; public static Icon stripesLaserTexture;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public static Icon transparentTexture; public static Icon transparentTexture;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public static IIconProvider iconProvider; public static IIconProvider iconProvider;
public static int blockByEntityModel; public static int blockByEntityModel;
public static int legacyPipeModel; public static int legacyPipeModel;
@ -168,12 +168,13 @@ public class BuildCraftCore {
@Instance("BuildCraft|Core") @Instance("BuildCraft|Core")
public static BuildCraftCore instance; public static BuildCraftCore instance;
@EventHandler @EventHandler
public void loadConfiguration(FMLPreInitializationEvent evt) { public void loadConfiguration(FMLPreInitializationEvent evt) {
BCLog.initLog(); BCLog.initLog();
BlueprintDatabase.configFolder = evt.getModConfigurationDirectory(); BlueprintDatabase.init(evt.getModConfigurationDirectory());
mainConfiguration = new BuildCraftConfiguration(new File(evt.getModConfigurationDirectory(), "buildcraft/main.conf")); mainConfiguration = new BuildCraftConfiguration(new File(evt.getModConfigurationDirectory(), "buildcraft/main.conf"));
try { try {
mainConfiguration.load(); mainConfiguration.load();
@ -278,8 +279,8 @@ public class BuildCraftCore {
} }
} }
@EventHandler @EventHandler
public void initialize(FMLInitializationEvent evt) { public void initialize(FMLInitializationEvent evt) {
// MinecraftForge.registerConnectionHandler(new ConnectionHandler()); // MinecraftForge.registerConnectionHandler(new ConnectionHandler());
ActionManager.registerTriggerProvider(new DefaultTriggerProvider()); ActionManager.registerTriggerProvider(new DefaultTriggerProvider());
ActionManager.registerActionProvider(new DefaultActionProvider()); ActionManager.registerActionProvider(new DefaultActionProvider());
@ -323,8 +324,8 @@ public class BuildCraftCore {
} }
@EventHandler @EventHandler
public void serverStarting(FMLServerStartingEvent event) { public void serverStarting(FMLServerStartingEvent event) {
event.registerServerCommand(new CommandBuildCraft()); event.registerServerCommand(new CommandBuildCraft());
} }
@ -336,16 +337,16 @@ public class BuildCraftCore {
iconProvider.registerIcons(event.map); iconProvider.registerIcons(event.map);
ActionTriggerIconProvider.INSTANCE.registerIcons(event.map); ActionTriggerIconProvider.INSTANCE.registerIcons(event.map);
} else if (event.map.textureType == 0) { } else if (event.map.textureType == 0) {
BuildCraftCore.redLaserTexture = event.map.registerIcon("buildcraft:blockRedLaser"); BuildCraftCore.redLaserTexture = event.map.registerIcon("buildcraft:blockRedLaser");
BuildCraftCore.blueLaserTexture = event.map.registerIcon("buildcraft:blockBlueLaser"); BuildCraftCore.blueLaserTexture = event.map.registerIcon("buildcraft:blockBlueLaser");
BuildCraftCore.stripesLaserTexture = event.map.registerIcon("buildcraft:blockStripesLaser"); BuildCraftCore.stripesLaserTexture = event.map.registerIcon("buildcraft:blockStripesLaser");
BuildCraftCore.transparentTexture = event.map.registerIcon("buildcraft:blockTransparentLaser"); BuildCraftCore.transparentTexture = event.map.registerIcon("buildcraft:blockTransparentLaser");
} }
} }
public void loadRecipes() { 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(woodenGearItem), " S ", "S S", " S ", 'S', "stickWood");
CoreProxy.proxy.addCraftingRecipe(new ItemStack(stoneGearItem), " I ", "IGI", " I ", 'I', "cobblestone", 'G', CoreProxy.proxy.addCraftingRecipe(new ItemStack(stoneGearItem), " I ", "IGI", " I ", 'I', "cobblestone", 'G',
woodenGearItem); woodenGearItem);
@ -355,7 +356,7 @@ public class BuildCraftCore {
} }
@EventHandler @EventHandler
public void processIMCRequests(FMLInterModComms.IMCEvent event) { public void processIMCRequests(FMLInterModComms.IMCEvent event) {
InterModComms.processIMC(event); InterModComms.processIMC(event);
} }
} }

View file

@ -13,12 +13,14 @@ import buildcraft.core.CreativeTabBuildCraft;
import buildcraft.core.ItemBuildCraft; import buildcraft.core.ItemBuildCraft;
import buildcraft.core.utils.NBTUtils; import buildcraft.core.utils.NBTUtils;
import buildcraft.core.utils.StringUtils; import buildcraft.core.utils.StringUtils;
import java.util.List; import java.util.List;
import java.util.UUID;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import buildcraft.builders.blueprints.BlueprintId;
public abstract class ItemBlueprint extends ItemBuildCraft { public abstract class ItemBlueprint extends ItemBuildCraft {
public ItemBlueprint(int i) { public ItemBlueprint(int i) {
@ -39,11 +41,14 @@ public abstract class ItemBlueprint extends ItemBuildCraft {
} }
public static Blueprint getBlueprint(ItemStack stack) { public static Blueprint getBlueprint(ItemStack stack) {
if (stack != null && stack.getItem() instanceof ItemBlueprint) { NBTTagCompound nbt = NBTUtils.getItemData(stack);
NBTTagCompound nbt = NBTUtils.getItemData(stack); byte[] idRaw = nbt.getByteArray("blueprint");
UUID uuid = NBTUtils.readUUID(nbt, "blueprint"); BlueprintId id = BlueprintId.fromRawId(idRaw);
return BlueprintDatabase.getBlueprint(uuid);
if (id == null) {
return null;
} else {
return BlueprintDatabase.get(id);
} }
return null;
} }
} }

View file

@ -93,14 +93,14 @@ public class TileArchitect extends TileBuildCraft implements IInventory {
blueprint.anchorOrientation = ForgeDirection.getOrientation(worldObj.getBlockMetadata(xCoord, yCoord, zCoord)); blueprint.anchorOrientation = ForgeDirection.getOrientation(worldObj.getBlockMetadata(xCoord, yCoord, zCoord));
BlueprintDatabase.addBlueprint(blueprint); BlueprintDatabase.add(blueprint);
setInventorySlotContents(1, blueprint.getBlueprintItem()); setInventorySlotContents(1, blueprint.getBlueprintItem());
setInventorySlotContents(0, null); setInventorySlotContents(0, null);
} }
private Blueprint createMaskBlueprint(Box box) { 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 x = box.xMin; x <= box.xMax; ++x) {
for (int y = box.yMin; y <= box.yMax; ++y) { 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) { 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 x = box.xMin; x <= box.xMax; ++x) {
for (int y = box.yMin; y <= box.yMax; ++y) { for (int y = box.yMin; y <= box.yMax; ++y) {

View file

@ -13,16 +13,18 @@ import buildcraft.core.inventory.StackHelper;
import buildcraft.core.utils.BCLog; import buildcraft.core.utils.BCLog;
import buildcraft.core.utils.NBTUtils; import buildcraft.core.utils.NBTUtils;
import buildcraft.factory.TileQuarry; import buildcraft.factory.TileQuarry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.UUID;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagList;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection; import net.minecraftforge.common.ForgeDirection;
/** /**
@ -30,42 +32,82 @@ import net.minecraftforge.common.ForgeDirection;
* world. * world.
* *
* @author CovertJaguar <http://www.railcraft.info/> * @author CovertJaguar <http://www.railcraft.info/>
* @author Player
*/ */
public class Blueprint { public class Blueprint {
private BlueprintMeta meta;
private final String version = "Blueprint-2.0";
private final UUID uuid;
private String name;
private String creator;
private final Schematic[][][] schematics; private final Schematic[][][] schematics;
public final int sizeX, sizeY, sizeZ; public final int sizeX, sizeY, sizeZ;
public int anchorX, anchorY, anchorZ; public int anchorX, anchorY, anchorZ;
public ForgeDirection anchorOrientation = ForgeDirection.NORTH; public ForgeDirection anchorOrientation = ForgeDirection.NORTH;
private List<ItemStack> costs; private List<ItemStack> costs;
public Blueprint(int sizeX, int sizeY, int sizeZ) { public static Blueprint create(int sizeX, int sizeY, int sizeZ) {
this(sizeX, sizeY, sizeZ, UUID.randomUUID()); return new Blueprint(new BlueprintMeta(), sizeX, sizeY, sizeZ);
} }
private Blueprint(int sizeX, int sizeY, int sizeZ, UUID uuid) { private Blueprint(BlueprintMeta meta, int sizeX, int sizeY, int sizeZ) {
this.uuid = uuid; this.meta = meta;
this.sizeX = sizeX; this.sizeX = sizeX;
this.sizeY = sizeY; this.sizeY = sizeY;
this.sizeZ = sizeZ; this.sizeZ = sizeZ;
schematics = new Schematic[sizeX][sizeY][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() { public String getName() {
return name; return meta.getName();
} }
public void setName(String name) { 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) { private void setSchematic(int x, int y, int z, Schematic schematic) {
if (schematic == null) if (getId() != null) throw new IllegalStateException("modifying finalized blueprint");
return;
schematic.x = x; schematic.x = x;
schematic.y = y; schematic.y = y;
schematic.z = z; schematic.z = z;
@ -124,10 +166,6 @@ public class Blueprint {
return schematics[x][y][z]; 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 * Returns a list of all blocks in the Blueprint in the order they should be
* built. * built.
@ -174,7 +212,10 @@ public class Blueprint {
} }
public void writeToNBT(NBTTagCompound nbt) { public void writeToNBT(NBTTagCompound nbt) {
meta.writeToNBT(nbt);
NBTTagList blockList = new NBTTagList(); NBTTagList blockList = new NBTTagList();
for (int y = 0; y < sizeY; y++) { for (int y = 0; y < sizeY; y++) {
for (int x = 0; x < sizeX; x++) { for (int x = 0; x < sizeX; x++) {
for (int z = 0; z < sizeZ; z++) { for (int z = 0; z < sizeZ; z++) {
@ -186,12 +227,8 @@ public class Blueprint {
} }
} }
} }
nbt.setTag("blocks", blockList); 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("sizeX", sizeX);
nbt.setInteger("sizeY", sizeY); nbt.setInteger("sizeY", sizeY);
nbt.setInteger("sizeZ", sizeZ); nbt.setInteger("sizeZ", sizeZ);
@ -201,46 +238,7 @@ public class Blueprint {
nbt.setByte("anchorOrientation", (byte) anchorOrientation.ordinal()); 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() { public void rotateLeft() {
anchorOrientation = anchorOrientation.getRotation(ForgeDirection.DOWN); anchorOrientation = anchorOrientation.getRotation(ForgeDirection.DOWN);
@ -249,7 +247,7 @@ public class Blueprint {
public ItemStack getBlueprintItem() { public ItemStack getBlueprintItem() {
ItemStack blueprint = new ItemStack(BuildCraftBuilders.blueprintItem, 1, 1); ItemStack blueprint = new ItemStack(BuildCraftBuilders.blueprintItem, 1, 1);
NBTTagCompound nbt = NBTUtils.getItemData(blueprint); NBTTagCompound nbt = NBTUtils.getItemData(blueprint);
NBTUtils.writeUUID(nbt, "blueprint", uuid); nbt.setByteArray("blueprint", getId().toRawId());
return blueprint; return blueprint;
} }
} }

View file

@ -8,127 +8,225 @@
*/ */
package buildcraft.builders.blueprints; package buildcraft.builders.blueprints;
import cpw.mods.fml.relauncher.Side; import java.io.ByteArrayInputStream;
import cpw.mods.fml.relauncher.SideOnly; import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter; import java.io.FilenameFilter;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.WeakHashMap;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
/** /**
* *
* @author Player
* @author CovertJaguar <http://www.railcraft.info/> * @author CovertJaguar <http://www.railcraft.info/>
*/ */
public class BlueprintDatabase { public class BlueprintDatabase {
public static void init(File configDir) {
blueprintFolder = new File(new File(configDir, "buildcraft"), "blueprints");
public static File configFolder; if (!blueprintFolder.exists()) blueprintFolder.mkdirs();
private static Map<UUID, Blueprint> blueprints = new HashMap<UUID, Blueprint>();
public static Blueprint getBlueprint(UUID uuid) { loadIndex();
if(uuid == null) }
return null;
Blueprint blueprint = blueprints.get(uuid); public static Blueprint get(BlueprintId id) {
if (blueprint == null) { Blueprint ret = blueprints.get(id);
blueprint = loadBlueprint(uuid);
addBlueprint(blueprint); 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) { public static BlueprintId add(Blueprint blueprint) {
if (blueprint == null) BlueprintId id = save(blueprint);
return;
blueprints.put(blueprint.getUUID(), blueprint); blueprint.setId(id);
blueprints.put(id, blueprint);
return id;
} }
private static File getBlueprintFolder() { private static BlueprintId save(Blueprint blueprint) {
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) {
NBTTagCompound nbt = new NBTTagCompound(); NBTTagCompound nbt = new NBTTagCompound();
blueprint.writeToNBT(nbt); blueprint.writeToNBT(nbt);
File blueprintFile = new File(getBlueprintFolder(), String.format(Locale.ENGLISH, "%x%x-%s.nbt", uuidToString(blueprint.getUUID()), blueprint.getName())); ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream os = new DataOutputStream(bos);
if (blueprintFile.exists())
return;
try { try {
CompressedStreamTools.write(nbt, blueprintFile); NBTBase.writeNamedTag(nbt, os);
} catch (IOException ex) { } catch (IOException e) {
Logger.getLogger("Buildcraft").log(Level.SEVERE, String.format("Failed to save Blueprint file: %s %s", blueprintFile.getName(), ex.getMessage())); 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() { private static void loadIndex() {
for (Blueprint blueprint : blueprints.values()) {
saveBlueprint(blueprint);
}
}
private static Blueprint loadBlueprint(final UUID uuid) {
FilenameFilter filter = new FilenameFilter() { FilenameFilter filter = new FilenameFilter() {
private String uuidString = uuidToString(uuid);
@Override @Override
public boolean accept(File dir, String name) { 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)) { for (File blueprintFile : blueprintFolder.listFiles(filter)) {
RawBlueprint rawBlueprint = load(blueprintFile);
if (rawBlueprint == null) {
// TODO: delete?
continue;
}
BlueprintMeta meta;
try { try {
nbt = CompressedStreamTools.read(blueprintFile); meta = new BlueprintMeta(rawBlueprint.id, rawBlueprint.nbt);
break; } catch (Exception e) {
} catch (IOException ex) { // TODO: delete?
Logger.getLogger("Buildcraft").log(Level.SEVERE, String.format("Failed to load Blueprint file: %s %s", blueprintFile.getName(), ex.getMessage())); 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 null;
} }
return Blueprint.readFromNBT(nbt);
return new RawBlueprint(id, nbt);
} }
public static void loadBlueprints() { private static class RawBlueprint {
FilenameFilter filter = new FilenameFilter() { RawBlueprint(BlueprintId id, NBTTagCompound nbt) {
@Override this.id = id;
public boolean accept(File dir, String name) { this.nbt = nbt;
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()));
}
} }
final BlueprintId id;
final NBTTagCompound nbt;
} }
@SideOnly(Side.CLIENT) private static final int bufferSize = 8192;
public static void sendBlueprintsToServer() { private static final String fileExt = ".bpt";
// TODO private static File blueprintFolder;
} private static Map<BlueprintId, BlueprintMeta> blueprintMetas = new HashMap<BlueprintId, BlueprintMeta>();
private static Map<BlueprintId, Blueprint> blueprints = new WeakHashMap<BlueprintId, Blueprint>();
} }

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -51,7 +51,6 @@ import net.minecraftforge.common.ForgeChunkManager;
import net.minecraftforge.common.ForgeChunkManager.Ticket; import net.minecraftforge.common.ForgeChunkManager.Ticket;
import net.minecraftforge.common.ForgeChunkManager.Type; import net.minecraftforge.common.ForgeChunkManager.Type;
import net.minecraftforge.common.ForgeDirection; import net.minecraftforge.common.ForgeDirection;
import static net.minecraftforge.common.ForgeDirection.*;
public class TileQuarry extends TileBuildCraft implements IMachine, IPowerReceptor, IBuilderInventory { 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()) if (columnVisitListIsUpdated && nextTarget == null && !visitList.isEmpty())
{ {
nextTarget = visitList.removeFirst(); nextTarget = visitList.removeFirst();
} }
else if (columnVisitListIsUpdated && nextTarget == null) else if (columnVisitListIsUpdated && nextTarget == null)
{ {
return false; return false;
} }
setTarget(nextTarget[0], nextTarget[1] + 1, nextTarget[2]); 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) if (height > 0 && height < by && worldObj.provider.dimensionId != -1)
{ {
continue; continue;
} }
int blockID = worldObj.getBlockId(bx, by, bz); int blockID = worldObj.getBlockId(bx, by, bz);
@ -342,10 +341,10 @@ public class TileQuarry extends TileBuildCraft implements IMachine, IPowerRecept
} else if (!BlockUtil.isSoftBlock(blockID, worldObj, bx, by, bz)) { } else if (!BlockUtil.isSoftBlock(blockID, worldObj, bx, by, bz)) {
visitList.add(new int[]{bx, by, bz}); visitList.add(new int[]{bx, by, bz});
} }
if (height == 0 && !worldObj.isAirBlock(bx, by, bz)) if (height == 0 && !worldObj.isAirBlock(bx, by, bz))
{ {
columnHeights[searchX][searchZ] = by; columnHeights[searchX][searchZ] = by;
} }
// Stop at two planes - generally any obstructions will have been found and will force a recompute prior to this // 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) if (visitList.size() > blueprintBuilder.blueprint.sizeZ * blueprintBuilder.blueprint.sizeX * 2)
@ -539,7 +538,7 @@ public class TileQuarry extends TileBuildCraft implements IMachine, IPowerRecept
if (placedBy != null && CoreProxy.proxy.isSimulating(worldObj)) { if (placedBy != null && CoreProxy.proxy.isSimulating(worldObj)) {
PacketDispatcher.sendPacketToPlayer( 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", 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(); sendNetworkUpdate();
return; return;
@ -568,7 +567,7 @@ public class TileQuarry extends TileBuildCraft implements IMachine, IPowerRecept
if (placedBy != null) { if (placedBy != null) {
PacketDispatcher.sendPacketToPlayer( PacketDispatcher.sendPacketToPlayer(
new Packet3Chat(ChatMessageComponent.createFromText(String.format("Quarry size is outside of chunkloading bounds or too small %d %d (%d)", xSize, zSize, 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); 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(); ForgeDirection o = ForgeDirection.values()[worldObj.getBlockMetadata(xCoord, yCoord, zCoord)].getOpposite();
switch (o) { switch (o) {
case EAST: case EAST:
xMin = xCoord + 1; xMin = xCoord + 1;
zMin = zCoord - 4 - 1; zMin = zCoord - 4 - 1;
break; break;
case WEST: case WEST:
xMin = xCoord - 9 - 2; xMin = xCoord - 9 - 2;
zMin = zCoord - 4 - 1; zMin = zCoord - 4 - 1;
break; break;
case SOUTH: case SOUTH:
xMin = xCoord - 4 - 1; xMin = xCoord - 4 - 1;
zMin = zCoord + 1; zMin = zCoord + 1;
break; break;
case NORTH: case NORTH:
default: default:
xMin = xCoord - 4 - 1; xMin = xCoord - 4 - 1;
zMin = zCoord - 9 - 2; zMin = zCoord - 9 - 2;
break; break;
} }
box.initialize(xMin, yCoord, zMin, xMin + xSize - 1, yCoord + ySize - 1, zMin + zSize - 1); 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() { 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 it = 0; it < 2; it++) {
for (int i = 0; i < blueprint.sizeX; ++i) { for (int i = 0; i < blueprint.sizeX; ++i) {