"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Game = exports.Server = void 0;
const events_1 = __importDefault(require("events"));
const Socket_js_1 = require("./Socket.js");
const Console_js_1 = require("./Console.js");
const Players_js_1 = require("./Players.js");
/**
* Root object for interacting with SourceMod.js servers.
* @class
* @property {string} host - The host WebSocket address. Example: `ws://localhost:5050`
* @property {boolean} connected - Will be true if the server is connected to the WebSocket, and false otherwise.
* @property {object} socket - An instance of the `Socket` class used for interacting with the WebSocket. Will be null if not yet connected.
* @property {object} console - Instance of the `Console` object for this server.
* @property {object} players - Instance of the `Players` object for this server.
* @property {string} currentMap - Name of the current map. Keep in mind that this is a generic response from the engine and not the game itself.
* @property {boolean} isDedicated - Whether the server is a dedicated server or not.
* @property {string} authID - The SteamID of the server.
* @property {number} gameTime - The game time, based on the game tick.
* @property {number} gameTick - The current game tick.
* @property {string} gameFolder - The directory of the server.
* @property {string} gameDescription - The description of the game. Keep in mind that this is a generic response from the engine, and not the game itself.
* @property {string} engineVersion - The engine version that SourceMod was compilied against.
*/
class Server extends events_1.default {
/**
* @constructor
* @param {string} host - The host WebSocket address. Example: `ws://localhost:5050`
* @param {object} options - Options to provide the server.
*/
constructor(host, options) {
super();
this.host = host;
this.options = new Map();
this.connected = false;
this.socket;
this.console = new Console_js_1.Console(this);
this.players = new Players_js_1.Players(this);
this.game = exports.Game.None;
this.currentMap = "";
this.nextMap = "";
this.isDedicated;
this.authID = "";
this.gameTime = 0;
this.gameTick = 0;
this.gameFolder = "";
this.gameDescription = "";
this.engineVersion = "";
if (options)
this.options = new Map(Object.entries(options));
}
/**
* Connects to the server.
* @function
*/
connect() {
return __awaiter(this, void 0, void 0, function* () {
this.socket = new Socket_js_1.Socket(this, this.host);
this.socket.on(Socket_js_1.Events.ServerUpdate, (data) => {
var msg = data.message;
this.currentMap = msg.currentMap;
this.nextMap = msg.nextMap;
this.isDedicated = msg.isDedicated;
this.authID = msg.authID;
this.gameTime = msg.gameTime;
this.gameTick = msg.gameTick;
this.gameFolder = msg.gameFolder;
this.gameDescription = msg.gameDescription;
this.engineVersion = msg.engineVersion;
});
this.socket.on(Socket_js_1.Events.ConVarChanged, (data) => {
/**
* Fires when a ConVar changes.
* [SourceMod API Reference](https://wiki.alliedmods.net/Generic_Source_Server_Events#server_cvar)
*
* @event Server#convarChanged
* @param {string} name - Name of the ConVar.
* @param {string} steamid - New value of the ConVar.
*/
this.emit("convarChanged", data.message.name, data.message.value);
});
this.socket.on("ready", () => __awaiter(this, void 0, void 0, function* () {
yield this.fetch();
this.connected = true;
switch (this.gameDescription) {
case "Team Fortress":
this.game = exports.Game.TeamFortress2;
break;
default:
this.game = exports.Game.Unknown;
break;
}
/**
* Fired when the connection to the server has been established.
*
* @event Server#ready
*/
this.emit("ready", true);
}));
});
}
/**
* Disconnects from the server. Internally calls Socket.disconnect().
* @function
*/
disconnect() {
var _a;
return __awaiter(this, void 0, void 0, function* () {
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.disconnect();
/**
* Fired when the server disconnects.
*
* @event Server#disconnect
*/
this.emit("disconnect", true);
});
}
/**
* Fetches information about the server. Keep in mind that you must run this function to keep the server information up-to-date.
* @function
* @returns {Object} The new server object with fetched information.
*/
fetch() {
return __awaiter(this, void 0, void 0, function* () {
if (this.socket == undefined)
return;
yield this.socket.send(Socket_js_1.Messages.FetchServer, true);
return this;
});
}
/**
* Forcefully changes the current map, with an optional reason.
* [SourceMod API Reference](https://sm.alliedmods.net/new-api/nextmap/SetNextMap)
* @function
* @param {string} - Name of the new map
* @param {string} - Reason for changing the map
* @returns {Object} - The new server object with fetched information.
*/
setMap(map, reason) {
return __awaiter(this, void 0, void 0, function* () {
if (this.socket == undefined)
return;
yield this.socket.send(Socket_js_1.Messages.SetMap, {
map: map,
reason: reason !== null && reason !== void 0 ? reason : "No reason provided!"
});
yield this.fetch();
return this.nextMap;
});
}
/**
* Sets SourceMod's internal nextmap. Same as changing `sm_nextmap`. Will run `Server.fetch()`, ensuring the nextMap property is updated.
* [SourceMod API Reference](https://sm.alliedmods.net/new-api/nextmap/SetNextMap)
* @function
* @param {string} - Name of the new map
* @returns {Object} - The new server object with fetched information.
*/
setNextMap(map) {
return __awaiter(this, void 0, void 0, function* () {
if (this.socket == undefined)
return;
yield this.socket.send(Socket_js_1.Messages.SetNextMap, map);
yield this.fetch();
return this.nextMap;
});
}
}
exports.Server = Server;
/**
* An enum describing the supported game that Sourcemod.JS is running on.
*
* @readonly
* @enum {string} Game
*/
exports.Game = {
None: "None",
Unknown: "Unknown",
TeamFortress2: "TeamFortress2"
};