steamid
Version:
Exposes a SteamID object class for easy SteamID management
282 lines • 22.1 kB
JavaScript
"use strict";
const enums_1 = require("./enums");
class SteamID {
/**
* List of possible universes
*/
static get Universe() {
return enums_1.Universes;
}
/**
* List of possible types
*/
static get Type() {
return enums_1.Types;
}
/**
* List of named instances
*/
static get Instance() {
return enums_1.Instances;
}
/**
* Mapping of SteamID types to their characters
*/
static get TypeChars() {
return {
[SteamID.Type.INVALID]: 'I',
[SteamID.Type.INDIVIDUAL]: 'U',
[SteamID.Type.MULTISEAT]: 'M',
[SteamID.Type.GAMESERVER]: 'G',
[SteamID.Type.ANON_GAMESERVER]: 'A',
[SteamID.Type.PENDING]: 'P',
[SteamID.Type.CONTENT_SERVER]: 'C',
[SteamID.Type.CLAN]: 'g',
[SteamID.Type.CHAT]: 'T',
[SteamID.Type.ANON_USER]: 'a'
};
}
/**
* Mask to be used to get the AccountID out of a 64-bit SteamID
* @static
* @returns {number}
*/
static get AccountIDMask() { return 0xFFFFFFFF; }
/**
* Mask to be used to get the instance out of the upper 32 bits of a 64-bit SteamID
*/
static get AccountInstanceMask() { return 0x000FFFFF; }
/**
* Flags in SteamID instance for chat type IDs
*/
static get ChatInstanceFlags() {
return {
Clan: (SteamID.AccountInstanceMask + 1) >> 1,
Lobby: (SteamID.AccountInstanceMask + 1) >> 2,
MMSLobby: (SteamID.AccountInstanceMask + 1) >> 3
};
}
/**
* Create a new SteamID object.
* @param {string|BigInt} [input] - BigInt containing 64-bit SteamID, or string containing 64-bit SteamID/Steam2/Steam3 text formats. If omitted, creates a blank SteamID object.
*/
constructor(input) {
this.universe = SteamID.Universe.INVALID;
this.type = SteamID.Type.INVALID;
this.instance = SteamID.Instance.ALL;
this.accountid = 0;
if (!input) {
// Use the default invalid values
return;
}
let matches;
if (typeof input == 'bigint' || (typeof input == 'string' && input.match(/^\d+$/))) {
// 64-bit ID
let num = BigInt(input);
this.accountid = Number(num & BigInt(SteamID.AccountIDMask));
this.instance = Number((num >> 32n) & BigInt(SteamID.AccountInstanceMask));
this.type = Number((num >> 52n) & 0xfn);
this.universe = Number(num >> 56n);
}
else if (typeof input == 'string' && (matches = input.match(/^STEAM_([0-5]):([0-1]):([0-9]+)$/))) {
// Steam2 ID
let [_, universe, mod, accountid] = matches;
this.universe = parseInt(universe, 10) || SteamID.Universe.PUBLIC; // If it's 0, turn it into 1 for public
this.type = SteamID.Type.INDIVIDUAL;
this.instance = SteamID.Instance.DESKTOP;
this.accountid = (parseInt(accountid, 10) * 2) + parseInt(mod, 10);
}
else if (typeof input == 'string' && (matches = input.match(/^\[([a-zA-Z]):([0-5]):([0-9]+)(:[0-9]+)?]$/))) {
// Steam3 ID
let [_, typeChar, universe, accountid, instanceid] = matches;
this.universe = parseInt(universe, 10);
this.accountid = parseInt(accountid, 10);
if (instanceid) {
this.instance = parseInt(instanceid.substring(1), 10);
}
switch (typeChar) {
case 'U':
// Individual. If we don't have an explicit instanceid, default to DESKTOP.
this.type = SteamID.Type.INDIVIDUAL;
if (!instanceid) {
this.instance = SteamID.Instance.DESKTOP;
}
break;
case 'c':
this.instance |= SteamID.ChatInstanceFlags.Clan;
this.type = SteamID.Type.CHAT;
break;
case 'L':
this.instance |= SteamID.ChatInstanceFlags.Lobby;
this.type = SteamID.Type.CHAT;
break;
default:
this.type = getTypeFromChar(typeChar);
}
}
else {
throw new Error(`Unknown SteamID input format "${input}"`);
}
}
/**
* Creates a new SteamID object from an individual account ID.
*/
static fromIndividualAccountID(accountid) {
if (typeof accountid == 'bigint') {
accountid = Number(accountid);
}
let parsed = parseInt(accountid.toString(), 10);
if (isNaN(parsed)) {
// writes to stderr in node
console.error(`[steamid] Warning: SteamID.fromIndividualAccountID() called with NaN argument "${accountid}" (type "${typeof accountid}")`);
parsed = 0;
}
let sid = new SteamID();
sid.universe = SteamID.Universe.PUBLIC;
sid.type = SteamID.Type.INDIVIDUAL;
sid.instance = SteamID.Instance.DESKTOP;
sid.accountid = parsed;
return sid;
}
/**
* Returns whether Steam would consider a given ID to be "valid".
* This does not check whether the given ID belongs to a real account, nor does it check that the given ID is for
* an individual account or in the public universe.
*/
isValid() {
fixTypes(this);
if (this.type <= SteamID.Type.INVALID || this.type > SteamID.Type.ANON_USER) {
return false;
}
if (this.universe <= SteamID.Universe.INVALID || this.universe > SteamID.Universe.DEV) {
return false;
}
if (this.type == SteamID.Type.INDIVIDUAL && (this.accountid === 0 || this.instance > SteamID.Instance.WEB)) {
return false;
}
if (this.type == SteamID.Type.CLAN && (this.accountid === 0 || this.instance != SteamID.Instance.ALL)) {
return false;
}
// noinspection RedundantIfStatementJS
if (this.type == SteamID.Type.GAMESERVER && this.accountid === 0) {
return false;
}
return true;
}
/**
* Returns whether this SteamID is valid and belongs to an individual user in the public universe with a desktop instance.
* This is what most people think of when they think of a SteamID. Does not check whether the account actually exists.
*/
isValidIndividual() {
return this.universe == SteamID.Universe.PUBLIC
&& this.type == SteamID.Type.INDIVIDUAL
&& this.instance == SteamID.Instance.DESKTOP
&& this.isValid();
}
/**
* Checks whether the given ID is for a legacy group chat.
*/
isGroupChat() {
fixTypes(this);
return !!(this.type == SteamID.Type.CHAT && this.instance & SteamID.ChatInstanceFlags.Clan);
}
/**
* Check whether the given Id is for a game lobby.
*/
isLobby() {
fixTypes(this);
return !!(this.type == SteamID.Type.CHAT && (this.instance & SteamID.ChatInstanceFlags.Lobby || this.instance & SteamID.ChatInstanceFlags.MMSLobby));
}
/**
* Renders the ID in Steam2 format (e.g. "STEAM_0:0:23071901")
* @param {boolean} [newerFormat=false] - If true, use 1 as the first digit instead of 0 for the public universe
*/
steam2(newerFormat = false) {
fixTypes(this);
if (this.type != SteamID.Type.INDIVIDUAL) {
throw new Error('Can\'t get Steam2 rendered ID for non-individual ID');
}
else {
let universe = this.universe;
if (!newerFormat && universe === 1) {
universe = 0;
}
return `STEAM_${universe}:${this.accountid & 1}:${Math.floor(this.accountid / 2)}`;
}
}
/**
* Renders the ID in Steam2 format (e.g. "STEAM_0:0:23071901")
* @param {boolean} [newerFormat=false] - If true, use 1 as the first digit instead of 0 for the public universe
*/
getSteam2RenderedID(newerFormat = false) {
return this.steam2(newerFormat);
}
/**
* Renders the ID in Steam3 format (e.g. "[U:1:46143802]")
*/
steam3() {
fixTypes(this);
let typeChar = SteamID.TypeChars[this.type] || 'i';
if (this.instance & SteamID.ChatInstanceFlags.Clan) {
typeChar = 'c';
}
else if (this.instance & SteamID.ChatInstanceFlags.Lobby) {
typeChar = 'L';
}
let shouldRenderInstance = (this.type == SteamID.Type.ANON_GAMESERVER ||
this.type == SteamID.Type.MULTISEAT ||
(this.type == SteamID.Type.INDIVIDUAL &&
this.instance != SteamID.Instance.DESKTOP));
return `[${typeChar}:${this.universe}:${this.accountid}${shouldRenderInstance ? `:${this.instance}` : ''}]`;
}
/**
* Renders the ID in Steam3 format (e.g. "[U:1:46143802]")
*/
getSteam3RenderedID() {
return this.steam3();
}
/**
* Renders the ID in 64-bit decimal format, as a string (e.g. "76561198006409530")
*/
getSteamID64() {
return this.getBigIntID().toString();
}
/**
* Renders the ID in 64-bit decimal format, as a string (e.g. "76561198006409530")
*/
toString() {
return this.getSteamID64();
}
/**
* Renders the ID in 64-bit decimal format, as a BigInt (e.g. 76561198006409530n)
*/
getBigIntID() {
fixTypes(this);
let universe = BigInt(this.universe);
let type = BigInt(this.type);
let instance = BigInt(this.instance);
let accountid = BigInt(this.accountid);
return (universe << 56n) | (type << 52n) | (instance << 32n) | accountid;
}
}
// Private methods/functions
function getTypeFromChar(typeChar) {
let charEntry = Object.entries(SteamID.TypeChars).find(([entryType, entryChar]) => entryChar == typeChar);
return charEntry ? parseInt(charEntry[0], 10) : SteamID.Type.INVALID;
}
function fixTypes(sid) {
['universe', 'type', 'instance', 'accountid'].forEach((prop) => {
if (typeof sid[prop] == 'bigint') {
// Not sure how this would ever happen, but fix it
sid[prop] = Number(sid[prop]);
}
else {
let val = parseInt(sid[prop], 10);
if (!isNaN(val)) {
sid[prop] = val;
}
}
});
}
module.exports = SteamID;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLG1DQUF5RztBQUV6RyxNQUFNLE9BQU87SUFDWjs7T0FFRztJQUNILE1BQU0sS0FBSyxRQUFRO1FBQ2xCLE9BQU8saUJBQVMsQ0FBQztJQUNsQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNLEtBQUssSUFBSTtRQUNkLE9BQU8sYUFBSyxDQUFDO0lBQ2QsQ0FBQztJQUVEOztPQUVHO0lBQ0gsTUFBTSxLQUFLLFFBQVE7UUFDbEIsT0FBTyxpQkFBUyxDQUFDO0lBQ2xCLENBQUM7SUFFRDs7T0FFRztJQUNILE1BQU0sS0FBSyxTQUFTO1FBQ25CLE9BQU87WUFDTixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsR0FBRztZQUMzQixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsR0FBRztZQUM5QixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsR0FBRztZQUM3QixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsR0FBRztZQUM5QixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEVBQUUsR0FBRztZQUNuQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsR0FBRztZQUMzQixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLEVBQUUsR0FBRztZQUNsQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRztZQUN4QixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRztZQUN4QixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsR0FBRztTQUM3QixDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7O09B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