forked from wmantly/mc-bot-town
storage
This commit is contained in:
217
nodejs/controller/storage/index.js
Normal file
217
nodejs/controller/storage/index.js
Normal file
@@ -0,0 +1,217 @@
|
||||
'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;
|
||||
Reference in New Issue
Block a user