[SPIGOT-839] Error when using .setFormat() with chat message that contains percent symbol '%' Created: 26/Apr/15  Updated: 06/May/15  Resolved: 06/May/15

Status: Closed
Project: Spigot
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Dominik Assignee: Unassigned
Resolution: Invalid Votes: 0
Labels: chat, error, event
Environment:

Occurred on both Windows and on Linux, doesn't seem to be important


Plugin: own plugin

 Description   

Steps how to reproduce:

1. Create plugin that changes chat formatting with the following code:

Listener.java
	@EventHandler(priority = EventPriority.NORMAL)
	public void playerChatFormatting(AsyncPlayerChatEvent e)
	{
		e.setFormat(ChatColor.GRAY + e.getPlayer().getName() + ChatColor.WHITE + ": " + e.getMessage());
	}

2. Client sends chat message containing percent char, like "I am 100% sure"

3. Event causes error:

[14:24:22] Async Chat Thread - #0/ERROR: Could not pass event AsyncPlayerChatEvent to ******************** v1.0
org.bukkit.event.EventException
at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:305) ~[spigot-1.8.3.jar:git-Spigot-2ec6f06-7722428]
at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62) ~[spigot-1.8.3.jar:git-Spigot-2ec6f06-7722428]
at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:502) [spigot-1.8.3.jar:git-Spigot-2ec6f06-7722428]
at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:484) [spigot-1.8.3.jar:git-Spigot-2ec6f06-7722428]
at net.minecraft.server.v1_8_R2.PlayerConnection.chat(PlayerConnection.java:1061) [spigot-1.8.3.jar:git-Spigot-2ec6f06-7722428]
at net.minecraft.server.v1_8_R2.PlayerConnection.a(PlayerConnection.java:999) [spigot-1.8.3.jar:git-Spigot-2ec6f06-7722428]
at net.minecraft.server.v1_8_R2.PacketPlayInChat$1.run(PacketPlayInChat.java:39) [spigot-1.8.3.jar:git-Spigot-2ec6f06-7722428]
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.7.0_71]
at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.7.0_71]
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [?:1.7.0_71]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [?:1.7.0_71]
at java.lang.Thread.run(Unknown Source) [?:1.7.0_71]
Caused by: java.util.FormatFlagsConversionMismatchException: Conversion = s, Flags =
at org.bukkit.event.player.AsyncPlayerChatEvent.setFormat(AsyncPlayerChatEvent.java:100) ~[spigot-1.8.3.jar:git-Spigot-2ec6f06-7722428]
at listener.MainListener.playerChatFormatting(MainListener.java:51) ~[?:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_71]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_71]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_71]
at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.7.0_71]
at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:301) ~[spigot-1.8.3.jar:git-Spigot-2ec6f06-7722428]
... 11 more

Somewhere I read this is due to '%' being an escape character, maybe that helps.



 Comments   
Comment by Jikoo [ 01/May/15 ]

Yes, %2$s will be replaced by the message from getMessage when the event is completed.

At the most basic level, you could

event.setFormat("%s: %s");

This would result in a message that looks like Name: message
However, you want the user's display name, not their name. Because you do not want the first String at all, you must specify that the second is the one you want inserted:

event.setFormat(player.getDisplayName() + ": %2$s");

The only "bug" is that you did not read the event's documentation properly.

public void setFormat(String format) throws IllegalFormatException, NullPointerException

Sets the format to use to display this chat message.

When this event finishes execution, the first format parameter is the Player.getDisplayName() and the second parameter is getMessage()

Parameters:
format - String.format(String, Object...) compatible format string

Comment by Dominik [ 30/Apr/15 ]

@Jikoo If I am not supposed to use setFormat(), how would I do it? Or did you mean I shouldn't use getMessage() and use the "%2$s" instead? If this is the case, this method I used would still work if Spigot was bugfree.

Comment by Jikoo [ 30/Apr/15 ]

Actually, Jannik8500's solution is correct.

The message should not be inserted into the format using setFormat. "%2$s" will be replaced by the message when the event runs to completion.

See http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html

Comment by Paxination [ 27/Apr/15 ]

"Client sends chat message containing percent char, like "I am 100% sure""

That wouldnt fix his issue. He's trying to format the chat. And it already contains the % character. Not add it in.

Comment by Jannik8500 [ 27/Apr/15 ]

Use: e.setFormat(ChatColor.GRAY + e.getPlayer().getName() + ChatColor.WHITE + ": " + "%2$s");

Generated at Fri Mar 14 14:36:09 UTC 2025 using Jira 10.3.3#10030003-sha1:d220e3fefc8dfc6d47f522d3b9a20c1455e12b7b.