diff --git a/src/main/java/dev/shared/halizeur/log_overlay/LogOverlay.java b/src/main/java/dev/shared/halizeur/log_overlay/LogOverlay.java index c086e672..9cc2fcf0 100644 --- a/src/main/java/dev/shared/halizeur/log_overlay/LogOverlay.java +++ b/src/main/java/dev/shared/halizeur/log_overlay/LogOverlay.java @@ -3,8 +3,10 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; +import java.util.EnumMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import eu.darkbot.api.PluginAPI; import eu.darkbot.api.config.ConfigSetting; @@ -18,6 +20,8 @@ import eu.darkbot.api.extensions.MapGraphics; import eu.darkbot.api.managers.EventBrokerAPI; import eu.darkbot.api.managers.GameLogAPI; +import eu.darkbot.api.managers.GameResourcesAPI; +import eu.darkbot.api.managers.GameResourcesAPI.TranslationMatcher; /** * Renders the latest in-game DarkOrbit log messages as an overlay on the @@ -26,6 +30,11 @@ * Source: {@link GameLogAPI.LogMessageEvent} emitted by DarkBot for each * new system message. Each line disappears after DISPLAY_MS ms so the * canvas does not get cluttered. + * + * Filter: per category, the overlay matches messages against translation + * patterns from {@link GameResourcesAPI} (the official Bigpoint flashres + * keys), so the filter works on every game locale without per-language + * keyword maintenance. */ @Feature(name = "Log Overlay", description = "Shows the latest in-game log messages as an overlay on the canvas", @@ -38,37 +47,117 @@ public class LogOverlay implements Behavior, Drawable, Listener, Configurable entries = new ArrayDeque<>(); + private final Map> matchers = new EnumMap<>(Cat.class); + private final List currencyNeedles = new ArrayList<>(); + private final List resourceNeedles = new ArrayList<>(); private LogOverlayConfig config; public LogOverlay(PluginAPI api) { api.requireAPI(EventBrokerAPI.class).registerListener(this); + + GameResourcesAPI res = api.requireAPI(GameResourcesAPI.class); + buildMatchers(res, Cat.GAINS, KEYS_GAINS); + buildMatchers(res, Cat.BOOSTERS, KEYS_BOOSTERS); + buildMatchers(res, Cat.ERRORS, KEYS_ERRORS); + buildMatchers(res, Cat.COMBAT, KEYS_COMBAT); + + for (String name : CURRENCY_NAMES) { + this.currencyNeedles.add(name); + } + for (String key : RESOURCE_KEYS) { + res.findTranslation(key).ifPresent(t -> { + String lower = t.toLowerCase(); + if (!this.resourceNeedles.contains(lower)) { + this.resourceNeedles.add(lower); + } + }); + } + } + + /** Pre-builds {@link TranslationMatcher} instances for every key in a + * category. Keys whose translation is missing in the active locale + * return {@link java.util.Optional#empty()} and are skipped silently. */ + private void buildMatchers(GameResourcesAPI res, Cat cat, String[] keys) { + List list = new ArrayList<>(); + for (String key : keys) { + res.getTranslationMatcher(key).ifPresent(list::add); + } + this.matchers.put(cat, list); } @Override @@ -100,13 +189,42 @@ public void onLogMessage(GameLogAPI.LogMessageEvent event) { } /** - * Whitelist filter: only display the message if it matches a keyword - * from {@link #WHITELIST} (case-insensitive). + * Filter: a message is kept when at least one checked category + * matches. Most categories use TranslationMatcher (built from the + * official Bigpoint translations); Currencies and Resources fall + * back to substring matching against localized names because the + * actual values appear inside the {@code %!} placeholder of the + * generic gain templates and are easier to detect this way. */ private boolean isAllowed(String msg) { - String lower = msg.toLowerCase(); - for (String kw : WHITELIST) { - if (lower.contains(kw)) return true; + LogOverlayConfig.Categories c = this.config.categories; + if (c == null) return false; + + if (c.gains && anyMatcherFinds(Cat.GAINS, msg)) return true; + if (c.boosters && anyMatcherFinds(Cat.BOOSTERS, msg)) return true; + if (c.errors && anyMatcherFinds(Cat.ERRORS, msg)) return true; + if (c.combat && anyMatcherFinds(Cat.COMBAT, msg)) return true; + + if (c.currencies || c.resources) { + String lower = msg.toLowerCase(); + if (c.currencies && containsAny(lower, this.currencyNeedles)) return true; + if (c.resources && containsAny(lower, this.resourceNeedles)) return true; + } + return false; + } + + private boolean anyMatcherFinds(Cat cat, String msg) { + List list = this.matchers.get(cat); + if (list == null) return false; + for (TranslationMatcher m : list) { + if (m.find(msg)) return true; + } + return false; + } + + private static boolean containsAny(String haystack, List needles) { + for (String n : needles) { + if (haystack.contains(n)) return true; } return false; } diff --git a/src/main/java/dev/shared/halizeur/log_overlay/LogOverlayConfig.java b/src/main/java/dev/shared/halizeur/log_overlay/LogOverlayConfig.java index 24c82f36..b5ed9d64 100644 --- a/src/main/java/dev/shared/halizeur/log_overlay/LogOverlayConfig.java +++ b/src/main/java/dev/shared/halizeur/log_overlay/LogOverlayConfig.java @@ -8,4 +8,33 @@ public class LogOverlayConfig { @Option("halizeur.log_overlay.enabled") public boolean enabled = false; + + @Option("halizeur.log_overlay.categories") + public Categories categories = new Categories(); + + /** + * Whitelist categories. A log message is shown when at least one + * checked category matches. Predefined keyword lists live in + * {@link LogOverlay} and stay in sync across game locales (FR + EN + * substrings are bundled together). + */ + public static class Categories { + @Option("halizeur.log_overlay.cat.gains") + public boolean gains = true; + + @Option("halizeur.log_overlay.cat.currencies") + public boolean currencies = true; + + @Option("halizeur.log_overlay.cat.resources") + public boolean resources = true; + + @Option("halizeur.log_overlay.cat.boosters") + public boolean boosters = true; + + @Option("halizeur.log_overlay.cat.errors") + public boolean errors = true; + + @Option("halizeur.log_overlay.cat.combat") + public boolean combat = false; + } } diff --git a/src/main/resources/dev/shared/lang/strings_en.properties b/src/main/resources/dev/shared/lang/strings_en.properties index d759c2c0..5415bcd0 100644 --- a/src/main/resources/dev/shared/lang/strings_en.properties +++ b/src/main/resources/dev/shared/lang/strings_en.properties @@ -6,6 +6,14 @@ general.enabled=Enable # ----- Halizeur : Log Overlay ----- halizeur.log_overlay.config=Log Overlay halizeur.log_overlay.enabled=Enabled +halizeur.log_overlay.categories=Categories to display +halizeur.log_overlay.categories.desc=Show only log messages whose content matches at least one checked category. +halizeur.log_overlay.cat.gains=Gains (loot, rewards) +halizeur.log_overlay.cat.currencies=Currencies (uridium, credits, honor, XP) +halizeur.log_overlay.cat.resources=Resources (prometium, endurium, …) +halizeur.log_overlay.cat.boosters=Boosters / drops +halizeur.log_overlay.cat.errors=Errors / refusals +halizeur.log_overlay.cat.combat=Combat / kills do_gamer.simple_healing.hp_repair=HP Repair (Solace, Orcus, Aegis, Hammerclaw) do_gamer.simple_healing.shield_repair=Shield Repair (Aegis, Hammerclaw) diff --git a/src/main/resources/dev/shared/lang/strings_fr.properties b/src/main/resources/dev/shared/lang/strings_fr.properties index 4f5ed14d..1761a914 100644 --- a/src/main/resources/dev/shared/lang/strings_fr.properties +++ b/src/main/resources/dev/shared/lang/strings_fr.properties @@ -6,6 +6,14 @@ general.enabled=Activer # ----- Halizeur : Log Overlay ----- halizeur.log_overlay.config=Log Overlay halizeur.log_overlay.enabled=Activé +halizeur.log_overlay.categories=Catégories à afficher +halizeur.log_overlay.categories.desc=N'affiche que les messages dont le contenu correspond à au moins une catégorie cochée. +halizeur.log_overlay.cat.gains=Gains (loot, récompenses) +halizeur.log_overlay.cat.currencies=Devises (uridium, crédits, honneur, XP) +halizeur.log_overlay.cat.resources=Ressources (prometium, endurium, …) +halizeur.log_overlay.cat.boosters=Boosters / drops +halizeur.log_overlay.cat.errors=Erreurs / refus +halizeur.log_overlay.cat.combat=Combat / kills do_gamer.simple_healing.hp_repair=Réparation des PV (Solace, Orcus, Aegis, Hammerclaw) do_gamer.simple_healing.shield_repair=Réparation du bouclier (Aegis, Hammerclaw)