The Small File Transfer System provides a quick and easy way to store small amounts of data for your world on the ViRSE server

Some ViRSE worlds will require persistent data storage. Where data requirements are low (less than 5k), the Small File Transfer System provides a simple way to store data on the ViRSE server, and retrieve it as required.

<aside> ℹ️ For larger files (>5k in size) or more complex requirements, the Large File Transfer System should be used instead

</aside>

Data for the small file should be supplied in the form of a byte array (’blob’). This can contain any data you like, but it is convenient to use C#s MemoryStream, BinaryWriter and BinaryReader classes to create your byte arrays, and to read them, as in the examples below.

byte[] blob;
using (MemoryStream stream = new MemoryStream())
{
	using (BinaryWriter writer = new BinaryWriter(stream))
	{
		writer.Write(anImportantString);
		writer.Write(anImportantInteger);
	}

	blob = stream.ToArray();
}
using (Stream stream = new MemoryStream(blob))
{
    using (BinaryReader reader = new BinaryReader(stream))
    {
				anImportantString = reader.ReadString();
				anImportantInteger = reader.ReadInt32();
    }
}

To store your constructed byte array on the server:

Plugin_Home.virseAPI.StoreFile(filename, byteArray);

And to request a retrieval:

Plugin_Home.virseAPI.RetrieveFile(filename);

filename should be some legal filename - don’t use spaces. It only has to be unique for your world - small files for different worlds are stored in different folders on the server, so cannot be confused. It does not matter what file extension you use - I normally use .bin for binary, but anything will work! Good examples might be “settings.bin” or “datapackage1.bin”. byteArray must be of type byte[], and of length < 5000.

Both of these operations are asynchronous - they take an appreciable amount of time (several frames) to complete, as they involve network communication as well as file operations on the server. Nonetheless they should be faster than using the Large File Transfer system, which has additional overhead.

Once a StoreFile command has been issued, you can simply assume it has completed - there is no error reporting.

To receive the data from a RetrieveFile request, you need to create an appropriate method to handle it. This must be of type public void, with arguments of string and byte[], in that order. For example, the method below receives the data, and retrieves a string and integer from it:

public void ReceiveFile(string filename, byte[] data)
{
	 using (Stream stream = new MemoryStream(data))
	 {
	    using (BinaryReader reader = new BinaryReader(stream))
	    {
					anImportantString = reader.ReadString();
					anImportantInteger = reader.ReadInt32();
	    }
	 }
}

Finally, hook this method up to the ‘On Small File Received From Server’ Unity event controller in ViRSEManager, so ViRSE knows where to send the received file.

Untitled

If your system uses the small file storage system for more than one purpose (i.e. you store data using more than one filename), you will need to hook all necessary receiver methods up in this one central place, and each should check the filename it has received to work out what to do with it.

<aside> ⚠️

Warning - over-use of the Small File Transfer System can place a heavy load on the server and impact its performance. It is intended for infrequent access, and especially infrequent StoreFile access. If your world plans on using it more heavily - i.e. retrieving more than one file per connected player per second, or storing more than one file per connected player per ten seconds - please speak to the ViRSE developers about alternative approaches.

</aside>