A modern web interface for Luanti (Minetest) server management with ContentDB integration. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
127 lines
3.2 KiB
JavaScript
127 lines
3.2 KiB
JavaScript
const fs = require('fs').promises;
|
|
const fsSync = require('fs');
|
|
const path = require('path');
|
|
const os = require('os');
|
|
|
|
class AppConfig {
|
|
constructor() {
|
|
this.configDir = path.join(os.homedir(), '.luhost');
|
|
this.configFile = path.join(this.configDir, 'config.json');
|
|
this.defaultConfig = {
|
|
dataDirectory: this.getDefaultDataDirectory(),
|
|
serverPort: 3000,
|
|
debugMode: false
|
|
};
|
|
this.config = null;
|
|
}
|
|
|
|
getDefaultDataDirectory() {
|
|
const homeDir = os.homedir();
|
|
const possibleDirs = [
|
|
path.join(homeDir, '.luanti'),
|
|
path.join(homeDir, '.minetest')
|
|
];
|
|
|
|
// Use the first one that exists, or default to .minetest
|
|
for (const dir of possibleDirs) {
|
|
if (fsSync.existsSync(dir)) {
|
|
return dir;
|
|
}
|
|
}
|
|
|
|
return path.join(homeDir, '.minetest');
|
|
}
|
|
|
|
async load() {
|
|
try {
|
|
// Ensure config directory exists
|
|
if (!fsSync.existsSync(this.configDir)) {
|
|
await fs.mkdir(this.configDir, { recursive: true });
|
|
}
|
|
|
|
// Try to read existing config
|
|
try {
|
|
const configData = await fs.readFile(this.configFile, 'utf8');
|
|
this.config = { ...this.defaultConfig, ...JSON.parse(configData) };
|
|
} catch (error) {
|
|
if (error.code === 'ENOENT') {
|
|
// Config file doesn't exist, create it with defaults
|
|
this.config = { ...this.defaultConfig };
|
|
await this.save();
|
|
} else {
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
return this.config;
|
|
} catch (error) {
|
|
console.error('Failed to load app config:', error);
|
|
// Fall back to defaults if config loading fails
|
|
this.config = { ...this.defaultConfig };
|
|
return this.config;
|
|
}
|
|
}
|
|
|
|
async save() {
|
|
try {
|
|
if (!fsSync.existsSync(this.configDir)) {
|
|
await fs.mkdir(this.configDir, { recursive: true });
|
|
}
|
|
|
|
await fs.writeFile(this.configFile, JSON.stringify(this.config, null, 2), 'utf8');
|
|
} catch (error) {
|
|
console.error('Failed to save app config:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
get(key) {
|
|
return this.config ? this.config[key] : this.defaultConfig[key];
|
|
}
|
|
|
|
set(key, value) {
|
|
if (!this.config) {
|
|
this.config = { ...this.defaultConfig };
|
|
}
|
|
this.config[key] = value;
|
|
}
|
|
|
|
async update(updates) {
|
|
if (!this.config) {
|
|
this.config = { ...this.defaultConfig };
|
|
}
|
|
|
|
Object.assign(this.config, updates);
|
|
await this.save();
|
|
}
|
|
|
|
getDataDirectory() {
|
|
return this.get('dataDirectory');
|
|
}
|
|
|
|
async setDataDirectory(dataDir) {
|
|
const resolvedPath = path.resolve(dataDir);
|
|
|
|
// Validate that the directory exists or can be created
|
|
try {
|
|
await fs.access(resolvedPath);
|
|
} catch (error) {
|
|
if (error.code === 'ENOENT') {
|
|
// Try to create the directory
|
|
try {
|
|
await fs.mkdir(resolvedPath, { recursive: true });
|
|
} catch (createError) {
|
|
throw new Error(`Cannot create data directory: ${createError.message}`);
|
|
}
|
|
} else {
|
|
throw new Error(`Cannot access data directory: ${error.message}`);
|
|
}
|
|
}
|
|
|
|
this.set('dataDirectory', resolvedPath);
|
|
await this.save();
|
|
return resolvedPath;
|
|
}
|
|
}
|
|
|
|
module.exports = new AppConfig(); |