forked from Minecraft/Hush
Added cancel_msg config and update docs (#3)
+ cancel_msg allows a category to cancel the offending message, blocking it from going to chat + Updated docs to be a bit more clear + Switched to woodpecker + Fixes #1 and #2 Reviewed-on: Minecraft/Hush#3 Co-authored-by: Joey Hines <joey@ahines.net> Co-committed-by: Joey Hines <joey@ahines.net>latest
parent
237328ab50
commit
784ebed9b0
42
.drone.yml
42
.drone.yml
|
@ -1,42 +0,0 @@
|
|||
---
|
||||
kind: pipeline
|
||||
name: compliance
|
||||
type: docker
|
||||
|
||||
trigger:
|
||||
event:
|
||||
- pull_request
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
pull: always
|
||||
image: gradle:6.6
|
||||
commands:
|
||||
- gradle build
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: release
|
||||
type: docker
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
event:
|
||||
- push
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
pull: always
|
||||
image: gradle:6.6
|
||||
commands:
|
||||
- gradle shadowjar
|
||||
- name: gitea-release
|
||||
pull: always
|
||||
image: jolheiser/drone-gitea-main:latest
|
||||
settings:
|
||||
token:
|
||||
from_secret: gitea_token
|
||||
base: https://git.etztech.xyz
|
||||
files:
|
||||
- "build/libs/*.jar"
|
|
@ -0,0 +1,29 @@
|
|||
clone:
|
||||
git:
|
||||
image: "woodpeckerci/plugin-git:next"
|
||||
pipeline:
|
||||
compliance:
|
||||
commands:
|
||||
- "gradle build"
|
||||
- "gradle test"
|
||||
image: "gradle:7.4-jdk17"
|
||||
when:
|
||||
event: pull_request
|
||||
build:
|
||||
commands:
|
||||
- "gradle shadowJar"
|
||||
image: "gradle:7.4-jdk17"
|
||||
when:
|
||||
branch: main
|
||||
event: push
|
||||
release:
|
||||
image: jolheiser/drone-gitea-main:latest
|
||||
settings:
|
||||
token:
|
||||
from_secret: gitea_token
|
||||
base: https://git.jojodev.com
|
||||
files:
|
||||
- "build/libs/*.jar"
|
||||
when:
|
||||
branch: main
|
||||
event: push
|
39
README.md
39
README.md
|
@ -1,26 +1,37 @@
|
|||
# Hush [![Build Status](https://drone.etztech.xyz/api/badges/Minecraft/Hush/status.svg)](https://drone.etztech.xyz/Minecraft/Hush)
|
||||
# Hush [![Build Status](https://ci.jojodev.com/api/badges/Minecraft/Hush/status.svg)](https://ci.jojodev.com/Minecraft/Hush)
|
||||
A plugin to monitor chat for forbidden phrases.
|
||||
|
||||
## Watch Lists
|
||||
Watch lists specifies phrases to monitor. Each watch list has an associated permission. In the form of
|
||||
`hush.<watchlist_name>`. A user with this permission will have their chat messages checked to see if
|
||||
they match the corresponding watch list.
|
||||
Watchlist are groups of categories Hush monitors for. To enable a watchlist for a player,
|
||||
they should be given the `hush.<watchlist_name>` permission.
|
||||
|
||||
Watch lists contain two types of phrases, Monitored and Banned.
|
||||
### Categories
|
||||
A category is a group of regex filters, and the actions to run when a player matches one of those filters.
|
||||
An example of a category is shown below:
|
||||
|
||||
### Monitored
|
||||
Phrases that should be checked for context. If a user says one of these phrases, a Discord webhook is
|
||||
sent out.
|
||||
```yaml
|
||||
# "ban" category
|
||||
ban:
|
||||
# Filters to search for in chat
|
||||
filters:
|
||||
- "heck"
|
||||
- "fricks"
|
||||
# Optional, commands to run when a filter matches. {player} is replaced with the player's name.
|
||||
commands:
|
||||
- "ban {player}"
|
||||
# Optional, should the message that matched the filter be cancelled? Default is "false".
|
||||
cancel_msg: true
|
||||
```
|
||||
|
||||
### Banned
|
||||
A banned phrase results in an immediate ban. If a user says a banned phrase, they are kicked and added
|
||||
to the ban list. A webhook is also sent to Discord.
|
||||
## Permissions
|
||||
* `hush.admin` - allows access to the `hush` command
|
||||
* `hush.<watchlist_name>` - used to determine if a player's messages should be checked by a watchlist
|
||||
|
||||
### Commands
|
||||
* `hush reload` - reloads the plugin config
|
||||
|
||||
## Example Config
|
||||
[Config](src/main/resources/config.yml)
|
||||
|
||||
## Permissions
|
||||
[Permissions](src/main/resources/plugin.yml)
|
||||
|
||||
## License
|
||||
[MIT](LICENSE)
|
||||
|
|
|
@ -4,7 +4,7 @@ plugins {
|
|||
}
|
||||
|
||||
group = 'com.zerohighdef'
|
||||
version = '0.2.1'
|
||||
version = '0.2.2'
|
||||
|
||||
sourceCompatibility = '8'
|
||||
|
||||
|
@ -16,7 +16,7 @@ repositories {
|
|||
}
|
||||
maven {
|
||||
name = 'etztech-repo'
|
||||
url = 'http://repo.etztech.xyz/'
|
||||
url = 'https://mvn.jojodev.com/releases/'
|
||||
}
|
||||
maven {url = 'https://jcenter.bintray.com'}
|
||||
maven {url = 'https://jitpack.io'}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
|
|
|
@ -44,7 +44,8 @@ public final class Hush extends JavaPlugin {
|
|||
ConfigurationSection categorySection = permissionSection.getConfigurationSection(category);
|
||||
List<String> filters = categorySection.getStringList("filters");
|
||||
List<String> commands = categorySection.getStringList("commands");
|
||||
watchCategories.add(new WatchCategory(category, filters, commands));
|
||||
boolean cancelMsg = categorySection.getBoolean("cancel_msg", false);
|
||||
watchCategories.add(new WatchCategory(category, filters, commands, cancelMsg));
|
||||
}
|
||||
watchLists.put(permission, watchCategories);
|
||||
}
|
||||
|
|
|
@ -9,11 +9,13 @@ public class WatchCategory {
|
|||
private final String categoryName;
|
||||
private final List<Pattern> patterns;
|
||||
private final List<String> commands;
|
||||
private final boolean cancelMsg;
|
||||
|
||||
public WatchCategory(String categoryName, List<String> patterns, List<String> commands) {
|
||||
public WatchCategory(String categoryName, List<String> patterns, List<String> commands, boolean cancelMsg) {
|
||||
this.categoryName = categoryName;
|
||||
this.patterns = buildPattern(patterns);
|
||||
this.commands = commands;
|
||||
this.cancelMsg = cancelMsg;
|
||||
}
|
||||
|
||||
private static List<Pattern> buildPattern(List<String> patternList) {
|
||||
|
@ -42,4 +44,8 @@ public class WatchCategory {
|
|||
public List<String> getCommands() {
|
||||
return commands;
|
||||
}
|
||||
|
||||
public boolean getCancelMsg() {
|
||||
return cancelMsg;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,10 @@ public class MainCommand implements CommandExecutor {
|
|||
@Override
|
||||
public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args) {
|
||||
if (!commandSender.hasPermission("hush.admin")) {
|
||||
BaseComponent[] message = new ComponentBuilder()
|
||||
.append("You don't have permission to to use this command.").color(ChatColor.RED)
|
||||
.create();
|
||||
commandSender.spigot().sendMessage(message);
|
||||
return true;
|
||||
}
|
||||
if (args.length == 0) {
|
||||
|
|
|
@ -26,59 +26,69 @@ public class HushAsyncChatListener implements Listener {
|
|||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public boolean onChat(AsyncPlayerChatEvent event) {
|
||||
public void onChat(AsyncPlayerChatEvent event) {
|
||||
String chatMessage = event.getMessage();
|
||||
Player sender = event.getPlayer();
|
||||
|
||||
for (String permission : plugin.getWatchLists().keySet()) {
|
||||
if (sender.hasPermission("hush." + permission)) {
|
||||
for (WatchCategory category : plugin.getWatchLists().get(permission)) {
|
||||
checkMessage(category, permission, sender, chatMessage);
|
||||
boolean is_match = checkMessage(category, permission, sender, chatMessage);
|
||||
|
||||
// If the message matched, and the category requires the event to be canceled
|
||||
if (is_match && category.getCancelMsg()) {
|
||||
// cancel event
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void runCommand(String command) {
|
||||
Bukkit.getScheduler().runTask(plugin, () -> Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command));
|
||||
}
|
||||
|
||||
private void checkMessage(WatchCategory category, String watchList, Player player, String chatMessage) {
|
||||
private boolean checkMessage(WatchCategory category, String watchList, Player player, String chatMessage) {
|
||||
Matcher match = category.checkPatterns(chatMessage);
|
||||
if (match != null) {
|
||||
String playerName = player.getName();
|
||||
String webhookURL = plugin.getConfig().getString("webhook");
|
||||
|
||||
for (String command: category.getCommands()) {
|
||||
runCommand(command.replace("{player}", playerName));
|
||||
}
|
||||
|
||||
plugin.log(String.format("%s matched filter in %s.%s", playerName, watchList, category.getCategoryName()));
|
||||
|
||||
if (webhookURL != null && !plugin.isInCoolDown(player)) {
|
||||
plugin.addCoolDown(player);
|
||||
chatMessage = match.replaceAll("**$0**");
|
||||
String message = Javacord.escapeFormat(playerName) + " said: " + chatMessage;
|
||||
Embed embed = new Embed()
|
||||
.color(0xC70039)
|
||||
.description(message)
|
||||
.addField(new Field("Watchlist", String.format("`%s`", watchList)))
|
||||
.addField(new Field("Category", String.format("`%s`", category.getCategoryName())))
|
||||
.author(new Author(playerName, "", String.format("https://minotar.net/helm/%s/100.png", playerName), ""))
|
||||
.timestamp(OffsetDateTime.now());
|
||||
|
||||
Webhook webhook = new Webhook("@here", embed);
|
||||
|
||||
this.plugin.getServer().getScheduler().runTaskAsynchronously(this.plugin, () -> {
|
||||
try {
|
||||
Javacord.sendWebhook(webhookURL, webhook);
|
||||
} catch (Exception e) {
|
||||
this.plugin.log("Webhook failed to send.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (match == null) {
|
||||
// message was not a match
|
||||
return false;
|
||||
}
|
||||
|
||||
String playerName = player.getName();
|
||||
String webhookURL = plugin.getConfig().getString("webhook");
|
||||
|
||||
for (String command: category.getCommands()) {
|
||||
runCommand(command.replace("{player}", playerName));
|
||||
}
|
||||
|
||||
plugin.log(String.format("%s matched filter in %s.%s", playerName, watchList, category.getCategoryName()));
|
||||
|
||||
if (webhookURL != null && !plugin.isInCoolDown(player)) {
|
||||
plugin.addCoolDown(player);
|
||||
chatMessage = match.replaceAll("**$0**");
|
||||
String message = Javacord.escapeFormat(playerName) + " said: " + chatMessage;
|
||||
Embed embed = new Embed()
|
||||
.color(0xC70039)
|
||||
.description(message)
|
||||
.addField(new Field("Watchlist", String.format("`%s`", watchList)))
|
||||
.addField(new Field("Category", String.format("`%s`", category.getCategoryName())))
|
||||
.author(new Author(playerName, "", String.format("https://minotar.net/helm/%s/100.png", playerName), ""))
|
||||
.timestamp(OffsetDateTime.now());
|
||||
|
||||
Webhook webhook = new Webhook("@here", embed);
|
||||
|
||||
this.plugin.getServer().getScheduler().runTaskAsynchronously(this.plugin, () -> {
|
||||
try {
|
||||
Javacord.sendWebhook(webhookURL, webhook);
|
||||
} catch (Exception e) {
|
||||
this.plugin.log("Webhook failed to send.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,18 +5,22 @@ cooldown: 5
|
|||
|
||||
watch_lists:
|
||||
# Permission to check
|
||||
# To enable the check, give the group the 'hush.<watch_list>' permission
|
||||
# To enable the check for a user, give the 'hush.<watch_list>' permission
|
||||
guest:
|
||||
# "ban" category
|
||||
ban:
|
||||
# Filters to search for
|
||||
# Filters to search for in chat
|
||||
filters:
|
||||
- "heck"
|
||||
- "fricks"
|
||||
# Commands to run {player} is replaced with the player's name
|
||||
# Optional, commands to run when a filter matches. {player} is replaced with the player's name.
|
||||
commands:
|
||||
- "ban {player}"
|
||||
# Optional, should the message that matched the filter be cancelled. Default is "false".
|
||||
cancel_msg: true
|
||||
# "monitor" category
|
||||
monitor:
|
||||
# Filters to search for
|
||||
# Filters to search for in chat
|
||||
filters:
|
||||
- "stupid"
|
||||
- "dumb"
|
Loading…
Reference in New Issue