#adventure-help

1 messages · Page 9 of 1

rare sage
#

what javier means is that something like text("foo", RED).appendNewline().append(text("this is also red")) will lose the red on the second line if you "just" split on an appendNewline call

summer comet
#

I assume this works fine on Chat messages but for lores is indeed a problem

boreal orchid
#

I would say it is the other way around

#

But I don’t know your use case, where are you getting these components with new lines from?

#

I guess it doesn’t matter, in the end as Kezz said, if you do want to carry style over then you’ll have to make an algorithm that satisfies your use case

summer comet
#

Yeah I'll prob put my code on my wrapper instead of increasing complexity on MiniMessage side

#

Indeed having style that break and a potential fix with performance-heavy functions doesn't sound the best

boreal orchid
#

Not so much performance heavy since you’d only do it once to port them over, just kind of annoying as there’s no shoe that fits all in this kind of situation, hence why adventure doesn’t provide an utility for it except maybe LinearComponents utility which people have used to have some semblance of style merging behavior

summer comet
#

I'll be taking a look, thanks for the help!

prisma mason
#

bump

boreal orchid
#

when using the normal deserialize method, it seems to contain a string representation of the tree as well as the exception's message

prisma mason
#

I really want the indices and parsing strings doesn't seem that effective

boreal orchid
#

if anything, you could probably make a PR so it gets exposed somehow when in debug mode

prisma mason
#

So I got it working by using some hacky stuff from internals

sterile rampart
#

ya we never fully explored how to expose that, it was supposed to be exposed as part of the completions project

#

but like, there hasn't been a ton of core parser work on MM after what was needed to shove it out the door

nova igloo
#

Hey, I'm looking to make my item looks like this: "§e§lArena §8▪ §7Clic-Droit" but using Component, I've been using different ways but still can't achieve the correct format, either all the text is getting bold or not a single character is, how can I do it ?

Current code:

@Override
  public @NotNull ItemStack getIcon(final Player entity) {
    return ItemBuilder.from(Material.NETHER_STAR)
        .name(
            Component.text("Arena", NamedTextColor.YELLOW, TextDecoration.BOLD)
                .append(Component.text(" ▪ ", NamedTextColor.DARK_GRAY)
                        .decoration(TextDecoration.BOLD, false))
                .append(Component.text("Clic-Droit", NamedTextColor.GRAY))
                    .decoration(TextDecoration.BOLD, false))
        .build();
  }

Current render:

sweet hornet
#

You should try making an empty root component, and then applying your style to individual child

#

Something along the line of:

Component.text()
    .append(Component.text("Arena", ...))
    .append(Component.text("..."))
    ...
    .build();
#

Because right now, your entire text is getting bold because you apply the bold style on the root component of your tree

upper tinselBOT
molten jasper
#

how to use adventure when im using properties file for translation keys but need diffrent number of lines for item description
because in diffrent languages sentences take diffrent amount of space

boreal orchid
#

sadly the properties file standard don't have a concept of lists so that's the best you can do with it

molten jasper
boreal orchid
#

just make sure to offer a reload command in your plugin so they can quickly change the translations lol

#

if your question is how to make them the same length in any language, that'd involve component splitting which isn't something that Adventure supports, at least yet. You'd have to make your own algorithm for that by using the component iterator as well as figuring out when to split based on character width

proper sandal
#

does the legacy component deserializer produce a linear output?

sweet hornet
#

Why?

proper sandal
#

it doesn't really matter honestly, made it recursive just in case

#

I'm trying to sanitize a component, thought there was some neater way to do it

sweet hornet
proper sandal
#

I should've asked the actual question first

sweet hornet
proper sandal
#

is there a neater way to iterate through a component and all its children already

#

while mutating them

proper sandal
sweet hornet
#

Iterating, yes, mutating, no since they're all immutable

#

However, you can get a builder using toBuilder() to something like this, and then .mapChildrenDeep(...)

#

(Method names may not be 100% accurate, check the javadoc for the exact ones, I've not used them in a while)

proper sandal
#

that's more like it, thanks

#

I'll have to check if it applies to the root component as well

#

doesn't look like it does, at least according to the javadocs

sweet hornet
#

iirc, the only downside is that mapChildrenDeep method is only on builder (because they need to be mutable) and you can't call toBuilder on a generic Component, you need to cast it to a concrete type (TextComponent, TranslatableComponent...), which is a little bit sad

proper sandal
#

I have a text component since I deserialize one using the legacy serializer

sweet hornet
proper sandal
#

the annoying part is that it doesn't apply the mapping to the actual component you pass it to, just the children

proper sandal
#

perhaps, I'll give it a shot

#

thanks

cloud vapor
#

sounds like a big xy, if you tell us a bit more about what you're actually doing we could point you to a better answer

sweet hornet
#

(But it's true it's very little info about the actual goal)

molten jasper
#

any other suggestions on how to do this?

sweet hornet
#

I guess you could have a key my.translation.key and loop through .0, .1 and so on?

cloud vapor
#

i just have a system where you do smth like "find every key.N key, loop until there's none left"

#

yeah basically that

molten jasper
#

while(true)
getTranslatedComponent(key.i)
if(component == null) break
addcomponent

#

but

#

if the key isnt found it doesnt give null right

#

so its unsafe

cloud vapor
#

you can just canTranslate(key, locale) so even easier

molten jasper
#

okay so this way

#

so maybe just iterate like canTranslate(key.i)
and if false then break?

cloud vapor
#

yep

molten jasper
#

thanks that works

cloud vapor
#

that's how i do it

molten jasper
#

actually one more thing i would ask you guys but that's more about general code managment i would say

sweet hornet
#

Maybe adding a built-in method to do so would be nice? So it makes like a clear intended way to handle multi-line translated lore, which could reduce the number of times this question is asked? x)

molten jasper
#

however so im having one abstract class on which another classes are based like for example stick or rod
and then normally im builidng itemstack in abstract class because this logic is practically same

#

however for the description it needs arguments which differs a lot based on class
however the logic of getting the description componenets is the same

#

oh yeah that;s also something i didnt think through much

#

so for example i have description like this:
where 2 hearts ( 4<3) is injected as an argument

#

however what if in another translation this first and only argumnet is on 3rd line

sweet hornet
#

I guess named arguments would be the way to go?

#

(But it only works for MM translation store iirc)

molten jasper
#

yeah im not sure if this would work in my case i didnt use them before

sweet hornet
#

Otherwise, you could always provide the whole list of arguments for every line, and then use numbers to reference them (I think you can)

#

Which translation store are you using?

molten jasper
#
    public static void loadTranslations(){

        MiniMessageTranslationStore store = MiniMessageTranslationStore.create(STORE_KEY, MiniMessage.miniMessage());

        for (Locale locale : SUPPORTED_LANGUAGES) {
            ResourceBundle bundle = ResourceBundle.getBundle(
                    BASE_NAME,
                    locale,
                    UTF8ResourceBundleControl.get()
            );

            for (String key : bundle.keySet()) {
                String message = bundle.getString(key);
                store.register(key, locale, message);
            }
        }

        GlobalTranslator.translator().addSource(store);

    }
#

im using miniMessageTranslationStore actually

sweet hornet
molten jasper
#

yeah that would also make it so i can actually get description components from the abstract class then write desc arguments in sepcific class and get them and render them into description right

sweet hornet
#

And only using it on the second line

#

But since you're using MM, I would suggest you to use named arguments

molten jasper
#

and then just if im using another argument then write in arg:1 right

sweet hornet
#

You can also use the Argument class to create named tags for ease of use. For example, this component Component.translatable(key, Argument.component("name", Component.text("Kezz")) will produce the string “Hello, Kezz!” when used with either Hello, <arg:0>! or Hello, <name>!.
https://docs.advntr.dev/minimessage/translator.html#using-a-minimessage-translator

molten jasper
#

yeah but i still have to pass it to all components read from desc.i

#

right?

#

i mean its more readable

sweet hornet
#

Of course

#

That's it

summer comet
#

Hey guys, not sure if anyone can help me on this one but do you have any idea how i can translate placeholders together with MiniMessage? Cause i have the MM Component, but PlaceholderAPI only accepts String and converting to String as we all know will lose information

sweet hornet
summer comet
supple schooner
#

How to net.kyori.adventure.text.Component -> net.kyori.adventure.nbt.BinaryTag?

sterile rampart
#

they're two completely different things lol

supple schooner
sterile rampart
#

for now the best way is to go via MC's serializers

#

or like, serialize to json and use DFU to convert json to nbt

#

eventually we want to do up native dfu codecs for adventure types so we aren't reimplementing the same logic 50 times for slightly different formats and libraries

supple schooner
summer comet
#

Hey guys, is the MiniMessage.miniMessage().serialize 100% reliable? (While using Paper ItemStack)

#

When i meant reliable, is it gonna really provide me with the correct syntax, without losing anything, so then when i do try to deserialize it again, it will match the original

sand drift
#

I mean, that is generally the intent, not doing so would generally be a failure and we have tests to try to ensure that

#

Do note that long term persistence of such data components is 100% unsupported by mojang however

cloud vapor
summer comet
#

Everything would stay in-memory, not sure if that is what you mean

boreal orchid
#

it isn't bad per-se, just not particularly clean way to do things. I do think there's cases where you can't avoid it though

summer comet
boreal orchid
#

you can do MM on Spigot too, if you're willing to use internals

summer comet
#

Tried creating a wrapper on both components but everything gets more difficult so working based on non-styled components (String-based), and then only create wrapper for end-results such as Player message, Items (like a encoding) is the one strategy i would say

summer comet
#

I mean, lets be honest, why would u still use Spigot right? If you really wanna use MM, I'm sure you would be okay going to paper

boreal orchid
#

it sounds bad but internals about these things are pretty solid right now, them being data components and all

boreal orchid
#

I don't particularly believe it is as annoying as one would think it is, just definitely not as straightforward of a process as it is on paper given the native support for adventure

summer comet
summer comet
boreal orchid
#

so, what you're trying to do breakthrough is kinda annoying because there's no good way to have a placeholder that is extended over multiple lines when it comes to the lore

tulip wedge
#

yeah

#

should i just do ugly stuff

boreal orchid
#

what I would do is just have the members part be a flag instead, so they can turn it off and on

tulip wedge
#

i just did ugly stuff

#

works perfectly

#

sometimes ugly stuff is the way to go

boreal orchid
tulip wedge
blazing drift
#

hi can anyone tell me how to remove all the players from my bossbar? or more precisely how do I completely remove the bossbar from the server?

rugged leaf
#

I just found out that this method exists net.kyori.adventure.text.minimessage.translation.Argument.numeric(String, String)

I think that one should be called "text" or something like that instead, right?

broken spade
#

when a player sends a chat message i want the message to be "formatable" using the minimessage formatings, so for example if the player sent "<red>hi" it would return a red hi. problem is that i can't pass a Component, which the chat renderer returns, to the .deserialize method. are there any other ways i could go about this?

sand drift
#

Well, you want the plain text contents of the components

broken spade
#

yes

sand drift
#

(use the plain text serialiser)

broken spade
#

something like this?

sand drift
#

Yes

broken spade
#

im dumb as shit, thanks for the help lmao

prisma mason
#

nah, nothing wrong with asking

broken spade
#

i read the docs like 3 times and i was unsure of the correct solution

#

i tried using the .serialize method on the miniMessage() but that cancelled the tags by putting a \ in front of it

sand drift
#

Well, yea, they're part of the contents to it escapes them to keep them as part of the contents 😄

blazing drift
#

guys, so who can tell me how to forcibly delete the boss bar from the server? I'm sorry for my English (I don't know it at all :D)

