Skip to content

Commit 75835a3

Browse files
committed
Adjust to Mike's suggestions, add /chatformatter mentiontoggle command
1 parent e6d39f9 commit 75835a3

6 files changed

Lines changed: 195 additions & 22 deletions

File tree

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.eternalcode.formatter;
22

33
import com.eternalcode.formatter.config.ConfigManager;
4+
import com.eternalcode.formatter.mention.MentionPlayerSettings;
45
import com.google.common.base.Stopwatch;
56
import net.kyori.adventure.audience.Audience;
67
import net.kyori.adventure.platform.AudienceProvider;
@@ -14,59 +15,86 @@
1415
import org.jetbrains.annotations.NotNull;
1516
import org.jetbrains.annotations.Nullable;
1617

17-
import java.util.Collections;
18+
import java.util.ArrayList;
1819
import java.util.List;
1920
import java.util.concurrent.TimeUnit;
2021

2122
class ChatFormatterCommand implements CommandExecutor, TabCompleter {
2223

2324
private static final String RELOAD_MESSAGE = "<b><gradient:#29fbff:#38b3ff>ChatFormatter:</gradient></b> <green>Successfully reloaded configs in %sms!";
24-
public static final String RELOAD_PERMISSION = "chatformatter.reload";
25+
private static final String PLAYER_ONLY_MESSAGE = "<b><gradient:#29fbff:#38b3ff>ChatFormatter:</gradient></b> <red>Only players can use this command!";
26+
private static final String TOGGLED_MESSAGE = "<b><gradient:#29fbff:#38b3ff>ChatFormatter:</gradient></b> <green>Toggled mention sound";
27+
private static final String RELOAD_PERMISSION = "chatformatter.reload";
28+
private static final String MENTION_TOGGLE_PERMISSION = "chatformatter.mentiontoggle";
2529

2630
private final ConfigManager configManager;
2731
private final AudienceProvider provider;
2832
private final MiniMessage miniMessage;
33+
private final MentionPlayerSettings playerSettings;
2934

30-
ChatFormatterCommand(ConfigManager configManager, AudienceProvider provider, MiniMessage miniMessage) {
35+
36+
ChatFormatterCommand(ConfigManager configManager, AudienceProvider provider, MiniMessage miniMessage, MentionPlayerSettings playerSettings) {
3137
this.configManager = configManager;
3238
this.provider = provider;
3339
this.miniMessage = miniMessage;
40+
this.playerSettings = playerSettings;
3441
}
3542

3643
@Override
3744
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
38-
if (args.length == 0 || !args[0].equalsIgnoreCase("reload")) {
45+
if (args.length == 0) {
3946
sender.sendMessage(command.getUsage());
4047
return true;
4148
}
4249

43-
if (sender.hasPermission(RELOAD_PERMISSION)) {
50+
Audience audience = sender instanceof Player player
51+
? this.provider.player(player.getUniqueId())
52+
: this.provider.console();
53+
54+
// /chatformatter reload
55+
if (args[0].equalsIgnoreCase("reload") && sender.hasPermission(RELOAD_PERMISSION)) {
4456
Stopwatch stopwatch = Stopwatch.createStarted();
4557

4658
this.configManager.loadAndRenderConfigs();
4759
long millis = stopwatch.elapsed(TimeUnit.MILLISECONDS);
4860

4961
Component deserialized = this.miniMessage.deserialize(String.format(RELOAD_MESSAGE, millis));
50-
Audience audience = sender instanceof Player player
51-
? this.provider.player(player.getUniqueId())
52-
: this.provider.console();
5362

5463
audience.sendMessage(deserialized);
5564

5665
return true;
5766
}
5867

68+
// /chatformatter mentiontoggle
69+
if (args[0].equalsIgnoreCase("mentiontoggle")) {
70+
if (!(sender instanceof Player player)) {
71+
audience.sendMessage(this.miniMessage.deserialize(PLAYER_ONLY_MESSAGE));
72+
return true;
73+
}
74+
75+
if (sender.hasPermission(MENTION_TOGGLE_PERMISSION)) {
76+
boolean enabled = this.playerSettings.toggleMentionSound(player.getUniqueId());
77+
audience.sendMessage(this.miniMessage.deserialize(TOGGLED_MESSAGE + (enabled ? " <green>on." : " <red>off.")));
78+
return true;
79+
}
80+
}
81+
5982
return false;
6083
}
6184

6285

6386
@Nullable
6487
@Override
6588
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
66-
if (args.length == 1 && sender.hasPermission(RELOAD_PERMISSION)) {
67-
return List.of("reload");
89+
List<String> suggestions = new ArrayList<>();
90+
if (args.length == 1) {
91+
if (sender.hasPermission(RELOAD_PERMISSION)) {
92+
suggestions.add("reload");
93+
}
94+
if (sender.hasPermission(MENTION_TOGGLE_PERMISSION)) {
95+
suggestions.add("mentiontoggle");
96+
}
6897
}
69-
70-
return Collections.emptyList();
98+
return suggestions;
7199
}
72100
}

chatformatter-core/src/main/java/com/eternalcode/formatter/ChatFormatterPlugin.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
import com.eternalcode.formatter.config.ConfigManager;
44
import com.eternalcode.formatter.config.PluginConfig;
5-
import com.eternalcode.formatter.mention.MentionConfig;
65
import com.eternalcode.formatter.mention.MentionListener;
6+
import com.eternalcode.formatter.mention.MentionPlayerSettings;
77
import com.eternalcode.formatter.mention.MentionService;
8+
import com.eternalcode.formatter.mention.controller.MentionSuggestionsController;
89
import com.eternalcode.formatter.placeholder.ConfiguredReplacer;
910
import com.eternalcode.formatter.placeholder.PlaceholderRegistry;
1011
import com.eternalcode.formatter.placeholderapi.PlaceholderAPIInitializer;
@@ -55,14 +56,15 @@ public ChatFormatterPlugin(Plugin plugin) {
5556
new Metrics(plugin, 15199);
5657

5758
this.chatHandler = new ChatHandlerImpl(miniMessage, pluginConfig, this.rankProvider, this.placeholderRegistry, this.templateService);
59+
MentionPlayerSettings mentionPlayerSettings = new MentionPlayerSettings(plugin.getDataFolder(), plugin.getLogger(), configManager.getPluginConfig().mentions);
5860

59-
server.getPluginCommand("chatformatter").setExecutor(new ChatFormatterCommand(configManager, audienceProvider, miniMessage));
6061

61-
// Mentions
62-
this.mentionService = new MentionService(server, pluginConfig);
62+
server.getPluginCommand("chatformatter").setExecutor(new ChatFormatterCommand(configManager, audienceProvider, miniMessage, mentionPlayerSettings));
63+
64+
this.mentionService = new MentionService(server, pluginConfig, mentionPlayerSettings);
6365
server.getPluginManager().registerEvents(new MentionListener(mentionService), plugin);
66+
server.getPluginManager().registerEvents(new MentionSuggestionsController(), plugin);
6467

65-
// Update checker
6668
server.getPluginManager().registerEvents(new UpdaterController(updaterService, pluginConfig, audienceProvider, miniMessage), plugin);
6769

6870
ChatFormatterApiProvider.enable(this);

chatformatter-core/src/main/java/com/eternalcode/formatter/mention/MentionConfig.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ public class MentionConfig implements Serializable {
1212
@Description("# When a player mentions another player with @playername, the mentioned player will hear a sound")
1313
public boolean enabled = true;
1414

15+
@Description("# Whether the mention system requires the @ character before the player name")
16+
public boolean requireAtCharacter = false;
17+
18+
@Description("# Whether the mention system requires the full and exact player name to be mentioned")
19+
public boolean requireFullPlayerName = true;
20+
1521
@Description("# The sound to play when a player is mentioned")
1622
@Description("# Available sounds: https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/Sound.html")
1723
public String sound = "BLOCK_NOTE_BLOCK_PLING";
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package com.eternalcode.formatter.mention;
2+
3+
import org.bukkit.configuration.file.YamlConfiguration;
4+
5+
import java.io.File;
6+
import java.io.IOException;
7+
import java.util.HashMap;
8+
import java.util.Map;
9+
import java.util.UUID;
10+
import java.util.logging.Logger;
11+
12+
public class MentionPlayerSettings {
13+
14+
private final File dataFile;
15+
private final Logger logger;
16+
private final Map<UUID, Boolean> settings = new HashMap<>();
17+
private final MentionConfig config;
18+
19+
public MentionPlayerSettings(File dataFolder, Logger logger, MentionConfig config) {
20+
this.logger = logger;
21+
this.config = config;
22+
this.dataFile = new File(dataFolder, "mention-settings.yml");
23+
this.load();
24+
}
25+
26+
public boolean isMentionSoundEnabled(UUID uuid) {
27+
return this.settings.getOrDefault(uuid, this.config.enabled);
28+
}
29+
30+
public void setMentionSoundEnabled(UUID uuid, boolean enabled) {
31+
this.settings.put(uuid, enabled);
32+
this.save();
33+
}
34+
35+
public boolean toggleMentionSound(UUID uuid) {
36+
boolean current = this.isMentionSoundEnabled(uuid);
37+
this.setMentionSoundEnabled(uuid, !current);
38+
return !current;
39+
}
40+
41+
private void load() {
42+
if (!this.dataFile.exists()) {
43+
return;
44+
}
45+
46+
try {
47+
YamlConfiguration config = YamlConfiguration.loadConfiguration(this.dataFile);
48+
49+
for (String key : config.getKeys(false)) {
50+
try {
51+
UUID uuid = UUID.fromString(key);
52+
boolean enabled = config.getBoolean(key, this.config.enabled);
53+
this.settings.put(uuid, enabled);
54+
} catch (IllegalArgumentException e) {
55+
this.logger.warning("Invalid UUID in mention-settings.yml: " + key);
56+
}
57+
}
58+
} catch (Exception e) {
59+
this.logger.warning("Failed to load mention settings: " + e.getMessage());
60+
}
61+
}
62+
63+
private void save() {
64+
try {
65+
if (!this.dataFile.exists()) {
66+
this.dataFile.getParentFile().mkdirs();
67+
this.dataFile.createNewFile();
68+
}
69+
70+
YamlConfiguration config = new YamlConfiguration();
71+
72+
for (Map.Entry<UUID, Boolean> entry : this.settings.entrySet()) {
73+
config.set(entry.getKey().toString(), entry.getValue());
74+
}
75+
76+
config.save(this.dataFile);
77+
} catch (IOException e) {
78+
this.logger.warning("Failed to save mention settings: " + e.getMessage());
79+
}
80+
}
81+
}

chatformatter-core/src/main/java/com/eternalcode/formatter/mention/MentionService.java

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,27 @@
1212

1313
public class MentionService {
1414

15-
private static final Pattern MENTION_PATTERN = Pattern.compile("@([a-zA-Z0-9_]{3,16})");
15+
private static final Pattern MENTION_PATTERN = Pattern.compile("([a-zA-Z0-9_]{3,16})");
16+
private static final Pattern AT_MENTION_PATTERN = Pattern.compile("@([a-zA-Z0-9_]{3,16})");
1617

1718
private final Server server;
1819
private final PluginConfig config;
20+
private final MentionPlayerSettings playerSettings;
1921

20-
public MentionService(Server server, PluginConfig config) {
22+
public MentionService(Server server, PluginConfig config, MentionPlayerSettings playerSettings) {
2123
this.server = server;
2224
this.config = config;
25+
this.playerSettings = playerSettings;
2326
}
2427

2528
void mentionPlayers(String message) {
2629
List<Player> mentionedPlayers = this.detectMentions(message);
2730
Sound sound = loadSound();
2831

2932
for (Player player : mentionedPlayers) {
30-
player.playSound(player.getLocation(), sound, config.mentions.volume, config.mentions.pitch);
33+
if (this.playerSettings.isMentionSoundEnabled(player.getUniqueId())) {
34+
player.playSound(player.getLocation(), sound, config.mentions.volume, config.mentions.pitch);
35+
}
3136
}
3237
}
3338

@@ -37,11 +42,23 @@ private List<Player> detectMentions(String message) {
3742
}
3843

3944
List<Player> mentionedPlayers = new ArrayList<>();
40-
Matcher matcher = MENTION_PATTERN.matcher(message);
45+
46+
Matcher matcher;
47+
if (this.config.mentions.requireAtCharacter) {
48+
matcher = AT_MENTION_PATTERN.matcher(message);
49+
} else {
50+
matcher = MENTION_PATTERN.matcher(message);
51+
}
4152

4253
while (matcher.find()) {
4354
String playerName = matcher.group(1);
44-
Player player = this.server.getPlayer(playerName);
55+
Player player;
56+
57+
if (this.config.mentions.requireFullPlayerName) {
58+
player = server.getPlayerExact(playerName);
59+
} else {
60+
player = server.getPlayer(playerName);
61+
}
4562

4663
if (player != null && player.isOnline()) {
4764
mentionedPlayers.add(player);
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.eternalcode.formatter.mention.controller;
2+
3+
import org.bukkit.Bukkit;
4+
import org.bukkit.entity.Player;
5+
import org.bukkit.event.EventHandler;
6+
import org.bukkit.event.Listener;
7+
import org.bukkit.event.player.PlayerJoinEvent;
8+
import org.bukkit.event.player.PlayerQuitEvent;
9+
10+
import java.util.ArrayList;
11+
import java.util.Collection;
12+
import java.util.List;
13+
14+
public class MentionSuggestionsController implements Listener {
15+
16+
@EventHandler
17+
public void onPlayerJoin(PlayerJoinEvent event) {
18+
this.updateChatSuggestions();
19+
}
20+
21+
@EventHandler
22+
public void onPlayerQuit(PlayerQuitEvent event) {
23+
this.updateChatSuggestions();
24+
}
25+
26+
private void updateChatSuggestions() {
27+
Collection<? extends Player> allPlayers = Bukkit.getOnlinePlayers();
28+
List<String> completions = new ArrayList<>();
29+
30+
for (Player player : allPlayers) {
31+
String s = "@" + player.getName();
32+
completions.add(s);
33+
}
34+
35+
for (Player player : allPlayers) {
36+
player.setCustomChatCompletions(completions);
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)