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.) # List of patterns that indicate NON-game text (UI, Discord, etc.)
invalid_patterns = [ invalid_patterns = [
# App/UI elements
'Discord', 'Presence', 'Event Bus', 'Example', 'Game Reader', 'Discord', 'Presence', 'Event Bus', 'Example', 'Game Reader',
'Test', 'Page Scanner', 'HOTKEY MODE', 'Skill Tracker', 'Test', 'Page Scanner', 'HOTKEY MODE', 'Skill Tracker',
'Navigate', 'window', 'UI', 'Plugin', 'Settings', 'Navigate', 'window', 'UI', 'Plugin', 'Settings',
@ -150,6 +151,17 @@ def is_valid_skill_text(text):
'Cleared', 'Parsed:', '[SkillScanner]', 'INFO', 'DEBUG', 'Cleared', 'Parsed:', '[SkillScanner]', 'INFO', 'DEBUG',
'Loading', 'Initializing', 'Connecting', 'Error:', 'Warning:', 'Loading', 'Initializing', 'Connecting', 'Error:', 'Warning:',
'Entropia.exe', 'Client (64 bit)', 'Arkadia', 'Calypso', '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 # 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) # Check for reasonable skill name length (not too long, not too short)
words = text.split() 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 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 return True
@ -280,6 +300,11 @@ class SkillOCRThread(QThread):
skill_name = re.sub(r'^(Skill|SKILL)\s*', '', skill_name, flags=re.IGNORECASE) skill_name = re.sub(r'^(Skill|SKILL)\s*', '', skill_name, flags=re.IGNORECASE)
skill_name = skill_name.strip() 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) # Validate - points should be reasonable (not too small)
if points > 0 and skill_name and len(skill_name) > 2: if points > 0 and skill_name and len(skill_name) > 2:
skills[skill_name] = { 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 = re.sub(r'^(Skill|SKILL)\s*', '', skill_name, flags=re.IGNORECASE)
skill_name = skill_name.strip() 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: if points > 0 and skill_name and len(skill_name) > 2:
skills[skill_name] = {'rank': rank, 'points': points} skills[skill_name] = {'rank': rank, 'points': points}