sand drift
#

I'd imagine that you're in the wrong channel

#

hiding platform specific bossbars is platform specific

blazing drift
#

Well, I use the library bar. And it is not possible to delete it as in the same Bukkit.

sand drift
#

paper doesn't expose the native bossbar in adventure

midnight spire
#

Audience#hideBossBar ?

blazing drift
rare sage
#

bossbars created via adventure are not tracked on the server

midnight spire
#

that's what the name says, yes. But you can't create native bossbars with adventure anyways as far as I'm aware?

rare sage
#

as long as you hide it to the player and lose a reference to it, there is nothing tracking it

sand drift
#

if you want to remove a player from an adventure boss bar you just remove them as a viewer somewhere

#

method on BossBar literally calls viewer.hideBossBar lol

cloud vapor
rugged leaf
#

Oh, I must be using an old version or something, then

midnight spire
#

is it just me or is adventure 4.25.0-SNAPSHOT not released to the maven repo?

cloud vapor
#

looks like it should be but yes that is weird

uneven silo
#

Hey, is there a library i can use to convert a minimessage string to html, kinda like the minimessage webui, but for javascript / typescript?

robust wharf
#

Nah, we didn't want to maintain a duplicated parser that might diverge, so they webui uses a server

#

But it has an API if you want

uneven silo
#

Understandable. What does the API allow me to do? Is it possible to send a minimessage String and get html in return?

robust wharf
#

Yep

#

I doubt it's documented but I can find you the endpoints in the code I think

uneven silo
#

Thanks. I'll see what I can find.

robust wharf
#

Uff I think we only have mini to json as a rest request, the other was moved to websockets

uneven silo
#

I'm creating a localization system for Minecraft plugins. Now when a now translation is added there should be a preview how it would look in game:
That of course means, I would have to send a request everytime a new character is entered

sand drift
#

fairly sure we already do that with the web UI?

uneven silo
#

Hmm right

sand drift
#

Like, you could always self host it yourself if so desired

#

There just isn't the interest in having to maintain two entirely different parsers with potentially differing behaviors, especially with the feature set of MM

uneven silo
#

Yeah I understand. I would definitely self-host it so that I don't burden the official instance.

robust wharf
#

For editing workflows there is an official api

#

Idk how exactly it works, never used it, but I think it generates a custom link to webui and you edit and save stuff and then your backend can retrieve the saved value

uneven silo
#

I don't think this would help me there? Thonk I just need the preview, the rest is handled through my backend.

robust wharf
#

Ah that's also not documented, I think only kezz uses it

#

If you already have a backend just have a route that uses MiniMessage?

#

Oh wait you need the html

uneven silo
#

Yes, or is there a better way to render it on a website? lul

robust wharf
#

Maybe a proper html serializer for adventure components is worth it? It's def not an unusual request

#

You would still need to have your own backend but then you just throw stuff together in a couple of lines

uneven silo
#

That would be great

robust wharf
#

Sounds like a fun project for somebody

sterile star
#

It wouldn't be impossible, but there is just some stuff which is kinda hard to implement (like sprite components from 1.21.9, everything that uses server state, and stuff like translatables).

#

I mean, you could just render the translatable key, but I think that is not clean for stuff like this

sweet hornet
#

I guess just do it like the current MM webui does

sterile star
#

I don't think it has support for object components just yet

#

So that is new territory in general

sweet hornet
#

(I was talking about translatable)

sterile star
#

How does it do them?

sweet hornet
#

Player heads wouldn't be that hard (just requires a little code and a few calls to Mojang's API), but sprites yeah without the vanilla resource pack, they wouldn't work. Maybe providing a way to hook a resource pack would solve it

#

No idea, I guess they renders the key

sterile star
#

I think rendering the key is not that great, maybe a Vanilla lang file on there for resolving would be great

sweet hornet
#

Oh no it just disappear

sterile star
sweet hornet
uneven silo
#

So, until the html serializer (maybe propably) becomes reality, what would be the best solution to my probem?

sterile star
#

You could make your own simple one. Something around the lines of MM -> Component -> Json -> HTML (with your own, very simple custom serializer, only needs to support colors and styling, and that should not be particularly hard to implement)

wicked torrent
#

no idea if it does what you need but there is an html serializer in squaremap

sterile star
#

@uneven silo btw could you open an issue on the adventure repository for this as a feature request just so that somebody more official can approve/deny it officially

#

I think having some input from the team would be good before anybody spends a sizable amount of time on that just for it to be rejected

robust wharf
#

I would start simple, as in, the stuff that is easily representable in html without any data or API or whatever

#

Can always extend later

robust wharf
sweet hornet
#

However idk if the best would be to output a completely standalone HTML element (with all styling embedded), or to use proper markup and CSS classes, and make it work with a predefined stylesheet

#

Either way, the fact that both HTML and components are trees should greatly help

prisma mason
#

oh wait hover boxes exist, hmm... 🤔

prisma mason
#

why does

<hover:show_text:\'test\'>test

fail?

cloud vapor
#

Not sure, but you should probably be using <hover:show_text:"'test'">test instead

#

Please open an issue

civic prawn
#

are there ways to split a component part way through its contents and insert another?

cloud vapor
#

What's the xy?

#

Few options, so it depends on what you're trying to do

civic prawn
#

ie component.text("foobar") -> component.text("foo").append(component.text("biz")).append(component.text("baz"))

cloud vapor
#

that's not xy :p

civic prawn
#

xy?

sweet hornet
#

why

upper tinselBOT
civic prawn
#

sorry i think misunderstand

#

ohh right

#

sorry was tryign to write another then responded to urs so

#

pretty much trying to play with the new sprite stuff at least partially,, i know i can split a component by its string contents and replace strings within a component, what i want to do is split a component where i see specific text and append the sprite component where that text previously was

#

kind of starting to believe this isnt really supported though lol

cloud vapor
#

can you give a real-world example?

#

e.g. expected input & desired output

civic prawn
#

someone types

hi XYZ, how are you

xyz gets replaced with the sprite component, so i suppose this would only have to handle textcomponents?

sweet hornet
#

(I add another question: how do you get your components in the first place?)

civic prawn
#

oh yeah sorry from chatevents

sweet hornet
#

It's basically text only then?

civic prawn
#

yeah

#

ig it works just as well if its possible to get all the text out of a component and just make another out of the text

#

sorry ended up being a bit drawn out with explanation.. probably shouldve fronted w that

sweet hornet
#

So, you should extract the plain text content as a string and work with that (do whatever manipulation you want, and then use something like MiniMessage or build a component yourself if you really want to control precisely the output)

cloud vapor
#

i mean it depends what XYZ is - fixed text? player name? placeholder? etc

civic prawn
#

any piece of text a player could send really

cloud vapor
#

that doesn't make sense, how would that even work haha

#

be more specific :p help us help you

sweet hornet
#

The question was: What do you want to replace in the text written by the player?

civic prawn
civic prawn
cloud vapor
#

Here's an example of the kinda info I'm looking for from you:

I would like to replace player names with the player name prefixed with their head as an object component

sweet hornet
#

That's what you want to add instead, but what do you want to remove

civic prawn
civic prawn
cloud vapor
#

okay there we go! so you've got a config with a map of strings -> sprites?

civic prawn
#

mhm!

#

sorry

#

oh you know what

#

im a complete bloody numpty

#

there is a content method in a text component..

#

idk how did not notice that XD i think should be able to do that w that,,, though dont think it would work if we got a player message that didnt contain a plain text message but Maybe that wont happen /shrug 😭 sorry again thank you for trying to walk through my rambling

prisma mason
#

is this an issue or expected behaviour?

#

@cloud vapor I hope you don't mind if I ping you for this

prisma mason
#

But why does

<hover:show_text:fo"o"b"ar>Hello!

parse thonk

shadow wyvern
#
component = component.replaceText(configurer -> {
            configurer.matchLiteral("%previous_page_button%").replacement((matchResult, builder) -> {
                if (page > 1) {
                    builder.append(formatPageString(options.previousButtonFormat, page));
                } else {
                    builder.append(Component.empty());
                }
                return builder;
            });
        });
