'use strict'; const Database = require('./database'); const Scanner = require('./scanner'); const Organizer = require('./organizer'); const WebServer = require('./web'); class Storage { constructor(args) { console.log('Storage: Constructor called'); this.bot = args.bot; this.config = args; this.isReady = false; this.webServer = null; } init() { console.log('Storage: init() called'); return new Promise((resolve, reject) => { this.bot.on('onReady', async () => { try { console.log(`Storage: Bot ${this.bot.name} is ready, initializing storage system...`); // Initialize database if (!Database.db) { console.log('Storage: Initializing database...'); await Database.initialize(this.config.dbFile || './storage/storage.db'); } else { console.log('Storage: Database already initialized'); } // Initialize scanner and organizer console.log('Storage: Creating Scanner and Organizer...'); this.scanner = new Scanner(); this.organizer = new Organizer(); // Start web server console.log('Storage: Starting web server...'); this.webServer = new WebServer(); await this.webServer.start(this.bot); if (this.config.startupTasks) { console.log('Storage: Running startup tasks...'); await this.config.startupTasks(); } this.isReady = true; console.log('Storage: Initialization complete! Ready to use.'); resolve(); } catch (error) { console.error('Storage: Error in init:', error); reject(error); } }); }); } async unload(keepDb = false) { console.log('Storage: Unloading...'); if (this.webServer) { console.log('Storage: Stopping web server...'); await this.webServer.close(); this.webServer = null; } if (this.scanner) delete this.scanner; if (this.organizer) delete this.organizer; // Close database only if not keeping it for web server if (!keepDb && Database.db) { console.log('Storage: Closing database...'); Database.close(); } this.isReady = false; console.log('Storage: Unload complete'); } async scanArea(force = false) { const { sleep } = require('../../utils'); console.log(`Storage[${this.bot.name}]: Scanning storage area...`); const chests = await this.scanner.discoverChests(this.bot, this.config.scanRadius || 30, Database); const shulkers = await this.scanner.scanAllChests(this.bot, Database); console.log(`Storage[${this.bot.name}]: Complete - ${chests.length} chests, ${shulkers} shulkers`); } async handleTrade(playerName, itemsReceived) { const { sleep } = require('../../utils'); console.log(`Storage[${this.bot.name}]: Processing trade from ${playerName}, received ${itemsReceived.length} item types`); // Log trade await Database.logTrade(playerName, 'deposit', itemsReceived); // Store items let totalItems = 0; for (const item of itemsReceived) { totalItems += item.count; } console.log(`Storage[${this.bot.name}]: Sorting ${totalItems} items from ${playerName}`); } async handleWithdrawRequest(playerName, itemId, count) { console.log(`Storage[${this.bot.name}]: Withdraw request from ${playerName}: ${itemId} x${count}`); // Search for item const items = await Database.searchItems(itemId); if (!items || items.length === 0) { return this.bot.whisper(playerName, `Item not found: ${itemId}`); } const item = items[0]; if (item.total_count < count) { return this.bot.whisper(playerName, `Not enough ${item.item_name}. Available: ${item.total_count}`); } // Queue withdrawal await Database.queueWithdrawal(playerName, itemId, item.item_name, count); this.bot.whisper(playerName, `Withdrawal queued. Use /trade when ready.`); } async getStatus(playerName) { const stats = await Database.getStats(); this.bot.whisper(playerName, `Storage: ${stats.totalItems} items in ${stats.totalShulkers} shulkers (${stats.totalChests} chests)`); } async findItem(itemName) { return await Database.searchItems(itemName); } async checkPermission(name, requiredRole) { return await Database.checkPermission(name, requiredRole); } // Command handler for in-game commands async handleCommand(from, command, ...args) { console.log(`Storage: Command '${command}' from ${from} with args:`, args); switch (command) { case 'scan': this.bot.whisper(from, 'Starting storage scan...'); try { await this.scanArea(true); const stats = await Database.getStats(); this.bot.whisper(from, `Scan complete! ${stats.totalChests} chests, ${stats.totalShulkers} shulkers, ${stats.totalItems} items`); } catch (error) { console.error('Storage: Scan error:', error); this.bot.whisper(from, `Scan failed: ${error.message}`); } break; case 'status': await this.getStatus(from); break; case 'withdraw': const [itemName, count] = args; await this.handleWithdrawRequest(from, itemName, count); break; case 'find': const [searchTerm] = args; const items = await this.findItem(searchTerm); if (items.length === 0) { this.bot.whisper(from, `No items found matching '${searchTerm}'`); } else { const results = items.slice(0, 5).map(i => `${i.item_name}: ${i.total_count}`); this.bot.whisper(from, `Found: ${results.join(', ')}`); } break; case 'chests': const chests = await Database.getChests(); this.bot.whisper(from, `Tracking ${chests.length} chests`); break; case 'organize': this.bot.whisper(from, 'Organize not yet implemented'); break; case 'addplayer': const [playerName, role] = args; try { await Database.addPlayer(playerName, role || 'team'); this.bot.whisper(from, `Added ${playerName} as ${role || 'team'}`); } catch (error) { this.bot.whisper(from, `Failed to add player: ${error.message}`); } break; case 'removeplayer': const [removePlayer] = args; try { await Database.removePlayer(removePlayer); this.bot.whisper(from, `Removed ${removePlayer}`); } catch (error) { this.bot.whisper(from, `Failed to remove player: ${error.message}`); } break; case 'players': const players = await Database.getAllPlayers(); const playerList = players.map(p => `${p.player_name}(${p.role})`).join(', '); this.bot.whisper(from, `Players: ${playerList}`); break; default: this.bot.whisper(from, `Unknown command: ${command}`); } } } module.exports = Storage;