UNPKG

@clusterio/host

Version:

Implementation of Clusterio host server

357 lines 12.7 kB
import fs from "fs-extra"; import child_process from "child_process"; import events from "events"; import { Rcon } from "rcon-client"; import * as lib from "@clusterio/lib"; /** * Determines the version of Factorio the datadir is pointing to by * reading the changelog.txt in it. * * @param changelogPath - Path to changelog.txt. * @internal */ declare function getVersion(changelogPath: string): Promise<string | null>; /** * Comparison function for sorting Factorio version strings * * @param a - Version to compare. * @param b - Version to compare. * @returns 1 if a < b, 0 if a = b and -1 if a > b. * @internal */ declare function versionOrder(a: string, b: string): 1 | -1 | 0; /** * Find factorio data directory of the given version * * Searches the given factorio dir for an installation of Factorio of * the target version. * * @param factorioDir - Path to Factorio installation dir(s). * @param targetVersion - * Version to look for, supports the special value "latest" for the * latest version available. * @returns Array with path to data dir and version found. * @internal */ declare function findVersion(factorioDir: string, targetVersion: lib.TargetVersion): Promise<any[]>; /** * Give a random dynamic port * * Returns a random port number in the Dynamic Ports range as defined by * RFC 6335. * * @return a number in the range 49152 to 65535. * @internal */ declare function randomDynamicPort(): number; /** * Generate a secure random password of the given length * * Uses crypto.randomBytes to generate a secure alphanumeric password of * the given length. * * @param length - the length of the password to generate. * @return password of the given length * @internal */ declare function generatePassword(length: number): Promise<string>; /** * Interpret lines of output from Factorio * * Parses a line of output from Factorio and interprets the content * based on the broad categories of output that it produces. * * TODO document output format. * * @param line - A line of output not including the line terminator * @param source - Passed into the output structure as source * * @returns - An object with interpeted data. * @internal */ declare function parseOutput(line: string, source: "stdout" | "stderr"): lib.ParsedFactorioOutput; export interface FactorioServerOptions { /** Logger to use for reporting errors. */ logger?: lib.Logger; /** * Version of Factorio to use. Can also be the string "latest" to use * the latest version found in `factorioDir`. */ version?: lib.TargetVersion; /** Path to executable to invoke when starting the server */ executablePath?: string; /** UDP port to host game on. */ gamePort?: number; /** TCP port to use for RCON. */ rconPort?: number; /** Password use for RCON. */ rconPassword?: string; /** Turn on whitelisting. */ enableWhitelist?: boolean; /** Enable Factorio.com based multiplayer bans. */ enableAuthserverBans?: boolean; /** Enable verbose logging. */ verboseLogging?: boolean; /** Enable console logging. */ consoleLogging?: boolean; /** Strip paths in the console. */ stripPaths?: boolean; /** * Maximum number of RCON commands transmitted in parallel on the RCON * connection. */ maxConcurrentCommands?: number; /** * Timeout in ms to wait after a shutdown is requested before killing the * process. Defaults to 0 meaning no timeout */ shutdownTimeoutMs?: number; } type FactorioServerEvents = { "stdout": [rawLine: Buffer]; "stderr": [rawLine: Buffer]; "output": [parsed: lib.ParsedFactorioOutput, line: string]; "error": [err: any]; "rcon-ready": []; "game-ready": []; "exit": []; "autosave-start": [name: string]; "autosave-finished": [name: string]; "save-finished": []; "whitelist-change": [added: string[], removed: string[]]; "_autosave": [name: string]; "_saving": []; "_saved": []; [ipcEvent: `ipc-${string}`]: [event: any]; }; /** * Factorio Server interface * * Handles the interactions with a Factorio server, including running, * stopping and sending commands to the server. It does not deal with * creating or managing servers, or downloading Factorio. * * This is an EventEmitter with the following events: * - stdout - invoked when Factorio outputs a line to stdout * - stderr - invoked when Factorio outputs a line to stderr * - output - invoked with parsed output from Factorio * - rcon-ready - invoked when the RCON client has connected * - game-ready - invoked when the server is finished starting up * - autosave-start - invoked when the server starts an autosave * - autosave-fnished - invoked when the autosave finished * - save-finished - invoked when the server has finished a manual save * - exit - invoked when the sterver has exited * @extends events.EventEmitter */ export declare class FactorioServer extends events.EventEmitter<FactorioServerEvents> { /** Path to executable to invoke when starting the server */ executablePath?: string; /** UDP port used for hosting the Factorio game server on */ gamePort: number; /** TCP port used for RCON on the Factorio game server */ rconPort: number; /** Password used for RCON on the Factorio game server */ rconPassword: string; /** Enable player whitelist */ enableWhitelist: boolean; /** Enable Factorio.com based multiplayer bans **/ enableAuthserverBans: boolean; /** Enable verbose logging */ verboseLogging: boolean; /** Enable console logging */ consoleLogging: boolean; _shutdownTimeoutMs: number; _stopTimeoutId?: ReturnType<typeof setTimeout>; _factorioDir: string; _writeDir: string; _version: lib.FullVersion | null; _dataDir: string | null; _whitelistWatcher: fs.FSWatcher | null; _whitelist: Set<string>; _logger: lib.Logger; _targetVersion: lib.TargetVersion; _state: "new" | "init" | "create" | "running" | "stopping"; _server: child_process.ChildProcessWithoutNullStreams | null; _rconClient: Rcon | null; _rconReady: boolean; _gameReady: boolean; _stripRegExp?: RegExp; _maxConcurrentCommands: number; _unexpected: string[]; _killed: boolean; _runningAutosave: string | null; /** * Create a Factorio server interface * * @param factorioDir - Directory of the Factorio install(s). * @param writeDir - Directory to write runtime data to. * @param options - Optional parameters. */ constructor(factorioDir: string, writeDir: string, options: FactorioServerOptions); _check(expectedStates: FactorioServer["_state"][]): void; handle<Event>(eventName: string, handler: (event: Event) => Promise<void>): void; _handleIpc(line: Buffer): Promise<void>; _handleOutput(rawLine: Buffer, source: "stdout" | "stderr"): void; _startRcon(): Promise<void>; _watchWhitelist(): void; /** Maximum number of RCON commands transmitted in parallel on the RCON connection */ get maxConcurrentCommands(): number; set maxConcurrentCommands(value: number); /** * Initialize class instance * * Must be called before instances of this class can be used. * @throws {Error} if the requested version of Factorio was not found. */ init(): Promise<void>; /** * The version of Factorio in use. This will be the actual version if * "latest" (the default) was specified as `factorioVersion` to the constructor. * This will be undefined before the server is initialized, or if init failed. */ get version(): lib.FullVersion | undefined; /** * The pid of the server process, or null if not running */ get pid(): number | null | undefined; _attachStdio(): void; _resetState(): void; _watchExit(): void; _notifyGameReady(): Promise<void>; _waitForReady(): Promise<void>; /** * Create a new save * * Spawns the Factorio server with the --create argument to create a new * map save with the given name. * * @param name - * Name of the save to create. Should end with ".zip". * @param seed - Seed to pass via --map-gen-seed * @param mapGenSettings - * Map get settings to pass via --map-gen-settings. * @param mapSettings - * Map setting to pass via --map-settings. */ create(name: string, seed?: number, mapGenSettings?: object, mapSettings?: object): Promise<void>; /** * Start server * * Spawn the Factorio server with the --start-server argument to * start the given save * * @param {string} save - Name of the save to run. */ start(save: string): Promise<void>; /** * Start scenario * * Spawn the Factorio server with the --start-server-load-scenario * argument to start the given scenario. * * @param scenario - Name of the scenario to run. * @param seed - Seed to pass via --map-gen-seed * @param mapGenSettings - * Map get settings to pass via --map-gen-settings. * @param mapSettings - * Map setting to pass via --map-settings. */ startScenario(scenario: string, seed?: number, mapGenSettings?: object, mapSettings?: object): Promise<void>; /** * Send message over RCON * * If the rcon connection hasn't been established yet, this will * wait until it is establied and then send the message. * * @param message - message to send to server over RCON. * @param expectEmpty - * if true throw if the response is not empty. Useful for detecting * errors that might have been sent in response. * @returns response from server. */ sendRcon(message: string, expectEmpty?: boolean): Promise<string>; /** * Timeout in ms to wait after a shutdown is requested before killing the * process. Defaults to 0 meaning no timeout */ get shutdownTimeoutMs(): number; set shutdownTimeoutMs(newTimeoutMs: number); _setStopTimeout(): void; _clearStopTimeout(): void; onStopTimeout(): void; /** * Stop the server * * Send stop signal to the server process and wait for it to shut * down. */ stop(): Promise<void>; /** * Kill the server * * Terminates the server without any cleanup or saving. * @param unexpected - * If true raise an error event as a result of killing the Factorio * process. */ kill(unexpected?: boolean): Promise<void>; /** * Disable achievements on the running server * * Ensures achievements are disabled on the save that's running. This is * necessary in order to run any commands at all. * * @returns * True if acheivements got disabled and false if they already where * disabled. */ disableAchievements(): Promise<boolean>; /** * Return path in data directory * * Creates a path using path.join with the given parts that's relative to * the data directory of the Factorio server. Not valid before init has * been called. * * @param parts - Extra parts to add to the data path. * @returns Data directory path. */ dataPath(...parts: string[]): string; /** * Get Factorio binary path * * Get the path to the factorio binary depending on the configuration * and or the platform (MacOS support) * * @returns Path to factorio binary */ binaryPath(): string; /** * Return path in write directory * * Creates a path using path.join with the given parts that's relative to * the write directory of the Factorio server. * * @param parts - Extra parts to add to the write path. * @returns Write directory path. */ writePath(...parts: string[]): string; /** * Get example server settings * * Loads server-settings.example.json from the data dir. * * @returns the parsed server-settings. */ exampleSettings(): Promise<any>; _writeConfigIniSync(): void; _writeMapSettingsSync(mapGenSettings?: object, mapSettings?: object): void; } export declare const _getVersion: typeof getVersion; export declare const _versionOrder: typeof versionOrder; export declare const _findVersion: typeof findVersion; export declare const _randomDynamicPort: typeof randomDynamicPort; export declare const _generatePassword: typeof generatePassword; export declare const _parseOutput: typeof parseOutput; export {}; //# sourceMappingURL=server.d.ts.map