/* * This file is part of SpoutcraftPlugin. * * Copyright (c) 2011 SpoutcraftDev <http://spoutcraft.org//> * SpoutcraftPlugin is licensed under the GNU Lesser General Public License. * * SpoutcraftPlugin is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SpoutcraftPlugin is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.getspout.spoutapi.chunkstore; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.HashMap; import java.util.Iterator; import java.util.UUID; import org.bukkit.World; public class ChunkStore { HashMap<UUID, HashMap<Long, SimpleRegionFile>> regionFiles = new HashMap<UUID, HashMap<Long, SimpleRegionFile>>(); public void closeAll() { for (UUID uid : regionFiles.keySet()) { HashMap<Long, SimpleRegionFile> worldRegions = regionFiles.get(uid); Iterator<SimpleRegionFile> itr = worldRegions.values().iterator(); while (itr.hasNext()) { SimpleRegionFile rf = itr.next(); if (rf != null) { rf.close(); itr.remove(); } } } regionFiles.clear(); } public ChunkMetaData readChunkMetaData(World world, int x, int z) throws IOException { SimpleRegionFile rf = getSimpleRegionFile(world, x, z); InputStream in = rf.getInputStream(x, z); if (in == null) { return null; } ObjectInputStream objectStream = new ObjectInputStream(in); try { Object o = objectStream.readObject(); if (o instanceof ChunkMetaData) { return (ChunkMetaData) o; } else { throw new RuntimeException("Wrong class type read for chunk meta data for " + x + ", " + z); } } catch (IOException e) { // Assume the format changed return null; //throw new RuntimeException("Unable to process chunk meta data for " + x + ", " + z, e); } catch (ClassNotFoundException e) { // Assume the format changed //System.out.println("[SpoutPlugin] is Unable to find serialized class for " + x + ", " + z + ", " + e.getMessage()); return null; //throw new RuntimeException("Unable to find serialized class for " + x + ", " + z, e); } } public void writeChunkMetaData(World world, int x, int z, ChunkMetaData data) { if (!data.isDirty()) { return; } try { SimpleRegionFile rf = getSimpleRegionFile(world, x, z); ObjectOutputStream objectStream = new ObjectOutputStream(rf.getOutputStream(x, z)); objectStream.writeObject(data); objectStream.flush(); objectStream.close(); data.setDirty(false); } catch (IOException e) { throw new RuntimeException("Unable to write chunk meta data for " + x + ", " + z, e); } } public void closeChunkMetaData(World world, int x, int z) { SimpleRegionFile rf = getSimpleRegionFile(world, x, z); if (rf != null) { rf.close(); } } private SimpleRegionFile getSimpleRegionFile(World world, int x, int z) { File directory = new File(world.getWorldFolder(), "spout_meta"); directory.mkdirs(); UUID key = world.getUID(); HashMap<Long, SimpleRegionFile> worldRegions = regionFiles.get(key); if (worldRegions == null) { worldRegions = new HashMap<Long, SimpleRegionFile>(); regionFiles.put(key, worldRegions); } int rx = x >> 5; int rz = z >> 5; long key2 = (((long) rx) << 32) | (((long) rz) & 0xFFFFFFFFL); SimpleRegionFile regionFile = worldRegions.get(key2); if (regionFile == null) { File file = new File(directory, "spout_" + rx + "_" + rz + "_.spm"); regionFile = new SimpleRegionFile(file, rx, rz); worldRegions.put(key2, regionFile); } return regionFile; } }