Paper1.21.11Official#sohbet#moderasyon#rütbe

Sohbet Yöneticisi

Rütbeye göre sohbet biçimi ve önek, küfür filtresi, büyük harf koruması, sohbet bekleme süresi, /mutechat ve /chatclear.

MinborAIminborai 4 0 0 1
Tüm hakları saklıdırUse on serverModifyCommercial· Attribution
src/main/java/com/minborai/sohbetyoneticisi/SohbetYoneticisi.java
1package com.minborai.sohbetyoneticisi;
2
3import io.papermc.paper.event.player.AsyncChatEvent;
4import net.kyori.adventure.text.Component;
5import net.kyori.adventure.text.TextReplacementConfig;
6import net.kyori.adventure.text.minimessage.MiniMessage;
7import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
8import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
9import org.bukkit.Bukkit;
10import org.bukkit.command.Command;
11import org.bukkit.command.CommandSender;
12import org.bukkit.configuration.ConfigurationSection;
13import org.bukkit.entity.Player;
14import org.bukkit.event.EventHandler;
15import org.bukkit.event.EventPriority;
16import org.bukkit.event.Listener;
17import org.bukkit.event.player.PlayerQuitEvent;
18import org.bukkit.plugin.java.JavaPlugin;
19
20import java.util.List;
21import java.util.Locale;
22import java.util.Map;
23import java.util.UUID;
24import java.util.concurrent.ConcurrentHashMap;
25import java.util.regex.Pattern;
26
27public final class SohbetYoneticisi extends JavaPlugin implements Listener {
28
29 private static final MiniMessage MM = MiniMessage.miniMessage();
30
31 private final Map<UUID, Long> lastMessage = new ConcurrentHashMap<>();
32 private volatile boolean muted = false;
33 private volatile Pattern badWords;
34
35 @Override
36 public void onEnable() {
37 saveDefaultConfig();
38 compileFilter();
39 getServer().getPluginManager().registerEvents(this, this);
40 }
41
42 private void compileFilter() {
43 List<String> words = getConfig().getStringList("filter.words");
44 if (words.isEmpty()) {
45 badWords = null;
46 return;
47 }
48 StringBuilder sb = new StringBuilder();
49 for (String w : words) {
50 if (w.isBlank()) continue;
51 if (sb.length() > 0) sb.append('|');
52 sb.append(Pattern.quote(w.toLowerCase(Locale.ROOT)));
53 }
54 badWords = sb.length() == 0 ? null : Pattern.compile(sb.toString(), Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
55 }
56
57 private Component msg(String key) {
58 return MM.deserialize(getConfig().getString("messages.prefix", "") + getConfig().getString("messages." + key, key));
59 }
60
61 /** İzne göre en öncelikli rütbe öneki (config'deki sıra = öncelik) */
62 private String prefixOf(Player player) {
63 ConfigurationSection groups = getConfig().getConfigurationSection("groups");
64 if (groups == null) return "";
65 for (String key : groups.getKeys(false)) {
66 String perm = groups.getString(key + ".permission", "");
67 if (perm.isEmpty() || player.hasPermission(perm)) return groups.getString(key + ".prefix", "");
68 }
69 return "";
70 }
71
72 @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
73 public void onChat(AsyncChatEvent event) {
74 Player player = event.getPlayer();
75 boolean bypass = player.hasPermission("chatmanager.bypass");
76
77 if (muted && !bypass) {
78 event.setCancelled(true);
79 player.sendMessage(msg("muted"));
80 return;
81 }
82 long cooldown = getConfig().getLong("cooldown-ms", 1500);
83 long now = System.currentTimeMillis();
84 Long last = lastMessage.get(player.getUniqueId());
85 if (!bypass && last != null && now - last < cooldown) {
86 event.setCancelled(true);
87 player.sendMessage(msg("slow-down"));
88 return;
89 }
90 lastMessage.put(player.getUniqueId(), now);
91
92 Component message = event.message();
93 String plain = PlainTextComponentSerializer.plainText().serialize(message);
94 // Büyük harf koruması: harflerin çoğu büyükse küçük harfe çevir
95 int letters = 0;
96 int upper = 0;
97 for (char c : plain.toCharArray()) {
98 if (Character.isLetter(c)) {
99 letters++;
100 if (Character.isUpperCase(c)) upper++;
101 }
102 }
103 if (!bypass && letters >= getConfig().getInt("caps.min-length", 6) && upper * 100 >= letters * getConfig().getInt("caps.percent", 70)) {
104 message = Component.text(plain.toLowerCase(new Locale("tr", "TR")));
105 }
106 Pattern filter = badWords;
107 if (filter != null && !bypass) {
108 String mask = getConfig().getString("filter.replacement", "***");
109 message = message.replaceText(TextReplacementConfig.builder().match(filter).replacement(mask).build());
110 }
111 event.message(message);
112
113 String format = getConfig().getString("format", "<prefix><player> <dark_gray>»</dark_gray> <message>");
114 String prefix = prefixOf(player);
115 event.renderer((source, displayName, msgComponent, viewer) -> MM.deserialize(format,
116 Placeholder.parsed("prefix", prefix),
117 Placeholder.component("player", displayName),
118 Placeholder.component("message", msgComponent)));
119 }
120
121 @EventHandler
122 public void onQuit(PlayerQuitEvent event) {
123 lastMessage.remove(event.getPlayer().getUniqueId());
124 }
125
126 @Override
127 public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
128 switch (command.getName()) {
129 case "chatclear" -> {
130 for (Player p : Bukkit.getOnlinePlayers()) {
131 if (p.hasPermission("chatmanager.bypass")) continue;
132 for (int i = 0; i < 100; i++) p.sendMessage(Component.empty());
133 }
134 Bukkit.broadcast(msg("cleared"));
135 }
136 case "mutechat" -> {
137 muted = !muted;
138 Bukkit.broadcast(msg(muted ? "mute-on" : "mute-off"));
139 }
140 case "chatreload" -> {
141 reloadConfig();
142 compileFilter();
143 sender.sendMessage(msg("reloaded"));
144 }
145 default -> {
146 return false;
147 }
148 }
149 return true;
150 }
151}
152