``` this doesn't seeem to actually replace the text, but rather append like after the text
boreal orchid
cloud vapor
boreal orchid
shadow wyvern
#

how do I do that?

cloud vapor
boreal orchid
#

you probably just want to set it to an empty text and then append

cloud vapor
boreal orchid
#

or I guess you could just forget about the provided builder altogether and return your formatPageString component

cloud vapor
#

i think you might need to make sure you copy over children?

boreal orchid
#

uh, that could be a thing. I know the text replacement renderer does it for you when you use a simple string replacement but I don't remember what happens when you do the function replacement

civic prawn
civic prawn
#

oops sorry ping

boreal orchid
#

And I don’t mind pings

civic prawn
#

that should remove some of the blehh'y parts from my code actually... ty !

buoyant mortar
#

hey, i added

implementation 'net.kyori:adventure-api:4.24.0'

to my project and i have access to stuff like Component, but for some reason, the Key class; the entire net.kyori.adventure.key package does not exist for some reason. Why is this?

rare sage
#

it's still a transitive dependency of adventure-api so something else in your build setup is being funky

buoyant mortar
#

ah ok, is there a github?

buoyant mortar
sterile star
#

Including key

buoyant mortar
#

not for me. this is what worked:

implementation 'net.kyori:adventure-api:4.24.0'
implementation 'net.kyori:adventure-text-serializer-gson:4.24.0'
implementation 'net.kyori:adventure-key:4.24.0'
#

i had to include it separately even though it's apparently transitive?

#

but if it works it works i guess

prisma mason
#
implementation(platform("net.kyori:adventure-bom:4.24.0"))
implementation("net.kyori:adventure-api")
implementation("net.kyori:adventure-text-minimessage")
buoyant mortar
#

this is getting out of hand:

    implementation 'net.kyori:adventure-api:4.24.0'
    implementation 'net.kyori:adventure-text-serializer-gson:4.24.0'
    implementation 'net.kyori:adventure-key:4.24.0'
    implementation 'net.kyori:examination-api:1.3.0'
#

i will use the BOM, but how come i have to declare each one independantly? is there no all-in-one artifact?

#

also this?

        return GsonComponentSerializer.gson().deserializeFromTree(json);
                                      ^
  class file for net.kyori.adventure.text.serializer.json.JSONComponentSerializer not found
boreal orchid
#

as for your issue, it is probably because you don't have the text-serializer-json module? Though it should be a transitive dependency of the gson module, make sure your build script isn't messing your classpath

#

also, is this a project independent of paper?

buoyant mortar
#

yes, i am experimenting with my own server software

#

just to see how some stuff works

buoyant mortar
cloud vapor
#

You really don't, key is a transitive of the api and json is transitive of gson which are both transitive of the api. Your built setup is scuffed if you have to declare each one individually

midnight spire
#

how does one create a ClickEvent with an Action and a Payload object? The constructor is private and the ClickEvent.clickEvent only takes a string (and the page) as the payload?

sand drift
#

ClickEvent.custom

midnight spire
#

no, that's not what I mean

#

I want to supply an arbitrary ClickEvent.Action object and it's Payload, similar to how it was in the past with the ClickEvent#clickEvent(Action, String) method but now there are payload types and that method is deprecated

sand drift
#

arbitary Action makes 0 sense

midnight spire
#

it does when you are parsing it from a string

#

meh, it doesn't like me cheating with reflections ;_;

cloud vapor
#

didn't see a use case for it before

#

bc you can just switch on the action

vague lintel
#

I just updated the version and not the color codes don't process

cloud vapor
#

gib more info pls

vague lintel
#

update adventure-platform-bukkit to 4.4.0

#

was working fine on older version of adventure-platform-bukkit

quaint monolith
#

What was working fine?

cloud vapor
#

code? platform? version? client version? etc?

vague lintel
#

processing the color codes

cloud vapor
#

cool thanks for answering literally zero of my questions, ill be sure to polish off my crystal ball to get you an answer asap

vague lintel
#

Sorry I had to eat dinner, now that I'm back lets see if I can figure out what you ask

#

adventure-platform-bukkit 4.4.0
Paper 1.21

quaint monolith
#

"processing the color codes" unless I'm just out of touch this doesn't actually mean anything

vague lintel
#

I don't recall whre the code is in the plugin, was over a year I did that

#

this is what I get in game <LIGHT_PURPLE>Active paths (<GOLD>Creative<LIGHT_PURPLE>): <GOLD>Active

vague lintel
#

I missed undo some code change from the auto fix, I rebuild and test again

cloud vapor
#

also you don't need adventure-platform on paper

tepid trench
#

Hey in the linearcomponentbuilder, how do I make the italic/bold etc sections stop? I dont see a RESET

fiery oracle
#

do you mean LinearComponents?

#

you could use TextDecorationAndState, i guess?

fleet crown
#

Is there a way to keep component style that was before in Component.replaceText(...);?

return component.replaceText(TextReplacementConfig.builder()
  .match("(/join\\s+\\S+)")
  .once()
  .replacement((match, builder) -> {
      String command = match.group(1) + " " + match.group(2);
      if (!someCondition) {
          // return default text that was before
          // in current it will return without any style
          return Component.text(command); // ???
      }
     
      return Component.text(command)
          .decorate(TextDecoration.UNDERLINED)
          .clickEvent(ClickEvent.suggestCommand(command));
  })
  .build());
quaint monolith
#

I think you'd have to manually copy over the style and decoration?

#

builder should have that data

rare sage
#

or you could just mutate the builder you are given shrug

quaint monolith
#

Doesn't that have the original text in it though?

rare sage
#

you can also just change that

quaint monolith
#

Well I guess it would have to be a single component with that text

rare sage
#

TextComponent.Builder#content(String)

#

text replacement only works on contiguous pieces of text in text components anyway and not across components

reef sedge
#

Does someone know how to use the Player Head Component with Adventure?

midnight spire
#

you just do it?

#

which part are you having trouble with?

karmic crystal
#
Searched in the following locations:
  - file:/C:/Users/pzvi/Downloads/totemNotifier/.gradle/loom-cache/remapped_mods/net/kyori/adventure-text-minimessage/4.25.0/adventure-text-minimessage-4.25.0.pom
  - file:/C:/Users/pzvi/.gradle/caches/fabric-loom/minecraftMaven/net/kyori/adventure-text-minimessage/4.25.0/adventure-text-minimessage-4.25.0.pom
  - file:/C:/Users/pzvi/Downloads/totemNotifier/.gradle/loom-cache/minecraftMaven/net/kyori/adventure-text-minimessage/4.25.0/adventure-text-minimessage-4.25.0.pom```
#

implementation("net.kyori:adventure-text-minimessage:4.25.0")

#

im confused

#

why wont this import

#

can someone help 🙏

fiery oracle
#

also wait, 4.25 isn't even out yet, is it?

karmic crystal
fiery oracle
#

what website?

#

afaik you'd need to add the snapshot repo to have access to 4.25

karmic crystal
#

why did it tell me to use that then bro 😭

fiery oracle
#

~shrug~
4.25 is probably coming out soon and those docs were just merged in, so probably just a case of them being updated a bit soon?

weak arrow
#

how can i make the MiniMessage#serialize(Component) method not to escape the < char?

quaint monolith
#

Manually unescape it afterward

weak arrow
#

😭

boreal orchid
weak arrow
#

🤫

proven otter
#

i'm trying to make a minimessage tag that adds a space between every charecter inside it, how would i do that? i want all the tags/placeholders inside it to be parsed first.
aka: <space:2><red>hi</red><level></space>
parses to h i 1 0 0 assuming level is 100

cloud vapor
#

You'd want to look at a modifying tag - shouldn't be too hard

sweet hornet
#

Placeholders are resolved from the inner-most to the outer-most, iirc, so I should "just works"

proven otter
sterile rampart
rare sage
#

ur fun

sterile rampart
#

prove it

proven otter
sterile rampart
#

uh whatever abstractcollrchangingtag does

rare sage
#

bless you

proven otter
sweet hornet
# proven otter oh god... modifying tags scare me

They're not that difficult, once you played a little bit with them. However there are a few things that are good to know before (otherwise you just spend more time figuring them out yourself):

  • The apply method is called with every component of the child tree (recursively), and the root (the first child, i.e. the whole content) is at depth == 0.
  • Children gets carried over automatically after the apply method, so if you want to not modify the component for whatever reason, you need to clear its children otherwise they'll get duplicated (component.children(List.of())).
  • If you want to traverse the tree yourself, you should only do it at depth == 0 and always return Component.empty() otherwise (so all the children become empty, and are not added)
#

If you want an example, here's an abstract class I'm using as a base for all my text-related Modifying tags:

public abstract class TextModifying implements Modifying {
    public abstract @NotNull String modifyText(@NotNull String text);

    @Override
    public @NotNull Component apply(@NotNull Component current, int depth) {
        if (current instanceof TextComponent text)
            return Component.text(this.modifyText(text.content()), text.style());
        return current.children(List.of());
    }
}

Feel free to take inspiration

proven otter
#

woah tysm!

#

this should be a lot easier now!

cloud vapor
#

hm, that might be a nice thing to have in the api if you fancy a pr :p

sweet hornet
# cloud vapor hm, that might be a nice thing to have in the api if you fancy a pr :p

Why not, however I would need to make sure about a few corner cases I am wondering (but never really got them myself):

  • I don't know about VirtualComponents, but I saw that when checks are done in other classes, they test for them to exclude them from instanceof TextComponent
  • Server-side translatable components could technically get processed as well, but it gets trickier and I never really played with that in practice
cloud vapor
#

whew yeah those are two tricky ones haha

#

i think you could either ignore or exclude virtual components that's fine

#

not sure about the second one, probably nothing you can do about that

sweet hornet
cloud vapor
#

they're just an implementation of TextComponent that holds some additional data that you can use to do funky stuff with

sweet hornet
#

Oh, so here the additional data would be lost with that code?

cloud vapor
#

yeah it would

sweet hornet
#

But since the content would be modified, it makes sense to drop that additional data because it could no longer be relevant?

cloud vapor
sweet hornet
#

Oh so the renderer of the virtual component is that additional data

cloud vapor
#

yeah

#

tbh i'd just skip virtual components entirely, too niche to bother for 99% of cases really

#

you could remake it with modified text ig

#

no ignore me, virtual components always have empty text

sweet hornet
#

So they're safe to ignore, and their children will get processed normally

cloud vapor
#

yep

sweet hornet
#

Nice

ruby lynx
#

the 4.25.0 release does not seem to be on the maven repository

midnight spire
#

it is

#

the search might've just not indexed it yet

ruby lynx
# midnight spire it is

