Search and replace in a text object?

Is there a way to search and replace in a text object. I have been looking around the API for a while and can not find any possible way I can accomplish this.

Here is an example detailing what I am trying to do:

I have a text object that was created by something along the lines of this:
Text text = Texts.of(TextColors.YELLOW,"%name%",TextColors.GRAY," has joined!");

I want to replace any instance of %name% with another String. Does anyone know how I could do this?

Wgy not replace %name% before adding it to the text object?

I found Texts extremly painful to work with, its quite pointless wrapper class. Use Text objects only if the api requires it. (not kidding)

Elaborations on why you find it a pain, and what you think may be better could potentially make it into a useful wrapper. (Sorry to go off-topic)

Not everyone needs that kind of high level abstraction, and the bad thing is that the api is forcing me to use Texts even on places where its not needed.

  1. Whats the point of using a wrapperclass when the forge and minecraft work with strings, apis should be kept simple.
  2. No easy way how to parse contained String objects. lastIndexOf/split/charAt/replace(All)/regexpsā€¦ equivalents?
  3. When trying to access string inside the Text object why do i have to use Texts.toPlain static method. One would excepted a non static method .toPlain in a Text class.
  4. Stringā€™s hashcode is cached for a good reason.
  5. 75% of all messages you want to send to players are just plain (no click/hover actions) But why there is no overloaded method in a commandsender interface? String hello=ā€œHelloā€; player.sendMessage(Texts.of(hello)); <= Is this ugly code really neccessary?
  6. Even if i can somehow understand that Text class should some kind of builder, which generates a json for all chat action events (on hover, on click) But why are item lore and sign data represented as Text as well? They are just list of strings, not json objects.
  7. Text.toText(){return this} <- seems like bad code design.
1 Like

I find new TextBuilder("asdf").color('green') (or something like that) a lot better than ChatColor.GREEN + "asdf"

Why? ā€œ+ā€ operator is overloaded in java just for that. You dont really need some ā€œtext builderā€ for joining two strings, only sponge is making you to think you do.

It is for an API, and is a configurable value. The user has the ability to style the message however they want. Unfortunately, I donā€™t believe that your suggestion will work.

I fully agree. I had to make an uncolor function to allow %message to be replaced by a chat message (which had to be converted to a string anyways) multiple times. I personally only use Texts.of(); as all the other syntax requires about 150 characters to create a text containing 4 colors.

Donā€™t get me wrong but I really donā€™t see the point of making it that complicated. By allowing custom color codes to be replaced without using Texts.legacy(); you would make the entire thing a lot more transparent. Mixing standalone ChatColors with strings hasnā€™t hurt anyone ever. :wink:

Iā€™ll just leave this here:

and this:

(So yes, the TextAPI will see some improvements in the future :wink: )

2 Likes

No offece but it wont change anything.

  • Text templates

      private final TextTemplate template = TextTemplate.of(
      "Hello ", TextElement.playerDisplayName().pos(0),
      ", a message was just sent to you: ", 
      TextElement.identity().pos(1));
    

    public Text transformMessage(CommandSource target, Text text) {
    return template.build(TextArgs.of(target, text));
    }
    vs

     final String msg = "Hello %1 " ...       
     and then somewhere 
     String = msg.replaceAll("%1", "bob");
    

I guess its clear who is the winner.

ā€œImprove Text Api prā€

    Text MAIN_MESSAGE = Texts.placeholder(input -> MessageContainer.get("MAIN_MESSAGE", ((Player) input.apply("0")).getLocale()));
// Text MAIN_MESSAGE = Texts.placeholder(new MultilanguageFunction("MAIN_MESSAGE"));
// Text MAIN_MESSAGE = MyMsgTools.msg("MAIN_MESSAGE");
Text RANKING_MESSAGE = Texts.placeholder(input -> Texts.format(MessageContainer.get("RANKING_MESSAGE", ((Player) input.apply("0")).getLocale(), input)));
// Text RANKING_MESSAGE = Texts.placeholder(new FormattedMultilanguageFunction("RANKING_MESSAGE"));
// Text RANKING_MESSAGE = MyMsgTools.formattedMsg("RANKING_MESSAGE");

for (Player player : participants) {
    player.sendMessage(Texts.format(MAIN_MESSAGE, player));
    int index = 1;
    for (Player ranked : topRanked) {
        player.sendMessage(Texts.format(RANKING_MESSAGE, player, index++, ranked));
    }
}

The author called this fancy way. Anyone cares to explain me whats exactly fancy? I think im either blind or just dumb.

Why not adding both? As I see it we just ask for:

player.sendMessage(TextColors.RED + "Hello");

