144 lines
4.6 KiB
JavaScript
144 lines
4.6 KiB
JavaScript
'use strict';
|
|
|
|
// Require log-web early to capture all console output from other modules
|
|
const LogWeb = require('./log-web');
|
|
|
|
const {sleep} = require('../utils');
|
|
const conf = require('../conf');
|
|
const {CJbot} = require('../model/minecraft');
|
|
|
|
const commands = require('./commands');
|
|
|
|
CJbot.pluginAdd(require('./swing'));
|
|
CJbot.pluginAdd(require('./craft'));
|
|
CJbot.pluginAdd(require('./tp'));
|
|
CJbot.pluginAdd(require('./ai'));
|
|
CJbot.pluginAdd(require('./guardianFarm'));
|
|
CJbot.pluginAdd(require('./goldFarm'));
|
|
CJbot.pluginAdd(require('./storage'));
|
|
CJbot.pluginAdd(require('./auto-eat'));
|
|
CJbot.pluginAdd(require('./farm-supply'));
|
|
CJbot.pluginAdd(require('./commands/navigation'));
|
|
|
|
for(let name in conf.mc.bots){
|
|
if(CJbot.bots[name]) continue;
|
|
let bot = new CJbot({name, host: conf.mc.host, ...conf.mc.bots[name]});
|
|
CJbot.bots[name] = bot;
|
|
|
|
for(let command of conf.mc.bots[name].commands || ['default']){
|
|
for(let [name, toAdd] of Object.entries(commands[command])){
|
|
bot.addCommand(name, toAdd)
|
|
}
|
|
}
|
|
}
|
|
|
|
const Database = require('./storage/database');
|
|
const SettingsManager = require('./settings/manager');
|
|
|
|
// Start web server immediately — it serves static/web routes independently of bot state
|
|
const webServer = require('./web-server');
|
|
const ActivityWeb = require('./activity-web');
|
|
const ChatWeb = require('./chat-web');
|
|
const InvitePlugin = require('./invite');
|
|
webServer.queuePlugin(ChatWeb);
|
|
webServer.queuePlugin(ActivityWeb);
|
|
webServer.queuePlugin(LogWeb);
|
|
webServer.queuePlugin(InvitePlugin);
|
|
const SettingsWeb = require('./settings/web');
|
|
webServer.queuePlugin(SettingsWeb);
|
|
webServer.start().catch(err => console.error('Failed to start web server:', err));
|
|
|
|
async function initDatabase() {
|
|
if (Database.db) return;
|
|
|
|
await Database.initialize(conf.storage.dbPath || './storage/storage.db');
|
|
console.log('DB initialized');
|
|
|
|
// Seed settings defaults (INSERT OR IGNORE — won't overwrite user changes)
|
|
const registry = SettingsManager.getRegistry();
|
|
const seedDefaults = registry.map(r => {
|
|
const parts = r.key.split('.');
|
|
let node = conf;
|
|
for (const p of parts) node = node?.[p];
|
|
|
|
let value = '';
|
|
if (node !== undefined && node !== null) {
|
|
if (r.key === 'ai.prompts' && typeof node === 'object') {
|
|
const templates = {};
|
|
for (const [name, fn] of Object.entries(node)) {
|
|
if (typeof fn === 'function') {
|
|
const fnStr = fn.toString();
|
|
const m = fnStr.match(/=>\s*`([\s\S]*)`\s*$/);
|
|
templates[name] = m ? m[1] : '';
|
|
}
|
|
}
|
|
value = JSON.stringify(templates);
|
|
} else if (r.type === 'json') {
|
|
value = JSON.stringify(node);
|
|
} else {
|
|
value = String(node);
|
|
}
|
|
}
|
|
|
|
return { key: r.key, value, type: r.type, category: r.category, label: r.label, description: r.description };
|
|
});
|
|
await Database.seedDefaultSettings(seedDefaults);
|
|
|
|
// Initialize settings cache from DB
|
|
await SettingsManager.initialize();
|
|
|
|
// Seed per-bot settings from config defaults
|
|
await Database.seedDefaultBotSettings();
|
|
|
|
// Apply DB-stored bot settings to live bot instances
|
|
for (const [botName, bot] of Object.entries(CJbot.bots)) {
|
|
try {
|
|
const rows = await Database.getAllBotSettings(botName);
|
|
for (const row of rows) {
|
|
let val = row.value;
|
|
if (row.type === 'number') val = Number(val) || 0;
|
|
else if (row.type === 'boolean') val = val === 'true';
|
|
else if (row.type === 'json') { try { val = JSON.parse(val); } catch (e) { val = null; } }
|
|
|
|
switch (row.key) {
|
|
case 'username': if (val) bot.username = val; break;
|
|
case 'password': if (val) bot.password = val; break;
|
|
case 'auth': if (val) bot.auth = val; break;
|
|
case 'autoConnect': bot.autoConnect = val; break;
|
|
case 'autoReConnect': bot.autoReConnect = val; break;
|
|
case 'onDemand': bot.onDemand = val; break;
|
|
case 'idleTimeout': bot._idleTimeout = Number(val) || 30000; break;
|
|
case 'commands': bot._dbCommands = val; break;
|
|
case 'plugins': bot.pluginsWanted = val || {}; break;
|
|
case 'hasAi': bot.hasAi = val; break;
|
|
}
|
|
}
|
|
console.log(`Applied DB settings for ${botName}`);
|
|
} catch (e) { /* bot may not exist in DB yet */ }
|
|
}
|
|
|
|
if (conf.invite?.seedSites) {
|
|
await Database.seedInviteSites(conf.invite.seedSites);
|
|
console.log('Invite sites seeded');
|
|
}
|
|
}
|
|
|
|
(async () => {
|
|
try {
|
|
// DB and settings must be ready before bots connect, so Storage
|
|
// constructors always see the correct DB-stored config values.
|
|
await initDatabase();
|
|
|
|
for (let name in CJbot.bots) {
|
|
const bot = CJbot.bots[name];
|
|
if (bot.autoConnect) {
|
|
console.log('Trying to connect', name);
|
|
console.log('Status for', name, await bot.connect());
|
|
await sleep(30000);
|
|
}
|
|
}
|
|
} catch (e) {
|
|
console.log('!!!!!!!! error:', e);
|
|
}
|
|
})();
|