diff --git a/pom.xml b/pom.xml index 7e6678146f3d960d0c4787f3d1fda7e64369c019..d0c08f8b32382bdba429e8c7ccfb78c4e8c7b9ed 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ <groupId>net.dappergoose</groupId> <artifactId>SimpleChatFilter</artifactId> - <version>1.0-SNAPSHOT</version> + <version>1.1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>SimpleChatFilter</name> @@ -24,8 +24,8 @@ <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> - <source>${java.version}</source> - <target>${java.version}</target> + <source>16</source> + <target>16</target> </configuration> </plugin> <plugin> @@ -71,5 +71,17 @@ <version>1.19-R0.1-SNAPSHOT</version> <scope>provided</scope> </dependency> + <dependency> + <groupId>com.velocitypowered</groupId> + <artifactId>velocity-api</artifactId> + <version>3.3.0-SNAPSHOT</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>de.exlll</groupId> + <artifactId>configlib-velocity</artifactId> + <version>4.5.0</version> + <scope>compile</scope> + </dependency> </dependencies> </project> diff --git a/src/main/java/net/dappergoose/simplechatfilter/SimpleChatFilter.java b/src/main/java/net/dappergoose/simplechatfilter/SimpleChatFilterBungee.java similarity index 98% rename from src/main/java/net/dappergoose/simplechatfilter/SimpleChatFilter.java rename to src/main/java/net/dappergoose/simplechatfilter/SimpleChatFilterBungee.java index 74ce92332518721bec0d5d52a0e135b84a0ce82a..73137d80371332baf93db64782f5b21d844c76c6 100644 --- a/src/main/java/net/dappergoose/simplechatfilter/SimpleChatFilter.java +++ b/src/main/java/net/dappergoose/simplechatfilter/SimpleChatFilterBungee.java @@ -17,7 +17,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -public final class SimpleChatFilter extends Plugin implements Listener { +public final class SimpleChatFilterBungee extends Plugin implements Listener { public void makeConfig() throws IOException { // Create plugin config folder if it doesn't exist diff --git a/src/main/java/net/dappergoose/simplechatfilter/SimpleChatFilterVelocity.java b/src/main/java/net/dappergoose/simplechatfilter/SimpleChatFilterVelocity.java new file mode 100644 index 0000000000000000000000000000000000000000..a0a5cc49341124b4dc964d6b835fdd395eae9ee0 --- /dev/null +++ b/src/main/java/net/dappergoose/simplechatfilter/SimpleChatFilterVelocity.java @@ -0,0 +1,138 @@ +package net.dappergoose.simplechatfilter; + +import com.google.inject.Inject; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.player.PlayerChatEvent; +import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; +import com.velocitypowered.api.plugin.annotation.DataDirectory; +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.ProxyServer; +import de.exlll.configlib.Comment; +import de.exlll.configlib.Configuration; +import de.exlll.configlib.YamlConfigurations; +import net.kyori.adventure.text.Component; +import org.slf4j.Logger; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Path; +import java.util.*; +import java.util.concurrent.atomic.AtomicReference; + + +public class SimpleChatFilterVelocity { + + private final ProxyServer server; + private final Logger logger; + private final Path dataDirectory; + + private BaseConfiguration config; + + @Configuration + public static class BaseConfiguration { + @Comment("Categories of blocked words and phrases") + Map<String, Category> categories = Map.of( + "advertising-pfcloud", + new Category(List.of( + "a friendly bot designed to join servers", + "If you are searching for a good server hosting provider", + "https://shop.pfcloud.io"), + List.of( + "ipban {username} Bot/Advertising -s"), + "&cPlease do not advertise!" + ) + ); + @Comment("Message sent to staff when a player is blocked") + String staffMessage = "&c{displayname} &7tried to say &c{message} &7in &c{server} &7but was blocked for &c{category}"; + } + + public record Category(List<String> blocked, List<String> commands, String message) {} + + @Inject + public SimpleChatFilterVelocity(ProxyServer server, Logger logger, @DataDirectory Path dataDirectory) { + this.server = server; + this.logger = logger; + this.dataDirectory = dataDirectory; + this.config = new BaseConfiguration(); + } + + public void makeConfig() throws IOException { + // Create plugin config folder if it doesn't exist + File dataPath = dataDirectory.toFile(); + if (!dataPath.exists()) { + logger.info("Created config folder: " + dataPath.mkdir()); + } + + File configFile = new File(dataPath, "config.yml"); + + // Copy default config if it doesn't exist + if (!configFile.exists()) { + FileOutputStream outputStream = new FileOutputStream(configFile); // Throws IOException + InputStream in = this.getClass().getClassLoader().getResourceAsStream("config.yml"); // This file must exist in the jar resources folder + in.transferTo(outputStream); // Throws IOException + } + } + + @Subscribe + public void onProxyInitialization(ProxyInitializeEvent event) { + try { + makeConfig(); + Path configPath = dataDirectory.resolve("config.yml"); + this.config = YamlConfigurations.load(configPath, BaseConfiguration.class); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Subscribe + public void onPlayerChat(PlayerChatEvent e) { + Player p = e.getPlayer(); + + String message = e.getMessage(); + boolean violated = false; + String matchedCategory = null; + for(String categoryKey : config.categories.keySet()) { + Category category = config.categories.get(categoryKey); + if(p.hasPermission("chatfilter.bypass." + category)) continue; + for(String word : category.blocked) { + if(message.contains(word)) { + violated = true; + matchedCategory = categoryKey; + break; + } + } + if(violated) break; + } + + if(violated) { + e.setResult(PlayerChatEvent.ChatResult.denied()); + AtomicReference<String> serverName = new AtomicReference<>("unknown"); + p.getCurrentServer().ifPresent(s -> serverName.set(s.getServerInfo().getName())); + sendStaffMessage( + Component.text(config.staffMessage + .replace("{displayname}", p.getUsername()) + .replace("{category}", matchedCategory) + .replace("{message}", message) + .replace("{server}", serverName.get()) + ) + ); + + p.sendMessage(Component.text( + config.categories.get(matchedCategory).message + )); + for(String command : config.categories.get(matchedCategory).commands) { + server.getCommandManager().executeAsync(server.getConsoleCommandSource(), command.replace("{username}", p.getUsername())); + } + } + } + + private void sendStaffMessage(Component component) { + for(Player p : server.getAllPlayers()) { + if(p.hasPermission("chatfilter.staff")) { + p.sendMessage(component); + } + } + } +} diff --git a/src/main/resources/bungee.yml b/src/main/resources/bungee.yml index cf15c94abbedc316d550ca2ffced483d19d1b447..bc862af8845fa3dda336b710da72ce9aadfebfa6 100644 --- a/src/main/resources/bungee.yml +++ b/src/main/resources/bungee.yml @@ -1,3 +1,3 @@ name: SimpleChatFilter version: '${project.version}' -main: net.dappergoose.simplechatfilter.SimpleChatFilter +main: net.dappergoose.simplechatfilter.SimpleChatFilterBungee diff --git a/src/main/resources/velocity-plugin.json b/src/main/resources/velocity-plugin.json new file mode 100644 index 0000000000000000000000000000000000000000..c06f4080ae89a92bf67dd1f54c8f02f08fd5895f --- /dev/null +++ b/src/main/resources/velocity-plugin.json @@ -0,0 +1,9 @@ +{ + "id":"simplechatfilter", + "name":"SimpleChatFilter", + "version":"${project.version}", + "url":"https://git.rb9.xyz/dappergoose/simplechatfilter", + "authors":["Radialbog9"], + "dependencies":[], + "main":"net.dappergoose.simplechatfilter.SimpleChatFilterVelocity" +} \ No newline at end of file