forked from wmantly/mc-bot-town
242 lines
6.2 KiB
JavaScript
242 lines
6.2 KiB
JavaScript
'use strict';
|
|
|
|
const path = require('path');
|
|
const sqlite3 = require('sqlite3').verbose();
|
|
const { open } = require('sqlite');
|
|
|
|
const target = process.argv[2];
|
|
const dbPath = path.resolve(__dirname, '..', 'storage', 'storage.db');
|
|
|
|
const GROUPS = {
|
|
all: {
|
|
tables: ['shulker_items', 'chest_loose_items', 'shulkers', 'chests',
|
|
'item_index', 'trades', 'invite_permissions', 'invite_sites',
|
|
'maps', 'permissions'],
|
|
label: 'ALL tables'
|
|
},
|
|
storage: {
|
|
tables: ['shulker_items', 'chest_loose_items', 'shulkers', 'chests', 'item_index'],
|
|
label: 'storage tables (chests, shulkers, items, index)'
|
|
},
|
|
permissions: {
|
|
tables: ['permissions'],
|
|
label: 'permissions table'
|
|
},
|
|
maps: {
|
|
tables: ['maps'],
|
|
label: 'maps table'
|
|
},
|
|
invites: {
|
|
tables: ['invite_permissions', 'invite_sites'],
|
|
label: 'invite tables'
|
|
},
|
|
trades: {
|
|
tables: ['trades'],
|
|
label: 'trades table'
|
|
}
|
|
};
|
|
|
|
function usage() {
|
|
console.log('Usage: node scripts/db-reset.js <target>');
|
|
console.log('Targets:');
|
|
for (const [name, group] of Object.entries(GROUPS)) {
|
|
console.log(` ${name.padEnd(14)} ${group.label}`);
|
|
}
|
|
process.exit(1);
|
|
}
|
|
|
|
if (!target || !GROUPS[target]) {
|
|
usage();
|
|
}
|
|
|
|
const group = GROUPS[target];
|
|
|
|
async function main() {
|
|
console.log(`Database: ${dbPath}`);
|
|
console.log(`Resetting ${group.label}...`);
|
|
|
|
const db = await open({
|
|
filename: dbPath,
|
|
driver: sqlite3.Database
|
|
});
|
|
|
|
try {
|
|
await db.run('PRAGMA foreign_keys = OFF');
|
|
|
|
for (const table of group.tables) {
|
|
console.log(` DROP TABLE IF EXISTS ${table}`);
|
|
await db.run(`DROP TABLE IF EXISTS ${table}`);
|
|
}
|
|
|
|
await db.run('PRAGMA foreign_keys = ON');
|
|
|
|
// Recreate tables and re-insert defaults
|
|
await recreateTables(db, group);
|
|
|
|
console.log('Done.');
|
|
} finally {
|
|
await db.close();
|
|
}
|
|
}
|
|
|
|
async function recreateTables(db, group) {
|
|
const tables = group.tables;
|
|
const recreate = (t) => tables.includes(t);
|
|
|
|
if (recreate('permissions')) {
|
|
await db.exec(`CREATE TABLE permissions (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
player_name TEXT UNIQUE NOT NULL,
|
|
role TEXT DEFAULT 'team' NOT NULL CHECK(role IN ('owner', 'team', 'readonly')),
|
|
joined_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)`);
|
|
console.log(' Recreated permissions');
|
|
await insertDefaultPermissions(db);
|
|
}
|
|
|
|
if (recreate('chests')) {
|
|
await db.exec(`CREATE TABLE chests (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
pos_x INTEGER NOT NULL,
|
|
pos_y INTEGER NOT NULL,
|
|
pos_z INTEGER NOT NULL,
|
|
chest_type TEXT NOT NULL CHECK(chest_type IN ('single', 'double')),
|
|
row INTEGER NOT NULL,
|
|
column INTEGER NOT NULL,
|
|
category TEXT,
|
|
last_scan TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
UNIQUE(pos_x, pos_y, pos_z)
|
|
)`);
|
|
console.log(' Recreated chests');
|
|
}
|
|
|
|
if (recreate('shulkers')) {
|
|
await db.exec(`CREATE TABLE shulkers (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
chest_id INTEGER NOT NULL,
|
|
slot INTEGER NOT NULL,
|
|
shulker_type TEXT DEFAULT 'shulker_box',
|
|
category TEXT,
|
|
item_focus TEXT,
|
|
slot_count INTEGER DEFAULT 0,
|
|
total_items INTEGER DEFAULT 0,
|
|
last_scan TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (chest_id) REFERENCES chests(id) ON DELETE CASCADE,
|
|
UNIQUE(chest_id, slot)
|
|
)`);
|
|
console.log(' Recreated shulkers');
|
|
}
|
|
|
|
if (recreate('shulker_items')) {
|
|
await db.exec(`CREATE TABLE shulker_items (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
shulker_id INTEGER NOT NULL,
|
|
item_name TEXT NOT NULL,
|
|
item_id INTEGER NOT NULL,
|
|
slot INTEGER NOT NULL,
|
|
count INTEGER NOT NULL,
|
|
nbt_data TEXT,
|
|
FOREIGN KEY (shulker_id) REFERENCES shulkers(id) ON DELETE CASCADE,
|
|
UNIQUE(shulker_id, slot),
|
|
CHECK(slot >= 0 AND slot <= 26),
|
|
CHECK(count > 0 AND count <= 64)
|
|
)`);
|
|
console.log(' Recreated shulker_items');
|
|
}
|
|
|
|
if (recreate('trades')) {
|
|
await db.exec(`CREATE TABLE trades (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
player_name TEXT NOT NULL,
|
|
action TEXT NOT NULL CHECK(action IN ('deposit', 'withdraw')),
|
|
items TEXT NOT NULL,
|
|
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)`);
|
|
console.log(' Recreated trades');
|
|
}
|
|
|
|
if (recreate('chest_loose_items')) {
|
|
await db.exec(`CREATE TABLE chest_loose_items (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
chest_id INTEGER NOT NULL,
|
|
slot INTEGER NOT NULL,
|
|
item_name TEXT NOT NULL,
|
|
item_id INTEGER NOT NULL,
|
|
count INTEGER NOT NULL,
|
|
FOREIGN KEY (chest_id) REFERENCES chests(id) ON DELETE CASCADE,
|
|
UNIQUE(chest_id, slot)
|
|
)`);
|
|
console.log(' Recreated chest_loose_items');
|
|
}
|
|
|
|
if (recreate('item_index')) {
|
|
await db.exec(`CREATE TABLE item_index (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
item_id INTEGER UNIQUE NOT NULL,
|
|
item_name TEXT NOT NULL,
|
|
total_count INTEGER DEFAULT 0,
|
|
shulker_ids TEXT,
|
|
last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)`);
|
|
console.log(' Recreated item_index');
|
|
}
|
|
|
|
if (recreate('maps')) {
|
|
await db.exec(`CREATE TABLE maps (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
map_id INTEGER UNIQUE NOT NULL,
|
|
image_data TEXT,
|
|
pixel_data TEXT,
|
|
captured_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)`);
|
|
console.log(' Recreated maps');
|
|
}
|
|
|
|
if (recreate('invite_sites')) {
|
|
await db.exec(`CREATE TABLE invite_sites (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT UNIQUE NOT NULL,
|
|
label TEXT NOT NULL,
|
|
bot_name TEXT NOT NULL,
|
|
description TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)`);
|
|
console.log(' Recreated invite_sites');
|
|
}
|
|
|
|
if (recreate('invite_permissions')) {
|
|
await db.exec(`CREATE TABLE invite_permissions (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
site_id INTEGER NOT NULL,
|
|
player_name TEXT NOT NULL,
|
|
FOREIGN KEY (site_id) REFERENCES invite_sites(id) ON DELETE CASCADE,
|
|
UNIQUE(site_id, player_name)
|
|
)`);
|
|
console.log(' Recreated invite_permissions');
|
|
}
|
|
}
|
|
|
|
async function insertDefaultPermissions(db) {
|
|
const conf = require('../conf/base');
|
|
const defaultPlayers = conf.storage?.defaultPlayers || [];
|
|
|
|
for (const player of defaultPlayers) {
|
|
try {
|
|
await db.run(
|
|
'INSERT OR IGNORE INTO permissions (player_name, role) VALUES (?, ?)',
|
|
[player.name, player.role]
|
|
);
|
|
} catch (e) {
|
|
console.error(` Error inserting ${player.name}:`, e.message);
|
|
}
|
|
}
|
|
if (defaultPlayers.length > 0) {
|
|
console.log(` Inserted ${defaultPlayers.length} default players`);
|
|
}
|
|
}
|
|
|
|
main().catch(err => {
|
|
console.error('Fatal:', err);
|
|
process.exit(1);
|
|
});
|