Advertisement
Guest User

Untitled

a guest
Jan 31st, 2016
291
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.52 KB | None | 0 0
  1. module.exports = Entity;
  2.  
  3. var mongoose = require('mongoose'),
  4. util = require('util'),
  5. log = require('../services/logger').log('BotAccount'),
  6. Registry = require('../helpers/registry'),
  7. SteamTradeOffers = require('../steam/tradeOffers'),
  8. steam = require('../steam/lib/steam_client.js'),
  9. events = require('events'),
  10. underscore = require('underscore'),
  11. moment = require('moment'),
  12. q = require('q');
  13.  
  14. function Entity() {
  15. /*if (!GLOBAL.BotAccountsRegistry) {
  16. GLOBAL.BotAccountsRegistry = new Registry();
  17. };*/
  18.  
  19. var botAccountModel = mongoose.models['BotAccount'];
  20.  
  21. if (!botAccountModel) {
  22. var botAccountSchema = new mongoose.Schema({
  23. accountName: String,
  24. password: String,
  25. shaSentryfile: Buffer,
  26. shaSentryUpdated: Date,
  27. isActive: Boolean,
  28. apiKey: {
  29. domain: String,
  30. value: String
  31. }
  32. }, { strict: true });
  33.  
  34. botAccountSchema.methods.getLogOnOptions = instanceGetLogOnOptions;
  35. botAccountSchema.methods.connectAccount = instanceConnect;
  36. botAccountSchema.methods.initSteam = instanceInit;
  37. botAccountSchema.methods.loadInventory = instanceLoadInventory;
  38. botAccountSchema.methods.partnersInventory = instancePartnersInventory;
  39. botAccountSchema.methods.makeOffer = instanceMakeOffer;
  40. botAccountSchema.methods.getOffer = instanceGetOffer;
  41. botAccountSchema.methods.cancelOffer = instanceCancelOffer;
  42. botAccountSchema.methods.isConnected = function isConnected() {
  43. var self = this;
  44. return self.steamClient && self.steamClient.loggedOn;
  45. };
  46. botAccountSchema.methods.saveAsync = function () {
  47. var self = this;
  48.  
  49. return q.Promise(function (resolve, reject) {
  50. self.save(function (err, item, numberAffected) {
  51. if (err) {
  52. reject(err);
  53. }
  54. resolve(item, numberAffected);
  55. });
  56. });
  57. };
  58.  
  59. // hooks
  60. botAccountSchema.post('init', instanceInit);
  61.  
  62. botAccountModel = mongoose.model('BotAccount', botAccountSchema);
  63. }
  64.  
  65. Entity.prototype.BotAccountModel = botAccountModel;
  66. };
  67.  
  68. // bot store
  69. Entity.prototype.botAccountsRegistry = new Registry();
  70.  
  71. // todo
  72. Entity.prototype.getRandomBot = function() {
  73. var self = this;
  74. return self.getBotForTrade();
  75. };
  76.  
  77. Entity.prototype.getBotForTrade = function(deferred) {
  78. var self = this;
  79. if (!deferred)
  80. deferred = q.defer();
  81.  
  82. var botAccount = self.botAccountsRegistry.nextValue();
  83.  
  84. botAccount.connectAccount()
  85. .then(
  86. function () {
  87. deferred.resolve(botAccount);
  88. },
  89. function (error) {
  90. self.getBotForTrade(deferred);
  91. });
  92.  
  93. return deferred.promise;
  94. };
  95.  
  96. function onCriticalSteamError(error) {
  97. // remove entity from registry to allow relogin
  98. Entity.prototype.botAccountsRegistry.remove(this.accountName);
  99. log.error(error);
  100. };
  101.  
  102. Entity.prototype.findByName = function(name) {
  103. var self = this;
  104. var deferred = q.defer();
  105.  
  106. var bot = Entity.prototype.botAccountsRegistry.acquire(name);
  107. if (bot != undefined) {
  108. deferred.resolve(bot);
  109. }
  110. else {
  111. self.BotAccountModel
  112. .where('accountName', name)
  113. .findOne()
  114. .exec()
  115. .then(function (account) {
  116. if (!account) {
  117. deferred.reject(new Error('No bot account ' + name + ' was found in DB'));
  118. return;
  119. };
  120.  
  121. Entity.prototype.botAccountsRegistry.add(account.accountName, account);
  122. deferred.resolve(account);
  123.  
  124. }, function() {
  125. deferred.reject(new Error('Error while fetching the account ' + name));
  126. });
  127. };
  128.  
  129. return deferred.promise;
  130. };
  131.  
  132. Entity.prototype.LoadActive = function(isActive) {
  133. var self = this;
  134. var deferred = q.defer();
  135.  
  136. self.BotAccountModel
  137. .where('isActive', isActive)
  138. .exec()
  139. .then(function (accounts) {
  140. if (!accounts) {
  141. deferred.reject(new Error('No bot accounts was found in DB'));
  142. return;
  143. };
  144.  
  145. accounts.forEach(function (acc) {
  146. if (!Entity.prototype.botAccountsRegistry.acquire(acc.accountName)) {
  147. Entity.prototype.botAccountsRegistry.add(acc.accountName, acc);
  148. }
  149. });
  150.  
  151. deferred.resolve(Entity.prototype.botAccountsRegistry.acquireAll());
  152.  
  153. }, function () {
  154. deferred.reject(new Error('Error while fetching bot accounts'));
  155. });
  156.  
  157. return deferred.promise;
  158. };
  159.  
  160. instanceGetLogOnOptions = function () {
  161. var instance = this;
  162.  
  163. return {
  164. account_name : instance.accountName,
  165. password : instance.password,
  166. sha_sentryfile: instance.shaSentryfile
  167. };
  168. };
  169.  
  170. instanceLoadInventory = function () {
  171. var instance = this;
  172. var deferred = q.defer();
  173.  
  174. instance.connectAccount()
  175. .then(function () {
  176.  
  177. instance.tradeOffers.loadMyInventory({
  178. steamId: instance.steamClient.steamID,
  179. appId: 570, // dota2
  180. contextId: 2,
  181. language: "ru",
  182. tradableOnly: true
  183. }, function (err, items) {
  184.  
  185. if (err) {
  186. onCriticalSteamError.call(instance, err);
  187. deferred.reject(err);
  188. return;
  189. };
  190.  
  191. var tradableItems = underscore.filter(items, function(item) {
  192. return item.tradable && item.marketable;
  193. });
  194. deferred.resolve(tradableItems);
  195.  
  196. });
  197. },function (error) {
  198. onCriticalSteamError.call(instance, error);
  199. deferred.reject(error);
  200. });
  201.  
  202. return deferred.promise;
  203. };
  204.  
  205. instancePartnersInventory = function (options) {
  206. var instance = this;
  207. var deferred = q.defer();
  208.  
  209. instance.connectAccount()
  210. .then(function () {
  211.  
  212. instance.tradeOffers.loadPartnerInventory({
  213. appId: 570, // dota2
  214. contextId: 2,
  215. partnerSteamId: options.partnerSteamId,
  216. partnerAccountId: options.partnerAccountId,
  217. language: "ru",
  218. tradableOnly: true
  219. }, function (err, items) {
  220.  
  221. if (err) {
  222. onCriticalSteamError.call(instance, err);
  223. deferred.reject(err);
  224. return;
  225. };
  226.  
  227. var tradableItems = underscore.filter(items, function(item) {
  228. return item.tradable && item.marketable;
  229. });
  230. deferred.resolve(tradableItems);
  231.  
  232. });
  233. },function (error) {
  234. onCriticalSteamError.call(instance, error);
  235. deferred.reject(error);
  236. });
  237.  
  238. return deferred.promise;
  239. };
  240.  
  241. instanceMakeOffer = function (offerOptions) {
  242. var instance = this;
  243. var deferred = q.defer();
  244.  
  245. instance.connectAccount()
  246. .then(function () {
  247.  
  248. instance.tradeOffers.makeOffer(offerOptions,
  249. function (err, result) {
  250. if (err) {
  251. onCriticalSteamError.call(instance, err);
  252. deferred.reject(err);
  253. return;
  254. };
  255.  
  256. deferred.resolve(result);
  257. });
  258. },function (error) {
  259. onCriticalSteamError.call(instance, error);
  260. deferred.reject(error);
  261. });
  262.  
  263. return deferred.promise;
  264. };
  265.  
  266. instanceGetOffer = function (options) {
  267. var instance = this;
  268. var deferred = q.defer();
  269.  
  270. instance.connectAccount()
  271. .then(function () {
  272.  
  273. instance.tradeOffers.getOffer(options, function (err, result) {
  274. if (err || !result) {
  275. onCriticalSteamError.call(instance, err || "Empty response");
  276. deferred.reject(err);
  277. return;
  278. };
  279.  
  280. deferred.resolve(result.response);
  281. });
  282. },function (error) {
  283. onCriticalSteamError.call(instance, error);
  284. deferred.reject(error);
  285. });
  286.  
  287. return deferred.promise;
  288. };
  289.  
  290. instanceCancelOffer = function (options) {
  291. var instance = this;
  292. var deferred = q.defer();
  293.  
  294. instance.connectAccount()
  295. .then(function () {
  296.  
  297. instance.tradeOffers.cancelOffer(options, function (err, result) {
  298. if (err || !result) {
  299. onCriticalSteamError.call(instance, err || "Empty response");
  300. deferred.reject(err);
  301. return;
  302. };
  303.  
  304. deferred.resolve(result.response);
  305. });
  306. },function (error) {
  307. onCriticalSteamError.call(instance, error);
  308. deferred.reject(error);
  309. });
  310.  
  311. return deferred.promise;
  312. };
  313.  
  314. instanceConnect = function (authCode, ignoreSteamErrors) {
  315. var instance = this;
  316. var deferred = q.defer();
  317.  
  318. if (instance.isConnected()) {
  319. deferred.resolve(true);
  320. } else {
  321. var logOnOptions = instance.getLogOnOptions();
  322. if (authCode) {
  323. logOnOptions.auth_code = authCode;
  324. };
  325.  
  326. instance.events.once('error', function (err) {
  327. onCriticalSteamError.call(instance, err);
  328. if (ignoreSteamErrors) {
  329. deferred.resolve(true);
  330. } else {
  331. deferred.reject(err);
  332. }
  333. });
  334.  
  335. instance.events.once('connected', function() {
  336. deferred.resolve(true);
  337. });
  338.  
  339. instance.events.once('needAuthCode', function () {
  340. //onCriticalSteamError.call(instance, new Error('Account ' + instance.accountName + ' need Steam Secure Code'));
  341. deferred.resolve(false);
  342. });
  343.  
  344. instance.steamClient.on('connected', function () {
  345. instance.steamUser.logOn(logOnOptions);
  346. });
  347.  
  348. instance.steamClient.connect();
  349. }
  350.  
  351. return deferred.promise;
  352. };
  353.  
  354. // adds steam connect event handle functions
  355. instanceInit = function () {
  356. var instance = this;
  357.  
  358. instance.steamClient = new steam.SteamClient();
  359. instance.steamUser = new steam.SteamUser(instance.steamClient);
  360. instance.tradeOffers = new SteamTradeOffers(instance.steamClient, instance.steamUser);
  361.  
  362. //instance.events = new events.EventEmitter();
  363. instance.events = new events();
  364.  
  365. instance.events.on('error', function (error) {
  366. log.error(error);
  367. });
  368. //steam.on('debug', console.log);
  369.  
  370. instance.steamClient.on('error', function (error) {
  371. instance.events.emit('error', error);
  372. });
  373.  
  374. instance.steamClient.on('logOnResponse', function (logonResp) {
  375. if (logonResp.eresult != steam.EResult.OK) {
  376. if (logonResp.eresult == steam.EResult.AccountLogonDenied) {
  377. instance.events.emit('needAuthCode');
  378. } else {
  379. instance.events.emit('error', logonResp);
  380. }
  381. return;
  382. }
  383.  
  384. log.info('Logged on account ' + instance.accountName + ' accountFlags: ' + instance.tradeOffers.accountFlags.key);
  385.  
  386. // could not do anything with limited account
  387. var newDeviceLimit = moment.utc().diff(instance.shaSentryUpdated, 'days') < 7;
  388.  
  389. if (instance.tradeOffers.IsLimited || newDeviceLimit) {
  390. instance.isActive = false;
  391. instance.save(function (err) {
  392. if (err) {
  393. instance.events.emit('error', err);
  394. return;
  395. }
  396.  
  397. log.info('Account ' + instance.accountName + ' was disabled.');
  398. });
  399.  
  400. var error = new Error('Account ' + instance.accountName + ' is limited');
  401. log.error(error);
  402. instance.events.emit('error', error);
  403. return;
  404. }
  405.  
  406. var options = { host: 'localhost' };
  407.  
  408. if (instance.apiKey && instance.apiKey.domain == options.host) {
  409. options.apiKey = instance.apiKey.value;
  410. }
  411.  
  412. instance.tradeOffers.setup(options, function (error) {
  413. if (error) {
  414. log.error(error);
  415. instance.events.emit('error', error);
  416. return;
  417. }
  418.  
  419. log.info('Logged on web account ' + instance.accountName);
  420. var needUpdate = false;
  421.  
  422. if (!instance.isActive) {
  423. instance.isActive = true;
  424. needUpdate = true;
  425. }
  426.  
  427. if (!options.apiKey ) {
  428. instance.apiKey = {
  429. domain: options.host,
  430. value: instance.tradeOffers.APIKey
  431. };
  432. needUpdate = true;
  433. }
  434.  
  435. if (needUpdate){
  436. instance.save(function (err) {
  437. if (err) {
  438. instance.events.emit('error', err);
  439. return;
  440. }
  441. log.info('Account updated ' + instance.accountName);
  442. });
  443. }
  444.  
  445. instance.events.emit('connected');
  446. });
  447. });
  448.  
  449. instance.steamUser.on('updateMachineAuth', function (data, callback) {
  450. //callback({ sha_file: require('crypto').createHash('sha1').update(data.bytes).digest('hex') });
  451.  
  452. var sha = require('crypto').createHash('sha1');
  453. sha.update(data.bytes);
  454. var digest = sha.digest();
  455.  
  456. callback({ sha_file: digest });
  457.  
  458. instance.shaSentryfile = new Buffer(digest, 'binary');
  459. instance.shaSentryUpdated = moment.utc();
  460. instance.isActive = false;
  461. instance.save(function (error) {
  462. if (error) {
  463. instance.events.emit('error', error);
  464. return;
  465. }
  466.  
  467. log.info('Sentry code updated ' + instance.accountName);
  468. });
  469. });
  470.  
  471. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement