"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.Condition = exports.Player = void 0;
const events_1 = __importDefault(require("events"));
const Socket_js_1 = require("./Socket.js");
const Utilities_js_1 = require("./Utilities.js");
/**
* Object representing a player currently connected to the server.
* @class
* @property {object} players - The `Players` object this belongs to.
* @property {bool} partial - Whether this object is partial or not. Partial objects are only guaranteed to contain the `id` property.
* @property {number} id - ID of the player.
* @property {string} authid - SteamID of the player.
* @property {string} name - Name of the player.
* @property {string} ip - IP address of the player. (without the port)
* @property {number} health - Amount of health the player has.
* @property {number} gravity - Gravity of the player.
* @property {string} weapon - The current weapon the player has equipped. (Example: `tf_weapon_scattergun`)
* @property {number} kills - Amount of kills the player currently has.
* @property {number} deaths - Amount of deaths the player currently has.
* @property {number} team - Team index of the player. Keep in mind that this is a generic response from the engine and not the game.
* @property {number} connectionTime - The amount of time (in seconds) the player has been connected to the server. Will be 0 if the player is a bot/fake.
* @property {object} render - Rendering information about the player (effects, color, etc).
* @property {object} render.color - Rendering color information
* @property {number} render.color.r - Rendering color (red 0-255)
* @property {number} render.color.g - Rendering color (green 0-255)
* @property {number} render.color.b - Rendering color (blue 0-255)
* @property {number} render.color.a - Rendering color (alpha 0-255)
* @property {number} render.effect - Rendering effect
* @property {number} render.mode - Rendering mode
*/
class Player extends events_1.default {
/**
* @constructor
* @param {Players} players - The `Players` object this belongs to.
* @param {object} data - Player data sent from the server.
* @param {bool} partial - Whether this object is partial or not. Defaults to false.
*/
constructor(players, data, partial) {
super();
this.players = players;
this.partial = partial !== null && partial !== void 0 ? partial : false;
this.update(data);
this.players.on("chat", (plr, message, team) => {
if (plr.id != this.id)
return;
/**
* Fires when this player sends a chat message.
* [SourceMod API Reference](https://sm.alliedmods.net/new-api/console/OnClientSayCommand)
*
* @event Player#chat
* @param {string} message - Content of the chat message.
* @param {bool} team - True if the chat message was a team message, and false otherwise.
*/
this.emit("chat", message, team);
});
}
/**
* Fetches information about this player from the server. Keep in mind that you must run this function to keep this player up-to-date. Similar to `Players.fetch()`
* @function
* @returns {Object} The new player object with fetched information.
*/
fetch() {
return __awaiter(this, void 0, void 0, function* () {
if (this.players.server.socket == undefined)
return;
yield this.players.server.socket.send(Socket_js_1.Messages.FetchPlayer, this.id);
return this;
});
}
/**
* Updates the player with new information from `Player.fetch()`. Used internally.
* @function
* @returns {Object} The new player object with fetched information.
*/
update(data) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
this.id = (_a = data.id) !== null && _a !== void 0 ? _a : 0;
this.authid = (_b = data.authid) !== null && _b !== void 0 ? _b : "";
this.name = (_c = data.name) !== null && _c !== void 0 ? _c : "";
this.ip = (_d = data.ip) !== null && _d !== void 0 ? _d : "";
this.health = (_e = data.health) !== null && _e !== void 0 ? _e : 1;
this.weapon = (_f = data.weapon) !== null && _f !== void 0 ? _f : "";
this.gravity = (_g = data.gravity) !== null && _g !== void 0 ? _g : 0;
this.kills = (_h = data.kills) !== null && _h !== void 0 ? _h : 0;
this.deaths = (_j = data.deaths) !== null && _j !== void 0 ? _j : 0;
this.team = (_k = data.team) !== null && _k !== void 0 ? _k : 0;
this.connectionTime = (_l = Math.round(data.connectionTime)) !== null && _l !== void 0 ? _l : 0;
this.connectionTimeMinutes = (_m = Math.round(data.connectionTime / 60)) !== null && _m !== void 0 ? _m : 0;
this.render = {
color: {
r: (_o = data.colorr) !== null && _o !== void 0 ? _o : 255,
g: (_p = data.colorg) !== null && _p !== void 0 ? _p : 255,
b: (_q = data.colorb) !== null && _q !== void 0 ? _q : 255,
a: (_r = data.colora) !== null && _r !== void 0 ? _r : 255
},
effect: (_s = data.rendereffect) !== null && _s !== void 0 ? _s : 0,
mode: (_t = data.rendermode) !== null && _t !== void 0 ? _t : 0
};
return this;
}
/**
* Kicks a player from the server.
* [SourceMod API Reference](https://sm.alliedmods.net/new-api/clients/KickClient)
*
* @function
* @param {string} reason - The reason for the kick. Cannot exceed 256 bytes.
*/
kick(reason) {
var _a;
return (_a = this.players.server.socket) === null || _a === void 0 ? void 0 : _a.send(Socket_js_1.Messages.KickPlayer, {
id: this.id,
reason: reason
});
}
/**
* Sends a message to a player's chatbox. Cannot exceed 256 bytes.
* [SourceMod API Reference](https://sm.alliedmods.net/new-api/halflife/PrintToChat)
*
* @function
* @param {string} message - The message to send.
*/
chat(message) {
var _a;
if ((0, Utilities_js_1.checkBytes)(message, 256))
return;
return (_a = this.players.server.socket) === null || _a === void 0 ? void 0 : _a.send(Socket_js_1.Messages.PlayerChat, {
id: this.id,
message: message
});
}
/**
* Sends a message to a player's hint box. Cannot exceed 256 bytes.
* [SourceMod API Reference](https://sm.alliedmods.net/new-api/halflife/PrintHintText)
*
* @function
* @param {string} message - The message to send.
*/
hint(message) {
var _a;
if ((0, Utilities_js_1.checkBytes)(message, 256))
return;
return (_a = this.players.server.socket) === null || _a === void 0 ? void 0 : _a.send(Socket_js_1.Messages.PlayerHint, {
id: this.id,
message: message
});
}
/**
* Sends a message to a player's center hint box. Cannot exceed 256 bytes.
* [SourceMod API Reference](https://sm.alliedmods.net/new-api/halflife/PrintCenterText)
*
* @function
* @param {string} message - The message to send.
*/
centerHint(message) {
var _a;
if ((0, Utilities_js_1.checkBytes)(message, 256))
return;
return (_a = this.players.server.socket) === null || _a === void 0 ? void 0 : _a.send(Socket_js_1.Messages.PlayerCenterHint, {
id: this.id,
message: message
});
}
/**
* Plays a sound. The file path must be a game sound from `scripts/game_sound.txt` or `sound_misc_dir.vpk`. Cannot exceed 256 bytes.
* [SourceMod API Reference](https://sm.alliedmods.net/new-api/sdktools_sound/EmitGameSoundToClient)
*
* @function
* @param {string} path - File path to the sound
*/
playSound(path) {
var _a;
if ((0, Utilities_js_1.checkBytes)(path, 256))
return;
return (_a = this.players.server.socket) === null || _a === void 0 ? void 0 : _a.send(Socket_js_1.Messages.PlaySound, {
id: this.id,
path: path
});
}
/**
* Teleports a player to another player.
* [SourceMod API Reference](https://sm.alliedmods.net/new-api/sdktools_functions/TeleportEntity)
*
* @function
* @param {Player} player - The player to teleport to.
*/
teleport(player) {
var _a;
return (_a = this.players.server.socket) === null || _a === void 0 ? void 0 : _a.send(Socket_js_1.Messages.TeleportPlayer, {
to: player.id,
from: this.id
});
}
/**
* Slaps the player, with an optional amount of damage.
* [SourceMod API Reference](https://sm.alliedmods.net/new-api/sdktools_functions/SlapPlayer)
*
* @function
* @param {number} damage - The amount of damage to deal. Defaults to 0.
*/
slap(damage) {
var _a;
return (_a = this.players.server.socket) === null || _a === void 0 ? void 0 : _a.send(Socket_js_1.Messages.SlapPlayer, {
id: this.id,
damage: damage !== null && damage !== void 0 ? damage : 0
});
}
/**
* Updates the player's rendering, such as the color and render effects/modes. Every argument is optional, and won't change the value if not provided.
* [SourceMod API Reference (SetEntityRenderColor)](https://sm.alliedmods.net/new-api/entity_prop_stocks/SetEntityRenderColor)
* [SourceMod API Reference (SetEntityRenderFx)](https://sm.alliedmods.net/new-api/entity_prop_stocks/SetEntityRenderFx)
* [SourceMod API Reference (SetEntityRenderMode)](https://sm.alliedmods.net/new-api/entity_prop_stocks/SetEntityRenderMode)
*
* @function
* @param {number} r - Rendering color (red 0-255)
* @param {number} g - Rendering color (green 0-255)
* @param {number} b - Rendering color (blue 0-255)
* @param {number} a - Rendering color (alpha 0-255)
* @param {number} effect - Rendering effect
* @param {number} mode - Rendering mode
*/
setRendering(r, g, b, a, effect, mode) {
var _a;
return (_a = this.players.server.socket) === null || _a === void 0 ? void 0 : _a.send(Socket_js_1.Messages.SetPlayerRendering, {
id: this.id,
r: r !== null && r !== void 0 ? r : this.render.color.r,
g: g !== null && g !== void 0 ? g : this.render.color.g,
b: b !== null && b !== void 0 ? b : this.render.color.b,
a: a !== null && a !== void 0 ? a : this.render.color.a,
effect: effect !== null && effect !== void 0 ? effect : this.render.effect,
mode: mode !== null && mode !== void 0 ? mode : this.render.mode
});
}
/**
* Resets the player's rendering color/effect/mode.
* [SourceMod API Reference (SetEntityRenderColor)](https://sm.alliedmods.net/new-api/entity_prop_stocks/SetEntityRenderColor)
* [SourceMod API Reference (SetEntityRenderFx)](https://sm.alliedmods.net/new-api/entity_prop_stocks/SetEntityRenderFx)
* [SourceMod API Reference (SetEntityRenderMode)](https://sm.alliedmods.net/new-api/entity_prop_stocks/SetEntityRenderMode)
*
* @function
*/
resetRendering() {
return this.setRendering(255, 255, 255, 255, 0, 0);
}
/**
* Regenerates a player's health and ammo. Team Fortress 2 only!
* [SourceMod API Reference](https://sm.alliedmods.net/new-api/tf2/TF2_RegeneratePlayer)
*
* @function Player#regenerate
*/
regenerate() {
var _a;
if (this.players.server.game != "TeamFortress2") {
throw "This function is only available in Team Fortress 2.";
}
return (_a = this.players.server.socket) === null || _a === void 0 ? void 0 : _a.send(Socket_js_1.Messages.TF2_RegeneratePlayer, this.id);
}
/**
* Gives a player a weapon with custom stats. Team Fortress 2 only! Requires [TF2Items](https://forums.alliedmods.net/showthread.php?t=115100).
*
* @param {Weapon} weapon - The weapon object to give.
* @function Player#giveWeapon
*/
giveWeapon(weapon) {
var _a;
if (this.players.server.game != "TeamFortress2") {
throw "This function is only available in Team Fortress 2.";
}
weapon.id = this.id;
return (_a = this.players.server.socket) === null || _a === void 0 ? void 0 : _a.send(Socket_js_1.Messages.TF2_GiveWeapon, weapon);
}
/**
* Adds a condition to a player. Team Fortress 2 only.
* [SourceMod API Reference](https://sm.alliedmods.net/new-api/tf2/TF2_AddCondition)
*
* @param {Condition} condition
* @param {number} duration - How long to apply the condition for.
*/
applyCondition(condition, duration = 0) {
var _a;
if (this.players.server.game != "TeamFortress2") {
throw "This function is only available in Team Fortress 2.";
}
return (_a = this.players.server.socket) === null || _a === void 0 ? void 0 : _a.send(Socket_js_1.Messages.TF2_ApplyCondition, {
id: this.id,
condition: condition,
duration: duration == 0 ? 0 : duration + 0.1
});
}
}
exports.Player = Player;
/**
* Enum describing conditions that can be applied to a player. Team Fortress 2 only! [SourceMod API Reference](https://sm.alliedmods.net/new-api/tf2/TFCond)
*
* Keep in mind that applying some of these won't do anything. Checking for them or removing them from a player would be more useful.
*
* @readonly
* @enum {number} Condition
*
*/
exports.Condition = {
Slowed: 0,
Zoomed: 1,
Disguising: 2,
Disguised: 3,
Cloaked: 4,
Ubercharged: 5,
TeleportGlow: 6,
Taunting: 7,
UberchargeFading: 8,
CloakFlicker: 9,
Teleporting: 10,
Kritzkrieged: 11,
//TmpDamageBonus: 12,
DeadRingered: 13,
Bonked: 14,
Dazed: 15,
BuffBanner: 16,
DemoknightCharging: 17,
EyelanderEyeGlow: 18,
CritACola: 19,
InHealRadius: 20,
Healing: 21,
OnFire: 22,
Overhealed: 23,
Jarated: 24,
Bleeding: 25,
BattalionsBackup: 26,
MadMilk: 27,
QuickFix: 28,
Concheror: 29,
MarkedForDeath: 30,
NoHealingDamageBuff: 31,
DisciplinaryActionSpeed: 32,
HalloweenCritPumpkin: 33,
CritCanteen: 34,
CritDemoCharge: 35,
SodaPopperHype: 36,
ArenaFirstBlood: 37,
CritOnWin: 38,
CritOnFlagCapture: 39,
CritOnKill: 40,
RestrictToMelee: 41,
DefenseBuffNoCritBlock: 42,
//Reprogrammed: 43,
PhlogistinatorCritMmmph: 44,
PhlogistinatorDefenseMmmph: 45,
HitmansHeatmakerFocus: 46,
EnforcerDisguiseRemoved: 47,
MarkedForDeathSilent: 48,
DisguisedAsDispenser: 49,
// MvMSapperSparkle: 50,
// MvMUberchargedHidden: 51,
UberchargeCanteen: 52,
HalloweenBombHead: 53,
HalloweenForcedThrillerTaunt: 54,
RadiusHealing: 55,
CritOnDamage: 56,
UberOnDamage: 57,
VaccinatorUberBullet: 58,
VaccinatorUberBlast: 59,
VaccinatorUberFire: 60,
VaccinatorHealBullet: 61,
VaccinatorHealBlast: 62,
VaccinatorHealFire: 63,
// Stealthed: 64,
// MedigunDebuff: 65,
// StealthedUserBuffFade: 66,
BulletImmunity: 67,
BlastImmunity: 68,
FireImmunity: 69,
Buddha: 70,
// MvMRadiowave: 71,
HalloweenSpeedboost: 72,
HalloweenQuickheal: 73,
Giant: 74,
Tiny: 75,
HalloweenInHell: 76,
HalloweenGhost: 77,
MiniCritOnKill: 78,
// DodgeChance: 79,
BASEJumperParachute: 80,
BlastJumping: 81,
HalloweenKart: 82,
HalloweenKartDash: 83,
BalloonHead: 84,
MeleeOnly: 85,
SwimmingCurse: 86,
HalloweenKartNoTurn: 87,
HalloweenKartCage: 88,
Powerup: 89,
Powerup_Strength: 90,
Powerup_Haste: 91,
Powerup_Regeneration: 92,
Powerup_Resistance: 93,
Powerup_Vampire: 94,
Powerup_Reflect: 95,
Powerup_Precision: 96,
Powerup_Agility: 97,
GrapplingHook: 98,
GrapplingHookSafeFall: 99,
GrapplingHookLatched: 100,
GrapplingHookBleeding: 101,
DeadRingerAfterburnImmunity: 102,
Powerup_Knockout: 103,
Powerup_Imbalance: 104,
Powerup_Crit: 105,
PasstimeInterception: 106,
//SwimmingNoEffects: 107,
EscapedUnderworld: 108,
Powerup_King: 109,
Powerup_Plague: 110,
Powerup_Supernova: 111,
Powerup_Plague_Effect: 112,
Powerup_King_Effect: 113,
SpawnOutline: 114,
Airblasted: 115,
CompetitiveWinner: 116,
CompetitiveLoser: 117,
// NoTaunting,
// NoTaunting_DEPRECATED: 118,
HealingDebuff: 118,
PasstimePenaltyDebuff: 119,
GrappledToPlayer: 120,
// GrappledByPlayer: 121,
BASEJumperParachuteDeployed: 122,
GasPasser: 123,
DragonsFuryAfterburn: 124,
ThermalThrusterLaunched: 125,
LostFooting: 126,
ReducedAirControl: 127,
HalloweenHellHeal: 128,
Powerup_Dominant: 129
};