#(Wahrheit) NBT checking without deprecation warnings

142 messages · Page 1 of 1 (latest)

sharp fern
#

The NBT fixer script I worked on before now appears to be working great, although of course it results in script checker errors because the NBT tags are deprecated. Is there a reasonable way to write the script in such a way that it doesn't leave errors in my editor (and, ideally, is forward-compatible more or less indefinitely)?

Item_Tier_Fixer:
    type: task
    debug: false
    script:
    - foreach <player.inventory.map_slots> key:slot as:item:
        - foreach next if:<[item].has_flag[item_tier]>
        - if <[item].lore.filter[contains_text[Veteran]].is_truthy>:
            - inventory flag slot:<[slot]> item_tier:Veteran
        - else if <[value].lore.filter[contains_text[Elite]].is_truthy>:
            - inventory flag slot:<[slot]> item_tier:Elite
        - else if <[value].lore.filter[contains_text[Champion]].is_truthy>:
            - inventory flag slot:<[slot]> item_tier:Champion
    - foreach <player.inventory.map_slots.filter_tag[<[filter_value].nbt.exists>].filter_tag[<[filter_value].has_flag[nbt_converted].not>]> key:slot as:item:
        - foreach <[item].nbt.to_map> as:nbt:
            - inventory flag slot:<[slot]> <[key]>:<[nbt]>
        - inventory adjust slot:<[slot]> remove_nbt
        - inventory flag slot:<[slot]> nbt_converted
woeful timberBOT
#

(Wahrheit) NBT checking without deprecation warnings

#

Hi I'm AutoThreadBot! Don't mind me, I'll just be adding the helper team to this thread so they can see it. A human will get to you soon.
You can block this bot if you don't want to see these messages, I won't mind.
<@&525394568410038282>

gleaming fractal
#

Could probably use the new/modern NBT tags? will need a bit more manual parsing but will be a lot more future proof

#

!t raw_nbt

untold oysterBOT
gleaming fractal
#

These ^

sharp fern
#

yeahhhhhh I figured raw_nbt might have to be the move but I don't love it, it seemingly adds way more complexity

#

lol shit I don't know if I have any copies of old nbt items

silent berry
gleaming fractal
silent berry
#

otherwise, the raw_nbt is really the only reasonable option

sharp fern
silent berry
#

oh

sharp fern
#

I did not know that feature existed

gleaming fractal
#

Ah

sharp fern
#

@wicked vortex seeking secondary opinion, is this a reasonable case for using ignorewarning

silent berry
#

i dont believe he's going to say yes because it falls under ignoring critical errors, he didnt like me mentioning it to xeane even lol

sharp fern
#

realistically if we get to a point where the nbt stuff is removed and my players have nbt items I can probably fix them on a case by case basis or otherwise deal with the problem when it arises

#

technically it's a tag tracer error

#

the tag does exist the editor just doesn't recognize it because it got removed before we started doing deprecation warnings

silent berry
#

OH

sharp fern
#

if you use itemtag.nbt in game on an item with denizen nbt you will get a result

#

otherwise the script would not work

silent berry
#

yeah, it's not removed, it's just deprecated - actually i redact my comment becuase that does make sense

#

you can disable the in-game warning (as aya was starting to get to), but the editor is something totally different; for the case of fixing deprecated scripts to be modern, that absolutely sounds appropriate

#

but we can wait on his response

sharp fern
#

if monkey has a genius alternative, as he often does, I will be happy to use that

silent berry
#

that'd be an interesting extension add-on, to reflect the same concept with deprecated tags like our config lets us do for in-game

gleaming fractal
#

Reading it with the modern tags isn't that bad, something like /ex narrate <player.item_in_hand.all_raw_nbt.get[Denizen NBT].parse_value_tag[<[parse_value].after[string:]>]> gets you a map

sharp fern
#

this code is literally only here to handle updating legacy items so it's not like I'm hard depending on shit that's been removed

gleaming fractal
#

The old NBT system was before my time so not super familiar with it, but I think that should cover all cases of it

sharp fern
#

I don't think I have any items left that have denizen nbt on them

#

and I forget how the format goes for putting in the mechanism on an item script

gleaming fractal
#

I just adjusted it in-game, nbt:key/value|key2/value2

gleaming fractal
#

I.e. Your item has outdated data, please ask staff to update it or whatever?

sharp fern
#

well but if we're writing code to check whether the item exists using modern nbt tags we might as well just replace the data

#

spinning up localhost to test an item script

silent berry
#

!tag itemtag.nbt

untold oysterBOT
#
Possible Confusion

Did you mean to search for elementtag.not?

