258 lines
8.5 KiB
Python
258 lines
8.5 KiB
Python
"""
|
|
EU-Utility - Global Tracker Plugin
|
|
|
|
Track globals, HOFs, with notifications.
|
|
"""
|
|
|
|
import json
|
|
from datetime import datetime, timedelta
|
|
from pathlib import Path
|
|
from collections import deque
|
|
|
|
from PyQt6.QtWidgets import (
|
|
QWidget, QVBoxLayout, QHBoxLayout, QLabel,
|
|
QPushButton, QTableWidget, QTableWidgetItem,
|
|
QCheckBox, QFrame
|
|
)
|
|
from PyQt6.QtCore import Qt
|
|
|
|
from plugins.base_plugin import BasePlugin
|
|
from core.icon_manager import get_icon_manager
|
|
from PyQt6.QtGui import QPixmap
|
|
|
|
|
|
class GlobalTrackerPlugin(BasePlugin):
|
|
"""Track globals and HOFs with stats."""
|
|
|
|
name = "Global Tracker"
|
|
version = "1.0.0"
|
|
author = "ImpulsiveFPS"
|
|
description = "Track globals, HOFs, and ATHs"
|
|
hotkey = "ctrl+shift+g"
|
|
|
|
def initialize(self):
|
|
"""Setup global tracker."""
|
|
self.data_file = Path("data/globals.json")
|
|
self.data_file.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
self.globals = deque(maxlen=1000)
|
|
self.my_globals = []
|
|
self.notifications_enabled = True
|
|
|
|
self._load_data()
|
|
|
|
def _load_data(self):
|
|
"""Load global data."""
|
|
if self.data_file.exists():
|
|
try:
|
|
with open(self.data_file, 'r') as f:
|
|
data = json.load(f)
|
|
self.globals.extend(data.get('globals', []))
|
|
self.my_globals = data.get('my_globals', [])
|
|
except:
|
|
pass
|
|
|
|
def _save_data(self):
|
|
"""Save global data."""
|
|
with open(self.data_file, 'w') as f:
|
|
json.dump({
|
|
'globals': list(self.globals),
|
|
'my_globals': self.my_globals
|
|
}, f, indent=2)
|
|
|
|
def get_ui(self):
|
|
"""Create global tracker UI."""
|
|
widget = QWidget()
|
|
widget.setStyleSheet("background: transparent;")
|
|
layout = QVBoxLayout(widget)
|
|
layout.setSpacing(15)
|
|
layout.setContentsMargins(0, 0, 0, 0)
|
|
|
|
# Get icon manager
|
|
icon_mgr = get_icon_manager()
|
|
|
|
# Title with icon
|
|
title_layout = QHBoxLayout()
|
|
|
|
title_icon = QLabel()
|
|
icon_pixmap = icon_mgr.get_pixmap('dollar-sign', size=20)
|
|
title_icon.setPixmap(icon_pixmap)
|
|
title_icon.setFixedSize(20, 20)
|
|
title_layout.addWidget(title_icon)
|
|
|
|
title = QLabel("Global Tracker")
|
|
title.setStyleSheet("color: white; font-size: 16px; font-weight: bold;")
|
|
title_layout.addWidget(title)
|
|
title_layout.addStretch()
|
|
|
|
layout.addLayout(title_layout)
|
|
|
|
# Stats
|
|
stats_frame = QFrame()
|
|
stats_frame.setStyleSheet("""
|
|
QFrame {
|
|
background-color: rgba(30, 35, 45, 200);
|
|
border: 1px solid rgba(100, 110, 130, 80);
|
|
border-radius: 6px;
|
|
}
|
|
""")
|
|
stats_layout = QHBoxLayout(stats_frame)
|
|
|
|
total = len(self.globals)
|
|
hofs = sum(1 for g in self.globals if g.get('value', 0) >= 1000)
|
|
|
|
self.total_label = QLabel(f"Globals: {total}")
|
|
self.total_label.setStyleSheet("color: #4caf50; font-weight: bold;")
|
|
stats_layout.addWidget(self.total_label)
|
|
|
|
self.hof_label = QLabel(f"HOFs: {hofs}")
|
|
self.hof_label.setStyleSheet("color: #ffc107; font-weight: bold;")
|
|
stats_layout.addWidget(self.hof_label)
|
|
|
|
self.my_label = QLabel(f"My Globals: {len(self.my_globals)}")
|
|
self.my_label.setStyleSheet("color: #ff8c42; font-weight: bold;")
|
|
stats_layout.addWidget(self.my_label)
|
|
|
|
stats_layout.addStretch()
|
|
layout.addWidget(stats_frame)
|
|
|
|
# Filters
|
|
filters = QHBoxLayout()
|
|
self.show_mine_cb = QCheckBox("Show only my globals")
|
|
self.show_mine_cb.setStyleSheet("color: white;")
|
|
filters.addWidget(self.show_mine_cb)
|
|
|
|
self.show_hof_cb = QCheckBox("HOFs only")
|
|
self.show_hof_cb.setStyleSheet("color: white;")
|
|
filters.addWidget(self.show_hof_cb)
|
|
|
|
filters.addStretch()
|
|
layout.addLayout(filters)
|
|
|
|
# Globals table
|
|
self.globals_table = QTableWidget()
|
|
self.globals_table.setColumnCount(5)
|
|
self.globals_table.setHorizontalHeaderLabels(["Time", "Player", "Mob/Item", "Value", "Type"])
|
|
self.globals_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;
|
|
font-size: 11px;
|
|
}
|
|
""")
|
|
self.globals_table.horizontalHeader().setStretchLastSection(True)
|
|
layout.addWidget(self.globals_table)
|
|
|
|
self._refresh_globals()
|
|
|
|
# Test buttons
|
|
test_layout = QHBoxLayout()
|
|
|
|
test_global = QPushButton("Test Global")
|
|
test_global.setStyleSheet("""
|
|
QPushButton {
|
|
background-color: #4caf50;
|
|
color: white;
|
|
padding: 8px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
}
|
|
""")
|
|
test_global.clicked.connect(self._test_global)
|
|
test_layout.addWidget(test_global)
|
|
|
|
test_hof = QPushButton("Test HOF")
|
|
test_hof.setStyleSheet("""
|
|
QPushButton {
|
|
background-color: #ffc107;
|
|
color: black;
|
|
padding: 8px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
}
|
|
""")
|
|
test_hof.clicked.connect(self._test_hof)
|
|
test_layout.addWidget(test_hof)
|
|
|
|
test_layout.addStretch()
|
|
layout.addLayout(test_layout)
|
|
|
|
layout.addStretch()
|
|
return widget
|
|
|
|
def _refresh_globals(self):
|
|
"""Refresh globals table."""
|
|
recent = list(self.globals)[-50:] # Last 50
|
|
|
|
self.globals_table.setRowCount(len(recent))
|
|
for i, g in enumerate(reversed(recent)):
|
|
self.globals_table.setItem(i, 0, QTableWidgetItem(g.get('time', '-')[-8:]))
|
|
self.globals_table.setItem(i, 1, QTableWidgetItem(g.get('player', 'Unknown')))
|
|
self.globals_table.setItem(i, 2, QTableWidgetItem(g.get('target', 'Unknown')))
|
|
|
|
value_item = QTableWidgetItem(f"{g.get('value', 0):.2f} PED")
|
|
value = g.get('value', 0)
|
|
if value >= 10000:
|
|
value_item.setForeground(Qt.GlobalColor.magenta)
|
|
elif value >= 1000:
|
|
value_item.setForeground(Qt.GlobalColor.yellow)
|
|
elif value >= 50:
|
|
value_item.setForeground(Qt.GlobalColor.green)
|
|
self.globals_table.setItem(i, 3, value_item)
|
|
|
|
g_type = "ATH" if value >= 10000 else "HOF" if value >= 1000 else "Global"
|
|
self.globals_table.setItem(i, 4, QTableWidgetItem(g_type))
|
|
|
|
def _test_global(self):
|
|
"""Add test global."""
|
|
self.add_global("TestPlayer", "Argo Scout", 45.23, is_mine=True)
|
|
self._refresh_globals()
|
|
|
|
def _test_hof(self):
|
|
"""Add test HOF."""
|
|
self.add_global("TestPlayer", "Oratan Miner", 1250.00, is_mine=True)
|
|
self._refresh_globals()
|
|
|
|
def add_global(self, player, target, value, is_mine=False):
|
|
"""Add a global."""
|
|
entry = {
|
|
'time': datetime.now().isoformat(),
|
|
'player': player,
|
|
'target': target,
|
|
'value': value,
|
|
'is_mine': is_mine
|
|
}
|
|
|
|
self.globals.append(entry)
|
|
|
|
if is_mine:
|
|
self.my_globals.append(entry)
|
|
|
|
self._save_data()
|
|
self._refresh_globals()
|
|
|
|
def parse_chat_message(self, message):
|
|
"""Parse global from chat."""
|
|
# Look for global patterns
|
|
import re
|
|
|
|
# Example: "Player killed Argo Scout worth 45.23 PED!"
|
|
pattern = r'(\w+)\s+(?:killed|mined|crafted)\s+(.+?)\s+worth\s+([\d.]+)\s+PED'
|
|
match = re.search(pattern, message, re.IGNORECASE)
|
|
|
|
if match:
|
|
player = match.group(1)
|
|
target = match.group(2)
|
|
value = float(match.group(3))
|
|
|
|
is_mine = player == "You" or player == "Your avatar"
|
|
self.add_global(player, target, value, is_mine)
|