Initial Commit

+ Chat monitoring working
+ Banned phrases kick and ban the player
+ All phrases send a webhook to discord.
+ Config can be reloaded on the fly
master
Joey Hines 2020-09-20 16:34:23 -05:00
commit 108e0ecd8e
12 changed files with 434 additions and 0 deletions

118
.gitignore vendored 100644
View File

@ -0,0 +1,118 @@
# User-specific stuff
.idea/
*.iml
*.ipr
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
.gradle
build/
# Ignore Gradle GUI config
gradle-app.setting
# Cache of project
.gradletasknamecache
**/build/
# Common working directory
run/
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar

27
build.gradle 100644
View File

@ -0,0 +1,27 @@
plugins {
id 'java'
}
group = 'com.zerohighdef'
version = '0.1'
sourceCompatibility = '8'
repositories {
mavenLocal()
maven {
name = 'spigotmc-repo'
url = 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/'
}
maven {
name = 'etztech-repo'
url = 'http://repo.etztech.xyz/'
}
}
dependencies {
compileOnly 'org.spigotmc:spigot-api:1.16.3-R0.1-SNAPSHOT'
compileOnly 'xyz.etztech:plugin-api:1.0.8'
compileOnly 'xyz.etztech:javacord:0.2.0'
}

View File

BIN
gradle/wrapper/gradle-wrapper.jar vendored 100644

Binary file not shown.

View File

@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

1
settings.gradle 100644
View File

@ -0,0 +1 @@
rootProject.name = 'hush'

View File

@ -0,0 +1,54 @@
package com.zerohighdef.hush;
import com.zerohighdef.hush.commands.MainCommand;
import com.zerohighdef.hush.listeners.HushAsyncChatListener;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Logger;
public final class Hush extends JavaPlugin {
private final Logger log = Logger.getLogger("Minecraft");
private List<WatchList> watchLists;
@Override
public void onEnable() {
saveDefaultConfig();
reloadConfig();
if (isEnabled()) {
new HushAsyncChatListener(this);
new MainCommand(this);
}
}
@Override
public void reloadConfig() {
super.reloadConfig();
buildWatchLists();
}
private void buildWatchLists() {
watchLists = new LinkedList<>();
ConfigurationSection watchListSection = getConfig().getConfigurationSection("watch_lists");
for (String permission: watchListSection.getKeys(false)) {
String banMessage = watchListSection.getString(permission + ".ban_message");
List<String> banPatterns = watchListSection.getStringList(permission + ".ban");
List<String> monitorPatterns = watchListSection.getStringList(permission + ".monitor");
watchLists.add(new WatchList("hush." + permission, banMessage, banPatterns, monitorPatterns));
}
}
public void log(String message) {
log.info( "[Hush]: " + message );
}
public List<WatchList> getWatchLists() {
return watchLists;
}
}

View File

@ -0,0 +1,44 @@
package com.zerohighdef.hush;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class WatchList {
private final String permission;
private final String banMessage;
private final List<Pattern> banPatterns;
private final List<Pattern> monitorPatterns;
WatchList(String permission, String banMessage, List<String> banPatterns, List<String> monitorPatterns) {
this.permission = permission;
this.banMessage = banMessage;
this.banPatterns = WatchList.buildPattern(banPatterns);
this.monitorPatterns = WatchList.buildPattern(monitorPatterns);
}
private static List<Pattern> buildPattern(List<String> patternList) {
return patternList
.stream()
.map(Pattern::compile)
.collect(Collectors.toList());
}
public String getPermission() {
return permission;
}
public List<Pattern> getBanPatterns() {
return banPatterns;
}
public List<Pattern> getMonitorPatterns() {
return monitorPatterns;
}
public String getBanMessage() {
return banMessage;
}
}

View File

