@clusterio/host
Version:
Implementation of Clusterio host server
357 lines • 12.7 kB
TypeScript
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