AI works here
This commit is contained in:
@@ -130,6 +130,17 @@ class Database {
|
||||
)
|
||||
`);
|
||||
|
||||
// Maps table (filled map images)
|
||||
await this.db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS maps (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
map_id INTEGER UNIQUE NOT NULL,
|
||||
image_data TEXT,
|
||||
pixel_data TEXT,
|
||||
captured_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
`);
|
||||
|
||||
// Invite sites table
|
||||
await this.db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS invite_sites (
|
||||
@@ -340,7 +351,7 @@ class Database {
|
||||
`, [excludeId, excludeId]);
|
||||
}
|
||||
|
||||
// Find shulkers containing a specific item (for withdrawal, excludes in-transit)
|
||||
// Find shulkers containing a specific item (for withdrawal, excludes in-transit and special/named items)
|
||||
async findShulkersWithItem(itemName) {
|
||||
return await this.db.all(`
|
||||
SELECT s.*, c.pos_x, c.pos_y, c.pos_z, c.chest_type,
|
||||
@@ -349,6 +360,15 @@ class Database {
|
||||
INNER JOIN chests c ON c.id = s.chest_id
|
||||
INNER JOIN shulker_items si ON si.shulker_id = s.id
|
||||
WHERE si.item_name = ? AND s.slot_count >= 0
|
||||
AND NOT (
|
||||
si.nbt_data IS NOT NULL
|
||||
AND si.nbt_data != 'null'
|
||||
AND (
|
||||
si.nbt_data LIKE '%"displayName"%'
|
||||
OR si.nbt_data LIKE '%"lore"%'
|
||||
OR si.nbt_data LIKE '%"customModelData"%'
|
||||
)
|
||||
)
|
||||
GROUP BY s.id
|
||||
ORDER BY available_count ASC
|
||||
`, [itemName]);
|
||||
@@ -414,12 +434,21 @@ class Database {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get total count of a specific item across all shulkers
|
||||
// Get total count of a specific item across all shulkers (excludes special/named items)
|
||||
async getItemTotalCount(itemName) {
|
||||
const result = await this.db.get(`
|
||||
SELECT SUM(si.count) as total
|
||||
FROM shulker_items si
|
||||
WHERE si.item_name = ?
|
||||
AND NOT (
|
||||
si.nbt_data IS NOT NULL
|
||||
AND si.nbt_data != 'null'
|
||||
AND (
|
||||
si.nbt_data LIKE '%"displayName"%'
|
||||
OR si.nbt_data LIKE '%"lore"%'
|
||||
OR si.nbt_data LIKE '%"customModelData"%'
|
||||
)
|
||||
)
|
||||
`, [itemName]);
|
||||
return result?.total || 0;
|
||||
}
|
||||
@@ -711,6 +740,50 @@ class Database {
|
||||
);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// Maps
|
||||
// ========================================
|
||||
|
||||
async upsertMap(mapId, imageData, pixelData) {
|
||||
return await this.db.run(`
|
||||
INSERT INTO maps (map_id, image_data, pixel_data)
|
||||
VALUES (?, ?, ?)
|
||||
ON CONFLICT(map_id) DO UPDATE SET
|
||||
image_data = excluded.image_data,
|
||||
pixel_data = excluded.pixel_data,
|
||||
captured_at = CURRENT_TIMESTAMP
|
||||
`, [mapId, imageData, pixelData]);
|
||||
}
|
||||
|
||||
async getMap(mapId) {
|
||||
return await this.db.get('SELECT * FROM maps WHERE map_id = ?', [mapId]);
|
||||
}
|
||||
|
||||
async getAllMaps() {
|
||||
return await this.db.all('SELECT id, map_id, image_data, captured_at FROM maps ORDER BY map_id');
|
||||
}
|
||||
|
||||
async deleteMap(mapId) {
|
||||
return await this.db.run('DELETE FROM maps WHERE map_id = ?', [mapId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find filled_map items in shulkers that don't have captured images yet.
|
||||
* Returns items with location info needed to withdraw them.
|
||||
*/
|
||||
async getUncapturedMaps() {
|
||||
return await this.db.all(`
|
||||
SELECT si.*, s.slot as shulker_slot, s.chest_id, s.id as shulker_id,
|
||||
c.pos_x, c.pos_y, c.pos_z
|
||||
FROM shulker_items si
|
||||
INNER JOIN shulkers s ON s.id = si.shulker_id
|
||||
INNER JOIN chests c ON c.id = s.chest_id
|
||||
WHERE si.item_name = 'filled_map'
|
||||
AND s.slot_count >= 0
|
||||
ORDER BY si.id
|
||||
`);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// Stats
|
||||
// ========================================
|
||||
|
||||
Reference in New Issue
Block a user