From 194cda2c62e1b78863038c4098c9fbe150d9f343 Mon Sep 17 00:00:00 2001 From: LemonNexus Date: Sun, 15 Feb 2026 01:22:40 +0000 Subject: [PATCH] fix: Improve text filtering and add validation to skill parsing PROBLEM: UI text like 'Position Skills window Wounding' and 'Scan Current Page Serendipity' was being parsed as skills. FIXES: 1. Enhanced is_valid_skill_text() filtering: - Added more UI patterns: 'Position Skills', 'Scan Current Page', 'Select Area', 'Drag over', 'Navigate pages' - Added combined patterns: 'Combat Wounding', 'Scan Serendipity', 'Position Wounding', etc. - Added action word detection: Click, Scan, Position, Select, Navigate, Start, Save, Clear - any line with these is UI text - Reduced max words from 10 to 7 for skill names 2. Added validation in _parse_skills_from_text(): - After extracting skill name, validates with is_valid_skill_text() - Logs filtered names for debugging - Only adds to results if validation passes USER ACTION NEEDED: - Pull latest code: git pull origin main - Select Area button should appear in UI - Drag to select your Skills window area - Scan will only read from that area This should eliminate UI text from scan results. --- plugins/skill_scanner/plugin.py | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/plugins/skill_scanner/plugin.py b/plugins/skill_scanner/plugin.py index 101f0bf..0ba4b62 100644 --- a/plugins/skill_scanner/plugin.py +++ b/plugins/skill_scanner/plugin.py @@ -141,6 +141,7 @@ def is_valid_skill_text(text): """ # List of patterns that indicate NON-game text (UI, Discord, etc.) invalid_patterns = [ + # App/UI elements 'Discord', 'Presence', 'Event Bus', 'Example', 'Game Reader', 'Test', 'Page Scanner', 'HOTKEY MODE', 'Skill Tracker', 'Navigate', 'window', 'UI', 'Plugin', 'Settings', @@ -150,6 +151,17 @@ def is_valid_skill_text(text): 'Cleared', 'Parsed:', '[SkillScanner]', 'INFO', 'DEBUG', 'Loading', 'Initializing', 'Connecting', 'Error:', 'Warning:', 'Entropia.exe', 'Client (64 bit)', 'Arkadia', 'Calypso', + # Instructions from our own UI + 'Position Skills', 'Position Skills window', 'Start Smart Scan', + 'Scan Current Page', 'Save All', 'Clear Session', + 'Select Area', 'Drag over', 'Navigate pages', + # Column headers that might be picked up + 'Skill', 'Skills', 'Rank', 'Points', 'Name', + # Category names with extra text + 'Combat Wounding', 'Combat Serendipity', 'Combat Reflexes', + 'Scan Serendipity', 'Scan Wounding', 'Scan Reflexes', + 'Position Wounding', 'Position Serendipity', 'Position Reflexes', + 'Current Page', 'Smart Scan', 'All Scanned', ] # Check for invalid patterns @@ -160,9 +172,17 @@ def is_valid_skill_text(text): # Check for reasonable skill name length (not too long, not too short) words = text.split() - if len(words) > 10: # Skills don't have 10+ words + if len(words) > 7: # Skills rarely have 7+ words (reduced from 10) return False + # Check if text contains button/action words combined with skill-like text + action_words = ['Click', 'Scan', 'Position', 'Select', 'Navigate', 'Start', 'Save', 'Clear'] + text_lower = text.lower() + for word in action_words: + if word.lower() in text_lower: + # If it has action words, it's probably UI text + return False + return True @@ -280,6 +300,11 @@ class SkillOCRThread(QThread): skill_name = re.sub(r'^(Skill|SKILL)\s*', '', skill_name, flags=re.IGNORECASE) skill_name = skill_name.strip() + # Validate skill name - filter out UI text + if not is_valid_skill_text(skill_name): + print(f"[SkillScanner] Filtered invalid skill name: '{skill_name}'") + continue + # Validate - points should be reasonable (not too small) if points > 0 and skill_name and len(skill_name) > 2: skills[skill_name] = { @@ -1005,6 +1030,11 @@ class SkillScannerPlugin(BasePlugin): skill_name = re.sub(r'^(Skill|SKILL)\s*', '', skill_name, flags=re.IGNORECASE) skill_name = skill_name.strip() + # Validate skill name - filter out UI text + if not is_valid_skill_text(skill_name): + print(f"[SkillScanner] Filtered invalid skill name: '{skill_name}'") + continue + if points > 0 and skill_name and len(skill_name) > 2: skills[skill_name] = {'rank': rank, 'points': points}