mirror of
https://github.com/DoctorMcKay/node-steamcommunity.git
synced 2026-08-19 13:13:28 +08:00
Compare commits
84 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
051d376508 | ||
|
|
913dff68ef | ||
|
|
754847ee88 | ||
|
|
645e03b89c | ||
|
|
aa302bc09e | ||
|
|
1c0f8d4bca | ||
|
|
a7bd694f4b | ||
|
|
9e380e71f5 | ||
|
|
e97e63fe6d | ||
|
|
f6c7c74ab6 | ||
|
|
8846082f60 | ||
|
|
eb609b5c42 | ||
|
|
238a36de0f | ||
|
|
c38111b61a | ||
|
|
0eb27a15d2 | ||
|
|
0ab3a94493 | ||
|
|
7c2ec65b8c | ||
|
|
8e761ffe6c | ||
|
|
06f04887fd | ||
|
|
e5f986a8bf | ||
|
|
5da6e40ebb | ||
|
|
0b8dd57a40 | ||
|
|
6f8456882a | ||
|
|
0b57b47ecb | ||
|
|
b5f50a6614 | ||
|
|
4257140c15 | ||
|
|
724badd175 | ||
|
|
a9455b0ff6 | ||
|
|
b3dfdd47d8 | ||
|
|
1efac6bc70 | ||
|
|
eacb85c711 | ||
|
|
8eab34bf18 | ||
|
|
b45e8d97ed | ||
|
|
6abb14a9bc | ||
|
|
6049d7a259 | ||
|
|
e0320b27d7 | ||
|
|
7986a87b3f | ||
|
|
cf7e5f8995 | ||
|
|
a03dad9507 | ||
|
|
7da7ecfc56 | ||
|
|
6bf3f26f2f | ||
|
|
dc2e5d09a7 | ||
|
|
d716e8a494 | ||
|
|
458a179852 | ||
|
|
f5d76527ba | ||
|
|
5875f47ebc | ||
|
|
d7095aa7c5 | ||
|
|
03e0a1bdac | ||
|
|
a51973c9b9 | ||
|
|
96d87ee8e6 | ||
|
|
7beef548dc | ||
|
|
6d9ebabb17 | ||
|
|
5d5d8548af | ||
|
|
b5142ad0cc | ||
|
|
3045a5d0cc | ||
|
|
2dcb123761 | ||
|
|
bd29d598b1 | ||
|
|
7e39715427 | ||
|
|
a97edfd492 | ||
|
|
68b1f21655 | ||
|
|
b4772baf39 | ||
|
|
47dc22ca0d | ||
|
|
3bba7025d4 | ||
|
|
e2f94cb1e7 | ||
|
|
acbd71666b | ||
|
|
3c35026a32 | ||
|
|
aca375d9da | ||
|
|
91285ba1c7 | ||
|
|
758b749487 | ||
|
|
a9b16cef1e | ||
|
|
c6ab392c37 | ||
|
|
4542793175 | ||
|
|
d18a0244ec | ||
|
|
b1c772d9b9 | ||
|
|
530bbcb9eb | ||
|
|
f7ebe68bd8 | ||
|
|
e2dae00af2 | ||
|
|
bbd80d4154 | ||
|
|
c180557f52 | ||
|
|
b3174b9f0b | ||
|
|
12f1ddf6a0 | ||
|
|
db3aa4ace8 | ||
|
|
f1b742dff4 | ||
|
|
444649ee8c |
13
.editorconfig
Normal file
13
.editorconfig
Normal file
@@ -0,0 +1,13 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
insert_final_newline = false
|
||||
trim_trailing_whitespace = false
|
||||
@@ -28,6 +28,7 @@ Submitting a pull request? Great! Thanks for contributing your time and code! Pl
|
||||
- Tabs for indentation
|
||||
- camelCase for variables and functions
|
||||
- Opening braces on the same line as the if/for/while statement
|
||||
- No omitting unnecessary braces
|
||||
- etc.
|
||||
- Please avoid breaking changes. If you make a breaking change that can be done in a backwards-compatible manner, I won't accept it.
|
||||
- Please don't increment the version number in `package.json`. I'll do that myself when I publish it to npm.
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Alexander Corn
|
||||
Copyright (c) 2015 Alex Corn
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -9,6 +9,8 @@ This module provides an easy interface for the Steam Community website. This mod
|
||||
|
||||
It supports Steam Guard and CAPTCHAs.
|
||||
|
||||
This reports anonymous usage statistics to the author. [See here](https://github.com/DoctorMcKay/node-stats-reporter) for more information.
|
||||
|
||||
**Have a question about the module or coding in general? *Do not create a GitHub issue.* GitHub issues are for feature
|
||||
requests and bug reports. Instead, post in the [dedicated forum](https://dev.doctormckay.com/forum/8-node-steamcommunity/).
|
||||
Such issues may be ignored!**
|
||||
|
||||
@@ -12,7 +12,7 @@ SteamCommunity.prototype.getMarketItem = function(appid, hashName, currency, cal
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var $ = Cheerio.load(body);
|
||||
if($('.market_listing_table_message') && $('.market_listing_table_message').text().trim() == 'There are no listings for this item.') {
|
||||
callback(new Error("There are no listings for this item."));
|
||||
@@ -35,7 +35,7 @@ function CMarketItem(appid, hashName, community, body, $) {
|
||||
this._hashName = hashName;
|
||||
this._community = community;
|
||||
this._$ = $;
|
||||
|
||||
|
||||
this._country = "US";
|
||||
var match = body.match(/var g_strCountryCode = "([^"]+)";/);
|
||||
if(match) {
|
||||
@@ -47,14 +47,14 @@ function CMarketItem(appid, hashName, community, body, $) {
|
||||
if(match) {
|
||||
this._language = match[1];
|
||||
}
|
||||
|
||||
|
||||
this.commodity = false;
|
||||
var match = body.match(/Market_LoadOrderSpread\(\s*(\d+)\s*\);/);
|
||||
match = body.match(/Market_LoadOrderSpread\(\s*(\d+)\s*\);/);
|
||||
if(match) {
|
||||
this.commodity = true;
|
||||
this.commodityID = parseInt(match[1], 10);
|
||||
}
|
||||
|
||||
|
||||
this.medianSalePrices = null;
|
||||
match = body.match(/var line1=([^;]+);/);
|
||||
if(match) {
|
||||
@@ -78,7 +78,8 @@ function CMarketItem(appid, hashName, community, body, $) {
|
||||
if (match) {
|
||||
try {
|
||||
this.assets = JSON.parse(match[1]);
|
||||
this.assets = this.assets['730']['2'];
|
||||
this.assets = this.assets[appid];
|
||||
this.assets = this.assets[Object.keys(this.assets)[0]];
|
||||
this.firstAsset = this.assets[Object.keys(this.assets)[0]];
|
||||
} catch (e) {
|
||||
// ignore
|
||||
@@ -112,29 +113,29 @@ CMarketItem.prototype.updatePriceForCommodity = function(currency, callback) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(body.success != 1) {
|
||||
if(callback) {
|
||||
callback(new Error("Error " + body.success));
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var match = (body.sell_order_summary || '').match(/<span class="market_commodity_orders_header_promote">(\d+)<\/span>/);
|
||||
if(match) {
|
||||
self.quantity = parseInt(match[1], 10);
|
||||
}
|
||||
|
||||
|
||||
self.buyQuantity = 0;
|
||||
match = (body.buy_order_summary || '').match(/<span class="market_commodity_orders_header_promote">(\d+)<\/span>/);
|
||||
if(match) {
|
||||
self.buyQuantity = parseInt(match[1], 10);
|
||||
}
|
||||
|
||||
|
||||
self.lowestPrice = parseInt(body.lowest_sell_order, 10);
|
||||
self.highestBuyOrder = parseInt(body.highest_buy_order, 10);
|
||||
|
||||
|
||||
// TODO: The tables?
|
||||
if(callback) {
|
||||
callback(null);
|
||||
|
||||
@@ -3,26 +3,26 @@ var Cheerio = require('cheerio');
|
||||
|
||||
SteamCommunity.prototype.marketSearch = function(options, callback) {
|
||||
var qs = {};
|
||||
|
||||
|
||||
if(typeof options === 'string') {
|
||||
qs.query = options;
|
||||
} else {
|
||||
qs.query = options.query || '';
|
||||
qs.appid = options.appid;
|
||||
qs.search_descriptions = options.searchDescriptions ? 1 : 0;
|
||||
|
||||
|
||||
if(qs.appid) {
|
||||
for(var i in options) {
|
||||
if(['query', 'appid', 'searchDescriptions'].indexOf(i) != -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// This is a tag
|
||||
qs['category_' + qs.appid + '_' + i + '[]'] = 'tag_' + options[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
qs.start = 0;
|
||||
qs.count = 100;
|
||||
qs.sort_column = 'price';
|
||||
@@ -80,10 +80,10 @@ SteamCommunity.prototype.marketSearch = function(options, callback) {
|
||||
|
||||
function CMarketSearchResult(row) {
|
||||
var match = row.attr('href').match(/\/market\/listings\/(\d+)\/([^\?\/]+)/);
|
||||
|
||||
|
||||
this.appid = parseInt(match[1], 10);
|
||||
this.market_hash_name = decodeURIComponent(match[2]);
|
||||
this.image = row.find('.market_listing_item_img').attr('src').match(/^https?:\/\/[^\/]+\/economy\/image\/[^\/]+\//)[0];
|
||||
this.image = ((row.find('.market_listing_item_img').attr('src') || "").match(/^https?:\/\/[^\/]+\/economy\/image\/[^\/]+\//) || [])[0];
|
||||
this.price = parseInt(row.find('.market_listing_their_price .market_table_value span.normal_price').text().replace(/[^\d]+/g, ''), 10);
|
||||
this.quantity = parseInt(row.find('.market_listing_num_listings_qty').text().replace(/[^\d]+/g, ''), 10);
|
||||
}
|
||||
|
||||
@@ -113,3 +113,39 @@ CSteamGroup.prototype.kick = function(steamID, callback) {
|
||||
CSteamGroup.prototype.getHistory = function(page, callback) {
|
||||
this._community.getGroupHistory(this.steamID, page, callback);
|
||||
};
|
||||
|
||||
|
||||
CSteamGroup.prototype.getAllComments = function(from, count, callback) {
|
||||
this._community.getAllGroupComments(this.steamID, from, count, callback);
|
||||
};
|
||||
|
||||
CSteamGroup.prototype.deleteComment = function(cid, callback) {
|
||||
this._community.deleteGroupComment(this.steamID, cid, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get requests to join this restricted group.
|
||||
* @param {function} callback - First argument is null/Error, second is array of SteamID objects
|
||||
*/
|
||||
CSteamGroup.prototype.getJoinRequests = function(callback) {
|
||||
this._community.getGroupJoinRequests(this.steamID, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Respond to one or more join requests to this restricted group.
|
||||
* @param {SteamID|string|SteamID[]|string[]} steamIDs - The SteamIDs of the users you want to approve or deny membership for (or a single value)
|
||||
* @param {boolean} approve - True to put them in the group, false to deny their membership
|
||||
* @param {function} callback - Takes only an Error object/null as the first argument
|
||||
*/
|
||||
CSteamGroup.prototype.respondToJoinRequests = function(steamIDs, approve, callback) {
|
||||
this._community.respondToGroupJoinRequests(this.steamID, steamIDs, approve, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Respond to *ALL* pending group-join requests for this group.
|
||||
* @param {boolean} approve - True to allow everyone who requested into the group, false to not
|
||||
* @param {function} callback - Takes only an Error object/null as the first argument
|
||||
*/
|
||||
CSteamGroup.prototype.respondToAllJoinRequests = function(approve, callback) {
|
||||
this._community.respondToAllGroupJoinRequests(this.steamID, approve, callback);
|
||||
};
|
||||
|
||||
@@ -1,32 +1,9 @@
|
||||
var SteamCommunity = require('../index.js');
|
||||
var SteamID = require('steamid');
|
||||
|
||||
SteamCommunity.ChatState = {
|
||||
"Offline": 0,
|
||||
"LoggingOn": 1,
|
||||
"LogOnFailed": 2,
|
||||
"LoggedOn": 3
|
||||
};
|
||||
|
||||
SteamCommunity.PersonaState = {
|
||||
"Offline": 0,
|
||||
"Online": 1,
|
||||
"Busy": 2,
|
||||
"Away": 3,
|
||||
"Snooze": 4,
|
||||
"LookingToTrade": 5,
|
||||
"LookingToPlay": 6,
|
||||
"Max": 7
|
||||
};
|
||||
|
||||
SteamCommunity.PersonaStateFlag = {
|
||||
"HasRichPresence": 1,
|
||||
"InJoinableGame": 2,
|
||||
|
||||
"OnlineUsingWeb": 256,
|
||||
"OnlineUsingMobile": 512,
|
||||
"OnlineUsingBigPicture": 1024
|
||||
};
|
||||
SteamCommunity.ChatState = require('../resources/EChatState.js');
|
||||
SteamCommunity.PersonaState = require('../resources/EPersonaState.js');
|
||||
SteamCommunity.PersonaStateFlag = require('../resources/EPersonaStateFlag.js');
|
||||
|
||||
SteamCommunity.prototype.chatLogon = function(interval, uiMode) {
|
||||
if(this.chatState == SteamCommunity.ChatState.LoggingOn || this.chatState == SteamCommunity.ChatState.LoggedOn) {
|
||||
@@ -181,7 +158,7 @@ SteamCommunity.prototype._chatPoll = function() {
|
||||
},
|
||||
"json": true
|
||||
}, function(err, response, body) {
|
||||
if(self.chatState == SteamCommunity.ChatState.Offline) {
|
||||
if (self.chatState == SteamCommunity.ChatState.Offline) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -242,12 +219,20 @@ SteamCommunity.prototype._relogWebChat = function() {
|
||||
};
|
||||
|
||||
SteamCommunity.prototype._chatUpdatePersona = function(steamID) {
|
||||
if (!this.chatFriends || this.chatState == SteamCommunity.ChatState.Offline) {
|
||||
return; // we no longer care
|
||||
}
|
||||
|
||||
this.emit('debug', 'Updating persona data for ' + steamID);
|
||||
var self = this;
|
||||
this.httpRequest({
|
||||
"uri": "https://steamcommunity.com/chat/friendstate/" + steamID.accountid,
|
||||
"json": true
|
||||
}, function(err, response, body) {
|
||||
if (!self.chatFriends || self.chatState == SteamCommunity.ChatState.Offline) {
|
||||
return; // welp
|
||||
}
|
||||
|
||||
if(err || response.statusCode != 200) {
|
||||
self.emit('debug', 'Chat update persona error: ' + (err ? err.message : "HTTP error " + response.statusCode));
|
||||
setTimeout(function() {
|
||||
|
||||
@@ -243,6 +243,10 @@ SteamCommunity.prototype.acceptAllConfirmations = function(time, confKey, allowK
|
||||
};
|
||||
|
||||
function request(community, url, key, time, tag, params, json, callback) {
|
||||
if (!community.steamID) {
|
||||
throw new Error("Must be logged in before trying to do anything with confirmations");
|
||||
}
|
||||
|
||||
params = params || {};
|
||||
params.p = SteamTotp.getDeviceID(community.steamID);
|
||||
params.a = community.steamID.getSteamID64();
|
||||
|
||||
@@ -2,6 +2,8 @@ var SteamCommunity = require('../index.js');
|
||||
var SteamID = require('steamid');
|
||||
var xml2js = require('xml2js');
|
||||
var Cheerio = require('cheerio');
|
||||
var Helpers = require('./helpers.js');
|
||||
var EResult = SteamCommunity.EResult;
|
||||
|
||||
SteamCommunity.prototype.getGroupMembers = function(gid, callback, members, link, addresses, addressIdx) {
|
||||
members = members || [];
|
||||
@@ -142,7 +144,7 @@ SteamCommunity.prototype.getAllGroupAnnouncements = function(gid, time, callback
|
||||
headline: announcement.title[0],
|
||||
content: announcement.description[0],
|
||||
date: new Date(announcement.pubDate[0]),
|
||||
author: announcement.author[0],
|
||||
author: (typeof announcement.author === 'undefined') ? null : announcement.author[0],
|
||||
aid: splitLink[splitLink.length - 1]
|
||||
}
|
||||
}).filter(function(announcement) {
|
||||
@@ -152,7 +154,7 @@ SteamCommunity.prototype.getAllGroupAnnouncements = function(gid, time, callback
|
||||
return callback(null, announcements);
|
||||
});
|
||||
}, "steamcommunity");
|
||||
}
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.postGroupAnnouncement = function(gid, headline, content, callback) {
|
||||
if(typeof gid === 'string') {
|
||||
@@ -493,7 +495,7 @@ SteamCommunity.prototype.getGroupHistory = function(gid, page, callback) {
|
||||
sid.universe = SteamID.Universe.PUBLIC;
|
||||
sid.type = SteamID.Type.INDIVIDUAL;
|
||||
sid.instance = SteamID.Instance.DESKTOP;
|
||||
sid.accountid = $(users[0]).data('miniprofile');
|
||||
sid.accountid = $(users[1]).data('miniprofile');
|
||||
data.actor = sid;
|
||||
}
|
||||
|
||||
@@ -517,3 +519,179 @@ SteamCommunity.prototype.getGroupHistory = function(gid, page, callback) {
|
||||
callback(null, output);
|
||||
}, "steamcommunity");
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.getAllGroupComments = function(gid, from, count, callback) {
|
||||
if (typeof gid === 'string') {
|
||||
gid = new SteamID(gid);
|
||||
}
|
||||
|
||||
var options = {
|
||||
"uri": "https://steamcommunity.com/comment/Clan/render/" + gid.getSteamID64() + "/-1/",
|
||||
"form": {
|
||||
"start": from,
|
||||
"count": count
|
||||
}
|
||||
};
|
||||
|
||||
var self = this;
|
||||
this.httpRequestPost(options, function(err, response, body) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
var comments = [];
|
||||
|
||||
var $ = Cheerio.load(JSON.parse(body).comments_html);
|
||||
|
||||
$(".commentthread_comment_content").each(function () {
|
||||
var comment = {};
|
||||
var cachedSelector;
|
||||
|
||||
var $selector = $(this).find(".commentthread_author_link");
|
||||
comment.authorName = $($selector).find("bdi").text();
|
||||
comment.authorId = $($selector).attr("href").replace(/https?:\/\/steamcommunity.com\/(id|profiles)\//, "");
|
||||
comment.date = Helpers.decodeSteamTime($(this).find(".commentthread_comment_timestamp").text().trim());
|
||||
|
||||
$selector = $(this).find(".commentthread_comment_text");
|
||||
comment.commentId = $($selector).attr("id").replace("comment_content_", "");
|
||||
comment.text = $($selector).html().trim();
|
||||
|
||||
comments.push(comment);
|
||||
});
|
||||
|
||||
callback(null, comments);
|
||||
}, "steamcommunity");
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.deleteGroupComment = function(gid, cid, callback) {
|
||||
if (typeof gid === 'string') {
|
||||
gid = new SteamID(gid);
|
||||
}
|
||||
|
||||
if (typeof cid !== 'string') {
|
||||
cid = cid.toString();
|
||||
}
|
||||
|
||||
var options = {
|
||||
"uri": "https://steamcommunity.com/comment/Clan/delete/" + gid.getSteamID64() + "/-1/",
|
||||
"form": {
|
||||
"sessionid": this.getSessionID(),
|
||||
"gidcomment": cid
|
||||
}
|
||||
};
|
||||
|
||||
var self = this;
|
||||
this.httpRequestPost(options, function(err, response, body) {
|
||||
if(!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
callback(err || null);
|
||||
}, "steamcommunity");
|
||||
};
|
||||
|
||||
/**
|
||||
* Get requests to join a restricted group.
|
||||
* @param {SteamID|string} gid - The SteamID of the group you want to manage
|
||||
* @param {function} callback - First argument is null/Error, second is array of SteamID objects
|
||||
*/
|
||||
SteamCommunity.prototype.getGroupJoinRequests = function(gid, callback) {
|
||||
if (typeof gid === 'string') {
|
||||
gid = new SteamID(gid);
|
||||
}
|
||||
|
||||
this.httpRequestGet("https://steamcommunity.com/gid/" + gid.getSteamID64() + "/joinRequestsManage", (err, res, body) => {
|
||||
if (!body) {
|
||||
callback(new Error("Malformed response"));
|
||||
return;
|
||||
}
|
||||
|
||||
var matches = body.match(/JoinRequests_ApproveDenyUser\(\W*['"](\d+)['"],\W0\W\)/g);
|
||||
if (!matches) {
|
||||
// no pending requests
|
||||
callback(null, []);
|
||||
return;
|
||||
}
|
||||
|
||||
var requests = [];
|
||||
for (var i = 0; i < matches.length; i++) {
|
||||
requests.push(new SteamID("[U:1:" + matches[i].match(/JoinRequests_ApproveDenyUser\(\W*['"](\d+)['"],\W0\W\)/)[1] + "]"));
|
||||
}
|
||||
|
||||
callback(null, requests);
|
||||
}, "steamcommunity");
|
||||
};
|
||||
|
||||
/**
|
||||
* Respond to one or more join requests to a restricted group.
|
||||
* @param {SteamID|string} gid - The SteamID of the group you want to manage
|
||||
* @param {SteamID|string|SteamID[]|string[]} steamIDs - The SteamIDs of the users you want to approve or deny membership for (or a single value)
|
||||
* @param {boolean} approve - True to put them in the group, false to deny their membership
|
||||
* @param {function} callback - Takes only an Error object/null as the first argument
|
||||
*/
|
||||
SteamCommunity.prototype.respondToGroupJoinRequests = function(gid, steamIDs, approve, callback) {
|
||||
if (typeof gid === 'string') {
|
||||
gid = new SteamID(gid);
|
||||
}
|
||||
|
||||
var rgAccounts = (!Array.isArray(steamIDs) ? [steamIDs] : steamIDs).map(sid => sid.toString());
|
||||
|
||||
this.httpRequestPost({
|
||||
"uri": "https://steamcommunity.com/gid/" + gid.getSteamID64() + "/joinRequestsManage",
|
||||
"form": {
|
||||
"rgAccounts": rgAccounts,
|
||||
"bapprove": approve ? "1" : "0",
|
||||
"json": "1",
|
||||
"sessionID": this.getSessionID()
|
||||
},
|
||||
"json": true
|
||||
}, (err, res, body) => {
|
||||
if (!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (body != EResult.OK) {
|
||||
var err = new Error(EResult[body] || ("Error " + body));
|
||||
err.eresult = body;
|
||||
callback(err);
|
||||
} else {
|
||||
callback(null);
|
||||
}
|
||||
}, "steamcommunity");
|
||||
};
|
||||
|
||||
/**
|
||||
* Respond to *ALL* pending group-join requests for a particular group.
|
||||
* @param {SteamID|string} gid - The SteamID of the group you want to manage
|
||||
* @param {boolean} approve - True to allow everyone who requested into the group, false to not
|
||||
* @param {function} callback - Takes only an Error object/null as the first argument
|
||||
*/
|
||||
SteamCommunity.prototype.respondToAllGroupJoinRequests = function(gid, approve, callback) {
|
||||
if (typeof gid === 'string') {
|
||||
gid = new SteamID(gid);
|
||||
}
|
||||
|
||||
this.httpRequestPost({
|
||||
"uri": "https://steamcommunity.com/gid/" + gid.getSteamID64() + "/joinRequestsManage",
|
||||
"form": {
|
||||
"bapprove": approve ? "1" : "0",
|
||||
"json": "1",
|
||||
"action": "bulkrespond",
|
||||
"sessionID": this.getSessionID()
|
||||
},
|
||||
"json": true
|
||||
}, (err, res, body) => {
|
||||
if (!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (body != EResult.OK) {
|
||||
var err = new Error(EResult[body] || ("Error " + body));
|
||||
err.eresult = body;
|
||||
callback(err);
|
||||
} else {
|
||||
callback(null);
|
||||
}
|
||||
}, "steamcommunity");
|
||||
};
|
||||
|
||||
@@ -13,11 +13,26 @@ exports.isSteamID = function(input) {
|
||||
};
|
||||
|
||||
exports.decodeSteamTime = function(time) {
|
||||
var parts = time.split('@');
|
||||
if (!parts[0].match(/,/)) {
|
||||
// no year, assume current year
|
||||
parts[0] += ", " + (new Date()).getFullYear();
|
||||
var date = new Date();
|
||||
|
||||
if (time.includes("@")) {
|
||||
var parts = time.split('@');
|
||||
if (!parts[0].includes(",")) {
|
||||
// no year, assume current year
|
||||
parts[0] += ", " + date.getFullYear();
|
||||
}
|
||||
|
||||
date = new Date(parts.join('@').replace(/(am|pm)/, ' $1') + " UTC"); // add a space so JS can decode it
|
||||
} else {
|
||||
// Relative date
|
||||
var amount = time.replace(/(\d) (minutes|hour|hours) ago/, "$1");
|
||||
|
||||
if(time.includes("minutes")) {
|
||||
date.setMinutes(date.getMinutes() - amount);
|
||||
} else if(time.match(/hour|hours/)) {
|
||||
date.setHours(date.getHours() - amount);
|
||||
}
|
||||
}
|
||||
|
||||
return new Date(parts.join('@').replace(/(am|pm)/, ' $1') + " UTC"); // add a space so JS can decode it
|
||||
return date;
|
||||
};
|
||||
|
||||
@@ -98,7 +98,7 @@ SteamCommunity.prototype._checkHttpError = function(err, response, callback, bod
|
||||
return err;
|
||||
}
|
||||
|
||||
if (response.statusCode == 403 && response.body && response.body.match(/<div id="parental_notice_instructions">Enter your PIN below to exit Family View.<\/div>/)) {
|
||||
if (response.statusCode == 403 && typeof response.body === 'string' && response.body.match(/<div id="parental_notice_instructions">Enter your PIN below to exit Family View.<\/div>/)) {
|
||||
err = new Error("Family View Restricted");
|
||||
callback(err, response, body);
|
||||
return err;
|
||||
|
||||
@@ -13,6 +13,11 @@ var Async = require('async');
|
||||
* With "prev" set, you will request 30 trades that were completed MORE RECENTLY than after_time (and optionally after_trade)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @deprecated Use GetTradeHistory instead: https://lab.xpaw.me/steam_api_documentation.html#IEconService_GetTradeHistory_v1
|
||||
* @param {object} options
|
||||
* @param {function} callback
|
||||
*/
|
||||
SteamCommunity.prototype.getInventoryHistory = function(options, callback) {
|
||||
if (typeof options === 'function') {
|
||||
callback = options;
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
var SteamCommunity = require('../index.js');
|
||||
var Cheerio = require('cheerio');
|
||||
|
||||
/**
|
||||
* Get a list of all apps on the market
|
||||
* @param {function} callback - First argument is null|Error, second is an object of appid => name
|
||||
*/
|
||||
SteamCommunity.prototype.getMarketApps = function(callback) {
|
||||
var self = this;
|
||||
this.httpRequest('https://steamcommunity.com/market/', function (err, response, body) {
|
||||
@@ -11,8 +15,8 @@ SteamCommunity.prototype.getMarketApps = function(callback) {
|
||||
|
||||
var $ = Cheerio.load(body);
|
||||
if ($('.market_search_game_button_group')) {
|
||||
apps = {};
|
||||
$('.market_search_game_button_group > a').each(function (i, element) {
|
||||
let apps = {};
|
||||
$('.market_search_game_button_group a.game_button').each(function (i, element) {
|
||||
var e = Cheerio.load(element);
|
||||
var name = e('.game_button_game_name').text().trim();
|
||||
var url = element.attribs.href;
|
||||
@@ -25,3 +29,149 @@ SteamCommunity.prototype.getMarketApps = function(callback) {
|
||||
}
|
||||
}, "steamcommunity");
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if an item is eligible to be turned into gems and if so, get its gem value
|
||||
* @param {int} appid
|
||||
* @param {int|string} assetid
|
||||
* @param {function} callback
|
||||
*/
|
||||
SteamCommunity.prototype.getGemValue = function(appid, assetid, callback) {
|
||||
this._myProfile({
|
||||
"endpoint": "ajaxgetgoovalue/",
|
||||
"qs": {
|
||||
"sessionid": this.getSessionID(),
|
||||
"appid": appid,
|
||||
"contextid": 6,
|
||||
"assetid": assetid
|
||||
},
|
||||
"checkHttpError": false,
|
||||
"json": true
|
||||
}, null, (err, res, body) => {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (body.success && body.success != SteamCommunity.EResult.OK) {
|
||||
let err = new Error(body.message || SteamCommunity.EResult[body.success]);
|
||||
err.eresult = err.code = body.success;
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!body.goo_value || !body.strTitle) {
|
||||
callback(new Error("Malformed response"));
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, {"promptTitle": body.strTitle, "gemValue": parseInt(body.goo_value, 10)});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Turn an eligible item into gems.
|
||||
* @param {int} appid
|
||||
* @param {int|string} assetid
|
||||
* @param {int} expectedGemsValue
|
||||
* @param {function} callback
|
||||
*/
|
||||
SteamCommunity.prototype.turnItemIntoGems = function(appid, assetid, expectedGemsValue, callback) {
|
||||
this._myProfile({
|
||||
"endpoint": "ajaxgrindintogoo/",
|
||||
"json": true,
|
||||
"checkHttpError": false
|
||||
}, {
|
||||
"appid": appid,
|
||||
"contextid": 6,
|
||||
"assetid": assetid,
|
||||
"goo_value_expected": expectedGemsValue,
|
||||
"sessionid": this.getSessionID()
|
||||
}, (err, res, body) => {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (body.success && body.success != SteamCommunity.EResult.OK) {
|
||||
let err = new Error(body.message || SteamCommunity.EResult[body.success]);
|
||||
err.eresult = err.code = body.success;
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!body['goo_value_received '] || !body.goo_value_total) { // lol valve
|
||||
callback(new Error("Malformed response"));
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, {"gemsReceived": parseInt(body['goo_value_received '], 10), "totalGems": parseInt(body.goo_value_total, 10)});
|
||||
})
|
||||
};
|
||||
|
||||
/**
|
||||
* Get details about a gift in your inventory.
|
||||
* @param {string} giftID
|
||||
* @param {function} callback
|
||||
*/
|
||||
SteamCommunity.prototype.getGiftDetails = function(giftID, callback) {
|
||||
this.httpRequestPost({
|
||||
"uri": "https://steamcommunity.com/gifts/" + giftID + "/validateunpack",
|
||||
"form": {
|
||||
"sessionid": this.getSessionID()
|
||||
},
|
||||
"json": true
|
||||
}, (err, res, body) => {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (body.success && body.success != SteamCommunity.EResult.OK) {
|
||||
let err = new Error(body.message || SteamCommunity.EResult[body.success]);
|
||||
err.eresult = err.code = body.success;
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!body.packageid || !body.gift_name) {
|
||||
callback(new Error("Malformed response"));
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, {
|
||||
"giftName": body.gift_name,
|
||||
"packageID": parseInt(body.packageid, 10),
|
||||
"owned": body.owned
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Unpack a gift in your inventory to your library.
|
||||
* @param {string} giftID
|
||||
* @param {function} callback
|
||||
*/
|
||||
SteamCommunity.prototype.redeemGift = function(giftID, callback) {
|
||||
this.httpRequestPost({
|
||||
"uri": "https://steamcommunity.com/gifts/" + giftID + "/unpack",
|
||||
"form": {
|
||||
"sessionid": this.getSessionID()
|
||||
},
|
||||
"json": true
|
||||
}, (err, res, body) => {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (body.success && body.success != SteamCommunity.EResult.OK) {
|
||||
let err = new Error(body.message || SteamCommunity.EResult[body.success]);
|
||||
err.eresult = err.code = body.success;
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -21,7 +21,7 @@ SteamCommunity.prototype.setupProfile = function(callback) {
|
||||
if(!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(err || response.statusCode != 200) {
|
||||
callback(err || new Error("HTTP error " + response.statusCode));
|
||||
} else {
|
||||
@@ -37,82 +37,82 @@ SteamCommunity.prototype.editProfile = function(settings, callback) {
|
||||
if(callback) {
|
||||
callback(err || new Error("HTTP error " + response.statusCode));
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var $ = Cheerio.load(body);
|
||||
var form = $('#editForm');
|
||||
if(!form) {
|
||||
if(callback) {
|
||||
callback(new Error("Malformed response"));
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var values = {};
|
||||
form.serializeArray().forEach(function(item) {
|
||||
values[item.name] = item.value;
|
||||
});
|
||||
|
||||
|
||||
for(var i in settings) {
|
||||
if(!settings.hasOwnProperty(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
switch(i) {
|
||||
case 'name':
|
||||
values.personaName = settings[i];
|
||||
break;
|
||||
|
||||
|
||||
case 'realName':
|
||||
values.real_name = settings[i];
|
||||
break;
|
||||
|
||||
|
||||
case 'summary':
|
||||
values.summary = settings[i];
|
||||
break;
|
||||
|
||||
|
||||
case 'country':
|
||||
values.country = settings[i];
|
||||
break;
|
||||
|
||||
|
||||
case 'state':
|
||||
values.state = settings[i];
|
||||
break;
|
||||
|
||||
|
||||
case 'city':
|
||||
values.city = settings[i];
|
||||
break;
|
||||
|
||||
|
||||
case 'customURL':
|
||||
values.customURL = settings[i];
|
||||
break;
|
||||
|
||||
|
||||
case 'background':
|
||||
// The assetid of our desired profile background
|
||||
values.profile_background = settings[i];
|
||||
break;
|
||||
|
||||
|
||||
case 'featuredBadge':
|
||||
// Currently, game badges aren't supported
|
||||
values.favorite_badge_badgeid = settings[i];
|
||||
break;
|
||||
|
||||
|
||||
case 'primaryGroup':
|
||||
if(typeof settings[i] === 'object' && settings[i].getSteamID64) {
|
||||
values.primary_group_steamid = settings[i].getSteamID64();
|
||||
} else {
|
||||
values.primary_group_steamid = new SteamID(settings[i]).getSteamID64();
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
|
||||
|
||||
// TODO: profile showcases
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
self._myProfile("edit", values, function(err, response, body) {
|
||||
if (settings.customURL) {
|
||||
delete self._profileURL;
|
||||
@@ -122,10 +122,10 @@ SteamCommunity.prototype.editProfile = function(settings, callback) {
|
||||
if(callback) {
|
||||
callback(err || new Error("HTTP error " + response.statusCode));
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Check for an error
|
||||
var $ = Cheerio.load(body);
|
||||
var error = $('#errorText .formRowFields');
|
||||
@@ -135,11 +135,11 @@ SteamCommunity.prototype.editProfile = function(settings, callback) {
|
||||
if(callback) {
|
||||
callback(new Error(error));
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(callback) {
|
||||
callback(null);
|
||||
}
|
||||
@@ -154,58 +154,58 @@ SteamCommunity.prototype.profileSettings = function(settings, callback) {
|
||||
if(callback) {
|
||||
callback(err || new Error("HTTP error " + response.statusCode));
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var $ = Cheerio.load(body);
|
||||
var form = $('#editForm');
|
||||
if(!form) {
|
||||
if(callback) {
|
||||
callback(new Error("Malformed response"));
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var values = {};
|
||||
form.serializeArray().forEach(function(item) {
|
||||
values[item.name] = item.value;
|
||||
});
|
||||
|
||||
|
||||
for(var i in settings) {
|
||||
if(!settings.hasOwnProperty(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
switch(i) {
|
||||
case 'profile':
|
||||
values.privacySetting = settings[i];
|
||||
break;
|
||||
|
||||
|
||||
case 'comments':
|
||||
values.commentSetting = CommentPrivacyState[settings[i]];
|
||||
break;
|
||||
|
||||
|
||||
case 'inventory':
|
||||
values.inventoryPrivacySetting = settings[i];
|
||||
break;
|
||||
|
||||
|
||||
case 'inventoryGifts':
|
||||
values.inventoryGiftPrivacy = settings[i] ? 1 : 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
self._myProfile("edit/settings", values, function(err, response, body) {
|
||||
if(err || response.statusCode != 200) {
|
||||
if(callback) {
|
||||
callback(err || new Error("HTTP error " + response.statusCode));
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(callback) {
|
||||
callback(null);
|
||||
}
|
||||
@@ -219,6 +219,12 @@ SteamCommunity.prototype.uploadAvatar = function(image, format, callback) {
|
||||
format = null;
|
||||
}
|
||||
|
||||
// are we logged in?
|
||||
if (!this.steamID) {
|
||||
callback(new Error("Not Logged In"));
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
|
||||
if(image instanceof Buffer) {
|
||||
|
||||
@@ -218,16 +218,16 @@ SteamCommunity.prototype.getUserAliases = function(userID, callback) {
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.getUserInventoryContexts = function(userID, callback) {
|
||||
if(typeof userID === 'string') {
|
||||
if (typeof userID === 'string') {
|
||||
userID = new SteamID(userID);
|
||||
}
|
||||
|
||||
if(typeof userID === 'function') {
|
||||
if (typeof userID === 'function') {
|
||||
callback = userID;
|
||||
userID = this.steamID;
|
||||
}
|
||||
|
||||
if(!userID) {
|
||||
if (!userID) {
|
||||
callback(new Error("No SteamID specified and not logged in"));
|
||||
return;
|
||||
}
|
||||
@@ -240,8 +240,19 @@ SteamCommunity.prototype.getUserInventoryContexts = function(userID, callback) {
|
||||
}
|
||||
|
||||
var match = body.match(/var g_rgAppContextData = ([^\n]+);\r?\n/);
|
||||
if(!match) {
|
||||
callback(new Error("Malformed response"));
|
||||
if (!match) {
|
||||
var errorMessage = "Malformed response";
|
||||
|
||||
if(body.match(/0 items in their inventory\./)){
|
||||
callback(null, {});
|
||||
return;
|
||||
}else if(body.match(/inventory is currently private\./)){
|
||||
errorMessage = "Private inventory";
|
||||
}else if(body.match(/profile\_private\_info/)){
|
||||
errorMessage = "Private profile";
|
||||
}
|
||||
|
||||
callback(new Error(errorMessage));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -340,15 +351,21 @@ SteamCommunity.prototype.getUserInventory = function(userID, appID, contextID, t
|
||||
* @param {int} appID - The Steam application ID of the game for which you want an inventory
|
||||
* @param {int} contextID - The ID of the "context" within the game you want to retrieve
|
||||
* @param {boolean} tradableOnly - true to get only tradable items and currencies
|
||||
* @param {string} [language] - The language of item descriptions to return. Omit for default (which may either be English or your account's chosen language)
|
||||
* @param {function} callback
|
||||
*/
|
||||
SteamCommunity.prototype.getUserInventoryContents = function(userID, appID, contextID, tradableOnly, callback) {
|
||||
SteamCommunity.prototype.getUserInventoryContents = function(userID, appID, contextID, tradableOnly, language, callback) {
|
||||
var self = this;
|
||||
|
||||
if(typeof userID === 'string') {
|
||||
if (typeof userID === 'string') {
|
||||
userID = new SteamID(userID);
|
||||
}
|
||||
|
||||
if (typeof language === 'function') {
|
||||
callback = language;
|
||||
language = "english";
|
||||
}
|
||||
|
||||
var pos = 1;
|
||||
get([], []);
|
||||
|
||||
@@ -359,7 +376,7 @@ SteamCommunity.prototype.getUserInventoryContents = function(userID, appID, cont
|
||||
"Referer": "https://steamcommunity.com/profiles/" + userID.getSteamID64() + "/inventory"
|
||||
},
|
||||
"qs": {
|
||||
"l": "english", // Default language
|
||||
"l": language, // Default language
|
||||
"count": 5000, // Max items per 'page'
|
||||
"start_assetid": start
|
||||
},
|
||||
@@ -368,7 +385,7 @@ SteamCommunity.prototype.getUserInventoryContents = function(userID, appID, cont
|
||||
if (err) {
|
||||
if (err.message == "HTTP error 403" && body === null) {
|
||||
// 403 with a body of "null" means the inventory/profile is private.
|
||||
if(userID.getSteamID64() == self.steamID.getSteamID64()) {
|
||||
if (self.steamID && userID.getSteamID64() == self.steamID.getSteamID64()) {
|
||||
// We can never get private profile error for our own inventory!
|
||||
self._notifySessionExpired(err);
|
||||
}
|
||||
@@ -431,20 +448,16 @@ SteamCommunity.prototype.getUserInventoryContents = function(userID, appID, cont
|
||||
var quickDescriptionLookup = {};
|
||||
|
||||
function getDescription(descriptions, classID, instanceID) {
|
||||
instanceID = instanceID || '0'; // instanceID can be undefined, in which case it's 0.
|
||||
|
||||
var key = classID + '_' + instanceID;
|
||||
var key = classID + '_' + (instanceID || '0'); // instanceID can be undefined, in which case it's 0.
|
||||
|
||||
if (quickDescriptionLookup[key]) {
|
||||
return quickDescriptionLookup[key];
|
||||
}
|
||||
|
||||
for (var i = 0; i < descriptions.length; i++) {
|
||||
quickDescriptionLookup[key] = descriptions[i];
|
||||
|
||||
if (descriptions[i].classid == classID && descriptions[i].instanceid == instanceID) {
|
||||
return descriptions[i];
|
||||
}
|
||||
quickDescriptionLookup[descriptions[i].classid + '_' + (descriptions[i].instanceid || '0')] = descriptions[i];
|
||||
}
|
||||
|
||||
return quickDescriptionLookup[key];
|
||||
}
|
||||
};
|
||||
|
||||
@@ -14,6 +14,10 @@ SteamCommunity.prototype.getWebApiKey = function(domain, callback) {
|
||||
if(body.match(/<h2>Access Denied<\/h2>/)) {
|
||||
return callback(new Error("Access Denied"));
|
||||
}
|
||||
|
||||
if(body.match(/You must have a validated email address to create a Steam Web API key./)) {
|
||||
return callback(new Error("You must have a validated email address to create a Steam Web API key."));
|
||||
}
|
||||
|
||||
var match = body.match(/<p>Key: ([0-9A-F]+)<\/p>/);
|
||||
if(match) {
|
||||
|
||||
@@ -79,7 +79,7 @@ function doLogin(accountName, password, authCode, captcha) {
|
||||
|
||||
console.log("Writing secrets to twofactor_" + community.steamID.getSteamID64() + ".json");
|
||||
console.log("Revocation code: " + response.revocation_code);
|
||||
fs.writeFile("twofactor_" + community.steamID.getSteamID64() + ".json", JSON.stringify(response, null, "\t"));
|
||||
fs.writeFileSync("twofactor_" + community.steamID.getSteamID64() + ".json", JSON.stringify(response, null, "\t"));
|
||||
|
||||
promptActivationCode(response);
|
||||
});
|
||||
|
||||
205
index.js
205
index.js
@@ -1,21 +1,20 @@
|
||||
require('@doctormckay/stats-reporter').setup(require('./package.json'));
|
||||
|
||||
var Request = require('request');
|
||||
var RSA = require('node-bignumber').Key;
|
||||
var hex2b64 = require('node-bignumber').hex2b64;
|
||||
var SteamID = require('steamid');
|
||||
|
||||
const USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36";
|
||||
const USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36";
|
||||
|
||||
require('util').inherits(SteamCommunity, require('events').EventEmitter);
|
||||
|
||||
module.exports = SteamCommunity;
|
||||
|
||||
SteamCommunity.SteamID = SteamID;
|
||||
SteamCommunity.ConfirmationType = {
|
||||
// 1 is unknown, possibly "Invalid"
|
||||
"Trade": 2,
|
||||
"MarketListing": 3
|
||||
// 4 is opt-out or other like account confirmation?
|
||||
};
|
||||
SteamCommunity.ConfirmationType = require('./resources/EConfirmationType.js');
|
||||
SteamCommunity.EResult = require('./resources/EResult.js')
|
||||
|
||||
|
||||
function SteamCommunity(options) {
|
||||
options = options || {};
|
||||
@@ -45,7 +44,7 @@ function SteamCommunity(options) {
|
||||
defaults.localAddress = options.localAddress;
|
||||
}
|
||||
|
||||
this.request = options.request || Request.defaults();
|
||||
this.request = options.request || Request.defaults({"forever": true}); // "forever" indicates that we want a keep-alive agent
|
||||
this.request = this.request.defaults(defaults);
|
||||
|
||||
// English
|
||||
@@ -64,23 +63,30 @@ SteamCommunity.prototype.login = function(details, callback) {
|
||||
var parts = details.steamguard.split('||');
|
||||
this._setCookie(Request.cookie('steamMachineAuth' + parts[0] + '=' + encodeURIComponent(parts[1])), true);
|
||||
}
|
||||
|
||||
|
||||
var disableMobile = details.disableMobile;
|
||||
|
||||
var self = this;
|
||||
|
||||
// Delete the cache
|
||||
delete self._profileURL;
|
||||
|
||||
// headers required to convince steam that we're logging in from a mobile device so that we can get the oAuth data
|
||||
var mobileHeaders = {
|
||||
"X-Requested-With": "com.valvesoftware.android.steam.community",
|
||||
"Referer": "https://steamcommunity.com/mobilelogin?oauth_client_id=DE45CD61&oauth_scope=read_profile%20write_profile%20read_client%20write_client",
|
||||
"User-Agent": "Mozilla/5.0 (Linux; U; Android 4.1.1; en-us; Google Nexus 4 - 4.1.1 - API 16 - 768x1280 Build/JRO03S) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
|
||||
"Accept": "text/javascript, text/html, application/xml, text/xml, */*"
|
||||
};
|
||||
var mobileHeaders = {};
|
||||
if (!disableMobile) {
|
||||
mobileHeaders = {
|
||||
"X-Requested-With": "com.valvesoftware.android.steam.community",
|
||||
"Referer": "https://steamcommunity.com/mobilelogin?oauth_client_id=DE45CD61&oauth_scope=read_profile%20write_profile%20read_client%20write_client",
|
||||
"User-Agent": "Mozilla/5.0 (Linux; U; Android 4.1.1; en-us; Google Nexus 4 - 4.1.1 - API 16 - 768x1280 Build/JRO03S) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
|
||||
"Accept": "text/javascript, text/html, application/xml, text/xml, */*"
|
||||
};
|
||||
|
||||
this._setCookie(Request.cookie("mobileClientVersion=0 (2.1.3)"));
|
||||
this._setCookie(Request.cookie("mobileClient=android"));
|
||||
} else {
|
||||
mobileHeaders = {"Referer": "https://steamcommunity.com/login"};
|
||||
}
|
||||
|
||||
this._setCookie(Request.cookie("mobileClientVersion=0 (2.1.3)"));
|
||||
this._setCookie(Request.cookie("mobileClient=android"));
|
||||
|
||||
this.httpRequestPost("https://steamcommunity.com/login/getrsakey/", {
|
||||
"form": {"username": details.accountName},
|
||||
"headers": mobileHeaders,
|
||||
@@ -93,33 +99,39 @@ SteamCommunity.prototype.login = function(details, callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!body.publickey_mod || !body.publickey_exp) {
|
||||
if (!body.publickey_mod || !body.publickey_exp) {
|
||||
deleteMobileCookies();
|
||||
callback(new Error("Invalid RSA key received"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var key = new RSA();
|
||||
key.setPublic(body.publickey_mod, body.publickey_exp);
|
||||
|
||||
|
||||
var formObj = {
|
||||
"captcha_text": details.captcha || "",
|
||||
"captchagid": self._captchaGid,
|
||||
"emailauth": details.authCode || "",
|
||||
"emailsteamid": "",
|
||||
"password": hex2b64(key.encrypt(details.password)),
|
||||
"remember_login": "true",
|
||||
"rsatimestamp": body.timestamp,
|
||||
"twofactorcode": details.twoFactorCode || "",
|
||||
"username": details.accountName,
|
||||
"loginfriendlyname": "",
|
||||
"donotcache": Date.now()
|
||||
};
|
||||
|
||||
if(!disableMobile){
|
||||
formObj.oauth_client_id = "DE45CD61";
|
||||
formObj.oauth_scope = "read_profile write_profile read_client write_client";
|
||||
formObj.loginfriendlyname = "#login_emailauth_friendlyname_mobile";
|
||||
}
|
||||
|
||||
self.httpRequestPost({
|
||||
"uri": "https://steamcommunity.com/login/dologin/",
|
||||
"json": true,
|
||||
"form": {
|
||||
"captcha_text": details.captcha || "",
|
||||
"captchagid": self._captchaGid,
|
||||
"emailauth": details.authCode || "",
|
||||
"emailsteamid": "",
|
||||
"password": hex2b64(key.encrypt(details.password)),
|
||||
"remember_login": "true",
|
||||
"rsatimestamp": body.timestamp,
|
||||
"twofactorcode": details.twoFactorCode || "",
|
||||
"username": details.accountName,
|
||||
"oauth_client_id": "DE45CD61",
|
||||
"oauth_scope": "read_profile write_profile read_client write_client",
|
||||
"loginfriendlyname": "#login_emailauth_friendlyname_mobile",
|
||||
"donotcache": Date.now()
|
||||
},
|
||||
"form": formObj,
|
||||
"headers": mobileHeaders
|
||||
}, function(err, response, body) {
|
||||
deleteMobileCookies();
|
||||
@@ -130,38 +142,51 @@ SteamCommunity.prototype.login = function(details, callback) {
|
||||
}
|
||||
|
||||
var error;
|
||||
if(!body.success && body.emailauth_needed) {
|
||||
if (!body.success && body.emailauth_needed) {
|
||||
// Steam Guard (email)
|
||||
error = new Error("SteamGuard");
|
||||
error.emaildomain = body.emaildomain;
|
||||
|
||||
|
||||
callback(error);
|
||||
} else if(!body.success && body.requires_twofactor) {
|
||||
} else if (!body.success && body.requires_twofactor) {
|
||||
// Steam Guard (app)
|
||||
callback(new Error("SteamGuardMobile"));
|
||||
} else if(!body.success && body.captcha_needed && body.message.match(/Please verify your humanity/)) {
|
||||
} else if (!body.success && body.captcha_needed && body.message.match(/Please verify your humanity/)) {
|
||||
error = new Error("CAPTCHA");
|
||||
error.captchaurl = "https://steamcommunity.com/login/rendercaptcha/?gid=" + body.captcha_gid;
|
||||
|
||||
|
||||
self._captchaGid = body.captcha_gid;
|
||||
|
||||
|
||||
callback(error);
|
||||
} else if(!body.success) {
|
||||
} else if (!body.success) {
|
||||
callback(new Error(body.message || "Unknown error"));
|
||||
} else if(!body.oauth) {
|
||||
} else if (!disableMobile && !body.oauth) {
|
||||
callback(new Error("Malformed response"));
|
||||
} else {
|
||||
var sessionID = generateSessionID();
|
||||
var oAuth = JSON.parse( body.oauth );
|
||||
var oAuth;
|
||||
self._setCookie(Request.cookie('sessionid=' + sessionID));
|
||||
|
||||
self.steamID = new SteamID(oAuth.steamid);
|
||||
self.oAuthToken = oAuth.oauth_token;
|
||||
|
||||
var cookies = self._jar.getCookieString("https://steamcommunity.com").split(';').map(function(cookie) {
|
||||
return cookie.trim();
|
||||
});
|
||||
|
||||
|
||||
if (!disableMobile){
|
||||
oAuth = JSON.parse(body.oauth);
|
||||
self.steamID = new SteamID(oAuth.steamid);
|
||||
self.oAuthToken = oAuth.oauth_token;
|
||||
}else{
|
||||
for(var i = 0; i < cookies.length; i++) {
|
||||
var parts = cookies[i].split('=');
|
||||
if(parts[0] == 'steamLogin') {
|
||||
self.steamID = new SteamID(decodeURIComponent(parts[1]).split('||')[0])
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
self.oAuthToken = null;
|
||||
}
|
||||
|
||||
// Find the Steam Guard cookie
|
||||
var steamguard = null;
|
||||
for(var i = 0; i < cookies.length; i++) {
|
||||
@@ -173,8 +198,8 @@ SteamCommunity.prototype.login = function(details, callback) {
|
||||
}
|
||||
|
||||
self.setCookies(cookies);
|
||||
|
||||
callback(null, sessionID, cookies, steamguard, oAuth.oauth_token);
|
||||
|
||||
callback(null, sessionID, cookies, steamguard, disableMobile ? null : oAuth.oauth_token);
|
||||
}
|
||||
}, "steamcommunity");
|
||||
}, "steamcommunity");
|
||||
@@ -253,7 +278,7 @@ SteamCommunity.prototype.getSessionID = function() {
|
||||
return decodeURIComponent(match[2]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var sessionID = generateSessionID();
|
||||
this._setCookie(Request.cookie('sessionid=' + sessionID));
|
||||
return sessionID;
|
||||
@@ -275,22 +300,34 @@ SteamCommunity.prototype.parentalUnlock = function(pin, callback) {
|
||||
if(!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!body || typeof body.success !== 'boolean') {
|
||||
|
||||
if (!body || typeof body.success !== 'boolean') {
|
||||
callback("Invalid response");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!body.success) {
|
||||
callback("Incorrect PIN");
|
||||
|
||||
if (!body.success) {
|
||||
switch (body.eresult) {
|
||||
case 15:
|
||||
callback("Incorrect PIN");
|
||||
break;
|
||||
|
||||
case 25:
|
||||
callback("Too many invalid PIN attempts");
|
||||
break;
|
||||
|
||||
default:
|
||||
callback("Error " + body.eresult);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
callback();
|
||||
}.bind(this), "steamcommunity");
|
||||
};
|
||||
@@ -310,7 +347,7 @@ SteamCommunity.prototype.getNotifications = function(callback) {
|
||||
callback(new Error("Malformed response"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var notifications = {
|
||||
"trades": body.notifications[1] || 0,
|
||||
"gameTurns": body.notifications[2] || 0,
|
||||
@@ -350,16 +387,49 @@ SteamCommunity.prototype.loggedIn = function(callback) {
|
||||
callback(err || new Error("HTTP error " + response.statusCode));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(response.statusCode == 403) {
|
||||
callback(null, true, true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
callback(null, !!response.headers.location.match(/steamcommunity\.com(\/(id|profiles)\/[^\/]+)\/?/), false);
|
||||
}, "steamcommunity");
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.getTradeURL = function(callback) {
|
||||
this._myProfile("/tradeoffers/privacy", null, (err, response, body) => {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
var match = body.match(/https?:\/\/(www.)?steamcommunity.com\/tradeoffer\/new\/?\?partner=\d+(&|&)token=([a-zA-Z0-9-_]+)/);
|
||||
if (match) {
|
||||
var token = match[3];
|
||||
callback(null, match[0], token);
|
||||
} else {
|
||||
callback(new Error("Malformed response"));
|
||||
}
|
||||
}, "steamcommunity");
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.changeTradeURL = function(callback) {
|
||||
this._myProfile("/tradeoffers/newtradeurl", {"sessionid": this.getSessionID()}, (err, response, body) => {
|
||||
if (!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!body || typeof body !== "string" || body.length < 3 || body.indexOf('"') !== 0) {
|
||||
callback(new Error("Malformed response"));
|
||||
return;
|
||||
}
|
||||
|
||||
var newToken = body.replace(/"/g, ''); //"t1o2k3e4n" => t1o2k3e4n
|
||||
callback(null, "https://steamcommunity.com/tradeoffer/new/?partner=" + this.steamID.accountid + "&token=" + newToken, newToken);
|
||||
}, "steamcommunity");
|
||||
};
|
||||
|
||||
SteamCommunity.prototype._myProfile = function(endpoint, form, callback) {
|
||||
var self = this;
|
||||
|
||||
@@ -381,17 +451,16 @@ SteamCommunity.prototype._myProfile = function(endpoint, form, callback) {
|
||||
self._profileURL = match[1];
|
||||
setTimeout(function () {
|
||||
delete self._profileURL; // delete the cache
|
||||
}, 60000);
|
||||
}, 60000).unref();
|
||||
|
||||
completeRequest(match[1]);
|
||||
}, "steamcommunity");
|
||||
}
|
||||
|
||||
function completeRequest(url) {
|
||||
var options = {
|
||||
"uri": "https://steamcommunity.com" + url + "/" + endpoint,
|
||||
"method": "GET"
|
||||
};
|
||||
var options = endpoint.endpoint ? endpoint : {};
|
||||
options.uri = "https://steamcommunity.com" + url + "/" + (endpoint.endpoint || endpoint);
|
||||
options.method = "GET";
|
||||
|
||||
if (form) {
|
||||
options.method = "POST";
|
||||
@@ -420,4 +489,4 @@ require('./classes/CSteamUser.js');
|
||||
/**
|
||||
@callback SteamCommunity~genericErrorCallback
|
||||
@param {Error|null} err - An Error object on failure, or null on success
|
||||
*/
|
||||
*/
|
||||
|
||||
15
package.json
15
package.json
@@ -1,19 +1,28 @@
|
||||
{
|
||||
"name": "steamcommunity",
|
||||
"version": "3.30.4",
|
||||
"version": "3.35.2",
|
||||
"description": "Provides an interface for logging into and interacting with the Steam Community website",
|
||||
"keywords": ["steam", "steam community"],
|
||||
"keywords": [
|
||||
"steam",
|
||||
"steam community"
|
||||
],
|
||||
"homepage": "https://github.com/DoctorMcKay/node-steamcommunity",
|
||||
"bugs": {
|
||||
"url": "https://github.com/DoctorMcKay/node-steamcommunity/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"author": {
|
||||
"name": "Alex Corn",
|
||||
"email": "mckay@doctormckay.com",
|
||||
"url": "https://www.doctormckay.com"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/DoctorMcKay/node-steamcommunity.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"request": "^2.61.0",
|
||||
"@doctormckay/stats-reporter": "^1.0.2",
|
||||
"request": "^2.81.0",
|
||||
"node-bignumber": "^1.2.1",
|
||||
"steamid": "^1.0.0",
|
||||
"xml2js": "^0.4.11",
|
||||
|
||||
14
resources/EChatState.js
Normal file
14
resources/EChatState.js
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* @enum EChatState
|
||||
*/
|
||||
module.exports = {
|
||||
"Offline": 0,
|
||||
"LoggingOn": 1,
|
||||
"LogOnFailed": 2,
|
||||
"LoggedOn": 3,
|
||||
|
||||
"0": "Offline",
|
||||
"1": "LoggingOn",
|
||||
"2": "LogOnFailed",
|
||||
"3": "LoggedOn"
|
||||
};
|
||||
12
resources/EConfirmationType.js
Normal file
12
resources/EConfirmationType.js
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* @enum EConfirmationType
|
||||
*/
|
||||
module.exports = {
|
||||
// 1 is unknown, possibly "Invalid"
|
||||
"Trade": 2,
|
||||
"MarketListing": 3,
|
||||
// 4 is opt-out or other like account confirmation?
|
||||
|
||||
"2": "Trade",
|
||||
"3": "MarketListing"
|
||||
};
|
||||
23
resources/EPersonaState.js
Normal file
23
resources/EPersonaState.js
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* @enum EPersonaState
|
||||
*/
|
||||
module.exports = {
|
||||
"Offline": 0,
|
||||
"Online": 1,
|
||||
"Busy": 2,
|
||||
"Away": 3,
|
||||
"Snooze": 4,
|
||||
"LookingToTrade": 5,
|
||||
"LookingToPlay": 6,
|
||||
"Max": 7,
|
||||
|
||||
// Value-to-name mapping for convenience
|
||||
"0": "Offline",
|
||||
"1": "Online",
|
||||
"2": "Busy",
|
||||
"3": "Away",
|
||||
"4": "Snooze",
|
||||
"5": "LookingToTrade",
|
||||
"6": "LookingToPlay",
|
||||
"7": "Max",
|
||||
};
|
||||
27
resources/EPersonaStateFlag.js
Normal file
27
resources/EPersonaStateFlag.js
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @enum EPersonaStateFlag
|
||||
*/
|
||||
module.exports = {
|
||||
"HasRichPresence": 1,
|
||||
"InJoinableGame": 2,
|
||||
"Golden": 4, // removed "no longer has any effect"
|
||||
"OnlineUsingWeb": 256, // removed "renamed to ClientTypeWeb"
|
||||
"ClientTypeWeb": 256,
|
||||
"OnlineUsingMobile": 512, // removed "renamed to ClientTypeMobile"
|
||||
"ClientTypeMobile": 512,
|
||||
"OnlineUsingBigPicture": 1024, // removed "renamed to ClientTypeTenfoot"
|
||||
"ClientTypeTenfoot": 1024,
|
||||
"OnlineUsingVR": 2048, // removed "renamed to ClientTypeVR"
|
||||
"ClientTypeVR": 2048,
|
||||
"LaunchTypeGamepad": 4096,
|
||||
|
||||
// Value-to-name mapping for convenience
|
||||
"1": "HasRichPresence",
|
||||
"2": "InJoinableGame",
|
||||
"4": "Golden",
|
||||
"256": "ClientTypeWeb",
|
||||
"512": "ClientTypeMobile",
|
||||
"1024": "ClientTypeTenfoot",
|
||||
"2048": "ClientTypeVR",
|
||||
"4096": "LaunchTypeGamepad",
|
||||
};
|
||||
232
resources/EResult.js
Normal file
232
resources/EResult.js
Normal file
@@ -0,0 +1,232 @@
|
||||
/**
|
||||
* @enum EResult
|
||||
*/
|
||||
module.exports = {
|
||||
"Invalid": 0,
|
||||
"OK": 1,
|
||||
"Fail": 2,
|
||||
"NoConnection": 3,
|
||||
"InvalidPassword": 5,
|
||||
"LoggedInElsewhere": 6,
|
||||
"InvalidProtocolVer": 7,
|
||||
"InvalidParam": 8,
|
||||
"FileNotFound": 9,
|
||||
"Busy": 10,
|
||||
"InvalidState": 11,
|
||||
"InvalidName": 12,
|
||||
"InvalidEmail": 13,
|
||||
"DuplicateName": 14,
|
||||
"AccessDenied": 15,
|
||||
"Timeout": 16,
|
||||
"Banned": 17,
|
||||
"AccountNotFound": 18,
|
||||
"InvalidSteamID": 19,
|
||||
"ServiceUnavailable": 20,
|
||||
"NotLoggedOn": 21,
|
||||
"Pending": 22,
|
||||
"EncryptionFailure": 23,
|
||||
"InsufficientPrivilege": 24,
|
||||
"LimitExceeded": 25,
|
||||
"Revoked": 26,
|
||||
"Expired": 27,
|
||||
"AlreadyRedeemed": 28,
|
||||
"DuplicateRequest": 29,
|
||||
"AlreadyOwned": 30,
|
||||
"IPNotFound": 31,
|
||||
"PersistFailed": 32,
|
||||
"LockingFailed": 33,
|
||||
"LogonSessionReplaced": 34,
|
||||
"ConnectFailed": 35,
|
||||
"HandshakeFailed": 36,
|
||||
"IOFailure": 37,
|
||||
"RemoteDisconnect": 38,
|
||||
"ShoppingCartNotFound": 39,
|
||||
"Blocked": 40,
|
||||
"Ignored": 41,
|
||||
"NoMatch": 42,
|
||||
"AccountDisabled": 43,
|
||||
"ServiceReadOnly": 44,
|
||||
"AccountNotFeatured": 45,
|
||||
"AdministratorOK": 46,
|
||||
"ContentVersion": 47,
|
||||
"TryAnotherCM": 48,
|
||||
"PasswordRequiredToKickSession": 49,
|
||||
"AlreadyLoggedInElsewhere": 50,
|
||||
"Suspended": 51,
|
||||
"Cancelled": 52,
|
||||
"DataCorruption": 53,
|
||||
"DiskFull": 54,
|
||||
"RemoteCallFailed": 55,
|
||||
"PasswordNotSet": 56, // removed "renamed to PasswordUnset"
|
||||
"PasswordUnset": 56,
|
||||
"ExternalAccountUnlinked": 57,
|
||||
"PSNTicketInvalid": 58,
|
||||
"ExternalAccountAlreadyLinked": 59,
|
||||
"RemoteFileConflict": 60,
|
||||
"IllegalPassword": 61,
|
||||
"SameAsPreviousValue": 62,
|
||||
"AccountLogonDenied": 63,
|
||||
"CannotUseOldPassword": 64,
|
||||
"InvalidLoginAuthCode": 65,
|
||||
"AccountLogonDeniedNoMailSent": 66, // removed "renamed to AccountLogonDeniedNoMail"
|
||||
"AccountLogonDeniedNoMail": 66,
|
||||
"HardwareNotCapableOfIPT": 67,
|
||||
"IPTInitError": 68,
|
||||
"ParentalControlRestricted": 69,
|
||||
"FacebookQueryError": 70,
|
||||
"ExpiredLoginAuthCode": 71,
|
||||
"IPLoginRestrictionFailed": 72,
|
||||
"AccountLocked": 73, // removed "renamed to AccountLockedDown"
|
||||
"AccountLockedDown": 73,
|
||||
"AccountLogonDeniedVerifiedEmailRequired": 74,
|
||||
"NoMatchingURL": 75,
|
||||
"BadResponse": 76,
|
||||
"RequirePasswordReEntry": 77,
|
||||
"ValueOutOfRange": 78,
|
||||
"UnexpectedError": 79,
|
||||
"Disabled": 80,
|
||||
"InvalidCEGSubmission": 81,
|
||||
"RestrictedDevice": 82,
|
||||
"RegionLocked": 83,
|
||||
"RateLimitExceeded": 84,
|
||||
"AccountLogonDeniedNeedTwoFactorCode": 85, // removed "renamed to AccountLoginDeniedNeedTwoFactor"
|
||||
"AccountLoginDeniedNeedTwoFactor": 85,
|
||||
"ItemOrEntryHasBeenDeleted": 86, // removed "renamed to ItemDeleted"
|
||||
"ItemDeleted": 86,
|
||||
"AccountLoginDeniedThrottle": 87,
|
||||
"TwoFactorCodeMismatch": 88,
|
||||
"TwoFactorActivationCodeMismatch": 89,
|
||||
"AccountAssociatedToMultiplePlayers": 90, // removed "renamed to AccountAssociatedToMultiplePartners"
|
||||
"AccountAssociatedToMultiplePartners": 90,
|
||||
"NotModified": 91,
|
||||
"NoMobileDeviceAvailable": 92, // removed "renamed to NoMobileDevice"
|
||||
"NoMobileDevice": 92,
|
||||
"TimeIsOutOfSync": 93, // removed "renamed to TimeNotSynced"
|
||||
"TimeNotSynced": 93,
|
||||
"SMSCodeFailed": 94,
|
||||
"TooManyAccountsAccessThisResource": 95, // removed "renamed to AccountLimitExceeded"
|
||||
"AccountLimitExceeded": 95,
|
||||
"AccountActivityLimitExceeded": 96,
|
||||
"PhoneActivityLimitExceeded": 97,
|
||||
"RefundToWallet": 98,
|
||||
"EmailSendFailure": 99,
|
||||
"NotSettled": 100,
|
||||
"NeedCaptcha": 101,
|
||||
"GSLTDenied": 102,
|
||||
"GSOwnerDenied": 103,
|
||||
"InvalidItemType": 104,
|
||||
"IPBanned": 105,
|
||||
"GSLTExpired": 106,
|
||||
"InsufficientFunds": 107,
|
||||
"TooManyPending": 108,
|
||||
|
||||
// Value-to-name mapping for convenience
|
||||
"0": "Invalid",
|
||||
"1": "OK",
|
||||
"2": "Fail",
|
||||
"3": "NoConnection",
|
||||
"5": "InvalidPassword",
|
||||
"6": "LoggedInElsewhere",
|
||||
"7": "InvalidProtocolVer",
|
||||
"8": "InvalidParam",
|
||||
"9": "FileNotFound",
|
||||
"10": "Busy",
|
||||
"11": "InvalidState",
|
||||
"12": "InvalidName",
|
||||
"13": "InvalidEmail",
|
||||
"14": "DuplicateName",
|
||||
"15": "AccessDenied",
|
||||
"16": "Timeout",
|
||||
"17": "Banned",
|
||||
"18": "AccountNotFound",
|
||||
"19": "InvalidSteamID",
|
||||
"20": "ServiceUnavailable",
|
||||
"21": "NotLoggedOn",
|
||||
"22": "Pending",
|
||||
"23": "EncryptionFailure",
|
||||
"24": "InsufficientPrivilege",
|
||||
"25": "LimitExceeded",
|
||||
"26": "Revoked",
|
||||
"27": "Expired",
|
||||
"28": "AlreadyRedeemed",
|
||||
"29": "DuplicateRequest",
|
||||
"30": "AlreadyOwned",
|
||||
"31": "IPNotFound",
|
||||
"32": "PersistFailed",
|
||||
"33": "LockingFailed",
|
||||
"34": "LogonSessionReplaced",
|
||||
"35": "ConnectFailed",
|
||||
"36": "HandshakeFailed",
|
||||
"37": "IOFailure",
|
||||
"38": "RemoteDisconnect",
|
||||
"39": "ShoppingCartNotFound",
|
||||
"40": "Blocked",
|
||||
"41": "Ignored",
|
||||
"42": "NoMatch",
|
||||
"43": "AccountDisabled",
|
||||
"44": "ServiceReadOnly",
|
||||
"45": "AccountNotFeatured",
|
||||
"46": "AdministratorOK",
|
||||
"47": "ContentVersion",
|
||||
"48": "TryAnotherCM",
|
||||
"49": "PasswordRequiredToKickSession",
|
||||
"50": "AlreadyLoggedInElsewhere",
|
||||
"51": "Suspended",
|
||||
"52": "Cancelled",
|
||||
"53": "DataCorruption",
|
||||
"54": "DiskFull",
|
||||
"55": "RemoteCallFailed",
|
||||
"56": "PasswordUnset",
|
||||
"57": "ExternalAccountUnlinked",
|
||||
"58": "PSNTicketInvalid",
|
||||
"59": "ExternalAccountAlreadyLinked",
|
||||
"60": "RemoteFileConflict",
|
||||
"61": "IllegalPassword",
|
||||
"62": "SameAsPreviousValue",
|
||||
"63": "AccountLogonDenied",
|
||||
"64": "CannotUseOldPassword",
|
||||
"65": "InvalidLoginAuthCode",
|
||||
"66": "AccountLogonDeniedNoMail",
|
||||
"67": "HardwareNotCapableOfIPT",
|
||||
"68": "IPTInitError",
|
||||
"69": "ParentalControlRestricted",
|
||||
"70": "FacebookQueryError",
|
||||
"71": "ExpiredLoginAuthCode",
|
||||
"72": "IPLoginRestrictionFailed",
|
||||
"73": "AccountLockedDown",
|
||||
"74": "AccountLogonDeniedVerifiedEmailRequired",
|
||||
"75": "NoMatchingURL",
|
||||
"76": "BadResponse",
|
||||
"77": "RequirePasswordReEntry",
|
||||
"78": "ValueOutOfRange",
|
||||
"79": "UnexpectedError",
|
||||
"80": "Disabled",
|
||||
"81": "InvalidCEGSubmission",
|
||||
"82": "RestrictedDevice",
|
||||
"83": "RegionLocked",
|
||||
"84": "RateLimitExceeded",
|
||||
"85": "AccountLoginDeniedNeedTwoFactor",
|
||||
"86": "ItemDeleted",
|
||||
"87": "AccountLoginDeniedThrottle",
|
||||
"88": "TwoFactorCodeMismatch",
|
||||
"89": "TwoFactorActivationCodeMismatch",
|
||||
"90": "AccountAssociatedToMultiplePartners",
|
||||
"91": "NotModified",
|
||||
"92": "NoMobileDevice",
|
||||
"93": "TimeNotSynced",
|
||||
"94": "SMSCodeFailed",
|
||||
"95": "AccountLimitExceeded",
|
||||
"96": "AccountActivityLimitExceeded",
|
||||
"97": "PhoneActivityLimitExceeded",
|
||||
"98": "RefundToWallet",
|
||||
"99": "EmailSendFailure",
|
||||
"100": "NotSettled",
|
||||
"101": "NeedCaptcha",
|
||||
"102": "GSLTDenied",
|
||||
"103": "GSOwnerDenied",
|
||||
"104": "InvalidItemType",
|
||||
"105": "IPBanned",
|
||||
"106": "GSLTExpired",
|
||||
"107": "InsufficientFunds",
|
||||
"108": "TooManyPending",
|
||||
};
|
||||
Reference in New Issue
Block a user