From d1c62eae6b021ebfaf11331f54534b32c89c4b44 Mon Sep 17 00:00:00 2001 From: MSWS Date: Thu, 31 Mar 2022 13:56:06 -0700 Subject: [PATCH 1/2] 1.3.1 Push --- pom.xml | 10 ++- .../java/xyz/msws/admintools/data/Action.java | 39 +++------ .../xyz/msws/admintools/data/DataStructs.java | 16 ++++ .../xyz/msws/admintools/data/JailAction.java | 43 ++++++++-- .../xyz/msws/admintools/data/JailRole.java | 4 +- .../xyz/msws/admintools/parsers/JBParser.java | 83 ++++++++++++------- .../msws/admintools/parsers/TTTParser.java | 1 - 7 files changed, 128 insertions(+), 68 deletions(-) diff --git a/pom.xml b/pom.xml index f855117..e99246b 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,5 @@ - + 4.0.0 xyz.msws @@ -32,5 +30,11 @@ jsoup 1.14.3 + + org.projectlombok + lombok + 1.18.22 + provided + \ No newline at end of file diff --git a/src/main/java/xyz/msws/admintools/data/Action.java b/src/main/java/xyz/msws/admintools/data/Action.java index 2fe22a2..c138596 100644 --- a/src/main/java/xyz/msws/admintools/data/Action.java +++ b/src/main/java/xyz/msws/admintools/data/Action.java @@ -3,6 +3,8 @@ import java.util.ArrayList; import java.util.List; +import lombok.Getter; +import lombok.Setter; import xyz.msws.admintools.data.DataStructs.ActionType; import xyz.msws.admintools.data.DataStructs.Role; @@ -11,12 +13,17 @@ *

