Skip to content
Adamki11s edited this page Feb 8, 2012 · 7 revisions

< Home

Sync provides numerous ways of saving and loading data. Not only can you save and load primitive data types such as Strings and Integers but Sync also provides support for saving non Serializable classes such as the Location and ItemStack class. Furthermore Sync provides an easy wrapper class for serializing multiple objects into one file.

Standard File (SyncConfiguration)

The SyncIO class is a simple text file using a 'key:value' structure similar to Bukkit's Configuration class.

With SyncConfiguration not only can you add various keys and get their values as integers, booleans, strings or what have you you can insert comments and new lines into your configuration file. All values are stored in a LinkedHashMap so the data will be written to the file in the order it is added.

Saving Data

public void writeData(File f){
    SyncConfiguration stream = new SyncConfiguration(f); //Initialise the SyncIO object.
    stream.add("Key1", 456);
    stream.addNewLine();//Forces a line break, line breaks are inserted automatically after each key.
    stream.addComment("The value above 456 is mapped to the key Key1");
    stream.write();//Finally write all of the added data to the file.
}

This simple example above creates a file and uses SyncConfiguration to write data into it. To load the data from a file is also very simple.

Reading/Loading Data

public void readData(File f){
    SyncConfiguration stream = new SyncConfiguration(f);
    stream.read();//Loads all of the values from the file into memory
    if(stream.doesKeyExist("Key1"){ //Check if the key exists
        int value1 = stream.getInt("Key1"); //Gets the value for the key "Key1" and parses it to return an integer.
        System.out.println(value1);
    } else {
        System.out.println("Key1 was not found!");
    }
}

Serialized File (SyncObjectIO)

SyncObjectIO is probably one of the most useful classes - allowing you to save custom classes, Bukkit objects such as Location and Block safely and primitive Java data types as long as they implement the Serializable interface.

Saving and Loading Data

Saving Data using SyncObjectIO is also straightforward and similarly to SyncConfiguration all you need to do is create a file, add data and then call the write method. All of the hard work is done behind the scenes.

To allow you to store multiple objects inside a single serialized file Sync has to work in a Holder > Wrapper > Object Hierarchy. Therefore each object you save has to have a tag; similar to key's in SyncConfiguration which allows you to differentiate between multiple items.

A simple example of writing data using SyncObjectIO

public void serializeData(File f){
    SyncObjectIO stream = new SyncObjectIO(f);
    ArrayList<String> arrayList = new ArrayList<String>();
    arrayList.add("TestString");
    arrayList.add("TestString2");
    stream.add("StringArrayList", arrayList);//Add the arraylist to the stream with the tag 'StringArrayList'
    stream.write();//Write the data to the file.
}

Reading the data back is also simple but you will have to cast the object to the datatype like so.

public void deserializeData(File f){
    SyncObjectIO stream = new SyncObjectIO(f);
    stream.read(); //load the data into memory
    Object rawArrayList = null;//Setup our object
    ArrayList<String> arrayList;
    if(stream.doesObjectExist("StringArrayList")){
        rawArrayList = stream.getObject("StringArrayList");
        arrayList = (ArrayList<String>) rawArrayList;
        for(String s : arrayList){
            System.out.println("List objects : " + s);
        }
    } else {
        System.out.println("Fatal! Could not find oject with tag : 'StringArrayList'");
    }
}

Output

List objects : TestString

List objects : TestString2

Saving and Loading Custom Classes and Bukkit Objects

Sync Supports the saving and loading of the following Bukkit objects and their corresponding Sync Class.


  • Location > SyncLocation
  • Block > SyncBlock
  • ItemStack[] (Inventory) > SyncInventory (SyncItemStack[])
  • ItemStack > SyncItemStack
  • Enchantment > SyncEnchantment

Conversions are very straight forward to do.


Location l; Block b; ItemStack is; ItemStack[] invent;
SyncLocation sl; SyncBlock sb; SyncItemStack sis; SyncInventory si;

sl = new SyncLocation(l);
sb = new SyncBlock(b);
sis = new SyncItemStack(is);
si = new SyncInventory(invent);
l = sl.getBukkitLocation();
b = sb.getBukkitBlock();
is = sis.getBukkitItemStack();
invent = si.getContents();

This can also be done custom class provided it implements the Serializable interface. In the following example I will also demonstrate an example of saving and loading Bukkit locations. The same method can be applied to blocks, itemstacks and inventories.

This class is the class we will serialize to save and load a Location. This could be done solely with the SyncLocation object but I might as well show you how loading custom class would be done at the same time.

public class BukkitData implements Serializable {

    private static final long serialVersionUID = 7292621898449762302L;
    
    private final SyncLocation syncLoc;
    
    public BukkitData(SyncLocation syncLoc){
        this.syncLoc = syncLoc;
    }
    
    public Location getBukkitLocation(){
        return this.syncLoc.getBukkitLocation();
    }

}

So now that we have this BukkitData class lets create a SyncLocation object and save it. The examples below show loading and saving of the class.

public void saveClass(File f) {
	SyncObjectIO stream = new SyncObjectIO(f);
	Location l;// Assuming this object equals something
	SyncLocation sl = new SyncLocation(l);
	BukkitData bd = new BukkitData(sl);
	stream.add("BukkitData", bd); // Add our class
	stream.write(); // Write the data
}

public void loadClass(File f) {
	SyncObjectIO stream = new SyncObjectIO(f);
	stream.read();
	Object o = null;
	if (stream.doesObjectExist("BukkitData")) {
		o = stream.getObject("BukkitData");
		BukkitData bdClass = (BukkitData) o; //Just cast our object to the BukkitData class.
		Location l = bdClass.getBukkitLocation(); //Converts the SyncLocation to a Bukkit Location for us.
	} else {
		System.out.println("Fatal! Could not find an object with tag : BukkitData");
	}
}

Saving and Loading Blocks

Sync implements the method used by Notch to save chunks in Minecraft; know as JNBT or Java Named Binary Tag. It is a very efficient method of storage use bytes and GZipCompression to make the file size as small as possible. Loading blocks is forced onto a Synchronized task however saving blocks is done on an Asynchronous task.

To save a region of blocks you just need to create a SyncBlockIO object and then you can easily save and load blocks like so.

public void saveBlocks(File f){
    SyncBlockIO blockStream = new SyncBlockIO(f);
    try{
        World w;
        Location l1, l2;
        blockStream.saveBlockList(w, l1, l2);
    } catch (SizeExceededException se){
        sx.printStackTrace();//Size cannot exceed 256. That is the maximum value a byte can hold.
    }
}

public void loadBlocks(File f){
    SyncBlockIO blockStream = new SyncBlockIO(f);
    blockStream.loadBlockData(); //Load blockData from the file.
    World w;
    ArrayList<Block> blocks = blockStream.getBlockList(w);//Get a list of blocks from the coordinates in the file.
    blockStream.copyBlockListToWorld(w);//Copy all of the blocks into the world.
}