diff --git a/app/cdclient.py b/app/cdclient.py index 13bfea8..317c1cb 100644 --- a/app/cdclient.py +++ b/app/cdclient.py @@ -1,6 +1,7 @@ from app import db from sqlalchemy.dialects import sqlite from sqlalchemy_utils import generic_relationship +import enum class AICombatRoles(db.Model): @@ -1410,6 +1411,55 @@ class ComponentsRegistry(db.Model): component = generic_relationship(component_type, component_id) +# From DLU source +class ComponentType(enum.IntEnum): + COMPONENT_TYPE_CONTROLLABLE_PHYSICS = 1 # The ControllablePhysics Component + COMPONENT_TYPE_RENDER = 2 # The Render Component + COMPONENT_TYPE_SIMPLE_PHYSICS = 3 # The SimplePhysics Component + COMPONENT_TYPE_CHARACTER = 4 # The Character Component + COMPONENT_TYPE_SCRIPT = 5 # The Script Component + COMPONENT_TYPE_BOUNCER = 6 # The Bouncer Component + COMPONENT_TYPE_BUFF = 7 # The Buff Component + COMPONENT_TYPE_SKILL = 9 # The Skill Component + COMPONENT_TYPE_ITEM = 11 # The Item Component + COMPONENT_TYPE_VENDOR = 16 # The Vendor Component + COMPONENT_TYPE_INVENTORY = 17 # The Inventory Component + COMPONENT_TYPE_SHOOTING_GALLERY = 19 # The Shooting Gallery Component + COMPONENT_TYPE_RIGID_BODY_PHANTOM_PHYSICS = 20 # The RigidBodyPhantomPhysics Component + COMPONENT_TYPE_COLLECTIBLE = 23 # The Collectible Component + COMPONENT_TYPE_MOVING_PLATFORM = 25 # The MovingPlatform Component + COMPONENT_TYPE_PET = 26 # The Pet Component + COMPONENT_TYPE_VEHICLE_PHYSICS = 30 # The VehiclePhysics Component + COMPONENT_TYPE_MOVEMENT_AI = 31 # The MovementAI Component + COMPONENT_TYPE_PROPERTY = 36 # The Property Component + COMPONENT_TYPE_SCRIPTED_ACTIVITY = 39 # The ScriptedActivity Component + COMPONENT_TYPE_PHANTOM_PHYSICS = 40 # The PhantomPhysics Component + COMPONENT_TYPE_PROPERTY_ENTRANCE = 43 # The PhantomPhysics Component + COMPONENT_TYPE_PROPERTY_MANAGEMENT = 45 # The PropertyManagement Component + COMPONENT_TYPE_REBUILD = 48 # The Rebuild Component + COMPONENT_TYPE_SWITCH = 49 # The Switch Component + COMPONENT_TYPE_ZONE_CONTROL = 50 # The ZoneControl Component + COMPONENT_TYPE_PACKAGE = 53 # The Package Component + COMPONENT_TYPE_PLAYER_FLAG = 58 # The PlayerFlag Component + COMPONENT_TYPE_BASE_COMBAT_AI = 60 # The BaseCombatAI Component + COMPONENT_TYPE_MODULE_ASSEMBLY = 61 # The ModuleAssembly Component + COMPONENT_TYPE_PROPERTY_VENDOR = 65 # The PropertyVendor Component + COMPONENT_TYPE_ROCKET_LAUNCH = 67 # The RocketLaunch Component + COMPONENT_TYPE_RACING_CONTROL = 71 # The RacingControl Component + COMPONENT_TYPE_MISSION_OFFER = 73 # The MissionOffer Component + COMPONENT_TYPE_EXHIBIT = 75 # The Exhibit Component + COMPONENT_TYPE_RACING_STATS = 74 # The Exhibit Component + COMPONENT_TYPE_SOUND_TRIGGER = 77 # The Sound Trigger Component + COMPONENT_TYPE_PROXIMITY_MONITOR = 78 # The Proximity Monitor Component + COMPONENT_TYPE_MISSION = 84 # The Mission Component + COMPONENT_TYPE_ROCKET_LAUNCH_LUP = 97 # The LUP Launchpad Componen + COMPONENT_TYPE_RAIL_ACTIVATOR = 104 + COMPONENT_TYPE_POSSESSOR = 107 # The Component 107 + COMPONENT_TYPE_POSSESSABLE = 108 # The Component 108 + COMPONENT_TYPE_BUILD_BORDER = 114 # The Build Border Component + COMPONENT_TYPE_DESTROYABLE = 1000 # The Destroyable Component + + class ControlSchemes(db.Model): __tablename__ = 'ControlSchemes' __bind_key__ = 'cdclient' diff --git a/app/luclient.py b/app/luclient.py index eb4da3a..175133f 100644 --- a/app/luclient.py +++ b/app/luclient.py @@ -12,7 +12,13 @@ from app.models import CharacterInfo from app.cdclient import ( Objects, Icons, - ItemSets + ItemSets, + ComponentsRegistry, + ComponentType, + RenderComponent, + ItemComponent, + ObjectSkills, + SkillBehavior ) import glob import os @@ -21,7 +27,6 @@ from wand.exceptions import BlobError as BE import pathlib import json -import sqlite3 import xml.etree.ElementTree as ET from sqlalchemy import or_ @@ -71,32 +76,24 @@ def get_dds(filename): @luclient_blueprint.route('/get_icon_lot/') @login_required def get_icon_lot(id): + icon_path = RenderComponent.query.filter( + RenderComponent.id == ComponentsRegistry.query.filter( + ComponentsRegistry.component_type == ComponentType.COMPONENT_TYPE_RENDER + ).filter(ComponentsRegistry.id == id).first().component_id + ).first().icon_asset - render_component_id = query_cdclient( - 'select component_id from ComponentsRegistry where component_type = 2 and id = ?', - [id], - one=True - )[0] - - # find the asset from rendercomponent given the component id - filename = query_cdclient( - 'select icon_asset from RenderComponent where id = ?', - [render_component_id], - one=True - )[0] - - if filename: - filename = filename.replace("..\\", "").replace("\\", "/") + if icon_path: + icon_path = icon_path.replace("..\\", "").replace("\\", "/") else: return redirect(url_for('luclient.unknown')) - cache = f'app/cache/{filename.split(".")[0]}.png' + cache = f'app/cache/{icon_path.split(".")[0]}.png' if not os.path.exists(cache): root = 'app/luclient/res/' try: pathlib.Path(os.path.dirname(cache)).resolve().mkdir(parents=True, exist_ok=True) - with image.Image(filename=f'{root}{filename}'.lower()) as img: + with image.Image(filename=f'{root}{icon_path}'.lower()) as img: img.compression = "no" img.save(filename=cache) except BE: @@ -278,21 +275,11 @@ def register_luclient_jinja_helpers(app): def get_lot_rarity(lot_id): if not lot_id: return "Missing" - render_component_id = query_cdclient( - 'select component_id from ComponentsRegistry where component_type = 11 and id = ?', - [lot_id], - one=True - ) - if render_component_id: - render_component_id = render_component_id[0] - - rarity = query_cdclient( - 'select rarity from ItemComponent where id = ?', - [render_component_id], - one=True - ) - if rarity: - rarity = rarity[0] + rarity = ItemComponent.query.filter( + ItemComponent.id == ComponentsRegistry.query.filter( + ComponentsRegistry.component_type == ComponentType.COMPONENT_TYPE_ITEM + ).filter(ComponentsRegistry.id == id).first().component_id + ).first().rarity return rarity @app.template_filter('get_lot_desc') @@ -301,12 +288,12 @@ def register_luclient_jinja_helpers(app): return "Missing" desc = translate_from_locale(f'Objects_{lot_id}_description') if desc == f'Objects_{lot_id}_description': - desc = Objects.query.filter(Objects.id == id).first().description + desc = Objects.query.filter(Objects.id == lot_id).first() if desc in ("", None): desc = None else: - desc = desc[0] + desc = desc.description if desc in ("", None): desc = None if desc: @@ -334,12 +321,19 @@ def register_luclient_jinja_helpers(app): def get_lot_stats(lot_id): if not lot_id: return None - stats = query_cdclient( - 'SELECT imBonusUI, lifeBonusUI, armorBonusUI, skillID, skillIcon FROM SkillBehavior WHERE skillID IN (\ - SELECT skillID FROM ObjectSkills WHERE objectTemplate=?\ - )', - [lot_id] - ) + stats = SkillBehavior.query.with_entities( + SkillBehavior.imBonusUI, + SkillBehavior.lifeBonusUI, + SkillBehavior.armorBonusUI, + SkillBehavior.skillID, + SkillBehavior.skillIcon + ).filter( + SkillBehavior.skillID in ObjectSkills.query.with_entities( + ObjectSkills.skillID + ).filter( + ObjectSkills.objectTemplate == lot_id + ).all() + ).all() return consolidate_stats(stats) @@ -347,12 +341,19 @@ def register_luclient_jinja_helpers(app): def get_set_stats(lot_id): if not lot_id: return "Missing" - stats = query_cdclient( - 'SELECT imBonusUI, lifeBonusUI, armorBonusUI, skillID, skillIcon FROM SkillBehavior WHERE skillID IN (\ - SELECT skillID FROM ItemSetSkills WHERE SkillSetID=?\ - )', - [lot_id] - ) + stats = SkillBehavior.query.with_entities( + SkillBehavior.imBonusUI, + SkillBehavior.lifeBonusUI, + SkillBehavior.armorBonusUI, + SkillBehavior.skillID, + SkillBehavior.skillIcon + ).filter( + SkillBehavior.skillID == ObjectSkills.query.with_entities( + ObjectSkills.skillID + ).filter( + ObjectSkills.objectTemplate == lot_id + ).all() + ).all() return consolidate_stats(stats) @@ -364,26 +365,18 @@ def register_luclient_jinja_helpers(app): def consolidate_stats(stats): - if len(stats) > 1: + if stats: consolidated_stats = {"im": 0, "life": 0, "armor": 0, "skill": []} for stat in stats: - if stat[0]: - consolidated_stats["im"] += stat[0] - if stat[1]: - consolidated_stats["life"] += stat[1] - if stat[2]: - consolidated_stats["armor"] += stat[2] - if stat[3]: - consolidated_stats["skill"].append([stat[3], stat[4]]) - + if stat.imBonusUI: + consolidated_stats["im"] += stat.imBonusUI + if stat.lifeBonusUI: + consolidated_stats["life"] += stat.lifeBonusUI + if stat.armorBonusUI: + consolidated_stats["armor"] += stat.armorBonusUI + if stat.skillID: + consolidated_stats["skill"].append([stat.skillID, stat.skillIcon]) stats = consolidated_stats - elif len(stats) == 1: - stats = { - "im": stats[0][0] if stats[0][0] else 0, - "life": stats[0][1] if stats[0][1] else 0, - "armor": stats[0][2] if stats[0][2] else 0, - "skill": [[stats[0][3], stats[0][4]]] if stats[0][3] else None, - } else: stats = None return stats diff --git a/app/properties.py b/app/properties.py index 7fc64e8..6bd0517 100644 --- a/app/properties.py +++ b/app/properties.py @@ -13,6 +13,7 @@ from flask_user import login_required, current_user from datatables import ColumnDT, DataTables import time from app.models import Property, db, UGC, CharacterInfo, PropertyContent, Account, Mail +from app.cdclient import ComponentsRegistry, ComponentType, RenderComponent from app.schemas import PropertySchema from app import gm_level, log_audit from app.cdclient import ZoneTable @@ -409,17 +410,12 @@ def ugc(content): def prebuilt(content, file_format, lod): # translate LOT to component id # we need to get a type of 2 because reasons - render_component_id = query_cdclient( - 'select component_id from ComponentsRegistry where component_type = 2 and id = ?', - [content.lot], - one=True - )[0] - # find the asset from rendercomponent given the component id - filename = query_cdclient( - 'select render_asset from RenderComponent where id = ?', - [render_component_id], - one=True - ) + filename = RenderComponent.query.filter( + RenderComponent.id == ComponentsRegistry.query.filter( + ComponentsRegistry.component_type == ComponentType.COMPONENT_TYPE_RENDER + ).filter(ComponentsRegistry.id == id).first().component_id + ).first().render_asset + if filename: filename = filename[0].split("\\\\")[-1].lower().split(".")[0] if "/" in filename: