UNPKG

@jsprismarine/prismarine

Version:

Dedicated Minecraft Bedrock Edition server written in TypeScript

170 lines (169 loc) • 15.3 kB
import { withCwd } from "../utils/cwd.es.js"; import { SeedGenerator } from "../utils/Seed.es.js"; import { ConfigBuilder } from "./ConfigBuilder.es.js"; import { getGametypeName } from "@jsprismarine/minecraft"; //#region src/config/Config.ts var isDev = process.env.NODE_ENV === "development"; var FILE_NAME = "config.yaml"; var Config = class { configBuilder; logLevel; port; serverIp; levelName; worlds; maxPlayers; gamemode; motd; viewDistance; onlineMode; packetCompressionLevel; /** * Controls if the minecraft/source query response should be enabled. */ enableQuery = true; /** * Controls if the process title should be updated. * @remarks this can cause performance issues in some terminals. */ enableProcessTitle = true; /** * Controls if the ticking should be enabled. */ enableTicking = true; constructor() { this.configBuilder = new ConfigBuilder(withCwd(FILE_NAME)); this.logLevel = this.configBuilder.get("log-level", isDev ? "verbose" : "info"); } /** * On enable hook. * @group Lifecycle */ async enable() { this.configBuilder = new ConfigBuilder(withCwd(FILE_NAME)); this.logLevel = this.configBuilder.get("log-level", isDev ? "verbose" : "info"); this.port = this.configBuilder.get("port", 19132); this.serverIp = this.configBuilder.get("server-ip", "0.0.0.0"); this.levelName = this.configBuilder.get("level-name", "world"); this.worlds = this.configBuilder.get("worlds", { world: { generator: "Flat", provider: "Filesystem", seed: SeedGenerator() } }); this.maxPlayers = this.configBuilder.get("max-players", 20); this.gamemode = this.configBuilder.get("gamemode", "survival"); this.motd = this.configBuilder.get("motd", "Another JSPrismarine server!"); this.viewDistance = this.configBuilder.get("view-distance", 10); this.onlineMode = this.configBuilder.get("online-mode", false); this.packetCompressionLevel = this.configBuilder.get("packet-compression-level", 7); this.enableQuery = this.configBuilder.get("enable-query", this.enableQuery); this.enableProcessTitle = this.configBuilder.get("enable-process-title", this.enableProcessTitle); this.enableTicking = this.configBuilder.get("enable-ticking", this.enableTicking); } /** * On disable hook. * @group Lifecycle */ async disable() {} getLogLevel() { return this.logLevel; } /** * Get the server's port. * @returns {number} The server's port * @remarks The default port is `19132`. */ getServerPort() { return this.port; } /** * Get the server's IP address. * @remarks The default IP address is `0.0.0.0` * @returns {string} The server's IP address */ getServerIp() { return this.serverIp; } /** * Returns the default world's name (`id`). * @returns The world's name as a `string` * @remarks * If the world doesn't exist as a part of the `worlds` array the `worldManager` will * fail to initialize. */ getLevelName() { return this.levelName; } getWorlds() { return this.worlds; } /** * * @returns The max amount of players allowed onto the server at the same time. */ getMaxPlayers() { return this.maxPlayers; } getGamemode() { return this.gamemode; } /** * Set the default gamemode. * * @param gamemode - the gamemode * @param commit - if the value should be written to the `config.yml` file */ setGamemode(gamemode, commit = false) { this.gamemode = getGametypeName(gamemode); if (commit) this.configBuilder.set("gamemode", this.gamemode); } /** * Returns true or false depending on if online mode is enabled. * * @returns The message of the day as a `string` */ getMotd() { return this.motd; } /** * Set the motd. * * @param motd - the gamemode * @param commit - if the value should be written to the `config.yml` file */ setMotd(motd, commit = false) { this.motd = motd; if (commit) this.configBuilder.set("motd", this.motd); } /** * Returns the view distance. * * @returns The view distance as an `integer` */ getViewDistance() { return Math.round(this.viewDistance); } /** * Returns true or false depending on if online mode is enabled. * * @returns `true` if enabled, `false` otherwise */ getOnlineMode() { return this.onlineMode; } getPacketCompressionLevel() { return this.packetCompressionLevel; } getEnableQuery() { return this.enableQuery; } getEnableProcessTitle() { return this.enableProcessTitle; } getEnableTicking() { return this.enableTicking; } }; //#endregion export { Config }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29uZmlnLmVzLmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb25maWcvQ29uZmlnLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgTG9nTGV2ZWwgfSBmcm9tICdAanNwcmlzbWFyaW5lL2xvZ2dlcic7XG5pbXBvcnQgeyBTZWVkR2VuZXJhdG9yIH0gZnJvbSAnLi4vdXRpbHMvU2VlZCc7XG5pbXBvcnQgeyB3aXRoQ3dkIH0gZnJvbSAnLi4vdXRpbHMvY3dkJztcbmltcG9ydCB7IENvbmZpZ0J1aWxkZXIgfSBmcm9tICcuL0NvbmZpZ0J1aWxkZXInO1xuXG5pbXBvcnQgeyBnZXRHYW1ldHlwZU5hbWUgfSBmcm9tICdAanNwcmlzbWFyaW5lL21pbmVjcmFmdCc7XG5cbmNvbnN0IGlzRGV2ID0gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdkZXZlbG9wbWVudCc7XG5cbmNvbnN0IEZJTEVfTkFNRSA9ICdjb25maWcueWFtbCc7XG5cbmV4cG9ydCBjbGFzcyBDb25maWcge1xuICAgIHByaXZhdGUgY29uZmlnQnVpbGRlciE6IENvbmZpZ0J1aWxkZXI7XG5cbiAgICBwcml2YXRlIGxvZ0xldmVsITogTG9nTGV2ZWw7XG5cbiAgICBwcml2YXRlIHBvcnQhOiBudW1iZXI7XG4gICAgcHJpdmF0ZSBzZXJ2ZXJJcCE6IHN0cmluZztcbiAgICBwcml2YXRlIGxldmVsTmFtZSE6IHN0cmluZztcbiAgICBwcml2YXRlIHdvcmxkcyE6IGFueTtcbiAgICBwcml2YXRlIG1heFBsYXllcnMhOiBudW1iZXI7XG4gICAgcHJpdmF0ZSBnYW1lbW9kZSE6IHN0cmluZztcbiAgICBwcml2YXRlIG1vdGQhOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSB2aWV3RGlzdGFuY2UhOiBudW1iZXI7XG4gICAgcHJpdmF0ZSBvbmxpbmVNb2RlITogYm9vbGVhbjtcbiAgICBwcml2YXRlIHBhY2tldENvbXByZXNzaW9uTGV2ZWwhOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBDb250cm9scyBpZiB0aGUgbWluZWNyYWZ0L3NvdXJjZSBxdWVyeSByZXNwb25zZSBzaG91bGQgYmUgZW5hYmxlZC5cbiAgICAgKi9cbiAgICBwcml2YXRlIGVuYWJsZVF1ZXJ5OiBib29sZWFuID0gdHJ1ZTtcblxuICAgIC8qKlxuICAgICAqIENvbnRyb2xzIGlmIHRoZSBwcm9jZXNzIHRpdGxlIHNob3VsZCBiZSB1cGRhdGVkLlxuICAgICAqIEByZW1hcmtzIHRoaXMgY2FuIGNhdXNlIHBlcmZvcm1hbmNlIGlzc3VlcyBpbiBzb21lIHRlcm1pbmFscy5cbiAgICAgKi9cbiAgICBwcml2YXRlIGVuYWJsZVByb2Nlc3NUaXRsZTogYm9vbGVhbiA9IHRydWU7XG5cbiAgICAvKipcbiAgICAgKiBDb250cm9scyBpZiB0aGUgdGlja2luZyBzaG91bGQgYmUgZW5hYmxlZC5cbiAgICAgKi9cbiAgICBwcml2YXRlIGVuYWJsZVRpY2tpbmc6IGJvb2xlYW4gPSB0cnVlO1xuXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLmNvbmZpZ0J1aWxkZXIgPSBuZXcgQ29uZmlnQnVpbGRlcih3aXRoQ3dkKEZJTEVfTkFNRSkpO1xuICAgICAgICB0aGlzLmxvZ0xldmVsID0gdGhpcy5jb25maWdCdWlsZGVyLmdldCgnbG9nLWxldmVsJywgaXNEZXYgPyAndmVyYm9zZScgOiAnaW5mbycpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE9uIGVuYWJsZSBob29rLlxuICAgICAqIEBncm91cCBMaWZlY3ljbGVcbiAgICAgKi9cbiAgICBwdWJsaWMgYXN5bmMgZW5hYmxlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLmNvbmZpZ0J1aWxkZXIgPSBuZXcgQ29uZmlnQnVpbGRlcih3aXRoQ3dkKEZJTEVfTkFNRSkpO1xuICAgICAgICB0aGlzLmxvZ0xldmVsID0gdGhpcy5jb25maWdCdWlsZGVyLmdldCgnbG9nLWxldmVsJywgaXNEZXYgPyAndmVyYm9zZScgOiAnaW5mbycpO1xuICAgICAgICB0aGlzLnBvcnQgPSB0aGlzLmNvbmZpZ0J1aWxkZXIuZ2V0KCdwb3J0JywgMTkxMzIpIGFzIG51bWJlcjtcbiAgICAgICAgdGhpcy5zZXJ2ZXJJcCA9IHRoaXMuY29uZmlnQnVpbGRlci5nZXQoJ3NlcnZlci1pcCcsICcwLjAuMC4wJykgYXMgc3RyaW5nO1xuICAgICAgICB0aGlzLmxldmVsTmFtZSA9IHRoaXMuY29uZmlnQnVpbGRlci5nZXQoJ2xldmVsLW5hbWUnLCAnd29ybGQnKSBhcyBzdHJpbmc7XG4gICAgICAgIHRoaXMud29ybGRzID0gdGhpcy5jb25maWdCdWlsZGVyLmdldCgnd29ybGRzJywge1xuICAgICAgICAgICAgd29ybGQ6IHtcbiAgICAgICAgICAgICAgICBnZW5lcmF0b3I6ICdGbGF0JyxcbiAgICAgICAgICAgICAgICBwcm92aWRlcjogJ0ZpbGVzeXN0ZW0nLFxuICAgICAgICAgICAgICAgIHNlZWQ6IFNlZWRHZW5lcmF0b3IoKVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5tYXhQbGF5ZXJzID0gdGhpcy5jb25maWdCdWlsZGVyLmdldCgnbWF4LXBsYXllcnMnLCAyMCkgYXMgbnVtYmVyO1xuICAgICAgICB0aGlzLmdhbWVtb2RlID0gdGhpcy5jb25maWdCdWlsZGVyLmdldCgnZ2FtZW1vZGUnLCAnc3Vydml2YWwnKSBhcyBzdHJpbmc7XG4gICAgICAgIHRoaXMubW90ZCA9IHRoaXMuY29uZmlnQnVpbGRlci5nZXQoJ21vdGQnLCAnQW5vdGhlciBKU1ByaXNtYXJpbmUgc2VydmVyIScpIGFzIHN0cmluZztcbiAgICAgICAgdGhpcy52aWV3RGlzdGFuY2UgPSB0aGlzLmNvbmZpZ0J1aWxkZXIuZ2V0KCd2aWV3LWRpc3RhbmNlJywgMTApIGFzIG51bWJlcjtcbiAgICAgICAgdGhpcy5vbmxpbmVNb2RlID0gdGhpcy5jb25maWdCdWlsZGVyLmdldCgnb25saW5lLW1vZGUnLCBmYWxzZSkgYXMgYm9vbGVhbjtcbiAgICAgICAgdGhpcy5wYWNrZXRDb21wcmVzc2lvbkxldmVsID0gdGhpcy5jb25maWdCdWlsZGVyLmdldCgncGFja2V0LWNvbXByZXNzaW9uLWxldmVsJywgNykgYXMgbnVtYmVyO1xuICAgICAgICB0aGlzLmVuYWJsZVF1ZXJ5ID0gdGhpcy5jb25maWdCdWlsZGVyLmdldCgnZW5hYmxlLXF1ZXJ5JywgdGhpcy5lbmFibGVRdWVyeSkgYXMgdHlwZW9mIHRoaXMuZW5hYmxlUXVlcnk7XG4gICAgICAgIHRoaXMuZW5hYmxlUHJvY2Vzc1RpdGxlID0gdGhpcy5jb25maWdCdWlsZGVyLmdldChcbiAgICAgICAgICAgICdlbmFibGUtcHJvY2Vzcy10aXRsZScsXG4gICAgICAgICAgICB0aGlzLmVuYWJsZVByb2Nlc3NUaXRsZVxuICAgICAgICApIGFzIHR5cGVvZiB0aGlzLmVuYWJsZVByb2Nlc3NUaXRsZTtcbiAgICAgICAgdGhpcy5lbmFibGVUaWNraW5nID0gdGhpcy5jb25maWdCdWlsZGVyLmdldCgnZW5hYmxlLXRpY2tpbmcnLCB0aGlzLmVuYWJsZVRpY2tpbmcpIGFzIHR5cGVvZiB0aGlzLmVuYWJsZVRpY2tpbmc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogT24gZGlzYWJsZSBob29rLlxuICAgICAqIEBncm91cCBMaWZlY3ljbGVcbiAgICAgKi9cbiAgICBwdWJsaWMgYXN5bmMgZGlzYWJsZSgpOiBQcm9taXNlPHZvaWQ+IHt9XG5cbiAgICBwdWJsaWMgZ2V0TG9nTGV2ZWwoKTogTG9nTGV2ZWwge1xuICAgICAgICByZXR1cm4gdGhpcy5sb2dMZXZlbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHNlcnZlcidzIHBvcnQuXG4gICAgICogQHJldHVybnMge251bWJlcn0gVGhlIHNlcnZlcidzIHBvcnRcbiAgICAgKiBAcmVtYXJrcyBUaGUgZGVmYXVsdCBwb3J0IGlzIGAxOTEzMmAuXG4gICAgICovXG4gICAgcHVibGljIGdldFNlcnZlclBvcnQoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucG9ydDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHNlcnZlcidzIElQIGFkZHJlc3MuXG4gICAgICogQHJlbWFya3MgVGhlIGRlZmF1bHQgSVAgYWRkcmVzcyBpcyBgMC4wLjAuMGBcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgc2VydmVyJ3MgSVAgYWRkcmVzc1xuICAgICAqL1xuICAgIHB1YmxpYyBnZXRTZXJ2ZXJJcCgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5zZXJ2ZXJJcDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBkZWZhdWx0IHdvcmxkJ3MgbmFtZSAoYGlkYCkuXG4gICAgICogQHJldHVybnMgVGhlIHdvcmxkJ3MgbmFtZSBhcyBhIGBzdHJpbmdgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBJZiB0aGUgd29ybGQgZG9lc24ndCBleGlzdCBhcyBhIHBhcnQgb2YgdGhlIGB3b3JsZHNgIGFycmF5IHRoZSBgd29ybGRNYW5hZ2VyYCB3aWxsXG4gICAgICogZmFpbCB0byBpbml0aWFsaXplLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRMZXZlbE5hbWUoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubGV2ZWxOYW1lO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRXb3JsZHMoKTogYW55IHtcbiAgICAgICAgcmV0dXJuIHRoaXMud29ybGRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHJldHVybnMgVGhlIG1heCBhbW91bnQgb2YgcGxheWVycyBhbGxvd2VkIG9udG8gdGhlIHNlcnZlciBhdCB0aGUgc2FtZSB0aW1lLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRNYXhQbGF5ZXJzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXhQbGF5ZXJzO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRHYW1lbW9kZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2FtZW1vZGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBkZWZhdWx0IGdhbWVtb2RlLlxuICAgICAqXG4gICAgICogQHBhcmFtIGdhbWVtb2RlIC0gdGhlIGdhbWVtb2RlXG4gICAgICogQHBhcmFtIGNvbW1pdCAtIGlmIHRoZSB2YWx1ZSBzaG91bGQgYmUgd3JpdHRlbiB0byB0aGUgYGNvbmZpZy55bWxgIGZpbGVcbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0R2FtZW1vZGUoZ2FtZW1vZGU6IG51bWJlciwgY29tbWl0ID0gZmFsc2UpIHtcbiAgICAgICAgdGhpcy5nYW1lbW9kZSA9IGdldEdhbWV0eXBlTmFtZShnYW1lbW9kZSk7XG4gICAgICAgIGlmIChjb21taXQpIHRoaXMuY29uZmlnQnVpbGRlci5zZXQoJ2dhbWVtb2RlJywgdGhpcy5nYW1lbW9kZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0cnVlIG9yIGZhbHNlIGRlcGVuZGluZyBvbiBpZiBvbmxpbmUgbW9kZSBpcyBlbmFibGVkLlxuICAgICAqXG4gICAgICogQHJldHVybnMgVGhlIG1lc3NhZ2Ugb2YgdGhlIGRheSBhcyBhIGBzdHJpbmdgXG4gICAgICovXG4gICAgcHVibGljIGdldE1vdGQoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubW90ZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIG1vdGQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gbW90ZCAtIHRoZSBnYW1lbW9kZVxuICAgICAqIEBwYXJhbSBjb21taXQgLSBpZiB0aGUgdmFsdWUgc2hvdWxkIGJlIHdyaXR0ZW4gdG8gdGhlIGBjb25maWcueW1sYCBmaWxlXG4gICAgICovXG4gICAgcHVibGljIHNldE1vdGQobW90ZDogc3RyaW5nLCBjb21taXQgPSBmYWxzZSkge1xuICAgICAgICB0aGlzLm1vdGQgPSBtb3RkO1xuXG4gICAgICAgIGlmIChjb21taXQpIHRoaXMuY29uZmlnQnVpbGRlci5zZXQoJ21vdGQnLCB0aGlzLm1vdGQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZpZXcgZGlzdGFuY2UuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBUaGUgdmlldyBkaXN0YW5jZSBhcyBhbiBgaW50ZWdlcmBcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0Vmlld0Rpc3RhbmNlKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiBNYXRoLnJvdW5kKHRoaXMudmlld0Rpc3RhbmNlKTsgLy8gTWFrZSBzdXJlIGl0J3MgYWx3YXlzIGFuIGludGVnZXJcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRydWUgb3IgZmFsc2UgZGVwZW5kaW5nIG9uIGlmIG9ubGluZSBtb2RlIGlzIGVuYWJsZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBgdHJ1ZWAgaWYgZW5hYmxlZCwgYGZhbHNlYCBvdGhlcndpc2VcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0T25saW5lTW9kZSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMub25saW5lTW9kZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0UGFja2V0Q29tcHJlc3Npb25MZXZlbCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFja2V0Q29tcHJlc3Npb25MZXZlbDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0RW5hYmxlUXVlcnkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVuYWJsZVF1ZXJ5O1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRFbmFibGVQcm9jZXNzVGl0bGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVuYWJsZVByb2Nlc3NUaXRsZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0RW5hYmxlVGlja2luZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5hYmxlVGlja2luZztcbiAgICB9XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7O0FBT0EsSUFBTSxRQUFBLFFBQUEsSUFBQSxhQUFpQztBQUV2QyxJQUFNLFlBQVk7QUFF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