mirror of
https://github.com/DoctorMcKay/node-steamcommunity.git
synced 2026-08-19 13:13:28 +08:00
Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e09cf24fbf | ||
|
|
9d2b5ade67 | ||
|
|
be4e5c9449 | ||
|
|
5926197f23 | ||
|
|
2d86f81142 | ||
|
|
f37bff4a57 | ||
|
|
c700b7663b | ||
|
|
c26e548c64 | ||
|
|
658d8fb708 | ||
|
|
cd68841d1d | ||
|
|
5853968661 | ||
|
|
10d899f7a7 | ||
|
|
4e1453e702 | ||
|
|
f3cf2a4361 | ||
|
|
2890b70add | ||
|
|
1810727a2f | ||
|
|
3d566ed0fb | ||
|
|
80979bc387 | ||
|
|
4e326e3295 | ||
|
|
cff35ba863 | ||
|
|
d975fdfba8 | ||
|
|
4e3c319ee1 | ||
|
|
e5cbd23110 | ||
|
|
82f1d490f9 | ||
|
|
c3f5b492b3 | ||
|
|
09cd81b607 | ||
|
|
8a6d912374 | ||
|
|
c392f2ac74 | ||
|
|
8e6f859269 | ||
|
|
84dce9872a | ||
|
|
c2ad457e87 |
59
classes/CEconItem.js
Normal file
59
classes/CEconItem.js
Normal file
@@ -0,0 +1,59 @@
|
||||
module.exports = CEconItem;
|
||||
|
||||
function CEconItem(item, descriptions, contextID) {
|
||||
var thing;
|
||||
for(thing in item) {
|
||||
if(item.hasOwnProperty(thing)) {
|
||||
this[thing] = item[thing];
|
||||
}
|
||||
}
|
||||
|
||||
this.assetid = this.id = (this.id || this.assetid);
|
||||
this.instanceid = this.instanceid || '0';
|
||||
this.amount = parseInt(this.amount, 10);
|
||||
this.contextid = this.contextid || contextID.toString();
|
||||
|
||||
// Merge the description
|
||||
if(descriptions) {
|
||||
var description = descriptions[this.classid + '_' + this.instanceid];
|
||||
if(description) {
|
||||
for(thing in description) {
|
||||
if(description.hasOwnProperty(thing)) {
|
||||
this[thing] = description[thing];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.tradable = !!this.tradable;
|
||||
this.marketable = !!this.marketable;
|
||||
this.commodity = !!this.commodity;
|
||||
this.market_tradable_restriction = (this.market_tradable_restriction ? parseInt(this.market_tradable_restriction, 10) : 0);
|
||||
this.market_marketable_restriction = (this.market_marketable_restriction ? parseInt(this.market_marketable_restriction, 10) : 0);
|
||||
}
|
||||
|
||||
CEconItem.prototype.getImageURL = function() {
|
||||
return "https://steamcommunity-a.akamaihd.net/economy/image/" + this.icon_url + "/";
|
||||
};
|
||||
|
||||
CEconItem.prototype.getLargeImageURL = function() {
|
||||
if(!this.icon_url_large) {
|
||||
return this.getImageURL();
|
||||
}
|
||||
|
||||
return "https://steamcommunity-a.akamaihd.net/economy/image/" + this.icon_url_large + "/";
|
||||
};
|
||||
|
||||
CEconItem.prototype.getTag = function(category) {
|
||||
if(!this.tags) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for(var i = 0; i < this.tags.length; i++) {
|
||||
if(this.tags[i].category == category) {
|
||||
return this.tags[i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
@@ -40,6 +40,11 @@ SteamCommunity.prototype.getSteamUser = function(id, callback) {
|
||||
customurl = match[1];
|
||||
}
|
||||
}
|
||||
|
||||
if(!result.profile.steamID64) {
|
||||
callback(new Error("No valid response"));
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, new CSteamUser(self, result.profile, customurl));
|
||||
});
|
||||
@@ -50,22 +55,26 @@ function CSteamUser(community, userData, customurl) {
|
||||
this._community = community;
|
||||
|
||||
this.steamID = new SteamID(userData.steamID64[0]);
|
||||
this.name = userData.steamID[0];
|
||||
this.onlineState = userData.onlineState[0];
|
||||
this.stateMessage = userData.stateMessage[0];
|
||||
this.privacyState = userData.privacyState[0];
|
||||
this.visibilityState = userData.visibilityState[0];
|
||||
this.avatarHash = userData.avatarIcon[0].match(/([0-9a-f]+)\.[a-z]+$/)[1];
|
||||
this.vacBanned = !!userData.vacBanned[0];
|
||||
this.tradeBanState = userData.tradeBanState[0];
|
||||
this.isLimitedAccount = !!userData.isLimitedAccount[0];
|
||||
this.customURL = userData.customURL ? userData.customURL[0] : customurl;
|
||||
this.name = processItem('steamID');
|
||||
this.onlineState = processItem('onlineState');
|
||||
this.stateMessage = processItem('stateMessage');
|
||||
this.privacyState = processItem('privacyState', 'uncreated');
|
||||
this.visibilityState = processItem('visibilityState');
|
||||
this.avatarHash = processItem('avatarIcon', '').match(/([0-9a-f]+)\.[a-z]+$/);
|
||||
if(this.avatarHash) {
|
||||
this.avatarHash = this.avatarHash[1];
|
||||
}
|
||||
|
||||
this.vacBanned = !!processItem('vacBanned', false);
|
||||
this.tradeBanState = processItem('tradeBanState', 'None');
|
||||
this.isLimitedAccount = !!processItem('isLimitedAccount');
|
||||
this.customURL = processItem('customURL', customurl);
|
||||
|
||||
if(this.visibilityState == 3) {
|
||||
this.memberSince = new Date(userData.memberSince[0].replace(/(\d{1,2})(st|nd|th)/, "$1"));
|
||||
this.location = userData.location[0] || null;
|
||||
this.realName = userData.realname[0] || null;
|
||||
this.summary = userData.summary[0] || null;
|
||||
this.memberSince = new Date(processItem('memberSince', '0').replace(/(\d{1,2})(st|nd|th)/, "$1"));
|
||||
this.location = processItem('location');
|
||||
this.realName = processItem('realname');
|
||||
this.summary = processItem('summary');
|
||||
} else {
|
||||
this.memberSince = null;
|
||||
this.location = null;
|
||||
@@ -88,6 +97,14 @@ function CSteamUser(community, userData, customurl) {
|
||||
return new SteamID(group.groupID64[0]);
|
||||
});
|
||||
}
|
||||
|
||||
function processItem(name, defaultVal) {
|
||||
if(!userData[name]) {
|
||||
return defaultVal;
|
||||
}
|
||||
|
||||
return userData[name][0];
|
||||
}
|
||||
}
|
||||
|
||||
CSteamUser.getAvatarURL = function(hash, size, protocol) {
|
||||
@@ -134,3 +151,11 @@ CSteamUser.prototype.comment = function(message, callback) {
|
||||
CSteamUser.prototype.inviteToGroup = function(groupID, callback) {
|
||||
this._community.inviteUserToGroup(this.steamID, groupID, callback);
|
||||
};
|
||||
|
||||
CSteamUser.prototype.getInventoryContexts = function(callback) {
|
||||
this._community.getUserInventoryContexts(this.steamID, callback);
|
||||
};
|
||||
|
||||
CSteamUser.prototype.getInventory = function(appID, contextID, tradableOnly, callback) {
|
||||
this._community.getUserInventory(this.steamID, appID, contextID, tradableOnly, callback);
|
||||
};
|
||||
|
||||
@@ -203,7 +203,7 @@ SteamCommunity.prototype.scheduleGroupEvent = function(gid, name, type, descript
|
||||
|
||||
var self = this;
|
||||
this.request.post({
|
||||
"uri": "https://steamcommunity.com/gid/" + this.steamID.toString() + "/eventEdit",
|
||||
"uri": "https://steamcommunity.com/gid/" + gid.toString() + "/eventEdit",
|
||||
"form": form
|
||||
}, function(err, response, body) {
|
||||
if(!callback) {
|
||||
|
||||
141
components/inventoryhistory.js
Normal file
141
components/inventoryhistory.js
Normal file
@@ -0,0 +1,141 @@
|
||||
var SteamCommunity = require('../index.js');
|
||||
var CEconItem = require('../classes/CEconItem.js');
|
||||
var SteamID = require('steamid');
|
||||
var request = require('request');
|
||||
var Cheerio = require('cheerio');
|
||||
var Async = require('async');
|
||||
|
||||
SteamCommunity.prototype.getInventoryHistory = function(options, callback) {
|
||||
if(typeof options === 'function') {
|
||||
callback = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
options.page = options.page || 1;
|
||||
|
||||
this.request("https://steamcommunity.com/my/inventoryhistory?l=english&p=" + options.page, function(err, response, body) {
|
||||
if(err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
var output = {};
|
||||
var vanityURLs = [];
|
||||
|
||||
var $ = Cheerio.load(body);
|
||||
var html = $('.inventory_history_pagingrow').html();
|
||||
if(!html) {
|
||||
callback("Malformed page: no paging row found");
|
||||
return;
|
||||
}
|
||||
|
||||
var match = html.match(/(\d+) - (\d+) of (\d+) History Items/);
|
||||
|
||||
output.first = parseInt(match[1], 10);
|
||||
output.last = parseInt(match[2], 10);
|
||||
output.totalTrades = parseInt(match[3], 10);
|
||||
|
||||
// Load the inventory item data
|
||||
var match2 = body.match(/var g_rgHistoryInventory = (.*);/);
|
||||
if(!match2) {
|
||||
callback(new Error("Malformed page: no trade found"));
|
||||
return;
|
||||
}
|
||||
var historyInventory = JSON.parse(match2[1]);
|
||||
|
||||
output.trades = [];
|
||||
var trades = $('.tradehistoryrow');
|
||||
|
||||
var item, trade, profileLink, items, j, econItem, timeMatch, time;
|
||||
for(var i = 0; i < trades.length; i++) {
|
||||
item = $(trades[i]);
|
||||
trade = {};
|
||||
|
||||
timeMatch = item.find('.tradehistory_timestamp').html().match(/(\d+):(\d+)(am|pm)/);
|
||||
if(timeMatch[1] == 12 && timeMatch[3] == 'am') {
|
||||
timeMatch[1] = 0;
|
||||
}
|
||||
|
||||
if(timeMatch[1] < 12 && timeMatch[3] == 'pm') {
|
||||
timeMatch[1] = parseInt(timeMatch[1], 10) + 12;
|
||||
}
|
||||
|
||||
time = (timeMatch[1] < 10 ? '0' : '') + timeMatch[1] + ':' + timeMatch[2] + ':00';
|
||||
|
||||
trade.date = new Date(item.find('.tradehistory_date').html() + ' ' + time);
|
||||
trade.partnerName = item.find('.tradehistory_event_description a').html();
|
||||
trade.partnerSteamID = null;
|
||||
trade.partnerVanityURL = null;
|
||||
trade.itemsReceived = [];
|
||||
trade.itemsGiven = [];
|
||||
|
||||
profileLink = item.find('.tradehistory_event_description a').attr('href');
|
||||
if(profileLink.indexOf('/profiles/') != -1) {
|
||||
trade.partnerSteamID = new SteamID(profileLink.match(/(\d+)$/)[1]);
|
||||
} else {
|
||||
trade.partnerVanityURL = profileLink.match(/\/([^\/]+)$/)[1];
|
||||
if(options.resolveVanityURLs && vanityURLs.indexOf(trade.partnerVanityURL) == -1) {
|
||||
vanityURLs.push(trade.partnerVanityURL);
|
||||
}
|
||||
}
|
||||
|
||||
items = item.find('.history_item');
|
||||
for(j = 0; j < items.length; j++) {
|
||||
match = body.match(new RegExp("HistoryPageCreateItemHover\\( '" + $(items[j]).attr('id') + "', (\\d+), '(\\d+)', '(\\d+)', '(\\d+)' \\);"));
|
||||
econItem = historyInventory[match[1]][match[2]][match[3]];
|
||||
|
||||
if($(items[j]).attr('id').indexOf('received') != -1) {
|
||||
trade.itemsReceived.push(new CEconItem(econItem));
|
||||
} else {
|
||||
trade.itemsGiven.push(new CEconItem(econItem));
|
||||
}
|
||||
}
|
||||
|
||||
output.trades.push(trade);
|
||||
}
|
||||
|
||||
if(options.resolveVanityURLs) {
|
||||
Async.map(vanityURLs, resolveVanityURL, function(err, results) {
|
||||
if(err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
for(i = 0; i < output.trades.length; i++) {
|
||||
if(output.trades[i].partnerSteamID || !output.trades[i].partnerVanityURL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find the vanity URL
|
||||
for(j = 0; j < results.length; j++) {
|
||||
if(results[j].vanityURL == output.trades[i].partnerVanityURL) {
|
||||
output.trades[i].partnerSteamID = new SteamID(results[j].steamID);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
callback(null, output);
|
||||
});
|
||||
} else {
|
||||
callback(null, output);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function resolveVanityURL(vanityURL, callback) {
|
||||
request("https://steamcommunity.com/id/" + vanityURL + "/?xml=1", function(err, response, body) {
|
||||
if(err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
var match = body.match(/<steamID64>(\d+)<\/steamID64>/);
|
||||
if(!match || !match[1]) {
|
||||
callback(new Error("Couldn't find Steam ID"));
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, {"vanityURL": vanityURL, "steamID": match[1]});
|
||||
});
|
||||
}
|
||||
@@ -101,10 +101,10 @@ SteamCommunity.prototype.editProfile = function(settings, callback) {
|
||||
break;
|
||||
|
||||
case 'primaryGroup':
|
||||
if(typeof settings[i] === 'object' && settings[i].accountid) {
|
||||
values.primary_group_steamid = settings[i].accountid;
|
||||
if(typeof settings[i] === 'object' && settings[i].getSteamID64) {
|
||||
values.primary_group_steamid = settings[i].getSteamID64();
|
||||
} else {
|
||||
values.primary_group_steamid = new SteamID(settings[i]).accountid;
|
||||
values.primary_group_steamid = new SteamID(settings[i]).getSteamID64();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
var SteamCommunity = require('../index.js');
|
||||
var SteamID = require('steamid');
|
||||
var CEconItem = require('../classes/CEconItem.js');
|
||||
|
||||
SteamCommunity.prototype.addFriend = function(userID, callback) {
|
||||
if(typeof userID === 'string') {
|
||||
@@ -197,3 +198,101 @@ SteamCommunity.prototype.inviteUserToGroup = function(userID, groupID, callback)
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.getUserInventoryContexts = function(userID, callback) {
|
||||
if(typeof userID === 'string') {
|
||||
userID = new SteamID(userID);
|
||||
}
|
||||
|
||||
if(typeof userID === 'function') {
|
||||
callback = userID;
|
||||
userID = this.steamID;
|
||||
}
|
||||
|
||||
if(!userID) {
|
||||
callback(new Error("No SteamID specified and not logged in"));
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this.request("https://steamcommunity.com/profiles/" + userID.getSteamID64() + "/inventory/", function(err, response, body) {
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var match = body.match(/var g_rgAppContextData = ([^\n]+);\r?\n/);
|
||||
if(!match) {
|
||||
callback(new Error("Malformed response"));
|
||||
return;
|
||||
}
|
||||
|
||||
var data;
|
||||
try {
|
||||
data = JSON.parse(match[1]);
|
||||
} catch(e) {
|
||||
callback(new Error("Malformed response"));
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, data);
|
||||
});
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.getUserInventory = function(userID, appID, contextID, tradableOnly, callback) {
|
||||
var self = this;
|
||||
|
||||
if(typeof userID === 'string') {
|
||||
userID = new SteamID(userID);
|
||||
}
|
||||
|
||||
var endpoint = "/profiles/" + userID.getSteamID64();
|
||||
get([], []);
|
||||
|
||||
function get(inventory, currency, start) {
|
||||
self.request({
|
||||
"uri": "https://steamcommunity.com" + endpoint + "/inventory/json/" + appID + "/" + contextID,
|
||||
"qs": {
|
||||
"start": start,
|
||||
"trading": tradableOnly ? 1 : undefined
|
||||
},
|
||||
"json": true
|
||||
}, function(err, response, body) {
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!body || !body.success || !body.rgInventory || !body.rgDescriptions || !body.rgCurrency) {
|
||||
callback(new Error(body.Error || "Malformed response"));
|
||||
return;
|
||||
}
|
||||
|
||||
var i;
|
||||
for(i in body.rgInventory) {
|
||||
if(!body.rgInventory.hasOwnProperty(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
inventory.push(new CEconItem(body.rgInventory[i], body.rgDescriptions, contextID));
|
||||
}
|
||||
|
||||
for(i in body.rgCurrency) {
|
||||
if(!body.rgCurrency.hasOwnProperty(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
currency.push(new CEconItem(body.rgInventory[i], body.rgDescriptions, contextID));
|
||||
}
|
||||
|
||||
if(body.more) {
|
||||
var match = response.request.uri.href.match(/\/(profiles|id)\/([^\/]+)\//);
|
||||
if(match) {
|
||||
endpoint = "/" + match[1] + "/" + match[2];
|
||||
}
|
||||
|
||||
get(inventory, currency, body.more_start);
|
||||
} else {
|
||||
callback(null, inventory, currency);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
19
index.js
19
index.js
@@ -149,13 +149,16 @@ function generateSessionID() {
|
||||
|
||||
SteamCommunity.prototype.getWebApiKey = function(domain, callback) {
|
||||
var self = this;
|
||||
this.request("https://steamcommunity.com/dev/apikey", function(err, response, body) {
|
||||
this.request({
|
||||
"uri": "https://steamcommunity.com/dev/apikey",
|
||||
"followRedirect": false
|
||||
}, function(err, response, body) {
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(body.match(/<h2>Access Denied<\/h2>/)) {
|
||||
return callback("Access Denied");
|
||||
return callback(new Error("Access Denied"));
|
||||
}
|
||||
|
||||
var match = body.match(/<p>Key: ([0-9A-F]+)<\/p>/);
|
||||
@@ -172,8 +175,8 @@ SteamCommunity.prototype.getWebApiKey = function(domain, callback) {
|
||||
"Submit": "Register"
|
||||
}
|
||||
}, function(err, response, body) {
|
||||
if(err || response.statusCode >= 400) {
|
||||
return callback(err.message || "HTTP error " + response.statusCode);
|
||||
if(self._checkHttpError(err, response, callback)) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.getWebApiKey(domain, callback);
|
||||
@@ -308,7 +311,12 @@ SteamCommunity.prototype._checkHttpError = function(err, response, callback) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(response.statusCode != 200) {
|
||||
if(response.statusCode >= 300 && response.statusCode <= 399 && response.headers.location.indexOf('/login') != -1) {
|
||||
callback(new Error("Not Logged In"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if(response.statusCode >= 400) {
|
||||
var error = new Error("HTTP error " + response.statusCode);
|
||||
error.code = response.statusCode;
|
||||
callback(error);
|
||||
@@ -323,6 +331,7 @@ require('./components/profile.js');
|
||||
require('./components/market.js');
|
||||
require('./components/groups.js');
|
||||
require('./components/users.js');
|
||||
require('./components/inventoryhistory.js');
|
||||
require('./classes/CMarketItem.js');
|
||||
require('./classes/CMarketSearchResult.js');
|
||||
require('./classes/CSteamGroup.js');
|
||||
|
||||
11
package.json
11
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "steamcommunity",
|
||||
"version": "3.7.0",
|
||||
"version": "3.9.8",
|
||||
"description": "Provides an interface for logging into and interacting with the Steam Community website",
|
||||
"keywords": ["steam", "steam community"],
|
||||
"homepage": "https://github.com/DoctorMcKay/node-steamcommunity",
|
||||
@@ -13,10 +13,11 @@
|
||||
"url": "https://github.com/DoctorMcKay/node-steamcommunity.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"request": "^2.58.0",
|
||||
"request": "^2.61.0",
|
||||
"node-bignumber": "^1.2.1",
|
||||
"steamid": "^0.3.0",
|
||||
"xml2js": "^0.4.9",
|
||||
"cheerio": "^0.19.0"
|
||||
"steamid": "^0.3.1",
|
||||
"xml2js": "^0.4.11",
|
||||
"cheerio": "^0.19.0",
|
||||
"async": "^1.4.2"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user