sharp fern
#
Item_Tier_Fixer:
    type: task
    debug: false
    script:
    - foreach <player.inventory.map_slots> key:slot as:item:
        - foreach next if:<[item].has_flag[item_tier]>
        - if <[item].lore.filter[contains_text[Veteran]].is_truthy>:
            - inventory flag slot:<[slot]> item_tier:Veteran
        - else if <[value].lore.filter[contains_text[Elite]].is_truthy>:
            - inventory flag slot:<[slot]> item_tier:Elite
        - else if <[value].lore.filter[contains_text[Champion]].is_truthy>:
            - inventory flag slot:<[slot]> item_tier:Champion
    - foreach <player.inventory.map_slots.filter_tag[<[filter_value].all_raw_nbt.get[Denizen NBT].exists>].filter_tag[<[filter_value].has_flag[nbt_converted].not>]> key:slot as:item:
        - foreach <[item].all_raw_nbt.get[Denizen NBT].parse_value_tag[<[parse_value].after[string:]>]> as:nbt:
            - inventory flag slot:<[slot]> <[key]>:<[nbt]>
        - inventory adjust slot:<[slot]> remove_nbt
        - inventory flag slot:<[slot]> nbt_converted
#

the script of course becomes a fucking lolcow

silent berry
#

so um, .nbt either isnt documented anymore because it was before we left deprecated tags with deprecation notices, like uh

silent berry
#

like these

