config command
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
package io.github.itzispyder.ogredupealias;
|
||||
|
||||
import io.github.itzispyder.ogredupealias.commands.commands.ConfigCommand;
|
||||
import io.github.itzispyder.ogredupealias.commands.commands.MuteChatCommand;
|
||||
import io.github.itzispyder.ogredupealias.commands.commands.StaffChatCommand;
|
||||
import io.github.itzispyder.ogredupealias.data.Config;
|
||||
import io.github.itzispyder.ogredupealias.events.ChatEventListener;
|
||||
import io.github.itzispyder.ogredupealias.events.PlayerEventListener;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
@@ -31,10 +35,16 @@ public final class OgreDupeAlias extends JavaPlugin {
|
||||
|
||||
public void init() {
|
||||
// Events
|
||||
pm.registerEvents(new ChatEventListener(),this);
|
||||
pm.registerEvents(new PlayerEventListener(),this);
|
||||
|
||||
// Commands
|
||||
getCommand("config").setExecutor(new ConfigCommand());
|
||||
getCommand("config").setTabCompleter(new ConfigCommand());
|
||||
getCommand("mutechat").setExecutor(new MuteChatCommand());
|
||||
getCommand("mutechat").setTabCompleter(new MuteChatCommand());
|
||||
getCommand("staffchat").setExecutor(new StaffChatCommand());
|
||||
getCommand("staffchat").setTabCompleter(new StaffChatCommand());
|
||||
}
|
||||
|
||||
public void initConfig() {
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package io.github.itzispyder.ogredupealias.commands.commands;
|
||||
|
||||
import io.github.itzispyder.ogredupealias.commands.CmdExHandler;
|
||||
import io.github.itzispyder.ogredupealias.commands.TabComplBuilder;
|
||||
import io.github.itzispyder.ogredupealias.utils.ChatConstraints;
|
||||
import io.github.itzispyder.ogredupealias.utils.Text;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MuteChatCommand implements TabExecutor {
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
try {
|
||||
if (args.length == 0) ChatConstraints.setChatMuted(!ChatConstraints.isChatMuted());
|
||||
else ChatConstraints.setChatMuted(Boolean.parseBoolean(args[0]));
|
||||
|
||||
boolean muted = ChatConstraints.isChatMuted();
|
||||
sender.sendMessage(Text.builder("&3Chat is now " + (muted ? "&cmuted" : "&aunmuted") + "&3!")
|
||||
.prefix()
|
||||
.color()
|
||||
.build());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
CmdExHandler handler = new CmdExHandler(ex,command);
|
||||
sender.sendMessage(handler.getHelp());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||
return new TabComplBuilder(sender, command, alias, args)
|
||||
.add(1, new String[] {
|
||||
"true",
|
||||
"false"
|
||||
})
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package io.github.itzispyder.ogredupealias.commands.commands;
|
||||
|
||||
import io.github.itzispyder.ogredupealias.commands.CmdExHandler;
|
||||
import io.github.itzispyder.ogredupealias.commands.TabComplBuilder;
|
||||
import io.github.itzispyder.ogredupealias.utils.ArrayUtils;
|
||||
import io.github.itzispyder.ogredupealias.utils.ServerUtils;
|
||||
import io.github.itzispyder.ogredupealias.utils.Text;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class StaffChatCommand implements TabExecutor {
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
try {
|
||||
String msg = String.join(" ", args);
|
||||
ServerUtils.dmEachPlayer(p -> p.hasPermission("oda.commands.staffchat"), Text.builder()
|
||||
.message("&7[&bStaffChat&7] &8>> &e" + msg)
|
||||
.color()
|
||||
.prefix()
|
||||
.build());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
CmdExHandler handler = new CmdExHandler(ex,command);
|
||||
sender.sendMessage(handler.getHelp());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||
return new TabComplBuilder(sender, command, alias, args)
|
||||
.add(1, ArrayUtils.toNewList(Bukkit.getOnlinePlayers(), Player::getName))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package io.github.itzispyder.ogredupealias.data;
|
||||
|
||||
import io.github.itzispyder.ogredupealias.OgreDupeAlias;
|
||||
import io.github.itzispyder.ogredupealias.utils.Text;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
@@ -90,6 +92,9 @@ public abstract class Config {
|
||||
|
||||
public static class Player {
|
||||
private static final String path = "player.";
|
||||
public static String firstJoinMessage() {
|
||||
return Text.color(get().getString(path + "first-join-message","&e%player% has joined the game for their first time!"));
|
||||
}
|
||||
public static String joinMessage() {
|
||||
return Text.color(get().getString(path + "join-message","&e%player% has joined the game"));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package io.github.itzispyder.ogredupealias.events;
|
||||
|
||||
import io.github.itzispyder.ogredupealias.utils.ChatConstraints;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
|
||||
public class ChatEventListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onChat(AsyncPlayerChatEvent e) {
|
||||
final Player p = e.getPlayer();
|
||||
final String msg = e.getMessage();
|
||||
final ChatConstraints cc = new ChatConstraints(p,msg);
|
||||
|
||||
if (!cc.passAllChecks()) e.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package io.github.itzispyder.ogredupealias.events;
|
||||
|
||||
import io.github.itzispyder.ogredupealias.data.Config;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
public class PlayerEventListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PlayerJoinEvent e) {
|
||||
final Player p = e.getPlayer();
|
||||
|
||||
e.setJoinMessage((p.hasPlayedBefore() ? Config.Player.joinMessage() : Config.Player.firstJoinMessage()).replaceAll("%player%",p.getDisplayName()));
|
||||
Config.Player.onJoin().forEach(p::chat);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onLeave(PlayerQuitEvent e) {
|
||||
final Player p = e.getPlayer();
|
||||
|
||||
e.setQuitMessage(Config.Player.quitMessage().replaceAll("%player%",p.getDisplayName()));
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.github.itzispyder.ogredupealias.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
@@ -19,4 +20,14 @@ public abstract class ArrayUtils {
|
||||
e.forEach(i -> list.add(a.apply(i)));
|
||||
return list;
|
||||
}
|
||||
|
||||
public static <T> String list2string(List<T> list) {
|
||||
return Text.color("&7[&e" + String.join("&7, &e", ArrayUtils.toNewList(list, Object::toString)) + "&7]");
|
||||
}
|
||||
|
||||
public static <T> List<T> bind(Iterable<T> tList, T... ts) {
|
||||
List<T> list = Arrays.asList(ts);
|
||||
tList.forEach(list::add);
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
package io.github.itzispyder.ogredupealias.utils;
|
||||
|
||||
import io.github.itzispyder.ogredupealias.data.Config;
|
||||
import net.md_5.bungee.api.chat.HoverEvent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ChatConstraints {
|
||||
|
||||
private static final Map<String,Long> chatCooldown = new HashMap<>();
|
||||
private static final Map<String,String> lastMessage = new HashMap<>();
|
||||
private static boolean isChatMuted = false;
|
||||
private final Player player;
|
||||
private final String message;
|
||||
|
||||
public ChatConstraints(Player player, String message) {
|
||||
this.player = player;
|
||||
this.message = this.removeColors(message);
|
||||
}
|
||||
|
||||
public boolean passAllChecks() {
|
||||
return passChatMuted() && passRepeat() && passSwear() && passUnicode() && passSpam();
|
||||
}
|
||||
|
||||
public boolean passChatMuted() {
|
||||
if (!isChatMuted) return true;
|
||||
if (player.hasPermission("oda.chat.bypass")) return true;
|
||||
player.sendMessage(Text.builder()
|
||||
.message("&cChat is currently muted! Please contact an administrator if you believe this is a mistake!")
|
||||
.prefix()
|
||||
.color()
|
||||
.build());
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean passRepeat() {
|
||||
if (!Config.Chat.AntiRepeat.enabled()) return true;
|
||||
if (player.hasPermission("oda.chat.bypass.repeat")) return true;
|
||||
|
||||
if (lastMessage.containsKey(player.getName()) && isSimilar(message, lastMessage.get(player.getName()))) {
|
||||
player.sendMessage(Text.builder("&cPlease do not repeat similar messages!")
|
||||
.prefix()
|
||||
.color()
|
||||
.build());
|
||||
return false;
|
||||
}
|
||||
lastMessage.put(player.getName(), message);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean passSpam() {
|
||||
if (!Config.Chat.AntiSpam.enabled()) return true;
|
||||
if (player.hasPermission("oda.chat.bypass.spam")) return true;
|
||||
|
||||
if (chatCooldown.containsKey(player.getName()) && chatCooldown.get(player.getName()) > System.currentTimeMillis()) {
|
||||
player.sendMessage(Text.builder("&cYou can chat again in &e" + getChatCooldown(player) + "&c seconds!")
|
||||
.prefix()
|
||||
.color()
|
||||
.build());
|
||||
return false;
|
||||
}
|
||||
int cooldownMillis = (int) (Config.Chat.AntiSpam.cooldown() * 1000);
|
||||
chatCooldown.put(player.getName(), System.currentTimeMillis() + cooldownMillis);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean passUnicode() {
|
||||
if (!Config.Chat.AntiUnicode.enabled()) return true;
|
||||
if (player.hasPermission("oda.chat.bypass.unicode")) return true;
|
||||
|
||||
String nonAllowed = message.replaceAll("[A-Za-z0-9\\[,./?><|\\]()*&^%$#@!~`{}:;'\"-_]","").trim();
|
||||
if (nonAllowed.length() == 0) return true;
|
||||
|
||||
TextComponent text = new TextComponent();
|
||||
text.setText(Text.builder(
|
||||
"&cPlease do not send unsupported characters in chat!"
|
||||
+ "\n&cMessage: &f" + message
|
||||
+ "\n&cCaught: &e" + nonAllowed
|
||||
).prefix()
|
||||
.color()
|
||||
.build());
|
||||
text.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(Text.color(
|
||||
"&cMessage: &f" + message
|
||||
+ "\n&cCaught: &e" + nonAllowed
|
||||
))));
|
||||
player.spigot().sendMessage(text);
|
||||
ServerUtils.forEachStaff(p -> {
|
||||
p.spigot().sendMessage(text);
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean passSwear() {
|
||||
if (!Config.Chat.AntiSwear.enabled()) return true;
|
||||
if (player.hasPermission("oda.chat.bypass.swear")) return true;
|
||||
|
||||
String s = message.toLowerCase().replaceAll("[^a-z0-9]","");
|
||||
String d = s;
|
||||
List<String> caught = new ArrayList<>();
|
||||
|
||||
for (String whitelisted : Config.Chat.AntiSwear.whitelist()) {
|
||||
s = s.replaceAll(whitelisted.toLowerCase(),"");
|
||||
}
|
||||
|
||||
for (String blacklisted : Config.Chat.AntiSwear.blacklist()) {
|
||||
if (s.contains(blacklisted.toLowerCase())) {
|
||||
caught.add(blacklisted);
|
||||
d = d.replaceAll(blacklisted, Text.color("&e" + blacklisted + "&f"));
|
||||
}
|
||||
}
|
||||
|
||||
if (caught.isEmpty()) return true;
|
||||
|
||||
String warn = ArrayUtils.list2string(caught);
|
||||
TextComponent text = new TextComponent();
|
||||
text.setText(Text.builder(
|
||||
"&cPlease do not swear in chat!"
|
||||
+ "\n&cMessage: &f" + d
|
||||
+ "\n&cCaught: &e" + warn
|
||||
).prefix()
|
||||
.color()
|
||||
.build());
|
||||
text.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(Text.color(
|
||||
"&cMessage: &f" + d
|
||||
+ "\n&cCaught: &e" + warn
|
||||
))));
|
||||
player.spigot().sendMessage(text);
|
||||
ServerUtils.forEachStaff(p -> {
|
||||
p.spigot().sendMessage(text);
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
private String removeColors(String msg) {
|
||||
return String.join(" ", Arrays.stream(msg.split(" "))
|
||||
.filter(s -> !(s.length() >= 1 && s.charAt(0) == '§'))
|
||||
.toList());
|
||||
}
|
||||
|
||||
public double getChatCooldown() {
|
||||
return getChatCooldown(player);
|
||||
}
|
||||
|
||||
public static double getChatCooldown(Player p) {
|
||||
if (!chatCooldown.containsKey(p.getName())) return 0.0;
|
||||
if (chatCooldown.get(p.getName()) <= System.currentTimeMillis()) return 0.0;
|
||||
|
||||
return Math.floor((chatCooldown.get(p.getName()) - System.currentTimeMillis()) / 10.0) / 100.0;
|
||||
}
|
||||
|
||||
private boolean isSimilar(String s1, String s2) {
|
||||
float max = Math.max(s1.length(), s2.length());
|
||||
float min = Math.min(s1.length(), s2.length());
|
||||
double lengthRatio = min / max;
|
||||
if (lengthRatio < 0.6) return false;
|
||||
return s1.toLowerCase().contains(s2.toLowerCase()) || s2.toLowerCase().contains(s1.toLowerCase());
|
||||
}
|
||||
|
||||
public static void setChatMuted(boolean muted) {
|
||||
isChatMuted = muted;
|
||||
}
|
||||
|
||||
public static boolean isChatMuted() {
|
||||
return isChatMuted;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package io.github.itzispyder.ogredupealias.utils;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class ServerUtils {
|
||||
|
||||
public static List<Player> getPlayers() {
|
||||
return new ArrayList<>(Bukkit.getOnlinePlayers());
|
||||
}
|
||||
|
||||
public static List<Player> getStaff() {
|
||||
return getPlayers().stream().filter(Player::isOp).toList();
|
||||
}
|
||||
|
||||
public static void forEachPlayer(Consumer<Player> consumer) {
|
||||
getPlayers().forEach(consumer);
|
||||
}
|
||||
|
||||
public static void forEachStaff(Consumer<Player> consumer) {
|
||||
getStaff().forEach(consumer);
|
||||
}
|
||||
|
||||
public static void dmEachPlayer(Predicate<Player> condition, String dm) {
|
||||
forEachPlayer(p -> {
|
||||
if (condition.test(p)) p.sendMessage(dm);
|
||||
});
|
||||
}
|
||||
|
||||
public static void dmEachPlayer(String dm) {
|
||||
forEachPlayer(p -> p.sendMessage(dm));
|
||||
}
|
||||
|
||||
public static void forEachSpecified(Iterable<Player> players, Consumer<Player> consumer) {
|
||||
players.forEach(consumer);
|
||||
}
|
||||
|
||||
public static void forEachSpecified(Consumer<Player> consumer, Player... players) {
|
||||
Arrays.stream(players).forEach(consumer);
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,9 @@ chat:
|
||||
anti-swear:
|
||||
enabled: true
|
||||
whitelist:
|
||||
- d
|
||||
- glass
|
||||
blacklist:
|
||||
- d
|
||||
- ass
|
||||
anti-spam:
|
||||
enabled: true
|
||||
cooldown: 5
|
||||
@@ -17,6 +17,7 @@ chat:
|
||||
enabled: true
|
||||
|
||||
player:
|
||||
first-join-message: "%player% has joined the game for their first time!"
|
||||
join-message: "&e%player% has joined the game"
|
||||
quit-message: "&e%player% has left the game"
|
||||
on-join:
|
||||
|
||||
@@ -6,7 +6,53 @@ prefix: ODA
|
||||
authors: [ ImproperIssues, TheTrouper ]
|
||||
description: Server utilities for OgreDupe.minehut.gg
|
||||
website: https://itzispyder.github.io/
|
||||
|
||||
permissions:
|
||||
oda.commands.config:
|
||||
description: Able to manage config from in game
|
||||
default: op
|
||||
oda.commands.mutechat:
|
||||
description: Able to mute chat
|
||||
default: op
|
||||
oda.commands.staffchat:
|
||||
description: Access to staffchat.
|
||||
default: op
|
||||
oda.chat.bypass:
|
||||
description: Bypass chat restrictions
|
||||
default: op
|
||||
children:
|
||||
- oda.chat.bypass.swear
|
||||
- oda.chat.bypass.spam
|
||||
- oda.chat.bypass.repeat
|
||||
- oda.chat.bypass.unicode
|
||||
oda.chat.bypass.swear:
|
||||
description: Bypass anti-swear
|
||||
default: op
|
||||
oda.chat.bypass.spam:
|
||||
description: Bypass anti-spam
|
||||
default: op
|
||||
oda.chat.bypass.repeat:
|
||||
description: Bypass anti-repeat
|
||||
default: op
|
||||
oda.chat.bypass.unicode:
|
||||
description: Bypass anti-unicode
|
||||
default: op
|
||||
|
||||
commands:
|
||||
config:
|
||||
description: Config management
|
||||
usage: /config [get|set] <path> <datatype> <value>
|
||||
permission: oda.commands.config
|
||||
aliases:
|
||||
- configuration
|
||||
mutechat:
|
||||
description: Mutes the chat
|
||||
usage: /mutechat [true|false]
|
||||
permission: oda.commands.mutechat
|
||||
staffchat:
|
||||
description: Staff chat
|
||||
usage: /staffchat [<message>]
|
||||
permission: oda.commands.staffchat
|
||||
aliases:
|
||||
- sc
|
||||
- schat
|
||||
Reference in New Issue
Block a user