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.
Tüm hakları saklıdırUse on serverModifyCommercial· Attribution
src/main/java/com/minborai/sohbetyoneticisi/SohbetYoneticisi.java
1package com.minborai.sohbetyoneticisi;23import 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;1920import 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;2627public final class SohbetYoneticisi extends JavaPlugin implements Listener {2829private static final MiniMessage MM = MiniMessage.miniMessage();3031private final Map<UUID, Long> lastMessage = new ConcurrentHashMap<>();32private volatile boolean muted = false;33private volatile Pattern badWords;3435@Override36public void onEnable() {37saveDefaultConfig();38compileFilter();39getServer().getPluginManager().registerEvents(this, this);40}4142private void compileFilter() {43List<String> words = getConfig().getStringList("filter.words");44if (words.isEmpty()) {45badWords = null;46return;47}48StringBuilder sb = new StringBuilder();49for (String w : words) {50if (w.isBlank()) continue;51if (sb.length() > 0) sb.append('|');52sb.append(Pattern.quote(w.toLowerCase(Locale.ROOT)));53}54badWords = sb.length() == 0 ? null : Pattern.compile(sb.toString(), Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);55}5657private Component msg(String key) {58return MM.deserialize(getConfig().getString("messages.prefix", "") + getConfig().getString("messages." + key, key));59}6061/** İzne göre en öncelikli rütbe öneki (config'deki sıra = öncelik) */62private String prefixOf(Player player) {63ConfigurationSection groups = getConfig().getConfigurationSection("groups");64if (groups == null) return "";65for (String key : groups.getKeys(false)) {66String perm = groups.getString(key + ".permission", "");67if (perm.isEmpty() || player.hasPermission(perm)) return groups.getString(key + ".prefix", "");68}69return "";70}7172@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)73public void onChat(AsyncChatEvent event) {74Player player = event.getPlayer();75boolean bypass = player.hasPermission("chatmanager.bypass");7677if (muted && !bypass) {78event.setCancelled(true);79player.sendMessage(msg("muted"));80return;81}82long cooldown = getConfig().getLong("cooldown-ms", 1500);83long now = System.currentTimeMillis();84Long last = lastMessage.get(player.getUniqueId());85if (!bypass && last != null && now - last < cooldown) {86event.setCancelled(true);87player.sendMessage(msg("slow-down"));88return;89}90lastMessage.put(player.getUniqueId(), now);9192Component message = event.message();93String plain = PlainTextComponentSerializer.plainText().serialize(message);94// Büyük harf koruması: harflerin çoğu büyükse küçük harfe çevir95int letters = 0;96int upper = 0;97for (char c : plain.toCharArray()) {98if (Character.isLetter(c)) {99letters++;100if (Character.isUpperCase(c)) upper++;101}102}103if (!bypass && letters >= getConfig().getInt("caps.min-length", 6) && upper * 100 >= letters * getConfig().getInt("caps.percent", 70)) {104message = Component.text(plain.toLowerCase(new Locale("tr", "TR")));105}106Pattern filter = badWords;107if (filter != null && !bypass) {108String mask = getConfig().getString("filter.replacement", "***");109message = message.replaceText(TextReplacementConfig.builder().match(filter).replacement(mask).build());110}111event.message(message);112113String format = getConfig().getString("format", "<prefix><player> <dark_gray>»</dark_gray> <message>");114String prefix = prefixOf(player);115event.renderer((source, displayName, msgComponent, viewer) -> MM.deserialize(format,116Placeholder.parsed("prefix", prefix),117Placeholder.component("player", displayName),118Placeholder.component("message", msgComponent)));119}120121@EventHandler122public void onQuit(PlayerQuitEvent event) {123lastMessage.remove(event.getPlayer().getUniqueId());124}125126@Override127public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {128switch (command.getName()) {129case "chatclear" -> {130for (Player p : Bukkit.getOnlinePlayers()) {131if (p.hasPermission("chatmanager.bypass")) continue;132for (int i = 0; i < 100; i++) p.sendMessage(Component.empty());133}134Bukkit.broadcast(msg("cleared"));135}136case "mutechat" -> {137muted = !muted;138Bukkit.broadcast(msg(muted ? "mute-on" : "mute-off"));139}140case "chatreload" -> {141reloadConfig();142compileFilter();143sender.sendMessage(msg("reloaded"));144}145default -> {146return false;147}148}149return true;150}151}152