mirror of
https://github.com/DoctorMcKay/node-steamcommunity.git
synced 2026-08-19 21:23:28 +08:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa84505132 | ||
|
|
bb97565f2a | ||
|
|
7462e4b767 | ||
|
|
adbf1d47a7 | ||
|
|
8c4fde720a | ||
|
|
458d7b6db1 | ||
|
|
411d74036f | ||
|
|
1b3117b8dc | ||
|
|
6eec88d196 | ||
|
|
3921ce17d0 | ||
|
|
4441d6f6e0 | ||
|
|
870de6817e | ||
|
|
d5dbb230df | ||
|
|
5e9c06bdc4 | ||
|
|
8d163d0d85 |
@@ -7,29 +7,29 @@ SteamCommunity.prototype.getSteamUser = function(id, callback) {
|
||||
if(typeof id !== 'string' && !Helpers.isSteamID(id)) {
|
||||
throw new Error("id parameter should be a user URL string or a SteamID object");
|
||||
}
|
||||
|
||||
|
||||
if(typeof id === 'object' && (id.universe != SteamID.Universe.PUBLIC || id.type != SteamID.Type.INDIVIDUAL)) {
|
||||
throw new Error("SteamID must stand for an individual account in the public universe");
|
||||
}
|
||||
|
||||
|
||||
var self = this;
|
||||
this.httpRequest("http://steamcommunity.com/" + (typeof id === 'string' ? "id/" + id : "profiles/" + id.toString()) + "/?xml=1", function(err, response, body) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
xml2js.parseString(body, function(err, result) {
|
||||
if(err || (!result.response && !result.profile)) {
|
||||
callback(err || new Error("No valid response"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(result.response && result.response.error && result.response.error.length) {
|
||||
callback(new Error(result.response.error[0]));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Try and find custom URL from redirect
|
||||
var customurl = null;
|
||||
if(response.request.redirects && response.request.redirects.length) {
|
||||
@@ -43,7 +43,7 @@ SteamCommunity.prototype.getSteamUser = function(id, callback) {
|
||||
callback(new Error("No valid response"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
callback(null, new CSteamUser(self, result.profile, customurl));
|
||||
});
|
||||
}, "steamcommunity");
|
||||
@@ -51,7 +51,7 @@ SteamCommunity.prototype.getSteamUser = function(id, callback) {
|
||||
|
||||
function CSteamUser(community, userData, customurl) {
|
||||
this._community = community;
|
||||
|
||||
|
||||
this.steamID = new SteamID(userData.steamID64[0]);
|
||||
this.name = processItem('steamID');
|
||||
this.onlineState = processItem('onlineState');
|
||||
@@ -67,7 +67,7 @@ function CSteamUser(community, userData, customurl) {
|
||||
this.tradeBanState = processItem('tradeBanState', 'None');
|
||||
this.isLimitedAccount = processItem('isLimitedAccount') == 1;
|
||||
this.customURL = processItem('customURL', customurl);
|
||||
|
||||
|
||||
if(this.visibilityState == 3) {
|
||||
this.memberSince = new Date(processItem('memberSince', '0').replace(/(\d{1,2})(st|nd|th)/, "$1"));
|
||||
this.location = processItem('location');
|
||||
@@ -79,19 +79,19 @@ function CSteamUser(community, userData, customurl) {
|
||||
this.realName = null;
|
||||
this.summary = null;
|
||||
}
|
||||
|
||||
|
||||
// Maybe handle mostPlayedGames?
|
||||
|
||||
|
||||
this.groups = null;
|
||||
this.primaryGroup = null;
|
||||
|
||||
|
||||
var self = this;
|
||||
if(userData.groups && userData.groups[0] && userData.groups[0].group) {
|
||||
this.groups = userData.groups[0].group.map(function(group) {
|
||||
if(group['$'] && group['$'].isPrimary === "1") {
|
||||
self.primaryGroup = new SteamID(group.groupID64[0]);
|
||||
}
|
||||
|
||||
|
||||
return new SteamID(group.groupID64[0]);
|
||||
});
|
||||
}
|
||||
@@ -110,7 +110,7 @@ CSteamUser.getAvatarURL = function(hash, size, protocol) {
|
||||
protocol = protocol || 'http://';
|
||||
|
||||
hash = hash || "72f78b4c8cc1f62323f8a33f6d53e27db57c2252"; // The default "?" avatar
|
||||
|
||||
|
||||
var url = protocol + "steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/" + hash.substring(0, 2) + "/" + hash;
|
||||
if(size == 'full' || size == 'medium') {
|
||||
return url + "_" + size + ".jpg";
|
||||
@@ -182,3 +182,11 @@ CSteamUser.prototype.getInventory = function(appID, contextID, tradableOnly, cal
|
||||
CSteamUser.prototype.getInventoryContents = function(appID, contextID, tradableOnly, callback) {
|
||||
this._community.getUserInventoryContents(this.steamID, appID, contextID, tradableOnly, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the background URL of user's profile.
|
||||
* @param {function} callback
|
||||
*/
|
||||
CSteamUser.prototype.getProfileBackground = function(callback) {
|
||||
this._community.getUserProfileBackground(this.steamID, callback);
|
||||
};
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
const EResult = require('../resources/EResult.js');
|
||||
|
||||
exports.isSteamID = function(input) {
|
||||
var keys = Object.keys(input);
|
||||
if (keys.length != 4) {
|
||||
@@ -36,3 +38,19 @@ exports.decodeSteamTime = function(time) {
|
||||
|
||||
return date;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an Error object for a particular EResult
|
||||
* @param {int} eresult
|
||||
* @returns {null|Error}
|
||||
*/
|
||||
exports.eresultError = function(eresult) {
|
||||
if (eresult == EResult.OK) {
|
||||
// no error
|
||||
return null;
|
||||
}
|
||||
|
||||
var err = new Error(EResult[eresult] || ("Error " + eresult));
|
||||
err.eresult = eresult;
|
||||
return err;
|
||||
};
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
var SteamCommunity = require('../index.js');
|
||||
var SteamID = require('steamid');
|
||||
var Cheerio = require('cheerio');
|
||||
var fs = require('fs');
|
||||
const Cheerio = require('cheerio');
|
||||
const FS = require('fs');
|
||||
const SteamID = require('steamid');
|
||||
|
||||
const Helpers = require('./helpers.js');
|
||||
const SteamCommunity = require('../index.js');
|
||||
|
||||
SteamCommunity.PrivacyState = {
|
||||
"Private": 1,
|
||||
@@ -10,9 +12,9 @@ SteamCommunity.PrivacyState = {
|
||||
};
|
||||
|
||||
var CommentPrivacyState = {
|
||||
"1": "commentselfonly",
|
||||
"2": "commentfriendsonly",
|
||||
"3": "commentanyone"
|
||||
"1": 2, // private
|
||||
"2": 0, // friends only
|
||||
"3": 1 // anyone
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.setupProfile = function(callback) {
|
||||
@@ -148,10 +150,9 @@ SteamCommunity.prototype.editProfile = function(settings, callback) {
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.profileSettings = function(settings, callback) {
|
||||
var self = this;
|
||||
this._myProfile("edit/settings", null, function(err, response, body) {
|
||||
if(err || response.statusCode != 200) {
|
||||
if(callback) {
|
||||
this._myProfile("edit/settings", null, (err, response, body) => {
|
||||
if (err || response.statusCode != 200) {
|
||||
if (callback) {
|
||||
callback(err || new Error("HTTP error " + response.statusCode));
|
||||
}
|
||||
|
||||
@@ -159,8 +160,8 @@ SteamCommunity.prototype.profileSettings = function(settings, callback) {
|
||||
}
|
||||
|
||||
var $ = Cheerio.load(body);
|
||||
var form = $('#editForm');
|
||||
if(!form) {
|
||||
var existingSettings = $('.ProfileReactRoot[data-privacysettings]').data('privacysettings');
|
||||
if (!existingSettings) {
|
||||
if(callback) {
|
||||
callback(new Error("Malformed response"));
|
||||
}
|
||||
@@ -168,46 +169,71 @@ SteamCommunity.prototype.profileSettings = function(settings, callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
var values = {};
|
||||
form.serializeArray().forEach(function(item) {
|
||||
values[item.name] = item.value;
|
||||
});
|
||||
// PrivacySettings => {PrivacyProfile, PrivacyInventory, PrivacyInventoryGifts, PrivacyOwnedGames, PrivacyPlaytime}
|
||||
// eCommentPermission
|
||||
var privacy = existingSettings.PrivacySettings;
|
||||
var commentPermission = existingSettings.eCommentPermission;
|
||||
|
||||
for(var i in settings) {
|
||||
if(!settings.hasOwnProperty(i)) {
|
||||
for (var i in settings) {
|
||||
if (!settings.hasOwnProperty(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(i) {
|
||||
switch (i) {
|
||||
case 'profile':
|
||||
values.privacySetting = settings[i];
|
||||
privacy.PrivacyProfile = settings[i];
|
||||
break;
|
||||
|
||||
case 'comments':
|
||||
values.commentSetting = CommentPrivacyState[settings[i]];
|
||||
commentPermission = CommentPrivacyState[settings[i]];
|
||||
break;
|
||||
|
||||
case 'inventory':
|
||||
values.inventoryPrivacySetting = settings[i];
|
||||
privacy.PrivacyInventory = settings[i];
|
||||
break;
|
||||
|
||||
case 'inventoryGifts':
|
||||
values.inventoryGiftPrivacy = settings[i] ? 1 : 0;
|
||||
privacy.PrivacyInventoryGifts = settings[i] ? SteamCommunity.PrivacyState.Private : SteamCommunity.PrivacyState.Public;
|
||||
break;
|
||||
|
||||
case 'gameDetails':
|
||||
privacy.PrivacyOwnedGames = settings[i];
|
||||
break;
|
||||
|
||||
case 'playtime':
|
||||
privacy.PrivacyPlaytime = settings[i] ? SteamCommunity.PrivacyState.Private : SteamCommunity.PrivacyState.Public;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
self._myProfile("edit/settings", values, function(err, response, body) {
|
||||
if(err || response.statusCode != 200) {
|
||||
if(callback) {
|
||||
this._myProfile({
|
||||
"method": "POST",
|
||||
"endpoint": "ajaxsetprivacy/",
|
||||
"json": true,
|
||||
"formData": { // it's multipart because lolvalve
|
||||
"sessionid": this.getSessionID(),
|
||||
"Privacy": JSON.stringify(privacy),
|
||||
"eCommentPermission": commentPermission
|
||||
}
|
||||
}, null, function(err, response, body) {
|
||||
if (err || response.statusCode != 200) {
|
||||
if (callback) {
|
||||
callback(err || new Error("HTTP error " + response.statusCode));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(callback) {
|
||||
callback(null);
|
||||
if (body.success != 1) {
|
||||
if (callback) {
|
||||
callback(new Error(body.success ? "Error " + body.success : "Request was not successful"));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
callback(null, body.Privacy);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -256,7 +282,7 @@ SteamCommunity.prototype.uploadAvatar = function(image, format, callback) {
|
||||
}
|
||||
}
|
||||
|
||||
fs.readFile(image, function(err, file) {
|
||||
FS.readFile(image, function(err, file) {
|
||||
if(err) {
|
||||
if(callback) {
|
||||
callback(err);
|
||||
@@ -367,3 +393,68 @@ SteamCommunity.prototype.uploadAvatar = function(image, format, callback) {
|
||||
}, "steamcommunity");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Post a new status to your profile activity feed.
|
||||
* @param {string} statusText - The text of this status update
|
||||
* @param {{appID: int}} [options] - Options for this status update. All are optional. If you don't pass any options, this can be omitted.
|
||||
* @param {function} callback - err, postID
|
||||
*/
|
||||
SteamCommunity.prototype.postProfileStatus = function(statusText, options, callback) {
|
||||
if (typeof options === 'function') {
|
||||
callback = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
this._myProfile("ajaxpostuserstatus/", {
|
||||
"appid": options.appID || 0,
|
||||
"sessionid": this.getSessionID(),
|
||||
"status_text": statusText
|
||||
}, (err, res, body) => {
|
||||
try {
|
||||
body = JSON.parse(body);
|
||||
if (body.message) {
|
||||
callback(new Error(body.message));
|
||||
return;
|
||||
}
|
||||
|
||||
var match = body.blotter_html.match(/id="userstatus_(\d+)_/);
|
||||
if (!match) {
|
||||
callback(new Error("Malformed response"));
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, parseInt(match[1], 10));
|
||||
} catch (ex) {
|
||||
callback(ex);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete a previously-posted profile status update.
|
||||
* @param {int} postID
|
||||
* @param {function} [callback]
|
||||
*/
|
||||
SteamCommunity.prototype.deleteProfileStatus = function(postID, callback) {
|
||||
this._myProfile("ajaxdeleteuserstatus/", {
|
||||
"sessionid": this.getSessionID(),
|
||||
"postid": postID
|
||||
}, (err, res, body) => {
|
||||
if (!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
body = JSON.parse(body);
|
||||
if (!body.success) {
|
||||
callback(new Error("Malformed response"));
|
||||
return;
|
||||
}
|
||||
|
||||
callback(Helpers.eresultError(body.success));
|
||||
} catch (ex) {
|
||||
callback(ex);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
var SteamCommunity = require('../index.js');
|
||||
var SteamID = require('steamid');
|
||||
var CEconItem = require('../classes/CEconItem.js');
|
||||
var Helpers = require('./helpers.js');
|
||||
const Cheerio = require('cheerio');
|
||||
const SteamID = require('steamid');
|
||||
|
||||
const SteamCommunity = require('../index.js');
|
||||
|
||||
const CEconItem = require('../classes/CEconItem.js');
|
||||
const Helpers = require('./helpers.js');
|
||||
|
||||
SteamCommunity.prototype.addFriend = function(userID, callback) {
|
||||
if(typeof userID === 'string') {
|
||||
@@ -217,6 +220,45 @@ SteamCommunity.prototype.getUserAliases = function(userID, callback) {
|
||||
}, "steamcommunity");
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the background URL of user's profile.
|
||||
* @param {SteamID|string} userID - The user's SteamID as a SteamID object or a string which can parse into one
|
||||
* @param {function} callback
|
||||
*/
|
||||
SteamCommunity.prototype.getUserProfileBackground = function(userID, callback) {
|
||||
if (typeof userID === 'string') {
|
||||
userID = new SteamID(userID);
|
||||
}
|
||||
|
||||
this.httpRequest("https://steamcommunity.com/profiles/" + userID.getSteamID64(), (err, response, body) => {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
var $ = Cheerio.load(body);
|
||||
|
||||
var $privateProfileInfo = $('.profile_private_info');
|
||||
if ($privateProfileInfo.length > 0) {
|
||||
callback(new Error($privateProfileInfo.text().trim()));
|
||||
return;
|
||||
}
|
||||
|
||||
if ($('body').hasClass('has_profile_background')) {
|
||||
var backgroundUrl = $('div.profile_background_image_content').css('background-image');
|
||||
var matcher = backgroundUrl.match(/\(([^)]+)\)/);
|
||||
|
||||
if (matcher.length != 2 || !matcher[1].length) {
|
||||
callback(new Error("Malformed response"));
|
||||
} else {
|
||||
callback(null, matcher[1]);
|
||||
}
|
||||
} else {
|
||||
callback(null, null);
|
||||
}
|
||||
}, "steamcommunity");
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.getUserInventoryContexts = function(userID, callback) {
|
||||
if (typeof userID === 'string') {
|
||||
userID = new SteamID(userID);
|
||||
@@ -389,7 +431,7 @@ SteamCommunity.prototype.getUserInventoryContents = function(userID, appID, cont
|
||||
// We can never get private profile error for our own inventory!
|
||||
self._notifySessionExpired(err);
|
||||
}
|
||||
|
||||
|
||||
callback(new Error("This profile is private."));
|
||||
return;
|
||||
}
|
||||
@@ -423,13 +465,13 @@ SteamCommunity.prototype.getUserInventoryContents = function(userID, appID, cont
|
||||
} else {
|
||||
callback(new Error("Malformed response"));
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < body.assets.length; i++) {
|
||||
var description = getDescription(body.descriptions, body.assets[i].classid, body.assets[i].instanceid);
|
||||
|
||||
|
||||
if (!tradableOnly || (description && description.tradable)) {
|
||||
body.assets[i].pos = pos++;
|
||||
(body.assets[i].currencyid ? currency : inventory).push(new CEconItem(body.assets[i], description, contextID));
|
||||
@@ -457,7 +499,7 @@ SteamCommunity.prototype.getUserInventoryContents = function(userID, appID, cont
|
||||
for (var i = 0; i < descriptions.length; i++) {
|
||||
quickDescriptionLookup[descriptions[i].classid + '_' + (descriptions[i].instanceid || '0')] = descriptions[i];
|
||||
}
|
||||
|
||||
|
||||
return quickDescriptionLookup[key];
|
||||
}
|
||||
};
|
||||
|
||||
21
index.js
21
index.js
@@ -1,9 +1,9 @@
|
||||
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 hex2b64 = require('node-bignumber').hex2b64;
|
||||
const Request = require('request');
|
||||
const RSA = require('node-bignumber').Key;
|
||||
const SteamID = require('steamid');
|
||||
|
||||
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";
|
||||
|
||||
@@ -259,14 +259,13 @@ SteamCommunity.prototype._setCookie = function(cookie, secure) {
|
||||
};
|
||||
|
||||
SteamCommunity.prototype.setCookies = function(cookies) {
|
||||
var self = this;
|
||||
cookies.forEach(function(cookie) {
|
||||
cookies.forEach((cookie) => {
|
||||
var cookieName = cookie.match(/(.+)=/)[1];
|
||||
if(cookieName == 'steamLogin') {
|
||||
self.steamID = new SteamID(cookie.match(/=(\d+)/)[1]);
|
||||
if (cookieName == 'steamLogin' || cookieName == 'steamLoginSecure') {
|
||||
this.steamID = new SteamID(cookie.match(/=(\d+)/)[1]);
|
||||
}
|
||||
|
||||
self._setCookie(Request.cookie(cookie), !!(cookieName.match(/^steamMachineAuth/) || cookieName.match(/Secure$/)));
|
||||
this._setCookie(Request.cookie(cookie), !!(cookieName.match(/^steamMachineAuth/) || cookieName.match(/Secure$/)));
|
||||
});
|
||||
};
|
||||
|
||||
@@ -460,11 +459,13 @@ SteamCommunity.prototype._myProfile = function(endpoint, form, callback) {
|
||||
function completeRequest(url) {
|
||||
var options = endpoint.endpoint ? endpoint : {};
|
||||
options.uri = "https://steamcommunity.com" + url + "/" + (endpoint.endpoint || endpoint);
|
||||
options.method = "GET";
|
||||
|
||||
if (form) {
|
||||
options.method = "POST";
|
||||
options.form = form;
|
||||
options.followAllRedirects = true;
|
||||
} else if (!options.method) {
|
||||
options.method = "GET";
|
||||
}
|
||||
|
||||
self.httpRequest(options, callback, "steamcommunity");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "steamcommunity",
|
||||
"version": "3.35.2",
|
||||
"version": "3.37.1",
|
||||
"description": "Provides an interface for logging into and interacting with the Steam Community website",
|
||||
"keywords": [
|
||||
"steam",
|
||||
@@ -22,7 +22,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@doctormckay/stats-reporter": "^1.0.2",
|
||||
"request": "^2.81.0",
|
||||
"request": "^2.86.0",
|
||||
"node-bignumber": "^1.2.1",
|
||||
"steamid": "^1.0.0",
|
||||
"xml2js": "^0.4.11",
|
||||
|
||||
@@ -119,6 +119,10 @@ module.exports = {
|
||||
"GSLTExpired": 106,
|
||||
"InsufficientFunds": 107,
|
||||
"TooManyPending": 108,
|
||||
"NoSiteLicensesFound": 109,
|
||||
"WGNetworkSendExceeded": 110,
|
||||
"AccountNotFriends": 111,
|
||||
"LimitedUserAccount": 112,
|
||||
|
||||
// Value-to-name mapping for convenience
|
||||
"0": "Invalid",
|
||||
@@ -229,4 +233,8 @@ module.exports = {
|
||||
"106": "GSLTExpired",
|
||||
"107": "InsufficientFunds",
|
||||
"108": "TooManyPending",
|
||||
"109": "NoSiteLicensesFound",
|
||||
"110": "WGNetworkSendExceeded",
|
||||
"111": "AccountNotFriends",
|
||||
"112": "LimitedUserAccount",
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user