Could not determine the dependencies of task ':demo:demo-minestom:compileJava'.

Could not resolve all dependencies for configuration ':demo:demo-minestom:compileClasspath'.
Could not resolve net.kyori:adventure-api:4.25.0.
Required by:
project ':demo:demo-minestom' > project :core:core-all > project :core:core-shared > project :api:core-api:core-shared-api
project ':demo:demo-minestom' > project :ootb:ootb-layer:ootb-layer-onboarding > project :api:layer-api:layer-core-api > project :platform:platform-minestom > net.minestomminestom1_21_9-SNAPSHOT:20251006.134713-8
Could not resolve net.kyori:adventure-api:4.25.0.
Could not parse POM https://repo.maven.apache.org/maven2/net/kyori/adventure-api/4.25.0/adventure-api-4.25.0.pom
Could not find net.kyori:adventure-bom:4.25.0.
There are 8 more failures with identical causes.

Odd because it does not seem like my project can fetch the dependancy

midnight spire
#

not sure what repo that is but it seems to include outdated jars

#

it's in https://oss.sonatype.org/content/repositories/releases/

#

ah, apparently central doesn't have it yet for some reason? I assume they do manual checks before publishing

green monolith
#

I know that in the past central could have ~10 minutes of delay between upload and it actually being on central, not sure what the situation is now that they migrated over to their new system.

cloud vapor
#

Just be patient, it takes time

#

It's in central for me, not for others - the rollout is gradual it seems or whatever cdn they use caches 404s or smth

hardy estuary
#

since replaceText doesnt work if message is "gradientized" is there an alternative?

sweet hornet
#

Certainly. Why would you need it? It's highly possible you can do without it

hardy estuary
#

mostly not for myself, but a plugin used for resourcepack, is not able to do replacement when the message is gradientized. But strange thing is that he uses AsyncChatDecorateEvent which is called before my event (AsyncChatEvent)

sweet hornet
#

And why don't you use something like <alien> instead?

#

(With the correct tag resolver/placeholder)

stark kiln
#

Players/people are accustomed to emois in format like :rolling_eyes:, with colons

hardy estuary
#

yes

sweet hornet
#

