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.
This commit is contained in:
LemonNexus 2026-02-15 01:22:40 +00:00
parent 67106ae64e
commit 194cda2c62
1 changed files with 31 additions and 1 deletions

View File

@ -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}