feat(globals): add personal global detection with PLAYER_NAME setting
- Add PLAYER_NAME setting to .env.example for avatar name configuration - Add personal_global patterns for Swedish and English: - EN: '[Globals] Player killed a creature (Creature) for X PED' - SV: '[Globala] Player dödade ett kreatur (Creature) med X PED' - Distinguish personal globals from other players' globals - Show 🎉🎉🎉 YOUR GLOBAL notification with creature name - Track personal_globals separately in session summary Fixes #42 - Users can now see when THEY global vs others.
This commit is contained in:
parent
06a95f56f4
commit
77d8e808fb
|
|
@ -69,6 +69,10 @@ DB_MAX_BACKUPS=10
|
|||
# Linux/Wine: ~/.wine/drive_c/users/<Username>/Documents/Entropia Universe/chat.log
|
||||
EU_CHAT_LOG_PATH=./test-data/chat.log
|
||||
|
||||
# Your Entropia Universe avatar name (for detecting personal globals/HoFs)
|
||||
# Example: PLAYER_NAME=John Doe
|
||||
PLAYER_NAME=
|
||||
|
||||
# Log polling interval (milliseconds)
|
||||
LOG_POLL_INTERVAL=1000
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,23 @@ class LogWatcher:
|
|||
re.IGNORECASE
|
||||
)
|
||||
|
||||
# PERSONAL GLOBAL (when YOU get a global - different from seeing others)
|
||||
# English: "[Globals] [Player] killed a creature (Creature) with a value of X PED"
|
||||
# Swedish: "[Globala] [Player] dödade ett kreatur (Creature) med ett värde av X PED"
|
||||
PATTERN_PERSONAL_GLOBAL_EN = re.compile(
|
||||
r'^(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})\s+\[Globals\]\s+\[?\]?\s*'
|
||||
r'([\w\s]+?)\s+killed\s+a\s+creature\s+\(([^)]+)\)\s+'
|
||||
r'(?:with\s+a\s+value\s+of|for)\s+(\d+(?:\.\d+)?)\s+PED',
|
||||
re.IGNORECASE
|
||||
)
|
||||
|
||||
PATTERN_PERSONAL_GLOBAL_SV = re.compile(
|
||||
r'^(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})\s+\[Globala\]\s+\[?\]?\s*'
|
||||
r'([\w\s]+?)\s+dödade\s+ett\s+kreatur\s+\(([^)]+)\)\s+'
|
||||
r'med\s+ett\s+värde\s+av\s+(\d+(?:\.\d+)?)\s+PED',
|
||||
re.IGNORECASE
|
||||
)
|
||||
|
||||
# HALL OF FAME PATTERNS
|
||||
# Swedish: "...En post har lagts till i Hall of Fame!"
|
||||
PATTERN_HOF_MARKER = re.compile(
|
||||
|
|
@ -234,6 +251,8 @@ class LogWatcher:
|
|||
'loot_sv': PATTERN_LOOT_SV,
|
||||
'global_en': PATTERN_GLOBAL_EN,
|
||||
'global_sv': PATTERN_GLOBAL_SV,
|
||||
'personal_global_en': PATTERN_PERSONAL_GLOBAL_EN,
|
||||
'personal_global_sv': PATTERN_PERSONAL_GLOBAL_SV,
|
||||
'hof': PATTERN_HOF_MARKER,
|
||||
'skill_en': PATTERN_SKILL_EN,
|
||||
'skill_sv': PATTERN_SKILL_SV,
|
||||
|
|
@ -371,6 +390,16 @@ class LogWatcher:
|
|||
if match:
|
||||
return self._create_global_event_en(match, line)
|
||||
|
||||
# PERSONAL GLOBAL - Swedish (when YOU get a global)
|
||||
match = self.PATTERN_PERSONAL_GLOBAL_SV.match(line)
|
||||
if match:
|
||||
return self._create_personal_global_event(match, line, 'swedish')
|
||||
|
||||
# PERSONAL GLOBAL - English (when YOU get a global)
|
||||
match = self.PATTERN_PERSONAL_GLOBAL_EN.match(line)
|
||||
if match:
|
||||
return self._create_personal_global_event(match, line, 'english')
|
||||
|
||||
# HOF
|
||||
match = self.PATTERN_HOF_MARKER.match(line)
|
||||
if match:
|
||||
|
|
@ -651,6 +680,20 @@ class LogWatcher:
|
|||
}
|
||||
)
|
||||
|
||||
def _create_personal_global_event(self, match: re.Match, line: str, language: str) -> LogEvent:
|
||||
"""Create personal global event (when YOU get a global)."""
|
||||
return LogEvent(
|
||||
timestamp=self._parse_timestamp(match.group(1)),
|
||||
event_type='personal_global',
|
||||
raw_line=line,
|
||||
data={
|
||||
'player_name': match.group(2).strip(),
|
||||
'creature': match.group(3).strip(),
|
||||
'value_ped': Decimal(match.group(4)),
|
||||
'language': language
|
||||
}
|
||||
)
|
||||
|
||||
# ========================================================================
|
||||
# ASYNC POLLING LOOP
|
||||
# ========================================================================
|
||||
|
|
|
|||
10
main.py
10
main.py
|
|
@ -207,7 +207,7 @@ class LemontropiaApp:
|
|||
logger.info(f"Using REAL log: {log_path}")
|
||||
|
||||
# Stats tracking
|
||||
stats = {'loot': 0, 'globals': 0, 'hofs': 0, 'skills': 0, 'level_ups': 0, 'weapon_tiers': 0, 'enhancers_broken': 0, 'damage_dealt': 0, 'damage_taken': 0, 'evades': 0, 'total_ped': Decimal('0.0')}
|
||||
stats = {'loot': 0, 'globals': 0, 'personal_globals': 0, 'hofs': 0, 'skills': 0, 'level_ups': 0, 'weapon_tiers': 0, 'enhancers_broken': 0, 'damage_dealt': 0, 'damage_taken': 0, 'evades': 0, 'total_ped': Decimal('0.0')}
|
||||
|
||||
def on_event(event):
|
||||
"""Handle log events."""
|
||||
|
|
@ -232,6 +232,10 @@ class LemontropiaApp:
|
|||
stats['globals'] += 1
|
||||
print(f" 🌍 GLOBAL: {event.data.get('player_name')} found {event.data.get('value_ped')} PED!")
|
||||
|
||||
elif event.event_type == 'personal_global':
|
||||
stats['personal_globals'] += 1
|
||||
print(f" 🎉🎉🎉 YOUR GLOBAL: {event.data.get('player_name')} killed {event.data.get('creature')} for {event.data.get('value_ped')} PED!!! 🎉🎉🎉")
|
||||
|
||||
elif event.event_type == 'hof':
|
||||
stats['hofs'] += 1
|
||||
print(f" 🏆 HALL OF FAME: {event.data.get('value_ped')} PED!")
|
||||
|
|
@ -271,6 +275,7 @@ class LemontropiaApp:
|
|||
# Subscribe to events
|
||||
self.watcher.subscribe('loot', on_event)
|
||||
self.watcher.subscribe('global', on_event)
|
||||
self.watcher.subscribe('personal_global', on_event)
|
||||
self.watcher.subscribe('hof', on_event)
|
||||
self.watcher.subscribe('skill', on_event)
|
||||
self.watcher.subscribe('level_up', on_event)
|
||||
|
|
@ -307,7 +312,8 @@ class LemontropiaApp:
|
|||
print("="*50)
|
||||
print(f"\n📊 SESSION SUMMARY:")
|
||||
print(f" Loot events: {stats['loot']}")
|
||||
print(f" Globals: {stats['globals']}")
|
||||
print(f" Your Globals: {stats['personal_globals']}")
|
||||
print(f" Other Globals: {stats['globals']}")
|
||||
print(f" HoFs: {stats['hofs']}")
|
||||
print(f" Skills: {stats['skills']}")
|
||||
print(f" Level Ups: {stats['level_ups']}")
|
||||
|
|
|
|||
Loading…
Reference in New Issue