Then do preprocessing of :something: into <emoji:'something'> and let the emoji tag resolver do the job (and fallback to :something: if the given emoji doesn't exist, so it undo the preprocessing done on incorrect texts)

hardy estuary
#

intercepting the message with packets, before it reaches PaperMC, will give problems to signature of the message?

cloud vapor
#

Zero reason to do that even if it does/doesn't

#

The chat event is basically a packet wrapper

hardy estuary
#

He mostly doesnt want to do that with event, to avoid altering the signature

cloud vapor
#

idk what you mean by that

#

you can't alter the signature

tepid trench
#

hey how would I obtain the list of tags from a tagresolver?

sweet hornet
#

Why?

tepid trench
sweet hornet
#

I know it once was a goal to provide auto-completion, but the idea wasn’t completed. Idk if there is still a draft somewhere you could inspire from

#

Maybe you can find a way to decompose your resolver that way

tepid trench
#

I am not sure how I would be able to use that to get all the tags though. But I'll have a look if I can find some info on that attempt at auto-completion

#

#923037327578771457 message seems like its just one issue that gets mentioned here and there. I guess I am just perpetuating the cycle because I am not sure if I have the abilities to fix this ;p

cloud vapor
#

it's not possible with the current api design bc tag resolvers dynamically match names - we'd need to expose a "completions" method somehow

#

it's not a big change assuming you only care about tag names, but becomes a bit more complex if you want to think about arguments too

tepid trench
#

Ah okay. thanks for the info!

#

so this would require breaking the api a little to add? TagResolver implementations would have to implement some kind of complete method?

cloud vapor
#

it wouldnt' break the api, as you could just default impl the method

tepid trench
# cloud vapor it's not a big change assuming you only care about tag names, but becomes a bit ...

Yeah only doing the tag names was quite easy. though finding a nice way to incorporate arguments has me stumped at the moment.
I added these methods to the interface: https://github.com/KyoriPowered/adventure/commit/6185ef508436d4c0a6f3740b07c8cb553c9ec23a#diff-485f6e5af727bcf56f843458cc0eef95903ea879f4fa4f72721a23bf7f1e9852R234-R237

But I think to make a functional autocompletion with this you would somehow need to know how many arguments a given tag needs

-# sorry for the ping, forgot to untick it

cloud vapor
#

So my idea of the design of it is a sealed CompletionContext object (an arg or a tag, the list of args) and then return some CompletionResult interface which can either be a concrete list of strings or some other implementation that holds a name of an argument or some other descriptor

jagged field
#

Could someone point me in the direction of finding a list of keys for the Keybind Tag

prisma mason
jagged field
tepid trench
cloud vapor
#

minimessage would create the context and pass it to a method in tag resolver - it being generic like this would let us e.g. expand to do argument completion later

weak hull
#

how do you apply the tint to an atlas?

#

I am doing something like:

import static net.kyori.adventure.text.object.ObjectContents.sprite;

Component spriteComponent = Component.object(sprite(
        Key.key("minecraft", "blocks"),
        Key.key(spritePath)
));
#

but things like leaves are greyscale

cloud vapor
#

You can't

#

Does colouring the component work?

boreal orchid
#

Coloring the component does work, I’ve accidentally tinted a sprite when trying that out lol

cloud vapor
#

neat!

broken spade
hardy estuary
hardy estuary
#

is the plugin colorizing the chat yours?

broken spade
#

currently not home but my plan was to maybe plain serialize the message and replacing the emojis with the placeholders before deserializing it again

#

havent tried yet thougj

hardy estuary
broken spade
weak arrow
#

how can i replace text independently of stuff like color and style? imagine i have a text and part of it is a rainbow "0123456", so each char is a different color; i want to add a hover event to the whole "0123456" and keep the color and any other formatting

boreal orchid
weak arrow
#

the rainbow was just an example, but im trying to replace an already made up Component

#

i want to add a hover to the second WizardlyBump17

quaint monolith
#

Probably easiest to serialize it to MM, do transforms to that text, then deserialize it

boreal orchid
#

you'll have to iterate through the component tree to do that, but again it is kind of tricky if it comes down to a lot of colors

boreal orchid
quaint monolith
#

Not sure on that front actually, was just thinking regex is easier to understand than a custom tree iterator

weak arrow
quaint monolith
#

Sure, just means you need a better regex 😄

wet kestrel
#

And it makes me wonder why you're already generating multicolor text before deciding "ya know what, I should add something else here"

quaint monolith
#

They're trying to edit someone else's message

boreal orchid
#

I imagine it has something to do with chat, yeah

#

probably adding an entity hover event to a player's display name or something

#

though if that's exactly the use-case, I think you could get away with something like this:

@EventHandler
public void onChat(AsyncChatEvent event) {
  event.renderer(viewerUnaware((source, displayName, message) -> {
    var uuid = source.getUniqueId().toString();
    return miniMessage()
      .deserialize("<hover:show_entity:'%s'><name></hover>: <message>".formatted(uuid), 
      component("message", message), 
      component("name", displayName));
  }));
}
heavy rover
#

what does velocity do when I send an object component to a 1.21.8 player?

wet kestrel
#

I imagine velocity doesn't care. Did you mean to say viaversion?

heavy rover
#

would velocity pass a 1.21.9 object component to a 1.21.8 connected player?

cloud vapor
#

You'd also have to ask velocity

viral lagoon
#

Can I use components (or minimessage) to display player heads and items, as has been possible since the 1.21.9 update?
Example: /title @a title {player:{name:Jeb_}}

cloud vapor
#

Yes - see object component and head/sprite tags

viral lagoon
#

👍 Thanks.
Do you know if adventure v4.25.0 is used in Paper 1.21.10-R0.1-SNAPSHOT ?

sweet hornet
slender garnet
#

how would i get the name of an enchantment in english/the player's language?

#

e.g., bukkit Enchantment.SHARPNESS -> "Sharpness"

#

translationKey is deprecated

#

(as a Component.translatable)

cloud vapor
#

Enchantment#description

slender garnet
#

oh thanks

#

does it take into account their language setting?

boreal orchid
polar nebula
#

Uhm, what's the exception thrown when a deserialization fails due to having legacy colors?

sweet hornet
#

ParsingExceptionImpl

sweet hornet
#

Which string-based encoding would you recommend to transfer a component between 2 programs? (I'm not storing it, it will be used immediately by the other program, and both programs will run with the exact same version of adventure, this is guaranteed)

sand drift
#

go for gson I'd guess

sweet hornet
#

(Technically it also work if the encoding is not strictly string-based and encodes as bytes, since I can always use base64, but you got the idea)

sweet hornet
#

I already use Gson to encode my full data object as JSON (the data contains various values, such as an UUID, a timestamp, and a component)

#

Would it be possible to do a "all-in-one" encoding, like configuring my Gson instance to properly encode/decode Component class?

#

(If not possible or not worth it, I'll just put a String in my data class and handle the component encoding myself, and it'll work, but was just wondering)

sand drift
#

I mean, sure, maybe, potentially

#

you'd need to grab all the type adaptors from the gson serialiser module and add them into your own thing

sweet hornet
#

Because I could also do it the other way around, since I'm using a plain new Gson() instance with all defaults, I could just grab the Gson from the serializer

#

Oh I think I understood what it was by looking at the impl

dense granite
#

Can the sprite text component be used in a form like Component.sprite(...)?
sprite text component?Component.sprite(...)のような形で使用できるようになりますか?

25w32aで来たObject Text Componentってこういうことね!
絵文字みたいにマイクラ内のアイテムをテキスト表示に使えると!!
マイクラのアイテムならわざわざリソパ作らんでもいいと!!!

うわぁお、ありがてぇ~~~~✨

boreal orchid
dense granite
#

thank

slender garnet
#

will two identical components return the same HashCode?

sweet hornet
#

What do you mean by "identical"?

slender garnet
#

e.g.,

for(int i = 0; i < 10; i++) {
    System.out.println("hashCode: " + Component.text("Test", NamedTextColor.GOLD).hashCode());
}

will this print the same thing 10 times?

sweet hornet
#

Yes

slender garnet
#

ok ty

sweet hornet
#

But we're talking about structurally identical components here, not visually identical ones

#

(Obviously, structurally identical components are also visually identical, but the reverse isn't always true)

slender garnet
#

i see

#

this is my usecase
obj.getScore("" + line.hashCode()).setScore(score--);
obj.getScore("" + line.hashCode()).customName(line);

dawn pewter
#

why are you using the hashcode for that?

slender garnet
#

there's no Objective.getScore(Component)

obsidian nimbus
#

e.g two different components may have same hashcode

daring heart
#

hi I was wondering how to know if this replacement was successful since it only returns a component

            for(final String match : REPLACEMENTS.get(key)) {
                nextComponent = nextComponent.replaceText(TextReplacementConfig.builder()
                    .matchLiteral(match)
                    .replacement(replacement)
                    .once()
                    .build());
            }
#

I just need a boolean to know whether something was updated or not
if anyone knows feel free to ping me

boreal orchid
daring heart
#

thank you

tiny bone
#

seems like the item doesnt show properly

sweet hornet
#

The "minecraft:items" atlas doesn't exist iirc

#

It's all in "minecraft:blocks"

#

And because this is the default atlas, you could just write <sprite:item/porkchop> / <sprite:block/stone>

tiny bone
#

thank you!

sterile star
#

Maybe we should fix that kekw

daring heart
#

hi

            final Component message = attribute.paintComponent(cosmetic.getMessage());
            final var replacement = TextReplacementConfig.builder()
                .matchLiteral("<name>")
                .replacement(KyoriHexUtil.colorify(this.buildName(user)))
                .once()
                .build();

            Bukkit.broadcast(message.replaceText(replacement));

I want to find <name> in my component and just replace it, I can't use TagResolvers or anything because I'm working with legacy code so it'd be too much of a hassle to modify everything, also the component looks like this sometimes

I want to just replace any reference of <name> with the component provided by KyoriHexUtil, is this possible?

quaint monolith
#

Nope, as soon as you made each one a different color you made this much harder

#

You can't just replaceText, you'd have to walk the tree and figure out if you're seeing <name> manually

#

Each character is a separate component, replaceText only works within a single component in the tree

daring heart
#

do you have any recommendations on how to do this or am I just cooked

sterile star
obsidian nimbus
daring heart
sour totem
#

you are already using components, if your codebase is in a state were you cannot add minimessage somewhere in between then perhaps you should do some much needed refactoring

#

the library you are working with is also called adventure, kyori is the name of the organization behind it

midnight spire
#

I mean, isn't that exactly what the replacement system is for or am I missing something?

sour totem
#

it is

#

(the one in minimessage at least)

midnight spire
#

I was referring to the one in adventure directly which they are already using

cloud vapor
daring heart
# cloud vapor Can you explain a bit more about your use case? It seems you might already be us...

Kind of.

I use MiniMessage in some scenarios to parse out the colors & you're right I use MiniMessage to do the gradient work.

But I also need to support different kinds of ways to build colors, i.e. "discrete" colors, provided below is the code to make discrete colors work.

public class DiscreteColorPainter implements ColorPainter {
    @Override
    public Component paintComponent(ColorService.Context ctx) {
        if(ctx.contents().isEmpty()) {
            return Component.empty();
        }

        Component component = Component.empty();
        int idx = 0;

        for(final ColorService.Content content : ctx.contents()) {
            if(content.special()) {
                component = component.append(Component.text(content.content()));
                continue;
            }

            for(final char c : content.content().toCharArray()) {
                final ColorContainer container = ctx.colors().get(idx);
                // skip over the letter i guess..
                if(container == null) {
                    continue;
                }

                component = component.append(Component.text(c)
                    .shadowColorIfAbsent(ctx.shadowColor())
                    .color(container.toTextColor())
                );

                if(++idx == ctx.colors().size()) {
                    idx = 0;
                }
            }
        }

        return component;
    }
}

Where I cycle through each TextColor then rebuild my string with each character using a new color.

Unless MiniMessage can support this kind of way of coloring then I don't think I'm able to use it for my use-case.
If I can build a MiniMessage tag to do this kind of coloring then I will be over the moon and implement that ASAP

daring heart
obsidian nimbus
#

what kind of overcomplication is ts

daring heart
midnight spire
#

what do you mean by "cycle through each TextColor"? Like a gradient? Or random colors for each character?

sweet hornet
cloud vapor
cloud vapor
daring heart
#

could you provide docs/an example? RockCheer

#

I'll go impl that into my resolver ASAP

cloud vapor
#

Yeah you'd be wanting to effectively adapt the gradient tag to change the colour for each character and remove lerping

#

so kinda like a simplified form of that tag

sweet hornet
daring heart
#

Gotcha, tysm Kezz & indyteo

cloud vapor
sweet hornet
#

Nice

cloud vapor
prisma mason
#

hey @cloud vapor I think ComponentSerializer#deseializeOrNull should also be removed as its been deprecated since 4.8.0 (<t:1623175431:R>)

sterile rampart
#

they just don't want to let me forget my spelling :p

warped pond
#

it is sad that adventure 5.0 will move from java 8, i know it is necessary but i planned to use adventure in a platform agnostic module implementation that can support multiple versions, however if the java required version changes that will not be possible anymore

tawny bolt
#

Older versions of the game can use modern Java too, you can just require that

wet kestrel
#

My approach is "you want to run something in 2025? Use modern Java." and my maintained 1.8 plugin requires Java 21. I know you said platform agnostic and I'm only talking Bukkit derivatives, but surely other maintained outdated platforms have upgraded themselves to 21 by now or are outdated in a "wow this server is insecure on the public internet" way.

warped pond
radiant shadow
sterile rampart
#

I mean why does 1.16.5 sponge matter? it ships with a fixed adventure version already

#

And at the end of the day, we have better things to do than restrict ourselves to old java versions on a hobby project

#

if you want to target old game versions, the old adventure versions aren't going anywhere

cloud vapor
#

Yeah old game versions target old Adventure versions, that's just how it works 🤷 You can always make your own adventure-platform-esque impl or just use that when we update it to Adventure 5.0

quiet sluice
cloud vapor
#

so yes we will be sealing key

quiet sluice
#

mainly the Minecraft client allowing file names with capital letters, and we use a key to store the paths of them "distant_horizons:darkTheme.svg" for example

#

that breaks when we try to store it

#

there're probably some other characters the client accepts that adventure keys do not

sweet hornet
#

Are those capitals really supported or only "tolerated" by the client? I mean, what are the docs/specs saying about this?

quiet sluice
#

probably tolerated

sweet hornet
#

And maybe this is a kind of stupid remark, but couldn't you just rename those files to have a more complient file name? dark_theme.svg

quiet sluice
#

we load assets that aren't ours

sweet hornet
#

Ah, I see

quiet sluice
#

as annoying as it is, we kinda have to work around it

#

luckily we're in a modded environment, worst case is mixin to key to remove the checks

sweet hornet
#

Then maybe the adventure key implementation should enforce only what Minecraft itself enforces, and maybe provide a configuration option to more strictly prohibit those characters

#

(Or the other way around, an option to be lenient instead of more aggressive)

quiet sluice
#

yeah that'd be a nice solution

sweet hornet
#

And just it doesn't really solve the issue, but iirc Windows filesystem is case insensitive. So maybe distant_horizons:darktheme.svg would work, at least on Windows?

#

But that's not a good solution indeed

#

Oh damn Windows is worse that I think:

The Windows file system supports setting case sensitivity with attribute flags per directory. While the standard behavior is to be case-insensitive, you can assign an attribute flag to make a directory case sensitive

#

Anyway really not a good idea to rely on this

cloud vapor
#

Capital letters are invalid characters in vanilla, I don't think whatever you're doing would be supported by the client either https://minecraft.wiki/w/Resource_location#Java_Edition

Minecraft Wiki

Resource locations (also known as namespaced IDs, namespaced identifiers, resource identifiers, or namespaced strings) are a way to declare and specify game objects in Minecraft, which can identify built-in and user-defined objects without potential ambiguity or conflicts.

#

We specifically match what the java edition client accepts

rare sage
#

that's going to be fun

cloud vapor
#

we have Keyed for that lol

sterile star
#

That's gonna suck with most of new Paper API taking in a Key and many users entering NamespacedKeys to them

#

Or does Keyed extend Key so that it would still work?

sweet hornet
#

I guess it's rather Key extends Keyed

sterile star
#

Well Keyed is iirc just an interface with has a method to return a Key. So making Keyed implement Key and it just delegates all method calls over to the underlying Key wouldn't be unplausible

#

I haven't looked at the key project, so idk how it is handled

sweet hornet
#

Long story short, Key = Keyed + Namespaced

cloud vapor
#

I think we might just have to unseal Key, it's not even marked as non-extendable atm

#

you actually have to ignore me ive already made that decision key isn't even sealed in 5.x lmao

sterile star
#

lol

quiet sluice
#

perhaps it's just skipping that asset, which we could also do

untold quarry
#

Isn't there any workaround for the lore newline problem so far?

sterile rampart
#

there is, specifying your lore as a list

dawn pewter
#

Why would there? It’s not intended to use newlines

sterile rampart
#

if you want newlines, you can always implement splitting

untold quarry
#

I'm using a TagResolver that doesn't really know where it's displayed, but it makes as newlines as necessary, and in my usecase the ItemStack creation for lore is based on a TranslationStore key/val with the args I specify.

For context, even though it may appear x/y problem, here is the layer of abstraction I'm using, which is based in config:

interface ItemStackWithArgs{
  ItemStack from(Locale locale, ComponentLike... args);

}

and I normally do itemStackWithArgs.from(player.locale(), Resolvers.myComplexResolverThatMayMakeMultiLines()

untold quarry
sterile rampart
#

pribably not

#

take a look at how replaceText is implemented

untold quarry
#

Hmm will check, but ain't the ComponentFlattener just traverse all over the component tree and I can have a List<Component> and only append when text isn't containing \n, but if it does just create a new entry in the list?

sterile rampart
#

no

untold quarry
#

TextReplacementRenderer is way too cooked for me

#

I guess reworking my abstraction would be easier 😂

untold quarry
sterile rampart
#

aaaand that's why component.split() doesn't exist yet :p

untold quarry
#

someone should have done it 🙁

#

I have seen this, but seems like it's still work in progress

sterile rampart
#

its a volunteer project lol

untold quarry
#

ik, I really appreciate the hardwork, tho I'm still surprised no efforts were made in resolving this issue

#

like each year I come to see if something new happened with this problem and still not yet anything new 😂

#

back in days when it was about legacy coloring, a String#split would resolve the problem lol, we can do it with LegacyComponentSerializer but that seems too cursed

boreal orchid
sweet hornet
#

Splitting on \n character isn't particularly hard (I've done it), however it's also relatively limited, because if you are able to place newlines yourself in your component, why not split it in multiple ones from the beginning...

boreal orchid
cloud vapor
#

The reason it hasn't been done is because it's not a good idea. It's considerably easier and more user friendly to start with a list in the first place

boreal orchid
#

how does that work with placeholders that span over multiple lines though

#

you just don't have those I guess? Lol

cloud vapor
#

Yep

sweet hornet
boreal orchid
#

then with each splitting, you could just decide whether you want to merge the previous component style or not

sweet hornet
sand drift
#

Knowing when to split is the easy part

#

it's the whole "splitting trees" which becomes somewhat cludgy

sweet hornet
polar nebula
#

Uh so I know I can use Placeholder#parsed() to create static placeholders in MM but how would I do ones where the output is dynamic aka depends on a condition (but can be static still)

sweet hornet
#

Can you give an example?

wet kestrel
wet kestrel
#

I do some stuff where I pop an arg and then switch

polar nebula
#

I see

#

would a Tag#inserting be the correct choice for a tag that just outputs a specific thing?

wet kestrel
#

Imagine Kitty says <meow>! where you compare a Tag#inserting and Tag#selfClosingInserting, and have the meow tag output a red meow. With inserting, the exclamation mark is red, with self closing it doesn't pick up the red.

polar nebula
#

I see, interesting, thanks!

#

Uhm actually, if I were to want the output of a tag to contain other tags, is it automatically parsed or would I have to deserialize it twice so to say?

#

In my case I am turning a component to string and then to component, wouldn't it be better to just do string manipulation at this point?

boreal orchid
#

nested tags should be parsed automatically

boreal orchid
polar nebula
polar nebula
# boreal orchid probably? What's the actual xy here

tldr; intercepting system chat messages, converting them to string, applying custom placeholders generated by the user (what I am trying to do), then convert it back to a component. Idea is to add minimessage support everywhere with some extra stuff

#

Not really sure how I'd properly approach this

#

I was previously only using static placeholders which made this easy but yeah, now I am not sure

boreal orchid
#

I am confused at the goal here, you would add mini message support to third-party messages (as in, not sent by your plugin) even though they wouldn't use them?

polar nebula
boreal orchid
#

for player messages I would understand, but for system messages I don't

boreal orchid
polar nebula
#

well the question is if I do the custom tags/placeholders handling when its a string or after deserializing

boreal orchid
#

I would just do it at deserialization, there shouldn't be anything that dynamic replacements don't support for this kind of thing

polar nebula
#

so using tag resolvers?

boreal orchid
#

yes

polar nebula
#

hmm can someone explain this error: Tag name must match pattern [!?#]?[a-z0-9_-]*, was p_isOnline? What exactly is this pattern

sand drift
#

lowercase

polar nebula
#

oh damn

#

missed that

lunar yew
sweet hornet
#

That's a known issue iirc, I've already heard of that one

#

Which version are you using?

#

It seems it has been fixed

#

Oh no that might still be an issue if you're using named arguments, as stated here, since this other issue is still open

lunar yew
#

Arguments are in the format {0}, {1}, {2}, ... .

sweet hornet
#

You're using MiniMessageTranslationStore or the other one?

lunar yew
sweet hornet
#

Then check the version of adventure in use (by that other plugin)

#

The issue you seems to encounter has been solved in 4.22.0

lunar yew
#

I'm assuming that adventure is provided by paperweight. So I'm not sure

#
id 'io.papermc.paperweight.userdev' version '2.0.0-beta.18'
sweet hornet
#

Which version of Paper are you on?

lunar yew
#

1.21.4-RO.1-SNAPSHOT

sweet hornet
#

Hmm, that might be why, let me check the adventure version in use by that version

#

Yep

#

Paper 1.21.4 uses Adventure 4.20.0

#

Your issue has been fixed in Adventure 4.22.0

lunar yew
#

Ouch

sweet hornet
#

So you either need to update to more recent Paper version (not a bad thing but can require more work), or bundles your own version of Adventure to use it, but you might have other issues by having 2 different adventure versions

lunar yew
#

I see, I'll let the developer of the translation plugin know. Thanks for the help

sweet hornet
#

Np, good luck for the rest x)

hardy estuary
#

This is not really a bug, but a small problem.

Basically I use PlainTextSerializer to flat a component then I parse the string with Minimessage to remove any know tags <red> <blue> etc.

Some users found a cool way to bypass this:

<<red>blue>How are you? has <red>

It will result in a blue colored message "How are you? has"

sterile star
#

Why not just use a MiniMessage instance without the default tags?

hardy estuary
hardy estuary
wet kestrel
#

I'm still confused. What are you doing this for.

#

Like, if you don't want them adding tags why is it going through mm

sterile star
#

That's the second question I wanted to ask lol

#

(Valorant was more important)

hardy estuary
wet kestrel
#

Okay, are we talking something like chat formatting?

sterile star
#

Why not parse the message as plaintext with the plaintext serializer and then insert it into the minimessage string with a component placeholder?

wet kestrel
#

unparsed takes string, strok

#

If it's the component from the event though I'd just push that component, without plaintextserializer, into a placeholder

sterile star
#

😠

#

I am still playing valo

wet kestrel
#

My point was the edit was unnecessary

hardy estuary
wet kestrel
#

then yes, what we said

hardy estuary
#

Will read it in a bit xD and properly reply

hardy estuary
wet kestrel
#

What on earth is this cursed format?

#

<player_name> -> <red><message> and then player name and message are placeholders.

hardy estuary
wet kestrel
#

Oh okay, then create a tag resolver to do papi.

<papi:player_name> -> <red><message>

hardy estuary
#

mmm is this documented? I mean has Minimess a way to resolve placeholder api placeholders? (without knowing them)

#

ah good lemme read it

#

hanks

wet kestrel
#

I wrote it :3

hardy estuary
#

thanks*

prime sigil
hardy estuary
#

the thing is always the same, if it was for me, this wouldnt have been a problem xD. Problem starts to arise when I have to make it extremely customizable without headache for the end user.

Btw that doc is helpful so thank you

civic loom
#

Is there a way for the server to know if a player hovered on a text? It looks like you can’t listen to HoverEvent. I want to do this to collect metrics

wet kestrel
#

Sounds cool, but I don't think there's anything sent back for that.

sweet hornet
#

Not the client doesn’t share this info

#

Your only way would be to set a click event and ask the user to click after hovering

unborn oxide
#

Why are messages not sending to a player?

  • Server version: Spigot 1.21.8
  • Spigot-API: 1.21-R0.1-SNAPSHOT
  • Adventure version: 4.25.0
  • Adventure Platform Bukkit: 4.4.1

Code example:

public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {

        Audience adventureSender = plugin.adventure().sender(sender);

        System.out.println(adventureSender.get(Identity.NAME)); // returns Optional[teunjojo]

        MiniMessage mm = MiniMessage.miniMessage();

        Component parsed = mm
                .deserialize("Hello <rainbow>world</rainbow>, isn't <underlined>MiniMessage</underlined> fun?");

        adventureSender.sendMessage(parsed);
}

when using plugin.adventure().sender(sender) no messages get send to the player but plugin.adventure().console does send it to the console
What am i doing wrong?

wicked torrent
#

have you actually downloaded and compiled spigot yourself or are you using paper

unborn oxide
#

actually spigot

wicked torrent
#

you'll need to enable debug logging for adventure platform and go from there, the flag should be in the docs somewhere

#

but if you're already targeting 1.21+ you should just drop spigot support and make things easier on yourself

unborn oxide
#

im targetting 1.8-1.12.8

wicked torrent
#

if you really want to hold on to old versions for longer then I would do a break and ship two jars

#

you will need separate code for paper eventually anyway, we update separately from and before spigot now (see our snapshot branch)

#

the 1.21.8+ paper only one does not

unborn oxide
#

alright

wicked torrent
#

long term that will have less maintenance, but if you still want to debug platform-bukkit debug logs are needed

unborn oxide
#

also on 1.8 it does show the messages but when i do

adventureSender.showTitle(Title.title(
        Component.text("Main title"),
        Component.text("Subtitle")));

the title doesn't show up

#

idk if that is somehow related

wicked torrent
#

big blue box about it there

unborn oxide
#

i set the flag but i dont get any special output. also when calling showTitle on 1.21.8 i get disconnected and the console throws an error:

[Netty Epoll Server IO #2/ERROR]: Error sending packet clientbound/minecraft:set_subtitle_text
io.netty.handler.codec.EncoderException: Failed to encode packet 'clientbound/minecraft:set_subtitle_text'
wet kestrel
sand drift
#

for an encoder exception you might need to enable debug in server.properties, vanilla does a good job of silencing exceptions inside of their networking stuff

unborn oxide
#

Ok so I don't know what I did but all of a sudden all, i got the debug messages, no more crashes and the messages and titles started working

#

thanks for the help tho

runic onyx
#

<@&748618676189528155>

wintry radish
#

How can I replace multiple texts in a component?

If I do this, then only {name} is replaced:

CachedComponents.IMP.player.kick.realname.replaceText(builder -> builder
        .matchLiteral("{realname}")
        .replacement(user.getRealName())
        .matchLiteral("{name}")
        .replacement(player.getUsername()))
boreal orchid
wintry radish
wet kestrel
#

It
Takes
WHAT

#

Please provide a spark report

stark badger
#

Must be a massive message

wintry radish
#

oh, sorry, I got the zeros a little wrong.
i converted nanoseconds to milliseconds incorrectly

#

but the very essence is the same, as for me it is better to create a component in advance than to do it in runtime

stark badger
#

Must be a very unusual use case

wintry radish
#

problem solved, i found a solution

dawn pewter
wintry radish
# dawn pewter What was the solution?

make two separate replaceText

btw, I checked, it's better to use match(Pattern) instead of matchLiteral(String) because with matchLiteral(String) the Pattern is compiled every time
instead, better to create a static Pattern and use it so that the replacement takes less time
that way it'll be more optimized

lunar yew
#

Sending this component to a player sends the correct message in chat, but it's missing hover and click events. Any idea why? Both messages from the config are TranslatableComponent's.

final Component acceptComponent = this.config.messages()
                .get(PlayerTradeMessageConfig.Messages.INCOMING_TRADE_REQUEST_ACCEPT_MESSAGE)
                .hoverEvent(HoverEvent.hoverEvent(HoverEvent.Action.SHOW_TEXT, this.config.messages().get(PlayerTradeMessageConfig.Messages.INCOMING_TRADE_REQUEST_ACCEPT_TOOLTIP)))
                .clickEvent(ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND, "/trade " + this.sender.getName()));
cloud vapor
cloud vapor
lunar yew
cloud vapor
#

any protocol hacks on your server or proxy?

lunar yew
cloud vapor
#

viaversion, other such plugins that mess with the protocol level, etc

lunar yew
#

viaversion, viabackwards is all we have probably

#

packetevents too

cloud vapor
#

try without those and you'll likely find what's causing it

molten jasper
#

okay so

#

to get player Locale i have to do smth like this

#

redisConnection.getPlayerData(uuid).getPlayerLanguage
so currently when i for example want to send message to all 10 players in game
i have to do it by for each player
getLanguage
translatableComponent = Component.translatable(key, args)
player.sendMessage(GlobalTranslator.translator().translate(translatableComponent, locale);

cloud vapor
#

yes there is no way to override the locale for a player yet but it is on my to-do list post 5.0 release

#

but you could easily extract that into a util method

molten jasper
#

okay so thats the only correct way to do this rn right?

cloud vapor
#

yep

molten jasper
#

just displayed the code for understanding

molten jasper
#

I was thinking of something like
TranslatableComponent
Audience.sendMessage(translatableComponent, ( road to player language like: ) redis.getPlayerData(playerInAudience.getUUID).getPlayerLanguage)
but whatever achieves goal of sending message to many players in diffrent languages based on those cached locale im
good with it

cloud vapor
#

depending on how you do your translation, it's possible to override the locale when creating the component (e.g. the built-in minimessage translator system lets you override it)

untold quarry
cloud vapor
#

You're also not getting (or very unlikely to get) better performance

untold quarry
#

right, although idk what's the point of not just using minimessage

#

after the MiniMessageTranslator was released, and the Argument class, it was my way since then

#

super flexible and easy to use

untold quarry
molten jasper
#

It wont work

#

It wont translate to the players sleecred language

untold quarry
#
players.forEach(player -> {
   var playerLocale = myOwnLocaleResolver(player);
  player.sendMessage(GlobalTranslator.get().translate(playerLocale, messageKey));
});
#

?

#

something like that

cloud vapor
untold quarry
untold quarry
cloud vapor
#

lmk if there's anything you think we could do to improve it!

molten jasper
untold quarry
#

right, if that means a lot for you why don't you fork adventure and add a way to set the locale (e.g. modify the locale pointer i guess?)

#

or just make your own abstraction

#

though they would def add it later but for now it's what it is lol

ripe tulip
#

i'm having an issue where my apostrophes are getting doubled up when displayed in game

this is my minimessage text (the hover:show_text at the end is where the issue is) :
message.command.map.output=<meadow>:earth_africa: <click:open_url:"https://map.worldmc.org/?zoom=6&x=<x>&y=64&z=<z>"><ash>Click here to view your location.</click> <hover:show_text:"<ash>Can't see yourself? Make sure you aren't under blocks or water!"><aqua>🛈

this is the code sending it:

sender.sendMessage(Component.translatable(
  "message.command.map.output",
  Argument.tag("x", Tag.preProcessParsed(String.valueOf(location.getBlockX()))),
  Argument.tag("z", Tag.preProcessParsed(String.valueOf(location.getBlockZ())))
));
#

i tried escaping with backslashes and more quotes and stuff but i couldn't figure anything out

fiery oracle
#

what's your code for creating the translator & registering the translations?

wintry radish
boreal orchid
boreal orchid
# wintry radish

yes, that compiles the literal and then that TextReplacementConfig is used to create the TextReplacementRenderer, which stores the Pattern in the TextReplacementRenderer.State class

#

so, there shouldn't be any difference

sweet hornet
boreal orchid
#

that would make sense

#

tbf I can't blame them for not reusing the config when most replaceText examples use the method that takes a consumer of the TRC builder

rare sage
#

compiling a literal pattern shouldn't take that long, lol

#

can't really say anything without a proper profile report however

untold quarry
sage tiger
#

For some reason I can no longer get the adventure-text-feature-pagination from maven. I've checked the https://central.sonatype.com/ site but can't find the package anywhere?

sweet hornet
#

iirc it's not longer published because it was never published (officially). Only snapshots were, and they expired. And since the project is discontinuated, you'll need to publish it yourself to your own repo, or build it locally

near valley
#

Sorry if this gets asked a lot but when will dialog support be worked on? The last time I checked a bunch of people wanted to wait until the dialog system becomes stable. According to the minecraft wiki mojang hasn't made any changes to it since it was initially added in 1.21.6, which was over 4 months ago now.

upper tinselBOT
near valley
# upper tinsel

that's why I asked when it will be worked on, not when it will be finished

sterile star
near valley
#

For how many more game drops do you want to wait then? Mojang could always make big changes to it, no matter how long you wait. I dont think there is gonna be a better indicator that it's gonna be stable for a while other than mojang not touching it.

sweet hornet
#

You basically answered yourself

#

I dont think there is gonna be a better indicator that it's gonna be stable for a while other than mojang not touching it.

near valley
#

well it's been over 4 months

#

of them not touching it

sweet hornet
#

And a single game drop

near valley
#

consider reading the first part of my message

sterile star
#

I am not entirely certain why this is a discussion. The adventure team will introduce a dialog API as soon as they believe it is safe to do, anything apart from that are just speculations

sweet hornet
#

Tbf, the whole dialog thing, while being revolutionary (compared to older alternatives, such as chat or chests), still feels harsh, and unfinished (there are a few "simple" features that could get added or reworked that could make the thing way better). So yeah maybe Mojang is happy with that, and they won't change it, and this waiting is "unnecessary", but considering they worked a lot on technical features and ability to customize things recently, the contrary wouldn't be surprising either. Anyway, I'm not the one who took that decision, and I blame no one for that because even if I don't completely agree (my personal opinion is that even if Mojang improves the dialogs, they won't change the whole system, but that's just my personal opinion), I understand the adventure team's point of view

near valley
#

mojang could always make major changes to the whole system and they probably will at some point

sweet hornet
#

Of course, we all take decisions based on how we think the future will be. How else could we do? I don't have a crystal ball x)

near valley
#

but we can't know when, so more waiting is pointless imo.

sweet hornet
#

Mojang has shown by the past that they could add something, and immediately change it in the next update(s)

#

So this is not far-fetched to think it could happen with dialogs

near valley
#

I agree but again

#

they haven't changed it in the update after

tepid trench
sweet hornet
#

(However, considering they did not change a thing about them in the latest update, yes we can begin to question whether this will be the case this time or not. And maybe the team will reconsider their decision. Or maybe not, idk, they take whatever decision they think it the best for their project)

sand drift
#

A single update isn't really too reflective of much, bearing in mind how much components have been churned around since

#

Adventure wants to be able to offer stable API

near valley
#

I feel like with this mindset, this could go on forever. If they keep it in its current state, you'll say it's clearly unfinished and they will touch it again. And if they do change it again you're also gonna keep waiting because "well clearly they're still working on it".

near valley
sweet hornet
#

Additions are fine

sand drift
#

Components were added in updates, they went back and modified a chunk of stuff from their first iteration in the 2nd gamedrop or so iirc

rare sage
sweet hornet
#

A "stable" API could receive new features (otherwise it would be a problem lmao), the things that are harder to handle is when a part of an API needs to change because it can no longer work the same

sand drift
#

like, perpetual can kicking is always a risk, but there is some level of trepidation over adopting brand new entire systems and writing the API for it, especially when there has been a whole host of feedback against it, I'd imagine it might be easier to start now, but, project done in free time, etc

rare sage
# sweet hornet Which one?

see for example the whole mayhem that was 1.19/.1/,2 etc around chat signing, first it was sender uuid, then it was signatures, chat types etc etc

#

adventure adopted every single one of those changes and a large chunk of those methods have been deprecated ever since because mojang just changed how the mechanisms worked the very next version

sweet hornet
rare sage
#

yes, so the question becomes: how long should one wait?

sweet hornet
#

Good thing Adventure 5.0 removes those

rare sage
#

how long is long enough

sand drift
#

I think that the decision to wait a version probably forgot how game drops worked now

sweet hornet
#

That's a tough question, of course. A question I could share my point of view of the answer, but idk if it would be very useful since I'm not the one taking decision (thankfully xD)

sweet hornet
near valley
#

I think waiting one game drop is enough. It's reasonable to assume that they will make adjustments to a new system in the following game drop. But after that it just becomes blind speculation.

cloud vapor
#

If you want an "official" answer - our current focus is the 5.0 update, then we'll likely revisit dialogs if they're still "stable" after the next drop or two

quaint monolith
#

I don't understand the rush

#

Paper already has an API for it, Fabric I'm sure you can just use Mojang's own stuff

#

Adventure's might end up being nicer to use but it's not like you can't do dialogs right now

rare sage
#

it does bring the point of abstraction, just write code for it once for all rather than once for each, i think it's fair enough given the surface area of the system

quaint monolith
#

I suppose but my guess is they're hoping for adventure-platform-bukkit to support it and that's the only concern 😛

tepid trench
#

I suspect they want to use it on velocity.

quaint monolith
#

adventure having an API for it isn't going to magic that up, although I suppose velocity could be waiting for adventure to have an API before adding dialog support

boreal orchid
#

I honestly don't believe there's any point in waiting either but I just assumed that adventure has very little manpower to muscle through a good design for the dialog API and nobody was up for a job that could possibly be thrown out of the window if Mojang decided to change things up, so we are where we are

#

it didn't come at a good time either given 5.x was in the works when dialogs were introduced, so that took focus instead. Though it would've been nice if 5.0 release would've introduced the dialog API, we're not there yet

tiny bone
#

Heya, iam creating a brigadier cmd that makes it able to edit a sign line.
i get the sign and the sign side then i set its line with the text to Component
however when i use sprites in the chat it shows on the sign as a black block instead of the sprite (blue_wool)
iam using sprite:block/blue_wool

untold quarry
#

Can client side translations take translation arguments 🤔?

#

didn't try client-side translations nor any mod development yet to know, but if they do support receiving translation arguments from server side, that would be neat

boreal orchid
untold quarry
#

ahh that sucks

rare sage
#

it doesn't use MessageFormat, it uses its own format that is basically a stripped down version of String.format, arguments can be and are components, what is not a component is the translation format itself, but it can take components for arguments

hollow valve
#
var player = (Player) commandSourceStack.getSender();

        var template = "<click:open_url:'ddd'><#ffe49c>Join our Discord server!</click>";
        var message = MiniMessage.miniMessage().deserialize(template);

        var component = Component.text().append(message).clickEvent(ClickEvent.openUrl("ddd")).build();

        player.sendMessage(component);
```

Does anyone know why the custom color code doesn't work
fiery oracle
#

what's your platform & the platform's version?

#

are you using the vanilla client? version?

proper oriole
#

could anyone tell me why my message when im not using <!i> at the start is always italic?

upper tinselBOT
dark rain
#

Because that inherits origin style which includes italics

twilit night
cold granite
#

Hey, I got an issue where the ' character gets duplicated, when I use translatable Components.
For instance my properties (UTF-8) has the following line: command.speed.set.other=Set <yellow><player>'s</yellow> speed to <yellow><speed><yellow>.
which is sent as Set players''s speed to 1.0. to the player/console.

cloud vapor
#

Set escapeSingleQuotes to false in your bundle loading code

cold granite
#

Whats the usecase for escaping single quotes? When does it come in handy?

prisma mason
#

otherwise you can't escape them

round bronze
#

How can I force adventure to parse the legacy style from the text components and fallbacks of translations?

My current code:

private static String translateInternal(Component component, Locale locale) {
    String discorded = DiscordSerializer.INSTANCE.serialize(GlobalTranslator.render(
            component, Objects.requireNonNullElse(locale, TranslatorUtils.DEFAULT_LOCALE)
    ), SERIALIZER_OPTIONS.withMaskedLinks(true));

    if (discorded.contains("§")) { // legacy
        discorded = DiscordSerializer.INSTANCE.serialize(
                LegacyComponentSerializer.legacySection().deserialize(discorded),
                SERIALIZER_OPTIONS.withMaskedLinks(false)
        );
    }

    return discorded;
}
cloud vapor
#

Just go from component -> discord, running it through the global translator first if you need to

round bronze
cloud vapor
#

why would you have legacy formatting inside a component? sounds like that's where your issue lies

round bronze
#

A good example would be something like:

    "name": {
        "translate": "translatekey",
        "fallback": "§4Fallback" // legacy
    }
cloud vapor
#

just don't do that, you can specify colour in json fine

#

best to keep one unified format

round bronze
#

As long as Minecraft can accept it, people will use it

cloud vapor
#

Then you're just gonna have to plain text serialize and hope you don't lose any other styling information

round bronze
#

I need parity with Minecraft

cloud vapor
#

This is why mixing formats is awful, no matter whether you're making a Minecraft plugin or something completely different

cloud vapor
round bronze
#

🙄

cloud vapor
#

Yeah, welcome to the joy of mixing formats haha

round bronze
#

how it works in minecraft?

cloud vapor
#

no clue, you'd have to look at the source

round bronze
#

Does bungeecord chat support this?

cloud vapor
#

Nope

#

You'd be having to do the same thing no matter what component library you were using

#

In fact you'd likely find it harder in bungeechat as they don't provide a framework for custom component renderers

round bronze
#

Why is it that using anything by Paper always has to be such a pain? moyai_wahhhh

cloud vapor
#

if you want help im here and happy and willing to help you but if you're just gonna complain and be rude then good luck you're on your own 👍

round bronze
#

Thank you for your help, I will continue my research! indigo_heart
||Developing plugins is a terrible experience, and I don't understand why many people still choose to do it||

cloud vapor
#

Godspeed! It definitely gets easier if you limit what you support based on what is easier that's for sure

sour plume
sterile rampart
sour plume
#

Thanks, I'll move my post there

frigid kestrel
#

Hi, can I remove or replace selected TagResolvers in the list if I have a duplicate but with different functionality? I'm trying to replace the selected TagResolvers in TagResolver.standard() to change the processing code, but if I specify them together, the processing is incorrect. I tried specifying all the standard TagResolvers manually, but I encountered a version difference: new format codes aren't processed, and I can't specify them in the old version of MiniMessage due to the core being tied to a specific version

fiery oracle
#

what tag resolvers are you replacing, specifically?

frigid kestrel
#

gradient and transition

sand drift
#

No, modifying them is unsupported, you would need to create your own tag resolver set

fiery oracle
#

The last specified resolver takes priority.

dawn pewter
#

woops did not intentionally trigger automod... sorry guys

#

does minimessage just not serialize closing tags if they are at the end of a string?

    private @NotNull String parse(String message, DiscordChatMessage discordChatMessage) {
        TagResolver.Single discordMessageHover = Placeholder.parsed("discord_notice", """
                <hover:show_text:'<gray>This message has been sent in the discord channel.
                <blue>Channel: <white>%s</white>
                Link: <white>%s</white></blue></gray>'><dark_gray>[<blue>D</blue>]</dark_gray></hover>"""
                .formatted(discordChatMessage.discordChannel(), "invite link"));

        Component temp = FormatUtils.getNoPrefixMiniMessage().deserialize(message, discordMessageHover);

        return FormatUtils.getNoPrefixMiniMessage().serialize(temp);
    }

This is what is returned by the instance:

<dark_gray><hover:show_text:'<gray>This message has been sent in the discord channel.
<blue>Channel: <white>allgemein</white>
Link: <white>invite link'>[<blue>D</blue>]
robust wharf
#

only in strict mode iirc

crude owl
#

Hi, I want to translate messages for players. But it's very difficult to support every language (that would take too much time). Therefore I am looking for a way to set the fallback language to english.
Example:

  • Player A has set his language to german: german is supported so the player gets a translated message
  • Player B has set the language to russian: but russian is not supported; the player gets a message in english (from the english resourcebundle)
    How can I do this? I already tried this:
public static boolean sendTranslatableMessage(Player player, String translationKey, Component... arguments) {
        Locale playerLocale = player.locale();
        Component translatedMessage = (Component) GlobalTranslator.translator().translate(translationKey, playerLocale);

        if (translatedMessage != null) {
            player.sendMessage(translatedMessage);
            return true;
        }

        Component translatedFallbackMessage = (Component) GlobalTranslator.translator().translate(translationKey, Locale.ENGLISH);

        if (translatedFallbackMessage == null) {
            return false;
        }

        player.sendMessage(translatedFallbackMessage);
        return true;
    }

But the problems is, that I cant involve arguments. I am happy about every idea :)

boreal orchid
crude owl
fiery oracle
#

generally, just look at the javadocs

crude owl
#

Yeah, sorry. Wait I thought I habe to create a translation store for every "language". Do I only have to create one for a plugin and add multiple resource bundles?

fiery oracle
#

you only have to create 1

#

when you register a resource bundle you specify the locale it's for

crude owl
hidden kiln
#

is there a way to make a tag resolver in minimessage that styles and appends something?

For example: <hp>2.5</hp> would show translate to what looks like <red>2.5</red> <glyph:heart>

sweet hornet
#

Is it strictly required for you to put the <glyph:heart> OUTSIDE of the <red>...</red> tag?

hidden kiln
#

it's not

sweet hornet
#

So it makes this easier- wait no nevermind it changes nothing. You can do it with a Modifying tag

sweet hornet
#

You don't need to test for the type of the component?

hidden kiln
#

True

sweet hornet
#

It's more like:

class StatTag implements Modifying {
  TextColor statColor = ...;
  Component statIcon = ...;

  @Override
  public Component apply(Component current, int depth) {
    if (depth != 0)
      return Component.empty(); // .apply() is called recursively with all children, but you only want to process the root to wrap it and append something

    // Here it depends if you want to overwrite possibly present child color and also color icon or not:
    return current.color(statColor).append(statIcon); // you might want to deep re-color children if you want to really overwrite the color
    // Otherwise, to leave the icon un-colored, and also not overwrite child color:
    // return Component.text()
    //   .append(current.colorIfAbsent(statColor))
    //   .append(statIcon)
    //   .build();
  }
}
#

Of course you need to adapt it to your exact context

#

But it's important to properly process (or not) children, because the Modifying tag has quite an odd default behavior (you can quickly duplicate them if not paying attention)

hidden kiln
#

Does custom font get processed inside of these? I'm placing the tag inside an item's lore, if that changes anything

sweet hornet
#

I don't know how your glyph/font works, but it looks like you're trying to give a minimessage-encoded string (<glyph:heart_icon>) to Component.text(...), which won't deserialize it. It looks like you need to use MiniMessage.miniMessage().deserialize(...) to turn your "<glyph:heart_icon>" to a Component

#

Except if your font renders the raw text <glyph:heart_icon> as the heart icon (but I doubt that, I think the glyph tag returns a special character that the font turns into the icon)

hidden kiln
#

This is elsewhere in my code. I'm using Nexo to generate my font files/resourcepack, and it does dynamic replacements like here