forked from wmantly/mc-bot-town
217 lines
6.3 KiB
JavaScript
217 lines
6.3 KiB
JavaScript
'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; |