* Compares by time */ -public abstract class Action implements Comparable { - ActionType type; - String player, target; - Role playerRole, targetRole; - String[] other; - String line; +public abstract class Action implements Comparable { + @Getter + protected ActionType type; + @Getter + @Setter + protected String player, target; + @Getter + @Setter + protected Role playerRole, targetRole; + protected String[] other; + protected String line; int playerRoleStart = Integer.MAX_VALUE, playerRoleEnd, targetRoleStart = -1, targetRoleEnd = -1; int playerStart, playerEnd; @@ -28,26 +35,6 @@ public Action(String line) { this.line = line; } - public String getPlayer() { - return player; - } - - public String getTarget() { - return target; - } - - public Role getPlayerRole() { - return playerRole; - } - - public Role getTargetRole() { - return targetRole; - } - - public ActionType getType() { - return type; - } - public String[] getOther() { return other; } diff --git a/src/main/java/xyz/msws/admintools/data/DataStructs.java b/src/main/java/xyz/msws/admintools/data/DataStructs.java index 1618040..722a620 100644 --- a/src/main/java/xyz/msws/admintools/data/DataStructs.java +++ b/src/main/java/xyz/msws/admintools/data/DataStructs.java @@ -5,6 +5,22 @@ public static interface ActionType { String getSummary(String... opts); } + public static enum GenericActionType implements ActionType { + DAMAGE("damaged %s (%s) for %s"), KILL("killed %s (%s)"), NADE("threw a %s"), GHOST_RESPAWN("respawned as ghost"); + + String sum; + + GenericActionType(String summary) { + this.sum = summary; + } + + @Override + public String getSummary(String... opts) { + return String.format(sum, (Object[]) opts); + } + + } + public static interface Role { String getIcon(); diff --git a/src/main/java/xyz/msws/admintools/data/JailAction.java b/src/main/java/xyz/msws/admintools/data/JailAction.java index 61f01f2..e4643cc 100644 --- a/src/main/java/xyz/msws/admintools/data/JailAction.java +++ b/src/main/java/xyz/msws/admintools/data/JailAction.java @@ -75,6 +75,8 @@ private JailActionType findActionType() { return JailActionType.KILL; } else if (line.contains("dropped the weapon")) { return JailActionType.DROP_WEAPON; + } else if (line.contains(" picked up ")) { + return JailActionType.PICKUP; } else if (line.endsWith("has been fired by an admin")) { return JailActionType.FIRE; } else if (line.endsWith("has passed warden")) { @@ -156,13 +158,31 @@ private String findTarget() { } private String[] findOther() { - switch (type) { - case KILL: - return new String[]{targetRole.getIcon()}; - case DAMAGE: - return new String[]{line.substring(line.lastIndexOf("with ") + "with ".length(), line.lastIndexOf("damage") - 1), line.substring(line.lastIndexOf("(") + 1, line.length() - 1)}; + if (type instanceof GenericActionType gType) { + switch (gType) { + case KILL: + return new String[] { targetRole.getIcon() }; + case DAMAGE: + return new String[] { + targetRole.getIcon(), + line.substring(line.lastIndexOf("with ") + "with ".length(), + line.lastIndexOf("damage") - 1), + line.substring(line.lastIndexOf("(") + 1, line.length() - 1) }; + case NADE: + return new String[] { line.substring(line.lastIndexOf(" ") + 1) }; + default: + return new String[] {}; + } + } + if (!(type instanceof JailActionType jbType)) + return new String[] { "Invalid Type" }; + String name, weapon; + switch (jbType) { case BUTTON: - String name = line.substring(line.substring(0, line.length() - 1).lastIndexOf(line.contains("pressed button 'Unknown'") ? "(" : "'", line.length() - 2) + 1, line.length() - 1); + name = line.substring( + line.substring(0, line.length() - 1).lastIndexOf( + line.contains("pressed button 'Unknown'") ? "(" : "'", line.length() - 2) + 1, + line.length() - 1); Button b = ButtonDatabase.getInstance().getButton(name); return new String[]{b.getName(), b.getAlias()}; case DROP_WEAPON: @@ -170,11 +190,18 @@ private String[] findOther() { case NADE: return new String[]{line.substring(line.lastIndexOf(" ") + 1)}; case RESKIN: - String weapon = line.substring(line.indexOf("reskinned weapon_") + "reskinned weapon_".length(), line.indexOf(" ", line.lastIndexOf("weapon_"))); + weapon = line.substring(line.indexOf("reskinned weapon_") + "reskinned weapon_".length(), + line.indexOf(" ", line.lastIndexOf("weapon_"))); if (line.endsWith("(not previously owned)")) { return new String[]{weapon, "their own"}; } - return new String[]{weapon, line.substring(line.indexOf("previous owner: ") + "previous owner: ".length(), line.length() - 1)}; + return new String[] { weapon, line + .substring(line.indexOf("previous owner: ") + "previous owner: ".length(), line.length() - 1) }; + case PICKUP: + name = line.substring(line.indexOf("picked up ") + "picked up ".length(), + line.lastIndexOf("'s ")); + weapon = line.substring(line.lastIndexOf(" ") + 1, line.length() - 1); + return new String[] { name, weapon }; default: return new String[]{}; } diff --git a/src/main/java/xyz/msws/admintools/data/JailRole.java b/src/main/java/xyz/msws/admintools/data/JailRole.java index 7f03b66..cae4aab 100644 --- a/src/main/java/xyz/msws/admintools/data/JailRole.java +++ b/src/main/java/xyz/msws/admintools/data/JailRole.java @@ -6,7 +6,7 @@ * Enum to identify a player's role on Jailbreak */ public enum JailRole implements Role { - WARDEN("W"), GUARD("G"), PRISONER("P"), REBEL("R"), SPECTATOR("S"), WORLD("World"), GHOST("Ghost"), + WARDEN("W"), GUARD("G"), PRISONER("P"), REBEL("R"), SPECTATOR("S"), WORLD("World"), GHOST("Ghost"), ST("ST"), UNKNOWN("Unknown"); private final String icon; @@ -24,7 +24,7 @@ public boolean isCT() { } public boolean isT() { - return this == PRISONER || this == REBEL; + return this == PRISONER || this == REBEL || this == ST; } public boolean isAlive() { diff --git a/src/main/java/xyz/msws/admintools/parsers/JBParser.java b/src/main/java/xyz/msws/admintools/parsers/JBParser.java index 28d38b1..77fc7c5 100644 --- a/src/main/java/xyz/msws/admintools/parsers/JBParser.java +++ b/src/main/java/xyz/msws/admintools/parsers/JBParser.java @@ -1,14 +1,26 @@ package xyz.msws.admintools.parsers; -import xyz.msws.admintools.Monitor; -import xyz.msws.admintools.data.*; -import xyz.msws.admintools.utils.MSG; - import java.io.File; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.TreeMap; import java.util.regex.Pattern; import java.util.stream.Collectors; +import xyz.msws.admintools.Monitor; +import xyz.msws.admintools.data.Button; +import xyz.msws.admintools.data.ButtonDatabase; +import xyz.msws.admintools.data.DataStructs.GenericActionType; +import xyz.msws.admintools.data.DataStructs.Role; +import xyz.msws.admintools.data.jb.JailAction; +import xyz.msws.admintools.data.jb.JailActionType; +import xyz.msws.admintools.data.jb.JailRole; +import xyz.msws.admintools.utils.MSG; + /** * Parses Jailbreak Logs */ @@ -62,6 +74,7 @@ public void parse(String line) { checkNades(); if (config.showGunPlants()) checkGuns(); + checkST(); checkSpectator(); jbActions.clear(); lines.clear(); @@ -263,34 +276,32 @@ private void checkNades() { * Checks if a CT drops a gun and a T uses the same type of gun soon after */ private void checkGuns() { - - List guns = jbActions.stream() - .filter(act -> act.getType() == JailActionType.DROP_WEAPON && act.getPlayerRole().isCT()) + List pickups = jbActions.stream() + .filter(act -> act.getType() == JailActionType.PICKUP && act.getPlayerRole().isT()) .collect(Collectors.toList()); - Iterator it = guns.iterator(); - while (it.hasNext()) { - JailAction drop = it.next(); + for (JailAction pickup : pickups) { + JailAction known = jbActions.stream().filter(a -> a.getPlayer().equals(pickup.getOther()[0])).findFirst() + .orElse(null); + if (known == null) + continue; + Role dropRole = known.getPlayerRole(); + if (!dropRole.isCT()) + continue; + JailAction firstDrop = jbActions.stream() + .filter(a -> a.getType() == JailActionType.DROP_WEAPON && a.getPlayer().equals(known.getPlayer()) + && a.getOther()[0].equals(pickup.getOther()[1])) + .findFirst().orElse(null); + if (firstDrop == null) { + continue; + } JailAction death = jbActions.stream() - .filter(a -> a.getType() == JailActionType.KILL && a.getTarget().equals(drop.getPlayer())) + .filter(a -> a.getType() == GenericActionType.KILL && a.getTarget().equals(known.getPlayer())) .findFirst().orElse(null); - if (death == null) + if (death.getTime() == firstDrop.getTime()) { continue; - if (death.getTime() == drop.getTime() || death.getTime() + 1 == drop.getTime()) - it.remove(); - } - - for (JailAction act : jbActions.stream() - .filter(act -> act.getType() == JailActionType.DAMAGE && act.getPlayerRole().isT()) - .collect(Collectors.toList())) { - List ds = guns.stream() - .filter(p -> p.getTime() <= act.getTime() && p.getTime() > act.getTime() - config.getGunTimeout() - && p.getOther()[0].equals(act.getOther()[1])) - .collect(Collectors.toList()); - for (JailAction p : ds) { - print("\nGun Plants"); - print(p.simplify() + " and " + act.getPlayer() + " (" + act.getPlayerRole().getIcon() - + ") used one shortly after"); } + print("\nGunplants"); + print(pickup.simplify() + ", dropped at " + firstDrop.getTimeString()); } } @@ -307,6 +318,22 @@ private void checkSpectator() { } } + /** + * Checks is a CT killed an ST + */ + private void checkST() { + List kills = jbActions.stream() + .filter(act -> act.getType() == GenericActionType.KILL && act.getTargetRole() == JailRole.ST + && act.getPlayerRole().isCT()) + .collect(Collectors.toList()); + if (kills.isEmpty()) + return; + for (JailAction kill : kills) { + print("\nST Kills"); + print(kill.simplify()); + } + } + /** * Returns true if CTs should not be shooting prisoners during this time * diff --git a/src/main/java/xyz/msws/admintools/parsers/TTTParser.java b/src/main/java/xyz/msws/admintools/parsers/TTTParser.java index 4308f9f..6c60806 100644 --- a/src/main/java/xyz/msws/admintools/parsers/TTTParser.java +++ b/src/main/java/xyz/msws/admintools/parsers/TTTParser.java @@ -13,5 +13,4 @@ public void parse(String line) { } - } From fafc224b2024c3ab8576fe49fb2e7f6ed3a493dc Mon Sep 17 00:00:00 2001 From: MSWS Date: Thu, 31 Mar 2022 14:10:07 -0700 Subject: [PATCH 2/2] Merge 1.3.1 --- .../java/xyz/msws/admintools/Monitor.java | 24 ++- .../java/xyz/msws/admintools/data/Action.java | 13 +- .../java/xyz/msws/admintools/data/Config.java | 23 ++- .../xyz/msws/admintools/data/FileConfig.java | 28 ++- .../msws/admintools/data/JailActionType.java | 20 --- .../admintools/data/{ => jb}/JailAction.java | 72 ++++---- .../admintools/data/jb/JailActionType.java | 22 +++ .../admintools/data/{ => jb}/JailRole.java | 2 +- .../msws/admintools/data/ttt/TTTAction.java | 162 ++++++++++++++++++ .../admintools/data/ttt/TTTActionType.java | 21 +++ .../xyz/msws/admintools/data/ttt/TTTRole.java | 30 ++++ .../xyz/msws/admintools/parsers/JBParser.java | 14 +- .../msws/admintools/parsers/TTTParser.java | 110 +++++++++++- 13 files changed, 452 insertions(+), 89 deletions(-) delete mode 100644 src/main/java/xyz/msws/admintools/data/JailActionType.java rename src/main/java/xyz/msws/admintools/data/{ => jb}/JailAction.java (80%) create mode 100644 src/main/java/xyz/msws/admintools/data/jb/JailActionType.java rename src/main/java/xyz/msws/admintools/data/{ => jb}/JailRole.java (94%) create mode 100644 src/main/java/xyz/msws/admintools/data/ttt/TTTAction.java create mode 100644 src/main/java/xyz/msws/admintools/data/ttt/TTTActionType.java create mode 100644 src/main/java/xyz/msws/admintools/data/ttt/TTTRole.java diff --git a/src/main/java/xyz/msws/admintools/Monitor.java b/src/main/java/xyz/msws/admintools/Monitor.java index e9fb685..a8f7a09 100644 --- a/src/main/java/xyz/msws/admintools/Monitor.java +++ b/src/main/java/xyz/msws/admintools/Monitor.java @@ -5,6 +5,7 @@ import xyz.msws.admintools.parsers.JBParser; import xyz.msws.admintools.parsers.Parser; import xyz.msws.admintools.parsers.PlaytimeParser; +import xyz.msws.admintools.parsers.TTTParser; import java.io.File; import java.io.FileWriter; @@ -33,6 +34,8 @@ public Monitor() { parsers.add(new PlaytimeParser(this)); if (config.doJailbreak()) parsers.add(new JBParser(this)); + if (config.doTTT()) + parsers.add(new TTTParser(this)); timer.schedule(this, 0, config.getRate()); } @@ -82,13 +85,16 @@ private boolean setupFiles() { } // Drive Specific - directories.add(master.getAbsolutePath().charAt(0) + ":\\Program Files (x86)\\Steam\\steamapps\\common\\Counter-Strike Global Offensive\\csgo"); - directories.add(master.getAbsolutePath().charAt(0) + ":\\Program Files\\Steam\\steamapps\\common\\Counter-Strike Global Offensive\\csgo"); + directories.add(master.getAbsolutePath().charAt(0) + + ":\\Program Files (x86)\\Steam\\steamapps\\common\\Counter-Strike Global Offensive\\csgo"); + directories.add(master.getAbsolutePath().charAt(0) + + ":\\Program Files\\Steam\\steamapps\\common\\Counter-Strike Global Offensive\\csgo"); // Default Computer directories.add("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Counter-Strike Global Offensive\\csgo"); directories.add("C:\\Program Files\\Steam\\steamapps\\common\\Counter-Strike Global Offensive\\csgo"); - directories.add("C:\\Program Files\\Steam\\steamapps\\common\\Counter-Strike Global Offensive\\csgo\\output.log"); + directories + .add("C:\\Program Files\\Steam\\steamapps\\common\\Counter-Strike Global Offensive\\csgo\\output.log"); // Mac directories.add("~/Library/Application Support/Steam/steamapps/common/Counter-Strike Global Offensive/csgo"); @@ -97,8 +103,10 @@ private boolean setupFiles() { directories.add("~/.steam/steam/SteamApps/common/Counter-Strike Global Offensive/csgo"); for (int i = 'A'; i <= 'Z'; i++) { - directories.add((char) i + ":\\Program Files (x86)\\Steam\\steamapps\\common\\Counter-Strike Global Offensive\\csgo"); - directories.add((char) i + ":\\Program Files\\Steam\\steamapps\\common\\Counter-Strike Global Offensive\\csgo"); + directories.add((char) i + + ":\\Program Files (x86)\\Steam\\steamapps\\common\\Counter-Strike Global Offensive\\csgo"); + directories.add( + (char) i + ":\\Program Files\\Steam\\steamapps\\common\\Counter-Strike Global Offensive\\csgo"); } File parent = null; @@ -112,7 +120,8 @@ private boolean setupFiles() { } } if (!parent.exists()) { - System.out.println("Could not locate CS:GO directory. Please specify the proper directory in the settings.txt"); + System.out.println( + "Could not locate CS:GO directory. Please specify the proper directory in the settings.txt"); return false; } @@ -154,7 +163,8 @@ private boolean setupFiles() { System.out.println("Supplied path is a folder, searching for " + logFile); output = new File(output, logFile); if (!output.exists()) - output = new File("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Counter-Strike Global Offensive\\csgo\\output.log"); + output = new File( + "C:\\Program Files (x86)\\Steam\\steamapps\\common\\Counter-Strike Global Offensive\\csgo\\output.log"); } if (!output.exists()) { output = new File(parent, logFile); diff --git a/src/main/java/xyz/msws/admintools/data/Action.java b/src/main/java/xyz/msws/admintools/data/Action.java index c138596..deecc0a 100644 --- a/src/main/java/xyz/msws/admintools/data/Action.java +++ b/src/main/java/xyz/msws/admintools/data/Action.java @@ -7,6 +7,7 @@ import lombok.Setter; import xyz.msws.admintools.data.DataStructs.ActionType; import xyz.msws.admintools.data.DataStructs.Role; +import xyz.msws.admintools.data.jb.JailRole; /** * Represents a line in Jailbreak Logs @@ -25,11 +26,11 @@ public abstract class Action implements Comparable { protected String[] other; protected String line; - int playerRoleStart = Integer.MAX_VALUE, playerRoleEnd, targetRoleStart = -1, targetRoleEnd = -1; - int playerStart, playerEnd; - int targetStart, targetEnd; + protected int playerRoleStart = Integer.MAX_VALUE, playerRoleEnd, targetRoleStart = -1, targetRoleEnd = -1; + protected int playerStart, playerEnd; + protected int targetStart, targetEnd; - long time; + protected long time; public Action(String line) { this.line = line; @@ -45,7 +46,7 @@ public String getLine() { public String simplify() { String[] opts; - if (target.isEmpty()) { + if (target == null || target.isEmpty()) { opts = other; } else { List s = new ArrayList<>(); @@ -68,7 +69,7 @@ public String getTimeString() { } @Override - public int compareTo(JailAction o) { + public int compareTo(Action o) { return (int) (this.getTime() - o.getTime()); } } diff --git a/src/main/java/xyz/msws/admintools/data/Config.java b/src/main/java/xyz/msws/admintools/data/Config.java index 5fc69eb..a0c46bf 100644 --- a/src/main/java/xyz/msws/admintools/data/Config.java +++ b/src/main/java/xyz/msws/admintools/data/Config.java @@ -1,8 +1,13 @@ package xyz.msws.admintools.data; -import xyz.msws.admintools.utils.Convert; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; -import java.util.EnumSet; +import xyz.msws.admintools.data.DataStructs.ActionType; +import xyz.msws.admintools.data.DataStructs.GenericActionType; +import xyz.msws.admintools.data.jb.JailActionType; +import xyz.msws.admintools.utils.Convert; /** * Represents the configurable values that the user can specify @@ -14,10 +19,12 @@ public abstract class Config { protected String header = ""; protected String outputPath = null, apiKey = null, clonePath = null; protected String webId = ""; - protected EnumSet actions = EnumSet.of(JailActionType.KILL, JailActionType.WARDEN, JailActionType.WARDEN_DEATH, JailActionType.FIRE, JailActionType.PASS, JailActionType.RESKIN); + protected Set actions = new HashSet<>(Arrays.asList(GenericActionType.KILL, JailActionType.WARDEN, + JailActionType.WARDEN_DEATH, JailActionType.FIRE, JailActionType.PASS, JailActionType.RESKIN)); protected int gunTimeout = 10, buttonTimeout = 5, nadeTimeout = 10, wardenTimeout = 5, freeTime = 10; - protected boolean showEarlyVents = true, showEarlyKills = true, showGameButtons = true, showNades = true, showGunPlants = true; - protected boolean doJailbreak = true, doPlaytime = true; + protected boolean showEarlyVents = true, showEarlyKills = true, showGameButtons = true, showNades = true, + showGunPlants = true; + protected boolean doJailbreak = true, doPlaytime = true, doTTT = true; protected boolean cacheGametimes = true, requestGametimes = true; protected int appId = 730; protected Convert.TimeUnit limitPlaytime = Convert.TimeUnit.YEARS; @@ -38,6 +45,10 @@ public boolean doJailbreak() { return doJailbreak; } + public boolean doTTT() { + return doJailbreak; + } + public boolean doPlaytime() { return doPlaytime; } @@ -54,7 +65,7 @@ public int getAppId() { return appId; } - public EnumSet getActions() { + public Set getActions() { return actions; } diff --git a/src/main/java/xyz/msws/admintools/data/FileConfig.java b/src/main/java/xyz/msws/admintools/data/FileConfig.java index 104bac9..edc00a9 100644 --- a/src/main/java/xyz/msws/admintools/data/FileConfig.java +++ b/src/main/java/xyz/msws/admintools/data/FileConfig.java @@ -1,5 +1,9 @@ package xyz.msws.admintools.data; +import xyz.msws.admintools.data.DataStructs.ActionType; +import xyz.msws.admintools.data.DataStructs.GenericActionType; +import xyz.msws.admintools.data.jb.JailActionType; +import xyz.msws.admintools.data.ttt.TTTActionType; import xyz.msws.admintools.utils.Convert; import xyz.msws.admintools.utils.Utils; @@ -52,8 +56,26 @@ public FileConfig(File file) { } else if (line.startsWith("showTypes=")) { String[] acts = getValue(line, "showTypes=").split(","); actions.clear(); - for (String s : acts) - actions.add(JailActionType.valueOf(s.toUpperCase())); + for (String s : acts) { + ActionType type = null; + try { + type = GenericActionType.valueOf(s.toUpperCase()); + } catch (IllegalArgumentException e1) { + try { + type = JailActionType.valueOf(s.toUpperCase()); + } catch (IllegalArgumentException e2) { + try { + type = TTTActionType.valueOf(s.toUpperCase()); + } catch (IllegalArgumentException e3) { + } + } + } + if (type == null) { + System.out.println("Invalid action type: " + s); + continue; + } + actions.add(type); + } } else if (line.startsWith("gundropTimeout=")) { gunTimeout = getValue(line, "gundropTimeout=", Integer.class); } else if (line.startsWith("nadeTimeout=")) { @@ -76,6 +98,8 @@ public FileConfig(File file) { freeTime = getValue(line, "freeTime=", Integer.class); } else if (line.startsWith("doJailbreak=")) { doJailbreak = getValue(line, "doJailbreak=", Boolean.class); + } else if (line.startsWith("doTTT=")) { + doTTT = getValue(line, "doTTT=", Boolean.class); } else if (line.startsWith("cacheGametimes=")) { cacheGametimes = getValue(line, "cacheGametimes=", Boolean.class); } else if (line.startsWith("requestGametimes=")) { diff --git a/src/main/java/xyz/msws/admintools/data/JailActionType.java b/src/main/java/xyz/msws/admintools/data/JailActionType.java deleted file mode 100644 index e874a4c..0000000 --- a/src/main/java/xyz/msws/admintools/data/JailActionType.java +++ /dev/null @@ -1,20 +0,0 @@ -package xyz.msws.admintools.data; - -/** - * Represents an action that a player can make on Jailbreak - */ -public enum JailActionType { - DAMAGE("damaged %s for %s"), KILL("killed %s (%s)"), BUTTON("pressed %s (%s)"), WARDEN("took warden"), VENTS("broke vents"), - DROP_WEAPON("dropped a(n) %s"), NADE("threw a(n) %s"), WARDEN_DEATH("died as warden"), PASS("passed warden"), FIRE("was fired"), - RESKIN("reskinned %2$s's %1$s"), GHOST_RESPAWN("respawned as ghost"); - - private final String sum; - - JailActionType(String summary) { - this.sum = summary; - } - - public String getSummary(String... objects) { - return String.format(sum, (Object[]) objects); - } -} diff --git a/src/main/java/xyz/msws/admintools/data/JailAction.java b/src/main/java/xyz/msws/admintools/data/jb/JailAction.java similarity index 80% rename from src/main/java/xyz/msws/admintools/data/JailAction.java rename to src/main/java/xyz/msws/admintools/data/jb/JailAction.java index e4643cc..b99e161 100644 --- a/src/main/java/xyz/msws/admintools/data/JailAction.java +++ b/src/main/java/xyz/msws/admintools/data/jb/JailAction.java @@ -1,28 +1,23 @@ -package xyz.msws.admintools.data; +package xyz.msws.admintools.data.jb; import java.util.ArrayList; import java.util.List; +import xyz.msws.admintools.data.Action; +import xyz.msws.admintools.data.Button; +import xyz.msws.admintools.data.ButtonDatabase; +import xyz.msws.admintools.data.DataStructs.ActionType; +import xyz.msws.admintools.data.DataStructs.GenericActionType; +import xyz.msws.admintools.data.DataStructs.Role; + /** * Represents a line in Jailbreak Logs *

* Compares by time */ -public class JailAction implements Comparable { - private JailActionType type; - private String player, target; - private JailRole playerRole, targetRole; - private String[] other; - private String line; - - private int playerRoleStart = Integer.MAX_VALUE, playerRoleEnd, targetRoleStart = -1, targetRoleEnd = -1; - private int playerStart, playerEnd; - private int targetStart, targetEnd; - - private long time; - +public class JailAction extends Action { public JailAction(String line) { - this.line = line; + super(line); this.type = findActionType(); calculateIndices(); @@ -42,15 +37,15 @@ public String getTarget() { return target; } - public JailRole getPlayerRole() { + public Role getPlayerRole() { return playerRole; } - public JailRole getTargetRole() { + public Role getTargetRole() { return targetRole; } - public JailActionType getType() { + public ActionType getType() { return type; } @@ -58,21 +53,22 @@ public String[] getOther() { return other; } - private JailActionType findActionType() { + private ActionType findActionType() { if (line.endsWith("is now warden")) { return JailActionType.WARDEN; } else if (line.endsWith("broke a vent or wall")) { return JailActionType.VENTS; } else if (line.contains(") pressed button '")) { return JailActionType.BUTTON; - } else if (line.contains("threw a") && (line.endsWith("smoke") || line.endsWith("grenade") || line.endsWith("flash") || line.endsWith("decoy") || line.endsWith("molotov"))) { - return JailActionType.NADE; + } else if (line.contains("threw a") && (line.endsWith("smoke") || line.endsWith("grenade") + || line.endsWith("flash") || line.endsWith("decoy") || line.endsWith("molotov"))) { + return GenericActionType.NADE; } else if (line.contains("hurt") && line.contains("with") && line.contains("damage (")) { - return JailActionType.DAMAGE; + return GenericActionType.DAMAGE; } else if (line.contains("has died and is no longer warden")) { return JailActionType.WARDEN_DEATH; } else if (line.contains("killed ")) { - return JailActionType.KILL; + return GenericActionType.KILL; } else if (line.contains("dropped the weapon")) { return JailActionType.DROP_WEAPON; } else if (line.contains(" picked up ")) { @@ -84,7 +80,7 @@ private JailActionType findActionType() { } else if (line.contains("reskinned weapon_")) { return JailActionType.RESKIN; } else if (line.contains("was respawned for touching")) { - return JailActionType.GHOST_RESPAWN; + return GenericActionType.GHOST_RESPAWN; } else if (line.endsWith("has disconnected, passing warden")) { return JailActionType.PASS; } else if (line.contains("broke '")) { @@ -102,7 +98,8 @@ private void calculateIndices() { } else if (role == JailRole.WORLD) { index = line.toUpperCase().indexOf((role.toString())); } else { - index = line.indexOf("(" + role.toString().charAt(0) + role.toString().substring(1).toLowerCase() + ")") + 1; + index = line.indexOf("(" + role.toString().charAt(0) + role.toString().substring(1).toLowerCase() + ")") + + 1; } if (index <= 0 || index > playerRoleStart) @@ -126,12 +123,13 @@ private void calculateIndices() { playerStart = 8; playerEnd = playerRoleStart - (world ? -5 : 2); - if (type != JailActionType.DAMAGE && type != JailActionType.KILL) + if (type != GenericActionType.DAMAGE && type != GenericActionType.KILL) return; for (JailRole role : JailRole.values()) { -// int index = line.toUpperCase().lastIndexOf("(" + role.toString() + ")") + 1; - int index = role == JailRole.WARDEN ? line.toUpperCase().lastIndexOf(role.toString()) : (line.toUpperCase().lastIndexOf("(" + role + ")") + 1); + // int index = line.toUpperCase().lastIndexOf("(" + role.toString() + ")") + 1; + int index = role == JailRole.WARDEN ? line.toUpperCase().lastIndexOf(role.toString()) + : (line.toUpperCase().lastIndexOf("(" + role + ")") + 1); if (index <= 0 || index == playerRoleStart) continue; @@ -141,7 +139,8 @@ private void calculateIndices() { break; } - String damageLine = line.substring(playerRoleEnd + (world ? 1 : 2), line.indexOf(" ", playerRoleEnd + (world ? 1 : 2))); + String damageLine = line.substring(playerRoleEnd + (world ? 1 : 2), + line.indexOf(" ", playerRoleEnd + (world ? 1 : 2))); targetStart = playerRoleEnd + (world ? 2 : 3) + damageLine.length(); targetEnd = targetRoleStart - 2; @@ -184,16 +183,14 @@ private String[] findOther() { line.contains("pressed button 'Unknown'") ? "(" : "'", line.length() - 2) + 1, line.length() - 1); Button b = ButtonDatabase.getInstance().getButton(name); - return new String[]{b.getName(), b.getAlias()}; + return new String[] { b.getName(), b.getAlias() }; case DROP_WEAPON: - return new String[]{line.substring(line.lastIndexOf(" ") + 1, line.length() - 1)}; - case NADE: - return new String[]{line.substring(line.lastIndexOf(" ") + 1)}; + return new String[] { line.substring(line.lastIndexOf(" ") + 1, line.length() - 1) }; case RESKIN: weapon = line.substring(line.indexOf("reskinned weapon_") + "reskinned weapon_".length(), line.indexOf(" ", line.lastIndexOf("weapon_"))); if (line.endsWith("(not previously owned)")) { - return new String[]{weapon, "their own"}; + return new String[] { weapon, "their own" }; } return new String[] { weapon, line .substring(line.indexOf("previous owner: ") + "previous owner: ".length(), line.length() - 1) }; @@ -203,7 +200,7 @@ private String[] findOther() { weapon = line.substring(line.lastIndexOf(" ") + 1, line.length() - 1); return new String[] { name, weapon }; default: - return new String[]{}; + return new String[] {}; } } @@ -240,9 +237,4 @@ public long getTime() { public String getTimeString() { return String.format("%02d:%02d", (int) Math.floor((float) time / 60), time % 60); } - - @Override - public int compareTo(JailAction o) { - return (int) (this.getTime() - o.getTime()); - } } diff --git a/src/main/java/xyz/msws/admintools/data/jb/JailActionType.java b/src/main/java/xyz/msws/admintools/data/jb/JailActionType.java new file mode 100644 index 0000000..3678c4d --- /dev/null +++ b/src/main/java/xyz/msws/admintools/data/jb/JailActionType.java @@ -0,0 +1,22 @@ +package xyz.msws.admintools.data.jb; + +import xyz.msws.admintools.data.DataStructs.ActionType; + +/** + * Represents an action that a player can make on Jailbreak + */ +public enum JailActionType implements ActionType { + BUTTON("pressed %s (%s)"), WARDEN("took warden"), + VENTS("broke vents"), DROP_WEAPON("dropped a(n) %s"), WARDEN_DEATH("died as warden"), PASS("passed warden"), + FIRE("was fired"), RESKIN("reskinned %2$s's %1$s"), PICKUP("picked up %s's %s"); + + private final String sum; + + JailActionType(String summary) { + this.sum = summary; + } + + public String getSummary(String... objects) { + return String.format(sum, (Object[]) objects); + } +} diff --git a/src/main/java/xyz/msws/admintools/data/JailRole.java b/src/main/java/xyz/msws/admintools/data/jb/JailRole.java similarity index 94% rename from src/main/java/xyz/msws/admintools/data/JailRole.java rename to src/main/java/xyz/msws/admintools/data/jb/JailRole.java index cae4aab..d767300 100644 --- a/src/main/java/xyz/msws/admintools/data/JailRole.java +++ b/src/main/java/xyz/msws/admintools/data/jb/JailRole.java @@ -1,4 +1,4 @@ -package xyz.msws.admintools.data; +package xyz.msws.admintools.data.jb; import xyz.msws.admintools.data.DataStructs.Role; diff --git a/src/main/java/xyz/msws/admintools/data/ttt/TTTAction.java b/src/main/java/xyz/msws/admintools/data/ttt/TTTAction.java new file mode 100644 index 0000000..810eadb --- /dev/null +++ b/src/main/java/xyz/msws/admintools/data/ttt/TTTAction.java @@ -0,0 +1,162 @@ +package xyz.msws.admintools.data.ttt; + +import xyz.msws.admintools.data.Action; +import xyz.msws.admintools.data.DataStructs.ActionType; +import xyz.msws.admintools.data.DataStructs.GenericActionType; + +public class TTTAction extends Action { + public TTTAction(String line) { + super(line); + + this.type = findActionType(); + calculateIndices(); + + this.player = findPlayer(); + this.target = findTarget(); + this.other = findOther(); + } + + private ActionType findActionType() { + if (line.contains("threw a") && (line.endsWith("smoke") || line.endsWith("grenade") + || line.endsWith("flash") || line.endsWith("decoy") || line.endsWith("molotov"))) { + return GenericActionType.NADE; + } else if (line.contains("killed ")) { + return this.isBadAction() ? TTTActionType.BAD_KILL : GenericActionType.KILL; + } else if (line.contains("damaged") && line.contains("for") && line.contains("with")) { + return this.isBadAction() ? TTTActionType.BAD_DAMAGE : GenericActionType.DAMAGE; + } else if (line.contains("identified body of")) { + return TTTActionType.IDENTIFY; + } else if (line.contains("purchased an item from the shop:")) { + return TTTActionType.SHOP; + } else if (line.contains("used traitor secret:")) { + return TTTActionType.T_SECRET; + } else if (line.contains("scanned a body, Killer was")) { + return TTTActionType.DNA; + } else if (line.contains("was tased by")) { + return TTTActionType.TAZE; + } + + throw new IllegalArgumentException("Invalid line: " + line); + } + + private void calculateIndices() { + for (TTTRole role : TTTRole.values()) { + int index = line.toUpperCase().indexOf("(" + role.toString() + ")"); + if (index != -1) { + index++; + } else if (role == TTTRole.WORLD) { + index = line.toUpperCase().indexOf((role.toString())); + } else { + index = line.indexOf("(" + role.toString().charAt(0) + role.toString().substring(1).toLowerCase() + ")") + + 1; + } + + if (index <= 0 || index > playerRoleStart) + continue; + if (role == TTTRole.WORLD) { + playerRoleStart = index; + playerRoleEnd = playerRoleStart + "The World".length(); + playerRole = TTTRole.WORLD; + } else { + playerRoleStart = index; + playerRoleEnd = playerRoleStart + role.toString().length(); + playerRole = TTTRole.valueOf(line.substring(playerRoleStart, playerRoleEnd).toUpperCase()); + } + } + + if (playerRole == null) { + System.out.println("Unknown line: " + line); + return; + } + boolean world = playerRole == TTTRole.WORLD; + + playerStart = 12; + playerEnd = playerRoleStart - (world ? -5 : 2); + + if (type != GenericActionType.DAMAGE && type != GenericActionType.KILL && type != TTTActionType.BAD_DAMAGE + && type != TTTActionType.BAD_KILL) + return; + + for (TTTRole role : TTTRole.values()) { + int index = line.toUpperCase().lastIndexOf("(" + role + ")") + 1; + + if (index <= 0 || index == playerRoleStart) + continue; + targetRoleStart = index; + targetRoleEnd = targetRoleStart + role.toString().length(); + targetRole = TTTRole.valueOf(line.substring(targetRoleStart, targetRoleEnd).toUpperCase()); + break; + } + + String damageLine = line.substring(playerRoleEnd + (world ? 1 : 2), + line.indexOf(" ", playerRoleEnd + (world ? 1 : 2))); + + targetStart = playerRoleEnd + (world ? 2 : 3) + damageLine.length(); + targetEnd = targetRoleStart - 2; + } + + private String findPlayer() { + return line.substring(playerStart, playerEnd); + } + + private String findTarget() { + if (targetStart == -1 || targetEnd == -1) + return null; + return line.substring(targetStart, targetEnd); + } + + private String[] findOther() { + if (type instanceof GenericActionType gType) { + switch (gType) { + case KILL: + return new String[] { targetRole.getIcon() }; + case DAMAGE: + return new String[] { + targetRole.getIcon(), + line.substring(line.lastIndexOf(") for ") + ") for ".length(), + line.lastIndexOf(" damage ") - 1), + line.substring(line.lastIndexOf(" ") + 1, line.length() - 1) }; + case NADE: + return new String[] { line.substring(line.lastIndexOf(" ") + 1) }; + default: + return new String[] {}; + } + } + if (!(type instanceof TTTActionType tttType)) + return new String[] { "Invalid Type" }; + switch (tttType) { + case BAD_KILL: + return new String[] { targetRole.getIcon() }; + case BAD_DAMAGE: + return new String[] { + targetRole.getIcon(), + line.substring(line.lastIndexOf(") for ") + ") for ".length(), + line.lastIndexOf(" damage ") - 1), + line.substring(line.lastIndexOf(" ") + 1, line.length() - 1) }; + case IDENTIFY: + return new String[] { + line.substring(line.lastIndexOf("identified body of ") + "identified body of ".length(), + line.lastIndexOf("(") - 1) }; + case DNA: + return new String[] { line.substring( + line.indexOf("scanned a body, Killer was ") + "scanned a body, Killer was ".length(), + line.lastIndexOf("(") - 1) }; + case SHOP: + return new String[] { + line.substring(line.lastIndexOf("shop: ") + "shop: ".length(), line.length() - 1) }; + case T_SECRET: + return new String[] { + line.substring(line.lastIndexOf("traitor secret: ") + "traitor secret: ".length(), + line.length() - 1) }; + case TAZE: + return new String[] { line.substring(line.lastIndexOf("was tased by ") + "was tased by ".length(), + line.length() - 1) }; + default: + return new String[] {}; + } + } + + public boolean isBadAction() { + return line.endsWith("BAD ACTION"); + } +} diff --git a/src/main/java/xyz/msws/admintools/data/ttt/TTTActionType.java b/src/main/java/xyz/msws/admintools/data/ttt/TTTActionType.java new file mode 100644 index 0000000..ac4cfb9 --- /dev/null +++ b/src/main/java/xyz/msws/admintools/data/ttt/TTTActionType.java @@ -0,0 +1,21 @@ +package xyz.msws.admintools.data.ttt; + +import xyz.msws.admintools.data.DataStructs.ActionType; + +public enum TTTActionType implements ActionType { + IDENTIFY("found %s's body"), DNA("DNA'd %s's body"), + SHOP("bought %s"), T_SECRET("activated %s"), TAZE("tazed %s"), BAD_KILL("killed %s (%s)"), + BAD_DAMAGE("damaged %s (%s)"); + + private final String sum; + + TTTActionType(String summary) { + this.sum = summary; + } + + @Override + public String getSummary(String... opts) { + return String.format(sum, (Object[]) opts); + } + +} diff --git a/src/main/java/xyz/msws/admintools/data/ttt/TTTRole.java b/src/main/java/xyz/msws/admintools/data/ttt/TTTRole.java new file mode 100644 index 0000000..8c3d4cf --- /dev/null +++ b/src/main/java/xyz/msws/admintools/data/ttt/TTTRole.java @@ -0,0 +1,30 @@ +package xyz.msws.admintools.data.ttt; + +import xyz.msws.admintools.data.DataStructs.Role; + +public enum TTTRole implements Role { + INNOCENT("I"), TRAITOR("T"), DETECTIVE("D"), SPECTATOR("S"), WORLD("World"), GHOST("Ghost"), + UNKNOWN("Unknown"); + + private final String icon; + + TTTRole(String icon) { + this.icon = icon; + } + + public String getIcon() { + return icon; + } + + public boolean isCT() { + return this == DETECTIVE; + } + + public boolean isT() { + return this == TRAITOR || this == INNOCENT; + } + + public boolean isAlive() { + return isCT() || isT(); + } +} diff --git a/src/main/java/xyz/msws/admintools/parsers/JBParser.java b/src/main/java/xyz/msws/admintools/parsers/JBParser.java index 77fc7c5..0419852 100644 --- a/src/main/java/xyz/msws/admintools/parsers/JBParser.java +++ b/src/main/java/xyz/msws/admintools/parsers/JBParser.java @@ -32,7 +32,7 @@ public class JBParser extends Parser { private final Pattern pattern = Pattern.compile("^\\[\\d\\d:\\d\\d]\s"); // Matches the timecode prefix of jailbreak // logs - boolean parse = false; + private boolean parse = false; public JBParser(Monitor monitor) { super(monitor); @@ -111,7 +111,9 @@ private void checkFreekills() { .collect(Collectors.toList()); TreeMap cease = new TreeMap<>(); for (JailAction act : allWarden) { - switch (act.getType()) { + if (!(act.getType() instanceof JailActionType jbType)) + continue; + switch (jbType) { case WARDEN -> cease.put(act.getTime() + config.getWardenTimeout(), false); case WARDEN_DEATH -> cease.put(act.getTime(), true); case FIRE, PASS -> { @@ -137,7 +139,7 @@ private void checkFreekills() { if (act.getTargetRole() != null && act.getTargetRole().isCT()) cts.add(act.getTarget()); } - List deaths = jbActions.stream().filter(act -> act.getType() == JailActionType.KILL) + List deaths = jbActions.stream().filter(act -> act.getType() == GenericActionType.KILL) .collect(Collectors.toList()); if (!deaths.isEmpty()) { boolean ctWin = deaths.get(deaths.size() - 1).getPlayerRole().isCT(); @@ -168,7 +170,7 @@ private void checkFreekills() { } List badCombat = jbActions.stream() - .filter(act -> act.getType() == JailActionType.DAMAGE || act.getType() == JailActionType.KILL) + .filter(act -> act.getType() == GenericActionType.DAMAGE || act.getType() == GenericActionType.KILL) .filter(act -> act.getPlayerRole().isCT()).filter(act -> act.getTargetRole() == JailRole.PRISONER) .filter(act -> ceaseFire(cease, act.getTime())).collect(Collectors.toList()); @@ -254,7 +256,7 @@ private void checkWorldButtons() { * soon after */ private void checkNades() { - List nades = jbActions.stream().filter(act -> act.getType() == JailActionType.NADE) + List nades = jbActions.stream().filter(act -> act.getType() == GenericActionType.NADE) .collect(Collectors.toList()); for (JailAction act : jbActions.stream().filter(act -> act.getPlayerRole() == JailRole.WORLD) @@ -310,7 +312,7 @@ private void checkGuns() { */ private void checkSpectator() { List damage = jbActions.stream() - .filter(act -> act.getType() == JailActionType.DAMAGE || act.getType() == JailActionType.KILL) + .filter(act -> act.getType() == GenericActionType.DAMAGE || act.getType() == GenericActionType.KILL) .filter(act -> act.getPlayerRole() == JailRole.SPECTATOR).collect(Collectors.toList()); for (JailAction act : damage) { print("\nSpectator Exploiters"); diff --git a/src/main/java/xyz/msws/admintools/parsers/TTTParser.java b/src/main/java/xyz/msws/admintools/parsers/TTTParser.java index 6c60806..420a779 100644 --- a/src/main/java/xyz/msws/admintools/parsers/TTTParser.java +++ b/src/main/java/xyz/msws/admintools/parsers/TTTParser.java @@ -1,16 +1,124 @@ package xyz.msws.admintools.parsers; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.regex.Pattern; + import xyz.msws.admintools.Monitor; +import xyz.msws.admintools.data.DataStructs.GenericActionType; +import xyz.msws.admintools.data.ttt.TTTAction; +import xyz.msws.admintools.data.ttt.TTTActionType; +import xyz.msws.admintools.data.ttt.TTTRole; public class TTTParser extends Parser { + private final List tttActions = new ArrayList<>(); + private final Pattern pattern = Pattern.compile("^\\[\\d\\d:\\d\\d]\s"); // Matches the timecode prefix of TTT + // logs + private boolean parse = false; + + Set lines = new HashSet<>(); + public TTTParser(Monitor monitor) { super(monitor); } @Override public void parse(String line) { - + if (line.equals("---------------TTT LOGS---------------") && !parse) { + tttActions.clear(); + lines.clear(); + parse = true; + return; + } + if (line.equals("--------------------------------------") && parse) { + Arrays.stream(config.getHeader().split("\\\\n")).forEach(System.out::println); + + System.out.println("TTT Logs"); + for (TTTAction act : tttActions) { + if (!config.getActions().contains(act.getType())) + continue; + try { + System.out.println(act.simplify()); + } catch (Exception e) { + System.out.println("Error occured while parsing " + act.getLine() + ":\n" + e.getMessage()); + } + } + + checkHidden(); + checkRDM(); + + tttActions.clear(); + lines.clear(); + parse = false; + return; + } + if (!parse) + return; + if (!line.startsWith("[") || line.charAt(8) != '-' || line.charAt(9) != '>') + return; + if (line.endsWith("has been started!")) + return; + if (!pattern.matcher(line).lookingAt()) + return; + + try { + TTTAction tttAction = new TTTAction(line); + tttActions.add(tttAction); + } catch (Exception e) { + e.printStackTrace(); + System.out.println("Unknown TTT line: " + line); + } + } + + private void checkHidden() { + Set revealed = new HashSet<>(); + Set toPrint = new HashSet<>(); + for (TTTAction act : tttActions) { + if (act.getPlayerRole() == TTTRole.TRAITOR + && (act.getType() == GenericActionType.DAMAGE || act.getType() == TTTActionType.T_SECRET + || act.getType() == TTTActionType.TAZE)) { + revealed.add(act.getType() == TTTActionType.TAZE ? act.getOther()[0] : act.getPlayer()); + continue; + } + + if (act.getTargetRole() != TTTRole.TRAITOR + || (act.getType() != GenericActionType.DAMAGE && act.getType() != GenericActionType.KILL)) + continue; + + if (revealed.contains(act.getTarget())) + continue; + + toPrint.add(act.simplify()); + } + if (toPrint.isEmpty()) + return; + print("\nEarly Traitor Kills (Ts did not commit any acts)"); + toPrint.forEach(s -> print(s)); + } + + private void checkRDM() { + Set toPrint = new HashSet<>(); + for (TTTAction act : tttActions) { + if (act.getPlayerRole() != act.getTargetRole() && !act.isBadAction()) + continue; + if (act.getType() == TTTActionType.BAD_DAMAGE) + continue; + toPrint.add(act.simplify()); + } + if (toPrint.isEmpty()) + return; + print("\nBad Actions"); + toPrint.forEach(s -> print(s)); + } + private void print(String line) { + if (lines.contains(line)) + return; + System.out.println(line); + lines.add(line); } }