cdclient and some analysis commands

This commit is contained in:
Aaron Kimbre 2022-07-14 08:31:31 -05:00
parent 62fb9a3c01
commit 92f7e5ae52
6 changed files with 305 additions and 48 deletions

2
.gitignore vendored
View File

@ -17,3 +17,5 @@ property_files/*
*.log *.log
app/settings.py app/settings.py
*.exe *.exe
*.csv
*.sql

View File

@ -18,7 +18,11 @@ from app.commands import (
load_property, load_property,
gen_image_cache, gen_image_cache,
gen_model_cache, gen_model_cache,
fix_clone_ids fix_clone_ids,
parse_lucache,
makeup_unlisted_objects,
gen_new_locales,
xref_scripts
) )
from app.models import Account, AccountInvitation, AuditLog from app.models import Account, AccountInvitation, AuditLog
@ -81,6 +85,10 @@ def create_app():
app.cli.add_command(gen_image_cache) app.cli.add_command(gen_image_cache)
app.cli.add_command(gen_model_cache) app.cli.add_command(gen_model_cache)
app.cli.add_command(fix_clone_ids) app.cli.add_command(fix_clone_ids)
app.cli.add_command(parse_lucache)
app.cli.add_command(makeup_unlisted_objects)
app.cli.add_command(gen_new_locales)
app.cli.add_command(xref_scripts)
register_logging(app) register_logging(app)
register_settings(app) register_settings(app)

View File

@ -1408,58 +1408,89 @@ class ComponentsRegistry(db.Model):
nullable=False nullable=False
) )
component = generic_relationship(component_type, component_id) # component = generic_relationship(component_type, component_id)
# From DLU source # From DLU source
class ComponentType(enum.IntEnum): class ComponentType(enum.IntEnum):
COMPONENT_TYPE_CONTROLLABLE_PHYSICS = 1 # The ControllablePhysics Component COMPONENT_TYPE_CONTROLLABLE_PHYSICS = 1 # noqa - The ControllablePhysics Component
COMPONENT_TYPE_RENDER = 2 # The Render Component COMPONENT_TYPE_RENDER = 2 # noqa - The Render Component
COMPONENT_TYPE_SIMPLE_PHYSICS = 3 # The SimplePhysics Component COMPONENT_TYPE_SIMPLE_PHYSICS = 3 # noqa - The SimplePhysics Component
COMPONENT_TYPE_CHARACTER = 4 # The Character Component COMPONENT_TYPE_CHARACTER = 4 # noqa - The Character Component
COMPONENT_TYPE_SCRIPT = 5 # The Script Component COMPONENT_TYPE_SCRIPT = 5 # noqa - The Script Component
COMPONENT_TYPE_BOUNCER = 6 # The Bouncer Component COMPONENT_TYPE_BOUNCER = 6 # noqa - The Bouncer Component
COMPONENT_TYPE_BUFF = 7 # The Buff Component COMPONENT_TYPE_BUFF = 7 # noqa - The Buff Component
COMPONENT_TYPE_SKILL = 9 # The Skill Component COMPONENT_TYPE_SKILL = 9 # noqa - The Skill Component
COMPONENT_TYPE_ITEM = 11 # The Item Component COMPONENT_TYPE_ITEM = 11 # noqa - The Item Component
COMPONENT_TYPE_VENDOR = 16 # The Vendor Component COMPONENT_TYPE_VENDOR = 16 # noqa - The Vendor Component
COMPONENT_TYPE_INVENTORY = 17 # The Inventory Component COMPONENT_TYPE_INVENTORY = 17 # noqa - The Inventory Component
COMPONENT_TYPE_SHOOTING_GALLERY = 19 # The Shooting Gallery Component COMPONENT_TYPE_SHOOTING_GALLERY = 19 # noqa - The Shooting Gallery Component
COMPONENT_TYPE_RIGID_BODY_PHANTOM_PHYSICS = 20 # The RigidBodyPhantomPhysics Component COMPONENT_TYPE_RIGID_BODY_PHANTOM_PHYSICS = 20 # noqa - The RigidBodyPhantomPhysics Component
COMPONENT_TYPE_COLLECTIBLE = 23 # The Collectible Component COMPONENT_TYPE_COLLECTIBLE = 23 # noqa - The Collectible Component
COMPONENT_TYPE_MOVING_PLATFORM = 25 # The MovingPlatform Component COMPONENT_TYPE_MOVING_PLATFORM = 25 # noqa - The MovingPlatform Component
COMPONENT_TYPE_PET = 26 # The Pet Component COMPONENT_TYPE_PET = 26 # noqa - The Pet Component
COMPONENT_TYPE_VEHICLE_PHYSICS = 30 # The VehiclePhysics Component COMPONENT_TYPE_VEHICLE_PHYSICS = 30 # noqa - The VehiclePhysics Component
COMPONENT_TYPE_MOVEMENT_AI = 31 # The MovementAI Component COMPONENT_TYPE_MOVEMENT_AI = 31 # noqa - The MovementAI Component
COMPONENT_TYPE_PROPERTY = 36 # The Property Component COMPONENT_TYPE_PROPERTY = 36 # noqa - The Property Component
COMPONENT_TYPE_SCRIPTED_ACTIVITY = 39 # The ScriptedActivity Component COMPONENT_TYPE_SCRIPTED_ACTIVITY = 39 # noqa - The ScriptedActivity Component
COMPONENT_TYPE_PHANTOM_PHYSICS = 40 # The PhantomPhysics Component COMPONENT_TYPE_PHANTOM_PHYSICS = 40 # noqa - The PhantomPhysics Component
COMPONENT_TYPE_PROPERTY_ENTRANCE = 43 # The PhantomPhysics Component COMPONENT_TYPE_PROPERTY_ENTRANCE = 43 # noqa - The PhantomPhysics Component
COMPONENT_TYPE_PROPERTY_MANAGEMENT = 45 # The PropertyManagement Component COMPONENT_TYPE_PROPERTY_MANAGEMENT = 45 # noqa - The PropertyManagement Component
COMPONENT_TYPE_REBUILD = 48 # The Rebuild Component COMPONENT_TYPE_REBUILD = 48 # noqa - The Rebuild Component
COMPONENT_TYPE_SWITCH = 49 # The Switch Component COMPONENT_TYPE_SWITCH = 49 # noqa - The Switch Component
COMPONENT_TYPE_ZONE_CONTROL = 50 # The ZoneControl Component COMPONENT_TYPE_ZONE_CONTROL = 50 # noqa - The ZoneControl Component
COMPONENT_TYPE_PACKAGE = 53 # The Package Component COMPONENT_TYPE_PACKAGE = 53 # noqa - The Package Component
COMPONENT_TYPE_PLAYER_FLAG = 58 # The PlayerFlag Component COMPONENT_TYPE_PLAYER_FLAG = 58 # noqa - The PlayerFlag Component
COMPONENT_TYPE_BASE_COMBAT_AI = 60 # The BaseCombatAI Component COMPONENT_TYPE_BASE_COMBAT_AI = 60 # noqa - The BaseCombatAI Component
COMPONENT_TYPE_MODULE_ASSEMBLY = 61 # The ModuleAssembly Component COMPONENT_TYPE_MODULE_ASSEMBLY = 61 # noqa - The ModuleAssembly Component
COMPONENT_TYPE_PROPERTY_VENDOR = 65 # The PropertyVendor Component COMPONENT_TYPE_PROPERTY_VENDOR = 65 # noqa - The PropertyVendor Component
COMPONENT_TYPE_ROCKET_LAUNCH = 67 # The RocketLaunch Component COMPONENT_TYPE_ROCKET_LAUNCH = 67 # noqa - The RocketLaunch Component
COMPONENT_TYPE_RACING_CONTROL = 71 # The RacingControl Component COMPONENT_TYPE_RACING_CONTROL = 71 # noqa - The RacingControl Component
COMPONENT_TYPE_MISSION_OFFER = 73 # The MissionOffer Component COMPONENT_TYPE_MISSION_OFFER = 73 # noqa - The MissionOffer Component
COMPONENT_TYPE_EXHIBIT = 75 # The Exhibit Component COMPONENT_TYPE_EXHIBIT = 75 # noqa - The Exhibit Component
COMPONENT_TYPE_RACING_STATS = 74 # The Exhibit Component COMPONENT_TYPE_RACING_STATS = 74 # noqa - The Exhibit Component
COMPONENT_TYPE_SOUND_TRIGGER = 77 # The Sound Trigger Component COMPONENT_TYPE_SOUND_TRIGGER = 77 # noqa - The Sound Trigger Component
COMPONENT_TYPE_PROXIMITY_MONITOR = 78 # The Proximity Monitor Component COMPONENT_TYPE_PROXIMITY_MONITOR = 78 # noqa - The Proximity Monitor Component
COMPONENT_TYPE_MISSION = 84 # The Mission Component COMPONENT_TYPE_MISSION = 84 # noqa - The Mission Component
COMPONENT_TYPE_ROCKET_LAUNCH_LUP = 97 # The LUP Launchpad Componen COMPONENT_TYPE_ROCKET_LAUNCH_LUP = 97 # noqa - The LUP Launchpad Componen
COMPONENT_TYPE_RAIL_ACTIVATOR = 104 COMPONENT_TYPE_RAIL_ACTIVATOR = 104 # noqa
COMPONENT_TYPE_POSSESSOR = 107 # The Component 107 COMPONENT_TYPE_POSSESSOR = 107 # noqa - The Component 107
COMPONENT_TYPE_POSSESSABLE = 108 # The Component 108 COMPONENT_TYPE_POSSESSABLE = 108 # noqa - The Component 108
COMPONENT_TYPE_BUILD_BORDER = 114 # The Build Border Component COMPONENT_TYPE_BUILD_BORDER = 114 # noqa - The Build Border Component
COMPONENT_TYPE_DESTROYABLE = 1000 # The Destroyable Component COMPONENT_TYPE_DESTROYABLE = 1000 # noqa - The Destroyable Component
# class ComponentMap(enum.Enum):
# 1 = ["PhysicsComponent"]
# 2 = ["RenderComponent"]
# 3 = ["PhysicsComponent"]
# 5 = ["ScriptComponent"]
# 7 = ["DestructibleComponent"]
# 9 = ["ObjectSkills", "SkillBehavior"]
# 12 = ["RebuildComponent"]
# 15 = ["RenderComponent"]
# 17 = ["InventoryComponent"]
# 18 = ["PhysicsComponent"]
# 20 = ["PhysicsComponent"]
# 24 = ["Blueprints"]
# 26 = ["PetComponent"]
# 29 = ["JetPackPadComponent"]
# 30 = ["VehiclePhysics"]
# 31 = ["MovementAIComponent"]
# 33 = ["mapIcon", "NpcIcons"]
# 40 = ["PhysicsComponent"]
# 46 = ["PhysicsComponent"]
# 47 = ["PhysicsComponent"]
# 48 = ["RebuildComponent"]
# 52 = ["ChoiceBuildComponent"]
# 53 = ["PackageComponent"]
# 60 = ["BaseCombatAIComponent"]
# 61 = ["ModularBuildComponent"]
# 67 = ["RocketLaunchpadControlComponent"]
# 73 = ["MissionNPCComponent"]
# 75 = ["LUPExhibitComponent"]
# 78 = ["ProximityMonitor"]
class ControlSchemes(db.Model): class ControlSchemes(db.Model):
__tablename__ = 'ControlSchemes' __tablename__ = 'ControlSchemes'
__bind_key__ = 'cdclient' __bind_key__ = 'cdclient'

View File

@ -15,7 +15,17 @@ from multiprocessing import Pool
from functools import partial from functools import partial
from sqlalchemy import func from sqlalchemy import func
import time import time
import csv
import json
from app.cdclient import (
ComponentsRegistry,
RenderComponent,
ItemComponent,
Objects,
ScriptComponent,
)
from app.luclient import translate_from_locale
@click.command("init_db") @click.command("init_db")
@click.argument('drop_tables', nargs=1) @click.argument('drop_tables', nargs=1)
@ -180,6 +190,187 @@ def load_property(zone, player):
) )
new_prop_content.save() new_prop_content.save()
@click.command("parse_lucache")
@with_appcontext
def parse_lucache():
"""Parses lucache csv file dump from nexus hq"""
unlisted_ids = [146, 147, 938, 1180, 1692, 1715, 1797, 1799, 1824, 1846, 1847, 1848, 1849, 1850, 1872, 1877, 1887, 1928, 1937, 1968, 1970, 1971, 1972, 1974, 1976, 1977, 1978, 1979, 1980, 1981, 1983, 1984, 2189, 2401, 2402, 2403, 2404, 2405, 2406, 2407, 2408, 2416, 2417, 2418, 2420, 2421, 2422, 2423, 2424, 2425, 2426, 2427, 2429, 2430, 2431, 2432, 2433, 2434, 2435, 2436, 2529, 2530, 2553, 2583, 2655, 2656, 2669, 2947, 2948, 3009, 3058, 3068, 3078, 3807, 3812, 3937, 4828, 4874, 4875, 4876, 4877, 4943, 4954, 5839, 5840, 6196, 6218, 6219, 6221, 6433, 6471, 6696, 6821, 6877, 6888, 6889, 6891, 6892, 6893, 6894, 6896, 6897, 6983, 7277, 7551, 7552, 7553, 7554, 7609, 7701, 7713, 7723, 7753, 7754, 7755, 7756, 7760, 7777, 7791, 7824, 7872, 8046, 8053, 8146, 9865, 9866, 9867, 9868, 10126, 10291, 10292, 10293, 10294, 10518, 10630, 10631, 10987, 11511, 11512, 11513, 11514, 11515, 11516, 11517, 11518, 11519, 11520, 11521, 11522, 11523, 11524, 11525, 12096, 12097, 12099, 12100, 12104, 12105, 12111, 12112, 12113, 12324, 12325, 12326, 12553, 12666, 12668, 12670, 12671, 12673, 12674, 12676, 12679, 12680, 12683, 12684, 12685, 12687, 12692, 12694, 12697, 12699, 12701, 12703, 12704, 12713, 12716, 12717, 12727, 12736, 12738, 12739, 12745, 12746, 12750, 12751, 12752, 12757, 12787, 12790, 12791, 12794, 12795, 12799, 12800, 12803, 12887, 12888, 12902, 12904, 12905, 12906, 12907, 12941, 13060, 13061, 13071, 13075, 13076, 13077, 13092, 13093, 13094, 13106, 13118, 13121, 13126, 13127, 13150, 13191, 13192, 13275, 13276, 13277, 13278, 13280, 13295, 13410, 13411, 13510, 13638, 13740, 13742, 13776, 13782, 13905, 13925, 13926, 13927, 13928, 13929, 13930, 13931, 13932, 13953, 13958, 13974, 13996, 13997, 13998, 13999, 14000, 14001, 14002, 14056, 14057, 14058, 14059, 14060, 14061, 14062, 14063, 14064, 14065, 14066, 14067, 14068, 14069, 14070, 14071, 14072, 14073, 14074, 14075, 14076, 14077, 14078, 14079, 14080, 14081, 14090, 14094, 14111, 14135, 14140, 14170, 14171, 14188, 14200, 14202, 14206, 14207, 14208, 14209, 14210, 14211, 14212, 14213, 14228, 14229, 14314, 14428, 14483, 14515, 14522, 14531, 14535, 14536, 14538, 14548, 14554, 14587, 14588, 14589, 14597, 14598, 14599, 14605, 14607, 14608, 14609, 14610, 14611, 14612, 14613, 14614, 14615, 14616, 14617, 14618, 14619, 14620, 14621, 14622, 14623, 14624, 14625, 14626, 14627, 14628, 14629, 14630, 14631, 14632, 14633, 14634, 14635, 14636, 14637, 14638, 14639, 14640, 14641, 14642, 14643, 14644, 14645, 14646, 14647, 14648, 14649, 14650, 14651, 14652, 14653, 14654, 14655, 14656, 14657, 14658, 14659, 14660, 14661, 14662, 14663, 14664, 14665, 14666, 14667, 14668, 14686, 14687, 14688, 14689, 14690, 14704, 14706, 14707, 14716, 14717, 14721, 14722, 14727, 14728, 14729, 14779, 14795, 14799, 14800, 14803, 14815, 14820, 14821, 14822, 14823, 14824, 14825, 14826, 14827, 14831, 14832, 14838, 14839, 15852, 15853, 15854, 15855, 15856, 15857, 15858, 15859, 15860, 15861, 15862, 15863, 15864, 15865, 15885, 15886, 15887, 15888, 15889, 15893, 15894, 15898, 15921, 15923, 15925, 15928, 15930, 15931, 15932, 15933, 15934, 15938, 15939, 15940, 15941, 15942, 15945, 15958, 15962, 15963, 15964, 15965, 15966, 15967, 15968, 15969, 15970, 15971, 15972, 15973, 15981, 15984, 15985, 15986, 15987, 15988, 15989, 15996, 15997, 15998, 15999, 16000, 16001, 16002, 16003, 16004, 16005, 16007, 16008, 16009, 16010, 16011, 16025, 16026, 16027, 16028, 16036, 16039, 16042, 16046, 16051, 16056, 16071, 16072, 16073, 16074, 16075, 16077, 16078, 16079, 16080, 16081, 16089, 16090, 16091, 16092, 16108, 16109, 16110, 16111, 16112, 16113, 16114, 16115, 16116, 16117, 16124, 16125, 16126, 16127, 16128, 16129, 16130, 16137, 16138, 16139, 16140, 16142, 16145, 16167, 16168, 16169, 16170, 16171, 16172, 16173, 16174, 16175, 16176, 16177, 16200, 16201, 16202, 16204, 16212, 16253, 16254, 16418, 16437, 16469, 16479, 16489, 16505, 16641, 16645, 16646, 16648, 16655, 16658, 16659, 16660, 16661, 16662, 16665, 16666, 16667, 16668, 16669, 16670, 16671, 16672, 16673, 16674, 16675, 16676, 16677, 16678, 16679, 16680, 16681, 16685, 16686, 16687, 16688, 16689, 16690, 16691, 16692, 16693, 16694, 16695, 16696, 16697, 16698, 16699, 16700, 16701, 16702, 16703, 16704, 16705, 16706, 16707, 16708, 16709, 16712, 16714, 16717, 16718, 16719, 16720, 16721, 16722, 16724, 16725, 16726, 16727, 16732, 16733, 16734, 16735] # noqa
with open("lucache.csv") as cache_file:
csv_reader = csv.reader(cache_file, delimiter=',')
line_count = 0
for row in csv_reader:
if row[0] == "id":
continue
if int(row[0]) in unlisted_ids:
json_data = json.loads(row[2])
components = ComponentsRegistry.query.filter(ComponentsRegistry.id == int(row[0])).all()
obj_type = "Environmental"
desc = json_data["Description"]
if desc in ["None", None, ""]:
desc = row[1]
nametag = 0
npcTemplateID = "null"
for comp in components:
if comp.component_type == 7: # Item
obj_type = "Smashable"
if comp.component_type == 11: # Item
obj_type = "Loot"
if comp.component_type == 35: # minifig
obj_type = "NPC"
npcTemplateID = comp.component_id
nametag = 1
if comp.component_type == 42: # b3
obj_type = "Behavior"
if comp.component_type == 60: # base combat ai
obj_type = "Enemy"
if comp.component_type == 73: # mission giver
if obj_type != "NPC":
obj_type = "Structure"
desc = f"__MG__{desc}"
if "vendor" in row[1].lower():
obj_type = "NPC"
print(f"""INSERT INTO "Objects" ("id","name","placeable","type","description","localize","npcTemplateID","displayName","interactionDistance","nametag","_internalNotes","locStatus","gate_version","HQ_valid") VALUES ("{row[0]}", "{row[1].replace("_", " ")}", 1, "{obj_type}", "{desc}", 1, {npcTemplateID} , "{json_data["DisplayName"]}", null , {nametag}, "Unlisted Object", 0, null, 1);""")
if obj_type in ["NPC", "Smashable", "Loot"]:
print(f""" <phrase id="Objects_{row[0]}_name">
<translation locale="en_US">{row[1]}</translation>
<translation locale="de_DE">TRASNSLATE UNLISTED</translation>
<translation locale="en_GB">{row[1]}</translation>
</phrase>
<phrase id="Objects_{row[0]}_description">
<translation locale="en_US">{desc}</translation>
<translation locale="de_DE">TRASNSLATE UNLISTED</translation>
<translation locale="en_GB">{desc}</translation>
</phrase>""")
# print(f'{row[0]}: {json_data["DisplayName"]}')
line_count += 1
# print(f'Processed {line_count} lines.')
@click.command("makeup_unlisted_objects")
@with_appcontext
def makeup_unlisted_objects():
objs_left = []
for obj in objs_left:
obj_type = "Environmental"
nametag = 0
name = "Name Missing"
desc = "null"
npcTemplateID = "null"
components = ComponentsRegistry.query.filter(ComponentsRegistry.id == obj).all()
for comp in components:
if comp.component_type == 2: # render
render = RenderComponent.query.filter(RenderComponent.id == comp.component_id).first()
if render is not None:
if render.render_asset not in [None, ""]:
name = render.render_asset.replace("_", " ").split('\\')[-1].split('/')[-1].split('.')[0].lower()
if name == "Name Missing":
if render.icon_asset not in [None, ""]:
name = render.icon_asset.replace("_", " ").split('\\')[-1].split('/')[-1].split('.')[0].lower()
name = name.replace("env ", "").replace("obj ", "").replace("minifig accessory ", "").replace("", "").replace("mf ", "").replace("cre ", "")
# print(f"{obj}: {name} : {alt_name}")
obj_type = "Smashable"
# else:
# print(f"{obj}: No Render")
if comp.component_type == 7: # destroyable
obj_type = "Smashable"
if comp.component_type == 11: # Item
item = ItemComponent.query.filter(ItemComponent.id == comp.component_id).first()
if item.itemType == 24:
obj_type = "Mount"
else:
obj_type = "Loot"
if comp.component_type == 35: # minifig
obj_type = "NPC"
npcTemplateID = comp.component_id
nametag = 1
if comp.component_type == 42: # b3
obj_type = "Behavior"
if comp.component_type == 60: # base combat ai
obj_type = "Enemy"
if comp.component_type == 73: # mission giver
if obj_type != "NPC":
obj_type = "Structure"
desc = f"__MG__{name}"
# print(f"""INSERT INTO "Objects" ("id","name","placeable","type","description","localize","npcTemplateID","displayName","interactionDistance","nametag","_internalNotes","locStatus","gate_version","HQ_valid") VALUES ("{obj}", "{name}", 1, "{obj_type}", "{desc}", 1, {npcTemplateID} , "{name}", null , {nametag}, "Unlisted Object", 0, null, 1);""")
if name != "Name Missing" and obj_type in ["Mount"]:
print(f""" <phrase id="Objects_{obj}_name">
<translation locale="en_US">{name}</translation>
<translation locale="de_DE">TRASNSLATE UNLISTED</translation>
<translation locale="en_GB">{name}</translation>
</phrase>""")
@click.command("gen_new_locales")
@with_appcontext
def gen_new_locales():
objects = Objects.query.order_by(Objects.id).all()
for obj in objects:
if obj.type == "Loot":
if obj.name not in ["Name Missing", None, "None"] and obj.name[:1] != "m":
name_to_trans = f"Object_{obj.id}_name"
name_transed = translate_from_locale(name_to_trans)
if name_to_trans == name_transed:
print(f""" <phrase id="Objects_{obj.id}_name">
<translation locale="en_US">{obj.name}</translation>
<translation locale="de_DE">TRASNSLATE OLD</translation>
<translation locale="en_GB">{obj.name}</translation>
</phrase>""")
if obj.description not in ["None", None, ""]:
description_to_trans = f"Object_{obj.id}_description"
description_transed = translate_from_locale(description_to_trans)
if description_to_trans == description_transed:
print(f""" <phrase id="Objects_{obj.id}_description">
<translation locale="en_US">{obj.description}</translation>
<translation locale="de_DE">TRASNSLATE OLD</translation>
<translation locale="en_GB">{obj.description}</translation>
</phrase>""")
@click.command("xref_scripts")
@with_appcontext
def xref_scripts():
"""cross refernce scripts dir with script component table"""
scripts = ScriptComponent.query.all()
base = 'app/luclient/res/'
server = 0
server_total = 0
client = 0
client_total = 0
server_used = 0
client_used = 0
used_total = 0
disk_scripts = [path for path in pathlib.Path('app/luclient/res/scripts').rglob("*.lua") if path.is_file()]
for script in scripts:
script_comps = ComponentsRegistry.query.filter(ComponentsRegistry.component_type == 5).filter(ComponentsRegistry.component_id == script.id).all()
if len(script_comps) > 0:
used_total += 1
if script.client_script_name not in [None, ""]:
cleaned_name = script.client_script_name.replace('\\', '/').lower()
client_script = pathlib.Path(f"{base}{cleaned_name}")
client_total += 1
if not client_script.is_file():
print(f"Missing Server Script: {client_script.as_posix()}")
client += 1
if len(script_comps) > 0:
client_used += 1
if script.script_name not in [None, ""]:
cleaned_name = script.script_name.replace('\\', '/').lower()
server_script = pathlib.Path(f"{base}{cleaned_name}")
server_total += 1
if not server_script.is_file():
print(f"Missing Client Script: {server_script.as_posix()}")
server += 1
if len(script_comps) > 0:
server_used += 1
print(f"Missing {server}/{server_total} server scripts")
print(f"Missing {client}/{client_total} client scripts")
print(f"Missing {server_used}/{used_total} used server scripts")
print(f"Missing {client_used}/{used_total} used client scripts")
print(f"Total cdclient scripts {server_total + client_total}\nTotal disk scripts {len(disk_scripts)}")
@click.command("gen_image_cache") @click.command("gen_image_cache")
def gen_image_cache(): def gen_image_cache():

View File

@ -7,6 +7,11 @@ APP_SYSTEM_ERROR_SUBJECT_LINE = APP_NAME + " system error"
APP_SECRET_KEY = "" APP_SECRET_KEY = ""
APP_DATABASE_URI = "mysql+pymysql://<username>:<password>@<host>:<port>/<database>" APP_DATABASE_URI = "mysql+pymysql://<username>:<password>@<host>:<port>/<database>"
CONFIG_LINK = False
CONFIG_LINK_TITLE = ""
CONFIG_LINK_HREF = ""
CONFIG_LINK_TEXT = ""
# Send Analytics for Developers to better fix issues # Send Analytics for Developers to better fix issues
ALLOW_ANALYTICS = False ALLOW_ANALYTICS = False

View File

@ -24,7 +24,27 @@
</div> </div>
{% endfor %} {% endfor %}
<hr> </div>
</div>
<div class='card mx-auto mt-5 shadow-sm bg-dark border-primary'>
<div class="card-body">
<h4 class="text-center">Links</h4>
{% if config.CONFIG_LINK %}
<div class="row">
<div class="col text-right">
{{ config.CONFIG_LINK_TITLE }}
</div>
<div class="col">
<a href="{{ url_for('static', filename=config.CONFIG_LINK_HREF) }}">
{{ config.CONFIG_LINK_TEXT }}
</a>
</div>
</div>
{% endif %}
<div class="row"> <div class="row">
<div class="col text-right"> <div class="col text-right">
Source Source