skidded greplogs

This commit is contained in:
ChomeNS 2023-03-28 17:25:58 +07:00
parent 2d592284ac
commit 7dcee59e43
6 changed files with 244 additions and 1 deletions

View file

@ -36,6 +36,7 @@ public class Bot {
@Getter @Setter private ConsolePlugin console;
@Getter @Setter private LoggerPlugin logger; // in ConsolePlugin
@Getter @Setter private DiscordPlugin discord;
@Getter private final ChatPlugin chat;
@Getter private final SelfCarePlugin selfCare;
@Getter private final PositionPlugin position;
@ -51,6 +52,7 @@ public class Bot {
@Getter private final ClearChatUsernamePlugin clearChatUsername;
@Getter private final TrustedPlugin trusted;
@Getter private final BruhifyPlugin bruhify;
@Getter private final GrepLogPlugin grepLog;
public Bot (String host, int port, String _username, boolean kaboom, String serverName, List<Bot> allBots, Configuration config) {
this.host = host;
@ -80,6 +82,7 @@ public class Bot {
this.clearChatUsername = new ClearChatUsernamePlugin(this);
this.trusted = new TrustedPlugin(this);
this.bruhify = new BruhifyPlugin(this);
this.grepLog = new GrepLogPlugin(this);
reconnect();
}

View file

@ -84,7 +84,7 @@ public class Logger {
}
public static synchronized void compressLogFile() throws IOException {
if (Files.size(logFile.toPath()) > 100*1024*1024) { // Will not save because log file is too big
if (Files.size(logFile.toPath()) > 100 * 1024 * 1024) { // Will not save because log file is too big
return;
}

View file

@ -0,0 +1,69 @@
package land.chipmunk.chayapak.chomens_bot.commands;
import land.chipmunk.chayapak.chomens_bot.Bot;
import land.chipmunk.chayapak.chomens_bot.command.Command;
import land.chipmunk.chayapak.chomens_bot.command.CommandContext;
import net.kyori.adventure.text.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class GrepLogCommand implements Command {
public String name() { return "greplog"; }
public String description() {
return "Queries the bot's log files";
}
public List<String> usage() {
final List<String> usages = new ArrayList<>();
usages.add("<{input}>");
usages.add("-ignorecase <{input}>");
usages.add("-regex <{input}>");
usages.add("-ignorecase -regex <{input}>");
usages.add("stop");
return usages;
}
public List<String> alias() {
final List<String> aliases = new ArrayList<>();
aliases.add("logquery");
aliases.add("greplogs");
return aliases;
}
public int trustLevel() {
return 0;
}
public Component execute(CommandContext context, String[] _args, String[] fullArgs) {
final Bot bot = context.bot();
String[] args = _args;
boolean ignoreCase = false;
boolean regex = false;
switch (_args[0]) {
case "-ignorecase" -> {
ignoreCase = true;
args = Arrays.copyOfRange(_args, 1, _args.length);
}
case "-regex" -> {
regex = true;
args = Arrays.copyOfRange(_args, 1, _args.length);
}
case "stop" -> {
bot.grepLog().thread().interrupt();
return Component.text("success");
}
}
bot.grepLog().query(String.join(" ", args), regex, ignoreCase);
return Component.text("success");
}
}

View file

@ -43,6 +43,7 @@ public class CommandHandlerPlugin {
registerCommand(new UUIDCommand());
registerCommand(new TimeCommand());
registerCommand(new BruhifyCommand());
registerCommand(new GrepLogCommand());
}
public void registerCommand (Command command) {

View file

@ -69,6 +69,8 @@ public class DiscordPlugin {
for (Bot bot : Main.allBots) {
String channelId = servers.get(bot.host() + ":" + bot.port());
bot.discord(this);
bot.addListener(new SessionAdapter() {
@Override
public void connected(ConnectedEvent event) {

View file

@ -0,0 +1,168 @@
package land.chipmunk.chayapak.chomens_bot.plugins;
import land.chipmunk.chayapak.chomens_bot.Bot;
import land.chipmunk.chayapak.chomens_bot.Logger;
import lombok.Getter;
import net.dv8tion.jda.api.entities.TextChannel;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;
public class GrepLogPlugin {
private final Bot bot;
@Getter private GrepLogThread thread = null;
public GrepLogPlugin (Bot bot) {
this.bot = bot;
}
public void query (String query, boolean regex, boolean ignoreCase) {
thread = new GrepLogThread(query, regex, ignoreCase);
thread.start();
}
// should i move this to another file or keep it here
public class GrepLogThread extends Thread {
private String query;
private final boolean regex;
private final boolean ignoreCase;
private Pattern pattern;
private boolean queryStopped = false;
private int matches = 0;
private final StringBuilder results = new StringBuilder();
public GrepLogThread(String query, boolean regex, boolean ignoreCase) {
this.regex = regex;
this.ignoreCase = ignoreCase;
this.query = query;
if (regex) {
if (ignoreCase) {
pattern = Pattern.compile(query, Pattern.CASE_INSENSITIVE);
}
else {
pattern = Pattern.compile(query);
}
} else {
if (ignoreCase) {
this.query = query.toLowerCase();
}
}
}
@Override
public void run() {
bot.chat().tellraw(
Component.translatable(
"Collecting %s in logs...",
Component.text(query).color(NamedTextColor.GOLD)
)
);
final File[] fileList = Logger.logDir.listFiles();
for (File file : fileList) {
final String fileName = file.getName();
if (fileName.matches(".*\\.txt\\.gz")) {
try (
FileInputStream fin = new FileInputStream(file);
GZIPInputStream gzin = new GZIPInputStream(fin, 65536);
BufferedReader br = new BufferedReader(new InputStreamReader(gzin, StandardCharsets.UTF_8))
) {
br.readLine();
readFile(br);
} catch (Exception ignored) {
} // TODO: Handle exception
} else {
try (
FileInputStream fin = new FileInputStream(file);
BufferedReader br = new BufferedReader(new InputStreamReader(fin, StandardCharsets.UTF_8))
) {
br.readLine();
readFile(br);
} catch (Exception ignored) {
} // TODO: Handle exception
}
if (Thread.interrupted()) {
bot.chat().tellraw(Component.text("Log query stopped"));
} else if (queryStopped) {
break;
}
}
finish();
}
private void readFile(BufferedReader br) {
String line;
try {
while ((line = br.readLine()) != null) {
if (line.length() == 0) continue;
String[] tokens = line.split("\\s+");
if (tokens.length < 3) continue; // not a valid log message
processLine(line);
}
} catch (IOException ignored) {}
}
private void processLine(String _line) {
// [day/month/year hh:mm:ss] [server:port] message
String[] tokens = _line.split("\\s+");
final String line = String.join(" ", Arrays.copyOfRange(tokens, 3, tokens.length)); // very 1 liner
if (regex) {
if (pattern.matcher(line).find()) {
match(_line);
}
} else {
if (ignoreCase) {
if (line.toLowerCase().contains(query)) {
match(_line);
}
} else {
if (line.contains(query)) {
match(_line);
}
}
}
}
private void match (String line) {
results.append(line);
results.append("\n");
matches++;
int resultsLimit = 1_000_000;
if (results.length() > resultsLimit) {
queryStopped = true;
}
}
private void finish () {
bot.chat().tellraw(
Component.translatable(
"Log query finished, found %s matches. Results were sent in Discord",
Component.text(matches).color(NamedTextColor.AQUA)
)
);
final String channelId = bot.discord().servers.get(bot.host() + ":" + bot.port());
final TextChannel logChannel = bot.discord().jda().getTextChannelById(channelId);
logChannel.sendMessage("Log query output").addFile(results.toString().getBytes(), "report.txt").queue();
}
}
}