Initial commit: LuHost - Luanti Server Management Web Interface
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>
This commit is contained in:
125
utils/config-parser.js
Normal file
125
utils/config-parser.js
Normal file
@@ -0,0 +1,125 @@
|
||||
const fs = require('fs').promises;
|
||||
const path = require('path');
|
||||
|
||||
class ConfigParser {
|
||||
static async parseConfig(filePath) {
|
||||
try {
|
||||
const content = await fs.readFile(filePath, 'utf8');
|
||||
const config = {};
|
||||
|
||||
const lines = content.split('\n');
|
||||
for (const line of lines) {
|
||||
const trimmed = line.trim();
|
||||
|
||||
if (!trimmed || trimmed.startsWith('#')) continue;
|
||||
|
||||
const equalIndex = trimmed.indexOf('=');
|
||||
if (equalIndex === -1) continue;
|
||||
|
||||
const key = trimmed.substring(0, equalIndex).trim();
|
||||
const value = trimmed.substring(equalIndex + 1).trim();
|
||||
|
||||
config[key] = value;
|
||||
}
|
||||
|
||||
return config;
|
||||
} catch (error) {
|
||||
if (error.code === 'ENOENT') {
|
||||
return {};
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
static async writeConfig(filePath, config) {
|
||||
const lines = [];
|
||||
|
||||
for (const [key, value] of Object.entries(config)) {
|
||||
if (value !== undefined && value !== null) {
|
||||
lines.push(`${key} = ${value}`);
|
||||
}
|
||||
}
|
||||
|
||||
await fs.writeFile(filePath, lines.join('\n') + '\n', 'utf8');
|
||||
}
|
||||
|
||||
static async parseModConfig(filePath) {
|
||||
const config = await this.parseConfig(filePath);
|
||||
|
||||
if (config.depends) {
|
||||
config.depends = config.depends.split(',').map(dep => dep.trim()).filter(Boolean);
|
||||
} else {
|
||||
config.depends = [];
|
||||
}
|
||||
|
||||
if (config.optional_depends) {
|
||||
config.optional_depends = config.optional_depends.split(',').map(dep => dep.trim()).filter(Boolean);
|
||||
} else {
|
||||
config.optional_depends = [];
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
static async writeModConfig(filePath, config) {
|
||||
const configCopy = { ...config };
|
||||
|
||||
if (Array.isArray(configCopy.depends)) {
|
||||
configCopy.depends = configCopy.depends.join(', ');
|
||||
}
|
||||
|
||||
if (Array.isArray(configCopy.optional_depends)) {
|
||||
configCopy.optional_depends = configCopy.optional_depends.join(', ');
|
||||
}
|
||||
|
||||
await this.writeConfig(filePath, configCopy);
|
||||
}
|
||||
|
||||
static async parseWorldConfig(filePath) {
|
||||
const config = await this.parseConfig(filePath);
|
||||
|
||||
const booleanFields = ['creative_mode', 'enable_damage', 'enable_pvp', 'server_announce'];
|
||||
for (const field of booleanFields) {
|
||||
if (config[field] !== undefined) {
|
||||
config[field] = config[field] === 'true';
|
||||
}
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
static async writeWorldConfig(filePath, config) {
|
||||
const configCopy = { ...config };
|
||||
|
||||
const booleanFields = ['creative_mode', 'enable_damage', 'enable_pvp', 'server_announce'];
|
||||
for (const field of booleanFields) {
|
||||
if (typeof configCopy[field] === 'boolean') {
|
||||
configCopy[field] = configCopy[field].toString();
|
||||
}
|
||||
}
|
||||
|
||||
await this.writeConfig(filePath, configCopy);
|
||||
}
|
||||
|
||||
static async parseGameConfig(filePath) {
|
||||
const config = await this.parseConfig(filePath);
|
||||
|
||||
// Parse common game config fields
|
||||
if (config.name) {
|
||||
config.name = config.name.trim();
|
||||
}
|
||||
if (config.title) {
|
||||
config.title = config.title.trim();
|
||||
}
|
||||
if (config.description) {
|
||||
config.description = config.description.trim();
|
||||
}
|
||||
if (config.author) {
|
||||
config.author = config.author.trim();
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ConfigParser;
|
Reference in New Issue
Block a user