diff --git a/README.md b/README.md index c56cb3236..10312b0f6 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ Also supports linux server (See [Linux Server Usage](#linux-server))
## Installation Requirements
-* A Windows (Root) Server with RDP/Shell access +* A Windows or linux (Root) Server with RDP/Shell access * hosted instances (like nitrado) cannot use this EXCEPT they can run arbitrary programs * To download mods: A steam account that owns DayZ and has SteamGuard set to EMAIL or DEACTIVATED! * That's it! @@ -124,26 +124,27 @@ Also supports linux server (See [Linux Server Usage](#linux-server)) ## Usage
* Download the [latest version](https://github.com/mr-guard/dayz-server-manager/releases/latest) of the manager -* Extract the manager and the config template -* Copy and rename the config template to `server-manager.json` +* Extract the manager in the directory where you want your serverfiles to be +* Start the manager once to create a new config with default values * Edit the `server-manager.json` config to fit your needs * Fill the required fields (everything is described in the file) `!IMPORTANT! Change the admin and rcon password` * Other than that the defaults will probably fit your needs * You can also checkout the [configuration guides](#configuration) -* Start the manager in the folder where the config is situated - +* Start the manager and it will use the updated config +
* It is recommended to create a separate Steam account which owns DayZ. You need to set SteamGuard to EMAIL or DEACTIVATED! Do not use Mobile authenticator because those codes will not be saved on the server and need to be entered on every download/update. - -* Optionally you can add it as Windows Service instead of launching it manually +
+* Optionally you can add it as Windows/Linux Service instead of launching it manually +
* Make sure the "Execution Location" is the folder, where the config is located (this is not necessarily the folder where the manager executable is located)
## Updating
This app was written with backwards compatibility in mind.
-Sometimes, however, some bracking changes to the server manager config will occur.
-The best strategy to update is to take the config template of the new version and and modify it to match your old version.
+Sometimes, however, some breaking changes to the server manager config will occur.
+The best strategy to update, is to take the config template of the new version and modify it to match your old values.
This way you can not miss out on new properties which might be required.

@@ -205,17 +206,17 @@ The example snippet shows how to add an admin, a manager and a moderator.
... "admins": [ { - "userId": "FunkyDude#1234", + "userId": "FunkyDude", "userLevel": "admin", "password": "admin" }, { - "userId": "TheDude#4242", + "userId": "the-discord-dude", "userLevel": "manage", "password": "somecoolpassword" }, { - "userId": "InternDude#4321", + "userId": "InternDude", "userLevel": "moderate", "password": "somoderatormuchwow" } @@ -420,7 +421,7 @@ If the manager crashes or shuts down, your dayz server will also be shut down. Replace `/dayz` with the directory you want your server to be in, but make sure its already created ```sh useradd --system -m -d /dayz -s /bin/bash dayz - chown dayz:dayz /dayz && \ + chown dayz:dayz /dayz ``` 3. Download and extract the latest linux release from the releases page 4. Setup the manager files @@ -534,7 +535,6 @@ If you are really paranoid about pasting your password somewhere, or you use ste * Provide self generated/signed certificates for HTTPS * More script hooks * Custom discord commands -* Edit/View Bans in WebUI * Examples and integration scripts for Workbench (for mod Development)
@@ -550,6 +550,8 @@ If you are really paranoid about pasting your password somewhere, or you use ste ----- steamcmd.exe ----- .. -- Workshop // contains the actual workshop mods +-- STEAM_GUARD_CODE // Optional text file. Containing only your steam guard code. will be deleted after usage. See Known Issues / Limitations for more details. +-- SERVER_LOCK // Optional file. If exists server restarts will be skipped ``` You can, however, change these paths to fit your needs @@ -560,8 +562,9 @@ You can, however, change these paths to fit your needs The server manager is a self contained NodeJS-App written in TypeScript and packaged with pkg. You DON'T need to install NodeJS or anything else. Everything you need is contained in the single executable (exe). -However, due to that the exe is around 50MB in size. -This tool makes use of the windows commandline tools (namely netsh and wmic) to determine installation requirements and the state of the server. +However, due to that the exe is around 90MB in size. +This tool makes use of the windows commandline tools (namely netsh and wmic) or the linux cli tools and procfs to determine installation requirements and the state of the server. +It is recommended NOT to use an elevated user for running it.
## Security
@@ -604,6 +607,14 @@ This way the traffic is handled securely until terminated at the reverse proxy.<
+* SteamCMD Rate-Limit: + * The SteamCMD rate limit might occur if you download many mods at once (i.e. first setup) + * You will see an error that includes status code = 5 or rate limit + * this is nothing bad.. you are not banned.. you just need to wait some time and retry + * the manager already tries to downloads mods in batches to prevent this by default, but sometimes thats not enough + +
+ * Apparently the steam cmd reverts changes to the default mission `dayzOffline.ChernarusPlus` when validating the isntallation.. * to prevent this simply add your own mission * simply copy `dayzOffline.chernarusplus` and rename it to `dayz.chernarusplus` (or something else) diff --git a/src/config/config-file-helper.ts b/src/config/config-file-helper.ts index f5e56927b..2416beefc 100644 --- a/src/config/config-file-helper.ts +++ b/src/config/config-file-helper.ts @@ -9,6 +9,9 @@ import { inject, injectable, singleton } from 'tsyringe'; import { FSAPI, InjectionTokens } from '../util/apis'; import { IService } from '../types/service'; import { LoggerFactory } from '../services/loggerfactory'; +import { origExit } from '../util/exit-capture'; +import { randomUUID } from 'crypto'; +import { detectOS } from '../util/detect-os'; // eslint-disable-next-line @typescript-eslint/no-var-requires const configschema = require('./config.schema.json'); @@ -96,4 +99,41 @@ export class ConfigFileHelper extends IService { } } + public createDefaultConfig(): void { + + const cfgPath = this.getConfigFilePath(); + + if (!this.fs.existsSync(cfgPath)) { + const defaultConfig = commentJson.parse(generateConfigTemplate(configschema)) as any as Config; + + // apply safe defaults + defaultConfig.admins[0].password = randomUUID(); + defaultConfig.ingameApiKey = randomUUID(); + defaultConfig.rconPassword = randomUUID(); + defaultConfig.serverCfg.passwordAdmin = randomUUID(); + + // linux specifics + if (detectOS() !== 'windows') { + defaultConfig.serverExe = 'DayZServer'; + } + + this.fs.writeFileSync( + cfgPath, + commentJson.stringify(defaultConfig, null, 2), + ); + + console.log('\n\n\n'); + console.log('Did not find a server manager config!'); + console.log(`Created a new config with default values at: ${cfgPath}`); + console.log('Adjust the config to fit your needs and restart the manager!'); + console.log('\n\n'); + + if (typeof global.it === 'function') { + return; + } + origExit(0); // end process + } + + } + } diff --git a/src/config/config.ts b/src/config/config.ts index 9d1b34089..2dd0616ea 100644 --- a/src/config/config.ts +++ b/src/config/config.ts @@ -480,8 +480,8 @@ export class Config { * * example: * { - * "userId": "senfo", - * "password": "admin", + * "userId": "admin", + * "password": "my-password", * "userLevel": "admin" * } * @@ -536,14 +536,12 @@ export class Config { * Whether or not to publish the Ingame Rest API * * Same as publish webport but for the Ingame REST API. - * Can be used for shared hives / provide the api for external servers. */ public publishIngameApi: boolean = false; /** * Alternative host for the Ingame Rest API. * - * Can be used for shared hives. * Provide "ip:port" to make the addon connect to another Ingame API. */ public ingameApiHostOverride: string | null = null; diff --git a/src/control/manager-controller.ts b/src/control/manager-controller.ts index 076ba9143..ed5c41baa 100644 --- a/src/control/manager-controller.ts +++ b/src/control/manager-controller.ts @@ -29,6 +29,7 @@ import { MetricsCollector } from '../services/metrics-collector'; import { IngameREST } from '../interface/ingame-rest'; import { SyberiaCompat } from '../services/syberia-compat'; import { DiscordEventConverter } from '../services/discord-event-converter'; +import { ConfigFileHelper } from '../config/config-file-helper'; @singleton() @registry([ @@ -123,7 +124,8 @@ export class ManagerController { private working = false; private started = false; - private skipInitialCheck: boolean = false; + + private skipInit: boolean = process.argv.includes('--skip-init'); private log: Logger; @@ -137,6 +139,7 @@ export class ManagerController { private requirements: Requirements, private discord: DiscordBot, private discordEvents: DiscordEventConverter, + private configFileHelper: ConfigFileHelper, ) { this.log = loggerFactory.createLogger('Bootstrap'); } @@ -200,6 +203,8 @@ export class ManagerController { public async start(): Promise { + this.configFileHelper.createDefaultConfig(); + if (this.working) { this.log.log(LogLevel.DEBUG, `Start called while ${this.started ? 'stopping' : 'starting'}`); return; @@ -225,7 +230,9 @@ export class ManagerController { process.title = `Server-Manager ${this.manager.getServerExePath()}`; // check any requirements before even starting - await this.requirements.check(); + if (!this.skipInit) { + await this.requirements.check(); + } this.log.log(LogLevel.DEBUG, 'Setting up services..'); @@ -233,7 +240,9 @@ export class ManagerController { this.log.log(LogLevel.DEBUG, 'Services are set up'); try { - await this.initialSetup(); + if (!this.skipInit) { + await this.initialSetup(); + } this.log.log(LogLevel.DEBUG, 'Initial Check done. Starting Init..'); for (const service of this.getStatefulServices()) { @@ -284,7 +293,7 @@ export class ManagerController { private async initialSetup(): Promise { - if (this.skipInitialCheck || await this.serverDetector.isServerRunning()) { + if (await this.serverDetector.isServerRunning()) { this.log.log(LogLevel.IMPORTANT, 'Skipping initial SteamCMD check because the server is already running'); return; } diff --git a/src/index.ts b/src/index.ts index db1c62418..f33ed1ff6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,6 +5,23 @@ import { isRunFromWindowsGUI } from './util/is-run-from-gui'; import * as childProcess from 'child_process'; import * as fs from 'fs'; import { container } from 'tsyringe'; +import { origExit } from './util/exit-capture'; + +const helpText = ` + Usage + $ dayz-server-manager + + Options + --skip-init Skip the init process (requirements check, server update, mod update) + --start-locked Activates the server restart lock so it does not start the dayz server when the manager starts + --skip-events Skips execution of scheduled events +`; + +if (process.argv.includes('--help')) { + console.log(helpText); + origExit(0); +} + void (async () => { diff --git a/src/services/events.ts b/src/services/events.ts index 8954d8d2f..8b8cbb9f7 100644 --- a/src/services/events.ts +++ b/src/services/events.ts @@ -3,6 +3,7 @@ import { Manager } from '../control/manager'; import * as cron from 'node-schedule'; import { LogLevel } from '../util/logger'; import { ServerState } from '../types/monitor'; +import { Event } from '../config/config'; import { injectable, singleton } from 'tsyringe'; import { LoggerFactory } from './loggerfactory'; import { RCON } from './rcon'; @@ -17,6 +18,8 @@ export class Events extends IStatefulService { private tasks: cron.Job[] = []; + private skipEvents: boolean = process.argv.includes('--skip-events'); + public constructor( logerFactory: LoggerFactory, private manager: Manager, @@ -31,67 +34,23 @@ export class Events extends IStatefulService { public async start(): Promise { for (const event of (this.manager.config.events ?? [])) { - const runTask = async (task: () => Promise): Promise => { - void task() - ?.then(() => { - this.log.log(LogLevel.DEBUG, `Successfully executed task '${event.name}'`); - }) - ?.catch(/* istanbul ignore next */ () => { - this.log.log(LogLevel.WARN, `Failed to execute task '${event.name}'`); - }); - }; - - const checkAndRun = async (task: () => Promise): Promise => { - if (this.monitor.serverState !== ServerState.STARTED) { - this.log.log(LogLevel.WARN, `Skipping '${event.name}' because server is not in STARTED state`); - return; - } - - void runTask(task); - }; - const job = cron.scheduleJob( event.name, event.cron, () => { - this.log.log(LogLevel.DEBUG, `Executing task '${event.name}' (${event.type})`); - switch (event.type) { - case 'restart': { - void checkAndRun(async () => { - this.eventBus.emit( - InternalEventTypes.DISCORD_MESSAGE, - { - type: 'notification', - message: 'Executing planned Restart!', - }, - ); - await this.monitor.killServer(); - }); - break; - } - case 'message': { - void checkAndRun(() => this.rcon.global(event.params[0])); - break; - } - case 'kickAll': { - void checkAndRun(() => void this.rcon.kickAll()); - break; - } - case 'lock': { - void checkAndRun(() => void this.rcon.lock()); - break; - } - case 'unlock': { - void checkAndRun(() => void this.rcon.unlock()); - break; - } - case 'backup': { - void runTask(() => this.backup.createBackup()); - break; - } - default: { - break; - } + if (this.skipEvents) { + this.log.log(LogLevel.IMPORTANT, `Skipping task '${event.name}' (${event.type}) because events are skipped`); + return; + } + + try { + this.execute(event); + } catch (e) { + this.log.log( + LogLevel.ERROR, + `Error executing task '${event.name}' (${event.type}). Check your config for errors!`, + e, + ); } }, ); @@ -116,4 +75,71 @@ export class Events extends IStatefulService { this.tasks = []; } + private runTask(event: Event, task: () => Promise): void { + void task() + ?.then(() => { + this.log.log(LogLevel.DEBUG, `Successfully executed task '${event.name}'`); + }) + ?.catch(/* istanbul ignore next */ () => { + this.log.log(LogLevel.WARN, `Failed to execute task '${event.name}'`); + }); + }; + + private checkStartedAndRun(event: Event, task: () => Promise): void { + if (this.monitor.serverState !== ServerState.STARTED) { + this.log.log(LogLevel.WARN, `Skipping '${event.name}' because server is not in STARTED state`); + return; + } + + this.runTask(event, task); + }; + + private execute(event: Event): void { + this.log.log(LogLevel.DEBUG, `Executing task '${event.name}' (${event.type})`); + switch (event.type) { + case 'restart': { + this.checkStartedAndRun(event, async () => { + this.eventBus.emit( + InternalEventTypes.DISCORD_MESSAGE, + { + type: 'notification', + message: 'Executing planned Restart!', + }, + ); + await this.monitor.killServer(); + }); + break; + } + case 'message': { + if (!event.params?.[0]) { + this.log.log( + LogLevel.ERROR, + `Message task '${event.name}' (${event.type}) is missing the message. Check your config!`, + ); + } + this.checkStartedAndRun(event, () => this.rcon.global(event.params[0])); + break; + } + case 'kickAll': { + this.checkStartedAndRun(event, () => void this.rcon.kickAll()); + break; + } + case 'lock': { + this.checkStartedAndRun(event, () => void this.rcon.lock()); + break; + } + case 'unlock': { + this.checkStartedAndRun(event, () => void this.rcon.unlock()); + break; + } + case 'backup': { + this.runTask(event, () => this.backup.createBackup()); + break; + } + default: { + break; + } + } + } + } diff --git a/src/services/monitor.ts b/src/services/monitor.ts index 4c17b7a4e..4d2fa2de7 100644 --- a/src/services/monitor.ts +++ b/src/services/monitor.ts @@ -10,6 +10,8 @@ import { EventBus } from '../control/event-bus'; import { InternalEventTypes } from '../types/events'; import { ServerStarter } from './server-starter'; import { ServerDetector } from './server-detector'; +import { Paths } from './paths'; +import * as path from 'path'; export type ServerStateListener = (state: ServerState) => any; @@ -39,9 +41,14 @@ export class Monitor extends IStatefulService { private processes: Processes, private serverStarter: ServerStarter, private serverDetector: ServerDetector, + private paths: Paths, @inject(InjectionTokens.fs) private fs: FSAPI, ) { super(loggerFactory.createLogger('Monitor')); + + if (process.argv.includes('--start-locked')) { + this.restartLock = true; + } } private get internalServerState(): ServerState { @@ -84,7 +91,10 @@ export class Monitor extends IStatefulService { } public async start(): Promise { - if (this.timers.getTimer('tick')) return; + if (this.timers.getTimer('tick')) return; // already started + + this.lockPath = path.join(this.paths.cwd(), 'SERVER_LOCK'); + this.lastTick = 0; this.tickRunning = false; this.timers.addInterval( diff --git a/test/config/config-file-helper.test.ts b/test/config/config-file-helper.test.ts index 8e808ab13..9633e484c 100644 --- a/test/config/config-file-helper.test.ts +++ b/test/config/config-file-helper.test.ts @@ -163,4 +163,17 @@ describe('Test class ConfigFileHelper', () => { }); + it('ConfigFileHelper-writeConfig', () => { + const helper = injector.resolve(ConfigFileHelper); + + helper.createDefaultConfig(); + + // Expect result + const cfgPath = helper.getConfigFilePath(); + expect(files.existsSync(cfgPath)).to.be.true; + + const config = helper.readConfig(); + expect(config?.admins[0].password).not.to.equal('admin'); + }); + }); diff --git a/test/control/manager-controller.test.ts b/test/control/manager-controller.test.ts index 2b20d9503..9891881e1 100644 --- a/test/control/manager-controller.test.ts +++ b/test/control/manager-controller.test.ts @@ -17,6 +17,7 @@ import { IStatefulService } from '../../src/types/service'; import { Config } from '../../src/config/config'; import { DiscordBot } from '../../src/services/discord'; import { DiscordEventConverter } from '../../src/services/discord-event-converter'; +import { ConfigFileHelper } from '../../src/config/config-file-helper'; class TestMonitor { public startCalled = false; @@ -93,6 +94,7 @@ describe('Test class ManagerController', () => { let injector: DependencyContainer; let configWatcher: StubInstance; + let configHelper: StubInstance; let manager: StubInstance; let serverDetector: StubInstance; let steamCmd: StubInstance; @@ -115,6 +117,7 @@ describe('Test class ManagerController', () => { injector = container.createChildContainer(); injector.register(ConfigWatcher, stubClass(ConfigWatcher), { lifecycle: Lifecycle.Singleton }); + injector.register(ConfigFileHelper, stubClass(ConfigFileHelper), { lifecycle: Lifecycle.Singleton }); injector.register(Manager, stubClass(Manager), { lifecycle: Lifecycle.Singleton }); injector.register(ServerDetector, stubClass(ServerDetector), { lifecycle: Lifecycle.Singleton }); injector.register(SteamCMD, stubClass(SteamCMD), { lifecycle: Lifecycle.Singleton }); @@ -124,6 +127,7 @@ describe('Test class ManagerController', () => { injector.register(DiscordEventConverter, stubClass(DiscordEventConverter), { lifecycle: Lifecycle.Singleton }); configWatcher = injector.resolve(ConfigWatcher) as any; + configHelper = injector.resolve(ConfigFileHelper) as any; manager = injector.resolve(Manager) as any; serverDetector = injector.resolve(ServerDetector) as any; steamCmd = injector.resolve(SteamCMD) as any; diff --git a/test/services/monitor.test.ts b/test/services/monitor.test.ts index 2f94ca227..adc884066 100644 --- a/test/services/monitor.test.ts +++ b/test/services/monitor.test.ts @@ -1,6 +1,6 @@ import { expect } from '../expect'; import { ImportMock } from 'ts-mock-imports' -import { StubInstance, disableConsole, enableConsole, memfs, sleep, stubClass } from '../util'; +import { StubInstance, disableConsole, enableConsole, fakeChildProcess, memfs, sleep, stubClass } from '../util'; import { Monitor } from '../../src/services/monitor'; import { SystemReporter } from '../../src/services/system-reporter'; import { ServerDetector } from '../../src/services/server-detector'; @@ -20,6 +20,7 @@ import { IngameReport } from '../../src/services/ingame-report'; import { Hooks } from '../../src/services/hooks'; import { EventBus } from '../../src/control/event-bus'; import { InternalEventTypes } from '../../src/types/events'; +import { Paths } from '../../src/services/paths'; describe('Test class ServerDetector', () => { @@ -285,6 +286,7 @@ describe('Test class Monitor', () => { let serverStarter: StubInstance; let serverDetector: StubInstance; let fs: FSAPI; + let paths: Paths; before(() => { @@ -308,7 +310,9 @@ describe('Test class Monitor', () => { injector.register(ServerStarter, stubClass(ServerStarter), { lifecycle: Lifecycle.Singleton }); injector.register(ServerDetector, stubClass(ServerDetector), { lifecycle: Lifecycle.Singleton }); injector.register(EventBus, EventBus, { lifecycle: Lifecycle.Singleton }); - + injector.register(Paths, Paths, { lifecycle: Lifecycle.Singleton }); + fakeChildProcess(injector); // for paths + fs = memfs({}, '/', injector); manager = injector.resolve(Manager) as any; @@ -316,6 +320,7 @@ describe('Test class Monitor', () => { eventBus = injector.resolve(EventBus) as any; serverStarter = injector.resolve(ServerStarter) as any; serverDetector = injector.resolve(ServerDetector) as any; + paths = injector.resolve(Paths); }); it('Monitor-startStop', async () => { diff --git a/ui/src/modules/maintenance/services/maintenance.service.ts b/ui/src/modules/maintenance/services/maintenance.service.ts index fcc8a9108..8e96cc4a7 100644 --- a/ui/src/modules/maintenance/services/maintenance.service.ts +++ b/ui/src/modules/maintenance/services/maintenance.service.ts @@ -59,7 +59,7 @@ export class MaintenanceService { } public async unlockRestarts(): Promise { - return this.execute('updateserver'); + return this.execute('unlockrestart'); } public async restartServer(force?: boolean): Promise { diff --git a/watcher_mod/DayZServerManager/Scripts/3_Game/DZSMApi.c b/watcher_mod/DayZServerManager/Scripts/3_Game/DZSMApi.c index eaf86b056..576a83fb4 100644 --- a/watcher_mod/DayZServerManager/Scripts/3_Game/DZSMApi.c +++ b/watcher_mod/DayZServerManager/Scripts/3_Game/DZSMApi.c @@ -16,9 +16,7 @@ ref DZSMApiOptions GetDZSMApiOptions() string jsonConfigPath = "$profile:\\DZSMApiOptions.json"; if (FileExist(jsonConfigPath)) { - #ifdef DZSM_DEBUG Print("DZSM ~ Loading API Config"); - #endif JsonFileLoader.JsonLoadFile(jsonConfigPath, m_dzsmApiOptions); } else diff --git a/watcher_mod/DayZServerManager/Scripts/5_Mission/DayZServerManager/Game/DayZServerManagerWatcher.c b/watcher_mod/DayZServerManager/Scripts/5_Mission/DayZServerManager/Game/DayZServerManagerWatcher.c index 7f42c38ee..778e247e2 100644 --- a/watcher_mod/DayZServerManager/Scripts/5_Mission/DayZServerManager/Game/DayZServerManagerWatcher.c +++ b/watcher_mod/DayZServerManager/Scripts/5_Mission/DayZServerManager/Game/DayZServerManagerWatcher.c @@ -9,10 +9,10 @@ class DZSMDumpEntry : Managed delete parents; } - void Init(string classname, string source) + void Init(string classnameParam, string sourceParam) { - this.classname = classname; - this.source = source; + classname = classnameParam; + source = sourceParam; parents = new TStringArray; string child = classname; @@ -21,7 +21,7 @@ class DZSMDumpEntry : Managed { if (parent && child != parent) { - parents.Insert(parent) + parents.Insert(parent); } else { @@ -58,9 +58,9 @@ class DZSMBaseDumpEntry : DZSMDumpEntry delete itemInfo; } - void Init(string classname, string source) + override void Init(string classnameParam, string sourceParam) { - super.Init(classname, source); + super.Init(classnameParam, sourceParam); displayName = GetGame().ConfigGetTextOut( source + " " + classname + " displayName" ); hitPoints = GetGame().ConfigGetFloat( source + " " + classname + " DamageSystem GlobalHealth Health hitpoints" ); @@ -120,9 +120,9 @@ class DZSMAmmoDumpEntry : DZSMDumpEntry float damageArmor; - void DZSMAmmoDumpEntry(string classname) + void DZSMAmmoDumpEntry(string classnameParam) { - Init(classname, "cfgMagazines"); + Init(classnameParam, "cfgMagazines"); displayName = GetGame().ConfigGetTextOut( "cfgMagazines " + classname + " displayName" ); projectile = GetGame().ConfigGetTextOut( "cfgMagazines " + classname + " ammo" ); @@ -190,9 +190,9 @@ class DZSMMagDumpEntry : DZSMDumpEntry ref TIntArray size; ref TStringArray ammo; - void DZSMMagDumpEntry(string classname) + void DZSMMagDumpEntry(string classnameParam) { - Init(classname, "cfgMagazines"); + Init(classnameParam, "cfgMagazines"); displayName = GetGame().ConfigGetTextOut( "cfgMagazines " + classname + " displayName" ); projectile = GetGame().ConfigGetTextOut( "cfgMagazines " + classname + " ammo" ); @@ -241,18 +241,18 @@ class DZSMWeaponModeDumpEntry : Managed float dispersion; float rounds; - void DZSMWeaponModeDumpEntry(string name, float rpm, float dispersion, float rounds) + void DZSMWeaponModeDumpEntry(string nameParam, float rpmParam, float dispersionParam, float roundsParam) { - this.name = name; - this.rpm = rpm; - this.dispersion = dispersion; - if (rounds) + name = nameParam; + rpm = rpmParam; + dispersion = dispersionParam; + if (roundsParam) { - this.rounds = rounds; + rounds = roundsParam; } else { - this.rounds = 1; + rounds = 1; } } } @@ -303,9 +303,9 @@ class DZSMWeaponDumpEntry : DZSMBaseDumpEntry ref array modes; - void DZSMWeaponDumpEntry(string classname) + void DZSMWeaponDumpEntry(string classnameParam) { - Init(classname, "cfgWeapons"); + Init(classnameParam, "cfgWeapons"); noise = GetGame().ConfigGetFloat( "cfgWeapons " + classname + " NoiseShoot strength" ); magazineSwitchTime = GetGame().ConfigGetFloat( "cfgWeapons " + classname + " magazineSwitchTime" ); @@ -357,9 +357,7 @@ class DZSMWeaponDumpEntry : DZSMBaseDumpEntry if (!CheckItemCrash(classname)) { - #ifdef DZSM_DEBUG Print("DZSM Dump ~ Determining recoil for " + classname); - #endif Weapon_Base ent; if ( !Class.CastTo( ent, GetGame().CreateObjectEx( classname, "0 0 0", ECE_CREATEPHYSICS ) ) ) return; @@ -429,9 +427,9 @@ static void DZSMWeaponDump() list.Insert(new DZSMWeaponDumpEntry(className)); } } - #ifdef DZSM_DEBUG + Print(string.Format("DZSM Dump ~ Weapon dump: %1 classes", list.Count())); - #endif + JsonFileLoader>.JsonSaveFile(filepath, list); } @@ -462,9 +460,9 @@ class DZSMClothingDumpEntry : DZSMBaseDumpEntry ref TStringArray attachments; - void DZSMClothingDumpEntry(string classname) + void DZSMClothingDumpEntry(string classnameParam) { - Init(classname, "cfgVehicles"); + Init(classnameParam, "cfgVehicles"); heatIsolation = GetGame().ConfigGetFloat( "cfgVehicles " + classname + " heatIsolation" ); visibilityModifier = GetGame().ConfigGetFloat( "cfgVehicles " + classname + " visibilityModifier" ); @@ -565,9 +563,9 @@ class DZSMItemDumpEntry : DZSMBaseDumpEntry float meleeDmg; float meleeDmgHeavy; - void DZSMItemDumpEntry(string classname) + void DZSMItemDumpEntry(string classnameParam) { - Init(classname, "cfgVehicles"); + Init(classnameParam, "cfgVehicles"); isMeleeWeapon = GetGame().ConfigGetInt( "cfgVehicles " + classname + " isMeleeWeapon" ) == 1; repairKitType = GetGame().ConfigGetInt( "cfgVehicles " + classname + " repairKitType" ); @@ -686,9 +684,9 @@ class DZSMContainerDumpEntry : DZSMBaseDumpEntry ref TStringArray attachments; - void DZSMContainerDumpEntry(string classname) + void DZSMContainerDumpEntry(string classnameParam) { - Init(classname, "cfgVehicles"); + Init(classnameParam, "cfgVehicles"); canBeDigged = GetGame().ConfigGetInt( "cfgVehicles " + classname + " canBeDigged" ); heavyItem = GetGame().ConfigGetInt( "cfgVehicles " + classname + " heavyItem" ); @@ -744,9 +742,9 @@ static void DZSMContainerDump() class DZSMZombieDumpEntry : DZSMDumpEntry { - void DZSMZombieDumpEntry(string classname) + void DZSMZombieDumpEntry(string classnameParam) { - Init(classname, "cfgVehicles"); + Init(classnameParam, "cfgVehicles"); } @@ -788,16 +786,12 @@ class ServerManagerCallback: RestCallback override void OnError(int errorCode) { - #ifdef DZSM_DEBUG Print("DZSM ~ OnError: " + errorCode); - #endif } override void OnTimeout() { - #ifdef DZSM_DEBUG Print("DZSM ~ OnTimeout"); - #endif } }; @@ -854,9 +848,7 @@ class DayZServerManagerWatcher void DayZServerManagerWatcher() { - #ifdef DZSM_DEBUG Print("DZSM ~ DayZServerManagerWatcher()"); - #endif m_InitTimer = new Timer(CALL_CATEGORY_GAMEPLAY); m_InitTimer.Run(2.0 * 60.0, this, "init", null, false); @@ -864,9 +856,7 @@ class DayZServerManagerWatcher void init() { - #ifdef DZSM_DEBUG Print("DZSM ~ DayZServerManagerWatcher() - INIT"); - #endif m_RestApi = CreateRestApi(); m_RestContext = m_RestApi.GetRestContext(GetDZSMApiOptions().host); @@ -874,54 +864,35 @@ class DayZServerManagerWatcher m_RestApi.EnableDebug(false); StartLoop(); - #ifdef DZSM_DEBUG + Print("DZSM ~ DayZServerManagerWatcher() - INIT DONE"); - #endif if (GetDZSMApiOptions().dataDump) { - #ifdef DZSM_DEBUG Print("DZSM ~ DayZServerManagerWatcher() - DATA DUMP"); - #endif - - #ifdef DZSM_DEBUG + Print("DZSM ~ DayZServerManagerWatcher() - AMMO DUMP"); - #endif DZSMAmmoDump(); - #ifdef DZSM_DEBUG Print("DZSM ~ DayZServerManagerWatcher() - MAG DUMP"); - #endif DZSMMagDump(); - #ifdef DZSM_DEBUG Print("DZSM ~ DayZServerManagerWatcher() - WEAPON DUMP"); - #endif DZSMWeaponDump(); - #ifdef DZSM_DEBUG Print("DZSM ~ DayZServerManagerWatcher() - CLOTHING DUMP"); - #endif DZSMClothingDump(); - #ifdef DZSM_DEBUG Print("DZSM ~ DayZServerManagerWatcher() - ITEM DUMP"); - #endif DZSMItemDump(); - #ifdef DZSM_DEBUG Print("DZSM ~ DayZServerManagerWatcher() - CONTAINER DUMP"); - #endif DZSMContainerDump(); - #ifdef DZSM_DEBUG Print("DZSM ~ DayZServerManagerWatcher() - ZOMBIE DUMP"); - #endif DZSMZombieDump(); - #ifdef DZSM_DEBUG Print("DZSM ~ DayZServerManagerWatcher() - DATA DUMP DONE"); - #endif } CrashTest(); @@ -937,9 +908,7 @@ class DayZServerManagerWatcher ref array crashCheckItems = new array; JsonFileLoader>.JsonLoadFile(crashCheckItemsPath, crashCheckItems); - #ifdef DZSM_DEBUG Print("DZSM ~ DayZServerManagerWatcher() - STARTING CRASH TEST"); - #endif string crashingItemsPath = "$profile:crashingitems.json"; ref array crashingItems = new array; @@ -1007,10 +976,7 @@ class DayZServerManagerWatcher } - - #ifdef DZSM_DEBUG Print("DZSM ~ DayZServerManagerWatcher() - CRASH TEST DONE"); - #endif } float GetInterval() @@ -1144,26 +1110,20 @@ modded class MissionServer void MissionServer() { - #ifdef DZSM_DEBUG Print("DZSM ~ MissionServer"); - #endif } override void OnInit() { super.OnInit(); - #ifdef DZSM_DEBUG Print("DZSM ~ MissionServer.OnInit"); - #endif } override void OnMissionStart() { super.OnMissionStart(); - #ifdef DZSM_DEBUG Print("DZSM ~ MissionServer.OnMissionStart"); - #endif if (!GetGame().IsClient()) { diff --git a/watcher_mod/DayZServerManagerSyberia/Scripts/3_Game/DatabaseApi.c b/watcher_mod/DayZServerManagerSyberia/Scripts/3_Game/DatabaseApi.c index e5863cb71..f36593cf0 100644 --- a/watcher_mod/DayZServerManagerSyberia/Scripts/3_Game/DatabaseApi.c +++ b/watcher_mod/DayZServerManagerSyberia/Scripts/3_Game/DatabaseApi.c @@ -28,16 +28,12 @@ class SyberiaDatabaseCallback: RestCallback override void OnError(int errorCode) { - #ifdef DZSM_DEBUG Print("DZSM Syberia ~ OnError: " + errorCode); - #endif } override void OnTimeout() { - #ifdef DZSM_DEBUG Print("DZSM Syberia ~ OnTimeout"); - #endif } };