added inventory, updated DB

This commit is contained in:
erik 2025-06-10 19:21:21 +00:00
parent f218350959
commit 10c51f6825
16528 changed files with 147743 additions and 79 deletions

View file

@ -0,0 +1,268 @@
#!/usr/bin/env python3
"""
Comprehensive enum extraction from Mag-Plugins/Shared directory.
Extracts all enums, dictionaries, and data needed for rich tooltip display.
"""
import json
import re
import csv
from pathlib import Path
from typing import Dict, Any
def extract_csharp_enum(file_path: Path) -> Dict[str, Any]:
"""Extract enum definition from C# file."""
try:
content = file_path.read_text(encoding='utf-8')
# Find enum declaration
enum_match = re.search(r'public enum (\w+)(?:\s*:\s*\w+)?\s*{([^}]+)}', content, re.DOTALL)
if not enum_match:
return {}
enum_name = enum_match.group(1)
enum_body = enum_match.group(2)
values = {}
for line in enum_body.split('\n'):
line = line.strip()
if not line or line.startswith('//'):
continue
# Parse enum values (handle various formats)
if '=' in line:
parts = line.split('=')
if len(parts) >= 2:
name = parts[0].strip().rstrip(',')
value_part = parts[1].strip().rstrip(',')
# Handle hex values
if value_part.startswith('0x'):
try:
value = int(value_part, 16)
values[str(value)] = name
except ValueError:
pass
# Handle decimal values
elif value_part.isdigit():
values[value_part] = name
# Handle expressions (for flags)
elif '|' in value_part:
values[f"EXPR:{value_part}"] = name
else:
# Auto-increment enum
name = line.rstrip(',').strip()
if name and not name.startswith('//'):
values[str(len(values))] = name
return {
'name': enum_name,
'values': values,
'source_file': str(file_path.name)
}
except Exception as e:
print(f"Error extracting enum from {file_path}: {e}")
return {}
def extract_dictionaries_cs(file_path: Path) -> Dict[str, Any]:
"""Extract dictionary mappings from Dictionaries.cs file."""
try:
content = file_path.read_text(encoding='utf-8')
dictionaries = {}
# Look for dictionary definitions with various patterns
dict_patterns = [
r'public static readonly Dictionary<int, string> (\w+) = new Dictionary<int, string>\s*\n\s*{([^}]+)}',
r'public static readonly Dictionary<int, string> (\w+) = new Dictionary<int, string>\(\)\s*\n\s*{([^}]+)}'
]
for pattern in dict_patterns:
for match in re.finditer(pattern, content, re.DOTALL):
dict_name = match.group(1)
dict_body = match.group(2)
values = {}
for line in dict_body.split('\n'):
line = line.strip()
if not line or line.startswith('//'):
continue
# Parse dictionary entries: { 0x1, "value" } or { 1, "value" }
entry_patterns = [
r'{\s*0x([0-9A-Fa-f]+),\s*"([^"]+)"\s*}', # Hex format
r'{\s*(\d+),\s*"([^"]+)"\s*}' # Decimal format
]
for entry_pattern in entry_patterns:
entry_match = re.search(entry_pattern, line)
if entry_match:
key_str = entry_match.group(1)
value = entry_match.group(2)
# Convert hex to decimal if needed
if 'x' in entry_pattern:
key = str(int(key_str, 16))
else:
key = key_str
values[key] = value
break
if values:
dictionaries[dict_name] = {
'name': dict_name,
'values': values,
'source_file': 'Dictionaries.cs'
}
return dictionaries
except Exception as e:
print(f"Error extracting dictionaries: {e}")
return {}
def extract_spells_csv(file_path: Path) -> Dict[str, Any]:
"""Extract spell data from Spells.csv."""
try:
spells = {}
# Try different encodings
for encoding in ['utf-8', 'latin1', 'cp1252']:
try:
with open(file_path, 'r', encoding=encoding) as f:
reader = csv.DictReader(f)
for row in reader:
spell_id = row.get('Id', '').strip()
if spell_id and spell_id.isdigit():
spells[spell_id] = {
'id': int(spell_id),
'name': row.get('Name', '').strip(),
'description': row.get('Description', '').strip(),
'school': row.get('School', '').strip(),
'difficulty': row.get('Difficulty', '').strip(),
'duration': row.get('Duration', '').strip(),
'mana': row.get('Mana', '').strip(),
'family': row.get('Family', '').strip(),
'speed': row.get('Speed', '').strip(),
'target_effect': row.get('TargetEffect', '').strip(),
'target_mask': row.get('TargetMask', '').strip()
}
break
except UnicodeDecodeError:
continue
return {
'name': 'Spells',
'values': spells,
'source_file': 'Spells.csv'
}
except Exception as e:
print(f"Error extracting spells: {e}")
return {}
def extract_object_class_cs(file_path: Path) -> Dict[str, Any]:
"""Extract ObjectClass enum specifically."""
try:
content = file_path.read_text(encoding='utf-8')
# Find ObjectClass enum
enum_match = re.search(r'public enum ObjectClass\s*{([^}]+)}', content, re.DOTALL)
if not enum_match:
return {}
enum_body = enum_match.group(1)
values = {}
current_value = 0
for line in enum_body.split('\n'):
line = line.strip()
if not line or line.startswith('//'):
continue
if '=' in line:
parts = line.split('=')
if len(parts) >= 2:
name = parts[0].strip().rstrip(',')
value_str = parts[1].strip().rstrip(',')
try:
current_value = int(value_str)
values[str(current_value)] = name
current_value += 1
except ValueError:
pass
else:
name = line.rstrip(',').strip()
if name and not name.startswith('//'):
values[str(current_value)] = name
current_value += 1
return {
'name': 'ObjectClass',
'values': values,
'source_file': 'ObjectClass.cs'
}
except Exception as e:
print(f"Error extracting ObjectClass: {e}")
return {}
def main():
base_path = Path('/home/erik/MosswartOverlord/Mag-Plugins/Shared')
constants_path = base_path / 'Constants'
spells_path = base_path / 'Spells'
comprehensive_database = {
'metadata': {
'extracted_at': '2025-06-10',
'source': 'Mag-Plugins/Shared (comprehensive)',
'version': '2.0.0'
},
'enums': {},
'dictionaries': {},
'spells': {},
'object_classes': {}
}
# Extract all constant enums
for cs_file in constants_path.glob('*.cs'):
if cs_file.name in ['Dictionaries.cs']:
continue # Handle separately
enum_data = extract_csharp_enum(cs_file)
if enum_data:
comprehensive_database['enums'][enum_data['name']] = enum_data
print(f"✓ Extracted enum: {enum_data['name']} ({len(enum_data['values'])} values)")
# Extract ObjectClass enum
object_class_file = base_path / 'ObjectClass.cs'
if object_class_file.exists():
object_class_data = extract_object_class_cs(object_class_file)
if object_class_data:
comprehensive_database['object_classes'] = object_class_data
print(f"✓ Extracted ObjectClass: {len(object_class_data['values'])} values")
# Extract dictionaries
dict_file = constants_path / 'Dictionaries.cs'
if dict_file.exists():
dict_data = extract_dictionaries_cs(dict_file)
comprehensive_database['dictionaries'] = dict_data
print(f"✓ Extracted dictionaries: {len(dict_data)} dictionaries")
# Extract spells
spells_file = spells_path / 'Spells.csv'
if spells_file.exists():
spell_data = extract_spells_csv(spells_file)
if spell_data:
comprehensive_database['spells'] = spell_data
print(f"✓ Extracted spells: {len(spell_data['values'])} spells")
# Save comprehensive database
output_file = Path('/home/erik/MosswartOverlord/inventory-service/comprehensive_enum_database_v2.json')
with open(output_file, 'w') as f:
json.dump(comprehensive_database, f, indent=2)
print(f"\n✅ Comprehensive enum database saved to: {output_file}")
print(f"📊 Total enums: {len(comprehensive_database['enums'])}")
print(f"📊 Total dictionaries: {len(comprehensive_database['dictionaries'])}")
print(f"📊 Total spells: {len(comprehensive_database['spells'].get('values', {}))}")
print(f"📊 Object classes: {len(comprehensive_database['object_classes'].get('values', {}))}")
if __name__ == '__main__':
main()