feat: Add chunk analysis table and enhance world_blocks schema for block state and tags
This commit is contained in:
@@ -145,6 +145,25 @@ export function initializeDatabase() {
|
|||||||
)
|
)
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
// Chunk analysis table (ore density per chunk)
|
||||||
|
db.exec(`
|
||||||
|
CREATE TABLE IF NOT EXISTS chunks (
|
||||||
|
x INTEGER NOT NULL,
|
||||||
|
z INTEGER NOT NULL,
|
||||||
|
analysis TEXT DEFAULT '{}',
|
||||||
|
scanned_at INTEGER NOT NULL,
|
||||||
|
PRIMARY KEY (x, z)
|
||||||
|
)
|
||||||
|
`);
|
||||||
|
|
||||||
|
// Add block_state and block_tags columns to world_blocks if not present
|
||||||
|
try {
|
||||||
|
db.exec(`ALTER TABLE world_blocks ADD COLUMN block_state TEXT DEFAULT '{}'`);
|
||||||
|
} catch (e) { /* column already exists */ }
|
||||||
|
try {
|
||||||
|
db.exec(`ALTER TABLE world_blocks ADD COLUMN block_tags TEXT DEFAULT '{}'`);
|
||||||
|
} catch (e) { /* column already exists */ }
|
||||||
|
|
||||||
// Create indexes for better performance
|
// Create indexes for better performance
|
||||||
db.exec(`
|
db.exec(`
|
||||||
CREATE INDEX IF NOT EXISTS idx_world_blocks_discovered
|
CREATE INDEX IF NOT EXISTS idx_world_blocks_discovered
|
||||||
@@ -156,6 +175,16 @@ export function initializeDatabase() {
|
|||||||
ON task_queue(status, priority DESC);
|
ON task_queue(status, priority DESC);
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
db.exec(`
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_world_blocks_name
|
||||||
|
ON world_blocks(block_name);
|
||||||
|
`);
|
||||||
|
|
||||||
|
db.exec(`
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_chunks_coords
|
||||||
|
ON chunks(x, z);
|
||||||
|
`);
|
||||||
|
|
||||||
console.log('✅ Database initialized');
|
console.log('✅ Database initialized');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,12 +232,14 @@ export function getTurtleConfig(turtleId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// World Blocks
|
// World Blocks
|
||||||
export function saveWorldBlock(x, y, z, blockName, metadata, discoveredBy) {
|
export function saveWorldBlock(x, y, z, blockName, metadata, discoveredBy, blockState = null, blockTags = null) {
|
||||||
const stmt = db.prepare(`
|
const stmt = db.prepare(`
|
||||||
INSERT OR REPLACE INTO world_blocks (x, y, z, block_name, metadata, discovered_by, discovered_at)
|
INSERT OR REPLACE INTO world_blocks (x, y, z, block_name, metadata, discovered_by, discovered_at, block_state, block_tags)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
`);
|
`);
|
||||||
stmt.run(x, y, z, blockName, metadata || 0, discoveredBy, Date.now());
|
stmt.run(x, y, z, blockName, metadata || 0, discoveredBy, Date.now(),
|
||||||
|
blockState ? JSON.stringify(blockState) : '{}',
|
||||||
|
blockTags ? JSON.stringify(blockTags) : '{}');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getWorldBlocks(limit = 10000) {
|
export function getWorldBlocks(limit = 10000) {
|
||||||
@@ -545,5 +576,82 @@ export function closeDatabase() {
|
|||||||
db.close();
|
db.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========== CHUNK ANALYSIS ==========
|
||||||
|
|
||||||
|
export function saveChunkAnalysis(x, z, analysis) {
|
||||||
|
const stmt = db.prepare(`
|
||||||
|
INSERT OR REPLACE INTO chunks (x, z, analysis, scanned_at)
|
||||||
|
VALUES (?, ?, ?, ?)
|
||||||
|
`);
|
||||||
|
stmt.run(x, z, JSON.stringify(analysis), Date.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getChunkAnalysis(x, z) {
|
||||||
|
const stmt = db.prepare('SELECT * FROM chunks WHERE x = ? AND z = ?');
|
||||||
|
const row = stmt.get(x, z);
|
||||||
|
if (row) {
|
||||||
|
return { ...row, analysis: JSON.parse(row.analysis) };
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAllChunkAnalyses() {
|
||||||
|
const stmt = db.prepare('SELECT * FROM chunks');
|
||||||
|
return stmt.all().map(row => ({
|
||||||
|
...row,
|
||||||
|
analysis: JSON.parse(row.analysis)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== BLOCK SEARCH ==========
|
||||||
|
|
||||||
|
export function getBlocksWithNameLike(fromX, fromY, fromZ, toX, toY, toZ, namePattern) {
|
||||||
|
const stmt = db.prepare(`
|
||||||
|
SELECT x, y, z, block_name as name, metadata, block_state, block_tags
|
||||||
|
FROM world_blocks
|
||||||
|
WHERE x BETWEEN ? AND ?
|
||||||
|
AND y BETWEEN ? AND ?
|
||||||
|
AND z BETWEEN ? AND ?
|
||||||
|
AND block_name LIKE ?
|
||||||
|
`);
|
||||||
|
return stmt.all(
|
||||||
|
Math.min(fromX, toX), Math.max(fromX, toX),
|
||||||
|
Math.min(fromY, toY), Math.max(fromY, toY),
|
||||||
|
Math.min(fromZ, toZ), Math.max(fromZ, toZ),
|
||||||
|
namePattern
|
||||||
|
).map(row => ({
|
||||||
|
...row,
|
||||||
|
state: row.block_state ? JSON.parse(row.block_state) : {},
|
||||||
|
tags: row.block_tags ? JSON.parse(row.block_tags) : {},
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getBlock(x, y, z) {
|
||||||
|
const stmt = db.prepare('SELECT block_name as name, metadata, block_state, block_tags FROM world_blocks WHERE x = ? AND y = ? AND z = ?');
|
||||||
|
const row = stmt.get(x, y, z);
|
||||||
|
if (row) {
|
||||||
|
return {
|
||||||
|
...row,
|
||||||
|
state: row.block_state ? JSON.parse(row.block_state) : {},
|
||||||
|
tags: row.block_tags ? JSON.parse(row.block_tags) : {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deleteBlocksInArea(fromX, fromY, fromZ, toX, toY, toZ) {
|
||||||
|
const stmt = db.prepare(`
|
||||||
|
DELETE FROM world_blocks
|
||||||
|
WHERE x BETWEEN ? AND ?
|
||||||
|
AND y BETWEEN ? AND ?
|
||||||
|
AND z BETWEEN ? AND ?
|
||||||
|
`);
|
||||||
|
return stmt.run(
|
||||||
|
Math.min(fromX, toX), Math.max(fromX, toX),
|
||||||
|
Math.min(fromY, toY), Math.max(fromY, toY),
|
||||||
|
Math.min(fromZ, toZ), Math.max(fromZ, toZ)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Export database instance for custom queries if needed
|
// Export database instance for custom queries if needed
|
||||||
export { db };
|
export { db };
|
||||||
|
|||||||
Reference in New Issue
Block a user