diff options
author | David <david@panic.tk> | 2018-11-07 23:50:06 +0100 |
---|---|---|
committer | David <david@panic.tk> | 2018-11-07 23:50:06 +0100 |
commit | 604cf01967ede98bf5024e4926bb0777fc4e8eee (patch) | |
tree | e2fa63d7e683769ee3bf3eddc75280648e92eb04 /src/main/java/com/redstoner/modules/logs | |
parent | e86c52ef7c0e1e33c6af0e8674b038976bec11cc (diff) |
Converted Modules to gradle
Diffstat (limited to 'src/main/java/com/redstoner/modules/logs')
-rw-r--r-- | src/main/java/com/redstoner/modules/logs/LogEntry.java | 71 | ||||
-rw-r--r-- | src/main/java/com/redstoner/modules/logs/LogHandler.java | 200 | ||||
-rw-r--r-- | src/main/java/com/redstoner/modules/logs/Logs.cmd | 34 | ||||
-rw-r--r-- | src/main/java/com/redstoner/modules/logs/Logs.java | 157 |
4 files changed, 462 insertions, 0 deletions
diff --git a/src/main/java/com/redstoner/modules/logs/LogEntry.java b/src/main/java/com/redstoner/modules/logs/LogEntry.java new file mode 100644 index 0000000..3ccc844 --- /dev/null +++ b/src/main/java/com/redstoner/modules/logs/LogEntry.java @@ -0,0 +1,71 @@ +package com.redstoner.modules.logs; + +public class LogEntry +{ + public final int line; + public final int global_line; + public final String filename; + public final String raw; + + public LogEntry(String raw, int line, int global_line) + { + this("Unkown", raw, line, global_line); + } + + public LogEntry(String filename, String raw, int line, int global_line) + { + this.raw = resolveColors(raw); + this.line = line; + this.global_line = global_line; + this.filename = filename; + } + + public String applyFormat(String format, boolean colors) + { + // Replace escaped % with placeholder + format = format.replace("%%", "§§"); + // Line numbers + format = format.replace("%l", "" + line); + format = format.replace("%L", "" + global_line); + // Filename + format = format.replace("%f", filename); + // Strip colors + if (!colors) + format = format.replace("%r", raw.replaceAll("$.", "")); + else + format = format.replace("%r", raw); + // Convert placeholder back + format = format.replace("§§", "%"); + return format; + } + + private String resolveColors(String message) + { + message = message.replace("[0;30;22m", "§0"); + message = message.replace("[0;34;22m", "§1"); + message = message.replace("[0;32;22m", "§2"); + message = message.replace("[0;36;22m", "§3"); + message = message.replace("[0;31;22m", "§4"); + message = message.replace("[0;35;22m", "§5"); + message = message.replace("[0;33;22m", "§6"); + message = message.replace("[0;37;22m", "§7"); + message = message.replace("[0;30;1m", "§8"); + message = message.replace("[0;34;1m", "§9"); + message = message.replace("[0;32;1m", "§a"); + message = message.replace("[0;36;1m", "§b"); + message = message.replace("[0;31;1m", "§c"); + message = message.replace("[0;35;1m", "§d"); + message = message.replace("[0;33;1m", "§e"); + message = message.replace("[0;37;1m", "§f"); + + message = message.replace("[5m", "§k"); + message = message.replace("[21m", "§l"); + message = message.replace("[9m", "§m"); + message = message.replace("[4m", "§n"); + message = message.replace("[3m", "§o"); + + message = message.replace("[m", "§r"); + + return message; + } +} diff --git a/src/main/java/com/redstoner/modules/logs/LogHandler.java b/src/main/java/com/redstoner/modules/logs/LogHandler.java new file mode 100644 index 0000000..76f3849 --- /dev/null +++ b/src/main/java/com/redstoner/modules/logs/LogHandler.java @@ -0,0 +1,200 @@ +package com.redstoner.modules.logs; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileReader; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; +import java.util.zip.GZIPInputStream; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.redstoner.misc.Utils; +import com.redstoner.modules.datamanager.DataManager; + +public class LogHandler extends Thread +{ + private CommandSender sender; + private String regex, fileName; + private static ArrayList<CommandSender> stillSearching = new ArrayList<>(); + public int totalFiles = 0; + public int filesSearched = 0; + public int totalLines = 0; + public int currentLine = 0; + + protected LogHandler(CommandSender sender, String regex, String fileName) + { + this.sender = sender; + this.regex = regex; + this.fileName = fileName; + } + + public void doSearch() + { + if (stillSearching.contains(sender)) + { + Logs.logger.message(sender, true, "§4 DO NOT EVER TRY TO QUERY TWO SEARCHES AT ONCE. Go die...!"); + return; + } + stillSearching.add(sender); + this.start(); + } + + /** Searches the logs for a certain regex and forwards any matches to the sender. + * + * @param sender the issuer of the search + * @param regex the regex to search for. Will be wrapped in "^.*" and ".*$" if it is missing line delimiters + * @param fileName the name of the files to search through. May contain wildcards. */ + private void search(CommandSender sender, String regex, String fileName) + { + long starttime = System.currentTimeMillis(); + int matches = 0; + Logs.logger.message(sender, "Starting log search for &e" + regex + "&7 in &e" + fileName + + " &7now. &cPlease do not query any other searches until this one completes."); + try + { + if (!regex.startsWith("^")) + regex = "^.*" + regex; + if (!regex.endsWith("$")) + regex += ".*$"; + File logFolder = Logs.getLogsDir(); + Pattern fileNamePattern; + try + { + fileNamePattern = Pattern.compile(fileName); + } + catch (PatternSyntaxException e) + { + Logs.logger.message(sender, true, "An error occured trying to compile the filename pattern!"); + stillSearching.remove(sender); + return; + } + File[] files = logFolder.listFiles(new FilenameFilter() + { + @Override + public boolean accept(File dir, String name) + { + return fileNamePattern.matcher(name).matches(); + } + }); + totalFiles = files.length; + if (totalFiles == 0) + { + Logs.logger.message(sender, true, "No files found!"); + stillSearching.remove(sender); + return; + } + else + Logs.logger.message(sender, "A total of &e" + totalFiles + "&7 files will be searched!"); + + boolean progress = (boolean) DataManager.getOrDefault(Utils.getID(sender), "Logs", "progress", true); + Pattern searchPattern; + try + { + searchPattern = Pattern.compile(regex); + } + catch (PatternSyntaxException e) + { + Logs.logger.message(sender, true, "An error occured trying to compile the search pattern!"); + stillSearching.remove(sender); + return; + } + for (File file : files) + { + if (file.getName().endsWith(".gz")) + { + + BufferedReader inputReader = new BufferedReader( + new InputStreamReader(new GZIPInputStream(new FileInputStream(file)))); + matches += searchStream(inputReader, searchPattern, sender, file.getName()); + inputReader.close(); + } + else + { + BufferedReader inputReader = new BufferedReader(new FileReader(file)); + matches += searchStream(inputReader, searchPattern, sender, file.getName()); + inputReader.close(); + } + filesSearched++; + if (progress) + { + sender.sendMessage("§7So far, §e" + filesSearched + "§7/§e" + totalFiles + "§7 File(s) and §e" + + totalLines + "§7 Line(s) were searched."); + } + } + } + catch (Exception e) + { + Logs.logger.message(sender, true, + "An unexpected error occured, please check your search parameters and try again!"); + stillSearching.remove(sender); + return; + } + stillSearching.remove(sender); + if ((boolean) DataManager.getOrDefault(Utils.getID(sender), "Logs", "summary", true)) + { + String[] message = new String[2]; + message[0] = "§aYour search completed after " + (System.currentTimeMillis() - starttime) + "ms!"; + message[1] = "§7In total: §e" + filesSearched + "§7 File(s) and §e" + totalLines + + "§7 Line(s) were searched, §a" + matches + "§7 Match(es) were found!"; + Logs.logger.message(sender, message); + } + return; + } + + /** This function searches through an InputStream to find a regex. If it finds a match, it will forward that match to the sender and increase the match counter. + * + * @param inputReader the input reader containing the data + * @param regex the regex to search for + * @param sender the issuer of the search + * @param singleFile true if only a single file is being searched, false if the original filename contained wildcards. + * @param filename the name of the file that is currently being searched + * @return how many matches it found + * @throws IOException if something goes wrong */ + private int searchStream(BufferedReader inputReader, Pattern searchPattern, CommandSender sender, String filename) + throws IOException + { + String format = (String) DataManager.getOrDefault(Utils.getID(sender), "Logs", "format", Logs.defaultFormat); + boolean colors = (boolean) DataManager.getOrDefault(Utils.getID(sender), "Logs", "colors", true); + Player p = null; + if (sender instanceof Player) + p = (Player) sender; + int matches = 0; + String line = ""; + currentLine = 0; + while ((line = inputReader.readLine()) != null) + { + totalLines++; + currentLine++; + if (searchPattern.matcher(line).matches()) + { + if (((p != null) && (!p.isOnline()))) + { + stillSearching.remove(sender); + throw new IOException("The player has left during the search. Aborting now."); + } + LogEntry entry = new LogEntry(filename, line, currentLine, totalLines); + sender.sendMessage(entry.applyFormat(format, colors)); + matches++; + } + } + return matches; + } + + @Override + public void run() + { + try + { + search(sender, regex, fileName); + } + catch (Exception e) + {} + } +} diff --git a/src/main/java/com/redstoner/modules/logs/Logs.cmd b/src/main/java/com/redstoner/modules/logs/Logs.cmd new file mode 100644 index 0000000..c5283fe --- /dev/null +++ b/src/main/java/com/redstoner/modules/logs/Logs.cmd @@ -0,0 +1,34 @@ +command log { + perm utils.logs; + alias logs; + search [string:file(s)] [string:search...] { + run search_logs file(s) search; + help Performs the specified search operation on the logs. Wildcards are supported in filenames. Search string is a regex.; + type player; + } + format { + run show_format; + help Displays your current log output format with an example result.; + type player; + } + format_help { + run show_format_help; + help Displays all available placeholders for the formatting; + type player; + } + option_help { + run show_option_help; + help Displays all available options.; + type player; + } + set format [string:format] { + run set_format format; + help Sets a new log output format; + type player; + } + set [string:option] [boolean:state] { + run set_option option state; + help Allows you to enable or disable various features such as sumamries, live progress updates, etc...; + type player; + } +}
\ No newline at end of file diff --git a/src/main/java/com/redstoner/modules/logs/Logs.java b/src/main/java/com/redstoner/modules/logs/Logs.java new file mode 100644 index 0000000..b54bfc9 --- /dev/null +++ b/src/main/java/com/redstoner/modules/logs/Logs.java @@ -0,0 +1,157 @@ +package com.redstoner.modules.logs; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.command.CommandSender; + +import com.nemez.cmdmgr.Command; +import com.redstoner.annotations.Commands; +import com.redstoner.annotations.Version; +import com.redstoner.misc.CommandHolderType; +import com.redstoner.modules.Module; +import com.redstoner.modules.ModuleLogger; +import com.redstoner.modules.datamanager.DataManager; + +@Commands(CommandHolderType.File) +@Version(major = 4, minor = 0, revision = 4, compatible = 4) +public class Logs implements Module +{ + public static final String defaultFormat = "§7 > %f: %r"; + private final LogEntry example_1 = new LogEntry("1970-01-01-2.log.gz", + "[01:23:45] [Async Chat Thread - #1337/INFO]: §aFooBar §7→ §4THIS SERVER SUCKS", 14, 73); + private final LogEntry example_2 = new LogEntry("1970-01-01-2.log.gz", + "[01:23:45] [Server thread/INFO]: admin issued server command: /ban FooBar Ab00se", 15, 74); + protected static ModuleLogger logger; + + @Override + public void firstLoad() + { + Module.super.firstLoad(); + DataManager.setConfig("logs.root", "/etc/minecraft/redstoner/logs"); + } + + @Override + public boolean onEnable() + { + Module.super.onEnable(); + logger = getLogger(); + return true; + } + + public static File getLogsDir() + { + return new File((String) DataManager.getConfigOrDefault("logs.root", "../logs")); + } + + @Command(hook = "search_logs") + public boolean search_logs(CommandSender sender, String files, String search) + { + LogHandler handler = new LogHandler(sender, search, files); + handler.doSearch(); + return true; + } + + // FORMATTING + @Command(hook = "show_format") + public boolean show_format(CommandSender sender) + { + showExample(sender); + return true; + } + + @Command(hook = "set_format") + public boolean set_format(CommandSender sender, String format) + { + if (format.equals("--reset")) + format = defaultFormat; + format = format.replace("&", "§").replace("$$", "&"); + DataManager.setData(sender, "format", format); + showExample(sender, format); + return true; + } + + private void showExample(CommandSender sender) + { + showExample(sender, (String) DataManager.getOrDefault(sender, "format", defaultFormat)); + } + + private void showExample(CommandSender sender, String format) + { + sender.sendMessage(getLogger().getHeader()); + sender.sendMessage("Your format is: " + format); + sender.sendMessage("Here's an example of what it would look like in an actual log search:"); + boolean colors = (boolean) DataManager.getOrDefault(sender, "colors", true); + if ((boolean) DataManager.getOrDefault(sender, "progress", true)) + { + sender.sendMessage("§7So far, §e1§7/§e2§7 File(s) and §e68§7 Line(s) were searched."); + } + sender.sendMessage(example_1.applyFormat(format, colors)); + sender.sendMessage(example_2.applyFormat(format, colors)); + if ((boolean) DataManager.getOrDefault(sender, "summary", true)) + { + sender.sendMessage("§aSearch completed after 39ms!"); + sender.sendMessage( + "§7In total: §e2§7 File(s) and §e105§7 Line(s) were searched, §a2§7 Match(es) were found!"); + } + } + + @Command(hook = "show_format_help") + public boolean format_help(CommandSender sender) + { + //@noformat + String[] format_help = new String[] { + " &e%l&cine&7 -> Linenumber in the current file", + " &e%L&cine&7 -> Global linenumber (sum of all previous files + current line)", + " &e%f&cile&7 -> Complete filename", + " &e%r&caw&7 -> The raw line containing the text as it appears in the logs", + "", + " &7Use %% to gain a literal %."}; + //@format + getLogger().message(sender, format_help); + return true; + } + + // SEARCH OPTIONS + @Command(hook = "show_option_help") + public boolean show_options(CommandSender sender) + { + List<String> options = new ArrayList<>(Option.values().length + 1); + options.add("Available options are:"); + for (Option o : Option.values()) + options.add(" - " + o.toString()); + getLogger().message(sender, options.toArray(new String[] {})); + return true; + } + + @Command(hook = "set_option") + public boolean set_option(CommandSender sender, String option, boolean state) + { + option = option.toLowerCase(); + Option o = null; + try + { + o = Option.valueOf(option); + } + catch (IllegalArgumentException e) + {} + if (o == null) + { + getLogger().message(sender, true, + "Invalid option! To get a list of all available options, run &e/logs option_help"); + return true; + } + DataManager.setData(sender, option, state); + getLogger().message(sender, + "Successfully turned displaying of &e" + option + (state ? " &aon&7!" : " &coff&7!")); + return true; + } +} + +enum Option +{ + summary, + progress, + colors +} |