import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.LinkedList;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import ru.fallus.modifire.lib.ByteUtils;
public class SchematicMaster
{
private Schemaster plugin;
private File schematicFolder;
public SchematicMaster(final Schemaster plugin)
{
this.plugin = plugin;
schematicFolder = plugin.getDataFolder();
}
public void saveSchematic(Location loc1, Location loc2, String name) throws IOException
{
int minX = Math.min(loc1.getBlockX(), loc2.getBlockX());
int maxX = Math.max(loc1.getBlockX(), loc2.getBlockX());
int minY = Math.min(loc1.getBlockY(), loc2.getBlockY());
int maxY = Math.max(loc1.getBlockY(), loc2.getBlockY());
int minZ = Math.min(loc1.getBlockZ(), loc2.getBlockZ());
int maxZ = Math.max(loc1.getBlockZ(), loc2.getBlockZ());
File file = new File(schematicFolder, name + ".sch");
if(!file.exists())
{
plugin.getDataFolder().mkdirs();
file.createNewFile();
}
FileOutputStream os = new FileOutputStream(file);
for(int x = minX; x < maxX; x++)
{
for(int y = minY; y < maxY; y++)
{
for(int z = minZ; z < maxZ; z++)
{
Block block = loc1.getWorld().getBlockAt(x, y, z);
if(block.getType() == Material.AIR)
continue;
//использаем числа в диапазоне 0 - 65535
short localX = (short) (x - minX);
short localY = (short) (y - minY);
short localZ = (short) (z - minZ);
short id = (short) block.getTypeId();
byte data = block.getData();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
//writing 9 bytes(in total) per block
bos.write(ByteUtils.makeBytes(localX));
bos.write(ByteUtils.makeBytes(localY));
bos.write(ByteUtils.makeBytes(localZ));
bos.write(ByteUtils.makeBytes(id));
bos.write(new byte[]{ data });
os.write(bos.toByteArray());
}
}
}
os.close();
}
public LinkedList<SchematicBlock> loadSchematic(String name) throws IOException
{
File file = new File(schematicFolder, name + ".sch");
if(!file.exists())
return null;
//файл поврежден или данные записаны неверно
if(file.length() % 9 != 0)
return null;
FileInputStream is = new FileInputStream(file);
//для хранения большого кол-ва элементов
LinkedList<SchematicBlock> blocks = new LinkedList<SchematicBlock>();
//количество блоков, записанных в файле
long blockCount = (long) (file.length() / 9);
for(long i = 0; i < blockCount; i++)
{
byte[] bytes = new byte[9];
if(is.read(bytes) == 9)
{
SchematicBlock b = new SchematicBlock();
b.localX = ByteUtils.makeShort(bytes, 0);
b.localY = ByteUtils.makeShort(bytes, 2);
b.localZ = ByteUtils.makeShort(bytes, 4);
b.id = ByteUtils.makeShort(bytes, 6);
b.data = bytes[8];
blocks.add(b);
}
}
is.close();
return blocks;
}
}