sharp fern
#
dumb_test_item:
    type: item
    material: diamond_sword
    mechanisms:
        nbt: key_1/value_1```
#

/ex narrate <player.item_in_hand.nbt>

#

it works lol

silent berry
#

nbt uses the old key/value map format right?

gleaming fractal
#

filter_tag[<[filter_value].all_raw_nbt.get[Denizen NBT].exists>] can be filter[all_raw_nbt.contains[Denizen NBT]]

silent berry
#

ah, yeah

#

!tag all_raw_nbt

untold oysterBOT
silent berry
#

!lang raw nbt encoding

untold oysterBOT
# silent berry !lang raw nbt encoding

The item Raw_NBT property encodes and decodes raw NBT data.
For the sake of inter-compatibility, a special standard format is used to preserve data types.
This system exists in Denizen primarily for the sake of compatibility with external plugins.
It should not be used in any scripts that don't rely on data from external plugins.

NBT Tags are encoded as follows:
CompoundTag: (a fully formed MapTag)
ListTag: list:(NBT type-code):(a fully formed ListTag)
ByteArrayTag: byte_array:(a pipe-separated list of numbers)
IntArrayTag: int_array:(a pipe-separated list of numbers)
ByteTag: byte:(#)
ShortTag: short:(#)
IntTag: int:(#)
LongTag: long:(#)
FloatTag: float:(#)
DoubleTag: double:(#)
StringTag: string:(text here)
EndTag: end

Group

Useful Lists

silent berry
#

ow

sharp fern
#

.filter does not exist for maptags

silent berry
#

!tag maptag.filt

untold oysterBOT
# silent berry !tag maptag.filt

Returns a copy of the map with all its contents parsed through the given input tag and only including ones that returned 'true'.
This requires a fully formed tag as input, making use of the 'filter_key' and 'filter_value' definition.

Returns

MapTag

Examples
# Narrates a map of '[c=3;d=4;e=5]'
- narrate <map[a=1;b=2;c=3;d=4;e=5].filter_tag[<[filter_value].is[or_more].than[3]>]>
silent berry
#

only for the values, but not keys

#

er, i guess kind of the keys

gleaming fractal
#

Oh yeah, my bad

sharp fern
#

this will work fine

#

I still want to wait to see if monkey has a mad genius idea that is more efficient

gleaming fractal
sharp fern
#

I think it's technically more efficient to do it in the initial check

#

I don't anticipate it being a problem either way

silent berry
#

you're probably going to hate this alternative but

#

!tag listtag.to_map

untold oysterBOT
gleaming fractal
#

I mean, that's a level of efficiency that doesn't really matter, but either way might not be because this way it has to convert the item's NBT to Denizen format twice

sharp fern
#

oh that's true

#

so I could just chop the second .filter_tag entirely right

gleaming fractal
#

Yeah I'd say move the has-Denizen-NBT filtering into the loop entirely

sharp fern
#

well actually

#

not every item is going to have this nbt converted tag

#

flag

#

we need to know that the item has denizen nbt to know whether to fuck with it

#

unless I'm missing something it has to work like this

gleaming fractal
#

Also unrelated, but a tag inspired by your last post about this was added - the lore checks can now use contains_match

#

<player.inventory.map_slots.filter_tag[<[filter_value].all_raw_nbt.get[Denizen NBT].exists>].filter_tag[<[filter_value].has_flag[nbt_converted].not>]>
It's already <player.inventory.map_slots.filter[has Denizen NBT].filter[Doesn't have NBT converted flag]>, I.e. the flag check is already ran for every item, isn't it?

#

The only difference would be the order of the checks

sharp fern
#

!t contains_match

untold oysterBOT
gleaming fractal
#

Also might be missing something, but why is that flag needed? you remove all of the Denizen NBT from the item after converting it to flags, so just a check for the item having Denizen NBT should be enough?

sharp fern
#

I am notorious for over-futureproofing

#

I think you might be right though

#

I think I added it when I wasn't sure whether the remove nbt thing was still present

#
Item_Tier_Fixer:
    type: task
    debug: false
    script:
    - foreach <player.inventory.map_slots> key:slot as:item:
        - foreach next if:<[item].has_flag[item_tier]>
        - if <[item].lore.contains_match[Veteran].is_truthy>:
            - inventory flag slot:<[slot]> item_tier:Veteran
        - else if <[value].lore.contains_match[Elite].is_truthy>:
            - inventory flag slot:<[slot]> item_tier:Elite
        - else if <[value].lore.contains_match[Champion].is_truthy>:
            - inventory flag slot:<[slot]> item_tier:Champion
    - foreach <player.inventory.map_slots.filter_tag[<[filter_value].all_raw_nbt.get[Denizen NBT].exists>]> key:slot as:item:
        - foreach <[item].all_raw_nbt.get[Denizen NBT].parse_value_tag[<[parse_value].after[string:]>]> as:nbt:
            - inventory flag slot:<[slot]> <[key]>:<[nbt]>
        - inventory adjust slot:<[slot]> remove_nbt
#

I can probably condense this again now

#

right?

#

the recursion always breaks my brain

wicked vortex
#

The most efficient and most long-term sustainable option is to do it inefficiently, once, and then delete the script

sharp fern
#

ha!

wicked vortex
#

might not be an option if your world file is so big that scanning chests takes more than a day

sharp fern
#

unfortunately that would require loading every chest that has ever existed

#

yeah

wicked vortex
#

would be a pretty big world

sharp fern
#

my server tar is 27gb every time I back it up

#

so!

wicked vortex
#

ow

#

how

sharp fern
#

that's across several worlds mind you

#

lotsa big maps

#

actually maybe I do need the nested foreaches

#

currently I only run this task on player join so it's not a huge deal

gleaming fractal
#

I'd probably still do that check in the foreach, even if just for the sake of cleaner code

sharp fern
#

I think I prefer it this way for my own understanding

gleaming fractal
#

But yeah whatever way you prefer ofc

sacred quiverBOT
#
Resolved

Thread closed as resolved.

gleaming fractal
sacred quiverBOT
#
Thread Reopened

Thread was manually reopened by @gleaming fractal.

gleaming fractal
#

And the is_truthy shouldn't be needed anymore I think? as it's already a boolean

sharp fern
#

ah shit you're right lol

gleaming fractal
#

Oh wait that's a fallback for the item not having lore, isn't it?

sharp fern
#

no it's a fallback for the item not having a flag

#

you're right

#

fixed

#
Item_Tier_Fixer_Join:
    type: world
    debug: false
    events:
        after player joins:
        - inject Item_Tier_Fixer

Item_Tier_Fixer:
    type: task
    debug: false
    script:
    - foreach <player.inventory.map_slots> key:slot as:item:
        - foreach next if:<[item].has_flag[item_tier]>
        - if <[item].lore.contains_match[*Veteran*]>:
            - inventory flag slot:<[slot]> item_tier:Veteran
        - else if <[value].lore.contains_match[*Elite*]>:
            - inventory flag slot:<[slot]> item_tier:Elite
        - else if <[value].lore.contains_match[*Champion*]>:
            - inventory flag slot:<[slot]> item_tier:Champion
    - foreach <player.inventory.map_slots.filter_tag[<[filter_value].all_raw_nbt.get[Denizen NBT].exists>]> key:slot as:item:
        - foreach <[item].all_raw_nbt.get[Denizen NBT].parse_value_tag[<[parse_value].after[string:]>]> as:nbt:
            - inventory flag slot:<[slot]> <[key]>:<[nbt]>
        - inventory adjust slot:<[slot]> remove_nbt
gleaming fractal
#

.get[Denizen NBT].exists can use contains

sharp fern
#

true

gleaming fractal
#

Also I'd probably move the .parse_value_tag[<[parse_value].after[string:]>] into a <[nbt].after[string:]> in the loop as that's cleaner/more readable imo, but that's mostly personal preference

sharp fern
#

meh

#

this is not code that is getting repeated anywhere

#

an extra def seems useless

gleaming fractal
#

You already have a def from the loop, I meant just - inventory flag slot:<[slot]> <[key]>:<[nbt].after[string:]> which makes it a bit easier to understand what's going on (imo) & makes the loop shorter

#

But either way yeah that looks good, mainly wanted to point out the matcher thing

sharp fern
#

ty