CoolFace
Apppublic

PixelPiggy/CS_float

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
index.js263 linesDownload Raw Back to root
1global._mckay_statistics_opt_out = true; // Opt out of node-steam-user stats2 3const optionDefinitions = [4    { name: 'config', alias: 'c', type: String, defaultValue: './config.js' }, // Config file location5    { name: 'steam_data', alias: 's', type: String } // Steam data directory6];7 8const winston = require('winston'),9    args = require('command-line-args')(optionDefinitions),10    bodyParser = require('body-parser'),11    rateLimit = require('express-rate-limit'),12    utils = require('./lib/utils'),13    queue = new (require('./lib/queue'))(),14    InspectURL = require('./lib/inspect_url'),15    botController = new (require('./lib/bot_controller'))(),16    CONFIG = require(args.config),17    postgres = new (require('./lib/postgres'))(CONFIG.database_url, CONFIG.enable_bulk_inserts),18    gameData = new (require('./lib/game_data'))(CONFIG.game_files_update_interval, CONFIG.enable_game_file_updates),19    errors = require('./errors'),20    Job = require('./lib/job');21 22if (CONFIG.max_simultaneous_requests === undefined) {23    CONFIG.max_simultaneous_requests = 1;24}25 26winston.level = CONFIG.logLevel || 'debug';27 28if (CONFIG.logins.length === 0) {29    console.log('There are no bot logins. Please add some in config.json');30    process.exit(1);31}32 33if (args.steam_data) {34    CONFIG.bot_settings.steam_user.dataDirectory = args.steam_data;35}36 37for (let [i, loginData] of CONFIG.logins.entries()) {38    const settings = Object.assign({}, CONFIG.bot_settings);39    if (CONFIG.proxies && CONFIG.proxies.length > 0) {40        const proxy = CONFIG.proxies[i % CONFIG.proxies.length];41 42        if (proxy.startsWith('http://')) {43            settings.steam_user = Object.assign({}, settings.steam_user, {httpProxy: proxy});44        } else if (proxy.startsWith('socks5://')) {45            settings.steam_user = Object.assign({}, settings.steam_user, {socksProxy: proxy});46        } else {47            console.log(`Invalid proxy '${proxy}' in config, must prefix with http:// or socks5://`);48            process.exit(1);49        }50    }51 52    botController.addBot(loginData, settings);53}54 55postgres.connect();56 57// Setup and configure express58const app = require('express')();59app.use(function (req, res, next) {60    if (req.method === 'POST') {61        // Default content-type62        req.headers['content-type'] = 'application/json';63    }64    next();65});66app.use(bodyParser.json({limit: '5mb'}));67 68app.use(function (error, req, res, next) {69    // Handle bodyParser errors70    if (error instanceof SyntaxError) {71        errors.BadBody.respond(res);72    }73    else next();74});75 76 77if (CONFIG.trust_proxy === true) {78    app.enable('trust proxy');79}80 81CONFIG.allowed_regex_origins = CONFIG.allowed_regex_origins || [];82CONFIG.allowed_origins = CONFIG.allowed_origins || [];83const allowedRegexOrigins = CONFIG.allowed_regex_origins.map((origin) => new RegExp(origin));84 85 86async function handleJob(job) {87    // See which items have already been cached88    const itemData = await postgres.getItemData(job.getRemainingLinks().map(e => e.link));89    for (let item of itemData) {90        const link = job.getLink(item.a);91 92        if (!item.price && link.price) {93            postgres.updateItemPrice(item.a, link.price);94        }95 96        gameData.addAdditionalItemProperties(item);97        item = utils.removeNullValues(item);98 99        job.setResponse(item.a, item);100    }101 102    if (!botController.hasBotOnline()) {103        return job.setResponseRemaining(errors.SteamOffline);104    }105 106    if (CONFIG.max_simultaneous_requests > 0 &&107        (queue.getUserQueuedAmt(job.ip) + job.remainingSize()) > CONFIG.max_simultaneous_requests) {108        return job.setResponseRemaining(errors.MaxRequests);109    }110 111    if (CONFIG.max_queue_size > 0 && (queue.size() + job.remainingSize()) > CONFIG.max_queue_size) {112        return job.setResponseRemaining(errors.MaxQueueSize);113    }114 115    if (job.remainingSize() > 0) {116        queue.addJob(job, CONFIG.bot_settings.max_attempts);117    }118}119 120function canSubmitPrice(key, link, price) {121    return CONFIG.price_key && key === CONFIG.price_key && price && link.isMarketLink() && utils.isOnlyDigits(price);122}123 124app.use(function (req, res, next) {125    if (CONFIG.allowed_origins.length > 0 && req.get('origin') != undefined) {126        // check to see if its a valid domain127        const allowed = CONFIG.allowed_origins.indexOf(req.get('origin')) > -1 ||128            allowedRegexOrigins.findIndex((reg) => reg.test(req.get('origin'))) > -1;129 130        if (allowed) {131            res.header('Access-Control-Allow-Origin', req.get('origin'));132            res.header('Access-Control-Allow-Methods', 'GET');133        }134    }135    next()136});137 138if (CONFIG.rate_limit && CONFIG.rate_limit.enable) {139    app.use(rateLimit({140        windowMs: CONFIG.rate_limit.window_ms,141        max: CONFIG.rate_limit.max,142        headers: false,143        handler: function (req, res) {144            errors.RateLimit.respond(res);145        }146    }))147}148 149app.get('/', function(req, res) {150    // Get and parse parameters151    let link;152 153    if ('url' in req.query) {154        link = new InspectURL(req.query.url);155    }156    else if ('a' in req.query && 'd' in req.query && ('s' in req.query || 'm' in req.query)) {157        link = new InspectURL(req.query);158    }159 160    if (!link || !link.getParams()) {161        return errors.InvalidInspect.respond(res);162    }163 164    const job = new Job(req, res, /* bulk */ false);165 166    let price;167 168    if (canSubmitPrice(req.query.priceKey, link, req.query.price)) {169        price = parseInt(req.query.price);170    }171 172    job.add(link, price);173 174    try {175        handleJob(job);176    } catch (e) {177        winston.warn(e);178        errors.GenericBad.respond(res);179    }180});181 182app.post('/bulk', (req, res) => {183    if (!req.body || (CONFIG.bulk_key && req.body.bulk_key != CONFIG.bulk_key)) {184        return errors.BadSecret.respond(res);185    }186 187    if (!req.body.links || req.body.links.length === 0) {188        return errors.BadBody.respond(res);189    }190 191    if (CONFIG.max_simultaneous_requests > 0 && req.body.links.length > CONFIG.max_simultaneous_requests) {192        return errors.MaxRequests.respond(res);193    }194 195    const job = new Job(req, res, /* bulk */ true);196 197    for (const data of req.body.links) {198        const link = new InspectURL(data.link);199        if (!link.valid) {200            return errors.InvalidInspect.respond(res);201        }202 203        let price;204 205        if (canSubmitPrice(req.body.priceKey, link, data.price)) {206            price = parseInt(req.query.price);207        }208 209        job.add(link, price);210    }211 212    try {213        handleJob(job);214    } catch (e) {215        winston.warn(e);216        errors.GenericBad.respond(res);217    }218});219 220app.get('/stats', (req, res) => {221    res.json({222        bots_online: botController.getReadyAmount(),223        bots_total: botController.bots.length,224        queue_size: queue.queue.length,225        queue_concurrency: queue.concurrency,226    });227});228 229const http_server = require('http').Server(app);230http_server.listen(CONFIG.http.port);231winston.info('Listening for HTTP on port: ' + CONFIG.http.port);232 233queue.process(CONFIG.logins.length, botController, async (job) => {234    const itemData = await botController.lookupFloat(job.data.link);235    winston.debug(`Received itemData for ${job.data.link.getParams().a}`);236 237    // Save and remove the delay attribute238    let delay = itemData.delay;239    delete itemData.delay;240 241    // add the item info to the DB242    await postgres.insertItemData(itemData.iteminfo, job.data.price);243 244    // Get rank, annotate with game files245    itemData.iteminfo = Object.assign(itemData.iteminfo, await postgres.getItemRank(itemData.iteminfo.a));246    gameData.addAdditionalItemProperties(itemData.iteminfo);247 248    itemData.iteminfo = utils.removeNullValues(itemData.iteminfo);249    itemData.iteminfo.stickers = itemData.iteminfo.stickers.map((s) => utils.removeNullValues(s));250    itemData.iteminfo.keychains = itemData.iteminfo.keychains.map((s) => utils.removeNullValues(s));251 252    job.data.job.setResponse(job.data.link.getParams().a, itemData.iteminfo);253 254    return delay;255});256 257queue.on('job failed', (job, err) => {258    const params = job.data.link.getParams();259    winston.warn(`Job Failed! S: ${params.s} A: ${params.a} D: ${params.d} M: ${params.m} IP: ${job.ip}, Err: ${(err || '').toString()}`);260 261    job.data.job.setResponse(params.a, errors.TTLExceeded);262});263