""" EU-Utility - Profession Scanner Plugin Scan and track profession progress with OCR. """ import re import json from datetime import datetime from pathlib import Path from decimal import Decimal from PyQt6.QtWidgets import ( QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QTableWidget, QTableWidgetItem, QProgressBar, QFrame, QGroupBox, QComboBox ) from PyQt6.QtCore import Qt, QThread, pyqtSignal from plugins.base_plugin import BasePlugin class ProfessionOCRThread(QThread): """OCR scan for professions window.""" scan_complete = pyqtSignal(dict) scan_error = pyqtSignal(str) progress_update = pyqtSignal(str) def run(self): """Perform OCR scan.""" try: self.progress_update.emit("Capturing screen...") import pyautogui screenshot = pyautogui.screenshot() self.progress_update.emit("Running OCR...") # OCR try: import easyocr reader = easyocr.Reader(['en'], verbose=False) results = reader.readtext(screenshot) text = '\n'.join([r[1] for r in results]) except: import pytesseract from PIL import Image text = pytesseract.image_to_string(screenshot) # Parse professions professions = self._parse_professions(text) self.scan_complete.emit(professions) except Exception as e: self.scan_error.emit(str(e)) def _parse_professions(self, text): """Parse profession data from OCR text.""" professions = {} # Pattern: ProfessionName Rank %Progress # Example: "Laser Pistoleer (Hit) Elite, 72 68.3%" lines = text.split('\n') for line in lines: # Match profession with rank and percentage match = re.search(r'(\w+(?:\s+\w+)*)\s+\(?(\w+)?\)?\s+(Elite|Champion|Astonishing|Remarkable|Outstanding|Marvelous|Prodigious|Amazing|Incredible|Awesome),?\s+(\d+)[,\s]+(\d+\.?\d*)%?', line) if match: prof_name = match.group(1).strip() spec = match.group(2) or "" rank_name = match.group(3) rank_num = match.group(4) progress = float(match.group(5)) full_name = f"{prof_name} ({spec})" if spec else prof_name professions[full_name] = { 'rank_name': rank_name, 'rank_num': int(rank_num), 'progress': progress, 'scanned_at': datetime.now().isoformat() } return professions class ProfessionScannerPlugin(BasePlugin): """Scan and track profession progress.""" name = "Profession Scanner" version = "1.0.0" author = "ImpulsiveFPS" description = "Track profession ranks and progress" hotkey = "ctrl+shift+p" def initialize(self): """Setup profession scanner.""" self.data_file = Path("data/professions.json") self.data_file.parent.mkdir(parents=True, exist_ok=True) self.professions = {} self._load_data() def _load_data(self): """Load saved data.""" if self.data_file.exists(): try: with open(self.data_file, 'r') as f: data = json.load(f) self.professions = data.get('professions', {}) except: pass def _save_data(self): """Save data.""" with open(self.data_file, 'w') as f: json.dump({'professions': self.professions}, f, indent=2) def get_ui(self): """Create profession scanner UI.""" widget = QWidget() layout = QVBoxLayout(widget) layout.setSpacing(15) layout.setContentsMargins(0, 0, 0, 0) # Header header = QLabel("Profession Tracker") header.setStyleSheet("font-size: 18px; font-weight: bold; color: white;") layout.addWidget(header) # Summary summary = QHBoxLayout() self.total_label = QLabel(f"Professions: {len(self.professions)}") self.total_label.setStyleSheet("color: #4ecdc4; font-weight: bold;") summary.addWidget(self.total_label) summary.addStretch() layout.addLayout(summary) # Scan button scan_btn = QPushButton("Scan Professions Window") scan_btn.setStyleSheet(""" QPushButton { background-color: #ff8c42; color: white; padding: 12px; border: none; border-radius: 4px; font-weight: bold; } """) scan_btn.clicked.connect(self._scan_professions) layout.addWidget(scan_btn) # Progress self.progress_label = QLabel("Ready to scan") self.progress_label.setStyleSheet("color: rgba(255,255,255,150);") layout.addWidget(self.progress_label) # Professions table self.prof_table = QTableWidget() self.prof_table.setColumnCount(4) self.prof_table.setHorizontalHeaderLabels(["Profession", "Rank", "Level", "Progress"]) self.prof_table.horizontalHeader().setStretchLastSection(True) # Style table self.prof_table.setStyleSheet(""" QTableWidget { background-color: rgba(30, 35, 45, 200); color: white; border: 1px solid rgba(100, 110, 130, 80); border-radius: 6px; } QHeaderView::section { background-color: rgba(35, 40, 55, 200); color: rgba(255,255,255,180); padding: 8px; font-weight: bold; } """) layout.addWidget(self.prof_table) # Refresh table self._refresh_table() return widget def _scan_professions(self): """Start OCR scan.""" self.scanner = ProfessionOCRThread() self.scanner.scan_complete.connect(self._on_scan_complete) self.scanner.scan_error.connect(self._on_scan_error) self.scanner.progress_update.connect(self._on_progress) self.scanner.start() def _on_progress(self, message): """Update progress.""" self.progress_label.setText(message) def _on_scan_complete(self, professions): """Handle scan completion.""" self.professions.update(professions) self._save_data() self._refresh_table() self.progress_label.setText(f"Found {len(professions)} professions") self.total_label.setText(f"Professions: {len(self.professions)}") def _on_scan_error(self, error): """Handle error.""" self.progress_label.setText(f"Error: {error}") def _refresh_table(self): """Refresh professions table.""" self.prof_table.setRowCount(len(self.professions)) for i, (name, data) in enumerate(sorted(self.professions.items())): self.prof_table.setItem(i, 0, QTableWidgetItem(name)) self.prof_table.setItem(i, 1, QTableWidgetItem(data.get('rank_name', '-'))) self.prof_table.setItem(i, 2, QTableWidgetItem(str(data.get('rank_num', 0)))) # Progress with bar progress = data.get('progress', 0) progress_widget = QWidget() progress_layout = QHBoxLayout(progress_widget) progress_layout.setContentsMargins(5, 2, 5, 2) bar = QProgressBar() bar.setValue(int(progress)) bar.setTextVisible(True) bar.setFormat(f"{progress:.1f}%") bar.setStyleSheet(""" QProgressBar { background-color: rgba(60, 70, 90, 150); border: none; border-radius: 3px; text-align: center; color: white; } QProgressBar::chunk { background-color: #ff8c42; border-radius: 3px; } """) progress_layout.addWidget(bar) self.prof_table.setCellWidget(i, 3, progress_widget)