Persistent Attributes

The official Rising World Soundtrack is available!
You can also get the Soundtrack on Steam
  • Attributes are indeed only valid during the session. Right now it's more meant to be a convenient way to store temporary per-instance data (and possibly share it between plugins)... in fact it wouldn't be easy to make them persistent - right now it's possible to store any object as attribute (this could be a reference to another class, e.g a UI element, or just a primitive data type), but we could only store primitive data types persistently (no way to store and recover that properly).


    We could think about adding a way to store separate, persistent attributes, but that would be limited to serializable data only (e.g. primitive data types, strings, vectors etc). Custom objects could only be stored if they implement the serializable interface (but no way to store API objects, like players, UI elements etc). It would be a separate API then, like setPersistentAttribute(), getPersistentAttribute() etc.

  • I'm going to share a couple of functions I use to save/get data, which also takes in account attributes.
    With these you can simply call get/set data, if it exists returns the value and if not it returns 0.

    //Call InitDB() when plugin starts, to create a player database

    void InitDB() throws SQLException {

    db = getSQLiteConnection(getPath() + "/players.db");

    String query = "CREATE TABLE IF NOT EXISTS `userdata` " +

    "(`id` INTEGER PRIMARY KEY, " +

    "`userid` TEXT, " +

    "`key` TEXT, " +

    "`value` TEXT)";

    db.execute(query);}

    //Usage: int stepsTaken = Integer.parseInt(getData(player,"stepsTaken"));

    String getData(Player player, String key) {

    if(player.hasAttribute(key)) return player.getAttribute(key).toString();

    String ret = "0";

    String userid = player.getUID();

    String query = "SELECT `value` FROM `userdata` WHERE `key`='%s' AND `userid`='%s' LIMIT 1".formatted(key,userid);

    try(ResultSet res = db.executeQuery(query))

    {

    while(res.next())

    {

    ret = res.getString("value");

    if(ret == null) ret = "0";

    //if(key.equals("level") && ret.equals("0")) ret = "1";

    return ret;

    }

    }

    catch (SQLException e)

    {

    System.out.println(e.getMessage());

    }

    //if(key.equals("level") && ret.equals("0")) ret = "1";

    return ret;

    }

    //usage: int steps = 200;

    //setData(player, "stepsTaken", steps);

    void setData(Player player, String key, Object obVal)

    {

    if(!player.isConnected()) return;

    String val = obVal.toString();

    if(player.hasAttribute(key))

    {

    String at = (String)player.getAttribute(key);

    if(at.equals(val)) return;

    }

    player.setAttribute(key,val);

    String userid = player.getUID();

    String delquery = "DELETE FROM `userdata` WHERE `userid`='%s' AND `key`='%s;'".formatted(userid,key);

    if(val.equals("false"))

    {

    db.execute(delquery);

    //player.setAttribute(key,null);

    player.deleteAttribute(key);

    return;

    }

    db.execute(delquery);

    String query =

    "INSERT OR IGNORE INTO `userdata` (`userid`, `key`, `value`) VALUES ('%s','%s','%s');"

    .formatted(userid,key,

    val);

    db.execute(query);

    query = "UPDATE `userdata` SET `value`='%s' WHERE `key`='%s' AND `userid`='%s'".formatted(val,key,userid);

    db.execute(query);

    }


    With those set up, you can persist attribute data on the go. You can also modify them for npcs, plants, etc.

Participate now!

Don’t have an account yet? Create a new account now and be part of our community!