One of latest usage for Buffer has been done some time ago during tent system rework - i needed something for easy storing of tent names and that's how PData ("Personal Data") mini-system was made. Initially allowing to attach only strings to Location, after few updates, it allows to attach any data (as long Buffer knows how to convert it to uint8[]) to most important objects used - Location, Map, Critter and Item (but not stackable ones, due to mess with merging/splitting stacks). It can be easily extended to almost anything what a) can be identified by number, b) we can check if it exists by providing that number.
Other than Buffer, enum is second thing which has been used as a base of whole thing. Unlike defines, enums actually exists inside AngelScripts engine, so we can use them in our way. FOnline SDK does not provide anything what could make working with enums easier, so we need to provide our own stuff; lucky, it was already done at this point
When first PData is created, two AnyData entries are created - first contains data stored as byte array, and second - array of ids of single type (Critter etc.) which have anything attached to them. So for example: we want to attach array of strings to Map.
void SetMapOwners( Map& map, array<string>& owners )
{
Buffer@ buff = NewBuffer();
buff << owners;
SetPersonalData( Map, "owners", buff.AsUint8() );
}
This will do few things (let's assume that map have id 12345): first, AnyData named "PDataMap:12345" is created, where we keep our string array. Second, we push map id into array named "PDataMap". This will help us later in cleanup. But before that, let's get the saved data and abuse it hard
void GetMapOwners( Map& map )
{
array<uint8> raw;
if( IsPersonalData( map, "owners" ) && GetPersonalData( map, "owners", raw ))
{
array<string> owners;
Buffer@ buff = NewBuffer( raw );
buffer >> owners;
// ... do some heavy abuse on owners[] ... //
}
}
Due to fact that AnyData is saved forever and ever, we need to take care of removing these, which are owned by non-existing objects - instead doing it on our own (what sometimes is impossible), we're going to use time event which will watch ids saved in previously made "PDataMap" for us. All what we need to do is start it on server init (for simplicity, event is not saved in worldsave).
StartPersonalDataCleanup()
Whole system sits deep under swarm of fuctions, but in the end we should use just top layer of them.
import void StartPersonalDataCleanup() from "pdata";
import bool IsPersonalData( Location& location, string& name ) from "pdata";
import bool GetPersonalData( Location& location, string& name, array<uint8>& value ) from "pdata";
import uint GetPersonalData( Location& location, array<string>& names, array<array<uint8>>& values ) from "pdata";
import bool SetPersonalData( Location& location, string& name, array<uint8>& value ) from "pdata";
import bool UnsetPersonalData( Location& location, string& name ) from "pdata";
import bool IsPersonalData( Map& map, string& name ) from "pdata";
import bool GetPersonalData( Map& map, string& name, array<uint8>& value ) from "pdata";
import uint GetPersonalData( Map& map, array<string>& names, array<array<uint8>>& values ) from "pdata";
import bool SetPersonalData( Map& map, string& name, array<uint8>& value ) from "pdata";
import bool UnsetPersonalData( Map& map, string& name ) from "pdata";
import bool IsPersonalData( Critter& critter, string& name ) from "pdata";
import bool GetPersonalData( Critter& critter, string& name, array<uint8>& value ) from "pdata";
import uint GetPersonalData( Critter& critter, array<string>& names, array<array<uint8>>& values ) from "pdata";
import bool SetPersonalData( Critter& critter, string& name, array<uint8>& value ) from "pdata";
import bool UnsetPersonalData( Critter& critter, string& name ) from "pdata";
import bool IsPersonalData( Item& item, string& name ) from "pdata";
import bool GetPersonalData( Item& item, string& name, array<uint8>& value ) from "pdata";
import uint GetPersonalData( Item& item, array<string>& names, array<array<uint8>>& values ) from "pdata";
import bool SetPersonalData( Item& item, string& name, array<uint8>& value ) from "pdata";
import bool UnsetPersonalData( Item& item, string& name ) from "pdata";
This is probably not best example ever made for FOnline script, but whole Buffer-scripts family (yes, there's more!1one) is released for people who already have experience with developing FOnline, and are able to tune even poorly documented source (yes, that's only code i can create!1two) to own needs... sorry!
So, have fun.
https://github.com/whine/buffer/tree/master/pdata