Skript Chest Inventory Serialization (SkBee)

  • Welcome to skUnity!

    Welcome to skUnity! This is a forum where members of the Skript community can communicate and interact. Skript Resource Creators can post their Resources for all to see and use.

    If you haven't done so already, feel free to join our official Discord server to expand your level of interaction with the comminuty!

    Now, what are you waiting for? Join the community now!

AsuDev

VIP
Jan 27, 2017
241
22
18
24
United States
This is a little tutorial on how to serialize chest inventories and items using SkBee.

Main serialization function
code_language.skript:
function serializeInventoryContents(inv: inventory) :: objects:
    loop (rows of {_inv})*9 times:
        set {_i} to slot (loop-value - 1) of {_inv}
        set {_contents::%loop-value%} to full nbt compound of {_i}
    return {_contents::*}
This function will take a chest inventory and convert every item in every slot into a full nbt compound.

Main deserialization function
code_language.skript:
function deserializeInventoryContents(serialized: objects, inv: inventory) :: inventory:
    if size of {_serialized::*}/9 = rows of {_inv}:
        loop {_serialized::*}:
            set {_i} to item from nbt loop-value
            set {_index} to loop-index parsed as integer
            set slot ({_index}-1) of {_inv} to {_i}
        return {_inv}
    else:
        send "&c[ERROR] Gui size invalid. Serialized list is size %size of {_serialized::*}/9% while input inventory is size %rows of {_inv}%." to console
    return {_inv}
This function will take a serialized list of nbt compounds and reformat an inventory from serialized items.

This is pretty much all you need to actually serialize items using SkBee. If you want a version where items are stored as strings instead (for databases), you have to change the code slightly and create some extra functions.

Serialization function (strings)
code_language.skript:
function serializeInventoryContents(inv: inventory) :: strings:
    loop (rows of {_inv})*9 times:
        set {_i} to slot (loop-value - 1) of {_inv}
        set {_contents::%loop-value%} to "%full nbt compound of {_i}%"
    return {_contents::*}

Deserialization function (strings)
code_language.skript:
function deserializeInventoryContents(serialized: strings, inv: inventory) :: inventory:
    if size of {_serialized::*}/9 = rows of {_inv}:
        loop {_serialized::*}:
            set {_i} to item from nbt (nbt compound from loop-value)
            set {_index} to loop-index parsed as integer
            set slot ({_index}-1) of {_inv} to {_i}
        return {_inv}
    else:
        send "&c[ERROR] Gui size invalid. Serialized list is size %size of {_serialized::*}/9% while input inventory is size %rows of {_inv}%." to console
    return {_inv}

Want to serialize an inventory all into one string? Here is how:
code_language.skript:
function getSerializedSingleString(inv: inventory) :: string:
    loop (rows of {_inv})*9 times:
        set {_i} to slot (loop-value - 1) of {_inv}
        set {_contents::%loop-value%} to "%full nbt compound of {_i}%"
    return join {_contents::*} by "^*^"
Note: I'm using "^*^" as a delimiter in this case. You can choose to split by a different value, just make sure its a value that probably will never show up in an items data.

Deserialize single string (Using the function from above)
code_language.skript:
function deserializeSingleString(serialized: string, inv: inventory) :: inventory:
    return deserializeInventoryContents(split {_serialized} by "^*^", {_inv})

Examples:

Single string serialization/deserialization
code_language.skript:
command /teststringserial:
    trigger:
    
        # Setup inventory
        set {_inv} to chest inventory with 6 rows named "Hello"
        set slot 4 of {_inv} to 1 of apple
        set slot 15 of {_inv} to 1 of stone
        set slot 43 of {_inv} to 1 of stone axe
        
        # Get inventory serialized as one string
        set {_contents} to getSerializedSingleString({_inv})
        broadcast {_contents}

        # Deserialize our string from earlier
        set {_newinv} to deserializeSingleString({_contents}, chest inventory with 6 rows named "Hello")
        open {_newinv} to player

Using compounds list
code_language.skript:
command /testserial:
    trigger:
    
        # Setup inventory
        set {_inv} to chest inventory with 6 rows named "Hello"
        set slot 4 of {_inv} to 1 of apple
        set slot 15 of {_inv} to 1 of stone
        set slot 43 of {_inv} to 1 of stone axe
        
        # Get inventory serialized as nbt compounds
        set {_contents::*} to serializeInventoryContents({_inv})
        broadcast "%{_contents::*}%"

        # Deserialize our compounds from earlier
        set {_newinv} to deserializeInventoryContents({_contents::*}, chest inventory with 6 rows named "Hello")
        open {_newinv} to player

If you want a list of strings for serialized items, you'd basically use the same code as above, just make sure you have the functions formatted for strings instead of nbt compounds.