{
  "name": "serverModuleCloner",
  "author": "limon",
  "supportedGames": [
    "all"
  ],
  "takaroVersion": "v0.0.29",
  "versions": [
    {
      "tag": "latest",
      "description": "# Module Importer: Cross-Server Module Configuration Replication\n\n---\n🎥 **SETUP TUTORIAL**  \n**[► Watch the Complete Guide](https://youtu.be/7-7yn8cQ3Qw)**  \n*Learn how to replicate module configurations between servers*\n---\n\nThe **Module Importer** provides administrators with a powerful tool to replicate module configurations from one server to another. This administrative Takaro module streamlines server setup by copying all installed modules and their exact configurations from a source server, making it ideal for maintaining consistency across multiple game servers or quickly deploying tested configurations.\n\n## Key Benefits:\n- **Time-Saving Setup**: Instantly replicate complex module configurations instead of manual setup\n- **Configuration Consistency**: Ensure identical module setups across multiple servers\n- **Template Server Approach**: Use one server as a master template for others\n- **Exact Configuration Copying**: Preserves both system and user configurations precisely\n- **Administrative Control**: Manual execution prevents accidental triggers\n\n## Features:\n* Manual execution through module builder for controlled deployment\n* Copies all installed modules from specified source server\n* Preserves exact user and system configurations\n* Updates existing modules with source server settings\n* Installs new modules that don't exist on target server\n* Detailed logging of installation, update, and skip operations\n* Source server identification via gameserver ID from dashboard URL\n* Built specifically for administrative use outside of gameplay\n* Progress tracking with comprehensive operation reporting\n\n## Important Notes:\n* Best used between servers running the same game type\n* Cross-game compatibility may cause issues with game-specific configurations\n* Requires administrator knowledge of module management\n* Manual trigger recommended for careful timing and control",
      "configSchema": "{\"$schema\":\"http://json-schema.org/draft-07/schema#\",\"type\":\"object\",\"required\":[],\"additionalProperties\":false,\"properties\":{\"sourceServerId\":{\"title\":\"sourceServerId\",\"description\":\"The ID of the server to copy modules from\\n\",\"type\":\"string\"}}}",
      "uiSchema": "{}",
      "commands": [],
      "hooks": [],
      "cronJobs": [
        {
          "name": "my-cronjob",
          "temporalValue": "5 4 * * *",
          "description": "",
          "function": "// cronJobs/copyModules.js\nimport { takaro, data } from '@takaro/helpers';\n\nasync function main() {\n    const { gameServerId, module: mod } = data;\n\n    // Get source server details from config\n    const sourceServerId = mod.userConfig.sourceServerId;\n\n    if (!sourceServerId) {\n        console.log('Module Copier: Source server ID not configured, skipping.');\n        return;\n    }\n\n    console.log(`Module Copier: Starting module copy from server ${sourceServerId} to server ${gameServerId}...`);\n\n    try {\n        // Get all modules from source server\n        const sourceModulesResponse = await takaro.module.moduleInstallationsControllerGetInstalledModules({\n            filters: {\n                gameserverId: [sourceServerId]\n            }\n        });\n\n        // Check if we got any modules back\n        if (!sourceModulesResponse.data.data || sourceModulesResponse.data.data.length === 0) {\n            console.log(`Module Copier: No modules found on source server ${sourceServerId}. Please check if the server ID is correct.`);\n            return;\n        }\n\n        // Use all modules regardless of enabled status\n        const sourceModules = sourceModulesResponse.data.data;\n\n        console.log(`Module Copier: Found ${sourceModules.length} modules on source server ${sourceServerId}. Starting to copy...`);\n\n        // Get modules installed on target server\n        const targetModules = await takaro.module.moduleInstallationsControllerGetInstalledModules({\n            filters: { gameserverId: [gameServerId] }\n        });\n\n        // Create lookup map for faster access\n        const existingModuleMap = {};\n        if (targetModules.data.data) {\n            targetModules.data.data.forEach(module => {\n                existingModuleMap[module.moduleId] = module;\n            });\n        }\n\n        // Track progress\n        let installed = 0;\n        let updated = 0;\n        let skipped = 0;\n\n        // Process each module from source server\n        for (const sourceModule of sourceModules) {\n            try {\n                const { moduleId, versionId, systemConfig, userConfig } = sourceModule;\n                const moduleName = sourceModule.module?.name || \"Unknown Module\";\n\n                console.log(`Module Copier: Processing module ${moduleName} (${moduleId})`);\n\n                // Check if module already exists on target server\n                if (existingModuleMap[moduleId]) {\n                    try {\n                        // Only function we know works\n                        await takaro.module.moduleInstallationsControllerInstallModule({\n                            versionId: versionId,\n                            gameServerId: gameServerId,\n                            moduleId: moduleId,\n                            // Copy configs as JSON strings\n                            systemConfig: typeof systemConfig === 'string' ? systemConfig : JSON.stringify(systemConfig || {}),\n                            userConfig: typeof userConfig === 'string' ? userConfig : JSON.stringify(userConfig || {})\n                        });\n\n                        updated++;\n                        console.log(`Module Copier: Updated module: ${moduleName}`);\n                    } catch (updateError) {\n                        console.log(`Module Copier: Error updating module ${moduleName}: ${updateError.message}`);\n                        skipped++;\n                    }\n                } else {\n                    try {\n                        // For new installations, don't include moduleId:\n                        await takaro.module.moduleInstallationsControllerInstallModule({\n                            versionId: versionId,\n                            gameServerId: gameServerId,\n                            // Remove moduleId parameter\n                            systemConfig: typeof systemConfig === 'string' ? systemConfig : JSON.stringify(systemConfig || {}),\n                            userConfig: typeof userConfig === 'string' ? userConfig : JSON.stringify(userConfig || {})\n                        }); installed++;\n                        console.log(`Module Copier: Installed module: ${moduleName}`);\n                    } catch (installError) {\n                        console.log(`Module Copier: Error installing module ${moduleName}: ${installError.message}`);\n                        skipped++;\n                    }\n                }\n            } catch (error) {\n                skipped++;\n                const moduleName = sourceModule.module?.name || \"Unknown Module\";\n                console.log(`Module Copier: Error processing module ${moduleName}: ${error.message}`);\n            }\n        }\n\n        console.log(`Module Copier: Module copy completed! Installed: ${installed}, Updated: ${updated}, Skipped: ${skipped}`);\n    } catch (error) {\n        console.log(`Module Copier: Error copying modules: ${error.message}`);\n    }\n}\n\nawait main();"
        }
      ],
      "functions": [],
      "permissions": []
    }
  ]
}