diff --git a/.env.template b/.env.template index 99830cd..2b933cd 100644 --- a/.env.template +++ b/.env.template @@ -219,6 +219,8 @@ MODULES_REQUIRES_PLAYERBOT_SOURCE=0 # Only set this if you need to override the auto-detected version # Example: v18.0, v17.0, etc. CLIENT_DATA_VERSION= +# Client data path for deployment (auto-calculated when left blank) +CLIENT_DATA_PATH= # ===================== # Server Configuration @@ -236,159 +238,66 @@ CLIENT_DATA_CACHE_PATH=${STORAGE_PATH_LOCAL}/client-data-cache # 🤖 Automation # Playerbot and AI systems -MODULE_NPCBOT_EXTENDED_COMMANDS=0 -MODULE_OLLAMA_CHAT=0 # mod-playerbots: Installs SQL/config assets; core functionality is built into playerbot images -MODULE_PLAYERBOTS=0 -MODULE_PLAYER_BOT_LEVEL_BRACKETS=0 # ✨ Quality of Life # Convenience features that improve gameplay experience -MODULE_AOE_LOOT=0 -MODULE_AUTO_REVIVE=0 -MODULE_FIREWORKS=0 -MODULE_INSTANCE_RESET=0 -MODULE_LEARN_SPELLS=0 -MODULE_SOLO_LFG=0 # ⚔️ Gameplay Enhancement # Core gameplay improvements and mechanics -MODULE_AUTOBALANCE=0 -MODULE_CHALLENGE_MODES=0 -MODULE_DUEL_RESET=0 -MODULE_DUNGEON_RESPAWN=0 -MODULE_HARDCORE_MODE=0 -MODULE_HORADRIC_CUBE=0 -MODULE_SOLOCRAFT=0 -MODULE_STATBOOSTER=0 -MODULE_TIME_IS_TIME=0 # 🏪 NPC Services # Service NPCs that provide player utilities -MODULE_ASSISTANT=0 -MODULE_MULTIVENDOR=0 -MODULE_NPC_BEASTMASTER=0 -MODULE_NPC_BUFFER=0 -MODULE_NPC_ENCHANTER=0 -MODULE_NPC_FREE_PROFESSIONS=0 # mod-npc-talent-template: Admin commands: .templatenpc create [TemplateName] and .templatenpc reload -MODULE_NPC_TALENT_TEMPLATE=0 -MODULE_REAGENT_BANK=0 -MODULE_TRANSMOG=0 # ⚡ PvP # Player vs Player focused modules -MODULE_1V1_ARENA=0 # mod-arena-replay: NPC ID: 98500; known issue: players who were participants experience unusual behavior when watching their own replay -MODULE_ARENA_REPLAY=0 -MODULE_GAIN_HONOR_GUARD=0 -MODULE_PHASED_DUELS=0 -MODULE_PVP_TITLES=0 -MODULE_ULTIMATE_FULL_LOOT_PVP=0 # 📈 Progression # Character and server progression systems -MODULE_DYNAMIC_XP=0 -MODULE_INDIVIDUAL_PROGRESSION=0 -MODULE_ITEM_LEVEL_UP=0 -MODULE_LEVEL_GRANT=0 # mod-progression-system: SQL files cannot be unloaded once executed; requires auto DB updater enabled in worldserver config -MODULE_PROGRESSION_SYSTEM=0 -MODULE_PROMOTION_AZEROTHCORE=0 -MODULE_WEEKEND_XP=0 # mod-zone-difficulty: Mythicmode NPC 1128001 spawned in raids/heroic dungeons; NPC 1128002 for Mythicmode rewards -MODULE_ZONE_DIFFICULTY=0 # 💰 Economy # Auction house, trading, and economic systems -MODULE_AHBOT=0 -MODULE_BLACK_MARKET_AUCTION_HOUSE=0 -MODULE_DYNAMIC_TRADER=0 -MODULE_EXCHANGE_NPC=0 -MODULE_GLOBAL_MAIL_BANKING_AUCTIONS=0 -MODULE_LOTTERY_LUA=0 -MODULE_LUA_AH_BOT=0 -MODULE_RANDOM_ENCHANTS=0 # 👥 Social # Social and community features -MODULE_ACTIVE_CHAT=0 -MODULE_BOSS_ANNOUNCER=0 -MODULE_BREAKING_NEWS=0 -MODULE_DISCORD_NOTIFIER=0 -MODULE_GLOBAL_CHAT=0 -MODULE_TEMP_ANNOUNCEMENTS=0 # 👤 Account-Wide # Features that apply across all characters on an account -MODULE_ACCOUNTWIDE_SYSTEMS=0 -MODULE_ACCOUNT_ACHIEVEMENTS=0 -MODULE_ACCOUNT_MOUNTS=0 # 🎨 Customization # Character and appearance customization -MODULE_ARAC=0 # mod-morphsummon: Allows customization of summoned creature appearances (Warlock demons, Death Knight ghouls, Mage water elementals); NPC ID: 601072 -MODULE_MORPHSUMMON=0 -MODULE_TRANSMOG_AIO=0 -MODULE_WORGOBLIN=0 # 📜 Scripting # Lua/Eluna scripting frameworks and tools # mod-aio: Azeroth Interface Override - enables client-server interface communication -MODULE_AIO=0 -MODULE_ELUNA=1 -MODULE_ELUNA_SCRIPTS=0 -MODULE_ELUNA_TS=0 -MODULE_EVENT_SCRIPTS=0 # 🔧 Admin Tools # Server administration and management utilities -MODULE_ANTIFARMING=0 -MODULE_CARBON_COPY=0 # mod-keep-out: Requires editing database table mod_mko_map_lock; use .gps command to obtain map and zone IDs -MODULE_KEEP_OUT=0 -MODULE_SEND_AND_BIND=0 -MODULE_SERVER_AUTO_SHUTDOWN=0 # mod-spell-regulator: WARNING: Custom code changes mandatory before module functions; requires custom hooks from external gist -MODULE_SPELL_REGULATOR=0 -MODULE_WHO_LOGGED=0 -MODULE_ZONE_CHECK=0 # 💎 Premium/VIP # Premium account and VIP systems -MODULE_ACORE_SUBSCRIPTIONS=0 # mod-premium: Script must be assigned to an item (like hearthstone) using script name 'premium_account' -MODULE_PREMIUM=0 -MODULE_SYSTEM_VIP=0 # 🎮 Mini-Games # Fun and entertainment features -MODULE_AIO_BLACKJACK=0 -MODULE_POCKET_PORTAL=0 # mod-tic-tac-toe: NPC ID: 100155 -MODULE_TIC_TAC_TOE=0 # 🏰 Content # Additional game content and features -MODULE_AZEROTHSHARD=0 -MODULE_BG_SLAVERYVALLEY=0 -MODULE_GUILDHOUSE=0 -MODULE_TREASURE_CHEST_SYSTEM=0 -MODULE_WAR_EFFORT=0 # 🎁 Rewards # Player reward and incentive systems -MODULE_LEVEL_UP_REWARD=0 -MODULE_PRESTIGE_DRAFT_MODE=0 -MODULE_RECRUIT_A_FRIEND=0 # mod-resurrection-scroll: Requires EnablePlayerSettings to be enabled in worldserver config file -MODULE_RESURRECTION_SCROLL=0 -MODULE_REWARD_PLAYED_TIME=0 # 🛠️ Developer Tools # Development and testing utilities -MODULE_SKELETON_MODULE=0 # ===================== # Rebuild automation @@ -452,39 +361,111 @@ KEIRA_DATABASE_HOST=ac-mysql KEIRA_DATABASE_PORT=3306 # Auto-generated defaults for new modules +MODULE_NPCBOT_EXTENDED_COMMANDS=0 +MODULE_OLLAMA_CHAT=0 +MODULE_PLAYERBOTS=0 +MODULE_PLAYER_BOT_LEVEL_BRACKETS=0 +MODULE_AOE_LOOT=0 +MODULE_AUTO_REVIVE=0 +MODULE_FIREWORKS=0 +MODULE_INSTANCE_RESET=0 +MODULE_LEARN_SPELLS=0 +MODULE_SOLO_LFG=0 +MODULE_AUTOBALANCE=0 +MODULE_DUEL_RESET=0 +MODULE_HARDCORE_MODE=0 +MODULE_HORADRIC_CUBE=0 +MODULE_SOLOCRAFT=0 +MODULE_TIME_IS_TIME=0 +MODULE_ASSISTANT=0 +MODULE_NPC_BEASTMASTER=0 +MODULE_NPC_BUFFER=0 +MODULE_NPC_ENCHANTER=0 +MODULE_NPC_FREE_PROFESSIONS=0 +MODULE_NPC_TALENT_TEMPLATE=0 +MODULE_REAGENT_BANK=0 +MODULE_TRANSMOG=0 +MODULE_1V1_ARENA=0 +MODULE_ARENA_REPLAY=0 +MODULE_GAIN_HONOR_GUARD=0 +MODULE_PHASED_DUELS=0 +MODULE_PVP_TITLES=0 +MODULE_ULTIMATE_FULL_LOOT_PVP=0 +MODULE_DYNAMIC_XP=0 +MODULE_INDIVIDUAL_PROGRESSION=0 +MODULE_ITEM_LEVEL_UP=0 +MODULE_PROGRESSION_SYSTEM=0 +MODULE_PROMOTION_AZEROTHCORE=0 +MODULE_WEEKEND_XP=0 +MODULE_ZONE_DIFFICULTY=0 +MODULE_DYNAMIC_TRADER=0 +MODULE_EXCHANGE_NPC=0 +MODULE_GLOBAL_MAIL_BANKING_AUCTIONS=0 +MODULE_LOTTERY_LUA=0 +MODULE_LUA_AH_BOT=0 +MODULE_RANDOM_ENCHANTS=0 +MODULE_ACTIVE_CHAT=0 +MODULE_BOSS_ANNOUNCER=0 +MODULE_BREAKING_NEWS=0 +MODULE_DISCORD_NOTIFIER=0 +MODULE_GLOBAL_CHAT=0 +MODULE_TEMP_ANNOUNCEMENTS=0 +MODULE_ACCOUNTWIDE_SYSTEMS=0 +MODULE_ACCOUNT_ACHIEVEMENTS=0 +MODULE_ACCOUNT_MOUNTS=0 +MODULE_ARAC=0 +MODULE_MORPHSUMMON=0 +MODULE_TRANSMOG_AIO=0 +MODULE_WORGOBLIN=0 +MODULE_AIO=0 +MODULE_ELUNA=1 +MODULE_ELUNA_SCRIPTS=0 +MODULE_ELUNA_TS=0 +MODULE_EVENT_SCRIPTS=0 +MODULE_ANTIFARMING=0 +MODULE_CARBON_COPY=0 +MODULE_KEEP_OUT=0 +MODULE_SEND_AND_BIND=0 +MODULE_SERVER_AUTO_SHUTDOWN=0 +MODULE_SPELL_REGULATOR=0 +MODULE_WHO_LOGGED=0 +MODULE_ZONE_CHECK=0 +MODULE_PREMIUM=0 +MODULE_SYSTEM_VIP=0 +MODULE_AIO_BLACKJACK=0 +MODULE_TIC_TAC_TOE=0 +MODULE_BG_SLAVERYVALLEY=0 +MODULE_GUILDHOUSE=0 +MODULE_TREASURE_CHEST_SYSTEM=0 +MODULE_WAR_EFFORT=0 +MODULE_LEVEL_UP_REWARD=0 +MODULE_PRESTIGE_DRAFT_MODE=0 +MODULE_RECRUIT_A_FRIEND=0 +MODULE_RESURRECTION_SCROLL=0 +MODULE_REWARD_PLAYED_TIME=0 +MODULE_SKELETON_MODULE=0 MODULE_1V1_PVP_SYSTEM=0 -MODULE_ACI=0 -MODULE_ACORE_API=0 MODULE_ACORE_BG_END_ANNOUNCER=0 MODULE_ACORE_BOX=0 -MODULE_ACORE_CLIENT=0 -MODULE_ACORE_CMS=0 MODULE_ACORE_ELUNATEST=0 MODULE_ACORE_LINUX_RESTARTER=0 MODULE_ACORE_LUA_UNLIMITED_AMMO=0 MODULE_ACORE_LXD_IMAGE=0 MODULE_ACORE_MALL=0 MODULE_ACORE_MINI_REG_PAGE=0 -MODULE_ACORE_NODE_SERVER=0 -MODULE_ACORE_PWA=0 MODULE_ACORE_SOD=0 MODULE_ACORE_SUMMONALL=0 -MODULE_ACORE_TILEMAP=0 MODULE_ACORE_ZONEDEBUFF=0 MODULE_ACREBUILD=0 MODULE_ADDON_FACTION_FREE_UNIT_POPUP=0 MODULE_AOE_LOOT_MERGE=0 -MODULE_APAW=0 MODULE_ARENA_SPECTATOR=0 -MODULE_ARENA_STATS=0 -MODULE_ATTRIBOOST=0 MODULE_AUTO_CHECK_RESTART=0 MODULE_AZEROTHCOREADMIN=0 MODULE_AZEROTHCOREDISCORDBOT=0 MODULE_AZEROTHCORE_ADDITIONS=0 MODULE_AZEROTHCORE_ALL_STACKABLES_200=0 MODULE_AZEROTHCORE_ANSIBLE=0 -MODULE_AZEROTHCORE_ARMORY=0 MODULE_AZEROTHCORE_LUA_ARENA_MASTER_COMMAND=0 MODULE_AZEROTHCORE_LUA_DEMON_MORPHER=0 MODULE_AZEROTHCORE_PASSRESET=0 @@ -494,41 +475,25 @@ MODULE_AZEROTHCORE_TRIVIA_SYSTEM=0 MODULE_AZEROTHCORE_WEBSITE=0 MODULE_AZEROTHCORE_WOWHEAD_MOD_LUA=0 MODULE_AZTRAL_AIRLINES=0 -MODULE_BGQUEUECHECKER=0 -MODULE_BG_QUEUE_ABUSER_VIEWER=0 MODULE_BLIZZLIKE_TELES=0 -MODULE_BREAKINGNEWSOVERRIDE=0 MODULE_CLASSIC_MODE=0 MODULE_CODEBASE=0 MODULE_CONFIG_RATES=0 MODULE_DEVJOESTAR=0 -MODULE_ELUNA_WOW_SCRIPTS=0 -MODULE_EXTENDEDXP=0 MODULE_EXTENDED_HOLIDAYS_LUA=0 -MODULE_FFAFIX=0 MODULE_FLAG_CHECKER=0 MODULE_GUILDBANKTABFEEFIXER=0 -MODULE_HARDMODE=0 MODULE_HEARTHSTONE_COOLDOWNS=0 -MODULE_ITEMBROADCASTGUILDCHAT=0 -MODULE_KARGATUM_SYSTEM=0 MODULE_KEIRA3=0 MODULE_LOTTERY_CHANCE_INSTANT=0 MODULE_LUA_AIO_MODRATE_EXP=0 MODULE_LUA_COMMAND_PLUS=0 MODULE_LUA_ITEMUPGRADER_TEMPLATE=0 -MODULE_LUA_NOTONLY_RANDOMMORPHER=0 -MODULE_LUA_PARAGON_ANNIVERSARY=0 MODULE_LUA_PVP_TITLES_RANKING_SYSTEM=0 MODULE_LUA_SCRIPTS=0 -MODULE_LUA_SUPER_BUFFERNPC=0 MODULE_LUA_VIP=0 -MODULE_MOD_ACCOUNTBOUND=0 MODULE_MOD_ACCOUNT_VANITY_PETS=0 -MODULE_MOD_ACTIVATEZONES=0 MODULE_MOD_AH_BOT_PLUS=0 -MODULE_MOD_ALPHA_REWARDS=0 -MODULE_MOD_AOE_LOOT=0 MODULE_MOD_APPRECIATION=0 MODULE_MOD_ARENA_TIGERSPEAK=0 MODULE_MOD_ARENA_TOLVIRON=0 @@ -539,44 +504,29 @@ MODULE_MOD_BG_ITEM_REWARD=0 MODULE_MOD_BG_REWARD=0 MODULE_MOD_BG_TWINPEAKS=0 MODULE_MOD_BIENVENIDA=0 -MODULE_MOD_BLACK_MARKET=0 -MODULE_MOD_BRAWLERS_GUILD=0 MODULE_MOD_BUFF_COMMAND=0 MODULE_MOD_CFPVE=0 -MODULE_MOD_CHANGEABLESPAWNRATES=0 MODULE_MOD_CHARACTER_SERVICES=0 -MODULE_MOD_CHARACTER_TOOLS=0 MODULE_MOD_CHAT_TRANSMITTER=0 MODULE_MOD_CHROMIE_XP=0 MODULE_MOD_CONGRATS_ON_LEVEL=0 MODULE_MOD_COSTUMES=0 MODULE_MOD_CRAFTSPEED=0 MODULE_MOD_CTA_SWITCH=0 -MODULE_MOD_DEAD_MEANS_DEAD=0 MODULE_MOD_DEATHROLL_AIO=0 MODULE_MOD_DEMONIC_PACT_CLASSIC=0 MODULE_MOD_DESERTION_WARNINGS=0 MODULE_MOD_DISCORD_ANNOUNCE=0 -MODULE_MOD_DISCORD_WEBHOOK=0 MODULE_MOD_DMF_SWITCH=0 MODULE_MOD_DUNGEONMASTER=0 -MODULE_MOD_DUNGEON_SCALE=0 -MODULE_MOD_DYNAMIC_LOOT_RATES=0 -MODULE_MOD_DYNAMIC_RESURRECTIONS=0 -MODULE_MOD_ENCOUNTER_LOGS=0 MODULE_MOD_FACTION_FREE=0 -MODULE_MOD_FIRSTLOGIN_AIO=0 MODULE_MOD_FLIGHTMASTER_WHISTLE=0 MODULE_MOD_FORTIS_AUTOBALANCE=0 -MODULE_MOD_GAME_STATE_API=0 MODULE_MOD_GEDDON_BINDING_SHARD=0 MODULE_MOD_GHOST_SPEED=0 -MODULE_MOD_GLOBALCHAT=0 MODULE_MOD_GM_COMMANDS=0 -MODULE_MOD_GOMOVE=0 MODULE_MOD_GROWNUP=0 MODULE_MOD_GUILDFUNDS=0 -MODULE_MOD_GUILD_VILLAGE=0 MODULE_MOD_GUILD_ZONE_SYSTEM=0 MODULE_MOD_HARDCORE=0 MODULE_MOD_HARDCORE_MAKGORA=0 @@ -585,32 +535,21 @@ MODULE_MOD_HIGH_RISK_SYSTEM=0 MODULE_MOD_HUNTER_PET_STORAGE=0 MODULE_MOD_IMPROVED_BANK=0 MODULE_MOD_INCREMENT_CACHE_VERSION=0 -MODULE_MOD_INDIVIDUAL_XP=0 -MODULE_MOD_INFLUXDB=0 -MODULE_MOD_INSTANCE_TOOLS=0 MODULE_MOD_IP2NATION=0 MODULE_MOD_IP_TRACKER=0 -MODULE_MOD_ITEMLEVEL=0 MODULE_MOD_ITEM_UPGRADE=0 MODULE_MOD_JUNK_TO_GOLD=0 MODULE_MOD_LEARNSPELLS=0 -MODULE_MOD_LEECH=0 -MODULE_MOD_LEVEL_15_BOOST=0 MODULE_MOD_LEVEL_ONE_MOUNTS=0 -MODULE_MOD_LEVEL_REWARDS=0 -MODULE_MOD_LOGIN_REWARDS=0 MODULE_MOD_LOW_LEVEL_ARENA=0 MODULE_MOD_LOW_LEVEL_RBG=0 MODULE_MOD_MISSING_OBJECTIVES=0 MODULE_MOD_MONEY_FOR_KILLS=0 MODULE_MOD_MOUNTS_ON_ACCOUNT=0 MODULE_MOD_MOUNT_REQUIREMENTS=0 -MODULE_MOD_MULTI_VENDOR=0 MODULE_MOD_MYTHIC_PLUS=0 -MODULE_MOD_NOCLIP=0 MODULE_MOD_NORDF=0 MODULE_MOD_NOTIFY_MUTED=0 -MODULE_MOD_NO_FARMING=0 MODULE_MOD_NO_HEARTHSTONE_COOLDOWN=0 MODULE_MOD_NPC_ALL_MOUNTS=0 MODULE_MOD_NPC_CODEBOX=0 @@ -620,96 +559,64 @@ MODULE_MOD_NPC_PROMOTION=0 MODULE_MOD_NPC_SERVICES=0 MODULE_MOD_NPC_SPECTATOR=0 MODULE_MOD_NPC_SUBCLASS=0 -MODULE_MOD_OBJSCALE=0 MODULE_MOD_OLLAMA_BOT_BUDDY=0 MODULE_MOD_ONY_NAXX_LOGOUT_TELEPORT=0 MODULE_MOD_PEACEKEEPER=0 MODULE_MOD_PETEQUIP=0 -MODULE_MOD_PREMIUM=0 -MODULE_MOD_PREMIUM_LIB=0 MODULE_MOD_PROFESSION_EXPERIENCE=0 -MODULE_MOD_PROFSPECS=0 MODULE_MOD_PTR_TEMPLATE=0 -MODULE_MOD_PVPSCRIPT=0 MODULE_MOD_PVPSTATS_ANNOUNCER=0 MODULE_MOD_PVP_ZONES=0 MODULE_MOD_QUEST_LOOT_PARTY=0 -MODULE_MOD_QUEST_STATUS=0 MODULE_MOD_QUEUE_LIST_CACHE=0 -MODULE_MOD_QUICKBALANCE=0 MODULE_MOD_QUICK_RESPAWN=0 MODULE_MOD_RACIAL_TRAIT_SWAP=0 -MODULE_MOD_RARE_DROPS=0 MODULE_MOD_RDF_EXPANSION=0 MODULE_MOD_REAL_ONLINE=0 MODULE_MOD_RECRUIT_FRIEND=0 MODULE_MOD_REFORGING=0 MODULE_MOD_RESET_RAID_COOLDOWNS=0 MODULE_MOD_REWARD_PLAYED_TIME_IMPROVED=0 -MODULE_MOD_REWARD_SHOP=0 MODULE_MOD_SELL_ITEMS=0 MODULE_MOD_SETXPBAR=0 -MODULE_MOD_SHARE_MOUNTS=0 -MODULE_MOD_SPAWNPOINTS=0 -MODULE_MOD_SPEC_REWARD=0 -MODULE_MOD_SPELLREGULATOR=0 -MODULE_MOD_SPONSORSHIP=0 MODULE_MOD_STARTER_GUILD=0 MODULE_MOD_STARTER_WANDS=0 -MODULE_MOD_STARTING_PET=0 MODULE_MOD_STREAMS=0 MODULE_MOD_SWIFT_TRAVEL_FORM=0 MODULE_MOD_TALENTBUTTON=0 -MODULE_MOD_TRADE_ITEMS_FILTER=0 MODULE_MOD_TREASURE=0 -MODULE_MOD_TRIAL_OF_FINALITY=0 MODULE_MOD_VANILLA_NAXXRAMAS=0 MODULE_MOD_WARLOCK_PET_RENAME=0 MODULE_MOD_WEAPON_VISUAL=0 MODULE_MOD_WEEKENDBONUS=0 MODULE_MOD_WEEKEND_XP=0 -MODULE_MOD_WHOLOGGED=0 MODULE_MORZA_ISLAND_ARAXIA_SERVER=0 MODULE_MPQ_TOOLS_OSX=0 MODULE_MYSQL_TOOLS=0 -MODULE_NODEROUTER=0 MODULE_OPENPROJECTS=0 -MODULE_PLAYERTELEPORT=0 MODULE_PORTALS_IN_ALL_CAPITALS=0 -MODULE_PRESTIGE=0 -MODULE_PRESTIGIOUS=0 MODULE_PVPSTATS=0 -MODULE_RAIDTELEPORTER=0 MODULE_RECACHE=0 -MODULE_RECYCLEDITEMS=0 -MODULE_REWARD_SYSTEM=0 MODULE_SAHTOUTCMS=0 -MODULE_SERVER_STATUS=0 MODULE_SETXPBAR=0 MODULE_SPELLSCRIPT_REFACTOR_TOOL=0 MODULE_SQL_NPC_TELEPORTER=0 -MODULE_STATBOOSTERREROLLER=0 MODULE_STRAPI_AZEROTHCORE=0 MODULE_TBC_RAID_HP_RESTORATION=0 MODULE_TELEGRAM_AUTOMATED_DB_BACKUP=0 MODULE_TOOL_TC_MIGRATION=0 MODULE_TRANSMOG_ADDONS=0 -MODULE_UPDATE_MOB_LEVEL_TO_PLAYER_AND_RANDOM_ITEM_STATS=0 MODULE_UPDATE_MODULE_CONFS=0 MODULE_WEB_CHARACTER_MIGRATION_TOOL=0 MODULE_WEEKLY_ARMOR_VENDOR_BLACK_MARKET=0 -MODULE_WORLD_BOSS_RANK=0 MODULE_WOWDATABASEEDITOR=0 MODULE_WOWLAUNCHER_DELPHI=0 MODULE_WOWSIMS_TO_COMMANDS=0 -MODULE_WOW_CLIENT_PATCHER=0 MODULE_WOW_ELUNA_TS_MODULE=0 MODULE_WOW_SERVER_RELAY=0 -MODULE_WOW_STATISTICS=0 MODULE_WRATH_OF_THE_VANILLA=0 MODULE_MOD_BOTS_LOGIN_FIX=0 MODULE_MOD_MATERIAL_BANK=0 MODULE_MOD_PROGRESSION_BLIZZLIKE=0 MODULE_MOD_PYTHON_ENGINE=0 MODULE_WRATH_OF_THE_VANILLA_V2=0 -MODULE_AZEROTHMCP=0 diff --git a/scripts/python/modules.py b/scripts/python/modules.py index c016239..fda61c5 100755 --- a/scripts/python/modules.py +++ b/scripts/python/modules.py @@ -371,9 +371,9 @@ def build_state(env_path: Path, manifest_path: Path) -> ModuleCollectionState: for unknown_key in extra_env_modules: warnings.append(f".env defines {unknown_key} but it is missing from the manifest") - # Warn if manifest entry lacks .env toggle + # Warn if manifest entry lacks .env toggle (skip blocked modules) for module in modules: - if module.key not in env_map and module.key not in os.environ: + if not module.blocked and module.key not in env_map and module.key not in os.environ: warnings.append( f"Manifest includes {module.key} but .env does not define it (defaulting to 0)" ) diff --git a/scripts/python/setup_manifest.py b/scripts/python/setup_manifest.py index 6d27b95..470d9e6 100755 --- a/scripts/python/setup_manifest.py +++ b/scripts/python/setup_manifest.py @@ -50,6 +50,9 @@ def clean(value: str) -> str: def cmd_keys(manifest_path: str) -> None: manifest = load_manifest(manifest_path) for entry in iter_modules(manifest): + # Skip blocked modules + if entry.get("status") == "blocked": + continue print(entry["key"]) @@ -96,7 +99,7 @@ def cmd_metadata(manifest_path: str) -> None: def cmd_sorted_keys(manifest_path: str) -> None: manifest = load_manifest(manifest_path) - modules = list(iter_modules(manifest)) + modules = [entry for entry in iter_modules(manifest) if entry.get("status") != "blocked"] modules.sort( key=lambda item: ( # Primary sort by order (default to 5000 if not specified) diff --git a/scripts/python/setup_profiles.py b/scripts/python/setup_profiles.py index 02aae4e..50ff64b 100755 --- a/scripts/python/setup_profiles.py +++ b/scripts/python/setup_profiles.py @@ -28,8 +28,9 @@ def normalize_modules(raw_modules: Iterable[str], profile: Path) -> List[str]: if not value: continue modules.append(value) - if not modules: - raise ValueError(f"Profile {profile.name}: modules list cannot be empty") + # Allow empty modules list for vanilla/minimal profiles + if not modules and "vanilla" not in profile.stem.lower() and "minimal" not in profile.stem.lower(): + raise ValueError(f"Profile {profile.name}: modules list cannot be empty (except for vanilla/minimal profiles)") return modules diff --git a/scripts/python/update_module_manifest.py b/scripts/python/update_module_manifest.py index df646c4..8ef5880 100755 --- a/scripts/python/update_module_manifest.py +++ b/scripts/python/update_module_manifest.py @@ -285,7 +285,7 @@ def collect_repositories( def update_env_template(manifest_path: str, template_path: str) -> bool: - """Update .env.template with missing module variables. + """Update .env.template with module variables for active modules only. Args: manifest_path: Path to the module manifest JSON file @@ -300,14 +300,19 @@ def update_env_template(manifest_path: str, template_path: str) -> bool: if not modules: return False - # Extract all module keys - module_keys = set() + # Extract only active module keys + active_module_keys = set() + disabled_module_keys = set() for module in modules: key = module.get("key") + status = module.get("status", "active") if key: - module_keys.add(key) + if status == "active": + active_module_keys.add(key) + else: + disabled_module_keys.add(key) - if not module_keys: + if not active_module_keys and not disabled_module_keys: return False # Check if template file exists @@ -324,36 +329,66 @@ def update_env_template(manifest_path: str, template_path: str) -> bool: print(f"Error reading .env.template: {exc}") return False - # Find which module variables are missing + # Find which module variables are currently in the template existing_vars = set() - for line in current_lines: - line = line.strip() - if "=" in line and not line.startswith("#"): - var_name = line.split("=", 1)[0].strip() - existing_vars.add(var_name) + current_module_lines = [] + non_module_lines = [] - missing_vars = module_keys - existing_vars - if not missing_vars: - print("✅ All module variables present in .env.template") + for line in current_lines: + stripped = line.strip() + if "=" in stripped and not stripped.startswith("#"): + var_name = stripped.split("=", 1)[0].strip() + if var_name.startswith("MODULE_"): + existing_vars.add(var_name) + current_module_lines.append((var_name, line)) + else: + non_module_lines.append(line) + else: + non_module_lines.append(line) + + # Determine what needs to change + missing_vars = active_module_keys - existing_vars + vars_to_remove = disabled_module_keys & existing_vars + vars_to_keep = active_module_keys & existing_vars + + changes_made = False + + # Report what will be done + if missing_vars: + print(f"📝 Adding {len(missing_vars)} active module variable(s) to .env.template:") + for var in sorted(missing_vars): + print(f" + {var}=0") + changes_made = True + + if vars_to_remove: + print(f"🗑️ Removing {len(vars_to_remove)} disabled module variable(s) from .env.template:") + for var in sorted(vars_to_remove): + print(f" - {var}") + changes_made = True + + if not changes_made: + print("✅ .env.template is up to date with active modules") return False - # Add missing variables to the end of the file - print(f"📝 Adding {len(missing_vars)} missing module variable(s) to .env.template:") + # Build new content: non-module lines + active module lines + new_lines = non_module_lines[:] - # Sort missing vars for consistent output - sorted_missing = sorted(missing_vars) + # Add existing active module variables (preserve their current values) + for var_name, original_line in current_module_lines: + if var_name in vars_to_keep: + new_lines.append(original_line) - # Prepare new content - new_lines = current_lines[:] - for var in sorted_missing: + # Add new active module variables + for var in sorted(missing_vars): new_lines.append(f"{var}=0") - print(f" • {var}=0") # Write updated content try: new_content = "\n".join(new_lines) + "\n" template_file.write_text(new_content, encoding="utf-8") print("✅ .env.template updated successfully") + print(f" Active modules: {len(active_module_keys)}") + print(f" Disabled modules removed: {len(vars_to_remove)}") return True except Exception as exc: print(f"Error writing .env.template: {exc}") @@ -379,11 +414,11 @@ def main(argv: Sequence[str]) -> int: print(f"Updated manifest {args.manifest}: added {added}, refreshed {updated}") - # Update .env.template if requested and we have changes - if not args.skip_template and (added > 0 or updated > 0): + # Update .env.template if requested (always run to clean up disabled modules) + if not args.skip_template: template_updated = update_env_template(args.manifest, args.update_template) if template_updated: - print(f"Updated {args.update_template} with new module variables") + print(f"Updated {args.update_template} with active modules only") return 0 diff --git a/setup.sh b/setup.sh index 93f3033..698be56 100755 --- a/setup.sh +++ b/setup.sh @@ -16,6 +16,12 @@ TEMPLATE_FILE="$SCRIPT_DIR/.env.template" source "$SCRIPT_DIR/scripts/bash/project_name.sh" DEFAULT_PROJECT_NAME="$(project_name::resolve "$ENV_FILE" "$TEMPLATE_FILE")" +# ============================================== +# Feature Flags +# ============================================== +# Set to 0 to disable server configuration preset selection +ENABLE_CONFIG_PRESETS="${ENABLE_CONFIG_PRESETS:-0}" + # ============================================== # Constants (auto-loaded from .env.template) # ============================================== @@ -963,58 +969,65 @@ fi BACKUP_DAILY_TIME=$(ask "Daily backup hour (00-23, UTC)" "${CLI_BACKUP_TIME:-$DEFAULT_BACKUP_TIME}" validate_number) # Server configuration - say HEADER "SERVER CONFIGURATION PRESET" local SERVER_CONFIG_PRESET - if [ -n "$CLI_CONFIG_PRESET" ]; then - SERVER_CONFIG_PRESET="$CLI_CONFIG_PRESET" - say INFO "Using preset from command line: $SERVER_CONFIG_PRESET" + if [ "$ENABLE_CONFIG_PRESETS" = "1" ]; then + say HEADER "SERVER CONFIGURATION PRESET" + + if [ -n "$CLI_CONFIG_PRESET" ]; then + SERVER_CONFIG_PRESET="$CLI_CONFIG_PRESET" + say INFO "Using preset from command line: $SERVER_CONFIG_PRESET" + else + declare -A CONFIG_PRESET_NAMES=() + declare -A CONFIG_PRESET_DESCRIPTIONS=() + declare -A CONFIG_MENU_INDEX=() + local config_dir="$SCRIPT_DIR/config/presets" + local menu_index=1 + + echo "Choose a server configuration preset:" + + if [ -x "$SCRIPT_DIR/scripts/python/parse-config-presets.py" ] && [ -d "$config_dir" ]; then + while IFS=$'\t' read -r preset_key preset_name preset_desc; do + [ -n "$preset_key" ] || continue + CONFIG_PRESET_NAMES["$preset_key"]="$preset_name" + CONFIG_PRESET_DESCRIPTIONS["$preset_key"]="$preset_desc" + CONFIG_MENU_INDEX[$menu_index]="$preset_key" + echo "$menu_index) $preset_name" + echo " $preset_desc" + menu_index=$((menu_index + 1)) + done < <(python3 "$SCRIPT_DIR/scripts/python/parse-config-presets.py" list --presets-dir "$config_dir") + else + # Fallback if parser script not available + CONFIG_MENU_INDEX[1]="none" + CONFIG_PRESET_NAMES["none"]="Default (No Preset)" + CONFIG_PRESET_DESCRIPTIONS["none"]="Use default AzerothCore settings" + echo "1) Default (No Preset)" + echo " Use default AzerothCore settings without any modifications" + fi + + local max_config_option=$((menu_index - 1)) + + if [ "$NON_INTERACTIVE" = "1" ]; then + SERVER_CONFIG_PRESET="none" + say INFO "Non-interactive mode: Using default configuration preset" + else + while true; do + read -p "$(echo -e "${YELLOW}🎯 Select server configuration [1-$max_config_option]: ${NC}")" choice + if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "$max_config_option" ]; then + SERVER_CONFIG_PRESET="${CONFIG_MENU_INDEX[$choice]}" + local chosen_name="${CONFIG_PRESET_NAMES[$SERVER_CONFIG_PRESET]}" + say INFO "Selected: $chosen_name" + break + else + say ERROR "Please select a number between 1 and $max_config_option" + fi + done + fi + fi else - declare -A CONFIG_PRESET_NAMES=() - declare -A CONFIG_PRESET_DESCRIPTIONS=() - declare -A CONFIG_MENU_INDEX=() - local config_dir="$SCRIPT_DIR/config/presets" - local menu_index=1 - - echo "Choose a server configuration preset:" - - if [ -x "$SCRIPT_DIR/scripts/python/parse-config-presets.py" ] && [ -d "$config_dir" ]; then - while IFS=$'\t' read -r preset_key preset_name preset_desc; do - [ -n "$preset_key" ] || continue - CONFIG_PRESET_NAMES["$preset_key"]="$preset_name" - CONFIG_PRESET_DESCRIPTIONS["$preset_key"]="$preset_desc" - CONFIG_MENU_INDEX[$menu_index]="$preset_key" - echo "$menu_index) $preset_name" - echo " $preset_desc" - menu_index=$((menu_index + 1)) - done < <(python3 "$SCRIPT_DIR/scripts/python/parse-config-presets.py" list --presets-dir "$config_dir") - else - # Fallback if parser script not available - CONFIG_MENU_INDEX[1]="none" - CONFIG_PRESET_NAMES["none"]="Default (No Preset)" - CONFIG_PRESET_DESCRIPTIONS["none"]="Use default AzerothCore settings" - echo "1) Default (No Preset)" - echo " Use default AzerothCore settings without any modifications" - fi - - local max_config_option=$((menu_index - 1)) - - if [ "$NON_INTERACTIVE" = "1" ]; then - SERVER_CONFIG_PRESET="none" - say INFO "Non-interactive mode: Using default configuration preset" - else - while true; do - read -p "$(echo -e "${YELLOW}🎯 Select server configuration [1-$max_config_option]: ${NC}")" choice - if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "$max_config_option" ]; then - SERVER_CONFIG_PRESET="${CONFIG_MENU_INDEX[$choice]}" - local chosen_name="${CONFIG_PRESET_NAMES[$SERVER_CONFIG_PRESET]}" - say INFO "Selected: $chosen_name" - break - else - say ERROR "Please select a number between 1 and $max_config_option" - fi - done - fi + # Config presets disabled - use default + SERVER_CONFIG_PRESET="none" + say INFO "Server configuration presets disabled - using default settings" fi local MODE_SELECTION=""