Files
tactical-shooter/package/dist/utils/autoload-ini.js
T
shawn 91b878f347 Quaternius weapons, input fixes, sound & path fixes
- Added 6 Quaternius weapon models (Pistol, Revolver, Rifle, Shotgun, P90, SniperRifle)
- Created weapon resource files with balanced stats
- Wired Pistol + Rifle into player.tscn replacing Kenney blasters
- Fixed WASD input (matched input map action names)
- Fixed Escape key toggles mouse capture
- Added Audio autoload singleton
- Fixed broken sound asset paths across all scripts
- Fixed all scene ext_resource text paths (nested under assets/kenney-fps/)
- Fixed all .import source_file paths
- Deleted stale .import files (will be regenerated by editor on open)
2026-07-05 22:53:27 -04:00

124 lines
5.1 KiB
JavaScript

import { readFileSync, writeFileSync } from 'fs';
/**
* Matches an empty `[autoload]` section (the header followed by only blank
* lines, up to the next section header or end-of-file). Used by cleanup paths
* to drop the section after the last entry is removed.
*/
export const EMPTY_AUTOLOAD_SECTION_REGEX = /\[autoload\]\s*(?=\n\[|\n*$)/g;
/**
* Mirrors the parser's `\w+` assumption (parseAutoloads / removeAutoloadEntry).
* Enforced on write paths to prevent a name with newlines or INI section
* delimiters from corrupting project.godot.
*/
export const VALID_AUTOLOAD_NAME_REGEX = /^\w+$/;
function assertValidName(name) {
if (!VALID_AUTOLOAD_NAME_REGEX.test(name)) {
throw new Error(`Invalid autoload name '${name}': must contain only word characters (letters, digits, underscore)`);
}
}
export function normalizeAutoloadPath(p) {
return p.startsWith('res://') ? p : `res://${p}`;
}
export function parseAutoloads(projectFilePath, existingContent) {
const content = existingContent ?? readFileSync(projectFilePath, 'utf8');
const autoloads = [];
let inAutoloadSection = false;
for (const line of content.split('\n')) {
const trimmed = line.trim();
if (trimmed.startsWith('[')) {
inAutoloadSection = trimmed === '[autoload]';
continue;
}
if (!inAutoloadSection || trimmed === '' || trimmed.startsWith(';') || trimmed.startsWith('#'))
continue;
// The surrounding `"?` are intentional: Godot always writes quotes, but
// hand-edited project.godot files sometimes omit them. Tolerating both
// shapes means a missing quote pair doesn't silently drop the entry.
const match = trimmed.match(/^(\w+)="?(\*?)([^"]*?)"?$/);
if (match) {
autoloads.push({ name: match[1], singleton: match[2] === '*', path: match[3] });
}
}
return autoloads;
}
export function addAutoloadEntry(projectFilePath, name, path, singleton, existingContent) {
assertValidName(name);
const content = existingContent ?? readFileSync(projectFilePath, 'utf8');
const lines = content.split('\n');
const entry = `${name}="${singleton ? '*' : ''}${normalizeAutoloadPath(path)}"`;
const sectionIdx = lines.findIndex((l) => l.trim() === '[autoload]');
if (sectionIdx === -1) {
writeFileSync(projectFilePath, content.trimEnd() + '\n\n[autoload]\n' + entry + '\n', 'utf8');
return;
}
let insertIdx = sectionIdx + 1;
while (insertIdx < lines.length && !lines[insertIdx].trim().startsWith('[')) {
insertIdx++;
}
lines.splice(insertIdx, 0, entry);
writeFileSync(projectFilePath, lines.join('\n'), 'utf8');
}
/**
* Remove the named autoload entry. Also drops the `[autoload]` section header
* if the removed entry was the last one in it. Returns true when the file was
* mutated.
*/
export function removeAutoloadEntry(projectFilePath, name) {
const content = readFileSync(projectFilePath, 'utf8');
const lines = content.split('\n');
let inAutoloadSection = false;
let removed = false;
const filtered = lines.filter((line) => {
const trimmed = line.trim();
if (trimmed.startsWith('[')) {
inAutoloadSection = trimmed === '[autoload]';
return true;
}
if (inAutoloadSection) {
const match = trimmed.match(/^(\w+)=/);
if (match && match[1] === name) {
removed = true;
return false;
}
}
return true;
});
if (!removed)
return false;
let newContent = filtered.join('\n');
newContent = newContent.replace(EMPTY_AUTOLOAD_SECTION_REGEX, '');
newContent = newContent.trimEnd() + '\n';
writeFileSync(projectFilePath, newContent, 'utf8');
return true;
}
export function updateAutoloadEntry(projectFilePath, name, newPath, singleton) {
assertValidName(name);
const content = readFileSync(projectFilePath, 'utf8');
const lines = content.split('\n');
let inAutoloadSection = false;
let updated = false;
const newLines = lines.map((line) => {
const trimmed = line.trim();
if (trimmed.startsWith('[')) {
inAutoloadSection = trimmed === '[autoload]';
return line;
}
if (inAutoloadSection) {
// The surrounding `"?` are intentional: Godot always writes quotes, but
// hand-edited project.godot files sometimes omit them. Tolerating both
// shapes means a missing quote pair doesn't silently drop the entry.
const match = trimmed.match(/^(\w+)="?(\*?)([^"]*?)"?$/);
if (match && match[1] === name) {
const effectiveSingleton = singleton !== undefined ? singleton : match[2] === '*';
const effectivePath = newPath !== undefined ? normalizeAutoloadPath(newPath) : match[3];
updated = true;
return `${name}="${effectiveSingleton ? '*' : ''}${effectivePath}"`;
}
}
return line;
});
if (updated)
writeFileSync(projectFilePath, newLines.join('\n'), 'utf8');
return updated;
}
//# sourceMappingURL=autoload-ini.js.map