@ -0,0 +1,57 @@
package com.zerohighdef.hush.commands;
import com.zerohighdef.hush.Hush;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
public class MainCommand implements CommandExecutor {
private final Hush plugin;
public MainCommand(Hush plugin) {
this.plugin = plugin;
this.plugin.getCommand("hush").setExecutor(this);
}
@Override
public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args) {
if (!commandSender.hasPermission("hush.admin")) {
return true;
}
if (args.length == 0) {
help(commandSender);
} else {
switch (args[0]) {
case "help":
help(commandSender);
break;
case "reload":
reload(commandSender);
break;
}
}
return true;
}
public void reload(CommandSender commandSender) {
plugin.reloadConfig();
BaseComponent[] message = new ComponentBuilder().append("Plugin reloaded").color(ChatColor.GREEN).create();
commandSender.spigot().sendMessage(message);
}
public void help(CommandSender commandSender) {
String version = Bukkit.getPluginManager().getPlugin("MineAlert").getDescription().getVersion();
BaseComponent[] message = new ComponentBuilder()
.append(String.format("*** Hush v%s ***", version)).color(ChatColor.DARK_AQUA)
.append("\n/hush help - Show this message").color(ChatColor.AQUA)
.append("\n/hush reload - Reload the config").color(ChatColor.AQUA)
.create();
commandSender.spigot().sendMessage(message);
}
}

View File

@ -0,0 +1,99 @@
package com.zerohighdef.hush.listeners;
import com.zerohighdef.hush.Hush;
import com.zerohighdef.hush.WatchList;
import org.apache.commons.lang.ObjectUtils;
import org.bukkit.BanList;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import xyz.etztech.Javacord;
import xyz.etztech.Webhook;
import xyz.etztech.embed.Author;
import xyz.etztech.embed.Embed;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.regex.Pattern;
interface Action {
void action();
}
public class HushAsyncChatListener implements Listener {
private final Hush plugin;
public HushAsyncChatListener(Hush plugin) {
this.plugin = plugin;
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = false)
public boolean onChat(AsyncPlayerChatEvent event) {
String chatMessage = event.getMessage();
Player sender = event.getPlayer();
for (WatchList list : plugin.getWatchLists()) {
if (sender.hasPermission(list.getPermission())) {
boolean phraseFound = checkPhraseList(list.getBanPatterns(), sender, chatMessage, (() -> {
banPlayer(sender, list.getBanMessage());
}));
if (phraseFound) {
event.setCancelled(true);
return true;
}
checkPhraseList(list.getMonitorPatterns(), sender, chatMessage, null);
}
}
return true;
}
private void banPlayer(Player player, String banMessage) {
Bukkit.getBanList(BanList.Type.NAME)
.addBan(player.getName(), banMessage, null, null);
Bukkit.getScheduler().runTask(plugin, new Runnable() {
@Override
public void run() {
player.kickPlayer("You have been banned: " + banMessage);
}
});
}
private boolean checkPhraseList(List<Pattern> patternList, Player player, String chatMessage, Action action) {
for (Pattern pattern: patternList) {
if (pattern.matcher(chatMessage).find()) {
if (action != null) {
action.action();
}
String playerName = player.getName();
String webhook = plugin.getConfig().getString("webhook");
if (webhook != null) {
String message = playerName + " said: " + "`" + Javacord.escapeFormat(chatMessage) + "`";
Embed embed = new Embed()
.color(0xC70039)
.description(message)
.author(new Author(playerName, "", String.format("https://minotar.net/helm/%s/100.png", playerName), ""))
.timestamp(OffsetDateTime.now());
this.plugin.getServer().getScheduler().runTaskAsynchronously(this.plugin, () -> {
try {
Javacord.sendWebhook(webhook, new Webhook("@here", embed));
} catch (Exception e) {
this.plugin.log("Webhook failed to send");
}
});
}
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,15 @@
# Discord webhook
webhook: ""
watch_lists:
# Permission to check
# To enable check give the group the 'hush.<perm>' permission
guest:
ban_message: "Please respect our players and staff. Appeal online"
#Phrases to ban for
ban:
- "heck"
- "fricks"
#Phrases to monitor
monitor:
- "hypixel"

View File

@ -0,0 +1,14 @@
name: Hush
version: v0.1.0
main: com.zerohighdef.hush.Hush
api-version: "1.16"
authors: [ZeroHighDef]
description: Monitor chat for forbidden phrases.
commands:
hush:
description: Admin command
permissions:
hush.admin:
description: Allows use of the admin command
default: op