Skip to content
This repository has been archived by the owner on Aug 5, 2023. It is now read-only.

Commit

Permalink
Adds Base Project
Browse files Browse the repository at this point in the history
  • Loading branch information
Step7750 committed Apr 26, 2019
1 parent 750d74d commit 882a465
Show file tree
Hide file tree
Showing 6 changed files with 753 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.idea/
node_modules/
items_game.txt
csgo_english.txt
config.js
7 changes: 7 additions & 0 deletions config.example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
port: 80,
// amount of seconds between updating game files
file_update_interval: 30 * 60 * 1000,
// postgres connection string
connectionString: '<POSTGRES_CONNECTION>'
};
120 changes: 120 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
const config = require('./config');
const vdf = require('simple-vdf');
const fs = require('fs');
const express = require('express');
const fetch = require('node-fetch');
const { Pool } = require('pg');
const ItemParser = require('./item_parser');
const app = express();

const pool = new Pool({
connectionString: config.connectionString,
});

let itemParser;

const itemUrl = `https://raw.githubusercontent.com/SteamDatabase/GameTracking-CSGO/master/csgo/scripts/items/items_game.txt`;
const englishUrl = `https://raw.githubusercontent.com/SteamDatabase/GameTracking-CSGO/master/csgo/resource/csgo_english.txt`;

async function updateItems() {
try {
const resp = await fetch(itemUrl);
const data = await resp.text();
fs.writeFile('items_game.txt', data, () => {
console.log('Saved items_game.txt');
});

const langResp = await fetch(englishUrl);
const langData = await langResp.text();
fs.writeFile('csgo_english.txt', langData, () => {
console.log('Saved csgo_english.txt');
});

itemParser = new ItemParser(vdf.parse(data).items_game, vdf.parse(langData).lang.Tokens);
} catch (e) {
console.error(e);
}
}

if (fs.existsSync('items_game.txt') && fs.existsSync('items_game.txt')) {
const itemsGame = fs.readFileSync('items_game.txt', 'utf8');
itemParser = new ItemParser(vdf.parse(itemsGame)['items_game']);

const english = fs.readFileSync('csgo_english.txt', 'utf8');
itemParser = new ItemParser(vdf.parse(itemsGame).items_game, vdf.parse(english).lang.Tokens);
} else {
updateItems();
}

setInterval(() => updateItems(), config.file_update_interval);


app.get('/items', (req, res) => {
if (itemParser) {
res.json(itemParser.getFullResponse());
} else {
res.status(500).json({error: 'Item response is not initialized, new csgo update?'});
}
});

/*
Possible URL Query Params
defIndex: Weapon index
paintIndex: Paint index
order: 1 for asc, -1 for desc
stattrak: true/false
souvenir: true/false
TODO: Implement support for stickers
*/
function buildQuery(params) {
const conditions = [], values = [];

if (params.defIndex) {
conditions.push(`defindex = $${conditions.length+1}`);
values.push(params.defIndex);
}

if (params.paintIndex) {
conditions.push(`paintindex = $${conditions.length+1}`);
values.push(params.paintIndex);
}

if (params.stattrak) {
conditions.push(`stattrak = $${conditions.length+1}`);
values.push(params.stattrak);
}

if (params.souvenir) {
conditions.push(`souvenir = $${conditions.length+1}`);
values.push(params.souvenir);
}

let statement;
if (conditions.length > 0) {
statement = `SELECT * FROM items ORDER BY paintwear ${params.order === -1 ? 'DESC' : ''} LIMIT 200`;
} else {
statement = `SELECT * FROM items ${conditions.length > 0 ? 'WHERE' : ''} ${conditions.join(' AND ')}
ORDER BY paintwear ${params.order === -1 ? 'DESC' : ''} LIMIT 200`;
}

return {
text: statement,
values
}
}

app.get('/search', async (req, res) => {
const query = buildQuery(req.params);

try {
const results = await pool.query(query);
res.json(results.rows);
} catch (e) {
console.error(e);
res.status(400).json({error: 'Something went wrong'});
}
});

app.listen(config.port, () => console.log(`Listening on Port ${config.port}`));
129 changes: 129 additions & 0 deletions item_parser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
class ItemParser {
constructor(itemsGame, language) {
this.itemsGame = itemsGame;
this.language = language;
}

_getPrefabStickerAmount(prefabName) {
const prefab = this.itemsGame.prefabs[prefabName];
return Object.keys(prefab.stickers || {}).length;
}

_isWeapon(prefabName) {
const prefab = this.itemsGame.prefabs[prefabName];
const usedClasses = prefab && prefab.used_by_classes;

return usedClasses && (usedClasses['terrorists'] || usedClasses['counter-terrorists']);
}

_getWeapons() {
const weapons = {};
for (const defIndex in this.itemsGame.items) {
const item = this.itemsGame.items[defIndex];
if (item.prefab && this._isWeapon(item.prefab)) {
weapons[defIndex] = item;
}
}

return weapons;
}

_getWeaponLanguageName(defIndex) {
const item = this.itemsGame.items[defIndex];

if (item.item_name) {
return this._getLanguageValue(item.item_name);
} else {
const prefab = this.itemsGame.prefabs[item.prefab];
return this._getLanguageValue(prefab.item_name);
}
}

_getPaintKitIndex(name) {
return Object.keys(this.itemsGame.paint_kits).find((paintIndex) => {
const kit = this.itemsGame.paint_kits[paintIndex];

if (kit.name === name) {
return true;
}
})
}

_getLanguageValue(token) {
return this.language[token.replace('#', '')];
}

_getWeaponPaints(weaponName) {
const paints = {};

for (const setName of Object.keys(this.itemsGame.item_sets)) {
const setItems = Object.keys(this.itemsGame.item_sets[setName].items);

for (const setItem of setItems) {
if (setItem.indexOf(weaponName) === -1) continue;

const paintName = setItem.match(/\[(.*)].*/)[1];

const index = this._getPaintKitIndex(paintName);

if (index) {
const kit = this.itemsGame.paint_kits[index];
paints[index] = {
name: this._getLanguageValue(kit.description_tag),
min: parseFloat(kit.wear_remap_min || 0.06),
max: parseFloat(kit.wear_remap_max || 0.80),
};
}

}
}

return paints;
}

getStickers() {
const stickers = {};

for (const stickerId of Object.keys(this.itemsGame.sticker_kits)) {
if (stickerId == '0') continue;

const sticker = this.itemsGame.sticker_kits[stickerId];

stickers[stickerId] = this._getLanguageValue(sticker.item_name)
}

return stickers;
}

getFullResponse() {
if (this.resp) return this.resp;

const resp = {};

const weapons = this._getWeapons();

const weaponsResp = {};

for (const defIndex of Object.keys(weapons)) {
const weapon = weapons[defIndex];
const paints = this._getWeaponPaints(weapon.name);

if (Object.keys(paints).length === 0) continue;

weaponsResp[defIndex] = {
name: this._getWeaponLanguageName(defIndex),
stickerAmount: this._getPrefabStickerAmount(weapon.prefab),
paints
};
}

resp.weapons = weaponsResp;
resp.stickers = this.getStickers();

this.resp = resp;

return resp;
}
}

module.exports = ItemParser;
Loading

0 comments on commit 882a465

Please sign in to comment.