[17.8k Lines] Started working on the chat filter
This commit is contained in:
parent
4d2a8369d9
commit
6803133935
@ -11,6 +11,7 @@ import zone.themcgamer.api.model.ModelSerializer;
|
||||
import zone.themcgamer.api.model.impl.*;
|
||||
import zone.themcgamer.api.repository.AccountRepository;
|
||||
import zone.themcgamer.api.route.AccountRoute;
|
||||
import zone.themcgamer.api.route.ChatRoute;
|
||||
import zone.themcgamer.api.route.PlayerStatusRoute;
|
||||
import zone.themcgamer.api.route.ServersRoute;
|
||||
import zone.themcgamer.data.APIAccessLevel;
|
||||
@ -63,6 +64,7 @@ public class API {
|
||||
addRoute(new ServersRoute());
|
||||
addRoute(new AccountRoute(accountRepository));
|
||||
addRoute(new PlayerStatusRoute());
|
||||
addRoute(new ChatRoute());
|
||||
|
||||
// 404 Handling
|
||||
Spark.notFound((request, response) -> {
|
||||
|
70
api/src/main/java/zone/themcgamer/api/route/ChatRoute.java
Normal file
70
api/src/main/java/zone/themcgamer/api/route/ChatRoute.java
Normal file
@ -0,0 +1,70 @@
|
||||
package zone.themcgamer.api.route;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
import zone.themcgamer.api.APIException;
|
||||
import zone.themcgamer.api.APIVersion;
|
||||
import zone.themcgamer.api.RestPath;
|
||||
import zone.themcgamer.common.EnumUtils;
|
||||
import zone.themcgamer.data.APIAccessLevel;
|
||||
import zone.themcgamer.data.ChatFilterLevel;
|
||||
import zone.themcgamer.data.jedis.data.APIKey;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* This route handles everything associated with the chat
|
||||
*
|
||||
* @author Braydon
|
||||
*/
|
||||
public class ChatRoute {
|
||||
private static final Map<ChatFilterLevel, List<String>> filteredWords = new HashMap<>() {{
|
||||
put(ChatFilterLevel.LOW, Arrays.asList(
|
||||
"ass"
|
||||
));
|
||||
put(ChatFilterLevel.MEDIUM, Arrays.asList(
|
||||
"fuck", "shit"
|
||||
));
|
||||
put(ChatFilterLevel.HIGH, Arrays.asList(
|
||||
"nigger"
|
||||
));
|
||||
}};
|
||||
|
||||
/**
|
||||
* This path handles filtering the provided text with the provided {@link ChatFilterLevel}
|
||||
*/
|
||||
@RestPath(path = "/filter/:text/:level", version = APIVersion.V1, accessLevel = APIAccessLevel.DEV)
|
||||
public String filterText(Request request, Response response, APIKey apiKey) throws APIException {
|
||||
String text = request.params(":text");
|
||||
ChatFilterLevel chatFilterLevel = EnumUtils.fromString(ChatFilterLevel.class, request.params(":level").toUpperCase());
|
||||
if (chatFilterLevel == null)
|
||||
throw new APIException("Invalid filter level, valid options: " + Arrays.stream(ChatFilterLevel.values()).map(ChatFilterLevel::name).collect(Collectors.joining(", ")));
|
||||
String filteredMessage = text;
|
||||
text = text.replace("{dot}", ".");
|
||||
if (chatFilterLevel.isUrls()) {
|
||||
// TODO: 2/20/21 filter urls with regex patterns
|
||||
}
|
||||
if (chatFilterLevel.isIps()) {
|
||||
// TODO: 2/20/21 filter ips with regex patterns
|
||||
}
|
||||
List<String> filteredWords = new ArrayList<>();
|
||||
for (ChatFilterLevel filterLevel : ChatFilterLevel.values()) {
|
||||
if (chatFilterLevel.ordinal() >= filterLevel.ordinal()) {
|
||||
List<String> list = ChatRoute.filteredWords.getOrDefault(filterLevel, new ArrayList<>());
|
||||
if (list.isEmpty())
|
||||
continue;
|
||||
filteredWords.addAll(list);
|
||||
}
|
||||
}
|
||||
for (String word : text.split(" ")) {
|
||||
for (String filteredWord : filteredWords) {
|
||||
if (word.toLowerCase().contains(filteredWord.toLowerCase())) {
|
||||
filteredMessage = filteredMessage.replace(word, Strings.repeat("*", word.length()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return filteredMessage;
|
||||
}
|
||||
}
|
@ -41,7 +41,7 @@ subprojects {
|
||||
|
||||
compileOnly("org.slf4j:slf4j-simple:1.7.30")
|
||||
|
||||
implementation("com.google.code.gson:gson:2.7")
|
||||
implementation("com.google.code.gson:gson:2.8.5")
|
||||
|
||||
implementation("commons-io:commons-io:2.6")
|
||||
|
||||
|
37
core/src/main/java/zone/themcgamer/core/api/WebAPI.java
Normal file
37
core/src/main/java/zone/themcgamer/core/api/WebAPI.java
Normal file
@ -0,0 +1,37 @@
|
||||
package zone.themcgamer.core.api;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import lombok.NonNull;
|
||||
import zone.themcgamer.core.api.json.JsonRequest;
|
||||
import zone.themcgamer.core.api.json.JsonResponse;
|
||||
import zone.themcgamer.data.ChatFilterLevel;
|
||||
|
||||
import java.net.http.HttpClient;
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* @author Braydon
|
||||
*/
|
||||
public class WebAPI {
|
||||
public static final String API_KEY = "406321cc-48f3-454b-900a-972fd88e4882";
|
||||
private static final String URL = "https://api.mcgamerzone.net/v1";
|
||||
public static HttpClient HTTP_CLIENT;
|
||||
|
||||
static {
|
||||
HTTP_CLIENT = java.net.http.HttpClient.newBuilder()
|
||||
.version(java.net.http.HttpClient.Version.HTTP_1_1)
|
||||
.followRedirects(java.net.http.HttpClient.Redirect.NORMAL)
|
||||
.connectTimeout(Duration.ofSeconds(30L))
|
||||
.build();
|
||||
}
|
||||
|
||||
public static String filterText(@NonNull String text, @NonNull ChatFilterLevel chatFilterLevel) {
|
||||
JsonResponse jsonResponse = new JsonRequest(URL + "/filter/" + text.replaceAll(" ", "%20") + "/" + chatFilterLevel.name()).getResponse();
|
||||
JsonElement jsonElement = jsonResponse.getJsonElement();
|
||||
if (!(jsonElement instanceof JsonObject))
|
||||
return text;
|
||||
JsonObject jsonObject = (JsonObject) jsonElement;
|
||||
return jsonObject.get("value").getAsString();
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package zone.themcgamer.core.api.json;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import zone.themcgamer.core.api.WebAPI;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.time.Duration;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* @author Braydon
|
||||
*/
|
||||
@AllArgsConstructor @Slf4j(topic = "Json Request")
|
||||
public class JsonRequest {
|
||||
private final String url;
|
||||
|
||||
/**
|
||||
* Get the {@link JsonResponse} from the provided url
|
||||
*
|
||||
* @return the response
|
||||
*/
|
||||
public JsonResponse getResponse() {
|
||||
try {
|
||||
return checkResponse(WebAPI.HTTP_CLIENT.send(buildRequest(), HttpResponse.BodyHandlers.ofString()));
|
||||
} catch (IOException | InterruptedException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link JsonResponse} from the provided url asynchronously
|
||||
*
|
||||
* @param consumer the consumer the response will be accepted in
|
||||
*/
|
||||
public void getResponseAsync(Consumer<JsonResponse> consumer) {
|
||||
WebAPI.HTTP_CLIENT.sendAsync(buildRequest(), HttpResponse.BodyHandlers.ofString())
|
||||
.thenAccept(httpResponse -> consumer.accept(checkResponse(httpResponse)));
|
||||
}
|
||||
|
||||
private JsonResponse checkResponse(HttpResponse<String> httpResponse) {
|
||||
int statusCode = httpResponse.statusCode();
|
||||
if (statusCode != 200) {
|
||||
log.warn("Response from \"" + url + "\" returned status code " + statusCode + ":");
|
||||
log.warn("Body: " + httpResponse.body());
|
||||
log.warn("Headers: " + httpResponse.headers().toString());
|
||||
}
|
||||
return new JsonResponse(httpResponse);
|
||||
}
|
||||
|
||||
private HttpRequest buildRequest() {
|
||||
return HttpRequest.newBuilder()
|
||||
.GET()
|
||||
.uri(URI.create(url))
|
||||
.timeout(Duration.ofMinutes(1L))
|
||||
.header("Content-Type", "application/json")
|
||||
.header("key", WebAPI.API_KEY)
|
||||
.build();
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package zone.themcgamer.core.api.json;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.net.http.HttpResponse;
|
||||
|
||||
/**
|
||||
* This class represents a response from a {@link JsonRequest}
|
||||
*
|
||||
* @author Braydon
|
||||
*/
|
||||
@Getter
|
||||
public class JsonResponse {
|
||||
private final HttpResponse<String> httpResponse;
|
||||
private final String json;
|
||||
private final JsonElement jsonElement;
|
||||
|
||||
public JsonResponse(HttpResponse<String> httpResponse) {
|
||||
this.httpResponse = httpResponse;
|
||||
json = httpResponse.body();
|
||||
jsonElement = new JsonParser().parse(json);
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@ import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import zone.themcgamer.core.account.Account;
|
||||
import zone.themcgamer.core.account.AccountManager;
|
||||
import zone.themcgamer.core.api.WebAPI;
|
||||
import zone.themcgamer.core.badSportSystem.BadSportClient;
|
||||
import zone.themcgamer.core.badSportSystem.BadSportSystem;
|
||||
import zone.themcgamer.core.badSportSystem.Punishment;
|
||||
@ -26,6 +27,7 @@ import zone.themcgamer.core.common.Style;
|
||||
import zone.themcgamer.core.cooldown.CooldownHandler;
|
||||
import zone.themcgamer.core.module.Module;
|
||||
import zone.themcgamer.core.module.ModuleInfo;
|
||||
import zone.themcgamer.data.ChatFilterLevel;
|
||||
import zone.themcgamer.data.Rank;
|
||||
|
||||
import java.util.*;
|
||||
@ -41,19 +43,21 @@ public class ChatManager extends Module {
|
||||
@Getter private final Map<String, String> emotes = new HashMap<>();
|
||||
|
||||
{
|
||||
emotes.put("¯\\_(ツ)_/¯", ":shrug:");
|
||||
emotes.put("⊂(´・◡・⊂ )∘˚˳°", ":happyghost:");
|
||||
emotes.put("ヽ༼ຈل͜ຈ༽ノ", ":donger:");
|
||||
emotes.put("ಠ_ಠ", ":disapproval:");
|
||||
emotes.put("(≖_≖)", ":squint:");
|
||||
emotes.put("(౮⦦ʖ౮)", ":lenny:");
|
||||
emotes.put("┬─┬ ノ( ゜-゜ノ)", ":unflip:");
|
||||
emotes.put("(☞゚ヮ゚)☞", ":same:");
|
||||
emotes.put("ლ(ಥ Д ಥ )ლ", ":why:");
|
||||
emotes.put("(╯°□°)╯︵ ┻━┻", ":tableflip:");
|
||||
emotes.put("⊂(•̀_•́⊂ )∘˚˳°", ":angryghost:");
|
||||
emotes.put("( ˘ ³˘)♥", ":kiss:");
|
||||
emotes.put("༼ つ ◕_◕ ༽つ", ":ameno:");
|
||||
emotes.put(":shrug:", "¯\\_(ツ)_/¯");
|
||||
emotes.put(":happyghost:", "⊂(´・◡・⊂ )∘˚˳°");
|
||||
emotes.put(":donger:", "ヽ༼ຈل͜ຈ༽ノ");
|
||||
emotes.put(":disapproval:", "ಠ_ಠ");
|
||||
emotes.put(":squint:", "(≖_≖)");
|
||||
emotes.put(":lenny:", "(౮⦦ʖ౮)");
|
||||
emotes.put(":unflip:", "┬─┬ ノ( ゜-゜ノ)");
|
||||
emotes.put(":same:", "(☞゚ヮ゚)☞");
|
||||
emotes.put(":why:", "ლ(ಥ Д ಥ )ლ");
|
||||
emotes.put(":tableflip:", "(╯°□°)╯︵ ┻━┻");
|
||||
emotes.put(":angryghost:", "⊂(•̀_•́⊂ )∘˚˳°");
|
||||
emotes.put(":kiss:", "( ˘ ³˘)♥");
|
||||
emotes.put(":ameno:", "༼ つ ◕_◕ ༽つ");
|
||||
emotes.put(":heart:", "❤");
|
||||
emotes.put("<3", "❤");
|
||||
}
|
||||
|
||||
public ChatManager(JavaPlugin plugin, AccountManager accountManager, BadSportSystem badSportSystem, IChatComponent[] chatComponents) {
|
||||
@ -88,7 +92,11 @@ public class ChatManager extends Module {
|
||||
player.sendMessage(Style.error("Bad Sport", PunishmentCategory.format(optionalMute.get())));
|
||||
return;
|
||||
}
|
||||
// TODO: 1/26/21 filter message
|
||||
try {
|
||||
message = WebAPI.filterText(message, ChatFilterLevel.HIGH);
|
||||
} catch (Exception ex) {
|
||||
player.sendMessage(Style.error("Chat", "§cProblem filtering chat message: §f" + ex.getLocalizedMessage()));
|
||||
}
|
||||
if (message.trim().isEmpty()) {
|
||||
player.sendMessage(Style.error("Chat", "§cCannot send empty chat message"));
|
||||
return;
|
||||
@ -104,7 +112,7 @@ public class ChatManager extends Module {
|
||||
return;
|
||||
}
|
||||
for (Map.Entry<String, String> emote : emotes.entrySet())
|
||||
message = message.replace(emote.getValue(), emote.getKey());
|
||||
message = message.replace(emote.getKey(), emote.getValue());
|
||||
List<BaseComponent> components = new ArrayList<>();
|
||||
for (IChatComponent chatComponent : chatComponents) {
|
||||
BaseComponent component = chatComponent.getComponent(player);
|
||||
|
@ -21,6 +21,6 @@ public class EmotesCommand {
|
||||
Player player = command.getPlayer();
|
||||
player.sendMessage(Style.main("Chat", "Chat Emotes:"));
|
||||
for (Map.Entry<String, String> entry : chatManager.getEmotes().entrySet())
|
||||
player.sendMessage(" §6" + entry.getValue() + " §7-> §b" + entry.getKey());
|
||||
player.sendMessage(" §6" + entry.getKey() + " §7-> §b" + entry.getValue());
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package zone.themcgamer.data;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author Braydon
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum ChatFilterLevel {
|
||||
LOW(false, true),
|
||||
MEDIUM(true, true),
|
||||
HIGH(true, true);
|
||||
|
||||
private final boolean urls, ips;
|
||||
}
|
Reference in New Issue
Block a user