mr-guard / dayz-server-manager

A server installer and watch-dog for dayz standalone with built-in Discord and RCon bot
MIT License
157 stars 41 forks source link

Bug with parsing args for servers #88

Open lankycraig opened 10 months ago

lankycraig commented 10 months ago

when the manager is creating the arsg for the server it does not account for spaces with in names white space cause a dayz server to pares each white space as a new arg

file dayz-server-manager / src / services / server-starter.ts

the following lines should surround the arg with double quotes ( " )
lines 168 -profiles=${this.manager.config.profilesPath}, 175
args.push(-mod=${modList.join(';')}); // old args.push("-mod=${modList.join(';')}"); // recomended
191

lankycraig commented 10 months ago

lines 168 -profiles=${this.manager.config.profilesPath}, //old "-profiles=${this.manager.config.profilesPath}", // recomended 175 args.push(-mod=${modList.join(';')}); // old args.push("-mod=${modList.join(';')}"); // recomended 191 args.push(-servermod=${serverMods.join(';')}); args.push("-servermod=${serverMods.join(';')}");

mr-guard commented 10 months ago

Will need to double check that because that might break compat with linux Thanks for the report tho

D4VOS commented 10 months ago

I've fixed this by changing the getWsModName() method in steamcmd.ts from:

    public getWsModName(modId: string): string {
        const wsPath = this.getWsPath();
        const modMeta = path.join(wsPath, modId, 'meta.cpp');
        if (!this.fs.existsSync(modMeta)) {
            return '';
        }
        const metaContent = this.fs.readFileSync(modMeta).toString();
        const names = metaContent.match(/name\s*=.*/g) ?? [];
        let modName = names
            .pop()
            ?.split('=')[1]
            ?.trim()
            ?.replace(/\//g, '-')
            ?.replace(/\\/g, '-')
            ?.replace(/ /g, '-')
            ?.replace(/[^a-zA-Z0-9\-_]/g, '')
            ?.replace(/-+/g, '-')
            || '';
        const isWindows = detectOS() === 'windows';
        if (!isWindows) {
            modName = modName?.toLowerCase();
        }
        return modName ? `@${modName}` : '';
    }

to:

    public getWsModName(modId: string): string {
        const wsPath = this.getWsPath();
        const modMeta = path.join(wsPath, modId, 'meta.cpp');
        if (!this.fs.existsSync(modMeta)) {
            return '';
        }
        const metaContent = this.fs.readFileSync(modMeta).toString();
        const names = metaContent.match(/name\s*=.*/g) ?? [];
        let modName = names
            .pop()
            ?.split('=')[1]
            ?.replace(/[\W_]+/g, '') || '';

        if (!isWindows) {
            modName = modName?.toLowerCase();
        }
        return modName ? `@${modName}` : '';
    }
mr-guard commented 10 months ago

Unfortunately it was not that easy. NodeJS's childprocess.spawn needs very special handling when using args with spaces. Just double quotes did not help and neither did a caret... That is probably because the manager needs to spawn cmd.exe to properly detach the dayz server instance from the manager.. (windows.. sigh..) Fortunately there is a library (cross-spawn) that correctly handles all the necessary escaping

@D4VOS your mentioned change would not help as whitespaces are already replaced. Whatever was wrong in your case might have been related to something else.

After all I still dont recommend having spaces in paths or filenames.. a lot of other stuff usually breaks because of this.. Just use "-" or "_" as separators

I will test this a bit more and push the fix with the next update if everything works correctly