Compare commits

..

No commits in common. "main" and "master" have entirely different histories.
main ... master

10 changed files with 103 additions and 126 deletions

42
.drone.yml 100644
View File

@ -0,0 +1,42 @@
---
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"

View File

@ -1,29 +0,0 @@
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

View File

@ -1,37 +1,26 @@
# Hush [![Build Status](https://ci.jojodev.com/api/badges/Minecraft/Hush/status.svg)](https://ci.jojodev.com/Minecraft/Hush)
# Hush [![Build Status](https://drone.etztech.xyz/api/badges/Minecraft/Hush/status.svg)](https://drone.etztech.xyz/Minecraft/Hush)
A plugin to monitor chat for forbidden phrases.
## Watch Lists
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 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.
### 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:
Watch lists contain two types of phrases, Monitored and Banned.
```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
```
### Monitored
Phrases that should be checked for context. If a user says one of these phrases, a Discord webhook is
sent out.
## 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
### 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.
## Example Config
[Config](src/main/resources/config.yml)
## Permissions
[Permissions](src/main/resources/plugin.yml)
## License
[MIT](LICENSE)

View File

@ -4,7 +4,7 @@ plugins {
}
group = 'com.zerohighdef'
version = '0.2.2'
version = '0.2.1'
sourceCompatibility = '8'
@ -16,7 +16,7 @@ repositories {
}
maven {
name = 'etztech-repo'
url = 'https://mvn.jojodev.com/releases/'
url = 'http://repo.etztech.xyz/'
}
maven {url = 'https://jcenter.bintray.com'}
maven {url = 'https://jitpack.io'}

View File

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

View File

@ -44,8 +44,7 @@ public final class Hush extends JavaPlugin {
ConfigurationSection categorySection = permissionSection.getConfigurationSection(category);
List<String> filters = categorySection.getStringList("filters");
List<String> commands = categorySection.getStringList("commands");
boolean cancelMsg = categorySection.getBoolean("cancel_msg", false);
watchCategories.add(new WatchCategory(category, filters, commands, cancelMsg));
watchCategories.add(new WatchCategory(category, filters, commands));
}
watchLists.put(permission, watchCategories);
}

View File

@ -9,13 +9,11 @@ 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, boolean cancelMsg) {
public WatchCategory(String categoryName, List<String> patterns, List<String> commands) {
this.categoryName = categoryName;
this.patterns = buildPattern(patterns);
this.commands = commands;
this.cancelMsg = cancelMsg;
}
private static List<Pattern> buildPattern(List<String> patternList) {
@ -44,8 +42,4 @@ public class WatchCategory {
public List<String> getCommands() {
return commands;
}
public boolean getCancelMsg() {
return cancelMsg;
}
}

View File

@ -21,10 +21,6 @@ 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) {

View File

@ -26,69 +26,59 @@ public class HushAsyncChatListener implements Listener {
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onChat(AsyncPlayerChatEvent event) {
public boolean 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)) {
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);
}
checkMessage(category, permission, sender, chatMessage);
}
}
}
return true;
}
private void runCommand(String command) {
Bukkit.getScheduler().runTask(plugin, () -> Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command));
}
private boolean checkMessage(WatchCategory category, String watchList, Player player, String chatMessage) {
private void 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;
}
}

View File

@ -5,22 +5,18 @@ cooldown: 5
watch_lists:
# Permission to check
# To enable the check for a user, give the 'hush.<watch_list>' permission
# To enable the check, give the group the 'hush.<watch_list>' permission
guest:
# "ban" category
ban:
# Filters to search for in chat
# Filters to search for
filters:
- "heck"
- "fricks"
# Optional, commands to run when a filter matches. {player} is replaced with the player's name.
# Commands to run {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 in chat
# Filters to search for
filters:
- "stupid"
- "dumb"