├── .gitignore ├── LICENSE ├── README.md ├── data ├── csgo_english.txt └── items_game.txt ├── index.js ├── package.json └── skins.json /.gitignore: -------------------------------------------------------------------------------- 1 | *.lnk 2 | node_modules -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 João Silva 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # node-csgo-items-parser 2 | NodeJS CSGO Items dumper 3 | 4 | Takes items_game.txt and csgo_english.txt as input and outputs skins.json with Paintkit IDs, names, weapons and associated Paintkits 5 | -------------------------------------------------------------------------------- /data/csgo_english.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vankxr/node-csgo-items-parser/9e03ef9e2c4da54ff4379d1f301dd3656aea15f7/data/csgo_english.txt -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const start = Date.now(); 2 | const vdf = require("simple-vdf"); 3 | 4 | var items_game = vdf.parse(require("fs").readFileSync("./data/items_game.txt", "utf8")).items_game; 5 | var csgo_english = vdf.parse(require("fs").readFileSync("./data/csgo_english.txt", "utf16le")); 6 | csgo_english = csgo_english[Object.keys(csgo_english)]; // Fuck UTF-16 Little Endian 7 | 8 | var weapon_indexes = {}; 9 | var weapon_classes = [ 10 | "weapon_deagle", 11 | "weapon_elite", 12 | "weapon_fiveseven", 13 | "weapon_glock", 14 | "weapon_hkp2000", 15 | "weapon_p250", 16 | "weapon_cz75a", 17 | "weapon_tec9", 18 | "weapon_bizon", 19 | "weapon_mac10", 20 | "weapon_mp7", 21 | "weapon_mp9", 22 | "weapon_p90", 23 | "weapon_mp5sd", 24 | "weapon_ump45", 25 | "weapon_ak47", 26 | "weapon_aug", 27 | "weapon_famas", 28 | "weapon_galilar", 29 | "weapon_m4a1_silencer", 30 | "weapon_m4a1", 31 | "weapon_sg556", 32 | "weapon_awp", 33 | "weapon_g3sg1", 34 | "weapon_scar20", 35 | "weapon_ssg08", 36 | "weapon_mag7", 37 | "weapon_nova", 38 | "weapon_sawedoff", 39 | "weapon_xm1014", 40 | "weapon_m249", 41 | "weapon_negev", 42 | "weapon_decoy", 43 | "weapon_flashbang", 44 | "weapon_hegrenade", 45 | "weapon_incgrenade", 46 | "weapon_molotov", 47 | "weapon_smokegrenade", 48 | "weapon_usp_silencer", 49 | "weapon_revolver", 50 | "weapon_bayonet", 51 | "weapon_knife_css", 52 | "weapon_knife_flip", 53 | "weapon_knife_gut", 54 | "weapon_knife_karambit", 55 | "weapon_knife_m9_bayonet", 56 | "weapon_knife_tactical", 57 | "weapon_knife_falchion", 58 | "weapon_knife_survival_bowie", 59 | "weapon_knife_butterfly", 60 | "weapon_knife_push", 61 | "weapon_knife_cord", 62 | "weapon_knife_canis", 63 | "weapon_knife_ursus", 64 | "weapon_knife_gypsy_jackknife", 65 | "weapon_knife_outdoor", 66 | "weapon_knife_stiletto", 67 | "weapon_knife_widowmaker", 68 | "weapon_knife_skeleton", 69 | "weapon_knife_default_ct", 70 | "weapon_knife_t", 71 | "studded_bloodhound_gloves", 72 | "ct_gloves", 73 | "sporty_gloves", 74 | "slick_gloves", 75 | "leather_handwraps", 76 | "motorcycle_gloves", 77 | "specialist_gloves", 78 | "studded_hydra_gloves", 79 | "t_gloves" 80 | ]; 81 | var item_rarities = ["default", "common", "uncommon", "rare", "mythical", "legendary", "ancient", "immortal", "unusual"]; 82 | var out = { 83 | paintkit_names: {}, 84 | paintkit_ids: {}, 85 | stickerkit_names: {}, 86 | stickerkit_ids: {}, 87 | stickerkits: [], 88 | weapon_skins: {}, 89 | medals: [], 90 | medal_names: {}, 91 | agents: [[], []], 92 | agent_names: {}, 93 | agent_models: {}, 94 | agent_rarities: {} 95 | }; 96 | 97 | var item_indexes = Object.keys(items_game.items); 98 | for(var i = 0; i < item_indexes.length; i++) { 99 | if(!items_game.items[item_indexes[i]].name) continue; 100 | 101 | weapon_indexes[items_game.items[item_indexes[i]].name] = parseInt(item_indexes[i]); 102 | 103 | if(!items_game.items[item_indexes[i]].item_name) continue; 104 | 105 | if(items_game.items[item_indexes[i]].item_name.indexOf("#CSGO_Collectible") != -1) 106 | { 107 | var medal_lang_key = items_game.items[item_indexes[i]].item_name.replace("#", ""); 108 | var medal_lang_name = csgo_english.Tokens[medal_lang_key]; 109 | 110 | out.medals.push(parseInt(item_indexes[i])); 111 | out.medal_names[item_indexes[i]] = medal_lang_name; 112 | } 113 | 114 | if(items_game.items[item_indexes[i]].prefab == "customplayertradable") 115 | { 116 | var agent_class; 117 | 118 | if(items_game.items[item_indexes[i]].used_by_classes["terrorists"]) 119 | agent_class = 0; 120 | else if(items_game.items[item_indexes[i]].used_by_classes["counter-terrorists"]) 121 | agent_class = 1; 122 | else 123 | continue; 124 | 125 | var agent_lang_key = items_game.items[item_indexes[i]].item_name.replace("#", ""); 126 | var agent_lang_name = csgo_english.Tokens[agent_lang_key]; 127 | 128 | if(!agent_lang_name) 129 | agent_lang_name = agent_lang_key.replace("CSGO_CustomPlayer_", "") 130 | 131 | out.agents[agent_class].push(parseInt(item_indexes[i])); 132 | out.agent_names[item_indexes[i]] = agent_lang_name; 133 | out.agent_models[item_indexes[i]] = items_game.items[item_indexes[i]].model_player; 134 | out.agent_rarities[item_indexes[i]] = item_rarities.indexOf(items_game.items[item_indexes[i]].item_rarity); 135 | } 136 | } 137 | 138 | var paintkit_ids = Object.keys(items_game.paint_kits); 139 | for(var i = 0; i < paintkit_ids.length; i++) { 140 | if(!items_game.paint_kits[paintkit_ids[i]].description_tag) continue; 141 | 142 | var paintkit_id = paintkit_ids[i]; 143 | var skin_lang_key = items_game.paint_kits[paintkit_id].description_tag.replace("#", ""); 144 | var skin_name = items_game.paint_kits[paintkit_id].name; 145 | 146 | var skin_lang_name = csgo_english.Tokens[skin_lang_key] ? csgo_english.Tokens[skin_lang_key] : csgo_english.Tokens[skin_lang_key.replace("PaintKit_", "Paintkit_")]; 147 | 148 | out.paintkit_ids[skin_name] = parseInt(paintkit_id); 149 | out.paintkit_names[skin_name] = skin_lang_name; 150 | } 151 | 152 | var stickerkit_ids = Object.keys(items_game.sticker_kits); 153 | for(var i = 0; i < stickerkit_ids.length; i++) { 154 | if(!items_game.sticker_kits[stickerkit_ids[i]].item_name) continue; 155 | 156 | var stickerkit_id = stickerkit_ids[i]; 157 | var sticker_lang_key = items_game.sticker_kits[stickerkit_id].item_name.replace("#", ""); 158 | var sticker_name = items_game.sticker_kits[stickerkit_id].name; 159 | 160 | var skin_lang_name = csgo_english.Tokens[sticker_lang_key]; 161 | 162 | out.stickerkits.push(sticker_name); 163 | out.stickerkit_ids[sticker_name] = parseInt(stickerkit_id); 164 | out.stickerkit_names[sticker_name] = skin_lang_name; 165 | } 166 | 167 | var model_ids = Object.keys(items_game.alternate_icons2.weapon_icons); 168 | for(var i = 0; i < model_ids.length; i++) { 169 | if(!items_game.alternate_icons2.weapon_icons[model_ids[i]].icon_path) continue; 170 | 171 | var weapon_skin_name = items_game.alternate_icons2.weapon_icons[model_ids[i]].icon_path.split("/")[2]; 172 | 173 | if(weapon_skin_name.substr(-6, 6) == "_heavy") weapon_skin_name = weapon_skin_name.substr(0, weapon_skin_name.length - 6); 174 | if(weapon_skin_name.substr(-6, 6) == "_light") weapon_skin_name = weapon_skin_name.substr(0, weapon_skin_name.length - 6); // Cant use replace cuz volvo sux "weapon_awp_am <_light> ning_awp <_light>" << 175 | if(weapon_skin_name.substr(-7, 7) == "_medium") weapon_skin_name = weapon_skin_name.substr(0, weapon_skin_name.length - 7); 176 | 177 | for(var j = 0; j < weapon_classes.length; j++) { 178 | if(weapon_skin_name.indexOf(weapon_classes[j]) == -1) continue; 179 | 180 | var weapon_name = weapon_classes[j]; 181 | var skin_name = weapon_skin_name.replace(weapon_name + "_", ""); 182 | 183 | out.weapon_skins[weapon_indexes[weapon_name]] = out.weapon_skins[weapon_indexes[weapon_name]] ? out.weapon_skins[weapon_indexes[weapon_name]] : {paintkit_names: [], paintkit_rarities: []}; 184 | 185 | if(out.weapon_skins[weapon_indexes[weapon_name]].paintkit_names.indexOf(skin_name) == -1) { 186 | if(!out.paintkit_names[skin_name]) { 187 | console.log("Weapon '" + weapon_name + "' has skin '" + skin_name + "' but it was not found!"); 188 | console.log(weapon_skin_name); 189 | } 190 | 191 | out.weapon_skins[weapon_indexes[weapon_name]].paintkit_names.push(skin_name); 192 | out.weapon_skins[weapon_indexes[weapon_name]].paintkit_rarities.push(item_rarities.indexOf(items_game.paint_kits_rarity[skin_name])); 193 | } 194 | 195 | break; 196 | } 197 | } 198 | 199 | var loot_lists = Object.keys(items_game.client_loot_lists); 200 | for(var i = 0; i < loot_lists.length; i++) { 201 | var list_name = loot_lists[i]; 202 | var list_name_parts = list_name.split("_"); 203 | var rarity = item_rarities.indexOf(list_name_parts[list_name_parts.length - 1]); 204 | 205 | if(rarity == -1) 206 | continue; 207 | 208 | var list_paintkits = Object.keys(items_game.client_loot_lists[list_name]); 209 | for(var j = 0; j < list_paintkits.length; j++) { 210 | var paintkit_parts = list_paintkits[j].replace("[", "").split("]"); 211 | 212 | if(paintkit_parts.length != 2) 213 | continue; 214 | 215 | var paintkit_name = paintkit_parts[0]; 216 | var weapon_name = paintkit_parts[1]; 217 | 218 | if(!weapon_indexes[weapon_name] || !out.weapon_skins[weapon_indexes[weapon_name]]) 219 | continue; 220 | 221 | for(var k = 0; k < out.weapon_skins[weapon_indexes[weapon_name]].paintkit_names.length; k++) { 222 | if(out.weapon_skins[weapon_indexes[weapon_name]].paintkit_names[k] == paintkit_name) { 223 | out.weapon_skins[weapon_indexes[weapon_name]].paintkit_rarities[k] = rarity; 224 | 225 | break; 226 | } 227 | } 228 | } 229 | } 230 | 231 | for(var i = 0; i < weapon_classes.length; i++) { 232 | if(i >= weapon_classes.indexOf("weapon_bayonet")) 233 | break; 234 | 235 | if(!weapon_indexes[weapon_classes[i]] || !out.weapon_skins[weapon_indexes[weapon_classes[i]]]) 236 | continue; 237 | 238 | if(out.weapon_skins[weapon_indexes[weapon_classes[i]]].paintkit_names.length > out.weapon_skins[weapon_indexes[weapon_classes[i]]].paintkit_rarities.length) 239 | console.log((out.weapon_skins[weapon_indexes[weapon_classes[i]]].paintkit_names.length - out.weapon_skins[weapon_indexes[weapon_classes[i]]].paintkit_rarities.length) + " paintkits for weapon '" + weapon_classes[i] + "' do not have a rarity!"); 240 | else if(out.weapon_skins[weapon_indexes[weapon_classes[i]]].paintkit_names.length < out.weapon_skins[weapon_indexes[weapon_classes[i]]].paintkit_rarities.length) 241 | console.log((out.weapon_skins[weapon_indexes[weapon_classes[i]]].paintkit_rarities.length - out.weapon_skins[weapon_indexes[weapon_classes[i]]].paintkit_names.length) + " paintkits for weapon '" + weapon_classes[i] + "' do not have a name, but have a rarity!"); 242 | 243 | } 244 | 245 | require("fs").writeFileSync("skins.json", JSON.stringify(out, null, "\t")); 246 | console.log("Time elapsed: " + (Date.now() - start) + " ms"); 247 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-csgo-items-parser", 3 | "version": "1.0.0", 4 | "description": "NodeJS CSGO Items dumper", 5 | "main": "index.js", 6 | "dependencies": { 7 | "simple-vdf": "^1.1.0" 8 | }, 9 | "devDependencies": {}, 10 | "scripts": { 11 | "test": "echo \"Error: no test specified\" && exit 1" 12 | }, 13 | "author": "Vankxr", 14 | "license": "MIT" 15 | } 16 | --------------------------------------------------------------------------------