added inventory, updated DB
|
|
@ -15,7 +15,8 @@ RUN python -m pip install --upgrade pip && \
|
||||||
databases[postgresql] \
|
databases[postgresql] \
|
||||||
sqlalchemy \
|
sqlalchemy \
|
||||||
alembic \
|
alembic \
|
||||||
psycopg2-binary
|
psycopg2-binary \
|
||||||
|
httpx
|
||||||
|
|
||||||
## Copy application source code and migration scripts into container
|
## Copy application source code and migration scripts into container
|
||||||
COPY static/ /app/static/
|
COPY static/ /app/static/
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ services:
|
||||||
- "./main.py:/app/main.py"
|
- "./main.py:/app/main.py"
|
||||||
- "./db_async.py:/app/db_async.py"
|
- "./db_async.py:/app/db_async.py"
|
||||||
- "./static:/app/static"
|
- "./static:/app/static"
|
||||||
|
- "./icons:/app/icons"
|
||||||
- "./alembic:/app/alembic"
|
- "./alembic:/app/alembic"
|
||||||
- "./alembic.ini:/app/alembic.ini"
|
- "./alembic.ini:/app/alembic.ini"
|
||||||
environment:
|
environment:
|
||||||
|
|
@ -56,6 +57,49 @@ services:
|
||||||
options:
|
options:
|
||||||
max-size: "10m"
|
max-size: "10m"
|
||||||
max-file: "3"
|
max-file: "3"
|
||||||
|
# Inventory Service: Separate microservice for item data processing
|
||||||
|
inventory-service:
|
||||||
|
build: ./inventory-service
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:8766:8000"
|
||||||
|
depends_on:
|
||||||
|
- inventory-db
|
||||||
|
volumes:
|
||||||
|
- "./inventory-service:/app"
|
||||||
|
environment:
|
||||||
|
DATABASE_URL: "postgresql://inventory_user:${INVENTORY_DB_PASSWORD}@inventory-db:5432/inventory_db"
|
||||||
|
LOG_LEVEL: "${LOG_LEVEL:-INFO}"
|
||||||
|
restart: unless-stopped
|
||||||
|
logging:
|
||||||
|
driver: "json-file"
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "3"
|
||||||
|
|
||||||
|
# Separate database for inventory service
|
||||||
|
inventory-db:
|
||||||
|
image: postgres:14
|
||||||
|
container_name: inventory-db
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: inventory_db
|
||||||
|
POSTGRES_USER: inventory_user
|
||||||
|
POSTGRES_PASSWORD: "${INVENTORY_DB_PASSWORD}"
|
||||||
|
volumes:
|
||||||
|
- inventory-data:/var/lib/postgresql/data
|
||||||
|
ports:
|
||||||
|
- "5433:5432"
|
||||||
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U inventory_user"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
logging:
|
||||||
|
driver: "json-file"
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "3"
|
||||||
|
|
||||||
# Grafana service for visualization and dashboards
|
# Grafana service for visualization and dashboards
|
||||||
grafana:
|
grafana:
|
||||||
image: grafana/grafana:latest
|
image: grafana/grafana:latest
|
||||||
|
|
@ -90,4 +134,5 @@ services:
|
||||||
max-file: "3"
|
max-file: "3"
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
timescale-data:
|
timescale-data:
|
||||||
|
inventory-data:
|
||||||
22
inventory-service/Dockerfile
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
FROM python:3.11-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install system dependencies
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
postgresql-client \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Copy requirements first for better caching
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# Copy application code
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Create non-root user
|
||||||
|
RUN useradd -m -u 1000 inventory && chown -R inventory:inventory /app
|
||||||
|
USER inventory
|
||||||
|
|
||||||
|
# Default command
|
||||||
|
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||||
2230
inventory-service/complete_enum_database.json
Normal file
83516
inventory-service/comprehensive_enum_database_v2.json
Normal file
179
inventory-service/database.py
Normal file
|
|
@ -0,0 +1,179 @@
|
||||||
|
"""
|
||||||
|
Database models and setup for Inventory Service.
|
||||||
|
|
||||||
|
Normalized schema designed around actual item JSON structure with proper enum translation.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import (
|
||||||
|
Column, Integer, String, Float, Boolean, DateTime, BigInteger, Text, JSON,
|
||||||
|
ForeignKey, Index, UniqueConstraint, CheckConstraint, create_engine, MetaData
|
||||||
|
)
|
||||||
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
from sqlalchemy.dialects.postgresql import JSONB
|
||||||
|
from sqlalchemy.orm import relationship
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
Base = declarative_base()
|
||||||
|
|
||||||
|
class Item(Base):
|
||||||
|
"""Core item identification and basic properties."""
|
||||||
|
__tablename__ = 'items'
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
character_name = Column(String(50), nullable=False, index=True)
|
||||||
|
item_id = Column(BigInteger, nullable=False) # Game item instance ID
|
||||||
|
timestamp = Column(DateTime, nullable=False, default=datetime.utcnow)
|
||||||
|
|
||||||
|
# Basic properties (always present)
|
||||||
|
name = Column(String(200), nullable=False, index=True)
|
||||||
|
icon = Column(Integer, nullable=False)
|
||||||
|
object_class = Column(Integer, nullable=False, index=True)
|
||||||
|
|
||||||
|
# Core stats
|
||||||
|
value = Column(Integer, default=0)
|
||||||
|
burden = Column(Integer, default=0)
|
||||||
|
|
||||||
|
# Metadata flags
|
||||||
|
has_id_data = Column(Boolean, default=False)
|
||||||
|
last_id_time = Column(BigInteger, default=0)
|
||||||
|
|
||||||
|
# Unique constraint per character
|
||||||
|
__table_args__ = (
|
||||||
|
UniqueConstraint('character_name', 'item_id', name='uq_char_item'),
|
||||||
|
Index('ix_items_name_char', 'character_name', 'name'),
|
||||||
|
Index('ix_items_class_char', 'character_name', 'object_class'),
|
||||||
|
)
|
||||||
|
|
||||||
|
class ItemCombatStats(Base):
|
||||||
|
"""Combat-related properties for weapons and armor."""
|
||||||
|
__tablename__ = 'item_combat_stats'
|
||||||
|
|
||||||
|
item_id = Column(Integer, ForeignKey('items.id'), primary_key=True)
|
||||||
|
|
||||||
|
# Damage properties
|
||||||
|
max_damage = Column(Integer)
|
||||||
|
damage = Column(Integer)
|
||||||
|
damage_type = Column(Integer)
|
||||||
|
damage_bonus = Column(Float)
|
||||||
|
elemental_damage_bonus = Column(Integer)
|
||||||
|
elemental_damage_vs_monsters = Column(Float)
|
||||||
|
variance = Column(Float)
|
||||||
|
|
||||||
|
# Attack properties
|
||||||
|
attack_bonus = Column(Float)
|
||||||
|
weapon_time = Column(Integer)
|
||||||
|
weapon_skill = Column(Integer)
|
||||||
|
|
||||||
|
# Defense properties
|
||||||
|
armor_level = Column(Integer, index=True)
|
||||||
|
shield_value = Column(Integer)
|
||||||
|
melee_defense_bonus = Column(Float)
|
||||||
|
missile_defense_bonus = Column(Float)
|
||||||
|
magic_defense_bonus = Column(Float)
|
||||||
|
|
||||||
|
# Resistances
|
||||||
|
resist_magic = Column(Integer)
|
||||||
|
|
||||||
|
# Mana properties
|
||||||
|
mana_conversion_bonus = Column(Float)
|
||||||
|
|
||||||
|
class ItemRequirements(Base):
|
||||||
|
"""Wield requirements and skill prerequisites."""
|
||||||
|
__tablename__ = 'item_requirements'
|
||||||
|
|
||||||
|
item_id = Column(Integer, ForeignKey('items.id'), primary_key=True)
|
||||||
|
|
||||||
|
wield_level = Column(Integer, index=True)
|
||||||
|
wield_requirement = Column(Integer)
|
||||||
|
skill_level = Column(Integer)
|
||||||
|
lore_requirement = Column(Integer)
|
||||||
|
|
||||||
|
# String-based requirements (parsed from StringValues)
|
||||||
|
equip_skill = Column(String(50))
|
||||||
|
mastery = Column(String(50))
|
||||||
|
|
||||||
|
class ItemEnhancements(Base):
|
||||||
|
"""Enhancements, materials, and modifications."""
|
||||||
|
__tablename__ = 'item_enhancements'
|
||||||
|
|
||||||
|
item_id = Column(Integer, ForeignKey('items.id'), primary_key=True)
|
||||||
|
|
||||||
|
material = Column(String(50), index=True)
|
||||||
|
imbue = Column(String(50))
|
||||||
|
tinks = Column(Integer)
|
||||||
|
workmanship = Column(Float)
|
||||||
|
salvage_workmanship = Column(Float)
|
||||||
|
|
||||||
|
# Set information
|
||||||
|
item_set = Column(String(100), index=True)
|
||||||
|
|
||||||
|
class ItemRatings(Base):
|
||||||
|
"""Modern rating system properties."""
|
||||||
|
__tablename__ = 'item_ratings'
|
||||||
|
|
||||||
|
item_id = Column(Integer, ForeignKey('items.id'), primary_key=True)
|
||||||
|
|
||||||
|
# Damage ratings
|
||||||
|
damage_rating = Column(Integer)
|
||||||
|
damage_resist_rating = Column(Integer)
|
||||||
|
crit_rating = Column(Integer)
|
||||||
|
crit_resist_rating = Column(Integer)
|
||||||
|
crit_damage_rating = Column(Integer)
|
||||||
|
crit_damage_resist_rating = Column(Integer)
|
||||||
|
|
||||||
|
# Utility ratings
|
||||||
|
heal_boost_rating = Column(Integer)
|
||||||
|
vitality_rating = Column(Integer)
|
||||||
|
mana_conversion_rating = Column(Integer)
|
||||||
|
|
||||||
|
# Calculated totals
|
||||||
|
total_rating = Column(Integer)
|
||||||
|
|
||||||
|
class ItemSpells(Base):
|
||||||
|
"""Spell information for items."""
|
||||||
|
__tablename__ = 'item_spells'
|
||||||
|
|
||||||
|
item_id = Column(Integer, ForeignKey('items.id'), primary_key=True)
|
||||||
|
spell_id = Column(Integer, primary_key=True)
|
||||||
|
is_active = Column(Boolean, default=False)
|
||||||
|
|
||||||
|
class ItemRawData(Base):
|
||||||
|
"""Preserve original raw enum data for completeness."""
|
||||||
|
__tablename__ = 'item_raw_data'
|
||||||
|
|
||||||
|
item_id = Column(Integer, ForeignKey('items.id'), primary_key=True)
|
||||||
|
|
||||||
|
# Raw enum collections
|
||||||
|
int_values = Column(JSONB)
|
||||||
|
double_values = Column(JSONB)
|
||||||
|
string_values = Column(JSONB)
|
||||||
|
bool_values = Column(JSONB)
|
||||||
|
|
||||||
|
# Original full JSON for reference
|
||||||
|
original_json = Column(JSONB)
|
||||||
|
|
||||||
|
# Database URL configuration
|
||||||
|
import os
|
||||||
|
DATABASE_URL = os.getenv("DATABASE_URL", "postgresql://inventory_user:inventory_pass@inventory-db:5432/inventory_db")
|
||||||
|
|
||||||
|
# Create all indexes for performance
|
||||||
|
def create_indexes(engine):
|
||||||
|
"""Create additional performance indexes."""
|
||||||
|
|
||||||
|
# Item search indexes
|
||||||
|
sa.Index('ix_items_search', Item.character_name, Item.name, Item.object_class).create(engine, checkfirst=True)
|
||||||
|
|
||||||
|
# Combat stats indexes for filtering
|
||||||
|
sa.Index('ix_combat_damage', ItemCombatStats.max_damage).create(engine, checkfirst=True)
|
||||||
|
sa.Index('ix_combat_armor', ItemCombatStats.armor_level).create(engine, checkfirst=True)
|
||||||
|
|
||||||
|
# Requirements indexes for filtering
|
||||||
|
sa.Index('ix_req_level', ItemRequirements.wield_level).create(engine, checkfirst=True)
|
||||||
|
|
||||||
|
# Enhancement indexes
|
||||||
|
sa.Index('ix_enh_material_set', ItemEnhancements.material, ItemEnhancements.item_set).create(engine, checkfirst=True)
|
||||||
|
|
||||||
|
# JSONB indexes for raw data querying
|
||||||
|
sa.Index('ix_raw_int_gin', ItemRawData.int_values, postgresql_using='gin').create(engine, checkfirst=True)
|
||||||
|
sa.Index('ix_raw_original_gin', ItemRawData.original_json, postgresql_using='gin').create(engine, checkfirst=True)
|
||||||
147
inventory-service/enums/BoolValueKey.json
Normal file
|
|
@ -0,0 +1,147 @@
|
||||||
|
{
|
||||||
|
"BoolValueKey": {
|
||||||
|
"type": "int",
|
||||||
|
"values": {
|
||||||
|
"0": "Undef",
|
||||||
|
"1": "Stuck",
|
||||||
|
"2": "Open",
|
||||||
|
"3": "Locked",
|
||||||
|
"4": "RotProof",
|
||||||
|
"5": "AllegianceUpdateRequest",
|
||||||
|
"6": "AiUsesMana",
|
||||||
|
"7": "AiUseHumanMagicAnimations",
|
||||||
|
"8": "AllowGive",
|
||||||
|
"9": "CurrentlyAttacking",
|
||||||
|
"10": "AttackerAi",
|
||||||
|
"11": "IgnoreCollisions",
|
||||||
|
"12": "ReportCollisions",
|
||||||
|
"13": "Ethereal",
|
||||||
|
"14": "GravityStatus",
|
||||||
|
"15": "LightsStatus",
|
||||||
|
"16": "ScriptedCollision",
|
||||||
|
"17": "Inelastic",
|
||||||
|
"18": "Visibility",
|
||||||
|
"19": "Attackable",
|
||||||
|
"20": "SafeSpellComponents",
|
||||||
|
"21": "AdvocateState",
|
||||||
|
"22": "Inscribable",
|
||||||
|
"23": "DestroyOnSell",
|
||||||
|
"24": "UiHidden",
|
||||||
|
"25": "IgnoreHouseBarriers",
|
||||||
|
"26": "HiddenAdmin",
|
||||||
|
"27": "PkWounder",
|
||||||
|
"28": "PkKiller",
|
||||||
|
"29": "NoCorpse",
|
||||||
|
"30": "UnderLifestoneProtection",
|
||||||
|
"31": "ItemManaUpdatePending",
|
||||||
|
"32": "GeneratorStatus",
|
||||||
|
"33": "ResetMessagePending",
|
||||||
|
"34": "DefaultOpen",
|
||||||
|
"35": "DefaultLocked",
|
||||||
|
"36": "DefaultOn",
|
||||||
|
"37": "OpenForBusiness",
|
||||||
|
"38": "IsFrozen",
|
||||||
|
"39": "DealMagicalItems",
|
||||||
|
"40": "LogoffImDead",
|
||||||
|
"41": "ReportCollisionsAsEnvironment",
|
||||||
|
"42": "AllowEdgeSlide",
|
||||||
|
"43": "AdvocateQuest",
|
||||||
|
"44": "IsAdmin",
|
||||||
|
"45": "IsArch",
|
||||||
|
"46": "IsSentinel",
|
||||||
|
"47": "IsAdvocate",
|
||||||
|
"48": "CurrentlyPoweringUp",
|
||||||
|
"49": "GeneratorEnteredWorld",
|
||||||
|
"50": "NeverFailCasting",
|
||||||
|
"51": "VendorService",
|
||||||
|
"52": "AiImmobile",
|
||||||
|
"53": "DamagedByCollisions",
|
||||||
|
"54": "IsDynamic",
|
||||||
|
"55": "IsHot",
|
||||||
|
"56": "IsAffecting",
|
||||||
|
"57": "AffectsAis",
|
||||||
|
"58": "SpellQueueActive",
|
||||||
|
"59": "GeneratorDisabled",
|
||||||
|
"60": "IsAcceptingTells",
|
||||||
|
"61": "LoggingChannel",
|
||||||
|
"62": "OpensAnyLock",
|
||||||
|
"63": "UnlimitedUse",
|
||||||
|
"64": "GeneratedTreasureItem",
|
||||||
|
"65": "IgnoreMagicResist",
|
||||||
|
"66": "IgnoreMagicArmor",
|
||||||
|
"67": "AiAllowTrade",
|
||||||
|
"68": "SpellComponentsRequired",
|
||||||
|
"69": "IsSellable",
|
||||||
|
"70": "IgnoreShieldsBySkill",
|
||||||
|
"71": "NoDraw",
|
||||||
|
"72": "ActivationUntargeted",
|
||||||
|
"73": "HouseHasGottenPriorityBootPos",
|
||||||
|
"74": "GeneratorAutomaticDestruction",
|
||||||
|
"75": "HouseHooksVisible",
|
||||||
|
"76": "HouseRequiresMonarch",
|
||||||
|
"77": "HouseHooksEnabled",
|
||||||
|
"78": "HouseNotifiedHudOfHookCount",
|
||||||
|
"79": "AiAcceptEverything",
|
||||||
|
"80": "IgnorePortalRestrictions",
|
||||||
|
"81": "RequiresBackpackSlot",
|
||||||
|
"82": "DontTurnOrMoveWhenGiving",
|
||||||
|
"83": "NpcLooksLikeObject",
|
||||||
|
"84": "IgnoreCloIcons",
|
||||||
|
"85": "AppraisalHasAllowedWielder",
|
||||||
|
"86": "ChestRegenOnClose",
|
||||||
|
"87": "LogoffInMinigame",
|
||||||
|
"88": "PortalShowDestination",
|
||||||
|
"89": "PortalIgnoresPkAttackTimer",
|
||||||
|
"90": "NpcInteractsSilently",
|
||||||
|
"91": "Retained",
|
||||||
|
"92": "IgnoreAuthor",
|
||||||
|
"93": "Limbo",
|
||||||
|
"94": "AppraisalHasAllowedActivator",
|
||||||
|
"95": "ExistedBeforeAllegianceXpChanges",
|
||||||
|
"96": "IsDeaf",
|
||||||
|
"97": "IsPsr",
|
||||||
|
"98": "Invincible",
|
||||||
|
"99": "Ivoryable",
|
||||||
|
"100": "Dyable",
|
||||||
|
"101": "CanGenerateRare",
|
||||||
|
"102": "CorpseGeneratedRare",
|
||||||
|
"103": "NonProjectileMagicImmune",
|
||||||
|
"104": "ActdReceivedItems",
|
||||||
|
"105": "Unknown105",
|
||||||
|
"106": "FirstEnterWorldDone",
|
||||||
|
"107": "RecallsDisabled",
|
||||||
|
"108": "RareUsesTimer",
|
||||||
|
"109": "ActdPreorderReceivedItems",
|
||||||
|
"110": "Afk",
|
||||||
|
"111": "IsGagged",
|
||||||
|
"112": "ProcSpellSelfTargeted",
|
||||||
|
"113": "IsAllegianceGagged",
|
||||||
|
"114": "EquipmentSetTriggerPiece",
|
||||||
|
"115": "Uninscribe",
|
||||||
|
"116": "WieldOnUse",
|
||||||
|
"117": "ChestClearedWhenClosed",
|
||||||
|
"118": "NeverAttack",
|
||||||
|
"119": "SuppressGenerateEffect",
|
||||||
|
"120": "TreasureCorpse",
|
||||||
|
"121": "EquipmentSetAddLevel",
|
||||||
|
"122": "BarberActive",
|
||||||
|
"123": "TopLayerPriority",
|
||||||
|
"124": "NoHeldItemShown",
|
||||||
|
"125": "LoginAtLifestone",
|
||||||
|
"126": "OlthoiPk",
|
||||||
|
"127": "Account15Days",
|
||||||
|
"128": "HadNoVitae",
|
||||||
|
"129": "NoOlthoiTalk",
|
||||||
|
"130": "AutowieldLeft",
|
||||||
|
"9001": "LinkedPortalOneSummon",
|
||||||
|
"9002": "LinkedPortalTwoSummon",
|
||||||
|
"9003": "HouseEvicted",
|
||||||
|
"9004": "UntrainedSkills",
|
||||||
|
"201326592": "Lockable_Decal",
|
||||||
|
"201326593": "Inscribable_Decal"
|
||||||
|
},
|
||||||
|
"comments": {},
|
||||||
|
"attributes": {},
|
||||||
|
"source_file": "BoolValueKey.cs"
|
||||||
|
}
|
||||||
|
}
|
||||||
33
inventory-service/enums/CoverageMask.json
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
{
|
||||||
|
"CoverageMask": {
|
||||||
|
"type": "int",
|
||||||
|
"values": {
|
||||||
|
"0": "None",
|
||||||
|
"1": "Unknown",
|
||||||
|
"2": "UnderwearUpperLegs",
|
||||||
|
"4": "UnderwearLowerLegs",
|
||||||
|
"8": "UnderwearChest",
|
||||||
|
"16": "UnderwearAbdomen",
|
||||||
|
"32": "UnderwearUpperArms",
|
||||||
|
"64": "UnderwearLowerArms",
|
||||||
|
"256": "OuterwearUpperLegs",
|
||||||
|
"512": "OuterwearLowerLegs",
|
||||||
|
"1024": "OuterwearChest",
|
||||||
|
"2048": "OuterwearAbdomen",
|
||||||
|
"4096": "OuterwearUpperArms",
|
||||||
|
"8192": "OuterwearLowerArms",
|
||||||
|
"16384": "Head",
|
||||||
|
"32768": "Hands",
|
||||||
|
"65536": "Feet",
|
||||||
|
"131072": "Cloak"
|
||||||
|
},
|
||||||
|
"comments": {
|
||||||
|
"Unknown": "Original pants abdomen?",
|
||||||
|
"UnderwearUpperLegs": "I think... 0x13 = Abdomen/UpperLegs",
|
||||||
|
"UnderwearLowerLegs": "I think... 0x16 = Abdomen/UpperLegs/LowerLegs",
|
||||||
|
"UnderwearAbdomen": "Original shirt abdomen?"
|
||||||
|
},
|
||||||
|
"attributes": {},
|
||||||
|
"source_file": "CoverageMask.cs"
|
||||||
|
}
|
||||||
|
}
|
||||||
207
inventory-service/enums/DoubleValueKey.json
Normal file
|
|
@ -0,0 +1,207 @@
|
||||||
|
{
|
||||||
|
"DoubleValueKey": {
|
||||||
|
"type": "int",
|
||||||
|
"values": {
|
||||||
|
"0": "Undef",
|
||||||
|
"1": "HeartbeatInterval",
|
||||||
|
"2": "HeartbeatTimestamp",
|
||||||
|
"3": "HealthRate",
|
||||||
|
"4": "StaminaRate",
|
||||||
|
"5": "ManaRate",
|
||||||
|
"6": "HealthUponResurrection",
|
||||||
|
"7": "StaminaUponResurrection",
|
||||||
|
"8": "ManaUponResurrection",
|
||||||
|
"9": "StartTime",
|
||||||
|
"10": "StopTime",
|
||||||
|
"11": "ResetInterval",
|
||||||
|
"12": "Shade",
|
||||||
|
"13": "ArmorModVsSlash",
|
||||||
|
"14": "ArmorModVsPierce",
|
||||||
|
"15": "ArmorModVsBludgeon",
|
||||||
|
"16": "ArmorModVsCold",
|
||||||
|
"17": "ArmorModVsFire",
|
||||||
|
"18": "ArmorModVsAcid",
|
||||||
|
"19": "ArmorModVsElectric",
|
||||||
|
"20": "CombatSpeed",
|
||||||
|
"21": "WeaponLength",
|
||||||
|
"22": "DamageVariance",
|
||||||
|
"23": "CurrentPowerMod",
|
||||||
|
"24": "AccuracyMod",
|
||||||
|
"25": "StrengthMod",
|
||||||
|
"26": "MaximumVelocity",
|
||||||
|
"27": "RotationSpeed",
|
||||||
|
"28": "MotionTimestamp",
|
||||||
|
"29": "WeaponDefense",
|
||||||
|
"30": "WimpyLevel",
|
||||||
|
"31": "VisualAwarenessRange",
|
||||||
|
"32": "AuralAwarenessRange",
|
||||||
|
"33": "PerceptionLevel",
|
||||||
|
"34": "PowerupTime",
|
||||||
|
"35": "MaxChargeDistance",
|
||||||
|
"36": "ChargeSpeed",
|
||||||
|
"37": "BuyPrice",
|
||||||
|
"38": "SellPrice",
|
||||||
|
"39": "DefaultScale",
|
||||||
|
"40": "LockpickMod",
|
||||||
|
"41": "RegenerationInterval",
|
||||||
|
"42": "RegenerationTimestamp",
|
||||||
|
"43": "GeneratorRadius",
|
||||||
|
"44": "TimeToRot",
|
||||||
|
"45": "DeathTimestamp",
|
||||||
|
"46": "PkTimestamp",
|
||||||
|
"47": "VictimTimestamp",
|
||||||
|
"48": "LoginTimestamp",
|
||||||
|
"49": "CreationTimestamp",
|
||||||
|
"50": "MinimumTimeSincePk",
|
||||||
|
"51": "DeprecatedHousekeepingPriority",
|
||||||
|
"52": "AbuseLoggingTimestamp",
|
||||||
|
"53": "LastPortalTeleportTimestamp",
|
||||||
|
"54": "UseRadius",
|
||||||
|
"55": "HomeRadius",
|
||||||
|
"56": "ReleasedTimestamp",
|
||||||
|
"57": "MinHomeRadius",
|
||||||
|
"58": "Facing",
|
||||||
|
"59": "ResetTimestamp",
|
||||||
|
"60": "LogoffTimestamp",
|
||||||
|
"61": "EconRecoveryInterval",
|
||||||
|
"62": "WeaponOffense",
|
||||||
|
"63": "DamageMod",
|
||||||
|
"64": "ResistSlash",
|
||||||
|
"65": "ResistPierce",
|
||||||
|
"66": "ResistBludgeon",
|
||||||
|
"67": "ResistFire",
|
||||||
|
"68": "ResistCold",
|
||||||
|
"69": "ResistAcid",
|
||||||
|
"70": "ResistElectric",
|
||||||
|
"71": "ResistHealthBoost",
|
||||||
|
"72": "ResistStaminaDrain",
|
||||||
|
"73": "ResistStaminaBoost",
|
||||||
|
"74": "ResistManaDrain",
|
||||||
|
"75": "ResistManaBoost",
|
||||||
|
"76": "Translucency",
|
||||||
|
"77": "PhysicsScriptIntensity",
|
||||||
|
"78": "Friction",
|
||||||
|
"79": "Elasticity",
|
||||||
|
"80": "AiUseMagicDelay",
|
||||||
|
"81": "ItemMinSpellcraftMod",
|
||||||
|
"82": "ItemMaxSpellcraftMod",
|
||||||
|
"83": "ItemRankProbability",
|
||||||
|
"84": "Shade2",
|
||||||
|
"85": "Shade3",
|
||||||
|
"86": "Shade4",
|
||||||
|
"87": "ItemEfficiency",
|
||||||
|
"88": "ItemManaUpdateTimestamp",
|
||||||
|
"89": "SpellGestureSpeedMod",
|
||||||
|
"90": "SpellStanceSpeedMod",
|
||||||
|
"91": "AllegianceAppraisalTimestamp",
|
||||||
|
"92": "PowerLevel",
|
||||||
|
"93": "AccuracyLevel",
|
||||||
|
"94": "AttackAngle",
|
||||||
|
"95": "AttackTimestamp",
|
||||||
|
"96": "CheckpointTimestamp",
|
||||||
|
"97": "SoldTimestamp",
|
||||||
|
"98": "UseTimestamp",
|
||||||
|
"99": "UseLockTimestamp",
|
||||||
|
"100": "HealkitMod",
|
||||||
|
"101": "FrozenTimestamp",
|
||||||
|
"102": "HealthRateMod",
|
||||||
|
"103": "AllegianceSwearTimestamp",
|
||||||
|
"104": "ObviousRadarRange",
|
||||||
|
"105": "HotspotCycleTime",
|
||||||
|
"106": "HotspotCycleTimeVariance",
|
||||||
|
"107": "SpamTimestamp",
|
||||||
|
"108": "SpamRate",
|
||||||
|
"109": "BondWieldedTreasure",
|
||||||
|
"110": "BulkMod",
|
||||||
|
"111": "SizeMod",
|
||||||
|
"112": "GagTimestamp",
|
||||||
|
"113": "GeneratorUpdateTimestamp",
|
||||||
|
"114": "DeathSpamTimestamp",
|
||||||
|
"115": "DeathSpamRate",
|
||||||
|
"116": "WildAttackProbability",
|
||||||
|
"117": "FocusedProbability",
|
||||||
|
"118": "CrashAndTurnProbability",
|
||||||
|
"119": "CrashAndTurnRadius",
|
||||||
|
"120": "CrashAndTurnBias",
|
||||||
|
"121": "GeneratorInitialDelay",
|
||||||
|
"122": "AiAcquireHealth",
|
||||||
|
"123": "AiAcquireStamina",
|
||||||
|
"124": "AiAcquireMana",
|
||||||
|
"125": "ResistHealthDrain",
|
||||||
|
"126": "LifestoneProtectionTimestamp",
|
||||||
|
"127": "AiCounteractEnchantment",
|
||||||
|
"128": "AiDispelEnchantment",
|
||||||
|
"129": "TradeTimestamp",
|
||||||
|
"130": "AiTargetedDetectionRadius",
|
||||||
|
"131": "EmotePriority",
|
||||||
|
"132": "LastTeleportStartTimestamp",
|
||||||
|
"133": "EventSpamTimestamp",
|
||||||
|
"134": "EventSpamRate",
|
||||||
|
"135": "InventoryOffset",
|
||||||
|
"136": "CriticalMultiplier",
|
||||||
|
"137": "ManaStoneDestroyChance",
|
||||||
|
"138": "SlayerDamageBonus",
|
||||||
|
"139": "AllegianceInfoSpamTimestamp",
|
||||||
|
"140": "AllegianceInfoSpamRate",
|
||||||
|
"141": "NextSpellcastTimestamp",
|
||||||
|
"142": "AppraisalRequestedTimestamp",
|
||||||
|
"143": "AppraisalHeartbeatDueTimestamp",
|
||||||
|
"144": "ManaConversionMod",
|
||||||
|
"145": "LastPkAttackTimestamp",
|
||||||
|
"146": "FellowshipUpdateTimestamp",
|
||||||
|
"147": "CriticalFrequency",
|
||||||
|
"148": "LimboStartTimestamp",
|
||||||
|
"149": "WeaponMissileDefense",
|
||||||
|
"150": "WeaponMagicDefense",
|
||||||
|
"151": "IgnoreShield",
|
||||||
|
"152": "ElementalDamageMod",
|
||||||
|
"153": "StartMissileAttackTimestamp",
|
||||||
|
"154": "LastRareUsedTimestamp",
|
||||||
|
"155": "IgnoreArmor",
|
||||||
|
"156": "ProcSpellRate",
|
||||||
|
"157": "ResistanceModifier",
|
||||||
|
"158": "AllegianceGagTimestamp",
|
||||||
|
"159": "AbsorbMagicDamage",
|
||||||
|
"160": "CachedMaxAbsorbMagicDamage",
|
||||||
|
"161": "GagDuration",
|
||||||
|
"162": "AllegianceGagDuration",
|
||||||
|
"163": "GlobalXpMod",
|
||||||
|
"164": "HealingModifier",
|
||||||
|
"165": "ArmorModVsNether",
|
||||||
|
"166": "ResistNether",
|
||||||
|
"167": "CooldownDuration",
|
||||||
|
"168": "WeaponAuraOffense",
|
||||||
|
"169": "WeaponAuraDefense",
|
||||||
|
"170": "WeaponAuraElemental",
|
||||||
|
"171": "WeaponAuraManaConv",
|
||||||
|
"8004": "PCAPRecordedWorkmanship",
|
||||||
|
"8010": "PCAPRecordedVelocityX",
|
||||||
|
"8011": "PCAPRecordedVelocityY",
|
||||||
|
"8012": "PCAPRecordedVelocityZ",
|
||||||
|
"8013": "PCAPRecordedAccelerationX",
|
||||||
|
"8014": "PCAPRecordedAccelerationY",
|
||||||
|
"8015": "PCAPRecordedAccelerationZ",
|
||||||
|
"8016": "PCAPRecordeOmegaX",
|
||||||
|
"8017": "PCAPRecordeOmegaY",
|
||||||
|
"8018": "PCAPRecordeOmegaZ",
|
||||||
|
"167772160": "SlashProt_Decal",
|
||||||
|
"167772161": "PierceProt_Decal",
|
||||||
|
"167772162": "BludgeonProt_Decal",
|
||||||
|
"167772163": "AcidProt_Decal",
|
||||||
|
"167772164": "LightningProt_Decal",
|
||||||
|
"167772165": "FireProt_Decal",
|
||||||
|
"167772166": "ColdProt_Decal",
|
||||||
|
"167772167": "Heading_Decal",
|
||||||
|
"167772168": "ApproachDistance_Decal",
|
||||||
|
"167772169": "SalvageWorkmanship_Decal",
|
||||||
|
"167772170": "Scale_Decal",
|
||||||
|
"167772171": "Variance_Decal",
|
||||||
|
"167772172": "AttackBonus_Decal",
|
||||||
|
"167772173": "Range_Decal",
|
||||||
|
"167772174": "DamageBonus_Decal"
|
||||||
|
},
|
||||||
|
"comments": {},
|
||||||
|
"attributes": {},
|
||||||
|
"source_file": "DoubleValueKey.cs"
|
||||||
|
}
|
||||||
|
}
|
||||||
60
inventory-service/enums/EquipMask.json
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
{
|
||||||
|
"EquipMask": {
|
||||||
|
"type": "uint",
|
||||||
|
"values": {
|
||||||
|
"0": "None",
|
||||||
|
"1": "HeadWear",
|
||||||
|
"2": "ChestWear",
|
||||||
|
"4": "AbdomenWear",
|
||||||
|
"8": "UpperArmWear",
|
||||||
|
"16": "LowerArmWear",
|
||||||
|
"32": "HandWear",
|
||||||
|
"64": "UpperLegWear",
|
||||||
|
"128": "LowerLegWear",
|
||||||
|
"256": "FootWear",
|
||||||
|
"512": "ChestArmor",
|
||||||
|
"1024": "AbdomenArmor",
|
||||||
|
"2048": "UpperArmArmor",
|
||||||
|
"4096": "LowerArmArmor",
|
||||||
|
"8192": "UpperLegArmor",
|
||||||
|
"16384": "LowerLegArmor",
|
||||||
|
"32768": "NeckWear",
|
||||||
|
"65536": "WristWearLeft",
|
||||||
|
"131072": "WristWearRight",
|
||||||
|
"262144": "FingerWearLeft",
|
||||||
|
"524288": "FingerWearRight",
|
||||||
|
"1048576": "MeleeWeapon",
|
||||||
|
"2097152": "Shield",
|
||||||
|
"4194304": "MissileWeapon",
|
||||||
|
"8388608": "MissileAmmo",
|
||||||
|
"16777216": "Held",
|
||||||
|
"33554432": "TwoHanded",
|
||||||
|
"67108864": "TrinketOne",
|
||||||
|
"134217728": "Cloak",
|
||||||
|
"268435456": "SigilOne",
|
||||||
|
"536870912": "SigilTwo",
|
||||||
|
"1073741824": "SigilThree",
|
||||||
|
"EXPR:0x80000000 | HeadWear | ChestWear | AbdomenWear | UpperArmWear | LowerArmWear | HandWear | UpperLegWear | LowerLegWear | FootWear": "Clothing",
|
||||||
|
"EXPR:ChestArmor | AbdomenArmor | UpperArmArmor | LowerArmArmor | UpperLegArmor | LowerLegArmor | FootWear": "Armor",
|
||||||
|
"EXPR:ChestArmor | AbdomenArmor | UpperArmArmor | LowerArmArmor | UpperLegArmor | LowerLegArmor": "ArmorExclusive",
|
||||||
|
"EXPR:HeadWear | HandWear | FootWear": "Extremity",
|
||||||
|
"EXPR:NeckWear | WristWearLeft | WristWearRight | FingerWearLeft | FingerWearRight | TrinketOne | Cloak | SigilOne | SigilTwo | SigilThree": "Jewelry",
|
||||||
|
"EXPR:WristWearLeft | WristWearRight": "WristWear",
|
||||||
|
"EXPR:FingerWearLeft | FingerWearRight": "FingerWear",
|
||||||
|
"EXPR:SigilOne | SigilTwo | SigilThree": "Sigil",
|
||||||
|
"EXPR:Held | TwoHanded | TrinketOne | Cloak | SigilOne | SigilTwo": "ReadySlot",
|
||||||
|
"EXPR:SigilTwo | TrinketOne | Held": "Weapon",
|
||||||
|
"EXPR:SigilOne | SigilTwo | TrinketOne | Held": "WeaponReadySlot",
|
||||||
|
"EXPR:MeleeWeapon | Shield | MissileWeapon | Held | TwoHanded": "Selectable",
|
||||||
|
"EXPR:Selectable | MissileAmmo": "SelectablePlusAmmo",
|
||||||
|
"2147483647": "CanGoInReadySlot"
|
||||||
|
},
|
||||||
|
"comments": {
|
||||||
|
"SigilOne": "Blue",
|
||||||
|
"SigilTwo": "Yellow",
|
||||||
|
"SigilThree": "Red"
|
||||||
|
},
|
||||||
|
"attributes": {},
|
||||||
|
"source_file": "EquipMask.cs"
|
||||||
|
}
|
||||||
|
}
|
||||||
463
inventory-service/enums/IntValueKey.json
Normal file
|
|
@ -0,0 +1,463 @@
|
||||||
|
{
|
||||||
|
"IntValueKey": {
|
||||||
|
"type": "int",
|
||||||
|
"values": {
|
||||||
|
"0": "Undef",
|
||||||
|
"1": "ItemType",
|
||||||
|
"2": "CreatureType",
|
||||||
|
"3": "PaletteTemplate",
|
||||||
|
"4": "ClothingPriority",
|
||||||
|
"5": "EncumbranceVal",
|
||||||
|
"6": "ItemsCapacity",
|
||||||
|
"7": "ContainersCapacity",
|
||||||
|
"8": "Mass",
|
||||||
|
"9": "ValidLocations",
|
||||||
|
"10": "CurrentWieldedLocation",
|
||||||
|
"11": "MaxStackSize",
|
||||||
|
"12": "StackSize",
|
||||||
|
"13": "StackUnitEncumbrance",
|
||||||
|
"14": "StackUnitMass",
|
||||||
|
"15": "StackUnitValue",
|
||||||
|
"16": "ItemUseable",
|
||||||
|
"17": "RareId",
|
||||||
|
"18": "UiEffects",
|
||||||
|
"19": "Value",
|
||||||
|
"20": "CoinValue",
|
||||||
|
"21": "TotalExperience",
|
||||||
|
"22": "AvailableCharacter",
|
||||||
|
"23": "TotalSkillCredits",
|
||||||
|
"24": "AvailableSkillCredits",
|
||||||
|
"25": "Level",
|
||||||
|
"26": "AccountRequirements",
|
||||||
|
"27": "ArmorType",
|
||||||
|
"28": "ArmorLevel",
|
||||||
|
"29": "AllegianceCpPool",
|
||||||
|
"30": "AllegianceRank",
|
||||||
|
"31": "ChannelsAllowed",
|
||||||
|
"32": "ChannelsActive",
|
||||||
|
"33": "Bonded",
|
||||||
|
"34": "MonarchsRank",
|
||||||
|
"35": "AllegianceFollowers",
|
||||||
|
"36": "ResistMagic",
|
||||||
|
"37": "ResistItemAppraisal",
|
||||||
|
"38": "ResistLockpick",
|
||||||
|
"39": "DeprecatedResistRepair",
|
||||||
|
"40": "CombatMode",
|
||||||
|
"41": "CurrentAttackHeight",
|
||||||
|
"42": "CombatCollisions",
|
||||||
|
"43": "NumDeaths",
|
||||||
|
"44": "Damage",
|
||||||
|
"45": "DamageType",
|
||||||
|
"46": "DefaultCombatStyle",
|
||||||
|
"47": "AttackType",
|
||||||
|
"48": "WeaponSkill",
|
||||||
|
"49": "WeaponTime",
|
||||||
|
"50": "AmmoType",
|
||||||
|
"51": "CombatUse",
|
||||||
|
"52": "ParentLocation",
|
||||||
|
"53": "PlacementPosition",
|
||||||
|
"54": "WeaponEncumbrance",
|
||||||
|
"55": "WeaponMass",
|
||||||
|
"56": "ShieldValue",
|
||||||
|
"57": "ShieldEncumbrance",
|
||||||
|
"58": "MissileInventoryLocation",
|
||||||
|
"59": "FullDamageType",
|
||||||
|
"60": "WeaponRange",
|
||||||
|
"61": "AttackersSkill",
|
||||||
|
"62": "DefendersSkill",
|
||||||
|
"63": "AttackersSkillValue",
|
||||||
|
"64": "AttackersClass",
|
||||||
|
"65": "Placement",
|
||||||
|
"66": "CheckpointStatus",
|
||||||
|
"67": "Tolerance",
|
||||||
|
"68": "TargetingTactic",
|
||||||
|
"69": "CombatTactic",
|
||||||
|
"70": "HomesickTargetingTactic",
|
||||||
|
"71": "NumFollowFailures",
|
||||||
|
"72": "FriendType",
|
||||||
|
"73": "FoeType",
|
||||||
|
"74": "MerchandiseItemTypes",
|
||||||
|
"75": "MerchandiseMinValue",
|
||||||
|
"76": "MerchandiseMaxValue",
|
||||||
|
"77": "NumItemsSold",
|
||||||
|
"78": "NumItemsBought",
|
||||||
|
"79": "MoneyIncome",
|
||||||
|
"80": "MoneyOutflow",
|
||||||
|
"81": "MaxGeneratedObjects",
|
||||||
|
"82": "InitGeneratedObjects",
|
||||||
|
"83": "ActivationResponse",
|
||||||
|
"84": "OriginalValue",
|
||||||
|
"85": "NumMoveFailures",
|
||||||
|
"86": "MinLevel",
|
||||||
|
"87": "MaxLevel",
|
||||||
|
"88": "LockpickMod",
|
||||||
|
"89": "BoosterEnum",
|
||||||
|
"90": "BoostValue",
|
||||||
|
"91": "MaxStructure",
|
||||||
|
"92": "Structure",
|
||||||
|
"93": "PhysicsState",
|
||||||
|
"94": "TargetType",
|
||||||
|
"95": "RadarBlipColor",
|
||||||
|
"96": "EncumbranceCapacity",
|
||||||
|
"97": "LoginTimestamp",
|
||||||
|
"98": "CreationTimestamp",
|
||||||
|
"99": "PkLevelModifier",
|
||||||
|
"100": "GeneratorType",
|
||||||
|
"101": "AiAllowedCombatStyle",
|
||||||
|
"102": "LogoffTimestamp",
|
||||||
|
"103": "GeneratorDestructionType",
|
||||||
|
"104": "ActivationCreateClass",
|
||||||
|
"105": "ItemWorkmanship",
|
||||||
|
"106": "ItemSpellcraft",
|
||||||
|
"107": "ItemCurMana",
|
||||||
|
"108": "ItemMaxMana",
|
||||||
|
"109": "ItemDifficulty",
|
||||||
|
"110": "ItemAllegianceRankLimit",
|
||||||
|
"111": "PortalBitmask",
|
||||||
|
"112": "AdvocateLevel",
|
||||||
|
"113": "Gender",
|
||||||
|
"114": "Attuned",
|
||||||
|
"115": "ItemSkillLevelLimit",
|
||||||
|
"116": "GateLogic",
|
||||||
|
"117": "ItemManaCost",
|
||||||
|
"118": "Logoff",
|
||||||
|
"119": "Active",
|
||||||
|
"120": "AttackHeight",
|
||||||
|
"121": "NumAttackFailures",
|
||||||
|
"122": "AiCpThreshold",
|
||||||
|
"123": "AiAdvancementStrategy",
|
||||||
|
"124": "Version",
|
||||||
|
"125": "Age",
|
||||||
|
"126": "VendorHappyMean",
|
||||||
|
"127": "VendorHappyVariance",
|
||||||
|
"128": "CloakStatus",
|
||||||
|
"129": "VitaeCpPool",
|
||||||
|
"130": "NumServicesSold",
|
||||||
|
"131": "MaterialType",
|
||||||
|
"132": "NumAllegianceBreaks",
|
||||||
|
"133": "ShowableOnRadar",
|
||||||
|
"134": "PlayerKillerStatus",
|
||||||
|
"135": "VendorHappyMaxItems",
|
||||||
|
"136": "ScorePageNum",
|
||||||
|
"137": "ScoreConfigNum",
|
||||||
|
"138": "ScoreNumScores",
|
||||||
|
"139": "DeathLevel",
|
||||||
|
"140": "AiOptions",
|
||||||
|
"141": "OpenToEveryone",
|
||||||
|
"142": "GeneratorTimeType",
|
||||||
|
"143": "GeneratorStartTime",
|
||||||
|
"144": "GeneratorEndTime",
|
||||||
|
"145": "GeneratorEndDestructionType",
|
||||||
|
"146": "XpOverride",
|
||||||
|
"147": "NumCrashAndTurns",
|
||||||
|
"148": "ComponentWarningThreshold",
|
||||||
|
"149": "HouseStatus",
|
||||||
|
"150": "HookPlacement",
|
||||||
|
"151": "HookType",
|
||||||
|
"152": "HookItemType",
|
||||||
|
"153": "AiPpThreshold",
|
||||||
|
"154": "GeneratorVersion",
|
||||||
|
"155": "HouseType",
|
||||||
|
"156": "PickupEmoteOffset",
|
||||||
|
"157": "WeenieIteration",
|
||||||
|
"158": "WieldRequirements",
|
||||||
|
"159": "WieldSkillType",
|
||||||
|
"160": "WieldDifficulty",
|
||||||
|
"161": "HouseMaxHooksUsable",
|
||||||
|
"162": "HouseCurrentHooksUsable",
|
||||||
|
"163": "AllegianceMinLevel",
|
||||||
|
"164": "AllegianceMaxLevel",
|
||||||
|
"165": "HouseRelinkHookCount",
|
||||||
|
"166": "SlayerCreatureType",
|
||||||
|
"167": "ConfirmationInProgress",
|
||||||
|
"168": "ConfirmationTypeInProgress",
|
||||||
|
"169": "TsysMutationData",
|
||||||
|
"170": "NumItemsInMaterial",
|
||||||
|
"171": "NumTimesTinkered",
|
||||||
|
"172": "AppraisalLongDescDecoration",
|
||||||
|
"173": "AppraisalLockpickSuccessPercent",
|
||||||
|
"174": "AppraisalPages",
|
||||||
|
"175": "AppraisalMaxPages",
|
||||||
|
"176": "AppraisalItemSkill",
|
||||||
|
"177": "GemCount",
|
||||||
|
"178": "GemType",
|
||||||
|
"179": "ImbuedEffect",
|
||||||
|
"180": "AttackersRawSkillValue",
|
||||||
|
"181": "ChessRank",
|
||||||
|
"182": "ChessTotalGames",
|
||||||
|
"183": "ChessGamesWon",
|
||||||
|
"184": "ChessGamesLost",
|
||||||
|
"185": "TypeOfAlteration",
|
||||||
|
"186": "SkillToBeAltered",
|
||||||
|
"187": "SkillAlterationCount",
|
||||||
|
"188": "HeritageGroup",
|
||||||
|
"189": "TransferFromAttribute",
|
||||||
|
"190": "TransferToAttribute",
|
||||||
|
"191": "AttributeTransferCount",
|
||||||
|
"192": "FakeFishingSkill",
|
||||||
|
"193": "NumKeys",
|
||||||
|
"194": "DeathTimestamp",
|
||||||
|
"195": "PkTimestamp",
|
||||||
|
"196": "VictimTimestamp",
|
||||||
|
"197": "HookGroup",
|
||||||
|
"198": "AllegianceSwearTimestamp",
|
||||||
|
"199": "HousePurchaseTimestamp",
|
||||||
|
"200": "RedirectableEquippedArmorCount",
|
||||||
|
"201": "MeleeDefenseImbuedEffectTypeCache",
|
||||||
|
"202": "MissileDefenseImbuedEffectTypeCache",
|
||||||
|
"203": "MagicDefenseImbuedEffectTypeCache",
|
||||||
|
"204": "ElementalDamageBonus",
|
||||||
|
"205": "ImbueAttempts",
|
||||||
|
"206": "ImbueSuccesses",
|
||||||
|
"207": "CreatureKills",
|
||||||
|
"208": "PlayerKillsPk",
|
||||||
|
"209": "PlayerKillsPkl",
|
||||||
|
"210": "RaresTierOne",
|
||||||
|
"211": "RaresTierTwo",
|
||||||
|
"212": "RaresTierThree",
|
||||||
|
"213": "RaresTierFour",
|
||||||
|
"214": "RaresTierFive",
|
||||||
|
"215": "AugmentationStat",
|
||||||
|
"216": "AugmentationFamilyStat",
|
||||||
|
"217": "AugmentationInnateFamily",
|
||||||
|
"218": "AugmentationInnateStrength",
|
||||||
|
"219": "AugmentationInnateEndurance",
|
||||||
|
"220": "AugmentationInnateCoordination",
|
||||||
|
"221": "AugmentationInnateQuickness",
|
||||||
|
"222": "AugmentationInnateFocus",
|
||||||
|
"223": "AugmentationInnateSelf",
|
||||||
|
"224": "AugmentationSpecializeSalvaging",
|
||||||
|
"225": "AugmentationSpecializeItemTinkering",
|
||||||
|
"226": "AugmentationSpecializeArmorTinkering",
|
||||||
|
"227": "AugmentationSpecializeMagicItemTinkering",
|
||||||
|
"228": "AugmentationSpecializeWeaponTinkering",
|
||||||
|
"229": "AugmentationExtraPackSlot",
|
||||||
|
"230": "AugmentationIncreasedCarryingCapacity",
|
||||||
|
"231": "AugmentationLessDeathItemLoss",
|
||||||
|
"232": "AugmentationSpellsRemainPastDeath",
|
||||||
|
"233": "AugmentationCriticalDefense",
|
||||||
|
"234": "AugmentationBonusXp",
|
||||||
|
"235": "AugmentationBonusSalvage",
|
||||||
|
"236": "AugmentationBonusImbueChance",
|
||||||
|
"237": "AugmentationFasterRegen",
|
||||||
|
"238": "AugmentationIncreasedSpellDuration",
|
||||||
|
"239": "AugmentationResistanceFamily",
|
||||||
|
"240": "AugmentationResistanceSlash",
|
||||||
|
"241": "AugmentationResistancePierce",
|
||||||
|
"242": "AugmentationResistanceBlunt",
|
||||||
|
"243": "AugmentationResistanceAcid",
|
||||||
|
"244": "AugmentationResistanceFire",
|
||||||
|
"245": "AugmentationResistanceFrost",
|
||||||
|
"246": "AugmentationResistanceLightning",
|
||||||
|
"247": "RaresTierOneLogin",
|
||||||
|
"248": "RaresTierTwoLogin",
|
||||||
|
"249": "RaresTierThreeLogin",
|
||||||
|
"250": "RaresTierFourLogin",
|
||||||
|
"251": "RaresTierFiveLogin",
|
||||||
|
"252": "RaresLoginTimestamp",
|
||||||
|
"253": "RaresTierSix",
|
||||||
|
"254": "RaresTierSeven",
|
||||||
|
"255": "RaresTierSixLogin",
|
||||||
|
"256": "RaresTierSevenLogin",
|
||||||
|
"257": "ItemAttributeLimit",
|
||||||
|
"258": "ItemAttributeLevelLimit",
|
||||||
|
"259": "ItemAttribute2ndLimit",
|
||||||
|
"260": "ItemAttribute2ndLevelLimit",
|
||||||
|
"261": "CharacterTitleId",
|
||||||
|
"262": "NumCharacterTitles",
|
||||||
|
"263": "ResistanceModifierType",
|
||||||
|
"264": "FreeTinkersBitfield",
|
||||||
|
"265": "EquipmentSetId",
|
||||||
|
"266": "PetClass",
|
||||||
|
"267": "Lifespan",
|
||||||
|
"268": "RemainingLifespan",
|
||||||
|
"269": "UseCreateQuantity",
|
||||||
|
"270": "WieldRequirements2",
|
||||||
|
"271": "WieldSkillType2",
|
||||||
|
"272": "WieldDifficulty2",
|
||||||
|
"273": "WieldRequirements3",
|
||||||
|
"274": "WieldSkillType3",
|
||||||
|
"275": "WieldDifficulty3",
|
||||||
|
"276": "WieldRequirements4",
|
||||||
|
"277": "WieldSkillType4",
|
||||||
|
"278": "WieldDifficulty4",
|
||||||
|
"279": "Unique",
|
||||||
|
"280": "SharedCooldown",
|
||||||
|
"281": "Faction1Bits",
|
||||||
|
"282": "Faction2Bits",
|
||||||
|
"283": "Faction3Bits",
|
||||||
|
"284": "Hatred1Bits",
|
||||||
|
"285": "Hatred2Bits",
|
||||||
|
"286": "Hatred3Bits",
|
||||||
|
"287": "SocietyRankCelhan",
|
||||||
|
"288": "SocietyRankEldweb",
|
||||||
|
"289": "SocietyRankRadblo",
|
||||||
|
"290": "HearLocalSignals",
|
||||||
|
"291": "HearLocalSignalsRadius",
|
||||||
|
"292": "Cleaving",
|
||||||
|
"293": "AugmentationSpecializeGearcraft",
|
||||||
|
"294": "AugmentationInfusedCreatureMagic",
|
||||||
|
"295": "AugmentationInfusedItemMagic",
|
||||||
|
"296": "AugmentationInfusedLifeMagic",
|
||||||
|
"297": "AugmentationInfusedWarMagic",
|
||||||
|
"298": "AugmentationCriticalExpertise",
|
||||||
|
"299": "AugmentationCriticalPower",
|
||||||
|
"300": "AugmentationSkilledMelee",
|
||||||
|
"301": "AugmentationSkilledMissile",
|
||||||
|
"302": "AugmentationSkilledMagic",
|
||||||
|
"303": "ImbuedEffect2",
|
||||||
|
"304": "ImbuedEffect3",
|
||||||
|
"305": "ImbuedEffect4",
|
||||||
|
"306": "ImbuedEffect5",
|
||||||
|
"307": "DamageRating",
|
||||||
|
"308": "DamageResistRating",
|
||||||
|
"309": "AugmentationDamageBonus",
|
||||||
|
"310": "AugmentationDamageReduction",
|
||||||
|
"311": "ImbueStackingBits",
|
||||||
|
"312": "HealOverTime",
|
||||||
|
"313": "CritRating",
|
||||||
|
"314": "CritDamageRating",
|
||||||
|
"315": "CritResistRating",
|
||||||
|
"316": "CritDamageResistRating",
|
||||||
|
"317": "HealingResistRating",
|
||||||
|
"318": "DamageOverTime",
|
||||||
|
"319": "ItemMaxLevel",
|
||||||
|
"320": "ItemXpStyle",
|
||||||
|
"321": "EquipmentSetExtra",
|
||||||
|
"322": "AetheriaBitfield",
|
||||||
|
"323": "HealingBoostRating",
|
||||||
|
"324": "HeritageSpecificArmor",
|
||||||
|
"325": "AlternateRacialSkills",
|
||||||
|
"326": "AugmentationJackOfAllTrades",
|
||||||
|
"327": "AugmentationResistanceNether",
|
||||||
|
"328": "AugmentationInfusedVoidMagic",
|
||||||
|
"329": "WeaknessRating",
|
||||||
|
"330": "NetherOverTime",
|
||||||
|
"331": "NetherResistRating",
|
||||||
|
"332": "LuminanceAward",
|
||||||
|
"333": "LumAugDamageRating",
|
||||||
|
"334": "LumAugDamageReductionRating",
|
||||||
|
"335": "LumAugCritDamageRating",
|
||||||
|
"336": "LumAugCritReductionRating",
|
||||||
|
"337": "LumAugSurgeEffectRating",
|
||||||
|
"338": "LumAugSurgeChanceRating",
|
||||||
|
"339": "LumAugItemManaUsage",
|
||||||
|
"340": "LumAugItemManaGain",
|
||||||
|
"341": "LumAugVitality",
|
||||||
|
"342": "LumAugHealingRating",
|
||||||
|
"343": "LumAugSkilledCraft",
|
||||||
|
"344": "LumAugSkilledSpec",
|
||||||
|
"345": "LumAugNoDestroyCraft",
|
||||||
|
"346": "RestrictInteraction",
|
||||||
|
"347": "OlthoiLootTimestamp",
|
||||||
|
"348": "OlthoiLootStep",
|
||||||
|
"349": "UseCreatesContractId",
|
||||||
|
"350": "DotResistRating",
|
||||||
|
"351": "LifeResistRating",
|
||||||
|
"352": "CloakWeaveProc",
|
||||||
|
"353": "WeaponType",
|
||||||
|
"354": "MeleeMastery",
|
||||||
|
"355": "RangedMastery",
|
||||||
|
"356": "SneakAttackRating",
|
||||||
|
"357": "RecklessnessRating",
|
||||||
|
"358": "DeceptionRating",
|
||||||
|
"359": "CombatPetRange",
|
||||||
|
"360": "WeaponAuraDamage",
|
||||||
|
"361": "WeaponAuraSpeed",
|
||||||
|
"362": "SummoningMastery",
|
||||||
|
"363": "HeartbeatLifespan",
|
||||||
|
"364": "UseLevelRequirement",
|
||||||
|
"365": "LumAugAllSkills",
|
||||||
|
"366": "UseRequiresSkill",
|
||||||
|
"367": "UseRequiresSkillLevel",
|
||||||
|
"368": "UseRequiresSkillSpec",
|
||||||
|
"369": "UseRequiresLevel",
|
||||||
|
"370": "GearDamage",
|
||||||
|
"371": "GearDamageResist",
|
||||||
|
"372": "GearCrit",
|
||||||
|
"373": "GearCritResist",
|
||||||
|
"374": "GearCritDamage",
|
||||||
|
"375": "GearCritDamageResist",
|
||||||
|
"376": "GearHealingBoost",
|
||||||
|
"377": "GearNetherResist",
|
||||||
|
"378": "GearLifeResist",
|
||||||
|
"379": "GearMaxHealth",
|
||||||
|
"380": "Unknown380",
|
||||||
|
"381": "PKDamageRating",
|
||||||
|
"382": "PKDamageResistRating",
|
||||||
|
"383": "GearPKDamageRating",
|
||||||
|
"384": "GearPKDamageResistRating",
|
||||||
|
"385": "Unknown385",
|
||||||
|
"386": "Overpower",
|
||||||
|
"387": "OverpowerResist",
|
||||||
|
"388": "GearOverpower",
|
||||||
|
"389": "GearOverpowerResist",
|
||||||
|
"390": "Enlightenment",
|
||||||
|
"8007": "PCAPRecordedAutonomousMovement",
|
||||||
|
"8030": "PCAPRecordedMaxVelocityEstimated",
|
||||||
|
"8041": "PCAPRecordedPlacement",
|
||||||
|
"8042": "PCAPRecordedAppraisalPages",
|
||||||
|
"8043": "PCAPRecordedAppraisalMaxPages",
|
||||||
|
"9008": "CurrentLoyaltyAtLastLogoff",
|
||||||
|
"9009": "CurrentLeadershipAtLastLogoff",
|
||||||
|
"9010": "AllegianceOfficerRank",
|
||||||
|
"9011": "HouseRentTimestamp",
|
||||||
|
"9012": "Hairstyle",
|
||||||
|
"9013": "VisualClothingPriority",
|
||||||
|
"9014": "SquelchGlobal",
|
||||||
|
"9015": "InventoryOrder",
|
||||||
|
"218103808": "WeenieClassId_Decal",
|
||||||
|
"218103809": "Icon_Decal_DID",
|
||||||
|
"218103810": "Container_Decal_IID",
|
||||||
|
"218103811": "Landblock_Decal",
|
||||||
|
"218103812": "ItemSlots_Decal",
|
||||||
|
"218103813": "PackSlots_Decal",
|
||||||
|
"218103814": "StackCount_Decal",
|
||||||
|
"218103815": "StackMax_Decal",
|
||||||
|
"218103816": "Spell_Decal_DID",
|
||||||
|
"218103817": "SlotLegacy_Decal",
|
||||||
|
"218103818": "Wielder_Decal_IID",
|
||||||
|
"218103819": "WieldingSlot_Decal",
|
||||||
|
"218103820": "Monarch_Decal_IID",
|
||||||
|
"218103821": "Coverage_Decal",
|
||||||
|
"218103822": "EquipableSlots_Decal",
|
||||||
|
"218103823": "EquipType_Decal",
|
||||||
|
"218103824": "IconOutline_Decal",
|
||||||
|
"218103825": "MissileType_Decal",
|
||||||
|
"218103826": "UsageMask_Decal",
|
||||||
|
"218103827": "HouseOwner_Decal_IID",
|
||||||
|
"218103828": "HookMask_Decal",
|
||||||
|
"218103829": "HookType_Decal",
|
||||||
|
"218103830": "Setup_Decal_DID",
|
||||||
|
"218103831": "ObjectDescriptionFlags_Decal",
|
||||||
|
"218103832": "CreateFlags1_Decal",
|
||||||
|
"218103833": "CreateFlags2_Decal",
|
||||||
|
"218103834": "Category_Decal",
|
||||||
|
"218103835": "Behavior_Decal",
|
||||||
|
"218103836": "MagicDef_Decal",
|
||||||
|
"218103837": "SpecialProps_Decal",
|
||||||
|
"218103838": "SpellCount_Decal",
|
||||||
|
"218103839": "WeapSpeed_Decal",
|
||||||
|
"218103840": "EquipSkill_Decal",
|
||||||
|
"218103841": "DamageType_Decal",
|
||||||
|
"218103842": "MaxDamage_Decal",
|
||||||
|
"218103843": "Unknown10_Decal",
|
||||||
|
"218103844": "Unknown100000_Decal",
|
||||||
|
"218103845": "Unknown800000_Decal",
|
||||||
|
"218103846": "Unknown8000000_Decal",
|
||||||
|
"218103847": "PhysicsDataFlags_Decal",
|
||||||
|
"218103848": "ActiveSpellCount_Decal",
|
||||||
|
"218103849": "IconOverlay_Decal_DID",
|
||||||
|
"218103850": "IconUnderlay_Decal_DID",
|
||||||
|
"231735296": "Slot_Decal"
|
||||||
|
},
|
||||||
|
"comments": {
|
||||||
|
"EncumbranceVal": "ENCUMB_VAL_INT,",
|
||||||
|
"ValidLocations": "LOCATIONS_INT",
|
||||||
|
"Unknown10_Decal": "CurrentWieldLocation?",
|
||||||
|
"Unknown100000_Decal": "RadarBlipColor ???"
|
||||||
|
},
|
||||||
|
"attributes": {},
|
||||||
|
"source_file": "IntValueKey.cs"
|
||||||
|
}
|
||||||
|
}
|
||||||
52
inventory-service/enums/ItemType.json
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
{
|
||||||
|
"ItemType": {
|
||||||
|
"type": "uint",
|
||||||
|
"values": {
|
||||||
|
"0": "None",
|
||||||
|
"1": "MeleeWeapon",
|
||||||
|
"2": "Armor",
|
||||||
|
"4": "Clothing",
|
||||||
|
"8": "Jewelry",
|
||||||
|
"16": "Creature",
|
||||||
|
"32": "Food",
|
||||||
|
"64": "Money",
|
||||||
|
"128": "Misc",
|
||||||
|
"256": "MissileWeapon",
|
||||||
|
"512": "Container",
|
||||||
|
"1024": "Useless",
|
||||||
|
"2048": "Gem",
|
||||||
|
"4096": "SpellComponents",
|
||||||
|
"8192": "Writable",
|
||||||
|
"16384": "Key",
|
||||||
|
"32768": "Caster",
|
||||||
|
"65536": "Portal",
|
||||||
|
"131072": "Lockable",
|
||||||
|
"262144": "PromissoryNote",
|
||||||
|
"524288": "ManaStone",
|
||||||
|
"1048576": "Service",
|
||||||
|
"2097152": "MagicWieldable",
|
||||||
|
"4194304": "CraftCookingBase",
|
||||||
|
"8388608": "CraftAlchemyBase",
|
||||||
|
"33554432": "CraftFletchingBase",
|
||||||
|
"67108864": "CraftAlchemyIntermediate",
|
||||||
|
"134217728": "CraftFletchingIntermediate",
|
||||||
|
"268435456": "LifeStone",
|
||||||
|
"536870912": "TinkeringTool",
|
||||||
|
"1073741824": "TinkeringMaterial",
|
||||||
|
"2147483648": "Gameboard",
|
||||||
|
"EXPR:Portal | LifeStone": "PortalMagicTarget",
|
||||||
|
"EXPR:Misc | Container": "LockableMagicTarget",
|
||||||
|
"EXPR:Armor | Clothing": "Vestements",
|
||||||
|
"EXPR:MeleeWeapon | MissileWeapon": "Weapon",
|
||||||
|
"EXPR:MeleeWeapon | MissileWeapon | Caster": "WeaponOrCaster",
|
||||||
|
"EXPR:MeleeWeapon | Armor | Clothing | Jewelry | Food | Money | Misc | MissileWeapon | Container |": "Item",
|
||||||
|
"EXPR:MeleeWeapon | Armor | Clothing | MissileWeapon | Caster": "RedirectableItemEnchantmentTarget",
|
||||||
|
"EXPR:MeleeWeapon | Armor | Clothing | Jewelry | Misc | MissileWeapon | Container | Gem | Caster | ManaStone": "ItemEnchantableTarget",
|
||||||
|
"EXPR:MeleeWeapon | Armor | Clothing | Food | Misc | MissileWeapon | Container | Useless | Writable | Key |": "VendorShopKeep",
|
||||||
|
"EXPR:Food | Container | Writable | Key | PromissoryNote | CraftCookingBase": "VendorGrocer"
|
||||||
|
},
|
||||||
|
"comments": {},
|
||||||
|
"attributes": {},
|
||||||
|
"source_file": "ItemType.cs"
|
||||||
|
}
|
||||||
|
}
|
||||||
83
inventory-service/enums/MaterialType.json
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
{
|
||||||
|
"MaterialType": {
|
||||||
|
"type": "uint",
|
||||||
|
"values": {
|
||||||
|
"0": "Unknown",
|
||||||
|
"1": "Ceramic",
|
||||||
|
"2": "Porcelain",
|
||||||
|
"4": "Linen",
|
||||||
|
"5": "Satin",
|
||||||
|
"6": "Silk",
|
||||||
|
"7": "Velvet",
|
||||||
|
"8": "Wool",
|
||||||
|
"10": "Agate",
|
||||||
|
"11": "Amber",
|
||||||
|
"12": "Amethyst",
|
||||||
|
"13": "Aquamarine",
|
||||||
|
"14": "Azurite",
|
||||||
|
"15": "BlackGarnet",
|
||||||
|
"16": "BlackOpal",
|
||||||
|
"17": "Bloodstone",
|
||||||
|
"18": "Carnelian",
|
||||||
|
"19": "Citrine",
|
||||||
|
"20": "Diamond",
|
||||||
|
"21": "Emerald",
|
||||||
|
"22": "FireOpal",
|
||||||
|
"23": "GreenGarnet",
|
||||||
|
"24": "GreenJade",
|
||||||
|
"25": "Hematite",
|
||||||
|
"26": "ImperialTopaz",
|
||||||
|
"27": "Jet",
|
||||||
|
"28": "LapisLazuli",
|
||||||
|
"29": "LavenderJade",
|
||||||
|
"30": "Malachite",
|
||||||
|
"31": "Moonstone",
|
||||||
|
"32": "Onyx",
|
||||||
|
"33": "Opal",
|
||||||
|
"34": "Peridot",
|
||||||
|
"35": "RedGarnet",
|
||||||
|
"36": "RedJade",
|
||||||
|
"37": "RoseQuartz",
|
||||||
|
"38": "Ruby",
|
||||||
|
"39": "Sapphire",
|
||||||
|
"40": "SmokeyQuartz",
|
||||||
|
"41": "Sunstone",
|
||||||
|
"42": "TigerEye",
|
||||||
|
"43": "Tourmaline",
|
||||||
|
"44": "Turquoise",
|
||||||
|
"45": "WhiteJade",
|
||||||
|
"46": "WhiteQuartz",
|
||||||
|
"47": "WhiteSapphire",
|
||||||
|
"48": "YellowGarnet",
|
||||||
|
"49": "YellowTopaz",
|
||||||
|
"50": "Zircon",
|
||||||
|
"51": "Ivory",
|
||||||
|
"52": "Leather",
|
||||||
|
"53": "ArmoredilloHide",
|
||||||
|
"54": "GromnieHide",
|
||||||
|
"55": "ReedSharkHide",
|
||||||
|
"57": "Brass",
|
||||||
|
"58": "Bronze",
|
||||||
|
"59": "Copper",
|
||||||
|
"60": "Gold",
|
||||||
|
"61": "Iron",
|
||||||
|
"62": "Pyreal",
|
||||||
|
"63": "Silver",
|
||||||
|
"64": "Steel",
|
||||||
|
"66": "Alabaster",
|
||||||
|
"67": "Granite",
|
||||||
|
"68": "Marble",
|
||||||
|
"69": "Obsidian",
|
||||||
|
"70": "Sandstone",
|
||||||
|
"71": "Serpentine",
|
||||||
|
"73": "Ebony",
|
||||||
|
"74": "Mahogany",
|
||||||
|
"75": "Oak",
|
||||||
|
"76": "Pine",
|
||||||
|
"77": "Teak"
|
||||||
|
},
|
||||||
|
"comments": {},
|
||||||
|
"attributes": {},
|
||||||
|
"source_file": "MaterialType.cs"
|
||||||
|
}
|
||||||
|
}
|
||||||
23
inventory-service/enums/QuadValueKey.json
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"QuadValueKey": {
|
||||||
|
"type": "int",
|
||||||
|
"values": {
|
||||||
|
"0": "Undef",
|
||||||
|
"1": "TotalExperience",
|
||||||
|
"2": "AvailableExperience",
|
||||||
|
"3": "AugmentationCost",
|
||||||
|
"4": "ItemTotalXp",
|
||||||
|
"5": "ItemBaseXp",
|
||||||
|
"6": "AvailableLuminance",
|
||||||
|
"7": "MaximumLuminance",
|
||||||
|
"8": "InteractionReqs",
|
||||||
|
"9000": "AllegianceXPCached",
|
||||||
|
"9001": "AllegianceXPGenerated",
|
||||||
|
"9002": "AllegianceXPReceived",
|
||||||
|
"9003": "VerifyXp"
|
||||||
|
},
|
||||||
|
"comments": {},
|
||||||
|
"attributes": {},
|
||||||
|
"source_file": "QuadValueKey.cs"
|
||||||
|
}
|
||||||
|
}
|
||||||
228
inventory-service/enums/Skill.json
Normal file
|
|
@ -0,0 +1,228 @@
|
||||||
|
{
|
||||||
|
"Skill": {
|
||||||
|
"type": "indexed",
|
||||||
|
"values": {
|
||||||
|
"0": {
|
||||||
|
"name": "None",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"name": "Axe",
|
||||||
|
"status": "Retired"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"name": "Bow",
|
||||||
|
"status": "Retired"
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
|
"name": "Crossbow",
|
||||||
|
"status": "Retired"
|
||||||
|
},
|
||||||
|
"4": {
|
||||||
|
"name": "Dagger",
|
||||||
|
"status": "Retired"
|
||||||
|
},
|
||||||
|
"5": {
|
||||||
|
"name": "Mace",
|
||||||
|
"status": "Retired"
|
||||||
|
},
|
||||||
|
"6": {
|
||||||
|
"name": "MeleeDefense",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"7": {
|
||||||
|
"name": "MissileDefense",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"8": {
|
||||||
|
"name": "Sling",
|
||||||
|
"status": "Retired"
|
||||||
|
},
|
||||||
|
"9": {
|
||||||
|
"name": "Spear",
|
||||||
|
"status": "Retired"
|
||||||
|
},
|
||||||
|
"10": {
|
||||||
|
"name": "Staff",
|
||||||
|
"status": "Retired"
|
||||||
|
},
|
||||||
|
"11": {
|
||||||
|
"name": "Sword",
|
||||||
|
"status": "Retired"
|
||||||
|
},
|
||||||
|
"12": {
|
||||||
|
"name": "ThrownWeapon",
|
||||||
|
"status": "Retired"
|
||||||
|
},
|
||||||
|
"13": {
|
||||||
|
"name": "UnarmedCombat",
|
||||||
|
"status": "Retired"
|
||||||
|
},
|
||||||
|
"14": {
|
||||||
|
"name": "ArcaneLore",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"15": {
|
||||||
|
"name": "MagicDefense",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"16": {
|
||||||
|
"name": "ManaConversion",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"17": {
|
||||||
|
"name": "Spellcraft",
|
||||||
|
"status": "Unimplemented"
|
||||||
|
},
|
||||||
|
"18": {
|
||||||
|
"name": "ItemTinkering",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"19": {
|
||||||
|
"name": "AssessPerson",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"20": {
|
||||||
|
"name": "Deception",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"21": {
|
||||||
|
"name": "Healing",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"22": {
|
||||||
|
"name": "Jump",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"23": {
|
||||||
|
"name": "Lockpick",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"24": {
|
||||||
|
"name": "Run",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"25": {
|
||||||
|
"name": "Awareness",
|
||||||
|
"status": "Unimplemented"
|
||||||
|
},
|
||||||
|
"26": {
|
||||||
|
"name": "ArmsAndArmorRepair",
|
||||||
|
"status": "Unimplemented"
|
||||||
|
},
|
||||||
|
"27": {
|
||||||
|
"name": "AssessCreature",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"28": {
|
||||||
|
"name": "WeaponTinkering",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"29": {
|
||||||
|
"name": "ArmorTinkering",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"30": {
|
||||||
|
"name": "MagicItemTinkering",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"31": {
|
||||||
|
"name": "CreatureEnchantment",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"32": {
|
||||||
|
"name": "ItemEnchantment",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"33": {
|
||||||
|
"name": "LifeMagic",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"34": {
|
||||||
|
"name": "WarMagic",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"35": {
|
||||||
|
"name": "Leadership",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"36": {
|
||||||
|
"name": "Loyalty",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"37": {
|
||||||
|
"name": "Fletching",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"38": {
|
||||||
|
"name": "Alchemy",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"39": {
|
||||||
|
"name": "Cooking",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"40": {
|
||||||
|
"name": "Salvaging",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"41": {
|
||||||
|
"name": "TwoHandedCombat",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"42": {
|
||||||
|
"name": "Gearcraft",
|
||||||
|
"status": "Retired"
|
||||||
|
},
|
||||||
|
"43": {
|
||||||
|
"name": "VoidMagic",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"44": {
|
||||||
|
"name": "HeavyWeapons",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"45": {
|
||||||
|
"name": "LightWeapons",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"46": {
|
||||||
|
"name": "FinesseWeapons",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"47": {
|
||||||
|
"name": "MissileWeapons",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"48": {
|
||||||
|
"name": "Shield",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"49": {
|
||||||
|
"name": "DualWield",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"50": {
|
||||||
|
"name": "Recklessness",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"51": {
|
||||||
|
"name": "SneakAttack",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"52": {
|
||||||
|
"name": "DirtyFighting",
|
||||||
|
"status": "Active"
|
||||||
|
},
|
||||||
|
"53": {
|
||||||
|
"name": "Challenge",
|
||||||
|
"status": "Unimplemented"
|
||||||
|
},
|
||||||
|
"54": {
|
||||||
|
"name": "Summoning",
|
||||||
|
"status": "Active"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"source_file": "Skill.cs"
|
||||||
|
}
|
||||||
|
}
|
||||||
710
inventory-service/enums/SpellCategory.json
Normal file
|
|
@ -0,0 +1,710 @@
|
||||||
|
{
|
||||||
|
"SpellCategory": {
|
||||||
|
"type": "int",
|
||||||
|
"values": {
|
||||||
|
"0": "Undefined",
|
||||||
|
"1": "Strength_Raising",
|
||||||
|
"2": "Strength_Lowering",
|
||||||
|
"3": "Endurance_Raising",
|
||||||
|
"4": "Endurance_Lowering",
|
||||||
|
"5": "Quickness_Raising",
|
||||||
|
"6": "Quickness_Lowering",
|
||||||
|
"7": "Coordination_Raising",
|
||||||
|
"8": "Coordination_Lowering",
|
||||||
|
"9": "Focus_Raising",
|
||||||
|
"10": "Focus_Lowering",
|
||||||
|
"11": "Self_Raising",
|
||||||
|
"12": "Self_Lowering",
|
||||||
|
"13": "Focus_Concentration",
|
||||||
|
"14": "Focus_Disruption",
|
||||||
|
"15": "Focus_Brilliance",
|
||||||
|
"16": "Focus_Dullness",
|
||||||
|
"17": "Axe_Raising",
|
||||||
|
"18": "Axe_Lowering",
|
||||||
|
"19": "Bow_Raising",
|
||||||
|
"20": "Bow_Lowering",
|
||||||
|
"21": "Crossbow_Raising",
|
||||||
|
"22": "Crossbow_Lowering",
|
||||||
|
"23": "Dagger_Raising",
|
||||||
|
"24": "Dagger_Lowering",
|
||||||
|
"25": "Mace_Raising",
|
||||||
|
"26": "Mace_Lowering",
|
||||||
|
"27": "Spear_Raising",
|
||||||
|
"28": "Spear_Lowering",
|
||||||
|
"29": "Staff_Raising",
|
||||||
|
"30": "Staff_Lowering",
|
||||||
|
"31": "Sword_Raising",
|
||||||
|
"32": "Sword_Lowering",
|
||||||
|
"33": "Thrown_Weapons_Raising",
|
||||||
|
"34": "Thrown_Weapons_Lowering",
|
||||||
|
"35": "Unarmed_Combat_Raising",
|
||||||
|
"36": "Unarmed_Combat_Lowering",
|
||||||
|
"37": "Melee_Defense_Raising",
|
||||||
|
"38": "Melee_Defense_Lowering",
|
||||||
|
"39": "Missile_Defense_Raising",
|
||||||
|
"40": "Missile_Defense_Lowering",
|
||||||
|
"41": "Magic_Defense_Raising",
|
||||||
|
"42": "Magic_Defense_Lowering",
|
||||||
|
"43": "Creature_Enchantment_Raising",
|
||||||
|
"44": "Creature_Enchantment_Lowering",
|
||||||
|
"45": "Item_Enchantment_Raising",
|
||||||
|
"46": "Item_Enchantment_Lowering",
|
||||||
|
"47": "Life_Magic_Raising",
|
||||||
|
"48": "Life_Magic_Lowering",
|
||||||
|
"49": "War_Magic_Raising",
|
||||||
|
"50": "War_Magic_Lowering",
|
||||||
|
"51": "Mana_Conversion_Raising",
|
||||||
|
"52": "Mana_Conversion_Lowering",
|
||||||
|
"53": "Arcane_Lore_Raising",
|
||||||
|
"54": "Arcane_Lore_Lowering",
|
||||||
|
"55": "Appraise_Armor_Raising",
|
||||||
|
"56": "Appraise_Armor_Lowering",
|
||||||
|
"57": "Appraise_Item_Raising",
|
||||||
|
"58": "Appraise_Item_Lowering",
|
||||||
|
"59": "Appraise_Magic_Item_Raising",
|
||||||
|
"60": "Appraise_Magic_Item_Lowering",
|
||||||
|
"61": "Appraise_Weapon_Raising",
|
||||||
|
"62": "Appraise_Weapon_Lowering",
|
||||||
|
"63": "Assess_Monster_Raising",
|
||||||
|
"64": "Assess_Monster_Lowering",
|
||||||
|
"65": "Deception_Raising",
|
||||||
|
"66": "Deception_Lowering",
|
||||||
|
"67": "Healing_Raising",
|
||||||
|
"68": "Healing_Lowering",
|
||||||
|
"69": "Jump_Raising",
|
||||||
|
"70": "Jump_Lowering",
|
||||||
|
"71": "Leadership_Raising",
|
||||||
|
"72": "Leadership_Lowering",
|
||||||
|
"73": "Lockpick_Raising",
|
||||||
|
"74": "Lockpick_Lowering",
|
||||||
|
"75": "Loyalty_Raising",
|
||||||
|
"76": "Loyalty_Lowering",
|
||||||
|
"77": "Run_Raising",
|
||||||
|
"78": "Run_Lowering",
|
||||||
|
"79": "Health_Raising",
|
||||||
|
"80": "Health_Lowering",
|
||||||
|
"81": "Stamina_Raising",
|
||||||
|
"82": "Stamina_Lowering",
|
||||||
|
"83": "Mana_Raising",
|
||||||
|
"84": "Mana_Lowering",
|
||||||
|
"85": "Mana_Remedy",
|
||||||
|
"86": "Mana_Malediction",
|
||||||
|
"87": "Health_Transfer_to_caster",
|
||||||
|
"88": "Health_Transfer_from_caster",
|
||||||
|
"89": "Stamina_Transfer_to_caster",
|
||||||
|
"90": "Stamina_Transfer_from_caster",
|
||||||
|
"91": "Mana_Transfer_to_caster",
|
||||||
|
"92": "Mana_Transfer_from_caster",
|
||||||
|
"93": "Health_Accelerating",
|
||||||
|
"94": "Health_Decelerating",
|
||||||
|
"95": "Stamina_Accelerating",
|
||||||
|
"96": "Stamina_Decelerating",
|
||||||
|
"97": "Mana_Accelerating",
|
||||||
|
"98": "Mana_Decelerating",
|
||||||
|
"99": "Vitae_Raising",
|
||||||
|
"100": "Vitae_Lowering",
|
||||||
|
"101": "Acid_Protection",
|
||||||
|
"102": "Acid_Vulnerability",
|
||||||
|
"103": "Bludgeon_Protection",
|
||||||
|
"104": "Bludgeon_Vulnerability",
|
||||||
|
"105": "Cold_Protection",
|
||||||
|
"106": "Cold_Vulnerability",
|
||||||
|
"107": "Electric_Protection",
|
||||||
|
"108": "Electric_Vulnerability",
|
||||||
|
"109": "Fire_Protection",
|
||||||
|
"110": "Fire_Vulnerability",
|
||||||
|
"111": "Pierce_Protection",
|
||||||
|
"112": "Pierce_Vulnerability",
|
||||||
|
"113": "Slash_Protection",
|
||||||
|
"114": "Slash_Vulnerability",
|
||||||
|
"115": "Armor_Raising",
|
||||||
|
"116": "Armor_Lowering",
|
||||||
|
"117": "Acid_Missile",
|
||||||
|
"118": "Bludgeoning_Missile",
|
||||||
|
"119": "Cold_Missile",
|
||||||
|
"120": "Electric_Missile",
|
||||||
|
"121": "Fire_Missile",
|
||||||
|
"122": "Piercing_Missile",
|
||||||
|
"123": "Slashing_Missile",
|
||||||
|
"124": "Acid_Seeker",
|
||||||
|
"125": "Bludgeoning_Seeker",
|
||||||
|
"126": "Cold_Seeker",
|
||||||
|
"127": "Electric_Seeker",
|
||||||
|
"128": "Fire_Seeker",
|
||||||
|
"129": "Piercing_Seeker",
|
||||||
|
"130": "Slashing_Seeker",
|
||||||
|
"131": "Acid_Burst",
|
||||||
|
"132": "Bludgeoning_Burst",
|
||||||
|
"133": "Cold_Burst",
|
||||||
|
"134": "Electric_Burst",
|
||||||
|
"135": "Fire_Burst",
|
||||||
|
"136": "Piercing_Burst",
|
||||||
|
"137": "Slashing_Burst",
|
||||||
|
"138": "Acid_Blast",
|
||||||
|
"139": "Bludgeoning_Blast",
|
||||||
|
"140": "Cold_Blast",
|
||||||
|
"141": "Electric_Blast",
|
||||||
|
"142": "Fire_Blast",
|
||||||
|
"143": "Piercing_Blast",
|
||||||
|
"144": "Slashing_Blast",
|
||||||
|
"145": "Acid_Scatter",
|
||||||
|
"146": "Bludgeoning_Scatter",
|
||||||
|
"147": "Cold_Scatter",
|
||||||
|
"148": "Electric_Scatter",
|
||||||
|
"149": "Fire_Scatter",
|
||||||
|
"150": "Piercing_Scatter",
|
||||||
|
"151": "Slashing_Scatter",
|
||||||
|
"152": "Attack_Mod_Raising",
|
||||||
|
"153": "Attack_Mod_Lowering",
|
||||||
|
"154": "Damage_Raising",
|
||||||
|
"155": "Damage_Lowering",
|
||||||
|
"156": "Defense_Mod_Raising",
|
||||||
|
"157": "Defense_Mod_Lowering",
|
||||||
|
"158": "Weapon_Time_Raising",
|
||||||
|
"159": "Weapon_Time_Lowering",
|
||||||
|
"160": "Armor_Value_Raising",
|
||||||
|
"161": "Armor_Value_Lowering",
|
||||||
|
"162": "Acid_Resistance_Raising",
|
||||||
|
"163": "Acid_Resistance_Lowering",
|
||||||
|
"164": "Bludgeon_Resistance_Raising",
|
||||||
|
"165": "Bludgeon_Resistance_Lowering",
|
||||||
|
"166": "Cold_Resistance_Raising",
|
||||||
|
"167": "Cold_Resistance_Lowering",
|
||||||
|
"168": "Electric_Resistance_Raising",
|
||||||
|
"169": "Electric_Resistance_Lowering",
|
||||||
|
"170": "Fire_Resistance_Raising",
|
||||||
|
"171": "Fire_Resistance_Lowering",
|
||||||
|
"172": "Pierce_Resistance_Raising",
|
||||||
|
"173": "Pierce_Resistance_Lowering",
|
||||||
|
"174": "Slash_Resistance_Raising",
|
||||||
|
"175": "Slash_Resistance_Lowering",
|
||||||
|
"176": "Bludgeoning_Resistance_Raising",
|
||||||
|
"177": "Bludgeoning_Resistance_Lowering",
|
||||||
|
"178": "Slashing_Resistance_Raising",
|
||||||
|
"179": "Slashing_Resistance_Lowering",
|
||||||
|
"180": "Piercing_Resistance_Raising",
|
||||||
|
"181": "Piercing_Resistance_Lowering",
|
||||||
|
"182": "Electrical_Resistance_Raising",
|
||||||
|
"183": "Electrical_Resistance_Lowering",
|
||||||
|
"184": "Frost_Resistance_Raising",
|
||||||
|
"185": "Frost_Resistance_Lowering",
|
||||||
|
"186": "Flame_Resistance_Raising",
|
||||||
|
"187": "Flame_Resistance_Lowering",
|
||||||
|
"188": "Acidic_Resistance_Raising",
|
||||||
|
"189": "Acidic_Resistance_Lowering",
|
||||||
|
"190": "Armor_Level_Raising",
|
||||||
|
"191": "Armor_Level_Lowering",
|
||||||
|
"192": "Lockpick_Resistance_Raising",
|
||||||
|
"193": "Lockpick_Resistance_Lowering",
|
||||||
|
"194": "Appraisal_Resistance_Raising",
|
||||||
|
"195": "Appraisal_Resistance_Lowering",
|
||||||
|
"196": "Vision_Raising",
|
||||||
|
"197": "Vision_Lowering",
|
||||||
|
"198": "Transparency_Raising",
|
||||||
|
"199": "Transparency_Lowering",
|
||||||
|
"200": "Portal_Tie",
|
||||||
|
"201": "Portal_Recall",
|
||||||
|
"202": "Portal_Creation",
|
||||||
|
"203": "Portal_Item_Creation",
|
||||||
|
"204": "Vitae",
|
||||||
|
"205": "Assess_Person_Raising",
|
||||||
|
"206": "Assess_Person_Lowering",
|
||||||
|
"207": "Acid_Volley",
|
||||||
|
"208": "Bludgeoning_Volley",
|
||||||
|
"209": "Frost_Volley",
|
||||||
|
"210": "Lightning_Volley",
|
||||||
|
"211": "Flame_Volley",
|
||||||
|
"212": "Force_Volley",
|
||||||
|
"213": "Blade_Volley",
|
||||||
|
"214": "Portal_Sending",
|
||||||
|
"215": "Lifestone_Sending",
|
||||||
|
"216": "Cooking_Raising",
|
||||||
|
"217": "Cooking_Lowering",
|
||||||
|
"218": "Fletching_Raising",
|
||||||
|
"219": "Fletching_Lowering",
|
||||||
|
"220": "Alchemy_Lowering",
|
||||||
|
"221": "Alchemy_Raising",
|
||||||
|
"222": "Acid_Ring",
|
||||||
|
"223": "Bludgeoning_Ring",
|
||||||
|
"224": "Cold_Ring",
|
||||||
|
"225": "Electric_Ring",
|
||||||
|
"226": "Fire_Ring",
|
||||||
|
"227": "Piercing_Ring",
|
||||||
|
"228": "Slashing_Ring",
|
||||||
|
"229": "Acid_Wall",
|
||||||
|
"230": "Bludgeoning_Wall",
|
||||||
|
"231": "Cold_Wall",
|
||||||
|
"232": "Electric_Wall",
|
||||||
|
"233": "Fire_Wall",
|
||||||
|
"234": "Piercing_Wall",
|
||||||
|
"235": "Slashing_Wall",
|
||||||
|
"236": "Acid_Strike",
|
||||||
|
"237": "Bludgeoning_Strike",
|
||||||
|
"238": "Cold_Strike",
|
||||||
|
"239": "Electric_Strike",
|
||||||
|
"240": "Fire_Strike",
|
||||||
|
"241": "Piercing_Strike",
|
||||||
|
"242": "Slashing_Strike",
|
||||||
|
"243": "Acid_Streak",
|
||||||
|
"244": "Bludgeoning_Streak",
|
||||||
|
"245": "Cold_Streak",
|
||||||
|
"246": "Electric_Streak",
|
||||||
|
"247": "Fire_Streak",
|
||||||
|
"248": "Piercing_Streak",
|
||||||
|
"249": "Slashing_Streak",
|
||||||
|
"250": "Dispel",
|
||||||
|
"251": "Creature_Mystic_Raising",
|
||||||
|
"252": "Creature_Mystic_Lowering",
|
||||||
|
"253": "Item_Mystic_Raising",
|
||||||
|
"254": "Item_Mystic_Lowering",
|
||||||
|
"255": "War_Mystic_Raising",
|
||||||
|
"256": "War_Mystic_Lowering",
|
||||||
|
"257": "Health_Restoring",
|
||||||
|
"258": "Health_Depleting",
|
||||||
|
"259": "Mana_Restoring",
|
||||||
|
"260": "Mana_Depleting",
|
||||||
|
"261": "Strength_Increase",
|
||||||
|
"262": "Strength_Decrease",
|
||||||
|
"263": "Endurance_Increase",
|
||||||
|
"264": "Endurance_Decrease",
|
||||||
|
"265": "Quickness_Increase",
|
||||||
|
"266": "Quickness_Decrease",
|
||||||
|
"267": "Coordination_Increase",
|
||||||
|
"268": "Coordination_Decrease",
|
||||||
|
"269": "Focus_Increase",
|
||||||
|
"270": "Focus_Decrease",
|
||||||
|
"271": "Self_Increase",
|
||||||
|
"272": "Self_Decrease",
|
||||||
|
"273": "GreatVitality_Raising",
|
||||||
|
"274": "PoorVitality_Lowering",
|
||||||
|
"275": "GreatVigor_Raising",
|
||||||
|
"276": "PoorVigor_Lowering",
|
||||||
|
"277": "GreaterIntellect_Raising",
|
||||||
|
"278": "LessorIntellect_Lowering",
|
||||||
|
"279": "LifeGiver_Raising",
|
||||||
|
"280": "LifeTaker_Lowering",
|
||||||
|
"281": "StaminaGiver_Raising",
|
||||||
|
"282": "StaminaTaker_Lowering",
|
||||||
|
"283": "ManaGiver_Raising",
|
||||||
|
"284": "ManaTaker_Lowering",
|
||||||
|
"285": "Acid_Ward_Protection",
|
||||||
|
"286": "Acid_Ward_Vulnerability",
|
||||||
|
"287": "Fire_Ward_Protection",
|
||||||
|
"288": "Fire_Ward_Vulnerability",
|
||||||
|
"289": "Cold_Ward_Protection",
|
||||||
|
"290": "Cold_Ward_Vulnerability",
|
||||||
|
"291": "Electric_Ward_Protection",
|
||||||
|
"292": "Electric_Ward_Vulnerability",
|
||||||
|
"293": "Leadership_Obedience_Raising",
|
||||||
|
"294": "Leadership_Obedience_Lowering",
|
||||||
|
"295": "Melee_Defense_Shelter_Raising",
|
||||||
|
"296": "Melee_Defense_Shelter_Lowering",
|
||||||
|
"297": "Missile_Defense_Shelter_Raising",
|
||||||
|
"298": "Missile_Defense_Shelter_Lowering",
|
||||||
|
"299": "Magic_Defense_Shelter_Raising",
|
||||||
|
"300": "Magic_Defense_Shelter_Lowering",
|
||||||
|
"301": "HuntersAcumen_Raising",
|
||||||
|
"302": "HuntersAcumen_Lowering",
|
||||||
|
"303": "StillWater_Raising",
|
||||||
|
"304": "StillWater_Lowering",
|
||||||
|
"305": "StrengthofEarth_Raising",
|
||||||
|
"306": "StrengthofEarth_Lowering",
|
||||||
|
"307": "Torrent_Raising",
|
||||||
|
"308": "Torrent_Lowering",
|
||||||
|
"309": "Growth_Raising",
|
||||||
|
"310": "Growth_Lowering",
|
||||||
|
"311": "CascadeAxe_Raising",
|
||||||
|
"312": "CascadeAxe_Lowering",
|
||||||
|
"313": "CascadeDagger_Raising",
|
||||||
|
"314": "CascadeDagger_Lowering",
|
||||||
|
"315": "CascadeMace_Raising",
|
||||||
|
"316": "CascadeMace_Lowering",
|
||||||
|
"317": "CascadeSpear_Raising",
|
||||||
|
"318": "CascadeSpear_Lowering",
|
||||||
|
"319": "CascadeStaff_Raising",
|
||||||
|
"320": "CascadeStaff_Lowering",
|
||||||
|
"321": "StoneCliffs_Raising",
|
||||||
|
"322": "StoneCliffs_Lowering",
|
||||||
|
"323": "MaxDamage_Raising",
|
||||||
|
"324": "MaxDamage_Lowering",
|
||||||
|
"325": "Bow_Damage_Raising",
|
||||||
|
"326": "Bow_Damage_Lowering",
|
||||||
|
"327": "Bow_Range_Raising",
|
||||||
|
"328": "Bow_Range_Lowering",
|
||||||
|
"329": "Extra_Defense_Mod_Raising",
|
||||||
|
"330": "Extra_Defense_Mod_Lowering",
|
||||||
|
"331": "Extra_Bow_Skill_Raising",
|
||||||
|
"332": "Extra_Bow_Skill_Lowering",
|
||||||
|
"333": "Extra_Alchemy_Skill_Raising",
|
||||||
|
"334": "Extra_Alchemy_Skill_Lowering",
|
||||||
|
"335": "Extra_Arcane_Lore_Skill_Raising",
|
||||||
|
"336": "Extra_Arcane_Lore_Skill_Lowering",
|
||||||
|
"337": "Extra_Appraise_Armor_Skill_Raising",
|
||||||
|
"338": "Extra_Appraise_Armor_Skill_Lowering",
|
||||||
|
"339": "Extra_Cooking_Skill_Raising",
|
||||||
|
"340": "Extra_Cooking_Skill_Lowering",
|
||||||
|
"341": "Extra_Crossbow_Skill_Raising",
|
||||||
|
"342": "Extra_Crossbow_Skill_Lowering",
|
||||||
|
"343": "Extra_Deception_Skill_Raising",
|
||||||
|
"344": "Extra_Deception_Skill_Lowering",
|
||||||
|
"345": "Extra_Loyalty_Skill_Raising",
|
||||||
|
"346": "Extra_Loyalty_Skill_Lowering",
|
||||||
|
"347": "Extra_Fletching_Skill_Raising",
|
||||||
|
"348": "Extra_Fletching_Skill_Lowering",
|
||||||
|
"349": "Extra_Healing_Skill_Raising",
|
||||||
|
"350": "Extra_Healing_Skill_Lowering",
|
||||||
|
"351": "Extra_Melee_Defense_Skill_Raising",
|
||||||
|
"352": "Extra_Melee_Defense_Skill_Lowering",
|
||||||
|
"353": "Extra_Appraise_Item_Skill_Raising",
|
||||||
|
"354": "Extra_Appraise_Item_Skill_Lowering",
|
||||||
|
"355": "Extra_Jumping_Skill_Raising",
|
||||||
|
"356": "Extra_Jumping_Skill_Lowering",
|
||||||
|
"357": "Extra_Life_Magic_Skill_Raising",
|
||||||
|
"358": "Extra_Life_Magic_Skill_Lowering",
|
||||||
|
"359": "Extra_Lockpick_Skill_Raising",
|
||||||
|
"360": "Extra_Lockpick_Skill_Lowering",
|
||||||
|
"361": "Extra_Appraise_Magic_Item_Skill_Raising",
|
||||||
|
"362": "Extra_Appraise_Magic_Item_Skill_Lowering",
|
||||||
|
"363": "Extra_Mana_Conversion_Skill_Raising",
|
||||||
|
"364": "Extra_Mana_Conversion_Skill_Lowering",
|
||||||
|
"365": "Extra_Assess_Creature_Skill_Raising",
|
||||||
|
"366": "Extra_Assess_Creature_Skill_Lowering",
|
||||||
|
"367": "Extra_Assess_Person_Skill_Raising",
|
||||||
|
"368": "Extra_Assess_Person_Skill_Lowering",
|
||||||
|
"369": "Extra_Run_Skill_Raising",
|
||||||
|
"370": "Extra_Run_Skill_Lowering",
|
||||||
|
"371": "Extra_Sword_Skill_Raising",
|
||||||
|
"372": "Extra_Sword_Skill_Lowering",
|
||||||
|
"373": "Extra_Thrown_Weapons_Skill_Raising",
|
||||||
|
"374": "Extra_Thrown_Weapons_Skill_Lowering",
|
||||||
|
"375": "Extra_Unarmed_Combat_Skill_Raising",
|
||||||
|
"376": "Extra_Unarmed_Combat_Skill_Lowering",
|
||||||
|
"377": "Extra_Appraise_Weapon_Skill_Raising",
|
||||||
|
"378": "Extra_Appraise_Weapon_Skill_Lowering",
|
||||||
|
"379": "Armor_Increase",
|
||||||
|
"380": "Armor_Decrease",
|
||||||
|
"381": "Extra_Acid_Resistance_Raising",
|
||||||
|
"382": "Extra_Acid_Resistance_Lowering",
|
||||||
|
"383": "Extra_Bludgeon_Resistance_Raising",
|
||||||
|
"384": "Extra_Bludgeon_Resistance_Lowering",
|
||||||
|
"385": "Extra_Fire_Resistance_Raising",
|
||||||
|
"386": "Extra_Fire_Resistance_Lowering",
|
||||||
|
"387": "Extra_Cold_Resistance_Raising",
|
||||||
|
"388": "Extra_Cold_Resistance_Lowering",
|
||||||
|
"389": "Extra_Attack_Mod_Raising",
|
||||||
|
"390": "Extra_Attack_Mod_Lowering",
|
||||||
|
"391": "Extra_Armor_Value_Raising",
|
||||||
|
"392": "Extra_Armor_Value_Lowering",
|
||||||
|
"393": "Extra_Pierce_Resistance_Raising",
|
||||||
|
"394": "Extra_Pierce_Resistance_Lowering",
|
||||||
|
"395": "Extra_Slash_Resistance_Raising",
|
||||||
|
"396": "Extra_Slash_Resistance_Lowering",
|
||||||
|
"397": "Extra_Electric_Resistance_Raising",
|
||||||
|
"398": "Extra_Electric_Resistance_Lowering",
|
||||||
|
"399": "Extra_Weapon_Time_Raising",
|
||||||
|
"400": "Extra_Weapon_Time_Lowering",
|
||||||
|
"401": "Bludgeon_Ward_Protection",
|
||||||
|
"402": "Bludgeon_Ward_Vulnerability",
|
||||||
|
"403": "Slash_Ward_Protection",
|
||||||
|
"404": "Slash_Ward_Vulnerability",
|
||||||
|
"405": "Pierce_Ward_Protection",
|
||||||
|
"406": "Pierce_Ward_Vulnerability",
|
||||||
|
"407": "Stamina_Restoring",
|
||||||
|
"408": "Stamina_Depleting",
|
||||||
|
"409": "Fireworks",
|
||||||
|
"410": "Health_Divide",
|
||||||
|
"411": "Stamina_Divide",
|
||||||
|
"412": "Mana_Divide",
|
||||||
|
"413": "Coordination_Increase2",
|
||||||
|
"414": "Strength_Increase2",
|
||||||
|
"415": "Focus_Increase2",
|
||||||
|
"416": "Endurance_Increase2",
|
||||||
|
"417": "Self_Increase2",
|
||||||
|
"418": "Melee_Defense_Multiply",
|
||||||
|
"419": "Missile_Defense_Multiply",
|
||||||
|
"420": "Magic_Defense_Multiply",
|
||||||
|
"421": "Attributes_Decrease",
|
||||||
|
"422": "LifeGiver_Raising2",
|
||||||
|
"423": "Item_Enchantment_Raising2",
|
||||||
|
"424": "Skills_Decrease",
|
||||||
|
"425": "Extra_Mana_Conversion_Bonus",
|
||||||
|
"426": "War_Mystic_Raising2",
|
||||||
|
"427": "War_Mystic_Lowering2",
|
||||||
|
"428": "Magic_Defense_Shelter_Raising2",
|
||||||
|
"429": "Extra_Life_Magic_Skill_Raising2",
|
||||||
|
"430": "Creature_Mystic_Raising2",
|
||||||
|
"431": "Item_Mystic_Raising2",
|
||||||
|
"432": "Mana_Raising2",
|
||||||
|
"433": "Self_Raising2",
|
||||||
|
"434": "CreatureEnchantment_Raising2",
|
||||||
|
"435": "Salvaging_Raising",
|
||||||
|
"436": "Extra_Salvaging_Raising",
|
||||||
|
"437": "Extra_Salvaging_Raising2",
|
||||||
|
"438": "CascadeAxe_Raising2",
|
||||||
|
"439": "Extra_Bow_Skill_Raising2",
|
||||||
|
"440": "Extra_Thrown_Weapons_Skill_Raising2",
|
||||||
|
"441": "Extra_Crossbow_Skill_Raising2",
|
||||||
|
"442": "CascadeDagger_Raising2",
|
||||||
|
"443": "CascadeMace_Raising2",
|
||||||
|
"444": "Extra_Unarmed_Combat_Skill_Raising2",
|
||||||
|
"445": "CascadeSpear_Raising2",
|
||||||
|
"446": "CascadeStaff_Raising2",
|
||||||
|
"447": "Extra_Sword_Skill_Raising2",
|
||||||
|
"448": "Acid_Protection_Rare",
|
||||||
|
"449": "Acid_Resistance_Raising_Rare",
|
||||||
|
"450": "Alchemy_Raising_Rare",
|
||||||
|
"451": "Appraisal_Resistance_Lowering_Rare",
|
||||||
|
"452": "Appraise_Armor_Raising_Rare",
|
||||||
|
"453": "Appraise_Item_Raising_Rare",
|
||||||
|
"454": "Appraise_Magic_Item_Raising_Rare",
|
||||||
|
"455": "Appraise_Weapon_Raising_Rare",
|
||||||
|
"456": "Arcane_Lore_Raising_Rare",
|
||||||
|
"457": "Armor_Raising_Rare",
|
||||||
|
"458": "Armor_Value_Raising_Rare",
|
||||||
|
"459": "Assess_Monster_Raising_Rare",
|
||||||
|
"460": "Assess_Person_Raising_Rare",
|
||||||
|
"461": "Attack_Mod_Raising_Rare",
|
||||||
|
"462": "Axe_Raising_Rare",
|
||||||
|
"463": "Bludgeon_Protection_Rare",
|
||||||
|
"464": "Bludgeon_Resistance_Raising_Rare",
|
||||||
|
"465": "Bow_Raising_Rare",
|
||||||
|
"466": "Cold_Protection_Rare",
|
||||||
|
"467": "Cold_Resistance_Raising_Rare",
|
||||||
|
"468": "Cooking_Raising_Rare",
|
||||||
|
"469": "Coordination_Raising_Rare",
|
||||||
|
"470": "Creature_Enchantment_Raising_Rare",
|
||||||
|
"471": "Crossbow_Raising_Rare",
|
||||||
|
"472": "Dagger_Raising_Rare",
|
||||||
|
"473": "Damage_Raising_Rare",
|
||||||
|
"474": "Deception_Raising_Rare",
|
||||||
|
"475": "Defense_Mod_Raising_Rare",
|
||||||
|
"476": "Electric_Protection_Rare",
|
||||||
|
"477": "Electric_Resistance_Raising_Rare",
|
||||||
|
"478": "Endurance_Raising_Rare",
|
||||||
|
"479": "Fire_Protection_Rare",
|
||||||
|
"480": "Fire_Resistance_Raising_Rare",
|
||||||
|
"481": "Fletching_Raising_Rare",
|
||||||
|
"482": "Focus_Raising_Rare",
|
||||||
|
"483": "Healing_Raising_Rare",
|
||||||
|
"484": "Health_Accelerating_Rare",
|
||||||
|
"485": "Item_Enchantment_Raising_Rare",
|
||||||
|
"486": "Jump_Raising_Rare",
|
||||||
|
"487": "Leadership_Raising_Rare",
|
||||||
|
"488": "Life_Magic_Raising_Rare",
|
||||||
|
"489": "Lockpick_Raising_Rare",
|
||||||
|
"490": "Loyalty_Raising_Rare",
|
||||||
|
"491": "Mace_Raising_Rare",
|
||||||
|
"492": "Magic_Defense_Raising_Rare",
|
||||||
|
"493": "Mana_Accelerating_Rare",
|
||||||
|
"494": "Mana_Conversion_Raising_Rare",
|
||||||
|
"495": "Melee_Defense_Raising_Rare",
|
||||||
|
"496": "Missile_Defense_Raising_Rare",
|
||||||
|
"497": "Pierce_Protection_Rare",
|
||||||
|
"498": "Pierce_Resistance_Raising_Rare",
|
||||||
|
"499": "Quickness_Raising_Rare",
|
||||||
|
"500": "Run_Raising_Rare",
|
||||||
|
"501": "Self_Raising_Rare",
|
||||||
|
"502": "Slash_Protection_Rare",
|
||||||
|
"503": "Slash_Resistance_Raising_Rare",
|
||||||
|
"504": "Spear_Raising_Rare",
|
||||||
|
"505": "Staff_Raising_Rare",
|
||||||
|
"506": "Stamina_Accelerating_Rare",
|
||||||
|
"507": "Strength_Raising_Rare",
|
||||||
|
"508": "Sword_Raising_Rare",
|
||||||
|
"509": "Thrown_Weapons_Raising_Rare",
|
||||||
|
"510": "Unarmed_Combat_Raising_Rare",
|
||||||
|
"511": "War_Magic_Raising_Rare",
|
||||||
|
"512": "Weapon_Time_Raising_Rare",
|
||||||
|
"513": "Armor_Increase_Inky_Armor",
|
||||||
|
"514": "Magic_Defense_Shelter_Raising_Fiun",
|
||||||
|
"515": "Extra_Run_Skill_Raising_Fiun",
|
||||||
|
"516": "Extra_Mana_Conversion_Skill_Raising_Fiun",
|
||||||
|
"517": "Attributes_Increase_Cantrip1",
|
||||||
|
"518": "Extra_Melee_Defense_Skill_Raising2",
|
||||||
|
"519": "ACTDPurchaseRewardSpell",
|
||||||
|
"520": "ACTDPurchaseRewardSpellHealth",
|
||||||
|
"521": "SaltAsh_Attack_Mod_Raising",
|
||||||
|
"522": "Quickness_Increase2",
|
||||||
|
"523": "Extra_Alchemy_Skill_Raising2",
|
||||||
|
"524": "Extra_Cooking_Skill_Raising2",
|
||||||
|
"525": "Extra_Fletching_Skill_Raising2",
|
||||||
|
"526": "Extra_Lockpick_Skill_Raising2",
|
||||||
|
"527": "MucorManaWell",
|
||||||
|
"528": "Stamina_Restoring2",
|
||||||
|
"529": "Allegiance_Raising",
|
||||||
|
"530": "Health_DoT",
|
||||||
|
"531": "Health_DoT_Secondary",
|
||||||
|
"532": "Health_DoT_Tertiary",
|
||||||
|
"533": "Health_HoT",
|
||||||
|
"534": "Health_HoT_Secondary",
|
||||||
|
"535": "Health_HoT_Tertiary",
|
||||||
|
"536": "Health_Divide_Secondary",
|
||||||
|
"537": "Health_Divide_Tertiary",
|
||||||
|
"538": "SetSword_Raising",
|
||||||
|
"539": "SetAxe_Raising",
|
||||||
|
"540": "SetDagger_Raising",
|
||||||
|
"541": "SetMace_Raising",
|
||||||
|
"542": "SetSpear_Raising",
|
||||||
|
"543": "SetStaff_Raising",
|
||||||
|
"544": "SetUnarmed_Raising",
|
||||||
|
"545": "SetBow_Raising",
|
||||||
|
"546": "SetCrossbow_Raising",
|
||||||
|
"547": "SetThrown_Raising",
|
||||||
|
"548": "SetItemEnchantment_Raising",
|
||||||
|
"549": "SetCreatureEnchantment_Raising",
|
||||||
|
"550": "SetWarMagic_Raising",
|
||||||
|
"551": "SetLifeMagic_Raising",
|
||||||
|
"552": "SetMeleeDefense_Raising",
|
||||||
|
"553": "SetMissileDefense_Raising",
|
||||||
|
"554": "SetMagicDefense_Raising",
|
||||||
|
"555": "SetStamina_Accelerating",
|
||||||
|
"556": "SetCooking_Raising",
|
||||||
|
"557": "SetFletching_Raising",
|
||||||
|
"558": "SetLockpick_Raising",
|
||||||
|
"559": "SetAlchemy_Raising",
|
||||||
|
"560": "SetSalvaging_Raising",
|
||||||
|
"561": "SetArmorExpertise_Raising",
|
||||||
|
"562": "SetWeaponExpertise_Raising",
|
||||||
|
"563": "SetItemTinkering_Raising",
|
||||||
|
"564": "SetMagicItemExpertise_Raising",
|
||||||
|
"565": "SetLoyalty_Raising",
|
||||||
|
"566": "SetStrength_Raising",
|
||||||
|
"567": "SetEndurance_Raising",
|
||||||
|
"568": "SetCoordination_Raising",
|
||||||
|
"569": "SetQuickness_Raising",
|
||||||
|
"570": "SetFocus_Raising",
|
||||||
|
"571": "SetWillpower_Raising",
|
||||||
|
"572": "SetHealth_Raising",
|
||||||
|
"573": "SetStamina_Raising",
|
||||||
|
"574": "SetMana_Raising",
|
||||||
|
"575": "SetSprint_Raising",
|
||||||
|
"576": "SetJumping_Raising",
|
||||||
|
"577": "SetSlashResistance_Raising",
|
||||||
|
"578": "SetBludgeonResistance_Raising",
|
||||||
|
"579": "SetPierceResistance_Raising",
|
||||||
|
"580": "SetFlameResistance_Raising",
|
||||||
|
"581": "SetAcidResistance_Raising",
|
||||||
|
"582": "SetFrostResistance_Raising",
|
||||||
|
"583": "SetLightningResistance_Raising",
|
||||||
|
"584": "Crafting_LockPick_Raising",
|
||||||
|
"585": "Crafting_Fletching_Raising",
|
||||||
|
"586": "Crafting_Cooking_Raising",
|
||||||
|
"587": "Crafting_Alchemy_Raising",
|
||||||
|
"588": "Crafting_ArmorTinkering_Raising",
|
||||||
|
"589": "Crafting_WeaponTinkering_Raising",
|
||||||
|
"590": "Crafting_MagicTinkering_Raising",
|
||||||
|
"591": "Crafting_ItemTinkering_Raising",
|
||||||
|
"592": "SkillPercent_Alchemy_Raising",
|
||||||
|
"593": "TwoHanded_Raising",
|
||||||
|
"594": "TwoHanded_Lowering",
|
||||||
|
"595": "Extra_TwoHanded_Skill_Raising",
|
||||||
|
"596": "Extra_TwoHanded_Skill_Lowering",
|
||||||
|
"597": "Extra_TwoHanded_Skill_Raising2",
|
||||||
|
"598": "TwoHanded_Raising_Rare",
|
||||||
|
"599": "SetTwoHanded_Raising",
|
||||||
|
"600": "GearCraft_Raising",
|
||||||
|
"601": "GearCraft_Lowering",
|
||||||
|
"602": "Extra_GearCraft_Skill_Raising",
|
||||||
|
"603": "Extra_GearCraft_Skill_Lowering",
|
||||||
|
"604": "Extra_GearCraft_Skill_Raising2",
|
||||||
|
"605": "GearCraft_Raising_Rare",
|
||||||
|
"606": "SetGearCraft_Raising",
|
||||||
|
"607": "LoyaltyMana_Raising",
|
||||||
|
"608": "LoyaltyStamina_Raising",
|
||||||
|
"609": "LeadershipHealth_Raising",
|
||||||
|
"610": "TrinketDamage_Raising",
|
||||||
|
"611": "TrinketDamage_Lowering",
|
||||||
|
"612": "TrinketHealth_Raising",
|
||||||
|
"613": "TrinketStamina_Raising",
|
||||||
|
"614": "TrinketMana_Raising",
|
||||||
|
"615": "TrinketXP_Raising",
|
||||||
|
"616": "DeceptionArcaneLore_Raising",
|
||||||
|
"617": "HealOverTime_Raising",
|
||||||
|
"618": "DamageOverTime_Raising",
|
||||||
|
"619": "HealingResistRating_Raising",
|
||||||
|
"620": "AetheriaDamageRating_Raising",
|
||||||
|
"621": "AetheriaDamageReduction_Raising",
|
||||||
|
"622": "SKIPPED",
|
||||||
|
"623": "AetheriaHealth_Raising",
|
||||||
|
"624": "AetheriaStamina_Raising",
|
||||||
|
"625": "AetheriaMana_Raising",
|
||||||
|
"626": "AetheriaCriticalDamage_Raising",
|
||||||
|
"627": "AetheriaHealingAmplification_Raising",
|
||||||
|
"628": "AetheriaProcDamageRating_Raising",
|
||||||
|
"629": "AetheriaProcDamageReduction_Raising",
|
||||||
|
"630": "AetheriaProcHealthOverTime_Raising",
|
||||||
|
"631": "AetheriaProcDamageOverTime_Raising",
|
||||||
|
"632": "AetheriaProcHealingReduction_Raising",
|
||||||
|
"633": "RareDamageRating_Raising",
|
||||||
|
"634": "RareDamageReductionRating_Raising",
|
||||||
|
"635": "AetheriaEndurance_Raising",
|
||||||
|
"636": "NetherDamageOverTime_Raising",
|
||||||
|
"637": "NetherDamageOverTime_Raising2",
|
||||||
|
"638": "NetherDamageOverTime_Raising3",
|
||||||
|
"639": "Nether_Streak",
|
||||||
|
"640": "Nether_Missile",
|
||||||
|
"641": "Nether_Ring",
|
||||||
|
"642": "NetherDamageRating_Lowering",
|
||||||
|
"643": "NetherDamageHealingReduction_Raising",
|
||||||
|
"644": "Void_Magic_Lowering",
|
||||||
|
"645": "Void_Magic_Raising",
|
||||||
|
"646": "Void_Mystic_Raising",
|
||||||
|
"647": "SetVoidMagic_Raising",
|
||||||
|
"648": "Void_Magic_Raising_Rare",
|
||||||
|
"649": "Void_Mystic_Raising2",
|
||||||
|
"650": "LuminanceDamageRating_Raising",
|
||||||
|
"651": "LuminanceDamageReduction_Raising",
|
||||||
|
"652": "LuminanceHealth_Raising",
|
||||||
|
"653": "AetheriaCriticalReduction_Raising",
|
||||||
|
"654": "Extra_Missile_Defense_Skill_Raising",
|
||||||
|
"655": "Extra_Missile_Defense_Skill_Lowering",
|
||||||
|
"656": "Extra_Missile_Defense_Skill_Raising2",
|
||||||
|
"657": "AetheriaHealthResistance_Raising",
|
||||||
|
"658": "AetheriaDotResistance_Raising",
|
||||||
|
"659": "Cloak_Skill_Raising",
|
||||||
|
"660": "Cloak_All_Skill_Raising",
|
||||||
|
"661": "Cloak_Magic_Defense_Lowering",
|
||||||
|
"662": "Cloak_Melee_Defense_Lowering",
|
||||||
|
"663": "Cloak_Missile_Defense_Lowering",
|
||||||
|
"664": "DirtyFighting_Lowering",
|
||||||
|
"665": "DirtyFighting_Raising",
|
||||||
|
"666": "Extra_DirtyFighting_Raising",
|
||||||
|
"667": "DualWield_Lowering",
|
||||||
|
"668": "DualWield_Raising",
|
||||||
|
"669": "Extra_DualWield_Raising",
|
||||||
|
"670": "Recklessness_Lowering",
|
||||||
|
"671": "Recklessness_Raising",
|
||||||
|
"672": "Extra_Recklessness_Raising",
|
||||||
|
"673": "Shield_Lowering",
|
||||||
|
"674": "Shield_Raising",
|
||||||
|
"675": "Extra_Shield_Raising",
|
||||||
|
"676": "SneakAttack_Lowering",
|
||||||
|
"677": "SneakAttack_Raising",
|
||||||
|
"678": "Extra_SneakAttack_Raising",
|
||||||
|
"679": "Rare_DirtyFighting_Raising",
|
||||||
|
"680": "Rare_DualWield_Raising",
|
||||||
|
"681": "Rare_Recklessness_Raising",
|
||||||
|
"682": "Rare_Shield_Raising",
|
||||||
|
"683": "Rare_SneakAttack_Raising",
|
||||||
|
"684": "DF_Attack_Skill_Debuff",
|
||||||
|
"685": "DF_Bleed_Damage",
|
||||||
|
"686": "DF_Defense_Skill_Debuff",
|
||||||
|
"687": "DF_Healing_Debuff",
|
||||||
|
"688": "SetDirtyFighting_Raising",
|
||||||
|
"689": "SetDualWield_Raising",
|
||||||
|
"690": "SetRecklessness_Raising",
|
||||||
|
"691": "SetShield_Raising",
|
||||||
|
"692": "SetSneakAttack_Raising",
|
||||||
|
"693": "LifeGiver_Mhoire",
|
||||||
|
"694": "RareDamageRating_Raising2",
|
||||||
|
"695": "Spell_Damage_Raising",
|
||||||
|
"696": "Summoning_Raising",
|
||||||
|
"697": "Summoning_Lowering",
|
||||||
|
"698": "Extra_Summoning_Skill_Raising",
|
||||||
|
"699": "SetSummoning_Raising"
|
||||||
|
},
|
||||||
|
"comments": {},
|
||||||
|
"attributes": {},
|
||||||
|
"source_file": "SpellCategory.cs"
|
||||||
|
}
|
||||||
|
}
|
||||||
74
inventory-service/enums/StringValueKey.json
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
{
|
||||||
|
"StringValueKey": {
|
||||||
|
"type": "int",
|
||||||
|
"values": {
|
||||||
|
"0": "Undef",
|
||||||
|
"1": "Name",
|
||||||
|
"2": "Title",
|
||||||
|
"3": "Sex",
|
||||||
|
"4": "HeritageGroup",
|
||||||
|
"5": "Template",
|
||||||
|
"6": "AttackersName",
|
||||||
|
"7": "Inscription",
|
||||||
|
"8": "ScribeName",
|
||||||
|
"9": "VendorsName",
|
||||||
|
"10": "Fellowship",
|
||||||
|
"11": "MonarchsName",
|
||||||
|
"12": "LockCode",
|
||||||
|
"13": "KeyCode",
|
||||||
|
"14": "Use",
|
||||||
|
"15": "ShortDesc",
|
||||||
|
"16": "LongDesc",
|
||||||
|
"17": "ActivationTalk",
|
||||||
|
"18": "UseMessage",
|
||||||
|
"19": "ItemHeritageGroupRestriction",
|
||||||
|
"20": "PluralName",
|
||||||
|
"21": "MonarchsTitle",
|
||||||
|
"22": "ActivationFailure",
|
||||||
|
"23": "ScribeAccount",
|
||||||
|
"24": "TownName",
|
||||||
|
"25": "CraftsmanName",
|
||||||
|
"26": "UsePkServerError",
|
||||||
|
"27": "ScoreCachedText",
|
||||||
|
"28": "ScoreDefaultEntryFormat",
|
||||||
|
"29": "ScoreFirstEntryFormat",
|
||||||
|
"30": "ScoreLastEntryFormat",
|
||||||
|
"31": "ScoreOnlyEntryFormat",
|
||||||
|
"32": "ScoreNoEntry",
|
||||||
|
"33": "Quest",
|
||||||
|
"34": "GeneratorEvent",
|
||||||
|
"35": "PatronsTitle",
|
||||||
|
"36": "HouseOwnerName",
|
||||||
|
"37": "QuestRestriction",
|
||||||
|
"38": "AppraisalPortalDestination",
|
||||||
|
"39": "TinkerName",
|
||||||
|
"40": "ImbuerName",
|
||||||
|
"41": "HouseOwnerAccount",
|
||||||
|
"42": "DisplayName",
|
||||||
|
"43": "DateOfBirth",
|
||||||
|
"44": "ThirdPartyApi",
|
||||||
|
"45": "KillQuest",
|
||||||
|
"46": "Afk",
|
||||||
|
"47": "AllegianceName",
|
||||||
|
"48": "AugmentationAddQuest",
|
||||||
|
"49": "KillQuest2",
|
||||||
|
"50": "KillQuest3",
|
||||||
|
"51": "UseSendsSignal",
|
||||||
|
"52": "GearPlatingName",
|
||||||
|
"8006": "PCAPRecordedCurrentMotionState",
|
||||||
|
"8031": "PCAPRecordedServerName",
|
||||||
|
"8032": "PCAPRecordedCharacterName",
|
||||||
|
"9001": "AllegianceMotd",
|
||||||
|
"9002": "AllegianceMotdSetBy",
|
||||||
|
"9003": "AllegianceSpeakerTitle",
|
||||||
|
"9004": "AllegianceSeneschalTitle",
|
||||||
|
"9005": "AllegianceCastellanTitle",
|
||||||
|
"9006": "GodState",
|
||||||
|
"9007": "TinkerLog",
|
||||||
|
"184549376": "SecondaryName_Decal"
|
||||||
|
},
|
||||||
|
"comments": {},
|
||||||
|
"attributes": {},
|
||||||
|
"source_file": "StringValueKey.cs"
|
||||||
|
}
|
||||||
|
}
|
||||||
84
inventory-service/enums/WeenieType.json
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
{
|
||||||
|
"WeenieType": {
|
||||||
|
"type": "uint",
|
||||||
|
"values": {
|
||||||
|
"0": "Undef",
|
||||||
|
"1": "Generic",
|
||||||
|
"2": "Clothing",
|
||||||
|
"3": "MissileLauncher",
|
||||||
|
"4": "Missile",
|
||||||
|
"5": "Ammunition",
|
||||||
|
"6": "MeleeWeapon",
|
||||||
|
"7": "Portal",
|
||||||
|
"8": "Book",
|
||||||
|
"9": "Coin",
|
||||||
|
"10": "Creature",
|
||||||
|
"11": "Admin",
|
||||||
|
"12": "Vendor",
|
||||||
|
"13": "HotSpot",
|
||||||
|
"14": "Corpse",
|
||||||
|
"15": "Cow",
|
||||||
|
"16": "AI",
|
||||||
|
"17": "Machine",
|
||||||
|
"18": "Food",
|
||||||
|
"19": "Door",
|
||||||
|
"20": "Chest",
|
||||||
|
"21": "Container",
|
||||||
|
"22": "Key",
|
||||||
|
"23": "Lockpick",
|
||||||
|
"24": "PressurePlate",
|
||||||
|
"25": "LifeStone",
|
||||||
|
"26": "Switch",
|
||||||
|
"27": "PKModifier",
|
||||||
|
"28": "Healer",
|
||||||
|
"29": "LightSource",
|
||||||
|
"30": "Allegiance",
|
||||||
|
"31": "UNKNOWN__GUESSEDNAME32",
|
||||||
|
"32": "SpellComponent",
|
||||||
|
"33": "ProjectileSpell",
|
||||||
|
"34": "Scroll",
|
||||||
|
"35": "Caster",
|
||||||
|
"36": "Channel",
|
||||||
|
"37": "ManaStone",
|
||||||
|
"38": "Gem",
|
||||||
|
"39": "AdvocateFane",
|
||||||
|
"40": "AdvocateItem",
|
||||||
|
"41": "Sentinel",
|
||||||
|
"42": "GSpellEconomy",
|
||||||
|
"43": "LSpellEconomy",
|
||||||
|
"44": "CraftTool",
|
||||||
|
"45": "LScoreKeeper",
|
||||||
|
"46": "GScoreKeeper",
|
||||||
|
"47": "GScoreGatherer",
|
||||||
|
"48": "ScoreBook",
|
||||||
|
"49": "EventCoordinator",
|
||||||
|
"50": "Entity",
|
||||||
|
"51": "Stackable",
|
||||||
|
"52": "HUD",
|
||||||
|
"53": "House",
|
||||||
|
"54": "Deed",
|
||||||
|
"55": "SlumLord",
|
||||||
|
"56": "Hook",
|
||||||
|
"57": "Storage",
|
||||||
|
"58": "BootSpot",
|
||||||
|
"59": "HousePortal",
|
||||||
|
"60": "Game",
|
||||||
|
"61": "GamePiece",
|
||||||
|
"62": "SkillAlterationDevice",
|
||||||
|
"63": "AttributeTransferDevice",
|
||||||
|
"64": "Hooker",
|
||||||
|
"65": "AllegianceBindstone",
|
||||||
|
"66": "InGameStatKeeper",
|
||||||
|
"67": "AugmentationDevice",
|
||||||
|
"68": "SocialManager",
|
||||||
|
"69": "Pet",
|
||||||
|
"70": "PetDevice",
|
||||||
|
"71": "CombatPet"
|
||||||
|
},
|
||||||
|
"comments": {
|
||||||
|
"UNKNOWN__GUESSEDNAME32": "NOTE: Missing 1"
|
||||||
|
},
|
||||||
|
"attributes": {},
|
||||||
|
"source_file": "WeenieType.cs"
|
||||||
|
}
|
||||||
|
}
|
||||||
23
inventory-service/enums/WieldRequirement.json
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"WieldRequirement": {
|
||||||
|
"type": "int",
|
||||||
|
"values": {
|
||||||
|
"0": "Invalid",
|
||||||
|
"1": "Skill",
|
||||||
|
"2": "RawSkill",
|
||||||
|
"3": "Attrib",
|
||||||
|
"4": "RawAttrib",
|
||||||
|
"5": "SecondaryAttrib",
|
||||||
|
"6": "RawSecondaryAttrib",
|
||||||
|
"7": "Level",
|
||||||
|
"8": "Training",
|
||||||
|
"9": "IntStat",
|
||||||
|
"10": "BoolStat",
|
||||||
|
"11": "CreatureType",
|
||||||
|
"12": "HeritageType"
|
||||||
|
},
|
||||||
|
"comments": {},
|
||||||
|
"attributes": {},
|
||||||
|
"source_file": "WieldRequirement.cs"
|
||||||
|
}
|
||||||
|
}
|
||||||
294
inventory-service/extract_all_enums.py
Normal file
|
|
@ -0,0 +1,294 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Comprehensive enum extraction from Mag-Plugins/Shared/Constants directory.
|
||||||
|
|
||||||
|
This script extracts ALL enum definitions from the Mag-Plugins source code
|
||||||
|
and creates structured JSON mappings for the inventory service.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Dict, List, Any, Tuple, Optional
|
||||||
|
|
||||||
|
def extract_enum_from_file(file_path: Path) -> Tuple[str, Dict[str, Any]]:
|
||||||
|
"""Extract enum definition from a C# file."""
|
||||||
|
|
||||||
|
with open(file_path, 'r', encoding='utf-8') as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
# Find enum declaration
|
||||||
|
enum_match = re.search(r'public enum (\w+)(?:\s*:\s*(\w+))?\s*{', content)
|
||||||
|
if not enum_match:
|
||||||
|
return None, {}
|
||||||
|
|
||||||
|
enum_name = enum_match.group(1)
|
||||||
|
enum_type = enum_match.group(2) or 'int'
|
||||||
|
|
||||||
|
print(f"Extracting {enum_name} from {file_path.name}")
|
||||||
|
|
||||||
|
# Extract enum entries
|
||||||
|
entries = {}
|
||||||
|
comments = {}
|
||||||
|
attributes = {}
|
||||||
|
|
||||||
|
# Pattern to match enum entries with various formats
|
||||||
|
# Supports: Name = Value, Name, Name = 0x12345, etc.
|
||||||
|
pattern = r'^\s*(?:\[([^\]]+)\])?\s*(?:/// <summary>\s*([^<]*?)\s*/// </summary>\s*)?(?:\[([^\]]+)\])?\s*(\w+)(?:\s*=\s*([^,]+?))?\s*,?\s*(?://\s*(.*))?$'
|
||||||
|
|
||||||
|
lines = content.split('\n')
|
||||||
|
in_enum = False
|
||||||
|
current_value = 0
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
# Check if we're entering the enum
|
||||||
|
if f'enum {enum_name}' in line:
|
||||||
|
in_enum = True
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Check if we're exiting the enum
|
||||||
|
if in_enum and '}' in line and not line.strip().startswith('//'):
|
||||||
|
break
|
||||||
|
|
||||||
|
if in_enum:
|
||||||
|
match = re.match(pattern, line)
|
||||||
|
if match:
|
||||||
|
attr1, summary, attr2, name, value, comment = match.groups()
|
||||||
|
|
||||||
|
# Parse value
|
||||||
|
if value:
|
||||||
|
value = value.strip()
|
||||||
|
if value.startswith('0x') and ' ' not in value:
|
||||||
|
# Simple hex value
|
||||||
|
parsed_value = int(value, 16)
|
||||||
|
elif value.isdigit():
|
||||||
|
# Simple integer
|
||||||
|
parsed_value = int(value)
|
||||||
|
elif '|' in value or '<<' in value or '+' in value:
|
||||||
|
# Complex expression - store as string for now
|
||||||
|
parsed_value = f"EXPR:{value}"
|
||||||
|
else:
|
||||||
|
# Try simple conversion
|
||||||
|
try:
|
||||||
|
parsed_value = int(value)
|
||||||
|
except ValueError:
|
||||||
|
parsed_value = f"VALUE:{value}"
|
||||||
|
else:
|
||||||
|
parsed_value = current_value
|
||||||
|
|
||||||
|
entries[parsed_value] = name
|
||||||
|
|
||||||
|
# Update current_value for auto-increment
|
||||||
|
if isinstance(parsed_value, int):
|
||||||
|
current_value = parsed_value + 1
|
||||||
|
else:
|
||||||
|
# For non-numeric values, increment anyway for next entry
|
||||||
|
current_value += 1
|
||||||
|
|
||||||
|
# Store metadata
|
||||||
|
if summary:
|
||||||
|
comments[name] = summary.strip()
|
||||||
|
if comment:
|
||||||
|
comments[name] = comment.strip()
|
||||||
|
if attr1 or attr2:
|
||||||
|
attributes[name] = (attr1 or '') + ' ' + (attr2 or '')
|
||||||
|
|
||||||
|
return enum_name, {
|
||||||
|
'type': enum_type,
|
||||||
|
'values': entries,
|
||||||
|
'comments': comments,
|
||||||
|
'attributes': attributes,
|
||||||
|
'source_file': file_path.name
|
||||||
|
}
|
||||||
|
|
||||||
|
def extract_skill_names():
|
||||||
|
"""Extract skill names with their indices from Skill.cs"""
|
||||||
|
skill_file = Path('/home/erik/MosswartOverlord/Mag-Plugins/Shared/Constants/Skill.cs')
|
||||||
|
|
||||||
|
with open(skill_file, 'r') as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
skills = {}
|
||||||
|
lines = content.split('\n')
|
||||||
|
in_enum = False
|
||||||
|
index = 0
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
if 'enum Skill' in line:
|
||||||
|
in_enum = True
|
||||||
|
continue
|
||||||
|
|
||||||
|
if in_enum and '}' in line:
|
||||||
|
break
|
||||||
|
|
||||||
|
if in_enum:
|
||||||
|
# Match skill entries like "None," or "Axe, /* Retired */"
|
||||||
|
match = re.match(r'^\s*(\w+),?\s*(?:/\*\s*([^*]*)\s*\*/)?', line)
|
||||||
|
if match:
|
||||||
|
skill_name = match.group(1)
|
||||||
|
status = match.group(2) or "Active"
|
||||||
|
skills[index] = {
|
||||||
|
'name': skill_name,
|
||||||
|
'status': status.strip()
|
||||||
|
}
|
||||||
|
index += 1
|
||||||
|
|
||||||
|
return skills
|
||||||
|
|
||||||
|
def categorize_enums():
|
||||||
|
"""Create logical categories for different enum types."""
|
||||||
|
return {
|
||||||
|
'item_properties': {
|
||||||
|
'description': 'Item property value keys for different data types',
|
||||||
|
'enums': ['IntValueKey', 'DoubleValueKey', 'StringValueKey', 'BoolValueKey', 'QuadValueKey']
|
||||||
|
},
|
||||||
|
'item_classification': {
|
||||||
|
'description': 'Item type and material classification',
|
||||||
|
'enums': ['ItemType', 'MaterialType', 'WeenieType']
|
||||||
|
},
|
||||||
|
'game_mechanics': {
|
||||||
|
'description': 'Skills, spells, and game system enums',
|
||||||
|
'enums': ['Skill', 'SpellCategory', 'WieldRequirement']
|
||||||
|
},
|
||||||
|
'technical': {
|
||||||
|
'description': 'Technical flags and masks for game engine',
|
||||||
|
'enums': ['CoverageMask', 'EquipMask']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def create_translation_mappings():
|
||||||
|
"""Create user-friendly translations for important enum values."""
|
||||||
|
|
||||||
|
# Map IntValueKey values to more descriptive names
|
||||||
|
int_value_translations = {
|
||||||
|
5: 'Encumbrance',
|
||||||
|
19: 'Value (Pyreals)',
|
||||||
|
25: 'Level',
|
||||||
|
28: 'Armor Level',
|
||||||
|
44: 'Base Damage',
|
||||||
|
45: 'Damage Type',
|
||||||
|
48: 'Weapon Skill',
|
||||||
|
158: 'Wield Requirements',
|
||||||
|
160: 'Wield Difficulty',
|
||||||
|
218103842: 'Maximum Damage',
|
||||||
|
218103849: 'Icon Overlay',
|
||||||
|
218103850: 'Icon Underlay'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Material type friendly names
|
||||||
|
material_translations = {
|
||||||
|
0: 'Unknown',
|
||||||
|
1: 'Ceramic',
|
||||||
|
20: 'Diamond',
|
||||||
|
21: 'Emerald',
|
||||||
|
31: 'Ruby',
|
||||||
|
32: 'Sapphire'
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
'int_values': int_value_translations,
|
||||||
|
'materials': material_translations
|
||||||
|
}
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Main extraction process."""
|
||||||
|
|
||||||
|
constants_dir = Path('/home/erik/MosswartOverlord/Mag-Plugins/Shared/Constants')
|
||||||
|
output_dir = Path('/home/erik/MosswartOverlord/inventory-service')
|
||||||
|
|
||||||
|
# Ensure output directory exists
|
||||||
|
output_dir.mkdir(exist_ok=True)
|
||||||
|
|
||||||
|
print("Starting comprehensive enum extraction from Mag-Plugins/Shared/Constants...")
|
||||||
|
|
||||||
|
# Extract all enum files
|
||||||
|
all_enums = {}
|
||||||
|
enum_files = list(constants_dir.glob('*.cs'))
|
||||||
|
|
||||||
|
for enum_file in enum_files:
|
||||||
|
if enum_file.name == 'Dictionaries.cs': # Skip non-enum files
|
||||||
|
continue
|
||||||
|
|
||||||
|
enum_name, enum_data = extract_enum_from_file(enum_file)
|
||||||
|
if enum_name and enum_data:
|
||||||
|
all_enums[enum_name] = enum_data
|
||||||
|
|
||||||
|
# Special handling for Skills (has complex structure)
|
||||||
|
skill_data = extract_skill_names()
|
||||||
|
all_enums['Skill'] = {
|
||||||
|
'type': 'indexed',
|
||||||
|
'values': skill_data,
|
||||||
|
'source_file': 'Skill.cs'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create categorized structure
|
||||||
|
categories = categorize_enums()
|
||||||
|
translations = create_translation_mappings()
|
||||||
|
|
||||||
|
# Save complete enum database
|
||||||
|
complete_data = {
|
||||||
|
'metadata': {
|
||||||
|
'extracted_at': '2025-06-10',
|
||||||
|
'source': 'Mag-Plugins/Shared/Constants',
|
||||||
|
'total_enums': len(all_enums),
|
||||||
|
'version': '1.0.0'
|
||||||
|
},
|
||||||
|
'categories': categories,
|
||||||
|
'translations': translations,
|
||||||
|
'enums': all_enums
|
||||||
|
}
|
||||||
|
|
||||||
|
# Save main database
|
||||||
|
main_output = output_dir / 'complete_enum_database.json'
|
||||||
|
with open(main_output, 'w') as f:
|
||||||
|
json.dump(complete_data, f, indent=2)
|
||||||
|
|
||||||
|
print(f"Saved complete enum database to {main_output}")
|
||||||
|
|
||||||
|
# Save individual enum files for backward compatibility
|
||||||
|
individual_dir = output_dir / 'enums'
|
||||||
|
individual_dir.mkdir(exist_ok=True)
|
||||||
|
|
||||||
|
for enum_name, enum_data in all_enums.items():
|
||||||
|
enum_file = individual_dir / f'{enum_name}.json'
|
||||||
|
with open(enum_file, 'w') as f:
|
||||||
|
json.dump({enum_name: enum_data}, f, indent=2)
|
||||||
|
|
||||||
|
# Update existing files for backward compatibility
|
||||||
|
if 'IntValueKey' in all_enums:
|
||||||
|
legacy_int_file = output_dir / 'int_value_enums.json'
|
||||||
|
with open(legacy_int_file, 'w') as f:
|
||||||
|
json.dump(all_enums['IntValueKey']['values'], f, indent=2)
|
||||||
|
print(f"Updated legacy file: {legacy_int_file}")
|
||||||
|
|
||||||
|
# Create comprehensive summary
|
||||||
|
print("\n" + "="*60)
|
||||||
|
print("EXTRACTION SUMMARY")
|
||||||
|
print("="*60)
|
||||||
|
|
||||||
|
for enum_name, enum_data in all_enums.items():
|
||||||
|
value_count = len(enum_data.get('values', {}))
|
||||||
|
enum_type = enum_data.get('type', 'unknown')
|
||||||
|
print(f"{enum_name:20} | {value_count:4} values | Type: {enum_type}")
|
||||||
|
|
||||||
|
print(f"\nTotal enums extracted: {len(all_enums)}")
|
||||||
|
print(f"Files created:")
|
||||||
|
print(f" - {main_output}")
|
||||||
|
print(f" - {len(all_enums)} individual enum files in {individual_dir}/")
|
||||||
|
|
||||||
|
# Show sample translations
|
||||||
|
print("\nSample enum translations:")
|
||||||
|
for enum_name in ['IntValueKey', 'MaterialType', 'ItemType', 'Skill']:
|
||||||
|
if enum_name in all_enums:
|
||||||
|
values = all_enums[enum_name]['values']
|
||||||
|
if isinstance(values, dict):
|
||||||
|
sample_keys = list(values.keys())[:3]
|
||||||
|
for key in sample_keys:
|
||||||
|
if isinstance(values[key], dict):
|
||||||
|
print(f" {enum_name}[{key}] = {values[key].get('name', values[key])}")
|
||||||
|
else:
|
||||||
|
print(f" {enum_name}[{key}] = {values[key]}")
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
268
inventory-service/extract_comprehensive_enums.py
Normal 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()
|
||||||
130
inventory-service/extract_enums.py
Normal file
|
|
@ -0,0 +1,130 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Extract enum definitions from Mag-Plugins C# files into JSON mappings.
|
||||||
|
|
||||||
|
This script parses the IntValueKey.cs file to create a mapping between
|
||||||
|
numeric enum values and their human-readable names for inventory processing.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
def extract_int_value_enums(cs_file_path):
|
||||||
|
"""Extract IntValueKey enum definitions from C# file."""
|
||||||
|
|
||||||
|
with open(cs_file_path, 'r') as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
# Pattern to match enum entries: EnumName = Value,
|
||||||
|
pattern = r'^\s*(?:\[[^\]]+\])?\s*(\w+)\s*=\s*(\d+),?\s*(?://.*)?$'
|
||||||
|
|
||||||
|
enums = {}
|
||||||
|
in_enum = False
|
||||||
|
|
||||||
|
for line in content.split('\n'):
|
||||||
|
# Check if we're entering the enum
|
||||||
|
if 'enum IntValueKey' in line:
|
||||||
|
in_enum = True
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Check if we're exiting the enum
|
||||||
|
if in_enum and line.strip() == '}':
|
||||||
|
break
|
||||||
|
|
||||||
|
# Parse enum entries
|
||||||
|
if in_enum:
|
||||||
|
match = re.match(pattern, line)
|
||||||
|
if match:
|
||||||
|
name = match.group(1)
|
||||||
|
value = int(match.group(2))
|
||||||
|
enums[value] = name
|
||||||
|
|
||||||
|
return enums
|
||||||
|
|
||||||
|
def create_property_mappings():
|
||||||
|
"""Create organized property mappings for different item aspects."""
|
||||||
|
|
||||||
|
# Based on analysis of the enum values and common item properties
|
||||||
|
property_categories = {
|
||||||
|
'basic': {
|
||||||
|
5: 'encumbrance', # EncumbranceVal
|
||||||
|
19: 'value', # Value
|
||||||
|
25: 'level', # Level
|
||||||
|
28: 'armor_level', # ArmorLevel
|
||||||
|
44: 'damage', # Damage
|
||||||
|
45: 'damage_type', # DamageType
|
||||||
|
},
|
||||||
|
|
||||||
|
'requirements': {
|
||||||
|
158: 'wield_requirement', # Common wield requirement key (from JSON data)
|
||||||
|
160: 'wield_level', # Common wield level key (from JSON data)
|
||||||
|
48: 'weapon_skill', # WeaponSkill
|
||||||
|
},
|
||||||
|
|
||||||
|
'combat': {
|
||||||
|
218103842: 'max_damage', # MaxDamage_Decal
|
||||||
|
36: 'resist_magic', # ResistMagic
|
||||||
|
56: 'shield_value', # ShieldValue
|
||||||
|
},
|
||||||
|
|
||||||
|
'display': {
|
||||||
|
218103809: 'icon', # Icon_Decal_DID
|
||||||
|
218103849: 'icon_overlay', # IconOverlay_Decal_DID
|
||||||
|
218103850: 'icon_underlay', # IconUnderlay_Decal_DID
|
||||||
|
},
|
||||||
|
|
||||||
|
'metadata': {
|
||||||
|
218103808: 'weenie_class_id', # WeenieClassId_Decal
|
||||||
|
218103847: 'physics_data_flags', # PhysicsDataFlags_Decal
|
||||||
|
218103831: 'object_desc_flags', # ObjectDescriptionFlags_Decal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return property_categories
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Main extraction process."""
|
||||||
|
|
||||||
|
# Paths
|
||||||
|
mag_plugins_path = Path('/home/erik/MosswartOverlord/Mag-Plugins')
|
||||||
|
int_value_key_path = mag_plugins_path / 'Shared' / 'Constants' / 'IntValueKey.cs'
|
||||||
|
output_dir = Path('/home/erik/MosswartOverlord/inventory-service')
|
||||||
|
|
||||||
|
# Create output directory
|
||||||
|
output_dir.mkdir(exist_ok=True)
|
||||||
|
|
||||||
|
# Extract all enum values
|
||||||
|
print("Extracting IntValueKey enums...")
|
||||||
|
int_enums = extract_int_value_enums(int_value_key_path)
|
||||||
|
print(f"Found {len(int_enums)} enum definitions")
|
||||||
|
|
||||||
|
# Create property categories
|
||||||
|
property_categories = create_property_mappings()
|
||||||
|
|
||||||
|
# Save complete enum mapping
|
||||||
|
enum_output = output_dir / 'int_value_enums.json'
|
||||||
|
with open(enum_output, 'w') as f:
|
||||||
|
json.dump(int_enums, f, indent=2)
|
||||||
|
print(f"Saved complete enum mapping to {enum_output}")
|
||||||
|
|
||||||
|
# Save categorized mappings
|
||||||
|
categories_output = output_dir / 'property_categories.json'
|
||||||
|
with open(categories_output, 'w') as f:
|
||||||
|
json.dump(property_categories, f, indent=2)
|
||||||
|
print(f"Saved property categories to {categories_output}")
|
||||||
|
|
||||||
|
# Print some interesting findings
|
||||||
|
print("\nKey mappings found:")
|
||||||
|
interesting_keys = [5, 19, 28, 44, 158, 160, 218103809, 218103842, 218103847, 218103849]
|
||||||
|
for key in interesting_keys:
|
||||||
|
if key in int_enums:
|
||||||
|
print(f" {key}: {int_enums[key]}")
|
||||||
|
|
||||||
|
print(f"\nFiles created in {output_dir}/")
|
||||||
|
print("- int_value_enums.json: Complete enum mapping")
|
||||||
|
print("- property_categories.json: Organized property categories")
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
121
inventory-service/extract_spell_names.py
Normal file
|
|
@ -0,0 +1,121 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Extract spell names from Mag-Plugins/Shared/Spells/Spells.csv for spell ID translation.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import csv
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
def extract_spell_names():
|
||||||
|
"""Extract spell ID to name mappings from Spells.csv."""
|
||||||
|
|
||||||
|
csv_path = Path('/home/erik/MosswartOverlord/Mag-Plugins/Shared/Spells/Spells.csv')
|
||||||
|
|
||||||
|
if not csv_path.exists():
|
||||||
|
print(f"❌ Spells.csv not found at {csv_path}")
|
||||||
|
return {}
|
||||||
|
|
||||||
|
spell_mappings = {}
|
||||||
|
|
||||||
|
# Try different encodings
|
||||||
|
encodings = ['utf-8', 'latin-1', 'windows-1252', 'utf-8-sig']
|
||||||
|
|
||||||
|
for encoding in encodings:
|
||||||
|
try:
|
||||||
|
with open(csv_path, 'r', encoding=encoding) as f:
|
||||||
|
reader = csv.DictReader(f)
|
||||||
|
print(f"✓ Successfully opened with {encoding} encoding")
|
||||||
|
|
||||||
|
for row in reader:
|
||||||
|
try:
|
||||||
|
spell_id = int(row['Id'])
|
||||||
|
spell_name = row['Name'].strip()
|
||||||
|
spell_description = row.get('Description', '').strip()
|
||||||
|
spell_school = row.get('School', '').strip()
|
||||||
|
spell_family = row.get('Family', '').strip()
|
||||||
|
spell_difficulty = row.get('Difficulty', '').strip()
|
||||||
|
spell_duration = row.get('Duration', '').strip()
|
||||||
|
spell_mana = row.get('Mana', '').strip()
|
||||||
|
|
||||||
|
# Create comprehensive spell data
|
||||||
|
spell_data = {
|
||||||
|
'name': spell_name,
|
||||||
|
'description': spell_description,
|
||||||
|
'school': spell_school,
|
||||||
|
'family': spell_family,
|
||||||
|
'difficulty': spell_difficulty,
|
||||||
|
'duration': spell_duration,
|
||||||
|
'mana': spell_mana
|
||||||
|
}
|
||||||
|
|
||||||
|
spell_mappings[spell_id] = spell_data
|
||||||
|
|
||||||
|
except (ValueError, KeyError) as e:
|
||||||
|
print(f"⚠️ Skipping invalid row: {e}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
# If we get here successfully, we're done
|
||||||
|
break
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Error with {encoding} encoding: {e}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
if spell_mappings:
|
||||||
|
print(f"✓ Extracted {len(spell_mappings)} spell entries")
|
||||||
|
else:
|
||||||
|
print("❌ Failed to extract spells with any encoding")
|
||||||
|
|
||||||
|
return spell_mappings
|
||||||
|
|
||||||
|
def save_spell_database(spell_mappings):
|
||||||
|
"""Save spell mappings to JSON file."""
|
||||||
|
|
||||||
|
output_path = Path('/home/erik/MosswartOverlord/inventory-service/spell_database.json')
|
||||||
|
|
||||||
|
spell_database = {
|
||||||
|
'metadata': {
|
||||||
|
'version': '1.0.0',
|
||||||
|
'source': 'Mag-Plugins/Shared/Spells/Spells.csv',
|
||||||
|
'total_spells': len(spell_mappings),
|
||||||
|
'description': 'Spell ID to name/data mappings for Asheron\'s Call'
|
||||||
|
},
|
||||||
|
'spells': spell_mappings
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(output_path, 'w', encoding='utf-8') as f:
|
||||||
|
json.dump(spell_database, f, indent=2, ensure_ascii=False)
|
||||||
|
|
||||||
|
print(f"✓ Spell database saved to {output_path}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Error saving spell database: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Main extraction process."""
|
||||||
|
print("Extracting spell names from Spells.csv...")
|
||||||
|
|
||||||
|
# Extract spell mappings
|
||||||
|
spell_mappings = extract_spell_names()
|
||||||
|
|
||||||
|
if not spell_mappings:
|
||||||
|
print("❌ No spells extracted")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Save to JSON file
|
||||||
|
if save_spell_database(spell_mappings):
|
||||||
|
# Show some sample spells
|
||||||
|
print("\nSample spell entries:")
|
||||||
|
for spell_id, spell_data in list(spell_mappings.items())[:5]:
|
||||||
|
print(f" {spell_id}: {spell_data['name']} ({spell_data['school']})")
|
||||||
|
|
||||||
|
print(f"\n✓ Successfully processed {len(spell_mappings)} spells")
|
||||||
|
else:
|
||||||
|
print("❌ Failed to save spell database")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
37
inventory-service/init_db.py
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Initialize the inventory service database.
|
||||||
|
Creates all tables and performs initial setup.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from database import Base, DATABASE_URL, create_indexes
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
async def init_database():
|
||||||
|
"""Initialize database tables and indexes."""
|
||||||
|
try:
|
||||||
|
# Create engine
|
||||||
|
engine = sa.create_engine(DATABASE_URL)
|
||||||
|
|
||||||
|
# Create all tables
|
||||||
|
logger.info("Creating database tables...")
|
||||||
|
Base.metadata.create_all(engine)
|
||||||
|
|
||||||
|
# Create indexes
|
||||||
|
logger.info("Creating performance indexes...")
|
||||||
|
create_indexes(engine)
|
||||||
|
|
||||||
|
logger.info("Database initialization completed successfully")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Database initialization failed: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(init_database())
|
||||||
450
inventory-service/int_value_enums.json
Normal file
|
|
@ -0,0 +1,450 @@
|
||||||
|
{
|
||||||
|
"0": "Undef",
|
||||||
|
"1": "ItemType",
|
||||||
|
"2": "CreatureType",
|
||||||
|
"3": "PaletteTemplate",
|
||||||
|
"4": "ClothingPriority",
|
||||||
|
"5": "EncumbranceVal",
|
||||||
|
"6": "ItemsCapacity",
|
||||||
|
"7": "ContainersCapacity",
|
||||||
|
"8": "Mass",
|
||||||
|
"9": "ValidLocations",
|
||||||
|
"10": "CurrentWieldedLocation",
|
||||||
|
"11": "MaxStackSize",
|
||||||
|
"12": "StackSize",
|
||||||
|
"13": "StackUnitEncumbrance",
|
||||||
|
"14": "StackUnitMass",
|
||||||
|
"15": "StackUnitValue",
|
||||||
|
"16": "ItemUseable",
|
||||||
|
"17": "RareId",
|
||||||
|
"18": "UiEffects",
|
||||||
|
"19": "Value",
|
||||||
|
"20": "CoinValue",
|
||||||
|
"21": "TotalExperience",
|
||||||
|
"22": "AvailableCharacter",
|
||||||
|
"23": "TotalSkillCredits",
|
||||||
|
"24": "AvailableSkillCredits",
|
||||||
|
"25": "Level",
|
||||||
|
"26": "AccountRequirements",
|
||||||
|
"27": "ArmorType",
|
||||||
|
"28": "ArmorLevel",
|
||||||
|
"29": "AllegianceCpPool",
|
||||||
|
"30": "AllegianceRank",
|
||||||
|
"31": "ChannelsAllowed",
|
||||||
|
"32": "ChannelsActive",
|
||||||
|
"33": "Bonded",
|
||||||
|
"34": "MonarchsRank",
|
||||||
|
"35": "AllegianceFollowers",
|
||||||
|
"36": "ResistMagic",
|
||||||
|
"37": "ResistItemAppraisal",
|
||||||
|
"38": "ResistLockpick",
|
||||||
|
"39": "DeprecatedResistRepair",
|
||||||
|
"40": "CombatMode",
|
||||||
|
"41": "CurrentAttackHeight",
|
||||||
|
"42": "CombatCollisions",
|
||||||
|
"43": "NumDeaths",
|
||||||
|
"44": "Damage",
|
||||||
|
"45": "DamageType",
|
||||||
|
"46": "DefaultCombatStyle",
|
||||||
|
"47": "AttackType",
|
||||||
|
"48": "WeaponSkill",
|
||||||
|
"49": "WeaponTime",
|
||||||
|
"50": "AmmoType",
|
||||||
|
"51": "CombatUse",
|
||||||
|
"52": "ParentLocation",
|
||||||
|
"53": "PlacementPosition",
|
||||||
|
"54": "WeaponEncumbrance",
|
||||||
|
"55": "WeaponMass",
|
||||||
|
"56": "ShieldValue",
|
||||||
|
"57": "ShieldEncumbrance",
|
||||||
|
"58": "MissileInventoryLocation",
|
||||||
|
"59": "FullDamageType",
|
||||||
|
"60": "WeaponRange",
|
||||||
|
"61": "AttackersSkill",
|
||||||
|
"62": "DefendersSkill",
|
||||||
|
"63": "AttackersSkillValue",
|
||||||
|
"64": "AttackersClass",
|
||||||
|
"65": "Placement",
|
||||||
|
"66": "CheckpointStatus",
|
||||||
|
"67": "Tolerance",
|
||||||
|
"68": "TargetingTactic",
|
||||||
|
"69": "CombatTactic",
|
||||||
|
"70": "HomesickTargetingTactic",
|
||||||
|
"71": "NumFollowFailures",
|
||||||
|
"72": "FriendType",
|
||||||
|
"73": "FoeType",
|
||||||
|
"74": "MerchandiseItemTypes",
|
||||||
|
"75": "MerchandiseMinValue",
|
||||||
|
"76": "MerchandiseMaxValue",
|
||||||
|
"77": "NumItemsSold",
|
||||||
|
"78": "NumItemsBought",
|
||||||
|
"79": "MoneyIncome",
|
||||||
|
"80": "MoneyOutflow",
|
||||||
|
"81": "MaxGeneratedObjects",
|
||||||
|
"82": "InitGeneratedObjects",
|
||||||
|
"83": "ActivationResponse",
|
||||||
|
"84": "OriginalValue",
|
||||||
|
"85": "NumMoveFailures",
|
||||||
|
"86": "MinLevel",
|
||||||
|
"87": "MaxLevel",
|
||||||
|
"88": "LockpickMod",
|
||||||
|
"89": "BoosterEnum",
|
||||||
|
"90": "BoostValue",
|
||||||
|
"91": "MaxStructure",
|
||||||
|
"92": "Structure",
|
||||||
|
"93": "PhysicsState",
|
||||||
|
"94": "TargetType",
|
||||||
|
"95": "RadarBlipColor",
|
||||||
|
"96": "EncumbranceCapacity",
|
||||||
|
"97": "LoginTimestamp",
|
||||||
|
"98": "CreationTimestamp",
|
||||||
|
"99": "PkLevelModifier",
|
||||||
|
"100": "GeneratorType",
|
||||||
|
"101": "AiAllowedCombatStyle",
|
||||||
|
"102": "LogoffTimestamp",
|
||||||
|
"103": "GeneratorDestructionType",
|
||||||
|
"104": "ActivationCreateClass",
|
||||||
|
"105": "ItemWorkmanship",
|
||||||
|
"106": "ItemSpellcraft",
|
||||||
|
"107": "ItemCurMana",
|
||||||
|
"108": "ItemMaxMana",
|
||||||
|
"109": "ItemDifficulty",
|
||||||
|
"110": "ItemAllegianceRankLimit",
|
||||||
|
"111": "PortalBitmask",
|
||||||
|
"112": "AdvocateLevel",
|
||||||
|
"113": "Gender",
|
||||||
|
"114": "Attuned",
|
||||||
|
"115": "ItemSkillLevelLimit",
|
||||||
|
"116": "GateLogic",
|
||||||
|
"117": "ItemManaCost",
|
||||||
|
"118": "Logoff",
|
||||||
|
"119": "Active",
|
||||||
|
"120": "AttackHeight",
|
||||||
|
"121": "NumAttackFailures",
|
||||||
|
"122": "AiCpThreshold",
|
||||||
|
"123": "AiAdvancementStrategy",
|
||||||
|
"124": "Version",
|
||||||
|
"125": "Age",
|
||||||
|
"126": "VendorHappyMean",
|
||||||
|
"127": "VendorHappyVariance",
|
||||||
|
"128": "CloakStatus",
|
||||||
|
"129": "VitaeCpPool",
|
||||||
|
"130": "NumServicesSold",
|
||||||
|
"131": "MaterialType",
|
||||||
|
"132": "NumAllegianceBreaks",
|
||||||
|
"133": "ShowableOnRadar",
|
||||||
|
"134": "PlayerKillerStatus",
|
||||||
|
"135": "VendorHappyMaxItems",
|
||||||
|
"136": "ScorePageNum",
|
||||||
|
"137": "ScoreConfigNum",
|
||||||
|
"138": "ScoreNumScores",
|
||||||
|
"139": "DeathLevel",
|
||||||
|
"140": "AiOptions",
|
||||||
|
"141": "OpenToEveryone",
|
||||||
|
"142": "GeneratorTimeType",
|
||||||
|
"143": "GeneratorStartTime",
|
||||||
|
"144": "GeneratorEndTime",
|
||||||
|
"145": "GeneratorEndDestructionType",
|
||||||
|
"146": "XpOverride",
|
||||||
|
"147": "NumCrashAndTurns",
|
||||||
|
"148": "ComponentWarningThreshold",
|
||||||
|
"149": "HouseStatus",
|
||||||
|
"150": "HookPlacement",
|
||||||
|
"151": "HookType",
|
||||||
|
"152": "HookItemType",
|
||||||
|
"153": "AiPpThreshold",
|
||||||
|
"154": "GeneratorVersion",
|
||||||
|
"155": "HouseType",
|
||||||
|
"156": "PickupEmoteOffset",
|
||||||
|
"157": "WeenieIteration",
|
||||||
|
"158": "WieldRequirements",
|
||||||
|
"159": "WieldSkillType",
|
||||||
|
"160": "WieldDifficulty",
|
||||||
|
"161": "HouseMaxHooksUsable",
|
||||||
|
"162": "HouseCurrentHooksUsable",
|
||||||
|
"163": "AllegianceMinLevel",
|
||||||
|
"164": "AllegianceMaxLevel",
|
||||||
|
"165": "HouseRelinkHookCount",
|
||||||
|
"166": "SlayerCreatureType",
|
||||||
|
"167": "ConfirmationInProgress",
|
||||||
|
"168": "ConfirmationTypeInProgress",
|
||||||
|
"169": "TsysMutationData",
|
||||||
|
"170": "NumItemsInMaterial",
|
||||||
|
"171": "NumTimesTinkered",
|
||||||
|
"172": "AppraisalLongDescDecoration",
|
||||||
|
"173": "AppraisalLockpickSuccessPercent",
|
||||||
|
"174": "AppraisalPages",
|
||||||
|
"175": "AppraisalMaxPages",
|
||||||
|
"176": "AppraisalItemSkill",
|
||||||
|
"177": "GemCount",
|
||||||
|
"178": "GemType",
|
||||||
|
"179": "ImbuedEffect",
|
||||||
|
"180": "AttackersRawSkillValue",
|
||||||
|
"181": "ChessRank",
|
||||||
|
"182": "ChessTotalGames",
|
||||||
|
"183": "ChessGamesWon",
|
||||||
|
"184": "ChessGamesLost",
|
||||||
|
"185": "TypeOfAlteration",
|
||||||
|
"186": "SkillToBeAltered",
|
||||||
|
"187": "SkillAlterationCount",
|
||||||
|
"188": "HeritageGroup",
|
||||||
|
"189": "TransferFromAttribute",
|
||||||
|
"190": "TransferToAttribute",
|
||||||
|
"191": "AttributeTransferCount",
|
||||||
|
"192": "FakeFishingSkill",
|
||||||
|
"193": "NumKeys",
|
||||||
|
"194": "DeathTimestamp",
|
||||||
|
"195": "PkTimestamp",
|
||||||
|
"196": "VictimTimestamp",
|
||||||
|
"197": "HookGroup",
|
||||||
|
"198": "AllegianceSwearTimestamp",
|
||||||
|
"199": "HousePurchaseTimestamp",
|
||||||
|
"200": "RedirectableEquippedArmorCount",
|
||||||
|
"201": "MeleeDefenseImbuedEffectTypeCache",
|
||||||
|
"202": "MissileDefenseImbuedEffectTypeCache",
|
||||||
|
"203": "MagicDefenseImbuedEffectTypeCache",
|
||||||
|
"204": "ElementalDamageBonus",
|
||||||
|
"205": "ImbueAttempts",
|
||||||
|
"206": "ImbueSuccesses",
|
||||||
|
"207": "CreatureKills",
|
||||||
|
"208": "PlayerKillsPk",
|
||||||
|
"209": "PlayerKillsPkl",
|
||||||
|
"210": "RaresTierOne",
|
||||||
|
"211": "RaresTierTwo",
|
||||||
|
"212": "RaresTierThree",
|
||||||
|
"213": "RaresTierFour",
|
||||||
|
"214": "RaresTierFive",
|
||||||
|
"215": "AugmentationStat",
|
||||||
|
"216": "AugmentationFamilyStat",
|
||||||
|
"217": "AugmentationInnateFamily",
|
||||||
|
"218": "AugmentationInnateStrength",
|
||||||
|
"219": "AugmentationInnateEndurance",
|
||||||
|
"220": "AugmentationInnateCoordination",
|
||||||
|
"221": "AugmentationInnateQuickness",
|
||||||
|
"222": "AugmentationInnateFocus",
|
||||||
|
"223": "AugmentationInnateSelf",
|
||||||
|
"224": "AugmentationSpecializeSalvaging",
|
||||||
|
"225": "AugmentationSpecializeItemTinkering",
|
||||||
|
"226": "AugmentationSpecializeArmorTinkering",
|
||||||
|
"227": "AugmentationSpecializeMagicItemTinkering",
|
||||||
|
"228": "AugmentationSpecializeWeaponTinkering",
|
||||||
|
"229": "AugmentationExtraPackSlot",
|
||||||
|
"230": "AugmentationIncreasedCarryingCapacity",
|
||||||
|
"231": "AugmentationLessDeathItemLoss",
|
||||||
|
"232": "AugmentationSpellsRemainPastDeath",
|
||||||
|
"233": "AugmentationCriticalDefense",
|
||||||
|
"234": "AugmentationBonusXp",
|
||||||
|
"235": "AugmentationBonusSalvage",
|
||||||
|
"236": "AugmentationBonusImbueChance",
|
||||||
|
"237": "AugmentationFasterRegen",
|
||||||
|
"238": "AugmentationIncreasedSpellDuration",
|
||||||
|
"239": "AugmentationResistanceFamily",
|
||||||
|
"240": "AugmentationResistanceSlash",
|
||||||
|
"241": "AugmentationResistancePierce",
|
||||||
|
"242": "AugmentationResistanceBlunt",
|
||||||
|
"243": "AugmentationResistanceAcid",
|
||||||
|
"244": "AugmentationResistanceFire",
|
||||||
|
"245": "AugmentationResistanceFrost",
|
||||||
|
"246": "AugmentationResistanceLightning",
|
||||||
|
"247": "RaresTierOneLogin",
|
||||||
|
"248": "RaresTierTwoLogin",
|
||||||
|
"249": "RaresTierThreeLogin",
|
||||||
|
"250": "RaresTierFourLogin",
|
||||||
|
"251": "RaresTierFiveLogin",
|
||||||
|
"252": "RaresLoginTimestamp",
|
||||||
|
"253": "RaresTierSix",
|
||||||
|
"254": "RaresTierSeven",
|
||||||
|
"255": "RaresTierSixLogin",
|
||||||
|
"256": "RaresTierSevenLogin",
|
||||||
|
"257": "ItemAttributeLimit",
|
||||||
|
"258": "ItemAttributeLevelLimit",
|
||||||
|
"259": "ItemAttribute2ndLimit",
|
||||||
|
"260": "ItemAttribute2ndLevelLimit",
|
||||||
|
"261": "CharacterTitleId",
|
||||||
|
"262": "NumCharacterTitles",
|
||||||
|
"263": "ResistanceModifierType",
|
||||||
|
"264": "FreeTinkersBitfield",
|
||||||
|
"265": "EquipmentSetId",
|
||||||
|
"266": "PetClass",
|
||||||
|
"267": "Lifespan",
|
||||||
|
"268": "RemainingLifespan",
|
||||||
|
"269": "UseCreateQuantity",
|
||||||
|
"270": "WieldRequirements2",
|
||||||
|
"271": "WieldSkillType2",
|
||||||
|
"272": "WieldDifficulty2",
|
||||||
|
"273": "WieldRequirements3",
|
||||||
|
"274": "WieldSkillType3",
|
||||||
|
"275": "WieldDifficulty3",
|
||||||
|
"276": "WieldRequirements4",
|
||||||
|
"277": "WieldSkillType4",
|
||||||
|
"278": "WieldDifficulty4",
|
||||||
|
"279": "Unique",
|
||||||
|
"280": "SharedCooldown",
|
||||||
|
"281": "Faction1Bits",
|
||||||
|
"282": "Faction2Bits",
|
||||||
|
"283": "Faction3Bits",
|
||||||
|
"284": "Hatred1Bits",
|
||||||
|
"285": "Hatred2Bits",
|
||||||
|
"286": "Hatred3Bits",
|
||||||
|
"287": "SocietyRankCelhan",
|
||||||
|
"288": "SocietyRankEldweb",
|
||||||
|
"289": "SocietyRankRadblo",
|
||||||
|
"290": "HearLocalSignals",
|
||||||
|
"291": "HearLocalSignalsRadius",
|
||||||
|
"292": "Cleaving",
|
||||||
|
"293": "AugmentationSpecializeGearcraft",
|
||||||
|
"294": "AugmentationInfusedCreatureMagic",
|
||||||
|
"295": "AugmentationInfusedItemMagic",
|
||||||
|
"296": "AugmentationInfusedLifeMagic",
|
||||||
|
"297": "AugmentationInfusedWarMagic",
|
||||||
|
"298": "AugmentationCriticalExpertise",
|
||||||
|
"299": "AugmentationCriticalPower",
|
||||||
|
"300": "AugmentationSkilledMelee",
|
||||||
|
"301": "AugmentationSkilledMissile",
|
||||||
|
"302": "AugmentationSkilledMagic",
|
||||||
|
"303": "ImbuedEffect2",
|
||||||
|
"304": "ImbuedEffect3",
|
||||||
|
"305": "ImbuedEffect4",
|
||||||
|
"306": "ImbuedEffect5",
|
||||||
|
"307": "DamageRating",
|
||||||
|
"308": "DamageResistRating",
|
||||||
|
"309": "AugmentationDamageBonus",
|
||||||
|
"310": "AugmentationDamageReduction",
|
||||||
|
"311": "ImbueStackingBits",
|
||||||
|
"312": "HealOverTime",
|
||||||
|
"313": "CritRating",
|
||||||
|
"314": "CritDamageRating",
|
||||||
|
"315": "CritResistRating",
|
||||||
|
"316": "CritDamageResistRating",
|
||||||
|
"317": "HealingResistRating",
|
||||||
|
"318": "DamageOverTime",
|
||||||
|
"319": "ItemMaxLevel",
|
||||||
|
"320": "ItemXpStyle",
|
||||||
|
"321": "EquipmentSetExtra",
|
||||||
|
"322": "AetheriaBitfield",
|
||||||
|
"323": "HealingBoostRating",
|
||||||
|
"324": "HeritageSpecificArmor",
|
||||||
|
"325": "AlternateRacialSkills",
|
||||||
|
"326": "AugmentationJackOfAllTrades",
|
||||||
|
"327": "AugmentationResistanceNether",
|
||||||
|
"328": "AugmentationInfusedVoidMagic",
|
||||||
|
"329": "WeaknessRating",
|
||||||
|
"330": "NetherOverTime",
|
||||||
|
"331": "NetherResistRating",
|
||||||
|
"332": "LuminanceAward",
|
||||||
|
"333": "LumAugDamageRating",
|
||||||
|
"334": "LumAugDamageReductionRating",
|
||||||
|
"335": "LumAugCritDamageRating",
|
||||||
|
"336": "LumAugCritReductionRating",
|
||||||
|
"337": "LumAugSurgeEffectRating",
|
||||||
|
"338": "LumAugSurgeChanceRating",
|
||||||
|
"339": "LumAugItemManaUsage",
|
||||||
|
"340": "LumAugItemManaGain",
|
||||||
|
"341": "LumAugVitality",
|
||||||
|
"342": "LumAugHealingRating",
|
||||||
|
"343": "LumAugSkilledCraft",
|
||||||
|
"344": "LumAugSkilledSpec",
|
||||||
|
"345": "LumAugNoDestroyCraft",
|
||||||
|
"346": "RestrictInteraction",
|
||||||
|
"347": "OlthoiLootTimestamp",
|
||||||
|
"348": "OlthoiLootStep",
|
||||||
|
"349": "UseCreatesContractId",
|
||||||
|
"350": "DotResistRating",
|
||||||
|
"351": "LifeResistRating",
|
||||||
|
"352": "CloakWeaveProc",
|
||||||
|
"353": "WeaponType",
|
||||||
|
"354": "MeleeMastery",
|
||||||
|
"355": "RangedMastery",
|
||||||
|
"356": "SneakAttackRating",
|
||||||
|
"357": "RecklessnessRating",
|
||||||
|
"358": "DeceptionRating",
|
||||||
|
"359": "CombatPetRange",
|
||||||
|
"360": "WeaponAuraDamage",
|
||||||
|
"361": "WeaponAuraSpeed",
|
||||||
|
"362": "SummoningMastery",
|
||||||
|
"363": "HeartbeatLifespan",
|
||||||
|
"364": "UseLevelRequirement",
|
||||||
|
"365": "LumAugAllSkills",
|
||||||
|
"366": "UseRequiresSkill",
|
||||||
|
"367": "UseRequiresSkillLevel",
|
||||||
|
"368": "UseRequiresSkillSpec",
|
||||||
|
"369": "UseRequiresLevel",
|
||||||
|
"370": "GearDamage",
|
||||||
|
"371": "GearDamageResist",
|
||||||
|
"372": "GearCrit",
|
||||||
|
"373": "GearCritResist",
|
||||||
|
"374": "GearCritDamage",
|
||||||
|
"375": "GearCritDamageResist",
|
||||||
|
"376": "GearHealingBoost",
|
||||||
|
"377": "GearNetherResist",
|
||||||
|
"378": "GearLifeResist",
|
||||||
|
"379": "GearMaxHealth",
|
||||||
|
"380": "Unknown380",
|
||||||
|
"381": "PKDamageRating",
|
||||||
|
"382": "PKDamageResistRating",
|
||||||
|
"383": "GearPKDamageRating",
|
||||||
|
"384": "GearPKDamageResistRating",
|
||||||
|
"385": "Unknown385",
|
||||||
|
"386": "Overpower",
|
||||||
|
"387": "OverpowerResist",
|
||||||
|
"388": "GearOverpower",
|
||||||
|
"389": "GearOverpowerResist",
|
||||||
|
"390": "Enlightenment",
|
||||||
|
"8007": "PCAPRecordedAutonomousMovement",
|
||||||
|
"8030": "PCAPRecordedMaxVelocityEstimated",
|
||||||
|
"8041": "PCAPRecordedPlacement",
|
||||||
|
"8042": "PCAPRecordedAppraisalPages",
|
||||||
|
"8043": "PCAPRecordedAppraisalMaxPages",
|
||||||
|
"9008": "CurrentLoyaltyAtLastLogoff",
|
||||||
|
"9009": "CurrentLeadershipAtLastLogoff",
|
||||||
|
"9010": "AllegianceOfficerRank",
|
||||||
|
"9011": "HouseRentTimestamp",
|
||||||
|
"9012": "Hairstyle",
|
||||||
|
"9013": "VisualClothingPriority",
|
||||||
|
"9014": "SquelchGlobal",
|
||||||
|
"9015": "InventoryOrder",
|
||||||
|
"218103808": "WeenieClassId_Decal",
|
||||||
|
"218103809": "Icon_Decal_DID",
|
||||||
|
"218103810": "Container_Decal_IID",
|
||||||
|
"218103811": "Landblock_Decal",
|
||||||
|
"218103812": "ItemSlots_Decal",
|
||||||
|
"218103813": "PackSlots_Decal",
|
||||||
|
"218103814": "StackCount_Decal",
|
||||||
|
"218103815": "StackMax_Decal",
|
||||||
|
"218103816": "Spell_Decal_DID",
|
||||||
|
"218103817": "SlotLegacy_Decal",
|
||||||
|
"218103818": "Wielder_Decal_IID",
|
||||||
|
"218103819": "WieldingSlot_Decal",
|
||||||
|
"218103820": "Monarch_Decal_IID",
|
||||||
|
"218103821": "Coverage_Decal",
|
||||||
|
"218103822": "EquipableSlots_Decal",
|
||||||
|
"218103823": "EquipType_Decal",
|
||||||
|
"218103824": "IconOutline_Decal",
|
||||||
|
"218103825": "MissileType_Decal",
|
||||||
|
"218103826": "UsageMask_Decal",
|
||||||
|
"218103827": "HouseOwner_Decal_IID",
|
||||||
|
"218103828": "HookMask_Decal",
|
||||||
|
"218103829": "HookType_Decal",
|
||||||
|
"218103830": "Setup_Decal_DID",
|
||||||
|
"218103831": "ObjectDescriptionFlags_Decal",
|
||||||
|
"218103832": "CreateFlags1_Decal",
|
||||||
|
"218103833": "CreateFlags2_Decal",
|
||||||
|
"218103834": "Category_Decal",
|
||||||
|
"218103835": "Behavior_Decal",
|
||||||
|
"218103836": "MagicDef_Decal",
|
||||||
|
"218103837": "SpecialProps_Decal",
|
||||||
|
"218103838": "SpellCount_Decal",
|
||||||
|
"218103839": "WeapSpeed_Decal",
|
||||||
|
"218103840": "EquipSkill_Decal",
|
||||||
|
"218103841": "DamageType_Decal",
|
||||||
|
"218103842": "MaxDamage_Decal",
|
||||||
|
"218103843": "Unknown10_Decal",
|
||||||
|
"218103844": "Unknown100000_Decal",
|
||||||
|
"218103845": "Unknown800000_Decal",
|
||||||
|
"218103846": "Unknown8000000_Decal",
|
||||||
|
"218103847": "PhysicsDataFlags_Decal",
|
||||||
|
"218103848": "ActiveSpellCount_Decal",
|
||||||
|
"218103849": "IconOverlay_Decal_DID",
|
||||||
|
"218103850": "IconUnderlay_Decal_DID",
|
||||||
|
"231735296": "Slot_Decal"
|
||||||
|
}
|
||||||
1112
inventory-service/main.py
Normal file
30
inventory-service/property_categories.json
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"basic": {
|
||||||
|
"5": "encumbrance",
|
||||||
|
"19": "value",
|
||||||
|
"25": "level",
|
||||||
|
"28": "armor_level",
|
||||||
|
"44": "damage",
|
||||||
|
"45": "damage_type"
|
||||||
|
},
|
||||||
|
"requirements": {
|
||||||
|
"158": "wield_requirement",
|
||||||
|
"160": "wield_level",
|
||||||
|
"48": "weapon_skill"
|
||||||
|
},
|
||||||
|
"combat": {
|
||||||
|
"218103842": "max_damage",
|
||||||
|
"36": "resist_magic",
|
||||||
|
"56": "shield_value"
|
||||||
|
},
|
||||||
|
"display": {
|
||||||
|
"218103809": "icon",
|
||||||
|
"218103849": "icon_overlay",
|
||||||
|
"218103850": "icon_underlay"
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"218103808": "weenie_class_id",
|
||||||
|
"218103847": "physics_data_flags",
|
||||||
|
"218103831": "object_desc_flags"
|
||||||
|
}
|
||||||
|
}
|
||||||
9
inventory-service/requirements.txt
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
fastapi==0.104.1
|
||||||
|
uvicorn[standard]==0.24.0
|
||||||
|
sqlalchemy==1.4.53
|
||||||
|
asyncpg==0.29.0
|
||||||
|
databases[postgresql]==0.8.0
|
||||||
|
pydantic==2.5.0
|
||||||
|
python-multipart==0.0.6
|
||||||
|
python-json-logger==2.0.7
|
||||||
|
psycopg2-binary==2.9.9
|
||||||
56404
inventory-service/spell_database.json
Normal file
149
main.py
|
|
@ -20,6 +20,7 @@ from fastapi.staticfiles import StaticFiles
|
||||||
from fastapi.encoders import jsonable_encoder
|
from fastapi.encoders import jsonable_encoder
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
import httpx
|
||||||
|
|
||||||
# Async database support
|
# Async database support
|
||||||
from sqlalchemy.dialects.postgresql import insert as pg_insert
|
from sqlalchemy.dialects.postgresql import insert as pg_insert
|
||||||
|
|
@ -49,6 +50,9 @@ logger = logging.getLogger(__name__)
|
||||||
# Get log level from environment (DEBUG, INFO, WARNING, ERROR)
|
# Get log level from environment (DEBUG, INFO, WARNING, ERROR)
|
||||||
log_level = os.getenv('LOG_LEVEL', 'INFO').upper()
|
log_level = os.getenv('LOG_LEVEL', 'INFO').upper()
|
||||||
logger.setLevel(getattr(logging, log_level, logging.INFO))
|
logger.setLevel(getattr(logging, log_level, logging.INFO))
|
||||||
|
|
||||||
|
# Inventory service configuration
|
||||||
|
INVENTORY_SERVICE_URL = os.getenv('INVENTORY_SERVICE_URL', 'http://inventory-service:8000')
|
||||||
# In-memory caches for REST endpoints
|
# In-memory caches for REST endpoints
|
||||||
_cached_live: dict = {"players": []}
|
_cached_live: dict = {"players": []}
|
||||||
_cached_trails: dict = {"trails": []}
|
_cached_trails: dict = {"trails": []}
|
||||||
|
|
@ -293,29 +297,24 @@ async def get_trails(
|
||||||
# --- GET Inventory Endpoints ---------------------------------
|
# --- GET Inventory Endpoints ---------------------------------
|
||||||
@app.get("/inventory/{character_name}")
|
@app.get("/inventory/{character_name}")
|
||||||
async def get_character_inventory(character_name: str):
|
async def get_character_inventory(character_name: str):
|
||||||
"""Get the complete inventory for a specific character from the database."""
|
"""Get the complete inventory for a specific character - inventory service only."""
|
||||||
try:
|
try:
|
||||||
query = """
|
async with httpx.AsyncClient(timeout=10.0) as client:
|
||||||
SELECT name, icon, object_class, value, burden, has_id_data, item_data, timestamp
|
response = await client.get(
|
||||||
FROM character_inventories
|
f"{INVENTORY_SERVICE_URL}/inventory/{character_name}"
|
||||||
WHERE character_name = :character_name
|
)
|
||||||
ORDER BY name
|
|
||||||
"""
|
if response.status_code == 200:
|
||||||
rows = await database.fetch_all(query, {"character_name": character_name})
|
return JSONResponse(content=response.json())
|
||||||
|
elif response.status_code == 404:
|
||||||
if not rows:
|
raise HTTPException(status_code=404, detail=f"No inventory found for character '{character_name}'")
|
||||||
raise HTTPException(status_code=404, detail=f"No inventory found for character '{character_name}'")
|
else:
|
||||||
|
logger.error(f"Inventory service returned {response.status_code} for {character_name}")
|
||||||
items = []
|
raise HTTPException(status_code=502, detail="Inventory service error")
|
||||||
for row in rows:
|
|
||||||
item = dict(row)
|
except httpx.RequestError as e:
|
||||||
items.append(item)
|
logger.error(f"Could not reach inventory service: {e}")
|
||||||
|
raise HTTPException(status_code=503, detail="Inventory service unavailable")
|
||||||
return JSONResponse(content=jsonable_encoder({
|
|
||||||
"character_name": character_name,
|
|
||||||
"item_count": len(items),
|
|
||||||
"items": items
|
|
||||||
}))
|
|
||||||
except HTTPException:
|
except HTTPException:
|
||||||
raise
|
raise
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
@ -458,18 +457,42 @@ async def _broadcast_to_browser_clients(snapshot: dict):
|
||||||
browser_conns.discard(ws)
|
browser_conns.discard(ws)
|
||||||
|
|
||||||
|
|
||||||
async def _store_inventory(inventory_msg: FullInventoryMessage):
|
async def _forward_to_inventory_service(inventory_msg: FullInventoryMessage):
|
||||||
"""Store complete character inventory to database with extracted searchable fields.
|
"""Forward inventory data to the inventory microservice for processing."""
|
||||||
|
|
||||||
Processes each item to extract key fields for indexing while preserving
|
|
||||||
complete item data in JSONB format. Uses UPSERT to handle item updates.
|
|
||||||
"""
|
|
||||||
try:
|
try:
|
||||||
# Create inventory directory if it doesn't exist
|
# Prepare data for inventory service
|
||||||
|
inventory_data = {
|
||||||
|
"character_name": inventory_msg.character_name,
|
||||||
|
"timestamp": inventory_msg.timestamp.isoformat(),
|
||||||
|
"items": inventory_msg.items
|
||||||
|
}
|
||||||
|
|
||||||
|
async with httpx.AsyncClient(timeout=30.0) as client:
|
||||||
|
response = await client.post(
|
||||||
|
f"{INVENTORY_SERVICE_URL}/process-inventory",
|
||||||
|
json=inventory_data
|
||||||
|
)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
result = response.json()
|
||||||
|
logger.info(f"Inventory service processed {result['processed']} items for {inventory_msg.character_name}")
|
||||||
|
else:
|
||||||
|
logger.error(f"Inventory service error {response.status_code}: {response.text}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Failed to forward inventory to service: {e}")
|
||||||
|
# Don't raise - this shouldn't block the main storage
|
||||||
|
|
||||||
|
async def _store_inventory(inventory_msg: FullInventoryMessage):
|
||||||
|
"""Forward inventory data to inventory microservice for processing and storage."""
|
||||||
|
try:
|
||||||
|
# Forward to inventory microservice for enhanced processing and storage
|
||||||
|
await _forward_to_inventory_service(inventory_msg)
|
||||||
|
|
||||||
|
# Optional: Create JSON file for debugging (can be removed in production)
|
||||||
inventory_dir = Path("./inventory")
|
inventory_dir = Path("./inventory")
|
||||||
inventory_dir.mkdir(exist_ok=True)
|
inventory_dir.mkdir(exist_ok=True)
|
||||||
|
|
||||||
# Store as JSON file for backwards compatibility / debugging
|
|
||||||
file_path = inventory_dir / f"{inventory_msg.character_name}_inventory.json"
|
file_path = inventory_dir / f"{inventory_msg.character_name}_inventory.json"
|
||||||
inventory_data = {
|
inventory_data = {
|
||||||
"character_name": inventory_msg.character_name,
|
"character_name": inventory_msg.character_name,
|
||||||
|
|
@ -480,51 +503,9 @@ async def _store_inventory(inventory_msg: FullInventoryMessage):
|
||||||
|
|
||||||
with open(file_path, 'w') as f:
|
with open(file_path, 'w') as f:
|
||||||
json.dump(inventory_data, f, indent=2)
|
json.dump(inventory_data, f, indent=2)
|
||||||
|
|
||||||
# Store items in database
|
|
||||||
for item in inventory_msg.items:
|
|
||||||
# Extract searchable fields
|
|
||||||
item_id = item.get("Id")
|
|
||||||
if item_id is None:
|
|
||||||
continue # Skip items without ID
|
|
||||||
|
|
||||||
name = item.get("Name", "")
|
|
||||||
icon = item.get("Icon", 0)
|
|
||||||
object_class = item.get("ObjectClass", 0)
|
|
||||||
value = item.get("Value", 0)
|
|
||||||
burden = item.get("Burden", 0)
|
|
||||||
has_id_data = item.get("HasIdData", False)
|
|
||||||
|
|
||||||
# UPSERT item into database
|
|
||||||
stmt = pg_insert(character_inventories).values(
|
|
||||||
character_name=inventory_msg.character_name,
|
|
||||||
item_id=item_id,
|
|
||||||
timestamp=inventory_msg.timestamp,
|
|
||||||
name=name,
|
|
||||||
icon=icon,
|
|
||||||
object_class=object_class,
|
|
||||||
value=value,
|
|
||||||
burden=burden,
|
|
||||||
has_id_data=has_id_data,
|
|
||||||
item_data=item
|
|
||||||
).on_conflict_do_update(
|
|
||||||
constraint="uq_char_item",
|
|
||||||
set_={
|
|
||||||
"timestamp": inventory_msg.timestamp,
|
|
||||||
"name": name,
|
|
||||||
"icon": icon,
|
|
||||||
"object_class": object_class,
|
|
||||||
"value": value,
|
|
||||||
"burden": burden,
|
|
||||||
"has_id_data": has_id_data,
|
|
||||||
"item_data": item
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
await database.execute(stmt)
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to store inventory for {inventory_msg.character_name}: {e}", exc_info=True)
|
logger.error(f"Failed to forward inventory for {inventory_msg.character_name}: {e}", exc_info=True)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -636,13 +617,13 @@ async def ws_receive_snapshots(
|
||||||
logger.debug(f"Updated kills for {snap.character_name}: +{delta} (total from {last} to {snap.kills})")
|
logger.debug(f"Updated kills for {snap.character_name}: +{delta} (total from {last} to {snap.kills})")
|
||||||
ws_receive_snapshots._last_kills[key] = snap.kills
|
ws_receive_snapshots._last_kills[key] = snap.kills
|
||||||
except Exception as db_error:
|
except Exception as db_error:
|
||||||
logger.error(f"Database transaction failed for {snap.character_name}: {db_error}", exc_info=True)
|
logger.error(f"💾 Database transaction failed for {snap.character_name} (session: {snap.session_id[:8]}): {db_error}", exc_info=True)
|
||||||
continue
|
continue
|
||||||
# Broadcast updated snapshot to all browser clients
|
# Broadcast updated snapshot to all browser clients
|
||||||
await _broadcast_to_browser_clients(snap.dict())
|
await _broadcast_to_browser_clients(snap.dict())
|
||||||
logger.debug(f"Processed telemetry from {snap.character_name}")
|
logger.debug(f"✅ Processed telemetry from {snap.character_name} (session: {snap.session_id[:8]}, kills: {snap.kills})")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to process telemetry event: {e}", exc_info=True)
|
logger.error(f"❌ Failed to process telemetry event from {data.get('character_name', 'unknown')}: {e}", exc_info=True)
|
||||||
continue
|
continue
|
||||||
# --- Rare event: update total and session counters and persist ---
|
# --- Rare event: update total and session counters and persist ---
|
||||||
if msg_type == "rare":
|
if msg_type == "rare":
|
||||||
|
|
@ -892,6 +873,22 @@ async def get_stats(character_name: str):
|
||||||
raise HTTPException(status_code=500, detail="Internal server error")
|
raise HTTPException(status_code=500, detail="Internal server error")
|
||||||
|
|
||||||
# -------------------- static frontend ---------------------------
|
# -------------------- static frontend ---------------------------
|
||||||
|
# Custom icon handler that prioritizes clean icons over originals
|
||||||
|
from fastapi.responses import FileResponse
|
||||||
|
|
||||||
|
@app.get("/icons/{icon_filename}")
|
||||||
|
async def serve_icon(icon_filename: str):
|
||||||
|
"""Serve icons from static/icons directory"""
|
||||||
|
|
||||||
|
# Serve from static/icons directory
|
||||||
|
icon_path = Path("static/icons") / icon_filename
|
||||||
|
if icon_path.exists():
|
||||||
|
return FileResponse(icon_path, media_type="image/png")
|
||||||
|
|
||||||
|
# Icon not found
|
||||||
|
raise HTTPException(status_code=404, detail="Icon not found")
|
||||||
|
|
||||||
|
# Icons are now served from static/icons directory
|
||||||
# Serve SPA files (catch-all for frontend routes)
|
# Serve SPA files (catch-all for frontend routes)
|
||||||
# Mount the single-page application frontend (static assets) at root path
|
# Mount the single-page application frontend (static assets) at root path
|
||||||
app.mount("/", StaticFiles(directory="static", html=True), name="static")
|
app.mount("/", StaticFiles(directory="static", html=True), name="static")
|
||||||
|
|
|
||||||
BIN
static/icons/06000133.png
Executable file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
static/icons/0600015D.png
Executable file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
static/icons/0600015F.png
Executable file
|
After Width: | Height: | Size: 996 B |
BIN
static/icons/06000160.png
Executable file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
static/icons/06000162.png
Executable file
|
After Width: | Height: | Size: 914 B |
BIN
static/icons/06000163.png
Executable file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
static/icons/06000164.png
Executable file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
static/icons/06000165.png
Executable file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
static/icons/06000167.png
Executable file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
static/icons/0600016A.png
Executable file
|
After Width: | Height: | Size: 1 KiB |
BIN
static/icons/0600016B.png
Executable file
|
After Width: | Height: | Size: 1 KiB |
BIN
static/icons/0600016D.png
Executable file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
static/icons/0600016E.png
Executable file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
static/icons/0600016F.png
Executable file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
static/icons/06000170.png
Executable file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
static/icons/06000173.png
Executable file
|
After Width: | Height: | Size: 1 KiB |
BIN
static/icons/06000178.png
Executable file
|
After Width: | Height: | Size: 992 B |
BIN
static/icons/0600017B.png
Executable file
|
After Width: | Height: | Size: 993 B |
BIN
static/icons/0600017C.png
Executable file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
static/icons/06000261.png
Executable file
|
After Width: | Height: | Size: 404 KiB |
BIN
static/icons/060002C4.png
Executable file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
static/icons/060002C5.png
Executable file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
static/icons/060002C6.png
Executable file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
static/icons/060002C7.png
Executable file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
static/icons/060002C8.png
Executable file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
static/icons/060002C9.png
Executable file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
static/icons/060004C6.png
Executable file
|
After Width: | Height: | Size: 8.9 KiB |
BIN
static/icons/060004C8.png
Executable file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
static/icons/060004CA.png
Executable file
|
After Width: | Height: | Size: 9.6 KiB |
BIN
static/icons/060004DA.png
Executable file
|
After Width: | Height: | Size: 9.7 KiB |
BIN
static/icons/060004DB.png
Executable file
|
After Width: | Height: | Size: 7.3 KiB |
BIN
static/icons/06000F50.png
Executable file
|
After Width: | Height: | Size: 5.3 KiB |
BIN
static/icons/06000F52.png
Executable file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
static/icons/06000F53.png
Executable file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
static/icons/06000F54.png
Executable file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
static/icons/06000F5A.png
Executable file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
static/icons/06000F5D.png
Executable file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
static/icons/06000F5E.png
Executable file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
static/icons/06000F66.png
Executable file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
static/icons/06000F68.png
Executable file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
static/icons/06000F6A.png
Executable file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
static/icons/06000F6B.png
Executable file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
static/icons/06000F6C.png
Executable file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
static/icons/06000F6E.png
Executable file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
static/icons/06000F86.png
Executable file
|
After Width: | Height: | Size: 14 KiB |
BIN
static/icons/06000F89.png
Executable file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
static/icons/06000F8A.png
Executable file
|
After Width: | Height: | Size: 343 B |
BIN
static/icons/06000F90.png
Executable file
|
After Width: | Height: | Size: 14 KiB |
BIN
static/icons/06000F93.png
Executable file
|
After Width: | Height: | Size: 6 KiB |
BIN
static/icons/06000F98.png
Executable file
|
After Width: | Height: | Size: 14 KiB |
BIN
static/icons/06000FAA.png
Executable file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
static/icons/06000FAC.png
Executable file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
static/icons/06000FAD.png
Executable file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
static/icons/06000FAE.png
Executable file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
static/icons/06000FB1.png
Executable file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
static/icons/06000FB5.png
Executable file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
static/icons/06000FB7.png
Executable file
|
After Width: | Height: | Size: 2 KiB |
BIN
static/icons/06000FB8.png
Executable file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
static/icons/06000FBB.png
Executable file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
static/icons/06000FBC.png
Executable file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
static/icons/06000FBD.png
Executable file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
static/icons/06000FBE.png
Executable file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
static/icons/06000FC2.png
Executable file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
static/icons/06000FC3.png
Executable file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
static/icons/06000FC4.png
Executable file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
static/icons/06000FC6.png
Executable file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
static/icons/06000FC7.png
Executable file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
static/icons/06000FCA.png
Executable file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
static/icons/06000FCB.png
Executable file
|
After Width: | Height: | Size: 2 KiB |
BIN
static/icons/06000FCC.png
Executable file
|
After Width: | Height: | Size: 2.2 KiB |