AI works here

This commit is contained in:
2026-04-30 12:48:29 -04:00
parent 92024c8a64
commit 6f4519894b
16 changed files with 1793 additions and 303 deletions
+75 -2
View File
@@ -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
// ========================================