Skip to content

Commit 4d47a75

Browse files
committed
added config option to enable chat format
1 parent f737b0e commit 4d47a75

File tree

4 files changed

+105
-0
lines changed

4 files changed

+105
-0
lines changed

.run/Package.run.xml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="Package" type="MavenRunConfiguration" factoryName="Maven">
3+
<MavenSettings>
4+
<option name="myGeneralSettings" />
5+
<option name="myRunnerSettings" />
6+
<option name="myRunnerParameters">
7+
<MavenRunnerParameters>
8+
<option name="cmdOptions" />
9+
<option name="profiles">
10+
<set />
11+
</option>
12+
<option name="goals">
13+
<list>
14+
<option value="package" />
15+
</list>
16+
</option>
17+
<option name="multimoduleDir" />
18+
<option name="pomFileName" />
19+
<option name="profilesMap">
20+
<map />
21+
</option>
22+
<option name="projectsCmdOptionValues">
23+
<list />
24+
</option>
25+
<option name="resolveToWorkspace" value="false" />
26+
<option name="workingDirPath" value="$PROJECT_DIR$" />
27+
</MavenRunnerParameters>
28+
</option>
29+
</MavenSettings>
30+
<method v="2" />
31+
</configuration>
32+
</component>

src/main/java/pro/cloudnode/smp/cloudnodemsg/PluginConfig.java

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,26 @@
11
package pro.cloudnode.smp.cloudnodemsg;
22

3+
import io.papermc.paper.chat.ChatRenderer;
4+
import me.clip.placeholderapi.PlaceholderAPI;
5+
import net.kyori.adventure.audience.Audience;
6+
import net.kyori.adventure.key.Key;
37
import net.kyori.adventure.text.Component;
8+
import net.kyori.adventure.text.event.ClickEvent;
9+
import net.kyori.adventure.text.event.HoverEvent;
10+
import net.kyori.adventure.text.format.TextColor;
411
import net.kyori.adventure.text.minimessage.MiniMessage;
12+
import net.kyori.adventure.text.minimessage.tag.Tag;
513
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
14+
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
15+
import org.bukkit.OfflinePlayer;
616
import org.bukkit.configuration.file.FileConfiguration;
17+
import org.bukkit.entity.Player;
718
import org.bukkit.scoreboard.Team;
819
import org.jetbrains.annotations.NotNull;
20+
import org.jetbrains.annotations.Nullable;
921

1022
import java.util.Objects;
23+
import java.util.Optional;
1124

1225
public final class PluginConfig {
1326
public @NotNull FileConfiguration config;
@@ -305,6 +318,44 @@ public PluginConfig(final @NotNull FileConfiguration config) {
305318
);
306319
}
307320

321+
/**
322+
* Chat format
323+
*/
324+
public @NotNull Optional<@NotNull ChatRenderer> chatFormat() {
325+
final @Nullable String str = config.getString("chat-format");
326+
if (str == null || str.equals("null") || str.isBlank())
327+
return Optional.empty();
328+
return Optional.of((source, sourceDisplayName, message, viewer) -> MiniMessage.miniMessage().deserialize(
329+
str,
330+
Placeholder.component("message", message),
331+
TagResolver.resolver("papi", (args, ctx) -> {
332+
String placeholder = args.popOr("placeholder expected").value().trim();
333+
if (!placeholder.startsWith("%") && !placeholder.endsWith("%"))
334+
placeholder = "%" + placeholder + "%";
335+
if (!CloudnodeMSG.getInstance().getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
336+
CloudnodeMSG.getInstance().getLogger().severe("Attempted to use PlaceholderAPI placeholder `" + placeholder
337+
+ "` in chat format, but PlaceholderAPI is not present!");
338+
return Tag.inserting(Component.text(PlaceholderAPI.setPlaceholders(source, placeholder)));
339+
}),
340+
TagResolver.resolver("has-team", (args, ctx) -> {
341+
final String text = args.popOr("text expected").value();
342+
final Team team = source.getScoreboard().getPlayerTeam(source);
343+
if (team == null) {
344+
if (args.hasNext())
345+
return Tag.inserting(MiniMessage.miniMessage().deserialize(args.popOr("expected fallback value").value()));
346+
else return Tag.inserting(Component.empty());
347+
}
348+
return Tag.inserting(ctx.deserialize(text,
349+
Placeholder.component("team", team.displayName())
350+
));
351+
}),
352+
TagResolver.resolver("player", (args, ctx) -> Tag.inserting(
353+
Component.text(source.getName())
354+
.clickEvent(ClickEvent.suggestCommand("/tell " + source.getName() + " "))
355+
))
356+
));
357+
}
358+
308359
/**
309360
* No permission
310361
*/

src/main/java/pro/cloudnode/smp/cloudnodemsg/listener/AsyncChatListener.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package pro.cloudnode.smp.cloudnodemsg.listener;
22

3+
import io.papermc.paper.chat.ChatRenderer;
34
import io.papermc.paper.event.player.AsyncChatEvent;
45
import net.kyori.adventure.audience.Audience;
6+
import net.kyori.adventure.text.Component;
57
import org.bukkit.OfflinePlayer;
68
import org.bukkit.Server;
79
import org.bukkit.entity.Player;
@@ -68,4 +70,10 @@ public void teamChannel(final @NotNull AsyncChatEvent event) {
6870
}
6971
TeamMessageCommand.sendTeamMessage(sender, team.get(), event.message());
7072
}
73+
74+
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
75+
public void chatFormat(final @NotNull AsyncChatEvent event) {
76+
final @NotNull Optional<@NotNull ChatRenderer> format = CloudnodeMSG.getInstance().config().chatFormat();
77+
format.ifPresent(event::renderer);
78+
}
7179
}

src/main/resources/config.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,20 @@ toggle:
8888
# <player> - the player's username
8989
other: "<green>(!) Re-enabled receiving of private messages for <gray><player></gray>.</green>"
9090

91+
# Set custom global/public chat format. Disabled by default.
92+
#
93+
# Placeholders:
94+
# <has-team:'if yes':'if no'> - show a different message based on whether the player is in a team
95+
# <team> - the player's team display name (only works in <has-team>)
96+
# <player> - the name of the player, when clicked suggests command `/tell` followed by the player's name
97+
# <message> - the message being sent in chat
98+
# <papi:…> - use a PlaceholderAPI placeholder, example `<papi:%player_displayname%>` or `<papi:player_displayname>`.
99+
# Requires PlaceholderAPI to be installed.
100+
#
101+
# Example:
102+
#chat-format: <has-team:'<dark_gray>[<white><team></white>]</dark_gray> '><white><player></white><dark_gray>:</dark_gray> <gray><message></gray>
103+
chat-format: null
104+
91105
# Error messages
92106
errors:
93107
# No permission

0 commit comments

Comments
 (0)