Same goes for broadcasting and all that stuff :yum:

Well, my intention was to show you that there is work done on texts. If this isnā€™t like you want to have it done, then why not make suggestions/comment on said PRs to improve it even further? Sponge is somewhat community driven so if thereā€™s a good reason and way things can be improved, why not suggest it there? There are chances youā€™re heard :wink:

However not every dev reads all topics on the forumsā€¦

You could ask/suggest on IRC in #spongedev too.

EDIT: You could even ask on SoS VI this evening :smile:

1 Like

We are aware of the issues with the TextAPI so your criticisms are valid. Your assumption that this is the way its going to be is foolish as weā€™ve already established a history of ā€œtearing down the fortā€ to fix something. One of the problems here is the ā€œColor Codesā€ youā€™ve come to rely upon will be eventually removed in the base game, that we are 100% certain of (though no ETA on that so donā€™t ask) as weā€™ve asked Mojang directly.

As for this whole debacle of dealing with Strings and suchā€¦As it stands, you donā€™t send the Minecraft client Strings (well almost, there are still a few places leftā€¦), you send it Json blobs. The Text API is a wrapper around constructing a JSON blob for you so unless you like doing that yourself, its already made that simple. Just because youā€™ve been able to send Strings willy-nilly in the past doesnā€™t mean its still that way. Things have changed.

Now, if you wanted for that ability to be preservedā€¦as in being able to join them together then that can be accommodated (even-though Texts.of() is pretty simple in itself). I just need for you to be aware that you are not correct that Minecraft and Forge ā€œJust work with Stringsā€. They donā€™t, they work with IChatComponents which can convert Strings (but isnā€™t guaranteed). Which makes doing the following awkward and volatile:

player.sendMessage(TextColors.RED + "Hello");

That out of the way, its on the TODO list and a team member (or contributor) will get to it when time permits.

4 Likes

Also to address a few points:

3) When trying to access string inside the Text object why do i have to 
use Texts.toPlain static method. One would excepted a non static method 
.toPlain in a Text class.

Will address this.

5) 75% of all messages you want to send to players are just plain (no 
click/hover actions) But why there is no overloaded method in a commandsender interface? String hello="Hello"; player.sendMessage(Texts.of(hello)); <= Is this ugly code really neccessary?

Could you provide where you got that percentage from? Otherwise, I agree (not with the percentage) and will be addressed.

6) Even if i can somehow understand that Text class should some kind of 
builder, which generates a json for all chat action events (on hover, on
 click) But why are item lore and sign data represented as Text as well?
 They are just list of strings, not json objects.

Actually, they are:

Signs can be created with JSON text which allows complex formatting (colors, bold, italic, etc.), hover and click events, localized translation (for Minecraft
technical terms, like ā€œRedstone Repeaterā€, otherwise translations must
be provided in language files in resource packs), and the incorporation
of scoreboard values into text. Use the /setblock command to create JSON signs and the /blockdata command to alter JSON signs.

Source: http://minecraft.gamepedia.com/Sign

Surely you donā€™t want us to cast out what map makers do.

ItemLore:

Iā€™ve easily been able to add colors to the text in Lore. Mods do too.

3 Likes

Do you have a clearer example of how this API is suppose to work? Iā€™m still not understanding how working with a String object before the text object wouldnā€™t work.

@Flibio @TrenTech

You first have to get the raw string out of the message which you can do by using:

String s = Texts.toPlain(yourtext);

Then youā€™ll be able to replace %name% and other placeholders by using the regular String functions. After that you got to build the new Text element. If you want to color &-codes you can use

Text t = Texts.legacy('&').from(s);

to convert it back to a colored Text. Of course you can also use:

Text t = Texts.of(TextColors.GREEN, s);

To change a joinmessage your final code would look somewhat like this:

String s = "&a%name% &fhas joined the game!";
s = s.replaceAll("%name%", player.getName());
Text t = Texts.legacy('&').from(s);

event.setMessage(t);

@TrenTech
This Text text = Texts.of(TextColors.YELLOW,"%name%",TextColors.GRAY," has joined!"); is a variable that can be set by the user of the API. My plugin will replace any instance of %name% with a String.

@CreepsterLGC
Thanks for the response, but I am need it to retain its original color set in the variable. I donā€™t believe that your approach will do this. I donā€™t want to have to use color codes because as many people have said, they will eventually be phased out of Minecraft.

What exactly is the purpose of this API? Can we see this project. Iā€™m getting the impression that your approach is making things more difficult than they need to be, no offense.

You can also replace the String by just grabbing one defined in a config file or something like thatā€¦ :yum:

Also, the function is currently deprecated and not removed as this is currently the only real way to transform those color codes.