├── .eslintignore ├── .eslintrc.json ├── .github └── workflows │ ├── codeql-analysis.yml │ ├── nodejs.yml │ └── npmpublish.yml ├── .gitignore ├── LICENSE ├── README.md ├── app.js ├── lib ├── hypixel.js └── util.js ├── package-lock.json ├── package.json └── test └── index.js /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parserOptions": { 3 | "ecmaVersion": 2017 4 | }, 5 | "env": { 6 | "es6": true, 7 | "node": true 8 | }, 9 | "extends": "eslint:recommended", 10 | "rules": { 11 | "no-console": "off", 12 | "indent": [ 13 | "error", 14 | 2, 15 | { 16 | "SwitchCase": 1 17 | } 18 | ], 19 | "linebreak-style": ["error", "windows"], 20 | "quotes": ["warn", "double"], 21 | // "semi": [ 22 | // "warn", 23 | // "always" 24 | // ], 25 | "keyword-spacing": [ 26 | "error", 27 | { 28 | "before": true, 29 | "after": true 30 | } 31 | ], 32 | "space-before-blocks": [ 33 | "error", 34 | { 35 | "functions": "always", 36 | "keywords": "always", 37 | "classes": "always" 38 | } 39 | ], 40 | "space-before-function-paren": [ 41 | "error", 42 | { 43 | "anonymous": "always", 44 | "named": "always", 45 | "asyncArrow": "always" 46 | } 47 | ], 48 | "prefer-const": [ 49 | "error", 50 | { 51 | "destructuring": "any", 52 | "ignoreReadBeforeAssign": false 53 | } 54 | ], 55 | "no-unused-vars": ["off"], 56 | "no-prototype-builtins": ["off"], 57 | "no-async-promise-executor": ["off"] 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ master ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ master ] 20 | schedule: 21 | - cron: '42 23 * * 0' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'javascript' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] 37 | # Learn more: 38 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed 39 | 40 | steps: 41 | - name: Checkout repository 42 | uses: actions/checkout@v2 43 | 44 | # Initializes the CodeQL tools for scanning. 45 | - name: Initialize CodeQL 46 | uses: github/codeql-action/init@v1 47 | with: 48 | languages: ${{ matrix.language }} 49 | # If you wish to specify custom queries, you can do so here or in a config file. 50 | # By default, queries listed here will override any specified in a config file. 51 | # Prefix the list here with "+" to use these queries and those in the config file. 52 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 53 | 54 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 55 | # If this step fails, then you should remove it and run the build manually (see below) 56 | - name: Autobuild 57 | uses: github/codeql-action/autobuild@v1 58 | 59 | # ℹ️ Command-line programs to run using the OS shell. 60 | # 📚 https://git.io/JvXDl 61 | 62 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 63 | # and modify them (or add more) to build your code if your project 64 | # uses a compiled language 65 | 66 | #- run: | 67 | # make bootstrap 68 | # make release 69 | 70 | - name: Perform CodeQL Analysis 71 | uses: github/codeql-action/analyze@v1 72 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: Node CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | strategy: 11 | matrix: 12 | node-version: [8.x, 10.x, 12.x] 13 | 14 | steps: 15 | - uses: actions/checkout@v1 16 | - name: Use Node.js ${{ matrix.node-version }} 17 | uses: actions/setup-node@v1 18 | with: 19 | node-version: ${{ matrix.node-version }} 20 | - name: npm install, build, and test 21 | run: | 22 | npm install 23 | npm test 24 | env: 25 | CI: true 26 | -------------------------------------------------------------------------------- /.github/workflows/npmpublish.yml: -------------------------------------------------------------------------------- 1 | name: Node.js Package 2 | 3 | on: 4 | release: 5 | types: [created] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v1 12 | - uses: actions/setup-node@v1 13 | with: 14 | node-version: 12 15 | - run: npm ci 16 | - run: npm test 17 | 18 | publish-npm: 19 | needs: build 20 | runs-on: ubuntu-latest 21 | steps: 22 | - uses: actions/checkout@v1 23 | - uses: actions/setup-node@v1 24 | with: 25 | node-version: 12 26 | registry-url: https://registry.npmjs.org/ 27 | - run: npm ci 28 | - run: npm publish 29 | env: 30 | NODE_AUTH_TOKEN: ${{secrets.npm_token}} 31 | 32 | publish-gpr: 33 | needs: build 34 | runs-on: ubuntu-latest 35 | steps: 36 | - uses: actions/checkout@v1 37 | - uses: actions/setup-node@v1 38 | with: 39 | node-version: 12 40 | registry-url: https://npm.pkg.github.com/ 41 | scope: '@treboryx' 42 | - run: npm ci 43 | - run: npm publish 44 | env: 45 | NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}} 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .eslintrc.json 3 | keys.json -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Robert & TJ 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![NPM](https://nodei.co/npm/mc-stats.png)](https://nodei.co/npm/mc-stats/) 2 |

3 |
4 | Minecraft server player statistics 5 |
6 |

7 | 8 |

A JavaScript wrapper for fetching player statistics and information from popular Minecraft networks. Created and maintained by the developers of the Crafty Discord bot.

9 | 10 |

11 | Documentation • 12 | Crafty Discord bot • 13 | Support Discord server 14 |

15 | 16 | 17 | ## Supported Minecraft servers 18 | ### Total: 14 19 | 20 | #### Hypixel - https://hypixel.net/ 21 | * Player information and game statistics 22 | * Watchdog information 23 | * Booster information 24 | * API key information 25 | 26 | #### HiveMC - https://hivemc.com/ 27 | * Player information and game statistics 28 | 29 | #### Wynncraft - https://wynncraft.com/ 30 | * Player information and game statistics 31 | * Guild information 32 | 33 | #### BlocksMC - https://blocksmc.com/ 34 | * Player information and game statistics 35 | * Game leaderboards 36 | 37 | #### Funcraft - https://www.funcraft.net/ 38 | * Player information and game statistics 39 | 40 | #### Mineplex - https://www.mineplex.com/home/ 41 | * Player information and game statistics 42 | > Currently not working. 43 | 44 | #### MannaCube - https://manacube.com/ 45 | * Player information and game statistics 46 | 47 | #### MineSaga - https://www.minesaga.org/ 48 | * Player information and game statistics 49 | 50 | #### GommeHD - https://www.gommehd.net/ 51 | * Player information and game statistics 52 | 53 | #### Timolia - https://www.timolia.de/ 54 | * Player information and game statistics 55 | 56 | #### VeltPvP - https://www.veltpvp.com/ 57 | * Player information and game statistics 58 | 59 | #### Universocraft - https://universocraft.com/ 60 | * Player information and game statistics 61 | 62 | #### MunchyMC - https://www.munchymc.com/ 63 | * Player information and game statistics 64 | * Gamemode leaderboards 65 | 66 | #### Minecraft Central - https://mccentral.org/ 67 | * Player information and game statistics 68 | * Gamemode leaderboards 69 | 70 | 71 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | module.exports = require("./lib/util.js"); -------------------------------------------------------------------------------- /lib/util.js: -------------------------------------------------------------------------------- 1 | const fetch = require("node-fetch"); // Main http module 2 | const cheerio = require("cheerio"); 3 | const moment = require("moment"); 4 | const hypixel = require("./hypixel"); 5 | require("moment-duration-format"); 6 | 7 | String.prototype.toProperCase = function () { 8 | return this.replace(/([^\W_]+[^\s-]*) */g, function (txt) { 9 | return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); 10 | }); 11 | }; 12 | 13 | Object.size = (obj) => { 14 | var size = 0, 15 | key; 16 | for (key in obj) { 17 | if (obj.hasOwnProperty(key)) size++; 18 | } 19 | return size; 20 | }; 21 | 22 | const camelCase = (val) => { 23 | if (val.includes(" ")) { 24 | const t = val.split(" "); 25 | const res = []; 26 | res.push(t[0]); 27 | for (let k = 1; t.length > k; k++) { 28 | res.push(t[k].toProperCase()); 29 | } 30 | return res.join(""); 31 | } else { 32 | return val; 33 | } 34 | }; 35 | 36 | const convertSeconds = (seconds) => { 37 | return ( 38 | Math.floor(seconds / 1440) + 39 | "D " + 40 | Math.floor(((seconds / 1440) % 1) * 24) + 41 | "H " + 42 | Math.floor(((seconds / 60) % 1) * 60) + 43 | "M " 44 | ); 45 | }; 46 | 47 | module.exports = { 48 | comugamers: (query, type) => { 49 | if (type === "player") { 50 | return new Promise(async (resolve, reject) => { 51 | const player = await fetch( 52 | `https://api.comugamers.net/player?username=${query}` 53 | ) 54 | .then((r) => r.json()) 55 | .catch((e) => reject(e)); 56 | if (player?.status === "OK") { 57 | resolve(player.data); 58 | } else 59 | reject({ error: player?.err?.message || "Something went wrong" }); 60 | }); 61 | } 62 | }, 63 | blocksmc: (query, type) => { 64 | if (type === "leaderboard") { 65 | return new Promise((resolve, reject) => { 66 | const leaderboards = [ 67 | "sky-wars", 68 | "sky-wars-solo", 69 | "bed-wars", 70 | "bed-wars-solo", 71 | "egg-wars", 72 | "egg-wars-solo", 73 | "top-skypvp-s1", 74 | "survival-games", 75 | "1vs1", 76 | "the-bridge", 77 | "lucky-block-wars", 78 | "sky-giant", 79 | "sky-giant-mini", 80 | "murder-mystery", 81 | "tnt-tag", 82 | "block-party", 83 | "gravity", 84 | "super-jump", 85 | "splegg", 86 | "quake-craft", 87 | "uhc-run", 88 | ]; 89 | if (!leaderboards.includes(query)) 90 | return resolve({ errors: "Invalid game leaderboard." }); 91 | fetch(`https://blocksmc.com/${query}`) 92 | .then((res) => res.text()) 93 | .then((body) => { 94 | const data = []; 95 | const template = []; 96 | const $ = cheerio.load(body); 97 | $("thead") 98 | .find("td") 99 | .each(function () { 100 | const stat = $(this) 101 | .text() 102 | .trim() 103 | .replace(/\s\s|^Av$/g, "") 104 | .toLowerCase() 105 | .replace("#", "rank") 106 | .replace("w/l", "winLossRatio") 107 | .replace("k/d", "killDeathRatio"); 108 | if (stat.length > 0) template.push(stat); 109 | }); 110 | $("tbody") 111 | .find("tr") 112 | .each(function () { 113 | const stat = $(this) 114 | .text() 115 | .trim() 116 | .replace(/\s\s/g, "") 117 | .split(" "); 118 | const obj = {}; 119 | for (let i = 0; i < template.length; i++) { 120 | obj[template[i]] = !isNaN(stat[i]) 121 | ? Number(stat[i]) 122 | : stat[i]; 123 | } 124 | data.push(obj); 125 | }); 126 | return resolve(data); 127 | }) 128 | .catch((e) => { 129 | resolve({ 130 | errors: "Can't fetch stats, Website is probably offline.", 131 | }); 132 | console.log(e); 133 | }); 134 | }); 135 | } 136 | if (type === "player") { 137 | return new Promise((resolve, reject) => { 138 | fetch(`https://blocksmc.com/player/${query}`) 139 | .then((res) => res.text()) 140 | .then((body) => { 141 | const data = { games: {} }; 142 | const $ = cheerio.load(body); 143 | const name = $(".profile-header h1").text().trim(); 144 | const rank = $(".profile-rank").text().replace("\n", "").trim(); 145 | const timePlayed = $("h1[dir=ltr]").text().replace("\n", "").trim(); 146 | let totalKills = 0; 147 | let totalWins = 0; 148 | let totalGames = 0; 149 | let totalPoints = 0; 150 | let totalDeaths = 0; 151 | $("div.col-xl-4").each(function () { 152 | const stats = {}; 153 | $(this) 154 | .find("li") 155 | .each(function () { 156 | if ($(this).find("div.key").text() === "Kills") 157 | totalKills += Number($(this).find("div.val").text()); 158 | if ($(this).find("div.key").text() === "Wins") 159 | totalWins += Number($(this).find("div.val").text()); 160 | if ($(this).find("div.key").text() === "Played") 161 | totalGames += Number($(this).find("div.val").text()); 162 | if ($(this).find("div.key").text() === "Points") 163 | totalPoints += Number($(this).find("div.val").text()); 164 | if ($(this).find("div.key").text() === "Deaths") 165 | totalDeaths += Number($(this).find("div.val").text()); 166 | 167 | Object.assign(stats, { 168 | [$(this).find("div.key").text()]: Number( 169 | $(this).find("div.val").text() 170 | ), 171 | }); 172 | }); 173 | data.games[ 174 | $(this) 175 | .find("div.title") 176 | .text() 177 | .trim() 178 | .replace(/ |:/g, "_") 179 | .replace("1VS1", "Duels") 180 | ] = stats; 181 | }); 182 | Object.assign(data, { 183 | name, 184 | rank, 185 | timePlayed, 186 | totalKills, 187 | totalWins, 188 | totalGames, 189 | totalPoints, 190 | totalDeaths, 191 | }); 192 | 193 | if (!name) return resolve({ errors: "User not found" }); 194 | resolve(data); 195 | }) 196 | .catch((e) => { 197 | resolve({ 198 | errors: "Can't fetch stats, Website is probably offline.", 199 | }); 200 | console.log(e); 201 | }); 202 | }); 203 | } 204 | }, 205 | 206 | hypixelPlayer: async (username, key) => { 207 | // completed 208 | return new Promise((resolve, reject) => { 209 | if (!username) 210 | return resolve({ 211 | errors: "No username provided", 212 | }); 213 | if (!key) 214 | return resolve({ 215 | errors: "No Hypixel API key provided", 216 | }); 217 | hypixel.hypixelPlayer(username, key).then((r) => resolve(r)); 218 | }); 219 | }, 220 | 221 | hypixelFindGuild: async (search, type, key) => { 222 | // completed 223 | return new Promise((resolve, reject) => { 224 | if (!search) 225 | return resolve({ 226 | errors: "No search term provided", 227 | }); 228 | if (!type) 229 | return resolve({ 230 | errors: "No search type provided", 231 | }); 232 | if (!key) 233 | return resolve({ 234 | errors: "No Hypixel API key provided", 235 | }); 236 | hypixel.hypixelFindGuild(search, type, key).then((r) => resolve(r)); 237 | }); 238 | }, 239 | 240 | hypixelGuild: async (id, key) => { 241 | // completed 242 | return new Promise((resolve, reject) => { 243 | if (!id) 244 | return resolve({ 245 | errors: "No guild ID provided", 246 | }); 247 | if (!key) 248 | return resolve({ 249 | errors: "No Hypixel API key provided", 250 | }); 251 | hypixel.hypixelGuild(id, key).then((r) => resolve(r)); 252 | }); 253 | }, 254 | 255 | hypixelWatchdog: async (key) => { 256 | // completed 257 | return new Promise((resolve, reject) => { 258 | fetch(`https://api.hypixel.net/watchdogstats?key=${key}`) 259 | .then((res) => res.json()) 260 | .then(async (json) => { 261 | resolve(json); 262 | }) 263 | .catch((e) => { 264 | resolve({ errors: "Can't fetch stats, API is probably offline." }); 265 | console.log(e); 266 | }); 267 | }); 268 | }, 269 | 270 | hypixelBoosters: async (key) => { 271 | return new Promise((resolve, reject) => { 272 | const getGametype = { 273 | 2: "QUAKECRAFT", 274 | 3: "WALLS", 275 | 4: "PAINTBALL", 276 | 5: "Blitz Survival Games", 277 | 6: "TNT GAMES", 278 | 7: "VAMPIREZ", 279 | 13: "Mega Walls", 280 | 14: "ARCADE", 281 | 17: "ARENA", 282 | 20: "UHC Champions", 283 | 21: "Cops and Crims", 284 | 23: "Warlords", 285 | 24: "Smash Heroes", 286 | 25: "Turbo Kart Racers", 287 | 26: "Housing", 288 | 51: "SkyWars", 289 | 52: "Crazy Walls", 290 | 54: "Speed UHC", 291 | 55: "SkyClash", 292 | 56: "Classic Games", 293 | 57: "Prototype", 294 | 58: "Bed Wars", 295 | 59: "Murder Mystery", 296 | 60: "Build Battle", 297 | 61: "Duels", 298 | }; 299 | fetch(`https://api.hypixel.net/boosters?key=${key}`) 300 | .then((res) => res.json()) 301 | .then(async (json) => { 302 | if (!json.success) 303 | return resolve({ errors: "There are no active boosters" }); 304 | const arr = []; 305 | json.boosters.forEach(async (e) => { 306 | const entry = { 307 | game: getGametype[e.gameType], 308 | multiplier: `x${e.amount}`, 309 | remaining: moment 310 | .duration(e.length, "seconds") 311 | .format(" m [mins], s [secs]"), 312 | originalLength: moment 313 | .duration(e.originalLength, "seconds") 314 | .format(" m [mins], s [secs]"), 315 | activated: e.dateActivated, 316 | }; 317 | arr.push(entry); 318 | }); 319 | resolve(arr); 320 | }); 321 | }); 322 | }, 323 | 324 | hypixelKey: async (key) => { 325 | // completed 326 | return new Promise((resolve, reject) => { 327 | fetch(`https://api.hypixel.net/key?key=${key}`) 328 | .then((res) => res.json()) 329 | .then(async (json) => { 330 | resolve(json); 331 | }) 332 | .catch((e) => { 333 | resolve({ errors: "Can't fetch stats, API is probably offline." }); 334 | console.log(e); 335 | }); 336 | }); 337 | }, 338 | 339 | funcraft: (username) => { 340 | // completed 341 | return new Promise((resolve, reject) => { 342 | if (!username) return resolve({ errors: "No username provided" }); 343 | fetch(`https://www.funcraft.net/fr/joueurs?q=${username}`) 344 | .then((res) => res.text()) 345 | .then((body) => { 346 | const clean = (val) => { 347 | if (val === "classement") { 348 | return "ranking"; 349 | } else if (val === "défaites") { 350 | return "losses"; 351 | } else if (val === "temps de jeu") { 352 | return "playtime"; 353 | } else if (val === "morts") { 354 | return "deaths"; 355 | } else if (val === "lits détruits") { 356 | return "destroyedBeds"; 357 | } else if (val === "top 1") { 358 | return "top1"; 359 | } else if (val === "dégats") { 360 | return "damage"; 361 | } else if (val === "dégats au Nexus") { 362 | return "nexusDamage"; 363 | } else if (val === "victoires") { 364 | return "wins"; 365 | } else if (val.includes("ème")) { 366 | return val.replace("ème", ""); 367 | } else if (val.includes(" ")) { 368 | return val.replace(" ", ""); 369 | } else { 370 | return val; 371 | } 372 | }; 373 | 374 | const toNumber = (n) => { 375 | if (n.match(/[a-z]/i)) { 376 | return n; 377 | } else if (!isNaN(parseInt(n))) { 378 | return parseInt(n).toLocaleString(); 379 | } else if (n.includes(" ")) { 380 | if (!isNaN(parseInt(n))) { 381 | return parseInt(n).toLocaleString(); 382 | } 383 | } else { 384 | return n; 385 | } 386 | }; 387 | 388 | const data = { games: {} }; 389 | const $ = cheerio.load(body); 390 | if ( 391 | $("div[class='container alert-container']") 392 | .text() 393 | .trim() 394 | .includes("× Une ou plusieurs erreurs sont survenues :") 395 | ) 396 | return resolve({ errors: "User does not have any information" }); 397 | 398 | function formatTimeFuncraft(date) { 399 | date = date.split(" "); 400 | var day = date[0]; 401 | var year = date[2].replace(",", ""); 402 | var time = date[3].replace("h", ":"); 403 | time = moment(time, "hh:mm").format("hh:mm a"); 404 | var month = ""; 405 | switch (date[1]) { 406 | case "janvier": 407 | month = "January"; 408 | break; 409 | case "février": 410 | month = "February"; 411 | break; 412 | case "mars": 413 | month = "March"; 414 | break; 415 | case "avril": 416 | month = "April"; 417 | break; 418 | case "mai": 419 | month = "May"; 420 | break; 421 | case "juin": 422 | month = "June"; 423 | break; 424 | case "juillet": 425 | month = "July"; 426 | break; 427 | case "aout": 428 | month = "August"; 429 | break; 430 | case "septembre": 431 | month = "September"; 432 | break; 433 | case "octobre": 434 | month = "October"; 435 | break; 436 | case "novembre": 437 | month = "November"; 438 | break; 439 | case "décembre": 440 | month = "December"; 441 | break; 442 | default: 443 | month = date[1]; 444 | break; 445 | } 446 | return `${day} ${month} ${year}, ${time}`; 447 | } 448 | 449 | const name = $(".playername").text().trim().split(" ")[1]; 450 | const rank = $(".playername").text().trim().split(" ")[0]; 451 | const gamesPlayed = Number( 452 | $("div[class='lbl lbl-me']").text().trim().split(" ")[0] 453 | ); 454 | const registration = formatTimeFuncraft( 455 | $("span[class='tooltips']")[0].attribs.title 456 | ); 457 | const lastLogin = formatTimeFuncraft( 458 | $("span[class='tooltips']")[1].attribs.title 459 | ); 460 | Object.assign(data, { 461 | name, 462 | rank, 463 | gamesPlayed, 464 | registration, 465 | lastLogin, 466 | }); 467 | $("div.col-md-4").each(function () { 468 | const stats = {}; 469 | 470 | $(this) 471 | .find("div.stats-entry") 472 | .each(function () { 473 | Object.assign(stats, { 474 | [clean( 475 | $(this).find("div.stats-name").text().trim().toLowerCase() 476 | )]: Number( 477 | toNumber( 478 | clean($(this).find("div.stats-value-daily").text().trim()) 479 | ) 480 | .replace(/-/g, 0) 481 | .replace(/h|m|,| /g, "") 482 | ), 483 | }); 484 | }); 485 | if (Object.size(stats)) { 486 | data.games[ 487 | $(this) 488 | .find("div.name") 489 | .text() 490 | .trim() 491 | .replace("Infecté", "Infected") 492 | ] = stats; 493 | } 494 | }); 495 | resolve(data); 496 | }) 497 | .catch((e) => { 498 | resolve({ 499 | errors: "Can't fetch stats, Website is probably offline.", 500 | }); 501 | console.log(e); 502 | }); 503 | }); 504 | }, 505 | 506 | mineplex: (username) => { 507 | // incomplete 508 | return new Promise((resolve, reject) => { 509 | if (!username) return resolve({ errors: "No username provided" }); 510 | fetch(`https://www.mineplex.com/players/${username}`) 511 | .then((res) => res.text()) 512 | .then((body) => { 513 | const data = { games: [] }; 514 | const $ = cheerio.load(body); 515 | const name = $(".www-mp-username").text().trim(); 516 | const rank = $('span[class="www-mp-rank"]').text().trim(); 517 | const gamesPlayed = $("div[class='lbl lbl-me']") 518 | .text() 519 | .trim() 520 | .split(" ")[0]; 521 | Object.assign(data, { name, rank }); 522 | $("div.col-md-4").each(function () { 523 | // const stats = {}; 524 | // $(this).find("div.stats-entry").each(function () { 525 | // Object.assign(stats, { [clean($(this).find("div.stats-name").text().trim().toLowerCase())]: toNumber(clean($(this).find("div.stats-value-daily").text().trim()))}); 526 | // }); 527 | // if (Object.size(stats)) { 528 | // data.games.push({ 529 | // game: $(this).find("div.name").text().trim(), 530 | // stats 531 | // }); 532 | // } 533 | }); 534 | resolve(data); 535 | }) 536 | .catch((e) => { 537 | resolve({ errors: "Can't fetch stats, API is probably offline." }); 538 | console.log(e); 539 | }); 540 | }); 541 | }, 542 | 543 | manacube: (username) => { 544 | // completed 545 | return new Promise((resolve, reject) => { 546 | if (!username) return resolve({ errors: "No username provided" }); 547 | fetch(`https://manacube.com/stats_data/fetch.php?username=${username}`) 548 | .then((res) => res.json()) 549 | .then((json) => { 550 | if (json.exists === false) 551 | return resolve({ errors: "User does not have any information" }); 552 | const data = { games: {} }; 553 | Object.assign(data, { 554 | name: username, 555 | level: json.level ? json.level : 0, 556 | rank: json.rank ? json.rank : "none", 557 | firstLogin: json.firstSeen ? json.firstSeen : "Never", 558 | lastLogin: json.lastSeen ? json.lastSeen : "Never", 559 | cubits: json.cubits ? Number(json.cubits) : 0, 560 | }); 561 | 562 | if (json.parkour && json.parkour.playtime !== "n/a") { 563 | data.games.parkour = { 564 | playtime: json.parkour.playtime, 565 | mana: json.parkour.mana !== "n/a" ? Number(json.parkour.mana) : 0, 566 | score: 567 | json.parkour.score !== "n/a" ? Number(json.parkour.score) : 0, 568 | courses: 569 | json.parkour.courses !== "n/a" 570 | ? Number(json.parkour.courses) 571 | : 0, 572 | }; 573 | } 574 | if (json.aztec && json.aztec.playtime !== "n/a") { 575 | data.games.aztec = { 576 | playtime: json.aztec.playtime, 577 | mobKills: 578 | json.aztec.mobKills !== "n/a" ? Number(json.aztec.mobKills) : 0, 579 | mana: json.aztec.mana !== "n/a" ? Number(json.aztec.mana) : 0, 580 | money: json.aztec.money !== "n/a" ? Number(json.aztec.money) : 0, 581 | }; 582 | } 583 | if (json.oasis && json.oasis.playtime !== "n/a") { 584 | data.games.oasis = { 585 | playtime: json.oasis.playtime, 586 | mobKills: 587 | json.oasis.mobKills !== "n/a" ? Number(json.oasis.mobKills) : 0, 588 | mana: json.oasis.mana !== "n/a" ? Number(json.oasis.mana) : 0, 589 | money: json.oasis.money !== "n/a" ? Number(json.oasis.money) : 0, 590 | }; 591 | } 592 | if (json.islands && json.islands.playtime !== "n/a") { 593 | data.games.islands = { 594 | playtime: json.islands.playtime, 595 | mobKills: 596 | json.islands.mobKills !== "n/a" 597 | ? Number(json.islands.mobKills) 598 | : 0, 599 | silver: 600 | json.islands.silver !== "n/a" ? Number(json.islands.silver) : 0, 601 | money: 602 | json.islands.money !== "n/a" ? Number(json.islands.money) : 0, 603 | }; 604 | } 605 | if (json.survival && json.survival.playtime !== "n/a") { 606 | data.games.survival = { 607 | playtime: json.survival.playtime, 608 | mobKills: 609 | json.survival.mobKills !== "n/a" 610 | ? Number(json.survival.mobKills) 611 | : 0, 612 | quests: 613 | json.survival.quests !== "n/a" 614 | ? Number(json.survival.quests) 615 | : 0, 616 | money: 617 | json.survival.money !== "n/a" ? Number(json.survival.money) : 0, 618 | }; 619 | } 620 | if (json.factions && json.factions.playtime !== "n/a") { 621 | data.games.factions = { 622 | playtime: json.factions.playtime, 623 | mobKills: 624 | json.factions.mobkills !== "n/a" 625 | ? Number(json.factions.mobkills) 626 | : 0, 627 | kills: 628 | json.factions.kills !== "n/a" ? Number(json.factions.kills) : 0, 629 | money: 630 | json.factions.money !== "n/a" ? Number(json.factions.money) : 0, 631 | }; 632 | } 633 | if (json.aether && json.aether.playtime !== "n/a") { 634 | data.games.aether = { 635 | playtime: json.aether.playtime, 636 | miningLevel: 637 | json.aether.miningLevel !== "n/a" 638 | ? Number(json.aether.miningLevel) 639 | : 0, 640 | rebirths: 641 | json.aether.rebirths !== "n/a" 642 | ? Number(json.aether.rebirths) 643 | : 0, 644 | money: 645 | json.aether.money !== "n/a" ? Number(json.aether.money) : 0, 646 | }; 647 | } 648 | if (json.atlas && json.atlas.playtime !== "n/a") { 649 | data.games.atlas = { 650 | playtime: json.atlas.playtime, 651 | miningLevel: 652 | json.atlas.miningLevel !== "n/a" 653 | ? Number(json.atlas.miningLevel) 654 | : 0, 655 | rebirths: 656 | json.atlas.rebirths !== "n/a" ? Number(json.atlas.rebirths) : 0, 657 | money: json.atlas.money !== "n/a" ? Number(json.atlas.money) : 0, 658 | }; 659 | } 660 | if (json.creative && json.creative.playtime !== "n/a") { 661 | data.games.creative = { 662 | playtime: json.creative.playtime, 663 | blocksplaced: 664 | json.creative.blocksplaced !== "n/a" 665 | ? Number(json.creative.blocksplaced) 666 | : 0, 667 | blocksbroken: 668 | json.creative.blocksbroken !== "n/a" 669 | ? Number(json.creative.blocksbroken) 670 | : 0, 671 | }; 672 | } 673 | if (json.kitpvp && json.kitpvp.playtime !== "n/a") { 674 | data.games.kitpvp = { 675 | playtime: json.kitpvp.playtime, 676 | level: 677 | json.kitpvp.level !== "n/a" ? Number(json.kitpvp.level) : 0, 678 | money: 679 | json.kitpvp.money !== "n/a" ? Number(json.kitpvp.money) : 0, 680 | kills: 681 | json.kitpvp.kills !== "n/a" ? Number(json.kitpvp.kills) : 0, 682 | }; 683 | } 684 | resolve(data); 685 | }) 686 | .catch((e) => { 687 | resolve({ errors: "Can't fetch stats, API is probably offline." }); 688 | console.log(e); 689 | }); 690 | }); 691 | }, 692 | 693 | minesaga: (username, quick) => { 694 | // completed 695 | return new Promise((resolve, reject) => { 696 | if (!username) return resolve({ errors: "No username provided" }); 697 | fetch(`https://www.minesaga.org/player/${username}`) 698 | .then((res) => res.text()) 699 | .then(async (body) => { 700 | const data = { games: {} }; 701 | 702 | const $ = cheerio.load(body); 703 | if ($.text().trim().includes("User not found")) 704 | return resolve({ errors: "User not found" }); 705 | const name = $(".dd-profile-details h2").text().trim().split(" ")[0]; 706 | const details = $(".dd-profile-details h4").text().split("\n"); 707 | const rank = details[3].trim(); 708 | const playtime = details[2].trim(); 709 | const firstSeen = details[0].trim(); 710 | const lastSeen = details[1].trim(); 711 | const plus = details[4] && details[4].trim() === "Plus"; 712 | const criminalRecord = $( 713 | "div[class='dd-profile-records positive']" 714 | ).text(); 715 | Object.assign(data, { 716 | name, 717 | rank, 718 | playtime, 719 | firstSeen, 720 | lastSeen, 721 | plus, 722 | criminalRecord, 723 | }); 724 | if (quick === true) return resolve(data); 725 | 726 | const games = $(".dd-profile-tab-control").text().trim().split("\n"); 727 | for (let i = 0; i < games.length; i++) { 728 | const game = games[i].replace(/\s\s/g, ""); 729 | if (game.length > 0) { 730 | const d = await fetch( 731 | `https://www.minesaga.org/player/${username}/${game}` 732 | ).then((res) => res.text()); 733 | const $ = cheerio.load(d); 734 | const stats = {}; 735 | $("div.dd-section").each(function () { 736 | $(this) 737 | .find("div.dd-stats") 738 | .each(function () { 739 | $(this) 740 | .find("dt") 741 | .each(function () { 742 | Object.assign(stats, { 743 | [camelCase($(this).text().trim().toLowerCase())]: $( 744 | this 745 | ) 746 | .parent() 747 | .find("dd") 748 | .text() 749 | .trim() 750 | .toLowerCase(), 751 | }); 752 | }); 753 | }); 754 | }); 755 | data.games[game.toLowerCase()] = stats; 756 | } 757 | } 758 | resolve(data); 759 | }) 760 | .catch((e) => { 761 | resolve({ errors: "Can't fetch stats, API is probably offline." }); 762 | console.log(e); 763 | }); 764 | }); 765 | }, 766 | 767 | gommehd: (username) => { 768 | // completed 769 | return new Promise((resolve, reject) => { 770 | if (!username) return resolve({ errors: "No username provided" }); 771 | fetch(`https://www.gommehd.net/player/index?playerName=${username}`) 772 | .then((res) => res.text()) 773 | .then(async (body) => { 774 | var data = { games: [] }; 775 | const $ = cheerio.load(body); 776 | if ($.text().trim().includes("User not found")) 777 | return resolve({ errors: "User not found" }); 778 | const name = $("div.user_info").text().trim().split(" ")[0]; 779 | Object.assign(data, { name }); 780 | $(".stat-table").each(function () { 781 | const stats = {}; 782 | $(this) 783 | .find("div.gametype-stats") 784 | .each(function () { 785 | $(this) 786 | .find("li") 787 | .each(function () { 788 | Object.assign(stats, { 789 | [camelCase( 790 | $(this) 791 | .not(".score") 792 | .text() 793 | .trim() 794 | .toLowerCase() 795 | .split("\n")[2] 796 | )]: $(this) 797 | .not(".score") 798 | .text() 799 | .trim() 800 | .toLowerCase() 801 | .split("\n")[0], 802 | }); 803 | }); 804 | }); 805 | data.games.push({ 806 | game: $(this) 807 | .find("div.map-content-wrap") 808 | .text() 809 | .trim() 810 | .toLowerCase(), 811 | stats, 812 | }); 813 | }); 814 | resolve(data); 815 | }) 816 | .catch((e) => { 817 | resolve({ errors: "Can't fetch stats, API is probably offline." }); 818 | console.log(e); 819 | }); 820 | }); 821 | }, 822 | 823 | timolia: (username) => { 824 | return new Promise((resolve, reject) => { 825 | if (!username) return resolve({ errors: "No username provided" }); 826 | fetch(`https://www.timolia.de/stats/${username}`) 827 | .then((res) => res.text()) 828 | .then(async (body) => { 829 | const clean = (val) => { 830 | switch (val) { 831 | case "Spiele gespielt": 832 | return "games_played"; 833 | case "Spiele gewonnen": 834 | return "games_won"; 835 | case "Knapp gewonnen": 836 | return "barely_won"; 837 | case "eZ gewonnen": 838 | return "easy_win"; 839 | case "K/D": 840 | return "kill_death_ratio"; 841 | case "W/L": 842 | return "win_loss_ratio"; 843 | case "Punkte": 844 | return "points"; 845 | case "Siege insg.": 846 | return "victories"; 847 | case "Tode insgesamt": 848 | return "deaths"; 849 | case "Meiste Kills pro Spiel": 850 | return "most_kills"; 851 | case "Durchschnittsrang": 852 | return "rank"; 853 | case "Rang": 854 | return "rank"; 855 | case "Duelle gespielt": 856 | return "games_played"; 857 | case "Duelle gewonnen": 858 | return "games_won"; 859 | case "Insg. versucht": 860 | return "total_attempts"; 861 | case "Insg. geschafft": 862 | return "total_made"; 863 | case "Abgeschlossen": 864 | return "completed"; 865 | case "Tagesieger beendet": 866 | return "jnrs_completed"; 867 | case "Tagessieger insg.": 868 | return "total_jnrs_completed"; 869 | case "JnRs veröffentlicht": 870 | return "jnrs_published"; 871 | case "Gesammelte Favos": 872 | return "favors_collected"; 873 | case "Getroffene Felder": 874 | return "fields_hit"; 875 | case "Meist getroffene Felder": 876 | return "most_fields_hit"; 877 | case "Flaggen erobert": 878 | return "flags_captured"; 879 | case "Gold eingesammelt": 880 | return "gold_collected"; 881 | case "Gold ausgegeben": 882 | return "gold_spent"; 883 | case "Gold verloren": 884 | return "gold_lost"; 885 | case "TNT verschossen": 886 | return "tnt_missed"; 887 | case "Strukturen aufgebaut": 888 | return "structures_built"; 889 | case "Meiste Zerstörung": 890 | return "most_destruction"; 891 | case "Durchschnittszerstörung": 892 | return "average_destruction"; 893 | case "Schnellster Sieg": 894 | return "fastest_win"; 895 | case "Ausgegebene Zeit": 896 | return "time_spent"; 897 | case "Dimensionsschwellen überwunden": 898 | return "thresholds_overcome"; 899 | case "Blöcke platziert": 900 | return "blocks_placed"; 901 | case "Blöcke zerstört": 902 | return "blocks_broken"; 903 | case "Mittelfackeln abgebaut insgesamt": 904 | return "flares_broken"; 905 | case "Produkte gekauft insgesamt": 906 | return "products_bought"; 907 | case "Chips gekauft insgesamt": 908 | return "chips_bought"; 909 | case "Materialienwerte ausgegeben insgesamt": 910 | return "meterials_spent"; 911 | case "Turnierspiele gespielt": 912 | return "tournaments_played"; 913 | case "Turnierspiele gewonnen": 914 | return "tournaments_won"; 915 | case "1vs1": 916 | return "duels"; 917 | case "TSpiele": 918 | return "tgames"; 919 | case "Bestzeit": 920 | return "best_time"; 921 | case "Durchschnittszeit": 922 | return "average_time"; 923 | case "Die letzten 10 PvP-Kämpfe": 924 | return "recent_battles"; 925 | default: 926 | return val.toLowerCase(); 927 | } 928 | }; 929 | 930 | const data = { 931 | totalWins: 0, 932 | totalKills: 0, 933 | totalDeaths: 0, 934 | totalGamesPlayed: 0, 935 | games: {}, 936 | }; 937 | const $ = cheerio.load(body); 938 | 939 | const name = $("h2#playername").text().trim(); 940 | if (!name) return resolve({ errors: "User not found" }); 941 | const rank = $(".stat-column td .label") 942 | .not(".label-success") 943 | .not(".label-danger") 944 | .text() 945 | .trim() 946 | .replace(/Ranked/g, ""); 947 | 948 | const calcFirstLogin = (input) => { 949 | var d = input.split(" ")[0]; 950 | var t = input.split(" ")[1]; 951 | var arr = d.split("."); 952 | return new Date(`${arr[2]}-${arr[1]}-${arr[0]}T${t}`); 953 | }; 954 | 955 | const firstLogin = calcFirstLogin( 956 | $("table.table tbody tr") 957 | .children("td") 958 | .text() 959 | .split(rank)[1] 960 | .split("\n")[0] 961 | ); 962 | const friends = $("table.table tbody tr") 963 | .children("td") 964 | .text() 965 | .split(rank)[1] 966 | .split("\n")[1] 967 | .trim(); 968 | 969 | const karma = $("table.table tbody tr") 970 | .children("td") 971 | .text() 972 | .split(rank)[1] 973 | .split("\n")[3] 974 | .trim(); 975 | 976 | const recent_battles = []; 977 | Object.assign(data, { name, rank, firstLogin, friends, karma }); 978 | $(".stat-column").each(function () { 979 | const game = 980 | clean($(this).find("th.stat-header").text().trim()) || 981 | clean($(this).find("tr.stat-header").text().trim()); 982 | if (game.length > 0) { 983 | data.games[game] = {}; 984 | $(this) 985 | .find("tbody") 986 | .each(function () { 987 | if (game === "recent_battles") { 988 | data.games[game] = []; 989 | $(this) 990 | .find("tr") 991 | .each(function () { 992 | $(this) 993 | .find("td") 994 | .each(function () { 995 | const text = $(this) 996 | .text() 997 | .trim() 998 | .replace(/vs\./g, ""); 999 | if (text.match(/[0-9]{2}:[0-9]{2}:[0-9]{2}/)) 1000 | recent_battles.push("newLine"); 1001 | if (text.length > 0) recent_battles.push(text); 1002 | }); 1003 | }); 1004 | } 1005 | $(this) 1006 | .find(".stats-table-field") 1007 | .each(function () { 1008 | const objName = clean( 1009 | $(this).find("td").not(".align-right").text() 1010 | ); 1011 | let objValue = $(this) 1012 | .find("td") 1013 | .last() 1014 | .text() 1015 | .replace("Sek.", "Seconds"); 1016 | if (!isNaN(objValue)) objValue = Number(objValue); 1017 | if (objName === "games_played") 1018 | data.totalGamesPlayed += objValue; 1019 | if (objName === "games_won") data.totalWins += objValue; 1020 | if (objName === "kills") data.totalKills += objValue; 1021 | if (objName === "deaths") data.totalDeaths += objValue; 1022 | 1023 | data.games[game][objName] = objValue; 1024 | }); 1025 | }); 1026 | } 1027 | }); 1028 | recent_battles 1029 | .join(" ") 1030 | .split("newLine") 1031 | .forEach((i) => { 1032 | if (i.length > 0) { 1033 | const e = i.split(" "); 1034 | data.games.recent_battles.push({ 1035 | duration: e[1], 1036 | type: e[2], 1037 | map: e[3], 1038 | fighter: e[4], 1039 | opponent: e[5], 1040 | kit: e[6], 1041 | result: e[7] 1042 | .replace(/Verloren/, "loss") 1043 | .replace(/Gewonnen/, "win"), 1044 | }); 1045 | } 1046 | }); 1047 | resolve(data); 1048 | }) 1049 | .catch((e) => { 1050 | resolve({ 1051 | errors: "Can't fetch stats, Website is probably offline.", 1052 | }); 1053 | console.log(e); 1054 | }); 1055 | }); 1056 | }, 1057 | 1058 | veltpvp: (username) => { 1059 | return new Promise(async (resolve, reject) => { 1060 | if (!username) return resolve({ errors: "No username provided" }); 1061 | fetch(`https://www.veltpvp.com/u/${username}`) 1062 | .then((res) => res.text()) 1063 | .then(async (body) => { 1064 | const calcFirstLogin = (input) => { 1065 | var arr = input.split("/"); 1066 | var final = new Date(`${arr[2]}-${arr[1]}-${arr[0]}`); 1067 | return `${moment(final).format("MMM Do YYYY")} (${moment( 1068 | final 1069 | ).fromNow()})`; 1070 | }; 1071 | 1072 | const data = { games: {} }; 1073 | const $ = cheerio.load(body); 1074 | if ($.text().trim().includes("not found")) 1075 | return resolve({ errors: "User not found" }); 1076 | const name = $("h1#name").text().trim(); 1077 | let status = $("div.top").text().trim(); // offline/online/banned 1078 | if (status.includes(" ")) status = status.split(" ")[1].toLowerCase(); 1079 | let seen; 1080 | if (status === "offline") { 1081 | seen = 1082 | $("div.bottom").text().trim().split("\n ")[0] + 1083 | " " + 1084 | $("div.bottom").text().trim().split("\n ")[1].trim(); 1085 | } else if (status === "online") { 1086 | seen = $("div.bottom").text().trim(); 1087 | } 1088 | const rank = $("div#profile h2").text().trim(); 1089 | const firstLogin = calcFirstLogin( 1090 | $("div.content strong").text().trim().substring(0, 10) 1091 | ); 1092 | Object.assign(data, { name, status, rank, firstLogin, seen }); 1093 | $(".server").each(function () { 1094 | const stats = {}; 1095 | $(this) 1096 | .find("div.server-stat") 1097 | .each(function () { 1098 | Object.assign(stats, { 1099 | [camelCase( 1100 | $(this) 1101 | .find(".server-stat-description") 1102 | .text() 1103 | .trim() 1104 | .toLowerCase() 1105 | ).replace(/ /g, "_")]: Number( 1106 | $(this) 1107 | .find(".server-stat-number") 1108 | .text() 1109 | .trim() 1110 | .toLowerCase() 1111 | .replace("n/a", 0) 1112 | ), 1113 | }); 1114 | }); 1115 | if ( 1116 | $(this).find(".server-header").text().trim().toLowerCase() 1117 | .length > 0 1118 | ) 1119 | data.games[ 1120 | $(this).find(".server-header").text().trim().toLowerCase() 1121 | ] = stats; 1122 | }); 1123 | resolve(data); 1124 | }) 1125 | .catch((e) => { 1126 | if (e.statusCode === 404) { 1127 | resolve({ errors: "User not found" }); 1128 | } else { 1129 | console.log(e); 1130 | } 1131 | }); 1132 | }); 1133 | }, 1134 | 1135 | universocraft: (username) => { 1136 | // semi-completed - last login yet to be done 1137 | return new Promise((resolve, reject) => { 1138 | if (!username) return resolve({ errors: "No username provided" }); 1139 | fetch(`https://stats.universocraft.com/stats.php?player=${username}`) 1140 | .then((res) => res.text()) 1141 | .then(async (body) => { 1142 | const data = { games: {} }; 1143 | const $ = cheerio.load(body); 1144 | if ($.text().trim().includes("No se ha encontrado")) 1145 | return resolve({ errors: "User not found" }); 1146 | const clean = (input) => { 1147 | input = input.toUpperCase(); 1148 | if (input === "VICTORIAS") { 1149 | return "wins"; 1150 | } else if (input === "ASESINATOS") { 1151 | return "kills"; 1152 | } else if (input === "MUERTES") { 1153 | return "deaths"; 1154 | } else if (input === "GOLES") { 1155 | return "goals"; 1156 | } else if (input === "PARTIDAS JUGADAS") { 1157 | return "matchesPlayed"; 1158 | } else if (input === "BLOQUES COLOCADOS") { 1159 | return "placedBlocks"; 1160 | } else if (input === "BLOQUES DESTRUIDOS") { 1161 | return "destroyedBlocks"; 1162 | } else if (input === "PROJECTILES LANZADOS") { 1163 | return "launchedProjectiles"; 1164 | } else if (input === "PROJECTILES IMPACTADOS") { 1165 | return "impactedProjectiles"; 1166 | } else if (input === "ASESINATOS FINALES") { 1167 | return "finalKills"; 1168 | } else if (input === "CAMAS DESTRUIDAS") { 1169 | return "destroyedBeds"; 1170 | } else if (input === "MUERTES FINALES") { 1171 | return "finalDeaths"; 1172 | } else if (input === "CONSTRUCCIONES PERFECTAS") { 1173 | return "perfectConstructions"; 1174 | } else if (input === "PERDIDAS") { 1175 | return "losses"; 1176 | } else if (input === "VICTORIAS TOTALES") { 1177 | return "totalWins"; 1178 | } else if (input === "VICTORIAS COMO CORREDOR") { 1179 | return "winsAsBroker"; 1180 | } else if (input === "VICTORIAS COMO BESTIA") { 1181 | return "winsAsBeast"; 1182 | } else if (input === "ASESINATO COMO CORREDOR") { 1183 | return "killsAsBroker"; 1184 | } else if (input === "ASESINATO COMO BESTIA") { 1185 | return "killsAsBeast"; 1186 | } else if (input === "PUNTAJE") { 1187 | return "score"; 1188 | } else if (input === "ASESINATOS CON ARCO") { 1189 | return "bowDeaths"; 1190 | } else if (input === "DISTANCIA MÁXIMA DE MUERTE CON ARCO") { 1191 | return "maximumDistanceOfDeathWithArc"; 1192 | } else if (input === "LANAS COLOCADAS") { 1193 | return "placedWool"; 1194 | } else if (input === "DAÑOS AL NEXUS") { 1195 | return "damageToAlnexus"; 1196 | } else if (input === "DESTRUCCIONES DEL NEXUS") { 1197 | return "nexusDestructions"; 1198 | } else if (input === "MENAS DESTRUIDAS") { 1199 | return "meansDestroyed"; 1200 | } else if (input === "TRONCOS DESTRUIDOS") { 1201 | return "trucksDestroyed"; 1202 | } else if (input === "HUEVOS ROTOS") { 1203 | return "brokenEggs"; 1204 | } else { 1205 | return camelCase(input); 1206 | } 1207 | }; 1208 | 1209 | const name = $("div.player-info h1").text().trim(); 1210 | const rank = $("div.player-rank").text().trim().toProperCase(); 1211 | let lastLogin = $("div.player-description p") 1212 | .not("p strong") 1213 | .text() 1214 | .trim() 1215 | .toProperCase(); 1216 | lastLogin = lastLogin.replace( 1217 | /ÚLtima Conexiónhace |ÚLtima Conexión /g, 1218 | "" 1219 | ); 1220 | if (lastLogin === "Hace unos días...") lastLogin = "A few days ago"; 1221 | else if (lastLogin.includes("Horas.")) 1222 | lastLogin = lastLogin.replace("Horas.", "hours ago"); 1223 | if (lastLogin.includes("Segundos")) 1224 | lastLogin = lastLogin.replace("Segundos", "seconds ago"); 1225 | if (lastLogin.includes("Minutos")) 1226 | lastLogin = lastLogin.replace("Minutos", "minutes ago"); 1227 | if (lastLogin.includes("Unos Días...")) 1228 | lastLogin = lastLogin.replace("Unos Días...", "A few days ago"); 1229 | lastLogin = lastLogin.replace("ago.", "ago"); 1230 | 1231 | Object.assign(data, { name, rank, lastLogin }); 1232 | $("div.game").each(function () { 1233 | const stats = {}; 1234 | 1235 | if ( 1236 | $(this).find(".game-header-title").text().trim().toLowerCase() !== 1237 | "thebridge" 1238 | ) { 1239 | $(this) 1240 | .find("div.game-content") 1241 | .each(function () { 1242 | $(this) 1243 | .find(".game-stat") 1244 | .each(function () { 1245 | Object.assign(stats, { 1246 | [clean( 1247 | $(this) 1248 | .find(".game-stat-title") 1249 | .text() 1250 | .trim() 1251 | .toLowerCase() 1252 | )]: Number( 1253 | $(this) 1254 | .find(".game-stat-count") 1255 | .text() 1256 | .trim() 1257 | .toLowerCase() 1258 | ), 1259 | }); 1260 | }); 1261 | }); 1262 | data.games[ 1263 | camelCase( 1264 | $(this).find(".game-header-title").text().trim().toLowerCase() 1265 | ) 1266 | ] = stats; 1267 | } 1268 | 1269 | if ( 1270 | $(this).find(".game-header-title").text().trim().toLowerCase() === 1271 | "thebridge" 1272 | ) { 1273 | $(this) 1274 | .find("div.game-content") 1275 | .each(function () { 1276 | const gamemode = {}; 1277 | let gameModeName, obj; 1278 | 1279 | $(this) 1280 | .find("div#thebridgetotal") 1281 | .each(function () { 1282 | gameModeName = "total"; 1283 | $(this) 1284 | .find(".game-stat") 1285 | .each(function () { 1286 | Object.assign(gamemode, { 1287 | [clean( 1288 | $(this) 1289 | .find(".game-stat-title") 1290 | .text() 1291 | .trim() 1292 | .toLowerCase() 1293 | )]: Number( 1294 | $(this) 1295 | .find(".game-stat-count") 1296 | .text() 1297 | .trim() 1298 | .toLowerCase() 1299 | ), 1300 | }); 1301 | }); 1302 | obj = { [gameModeName]: gamemode }; 1303 | Object.assign(stats, obj); 1304 | }); 1305 | 1306 | $(this) 1307 | .find("div#thebridgesolo") 1308 | .each(function () { 1309 | gameModeName = "solo"; 1310 | $(this) 1311 | .find(".game-stat") 1312 | .each(function () { 1313 | Object.assign(gamemode, { 1314 | [clean( 1315 | $(this) 1316 | .find(".game-stat-title") 1317 | .text() 1318 | .trim() 1319 | .toLowerCase() 1320 | )]: Number( 1321 | $(this) 1322 | .find(".game-stat-count") 1323 | .text() 1324 | .trim() 1325 | .toLowerCase() 1326 | ), 1327 | }); 1328 | }); 1329 | obj = { [gameModeName]: gamemode }; 1330 | Object.assign(stats, obj); 1331 | }); 1332 | 1333 | $(this) 1334 | .find("div#thebridgedoubles") 1335 | .each(function () { 1336 | gameModeName = "doubles"; 1337 | $(this) 1338 | .find(".game-stat") 1339 | .each(function () { 1340 | Object.assign(gamemode, { 1341 | [clean( 1342 | $(this) 1343 | .find(".game-stat-title") 1344 | .text() 1345 | .trim() 1346 | .toLowerCase() 1347 | )]: Number( 1348 | $(this) 1349 | .find(".game-stat-count") 1350 | .text() 1351 | .trim() 1352 | .toLowerCase() 1353 | ), 1354 | }); 1355 | }); 1356 | obj = { [gameModeName]: gamemode }; 1357 | Object.assign(stats, obj); 1358 | }); 1359 | 1360 | $(this) 1361 | .find("div#thebridgetriples") 1362 | .each(function () { 1363 | gameModeName = "triples"; 1364 | $(this) 1365 | .find(".game-stat") 1366 | .each(function () { 1367 | Object.assign(gamemode, { 1368 | [clean( 1369 | $(this) 1370 | .find(".game-stat-title") 1371 | .text() 1372 | .trim() 1373 | .toLowerCase() 1374 | )]: Number( 1375 | $(this) 1376 | .find(".game-stat-count") 1377 | .text() 1378 | .trim() 1379 | .toLowerCase() 1380 | ), 1381 | }); 1382 | }); 1383 | obj = { [gameModeName]: gamemode }; 1384 | Object.assign(stats, obj); 1385 | }); 1386 | }); 1387 | data.games[ 1388 | camelCase( 1389 | $(this).find(".game-header-title").text().trim().toLowerCase() 1390 | ) 1391 | ] = stats; 1392 | } 1393 | }); 1394 | resolve(data); 1395 | }) 1396 | .catch((e) => { 1397 | resolve({ errors: "Can't fetch stats, API is probably offline." }); 1398 | console.log(e); 1399 | }); 1400 | }); 1401 | }, 1402 | 1403 | hivemc: (username, type) => { 1404 | // Complete 1405 | return new Promise((resolve, reject) => { 1406 | if (!username) 1407 | return resolve({ 1408 | errors: "No username provided", 1409 | }); 1410 | if (!type) 1411 | return resolve({ 1412 | errors: "No query type provided", 1413 | }); 1414 | if (!username) { 1415 | return resolve({ 1416 | errors: "No username provided", 1417 | }); 1418 | } 1419 | if (!type) { 1420 | return resolve({ 1421 | errors: "No query type provided", 1422 | }); 1423 | } 1424 | if (type === "profile") { 1425 | fetch(`http://api.hivemc.com/v1/player/${username}`) 1426 | .then((res) => res.text()) 1427 | .then(async (body) => { 1428 | if ( 1429 | String(body).includes( 1430 | "Sorry, the page you are looking for could not be found" 1431 | ) 1432 | ) { 1433 | return resolve({ 1434 | errors: "No data found for user: " + username, 1435 | }); 1436 | } 1437 | body = JSON.parse(body); 1438 | let achievements; 1439 | const rank = body.modernRank.human || 0; 1440 | const tokens = body.tokens || 0; 1441 | const credits = body.credits || 0; 1442 | const medals = body.medals || 0; 1443 | const status = body.status.description || "None"; 1444 | const currentGame = body.status.game || "None"; 1445 | const firstLogin = 1446 | body.firstLogin > 0 1447 | ? `${moment 1448 | .unix(body.firstLogin) 1449 | .format("MMM Do YYYY")} (${moment 1450 | .unix(body.firstLogin) 1451 | .fromNow()})` 1452 | : "Never"; 1453 | const lastLogin = 1454 | body.lastLogin > 0 1455 | ? `${moment 1456 | .unix(body.lastLogin) 1457 | .format("MMM Do YYYY")} (${moment 1458 | .unix(body.lastLogin) 1459 | .fromNow()})` 1460 | : "Unknown"; 1461 | const lastLogout = 1462 | body.lastLogout > 0 1463 | ? `${moment 1464 | .unix(body.lastLogout) 1465 | .format("MMM Do YYYY")} (${moment 1466 | .unix(body.lastLogout) 1467 | .fromNow()})` 1468 | : "Unknown"; 1469 | if (body.achievements) 1470 | achievements = Object.keys(body.achievements).length; 1471 | else achievements = 0; 1472 | resolve({ 1473 | rank, 1474 | tokens, 1475 | credits, 1476 | medals, 1477 | status, 1478 | currentGame, 1479 | firstLogin, 1480 | lastLogin, 1481 | lastLogout, 1482 | achievements, 1483 | }); 1484 | }); 1485 | } 1486 | if (type === "SG") { 1487 | // Survival games 1 - broken 1488 | return resolve({ 1489 | errors: `No ${type} data found for user: ${username}`, 1490 | }); 1491 | // fetch(`http://api.hivemc.com/v1/player/${username}/SG`) 1492 | // .then(res => res.text()) 1493 | // .then(async body => { 1494 | // body = JSON.parse(body); 1495 | // if (body.code === 404 && body.short === "noprofile") return resolve({ errors: `No ${type} data found for user: ${username}` }); 1496 | // let achievements; 1497 | // const victories = body.victories || 0; 1498 | // const total_points = body.total_points || 0; 1499 | // const most_points = body.most_points || 0; 1500 | // const games_played = body.gamesplayed || 0; 1501 | // const crates_opened = body.cratesopened || 0; 1502 | // const death_matches = body.deathmatches || 0; 1503 | // const kills = body.kills || 0; 1504 | // const deaths = body.deaths || 0; 1505 | // const time_alive = convertSeconds(body.timealive) || "None"; 1506 | // const first_win = body.firstwinday && body.firstwinday > 0 ? { date: moment.unix(body.firstwinday).format("MMM Do YYYY"), fromnow: moment.unix(body.firstwinday).fromNow() } : "Never"; 1507 | // const first_game = body.firstlogin && body.firstlogin > 0 ? { date: moment.unix(body.firstlogin).format("MMM Do YYYY"), fromnow: moment.unix(body.firstlogin).fromNow() } : "Never"; 1508 | // const last_game = body.lastlogin && body.lastlogin > 0 ? { date: moment.unix(body.lastlogin).format("MMM Do YYYY"), fromnow: moment.unix(body.lastlogin).fromNow() } : "Never"; 1509 | // if (body.achievements) achievements = Object.keys(body.achievements).length; 1510 | // else achievements = 0; 1511 | 1512 | // resolve({ victories, total_points, most_points, games_played, crates_opened, death_matches, kills, deaths, time_alive, first_win, first_game, last_game, achievements }); 1513 | // }); 1514 | } 1515 | if (type === "BP") { 1516 | // block party 1517 | fetch(`http://api.hivemc.com/v1/player/${username}/BP`) 1518 | .then((res) => res.text()) 1519 | .then(async (body) => { 1520 | body = JSON.parse(body); 1521 | if (body.code === 404 && body.short === "noprofile") 1522 | return resolve({ 1523 | errors: `No ${type} data found for user: ${username}`, 1524 | }); 1525 | let achievements; 1526 | const games_played = body.games_played || 0; 1527 | const total_kills = body.total_eliminations || 0; 1528 | const total_placing = body.total_placing || 0; 1529 | const total_points = body.total_points || 0; 1530 | const victories = body.victories || 0; 1531 | if (body.achievements) 1532 | achievements = Object.keys(body.achievements).length; 1533 | else achievements = 0; 1534 | const title = body.title || "None"; 1535 | const first_game = 1536 | body.firstLogin && body.firstLogin > 0 1537 | ? { 1538 | date: moment.unix(body.firstLogin).format("MMM Do YYYY"), 1539 | fromnow: moment.unix(body.firstLogin).fromNow(), 1540 | } 1541 | : "Never"; 1542 | 1543 | resolve({ 1544 | games_played, 1545 | total_kills, 1546 | total_placing, 1547 | total_points, 1548 | victories, 1549 | achievements, 1550 | title, 1551 | first_game, 1552 | }); 1553 | }); 1554 | } 1555 | if (type === "CAI") { 1556 | // Cowboys and Indians 1557 | fetch(`http://api.hivemc.com/v1/player/${username}/CAI`) 1558 | .then((res) => res.text()) 1559 | .then(async (body) => { 1560 | body = JSON.parse(body); 1561 | if (body.code === 404 && body.short === "noprofile") 1562 | return resolve({ 1563 | errors: `No ${type} data found for user: ${username}`, 1564 | }); 1565 | let achievements; 1566 | const total_points = body.total_points || 0; 1567 | const captured = body.captured || 0; 1568 | const captures = body.captures || 0; 1569 | const catches = body.catches || 0; 1570 | const caught = body.caught || 0; 1571 | const games_played = body.gamesplayed || 0; 1572 | const victories = body.victories || 0; 1573 | if (body.achievements) 1574 | achievements = Object.keys(body.achievements).length; 1575 | else achievements = 0; 1576 | const title = body.title || "None"; 1577 | const first_game = 1578 | body.firstlogin && body.firstlogin > 0 1579 | ? { 1580 | date: moment.unix(body.firstlogin).format("MMM Do YYYY"), 1581 | fromnow: moment.unix(body.firstlogin).fromNow(), 1582 | } 1583 | : "Never"; 1584 | const last_game = 1585 | body.lastlogin && body.lastlogin > 0 1586 | ? { 1587 | date: moment.unix(body.lastlogin).format("MMM Do YYYY"), 1588 | fromnow: moment.unix(body.lastlogin).fromNow(), 1589 | } 1590 | : "Never"; 1591 | 1592 | resolve({ 1593 | total_points, 1594 | captured, 1595 | captures, 1596 | catches, 1597 | caught, 1598 | games_played, 1599 | victories, 1600 | title, 1601 | first_game, 1602 | last_game, 1603 | achievements, 1604 | }); 1605 | }); 1606 | } 1607 | if (type === "CR") { 1608 | // Cranked 1609 | fetch(`http://api.hivemc.com/v1/player/${username}/CR`) 1610 | .then((res) => res.text()) 1611 | .then(async (body) => { 1612 | body = JSON.parse(body); 1613 | if (body.code === 404 && body.short === "noprofile") 1614 | return resolve({ 1615 | errors: `No ${type} data found for user: ${username}`, 1616 | }); 1617 | let achievements; 1618 | const total_points = body.total_points || 0; 1619 | const victories = body.victories || 0; 1620 | const kills = body.kills || 0; 1621 | const deaths = body.deaths || 0; 1622 | const rccat_count = body.rccat_count || 0; 1623 | const rccat_kills = body.rccat_kills || 0; 1624 | const airstrike_count = body.airstrike_count || 0; 1625 | const airstrike_kills = body.airstrike_kills || 0; 1626 | const sonicsquid_count = body.sonicsquid_count || 0; 1627 | const sonicsquid_kills = body.sonicsquid_kills || 0; 1628 | const first_game = 1629 | body.firstlogin && body.firstlogin > 0 1630 | ? { 1631 | date: moment.unix(body.firstlogin).format("MMM Do YYYY"), 1632 | fromnow: moment.unix(body.firstlogin).fromNow(), 1633 | } 1634 | : "Never"; 1635 | const last_game = 1636 | body.lastlogin && body.lastlogin > 0 1637 | ? { 1638 | date: moment.unix(body.lastlogin).format("MMM Do YYYY"), 1639 | fromnow: moment.unix(body.lastlogin).fromNow(), 1640 | } 1641 | : "Never"; 1642 | const games_played = body.gamesplayed || 0; 1643 | if (body.achievements) 1644 | achievements = Object.keys(body.achievements).length; 1645 | else achievements = 0; 1646 | const title = body.title || "None"; 1647 | 1648 | resolve({ 1649 | total_points, 1650 | victories, 1651 | kills, 1652 | deaths, 1653 | rccat_count, 1654 | rccat_kills, 1655 | airstrike_count, 1656 | airstrike_kills, 1657 | sonicsquid_count, 1658 | sonicsquid_kills, 1659 | last_game, 1660 | first_game, 1661 | games_played, 1662 | achievements, 1663 | title, 1664 | }); 1665 | }); 1666 | } 1667 | if (type === "DR") { 1668 | // Death run 1669 | fetch(`http://api.hivemc.com/v1/player/${username}/DR`) 1670 | .then((res) => res.text()) 1671 | .then(async (body) => { 1672 | body = JSON.parse(body); 1673 | if (body.code === 404 && body.short === "noprofile") 1674 | return resolve({ 1675 | errors: `No ${type} data found for user: ${username}`, 1676 | }); 1677 | let achievements; 1678 | const total_points = body.total_points || 0; 1679 | const victories = body.victories || 0; 1680 | const kills = body.kills || 0; 1681 | const deaths = body.deaths || 0; 1682 | const games_played = body.games_played || 0; 1683 | const title = body.title || "None"; 1684 | const traps_activated = body.trapsactivated || 0; 1685 | const runner_games_played = body.runnergamesplayed || 0; 1686 | const death_games_played = body.deathgamesplayed || 0; 1687 | const total_checkpoints = body.totalcheckpoints || 0; 1688 | const runner_wins = body.runnerwins || 0; 1689 | const death_wins = body.deathwins || 0; 1690 | if (body.achievements) 1691 | achievements = Object.keys(body.achievements).length; 1692 | else achievements = 0; 1693 | const first_game = 1694 | body.firstlogin && body.firstlogin > 0 1695 | ? { 1696 | date: moment.unix(body.firstlogin).format("MMM Do YYYY"), 1697 | fromnow: moment.unix(body.firstlogin).fromNow(), 1698 | } 1699 | : "Never"; 1700 | const last_game = 1701 | body.lastlogin && body.lastlogin > 0 1702 | ? { 1703 | date: moment.unix(body.lastlogin).format("MMM Do YYYY"), 1704 | fromnow: moment.unix(body.lastlogin).fromNow(), 1705 | } 1706 | : "Never"; 1707 | 1708 | resolve({ 1709 | total_points, 1710 | victories, 1711 | kills, 1712 | deaths, 1713 | games_played, 1714 | title, 1715 | traps_activated, 1716 | runner_games_played, 1717 | death_games_played, 1718 | total_checkpoints, 1719 | runner_wins, 1720 | death_wins, 1721 | achievements, 1722 | last_game, 1723 | first_game, 1724 | }); 1725 | }); 1726 | } 1727 | 1728 | if (type === "HB") { 1729 | // The Herobrine 1730 | fetch(`http://api.hivemc.com/v1/player/${username}/HB`) 1731 | .then((res) => res.text()) 1732 | .then(async (body) => { 1733 | body = JSON.parse(body); 1734 | if (body.code === 404 && body.short === "noprofile") 1735 | return resolve({ 1736 | errors: `No ${type} data found for user: ${username}`, 1737 | }); 1738 | let achievements; 1739 | const captures = body.captures || 0; 1740 | const kills = body.kills || 0; 1741 | const deaths = body.deaths || 0; 1742 | const points = body.points || 0; 1743 | const title = body.title || "None"; 1744 | const active_classes = body.active_classes || 0; 1745 | if (body.achievements) 1746 | achievements = Object.keys(body.achievements).length; 1747 | else achievements = 0; 1748 | const first_game = 1749 | body.firstlogin && body.firstlogin > 0 1750 | ? { 1751 | date: moment.unix(body.firstlogin).format("MMM Do YYYY"), 1752 | fromnow: moment.unix(body.firstlogin).fromNow(), 1753 | } 1754 | : "Never"; 1755 | 1756 | resolve({ 1757 | captures, 1758 | kills, 1759 | deaths, 1760 | points, 1761 | active_classes, 1762 | achievements, 1763 | title, 1764 | first_game, 1765 | }); 1766 | }); 1767 | } 1768 | 1769 | if (type === "HERO") { 1770 | // SG:heros 1771 | fetch(`http://api.hivemc.com/v1/player/${username}/HERO`) 1772 | .then((res) => res.text()) 1773 | .then(async (body) => { 1774 | body = JSON.parse(body); 1775 | if (body.code === 404 && body.short === "noprofile") 1776 | return resolve({ 1777 | errors: `No ${type} data found for user: ${username}`, 1778 | }); 1779 | let achievements; 1780 | const total_points = body.total_points || 0; 1781 | const victories = body.victories || 0; 1782 | const kills = body.kills || 0; 1783 | const deaths = body.deaths || 0; 1784 | const one_vs_one_wins = body.one_vs_ones_wins || 0; 1785 | const games_played = body.games_played || 0; 1786 | const death_matches = body.deathmatches || 0; 1787 | const tnt_used = body.tnt_used || 0; 1788 | const crates_opened = body.crates_opened || 0; 1789 | const food_consumed = body.food_consumed || 0; 1790 | const first_game = 1791 | body.firstlogin && body.firstlogin > 0 1792 | ? { 1793 | date: moment.unix(body.firstlogin).format("MMM Do YYYY"), 1794 | fromnow: moment.unix(body.firstlogin).fromNow(), 1795 | } 1796 | : "Never"; 1797 | const last_game = 1798 | body.lastlogin && body.lastlogin > 0 1799 | ? { 1800 | date: moment.unix(body.lastlogin).format("MMM Do YYYY"), 1801 | fromnow: moment.unix(body.lastlogin).fromNow(), 1802 | } 1803 | : "Never"; 1804 | if (body.achievements) 1805 | achievements = Object.keys(body.achievements).length; 1806 | else achievements = 0; 1807 | 1808 | resolve({ 1809 | total_points, 1810 | victories, 1811 | kills, 1812 | deaths, 1813 | one_vs_one_wins, 1814 | games_played, 1815 | death_matches, 1816 | tnt_used, 1817 | crates_opened, 1818 | food_consumed, 1819 | first_game, 1820 | last_game, 1821 | achievements, 1822 | }); 1823 | }); 1824 | } 1825 | 1826 | if (type === "HIDE") { 1827 | // Hide and seek 1828 | fetch(`http://api.hivemc.com/v1/player/${username}/HIDE`) 1829 | .then((res) => res.text()) 1830 | .then(async (body) => { 1831 | body = JSON.parse(body); 1832 | if (body.code === 404 && body.short === "noprofile") 1833 | return resolve({ 1834 | errors: `No ${type} data found for user: ${username}`, 1835 | }); 1836 | let achievements; 1837 | const total_points = body.total_points || 0; 1838 | const victories = body.victories || 0; 1839 | const hider_kills = body.hiderkills || 0; 1840 | const seeker_kills = body.seekerkills || 0; 1841 | const deaths = body.deaths || 0; 1842 | const games_played = body.gamesplayed || 0; 1843 | const time_alive = convertSeconds(body.timealive) || 0; 1844 | var most_used_blocks = Object.keys(body.blockExperience).sort( 1845 | function (a, b) { 1846 | return body.blockExperience[b] - body.blockExperience[a]; 1847 | } 1848 | ); 1849 | most_used_blocks = most_used_blocks.slice(0, 5); 1850 | const first_game = 1851 | body.firstlogin && body.firstlogin > 0 1852 | ? { 1853 | date: moment.unix(body.firstlogin).format("MMM Do YYYY"), 1854 | fromnow: moment.unix(body.firstlogin).fromNow(), 1855 | } 1856 | : "Never"; 1857 | const last_game = 1858 | body.lastlogin && body.lastlogin > 0 1859 | ? { 1860 | date: moment.unix(body.lastlogin).format("MMM Do YYYY"), 1861 | fromnow: moment.unix(body.lastlogin).fromNow(), 1862 | } 1863 | : "Never"; 1864 | if (body.achievements) 1865 | achievements = Object.keys(body.achievements).length; 1866 | else achievements = 0; 1867 | 1868 | resolve({ 1869 | total_points, 1870 | victories, 1871 | hider_kills, 1872 | seeker_kills, 1873 | deaths, 1874 | games_played, 1875 | time_alive, 1876 | most_used_blocks, 1877 | first_game, 1878 | last_game, 1879 | achievements, 1880 | }); 1881 | }); 1882 | } 1883 | 1884 | if (type === "OITC") { 1885 | // One In The Chanber 1886 | fetch(`http://api.hivemc.com/v1/player/${username}/OITC`) 1887 | .then((res) => res.text()) 1888 | .then(async (body) => { 1889 | body = JSON.parse(body); 1890 | if (body.code === 404 && body.short === "noprofile") 1891 | return resolve({ 1892 | errors: `No ${type} data found for user: ${username}`, 1893 | }); 1894 | let achievements; 1895 | const total_points = body.total_points || 0; 1896 | const victories = body.victories || 0; 1897 | const kills = body.kills || 0; 1898 | const deaths = body.deaths || 0; 1899 | const arrows_fired = body.arrowsfired || 0; 1900 | const games_played = body.gamesplayed || 0; 1901 | const title = body.title || "None"; 1902 | const first_game = 1903 | body.firstlogin && body.firstlogin > 0 1904 | ? { 1905 | date: moment.unix(body.firstlogin).format("MMM Do YYYY"), 1906 | fromnow: moment.unix(body.firstlogin).fromNow(), 1907 | } 1908 | : "Never"; 1909 | const last_game = 1910 | body.lastlogin && body.lastlogin > 0 1911 | ? { 1912 | date: moment.unix(body.lastlogin).format("MMM Do YYYY"), 1913 | fromnow: moment.unix(body.lastlogin).fromNow(), 1914 | } 1915 | : "Never"; 1916 | if (body.achievements) 1917 | achievements = Object.keys(body.achievements).length; 1918 | else achievements = 0; 1919 | 1920 | resolve({ 1921 | total_points, 1922 | victories, 1923 | kills, 1924 | deaths, 1925 | arrows_fired, 1926 | games_played, 1927 | title, 1928 | first_game, 1929 | last_game, 1930 | achievements, 1931 | }); 1932 | }); 1933 | } 1934 | 1935 | if (type === "SP") { 1936 | // Splegg 1937 | fetch(`http://api.hivemc.com/v1/player/${username}/SP`) 1938 | .then((res) => res.text()) 1939 | .then(async (body) => { 1940 | body = JSON.parse(body); 1941 | if (body.code === 404 && body.short === "noprofile") 1942 | return resolve({ 1943 | errors: `No ${type} data found for user: ${username}`, 1944 | }); 1945 | let achievements; 1946 | const victories = body.victories || 0; 1947 | const games_played = body.gamesplayed || 0; 1948 | const eggs_fired = body.eggsfired || 0; 1949 | const blocks_destroyed = body.blocksdestroyed || 0; 1950 | const deaths = body.deaths || 0; 1951 | const points = body.points || 0; 1952 | const time_alive = convertSeconds(body.timealive) || 0; 1953 | const title = body.title || "None"; 1954 | const first_game = 1955 | body.firstlogin && body.firstlogin > 0 1956 | ? { 1957 | date: moment.unix(body.firstlogin).format("MMM Do YYYY"), 1958 | fromnow: moment.unix(body.firstlogin).fromNow(), 1959 | } 1960 | : "Never"; 1961 | const last_game = 1962 | body.lastlogin && body.lastlogin > 0 1963 | ? { 1964 | date: moment.unix(body.lastlogin).format("MMM Do YYYY"), 1965 | fromnow: moment.unix(body.lastlogin).fromNow(), 1966 | } 1967 | : "Never"; 1968 | if (body.achievements) 1969 | achievements = Object.keys(body.achievements).length; 1970 | else achievements = 0; 1971 | 1972 | resolve({ 1973 | victories, 1974 | games_played, 1975 | eggs_fired, 1976 | blocks_destroyed, 1977 | deaths, 1978 | points, 1979 | time_alive, 1980 | title, 1981 | first_game, 1982 | last_game, 1983 | achievements, 1984 | }); 1985 | }); 1986 | } 1987 | 1988 | if (type === "TIMV") { 1989 | // Trouble in Mineville 1990 | fetch(`http://api.hivemc.com/v1/player/${username}/TIMV`) 1991 | .then((res) => res.text()) 1992 | .then(async (body) => { 1993 | body = JSON.parse(body); 1994 | if (body.code === 404 && body.short === "noprofile") 1995 | return resolve({ 1996 | errors: `No ${type} data found for user: ${username}`, 1997 | }); 1998 | let achievements; 1999 | const total_points = body.total_points || 0; 2000 | const most_points = body.most_points || 0; 2001 | const role_points = body.role_points || 0; 2002 | const traitor_points = body.t_points || 0; 2003 | const detective_points = body.d_points || 0; 2004 | const innocent_points = body.i_points || 0; 2005 | const title = body.title || "None"; 2006 | const last_game = 2007 | body.lastlogin && body.lastlogin > 0 2008 | ? { 2009 | date: moment.unix(body.lastlogin).format("MMM Do YYYY"), 2010 | fromnow: moment.unix(body.lastlogin).fromNow(), 2011 | } 2012 | : "Never"; 2013 | if (body.achievements) 2014 | achievements = Object.keys(body.achievements).length; 2015 | else achievements = 0; 2016 | 2017 | resolve({ 2018 | total_points, 2019 | most_points, 2020 | role_points, 2021 | traitor_points, 2022 | detective_points, 2023 | innocent_points, 2024 | title, 2025 | last_game, 2026 | achievements, 2027 | }); 2028 | }); 2029 | } 2030 | 2031 | if (type === "SKY") { 2032 | // Skywars - broken 2033 | return resolve({ 2034 | errors: `No ${type} data found for user: ${username}`, 2035 | }); 2036 | // fetch(`http://api.hivemc.com/v1/player/${username}/SKY`) 2037 | // .then(res => res.text()) 2038 | // .then(async body => { 2039 | // body = JSON.parse(body); 2040 | // if (body.code === 404 && body.short === "noprofile") return resolve({ errors: `No ${type} data found for user: ${username}` }); 2041 | // let achievements; 2042 | // const total_points = body.total_points || 0; 2043 | // const victories = body.victories || 0; 2044 | // const games_played = body.gamesplayed || 0; 2045 | // const kills = body.kills || 0; 2046 | // const deaths = body.deaths || 0; 2047 | // const most_points = body.most_points || 0; 2048 | // const time_alive = convertSeconds(body.timealive) || 0; 2049 | // const title = body.title || "None"; 2050 | // const first_game = body.firstLogin && body.firstLogin > 0 ? { date: moment.unix(body.firstLogin).format("MMM Do YYYY"), fromnow: moment.unix(body.firstLogin).fromNow() } : "Never"; 2051 | // const last_game = body.lastlogin && body.lastlogin > 0 ? { date: moment.unix(body.lastlogin).format("MMM Do YYYY"), fromnow: moment.unix(body.lastlogin).fromNow() } : "Never"; 2052 | // if (body.achievements) achievements = Object.keys(body.achievements).length; 2053 | // else achievements = 0; 2054 | 2055 | // resolve({ total_points, victories, games_played, kills, deaths, most_points, time_alive, title, first_game, last_game, achievements }); 2056 | // }); 2057 | } 2058 | 2059 | if (type === "DRAW") { 2060 | // Draw it 2061 | fetch(`http://api.hivemc.com/v1/player/${username}/DRAW`) 2062 | .then((res) => res.text()) 2063 | .then(async (body) => { 2064 | body = JSON.parse(body); 2065 | if (body.code === 404 && body.short === "noprofile") 2066 | return resolve({ 2067 | errors: `No ${type} data found for user: ${username}`, 2068 | }); 2069 | let achievements; 2070 | const total_points = body.total_points || 0; 2071 | const victories = body.victories || 0; 2072 | const games_played = body.gamesplayed || 0; 2073 | const correct_guesses = body.correct_guesses || 0; 2074 | const incorrect_guesses = body.incorrect_guesses || 0; 2075 | const skips = body.skips || 0; 2076 | const title = body.title || "None"; 2077 | const first_game = 2078 | body.firstLogin && body.firstLogin > 0 2079 | ? { 2080 | date: moment.unix(body.firstLogin).format("MMM Do YYYY"), 2081 | fromnow: moment.unix(body.firstLogin).fromNow(), 2082 | } 2083 | : "Never"; 2084 | if (body.achievements) 2085 | achievements = Object.keys(body.achievements).length; 2086 | else achievements = 0; 2087 | 2088 | resolve({ 2089 | total_points, 2090 | victories, 2091 | games_played, 2092 | correct_guesses, 2093 | incorrect_guesses, 2094 | skips, 2095 | title, 2096 | first_game, 2097 | achievements, 2098 | }); 2099 | }); 2100 | } 2101 | 2102 | if (type === "SLAP") { 2103 | // Slaparoo 2104 | fetch(`http://api.hivemc.com/v1/player/${username}/SLAP`) 2105 | .then((res) => res.text()) 2106 | .then(async (body) => { 2107 | body = JSON.parse(body); 2108 | if (body.code === 404 && body.short === "noprofile") 2109 | return resolve({ 2110 | errors: `No ${type} data found for user: ${username}`, 2111 | }); 2112 | const victories = body.victories || 0; 2113 | const games_played = body.gamesplayed || 0; 2114 | const kills = body.kills || 0; 2115 | const deaths = body.deaths || 0; 2116 | const points = body.points || 0; 2117 | const title = body.title || "None"; 2118 | const first_game = 2119 | body.firstlogin && body.firstlogin > 0 2120 | ? { 2121 | date: moment.unix(body.firstlogin).format("MMM Do YYYY"), 2122 | fromnow: moment.unix(body.firstlogin).fromNow(), 2123 | } 2124 | : "Never"; 2125 | const last_game = 2126 | body.lastlogin && body.lastlogin > 0 2127 | ? { 2128 | date: moment.unix(body.lastlogin).format("MMM Do YYYY"), 2129 | fromnow: moment.unix(body.lastlogin).fromNow(), 2130 | } 2131 | : "Never"; 2132 | 2133 | resolve({ 2134 | victories, 2135 | games_played, 2136 | kills, 2137 | deaths, 2138 | points, 2139 | title, 2140 | first_game, 2141 | last_game, 2142 | }); 2143 | }); 2144 | } 2145 | 2146 | if (type === "EF") { 2147 | // Electric Floor 2148 | fetch(`http://api.hivemc.com/v1/player/${username}/EF`) 2149 | .then((res) => res.text()) 2150 | .then(async (body) => { 2151 | body = JSON.parse(body); 2152 | if (body.code === 404 && body.short === "noprofile") 2153 | return resolve({ 2154 | errors: `No ${type} data found for user: ${username}`, 2155 | }); 2156 | const victories = body.victories || 0; 2157 | const outlived = body.outlived || 0; 2158 | const games_played = body.gamesplayed || 0; 2159 | const points = body.points || 0; 2160 | const blocks_activated = body.blocksactivated || 0; 2161 | const title = body.title || "None"; 2162 | const first_game = 2163 | body.firstlogin && body.firstlogin > 0 2164 | ? { 2165 | date: moment.unix(body.firstlogin).format("MMM Do YYYY"), 2166 | fromnow: moment.unix(body.firstlogin).fromNow(), 2167 | } 2168 | : "Never"; 2169 | const last_game = 2170 | body.lastlogin && body.lastlogin > 0 2171 | ? { 2172 | date: moment.unix(body.lastlogin).format("MMM Do YYYY"), 2173 | fromnow: moment.unix(body.lastlogin).fromNow(), 2174 | } 2175 | : "Never"; 2176 | 2177 | resolve({ 2178 | victories, 2179 | outlived, 2180 | games_played, 2181 | points, 2182 | blocks_activated, 2183 | title, 2184 | first_game, 2185 | last_game, 2186 | }); 2187 | }); 2188 | } 2189 | if (type === "MM") { 2190 | // Music Masters 2191 | fetch(`http://api.hivemc.com/v1/player/${username}/MM`) 2192 | .then((res) => res.text()) 2193 | .then(async (body) => { 2194 | body = JSON.parse(body); 2195 | if (body.code === 404 && body.short === "noprofile") 2196 | return resolve({ 2197 | errors: `No ${type} data found for user: ${username}`, 2198 | }); 2199 | const victories = body.victories || 0; 2200 | const correct_notes = body.correctnotes || 0; 2201 | const incorrect_notes = body.incorrectnotes || 0; 2202 | const games_played = body.gamesplayed || 0; 2203 | const points = body.points || 0; 2204 | const notes_perfect = body.notes_perfect || 0; 2205 | const notes_good = body.notes_good || 0; 2206 | const title = body.title || "None"; 2207 | const first_game = 2208 | body.firstlogin && body.firstlogin > 0 2209 | ? { 2210 | date: moment.unix(body.firstlogin).format("MMM Do YYYY"), 2211 | fromnow: moment.unix(body.firstlogin).fromNow(), 2212 | } 2213 | : "Never"; 2214 | const last_game = 2215 | body.lastlogin && body.lastlogin > 0 2216 | ? { 2217 | date: moment.unix(body.lastlogin).format("MMM Do YYYY"), 2218 | fromnow: moment.unix(body.lastlogin).fromNow(), 2219 | } 2220 | : "Never"; 2221 | 2222 | resolve({ 2223 | victories, 2224 | correct_notes, 2225 | incorrect_notes, 2226 | games_played, 2227 | points, 2228 | notes_perfect, 2229 | notes_good, 2230 | title, 2231 | first_game, 2232 | last_game, 2233 | }); 2234 | }); 2235 | } 2236 | 2237 | if (type === "GRAV") { 2238 | // Gravity 2239 | fetch(`http://api.hivemc.com/v1/player/${username}/GRAV`) 2240 | .then((res) => res.text()) 2241 | .then(async (body) => { 2242 | body = JSON.parse(body); 2243 | if (body.code === 404 && body.short === "noprofile") 2244 | return resolve({ 2245 | errors: `No ${type} data found for user: ${username}`, 2246 | }); 2247 | const victories = body.victories || 0; 2248 | const games_played = body.gamesplayed || 0; 2249 | const points = body.points || 0; 2250 | var top_maps = Object.keys(body.maprecords).sort(function (a, b) { 2251 | return body.maprecords[b] - body.maprecords[a]; 2252 | }); 2253 | top_maps = top_maps.slice(0, 5); 2254 | const title = body.title || "None"; 2255 | const first_game = 2256 | body.firstlogin && body.firstlogin > 0 2257 | ? { 2258 | date: moment.unix(body.firstlogin).format("MMM Do YYYY"), 2259 | fromnow: moment.unix(body.firstlogin).fromNow(), 2260 | } 2261 | : "Never"; 2262 | const last_game = 2263 | body.lastlogin && body.lastlogin > 0 2264 | ? { 2265 | date: moment.unix(body.lastlogin).format("MMM Do YYYY"), 2266 | fromnow: moment.unix(body.lastlogin).fromNow(), 2267 | } 2268 | : "Never"; 2269 | 2270 | resolve({ 2271 | victories, 2272 | games_played, 2273 | points, 2274 | top_maps, 2275 | title, 2276 | first_game, 2277 | last_game, 2278 | }); 2279 | }); 2280 | } 2281 | 2282 | if (type === "RR") { 2283 | // Restaurant Rush 2284 | fetch(`http://api.hivemc.com/v1/player/${username}/RR`) 2285 | .then((res) => res.text()) 2286 | .then(async (body) => { 2287 | body = JSON.parse(body); 2288 | if (body.code === 404 && body.short === "noprofile") 2289 | return resolve({ 2290 | errors: `No ${type} data found for user: ${username}`, 2291 | }); 2292 | let achievements; 2293 | const victories = body.victories || 0; 2294 | const tables_cleared = body.tablescleared || 0; 2295 | const games_played = body.gamesplayed || 0; 2296 | const highscore = body.highscore || 0; 2297 | const points = body.points || 0; 2298 | const first_game = 2299 | body.firstlogin && body.firstlogin > 0 2300 | ? { 2301 | date: moment.unix(body.firstlogin).format("MMM Do YYYY"), 2302 | fromnow: moment.unix(body.firstlogin).fromNow(), 2303 | } 2304 | : "Never"; 2305 | const last_game = 2306 | body.lastlogin && body.lastlogin > 0 2307 | ? { 2308 | date: moment.unix(body.lastlogin).format("MMM Do YYYY"), 2309 | fromnow: moment.unix(body.lastlogin).fromNow(), 2310 | } 2311 | : "Never"; 2312 | if (body.achievements) 2313 | achievements = Object.keys(body.achievements).length; 2314 | else achievements = 0; 2315 | 2316 | resolve({ 2317 | victories, 2318 | tables_cleared, 2319 | highscore, 2320 | games_played, 2321 | points, 2322 | first_game, 2323 | last_game, 2324 | achievements, 2325 | }); 2326 | }); 2327 | } 2328 | if (type === "GNT") { 2329 | // SkyGiants 2330 | fetch(`http://api.hivemc.com/v1/player/${username}/GNT`) 2331 | .then((res) => res.text()) 2332 | .then(async (body) => { 2333 | body = JSON.parse(body); 2334 | if (body.code === 404 && body.short === "noprofile") 2335 | return resolve({ 2336 | errors: `No ${type} data found for user: ${username}`, 2337 | }); 2338 | const total_points = body.total_points || 0; 2339 | const victories = body.victories || 0; 2340 | const games_played = body.games_played || 0; 2341 | const kills = body.kills || 0; 2342 | const deaths = body.deaths || 0; 2343 | const gold_earned = body.gold_earned || 0; 2344 | const beasts_slain = body.beasts_slain || 0; 2345 | const shutdowns = body.shutdowns || 0; 2346 | const title = body.title || "None"; 2347 | const first_game = 2348 | body.firstLogin && body.firstLogin > 0 2349 | ? { 2350 | date: moment.unix(body.firstLogin).format("MMM Do YYYY"), 2351 | fromnow: moment.unix(body.firstLogin).fromNow(), 2352 | } 2353 | : "Never"; 2354 | const last_game = 2355 | body.lastlogin && body.lastlogin > 0 2356 | ? { 2357 | date: moment.unix(body.lastlogin).format("MMM Do YYYY"), 2358 | fromnow: moment.unix(body.lastlogin).fromNow(), 2359 | } 2360 | : "Never"; 2361 | 2362 | resolve({ 2363 | total_points, 2364 | victories, 2365 | games_played, 2366 | kills, 2367 | deaths, 2368 | gold_earned, 2369 | beasts_slain, 2370 | shutdowns, 2371 | title, 2372 | first_game, 2373 | last_game, 2374 | }); 2375 | }); 2376 | } 2377 | 2378 | if (type === "SGN") { 2379 | // Survival Games 2 - broken 2380 | return resolve({ 2381 | errors: `No ${type} data found for user: ${username}`, 2382 | }); 2383 | // fetch(`http://api.hivemc.com/v1/player/${username}/SGN`) 2384 | // .then(res => res.text()) 2385 | // .then(async body => { 2386 | // body = JSON.parse(body); 2387 | // if (body.code === 404 && body.short === "noprofile") return resolve({ errors: `No ${type} data found for user: ${username}` }); 2388 | // const victories = body.victories || 0; 2389 | // const total_points = body.total_points || 0; 2390 | // const most_points = body.most_points || 0; 2391 | // const games_played = body.games_played || 0; 2392 | // const crates_opened = body.crates_opened || 0; 2393 | // const death_matches = body.deathmatches || 0; 2394 | // const kills = body.kills || 0; 2395 | // const deaths = body.deaths || 0; 2396 | // const first_game = body.firstLogin && body.firstLogin > 0 ? { date: moment.unix(body.firstLogin).format("MMM Do YYYY"), fromnow: moment.unix(body.firstLogin).fromNow() } : "Never"; 2397 | // const last_game = body.lastlogin && body.lastlogin > 0 ? { date: moment.unix(body.lastlogin).format("MMM Do YYYY"), fromnow: moment.unix(body.lastlogin).fromNow() } : "Never"; 2398 | 2399 | // resolve({ victories, total_points, most_points, games_played, crates_opened, death_matches, kills, deaths, first_game, last_game }); 2400 | // }); 2401 | } 2402 | 2403 | if (type === "BD") { 2404 | // BatteryDash 2405 | fetch(`http://api.hivemc.com/v1/player/${username}/BD`) 2406 | .then((res) => res.text()) 2407 | .then(async (body) => { 2408 | body = JSON.parse(body); 2409 | if (body.code === 404 && body.short === "noprofile") 2410 | return resolve({ 2411 | errors: `No ${type} data found for user: ${username}`, 2412 | }); 2413 | const total_points = body.total_points || 0; 2414 | const games_played = body.games_played || 0; 2415 | const kills = body.kills || 0; 2416 | const deaths = body.deaths || 0; 2417 | const energy_collected = body.energy_collected || 0; 2418 | const batteries_charged = body.batteries_charged || 0; 2419 | const title = body.title || "None"; 2420 | const first_game = 2421 | body.firstLogin && body.firstLogin > 0 2422 | ? { 2423 | date: moment.unix(body.firstLogin).format("MMM Do YYYY"), 2424 | fromnow: moment.unix(body.firstLogin).fromNow(), 2425 | } 2426 | : "Never"; 2427 | const last_game = 2428 | body.lastlogin && body.lastlogin > 0 2429 | ? { 2430 | date: moment.unix(body.lastlogin).format("MMM Do YYYY"), 2431 | fromnow: moment.unix(body.lastlogin).fromNow(), 2432 | } 2433 | : "Never"; 2434 | 2435 | resolve({ 2436 | total_points, 2437 | games_played, 2438 | kills, 2439 | deaths, 2440 | energy_collected, 2441 | batteries_charged, 2442 | title, 2443 | first_game, 2444 | last_game, 2445 | }); 2446 | }); 2447 | } 2448 | 2449 | if (type === "SPL") { 2450 | // Sploop 2451 | fetch(`http://api.hivemc.com/v1/player/${username}/SPL`) 2452 | .then((res) => res.text()) 2453 | .then(async (body) => { 2454 | body = JSON.parse(body); 2455 | if (body.code === 404 && body.short === "noprofile") 2456 | return resolve({ 2457 | errors: `No ${type} data found for user: ${username}`, 2458 | }); 2459 | let achievements; 2460 | const total_points = body.total_points || 0; 2461 | const victories = body.victories || 0; 2462 | const games_played = body.games_played || 0; 2463 | const kills = body.kills || 0; 2464 | const deaths = body.deaths || 0; 2465 | const blocks_painted = body.blocks_painted || 0; 2466 | const ultimates_earned = body.ultimates_earned; 2467 | var booster_blocks_painted; 2468 | var booster_kills; 2469 | var booster_deaths; 2470 | var booster_ulimate_kills; 2471 | var booster_games_played; 2472 | var raven_blocks_painted; 2473 | var raven_kills; 2474 | var raven_deaths; 2475 | var raven_ulimate_kills; 2476 | var raven_games_played; 2477 | var torstein_blocks_painted; 2478 | var torstein_kills; 2479 | var torstein_deaths; 2480 | var torstein_ulimate_kills; 2481 | var torstein_games_played; 2482 | var oinky_blocks_painted; 2483 | var oinky_kills; 2484 | var oinky_deaths; 2485 | var oinky_ulimate_kills; 2486 | var oinky_games_played; 2487 | 2488 | if (body.character_stats) { 2489 | if (body.character_stats.BoosterCharacter) { 2490 | booster_blocks_painted = 2491 | body.character_stats.BoosterCharacter.blocks_painted || 0; 2492 | booster_kills = 2493 | body.character_stats.BoosterCharacter.kills || 0; 2494 | booster_deaths = 2495 | body.character_stats.BoosterCharacter.deaths || 0; 2496 | booster_ulimate_kills = 2497 | body.character_stats.BoosterCharacter.ultimate_kills || 0; 2498 | booster_games_played = 2499 | body.character_stats.BoosterCharacter.games_played || 0; 2500 | } 2501 | if (body.character_stats.RavenCharacter) { 2502 | raven_blocks_painted = 2503 | body.character_stats.RavenCharacter.blocks_painted || 0; 2504 | raven_kills = body.character_stats.RavenCharacter.kills || 0; 2505 | raven_deaths = body.character_stats.RavenCharacter.deaths || 0; 2506 | raven_ulimate_kills = 2507 | body.character_stats.RavenCharacter.ultimate_kills || 0; 2508 | raven_games_played = 2509 | body.character_stats.RavenCharacter.games_played || 0; 2510 | } 2511 | if (body.character_stats.TorsteinCharacter) { 2512 | torstein_blocks_painted = 2513 | body.character_stats.TorsteinCharacter.blocks_painted || 0; 2514 | torstein_kills = 2515 | body.character_stats.TorsteinCharacter.kills || 0; 2516 | torstein_deaths = 2517 | body.character_stats.TorsteinCharacter.deaths || 0; 2518 | torstein_ulimate_kills = 2519 | body.character_stats.TorsteinCharacter.ultimate_kills || 0; 2520 | torstein_games_played = 2521 | body.character_stats.TorsteinCharacter.games_played || 0; 2522 | } 2523 | if (body.character_stats.OinkyCharacter) { 2524 | oinky_blocks_painted = 2525 | body.character_stats.OinkyCharacter.blocks_painted || 0; 2526 | oinky_kills = body.character_stats.OinkyCharacter.kills || 0; 2527 | oinky_deaths = body.character_stats.OinkyCharacter.deaths || 0; 2528 | oinky_ulimate_kills = 2529 | body.character_stats.OinkyCharacter.ultimate_kills || 0; 2530 | oinky_games_played = 2531 | body.character_stats.OinkyCharacter.games_played || 0; 2532 | } 2533 | } 2534 | const title = body.title || "None"; 2535 | const first_game = 2536 | body.firstLogin && body.firstLogin > 0 2537 | ? { 2538 | date: moment.unix(body.firstLogin).format("MMM Do YYYY"), 2539 | fromnow: moment.unix(body.firstLogin).fromNow(), 2540 | } 2541 | : "Never"; 2542 | const last_game = 2543 | body.lastlogin && body.lastlogin > 0 2544 | ? { 2545 | date: moment.unix(body.lastlogin).format("MMM Do YYYY"), 2546 | fromnow: moment.unix(body.lastlogin).fromNow(), 2547 | } 2548 | : "Never"; 2549 | if (body.achievements) 2550 | achievements = Object.keys(body.achievements).length; 2551 | else achievements = 0; 2552 | 2553 | resolve({ 2554 | total_points, 2555 | victories, 2556 | games_played, 2557 | kills, 2558 | deaths, 2559 | blocks_painted, 2560 | ultimates_earned, 2561 | booster_blocks_painted, 2562 | booster_kills, 2563 | booster_deaths, 2564 | booster_ulimate_kills, 2565 | booster_games_played, 2566 | raven_blocks_painted, 2567 | raven_kills, 2568 | raven_deaths, 2569 | raven_ulimate_kills, 2570 | raven_games_played, 2571 | torstein_blocks_painted, 2572 | torstein_kills, 2573 | torstein_deaths, 2574 | torstein_ulimate_kills, 2575 | torstein_games_played, 2576 | oinky_blocks_painted, 2577 | oinky_kills, 2578 | oinky_deaths, 2579 | oinky_ulimate_kills, 2580 | oinky_games_played, 2581 | title, 2582 | first_game, 2583 | last_game, 2584 | achievements, 2585 | }); 2586 | }); 2587 | } 2588 | 2589 | if (type === "MIMV") { 2590 | // Murder In MineVille 2591 | fetch(`http://api.hivemc.com/v1/player/${username}/MIMV`) 2592 | .then((res) => res.text()) 2593 | .then(async (body) => { 2594 | body = JSON.parse(body); 2595 | if (body.code === 404 && body.short === "noprofile") 2596 | return resolve({ 2597 | errors: `No ${type} data found for user: ${username}`, 2598 | }); 2599 | let achievements; 2600 | const total_points = body.total_points || 0; 2601 | const games_played = body.games_played || 0; 2602 | const victories = body.victories || 0; 2603 | const kills = body.kills || 0; 2604 | const deaths = body.deaths || 0; 2605 | const title = body.title || "None"; 2606 | const first_game = 2607 | body.firstLogin && body.firstLogin > 0 2608 | ? { 2609 | date: moment.unix(body.firstLogin).format("MMM Do YYYY"), 2610 | fromnow: moment.unix(body.firstLogin).fromNow(), 2611 | } 2612 | : "Never"; 2613 | const last_game = 2614 | body.lastlogin && body.lastlogin > 0 2615 | ? { 2616 | date: moment.unix(body.lastlogin).format("MMM Do YYYY"), 2617 | fromnow: moment.unix(body.lastlogin).fromNow(), 2618 | } 2619 | : "Never"; 2620 | if (body.achievements) 2621 | achievements = Object.keys(body.achievements).length; 2622 | else achievements = 0; 2623 | 2624 | resolve({ 2625 | total_points, 2626 | games_played, 2627 | victories, 2628 | kills, 2629 | deaths, 2630 | title, 2631 | first_game, 2632 | last_game, 2633 | achievements, 2634 | }); 2635 | }); 2636 | } 2637 | 2638 | if (type === "BED") { 2639 | // Bedwars 2640 | fetch(`http://api.hivemc.com/v1/player/${username}/BED`) 2641 | .then((res) => res.text()) 2642 | .then(async (body) => { 2643 | body = JSON.parse(body); 2644 | if (body.code === 404 && body.short === "noprofile") 2645 | return resolve({ 2646 | errors: `No ${type} data found for user: ${username}`, 2647 | }); 2648 | let achievements; 2649 | const total_points = body.total_points || 0; 2650 | const victories = body.victories || 0; 2651 | const games_played = body.games_played || 0; 2652 | const kills = body.kills || 0; 2653 | const deaths = body.deaths || 0; 2654 | const beds_destroyed = body.beds_destroyed || 0; 2655 | const teams_eliminated = body.teams_eliminated || 0; 2656 | const win_streak = body.win_streak || 0; 2657 | const title = body.title || "None"; 2658 | const first_game = 2659 | body.firstLogin && body.firstLogin > 0 2660 | ? { 2661 | date: moment.unix(body.firstLogin).format("MMM Do YYYY"), 2662 | fromnow: moment.unix(body.firstLogin).fromNow(), 2663 | } 2664 | : "Never"; 2665 | const last_game = 2666 | body.lastlogin && body.lastlogin > 0 2667 | ? { 2668 | date: moment.unix(body.lastlogin).format("MMM Do YYYY"), 2669 | fromnow: moment.unix(body.lastlogin).fromNow(), 2670 | } 2671 | : "Never"; 2672 | if (body.achievements) 2673 | achievements = Object.keys(body.achievements).length; 2674 | else achievements = 0; 2675 | 2676 | resolve({ 2677 | total_points, 2678 | games_played, 2679 | victories, 2680 | kills, 2681 | deaths, 2682 | beds_destroyed, 2683 | teams_eliminated, 2684 | win_streak, 2685 | title, 2686 | first_game, 2687 | last_game, 2688 | achievements, 2689 | }); 2690 | }); 2691 | } 2692 | if (type === "leaderboards") { 2693 | fetch(`http://api.hivemc.com/v1/game/${username}/leaderboard/`) 2694 | .then((res) => res.text()) 2695 | .then(async (body) => { 2696 | body = JSON.parse(body); 2697 | if (body.code === 404) return resolve({ errors: body.message }); 2698 | resolve(body.leaderboard); 2699 | }); 2700 | } 2701 | }); 2702 | }, 2703 | wynncraft: (type, name) => { 2704 | return new Promise((resolve, reject) => { 2705 | if (!name) 2706 | return resolve({ 2707 | errors: "No username or guild name provided", 2708 | }); 2709 | if (!type) 2710 | return resolve({ 2711 | errors: "No type provided", 2712 | }); 2713 | if (type === "player") { 2714 | fetch(`https://api.wynncraft.com/v2/player/${name}/stats`) 2715 | .then((res) => res.text()) 2716 | .then(async (body) => { 2717 | body = JSON.parse(body); 2718 | if ( 2719 | body.code === 404 || 2720 | (body.code === 400 && body.message === "Bad Request") || 2721 | !body.data || 2722 | body.data.length === 0 2723 | ) { 2724 | return resolve({ 2725 | errors: `No player data found for user: ${name}`, 2726 | }); 2727 | } 2728 | const data = { 2729 | classes: {}, 2730 | ranking: {}, 2731 | }; 2732 | const player = body.data[0]; 2733 | const role = player.rank || "Unknown"; 2734 | const first_login = player.meta.firstJoin || "Unknown"; 2735 | const last_login = player.meta.lastJoin || "Unknown"; 2736 | const online = player.meta.location.online || false; 2737 | const location = player.meta.location.server || "Unknown"; 2738 | const play_time = 2739 | moment 2740 | .duration(player.meta.playtime, "minutes") 2741 | .format("D [days], H [hours], M [minutes]") || "Unknown"; 2742 | const rank = player.meta.tag.value || "None"; 2743 | const veteran = player.meta.veteran || false; 2744 | const guild_name = player.guild.name || "Unknown"; 2745 | const guild_rank = player.guild.rank || "Unknown"; 2746 | const chests_found = player.global.chestsFound || 0; 2747 | const items_identified = player.global.itemsIdentified || 0; 2748 | const mobs_killed = player.global.mobsKilled || 0; 2749 | const combat_level = player.global.totalLevel.combat || 0; 2750 | const profession_level = player.global.totalLevel.profession || 0; 2751 | const combined_level = player.global.totalLevel.combined || 0; 2752 | const players_killed = player.global.pvp.kills || 0; 2753 | const player_deaths = player.global.pvp.deaths || 0; 2754 | const blocks_walked = player.global.blocksWalked || 0; 2755 | const logins = player.global.logins || 0; 2756 | const deaths = player.global.deaths || 0; 2757 | const discoveries = player.global.discoveries || 0; 2758 | const events_won = player.global.eventsWon || 0; 2759 | 2760 | if (player.classes) { 2761 | player.classes.forEach(async (i) => { 2762 | const name = i.name.replace(/[0-9]+/g, "") || "None"; 2763 | const level = i.level || 0; 2764 | const chests_found = i.chestsFound || 0; 2765 | const items_identified = i.itemsIdentified || 0; 2766 | const mobs_killed = i.mobsKilled || 0; 2767 | const players_killed = i.pvp.kills || 0; 2768 | const player_deaths = i.pvp.deaths || 0; 2769 | const blocks_walked = i.blocksWalked || 0; 2770 | const logins = i.logins || 0; 2771 | const deaths = i.deaths || 0; 2772 | const playtime = 2773 | moment 2774 | .duration(i.playtime, "minutes") 2775 | .format("D [days], H [hours], M [minutes]") || 0; 2776 | const discoveries = i.discoveries || 0; 2777 | const events_won = i.eventsWon || 0; 2778 | const gamemode = i.gamemode || "None"; 2779 | const skill_strength = i.skills.strength || 0; 2780 | const skill_dexterity = i.skills.dexterity || 0; 2781 | const skill_intelligence = i.skills.intelligence || 0; 2782 | const skill_defence = i.skills.defence || 0; 2783 | const skill_agility = i.skills.agility || 0; 2784 | const profession_alchemism = i.professions.alchemism || 0; 2785 | const profession_armouring = i.professions.armouring || 0; 2786 | const profession_combat = i.professions.combat || 0; 2787 | const profession_cooking = i.professions.cooking || 0; 2788 | const profession_farming = i.professions.farming || 0; 2789 | const profession_fishing = i.professions.fishing || 0; 2790 | const profession_jeweling = i.professions.jeweling || 0; 2791 | const profession_mining = i.professions.mining || 0; 2792 | const profession_scribing = i.professions.scribing || 0; 2793 | const profession_tailoring = i.professions.tailoring || 0; 2794 | const profession_weaponsmithing = 2795 | i.professions.weaponsmithing || 0; 2796 | const profession_woodcutting = i.professions.woodcutting || 0; 2797 | const profession_woodworking = i.professions.woodworking || 0; 2798 | const dungeons_completed = i.dungeons.completed || 0; 2799 | var dungeons = []; 2800 | const quests_completed = i.quests.completed || 0; 2801 | const quests = i.quests.list || "None"; 2802 | i.dungeons.list.forEach((dungeon) => { 2803 | dungeons.push({ 2804 | name: dungeon.name, 2805 | completed: dungeon.completed, 2806 | }); 2807 | }); 2808 | if (!data.classes[name]) data.classes[name] = []; 2809 | data.classes[name].push({ 2810 | name, 2811 | level, 2812 | chests_found, 2813 | items_identified, 2814 | mobs_killed, 2815 | players_killed, 2816 | player_deaths, 2817 | blocks_walked, 2818 | logins, 2819 | deaths, 2820 | playtime, 2821 | discoveries, 2822 | events_won, 2823 | gamemode, 2824 | skill_strength, 2825 | skill_dexterity, 2826 | skill_intelligence, 2827 | skill_defence, 2828 | skill_agility, 2829 | profession_alchemism, 2830 | profession_armouring, 2831 | profession_farming, 2832 | profession_combat, 2833 | profession_cooking, 2834 | profession_fishing, 2835 | profession_jeweling, 2836 | profession_mining, 2837 | profession_scribing, 2838 | profession_tailoring, 2839 | profession_weaponsmithing, 2840 | profession_woodcutting, 2841 | profession_woodworking, 2842 | dungeons_completed, 2843 | dungeons, 2844 | quests_completed, 2845 | quests, 2846 | }); 2847 | }); 2848 | } 2849 | if (player.ranking) { 2850 | const guild_ranking = player.ranking.guild || 0; 2851 | const pvp_ranking = player.ranking.pvp || 0; 2852 | const solo_combat_ranking = 2853 | player.ranking.player.solo.combat || 0; 2854 | const solo_woodcutting_ranking = 2855 | player.ranking.player.solo.woodcutting || 0; 2856 | const solo_mining_ranking = 2857 | player.ranking.player.solo.mining || 0; 2858 | const solo_fishing_ranking = 2859 | player.ranking.player.solo.fishing || 0; 2860 | const solo_farming_ranking = 2861 | player.ranking.player.solo.farming || 0; 2862 | const solo_alchemism_ranking = 2863 | player.ranking.player.solo.alchemism || 0; 2864 | const solo_armouring_ranking = 2865 | player.ranking.player.solo.armouring || 0; 2866 | const solo_cooking_ranking = 2867 | player.ranking.player.solo.cooking || 0; 2868 | const solo_jeweling_ranking = 2869 | player.ranking.player.solo.jeweling || 0; 2870 | const solo_scribing_ranking = 2871 | player.ranking.player.solo.scribing || 0; 2872 | const solo_tailoring_ranking = 2873 | player.ranking.player.solo.tailoring || 0; 2874 | const solo_weaponsmithing_ranking = 2875 | player.ranking.player.solo.weaponsmithing || 0; 2876 | const solo_woodworking_ranking = 2877 | player.ranking.player.solo.woodworking || 0; 2878 | const solo_profession_ranking = 2879 | player.ranking.player.solo.profession || 0; 2880 | const solo_overall_ranking = 2881 | player.ranking.player.solo.overall || 0; 2882 | const overall_ranking = player.ranking.player.overall.all || 0; 2883 | const overall_combat_ranking = 2884 | player.ranking.player.overall.combat || 0; 2885 | const overall_profession_ranking = 2886 | player.ranking.player.overall.profession || 0; 2887 | 2888 | Object.assign(data.ranking, { 2889 | guild_ranking, 2890 | pvp_ranking, 2891 | solo_combat_ranking, 2892 | solo_woodcutting_ranking, 2893 | solo_mining_ranking, 2894 | solo_fishing_ranking, 2895 | solo_farming_ranking, 2896 | solo_alchemism_ranking, 2897 | solo_armouring_ranking, 2898 | solo_cooking_ranking, 2899 | solo_jeweling_ranking, 2900 | solo_scribing_ranking, 2901 | solo_tailoring_ranking, 2902 | solo_weaponsmithing_ranking, 2903 | solo_woodworking_ranking, 2904 | solo_profession_ranking, 2905 | solo_overall_ranking, 2906 | overall_ranking, 2907 | overall_combat_ranking, 2908 | overall_profession_ranking, 2909 | }); 2910 | } 2911 | Object.assign(data, { 2912 | role, 2913 | first_login, 2914 | last_login, 2915 | online, 2916 | location, 2917 | play_time, 2918 | rank, 2919 | veteran, 2920 | guild_name, 2921 | guild_rank, 2922 | chests_found, 2923 | items_identified, 2924 | mobs_killed, 2925 | combat_level, 2926 | profession_level, 2927 | combined_level, 2928 | players_killed, 2929 | player_deaths, 2930 | blocks_walked, 2931 | logins, 2932 | deaths, 2933 | discoveries, 2934 | events_won, 2935 | }); 2936 | resolve(data); 2937 | }); 2938 | } 2939 | if (type === "guild") { 2940 | fetch( 2941 | `https://api.wynncraft.com/public_api.php?action=guildStats&command=${name}` 2942 | ) 2943 | .then((res) => res.text()) 2944 | .then(async (body) => { 2945 | body = JSON.parse(body); 2946 | if (body.error === "Guild not found") 2947 | return resolve({ 2948 | errors: `No guild data found for guild: ${name}`, 2949 | }); 2950 | const data = {}; 2951 | const name = body.name || "None"; 2952 | const prefix = body.prefix || "None"; 2953 | const xp = body.xp || 0; 2954 | const level = body.level || 0; 2955 | const created = body.created || "Unknown"; 2956 | const territories = body.territories || 0; 2957 | const banner = body.banner ? body.banner : null; 2958 | if (body.members) { 2959 | const members = body.members.length; 2960 | const guild_owner = body.members.filter( 2961 | (guild) => guild.rank == "OWNER" 2962 | ); 2963 | const guild_chief = body.members.filter( 2964 | (guild) => guild.rank == "CHIEF" 2965 | ); 2966 | const guild_recruit = body.members.filter( 2967 | (guild) => guild.rank == "RECRUIT" 2968 | ); 2969 | const guild_captain = body.members.filter( 2970 | (guild) => guild.rank == "CAPTAIN" 2971 | ); 2972 | const guild_recruiter = body.members.filter( 2973 | (guild) => guild.rank == "RECRUITER" 2974 | ); 2975 | Object.assign(data, { 2976 | members, 2977 | guild_owner, 2978 | guild_chief, 2979 | guild_recruit, 2980 | guild_captain, 2981 | guild_recruiter, 2982 | }); 2983 | } 2984 | Object.assign(data, { 2985 | name, 2986 | prefix, 2987 | xp, 2988 | level, 2989 | created, 2990 | territories, 2991 | banner, 2992 | }); 2993 | resolve(data); 2994 | }); 2995 | } 2996 | }); 2997 | }, 2998 | 2999 | munchymc: (query, type) => { 3000 | if (type === "leaderboard") { 3001 | return new Promise((resolve, reject) => { 3002 | fetch(`https://www.munchymc.com/leaderboards/${query}`) 3003 | .then((res) => res.text()) 3004 | .then((body) => { 3005 | const data = {}; 3006 | const $ = cheerio.load(body); 3007 | 3008 | $( 3009 | $("div.col-md-4").length > 0 ? "div.col-md-4" : "div.col-md-6" 3010 | ).each(function () { 3011 | const leaderboard = $(this) 3012 | .find("div.caption-stats") 3013 | .text() 3014 | .trim() 3015 | .replace(/ /g, ""); 3016 | if (leaderboard.length > 0) { 3017 | data[leaderboard] = []; 3018 | $(this) 3019 | .find(".list-group-item") 3020 | .each(function () { 3021 | const stat = $(this) 3022 | .text() 3023 | .trim() 3024 | .replace(/\s\s /g, "") 3025 | .replace(/#[0-9]{1,2} {1,3}/, "") 3026 | .replace(/ {2}/, " ") 3027 | .split(/ /); 3028 | data[leaderboard].push({ 3029 | username: stat[0], 3030 | value: stat[1], 3031 | }); 3032 | }); 3033 | } 3034 | }); 3035 | return resolve(data); 3036 | }) 3037 | .catch((e) => { 3038 | resolve({ 3039 | errors: "Can't fetch stats, Website is probably offline.", 3040 | }); 3041 | console.log(e); 3042 | }); 3043 | }); 3044 | } 3045 | if (type === "player") { 3046 | return new Promise((resolve, reject) => { 3047 | fetch(`https://www.munchymc.com/profile/${query}`) 3048 | .then((res) => res.text()) 3049 | .then((body) => { 3050 | const data = { games: {} }; 3051 | const $ = cheerio.load(body); 3052 | if ( 3053 | $("div.col-md-12") 3054 | .text() 3055 | .includes( 3056 | "Looks like we couldn't find that name in our database!" 3057 | ) 3058 | ) { 3059 | return resolve({ 3060 | errors: `No inforamtion was found for ${query}`, 3061 | }); 3062 | } 3063 | const details = []; 3064 | const statistics = []; 3065 | 3066 | $('div[class="panel panel-success"]').each(function () { 3067 | $(this) 3068 | .find("li") 3069 | .each(function () { 3070 | details.push( 3071 | $(this) 3072 | .text() 3073 | .trim() 3074 | .replace(/(\s){2,}/g, "") 3075 | ); 3076 | }); 3077 | }); 3078 | console.log(details); 3079 | data.rank = details[0].replace("Rank: ", ""); 3080 | data.status = details[1].replace("Status:", ""); 3081 | data.tokens = details[2].replace("Tokens:", ""); 3082 | data.firstLogin = details[3].replace("Joined: ", ""); 3083 | data.lastLogin = details[4].replace("Last Login: ", ""); 3084 | 3085 | $('span[class="badge"]').each(function () { 3086 | statistics.push($(this).text().trim().replace(/\s*/g, "")); 3087 | }); 3088 | 3089 | data.games.woolwars = { 3090 | wins: Number(statistics[0]) || 0, 3091 | games: Number(statistics[1]) || 0, 3092 | kills: Number(statistics[2]) || 0, 3093 | }; 3094 | 3095 | data.games.skywars = { 3096 | wins: Number(statistics[4]) || 0, 3097 | games: Number(statistics[5]) || 0, 3098 | kills: Number(statistics[6]) || 0, 3099 | deaths: Number(statistics[7]) || 0, 3100 | }; 3101 | 3102 | data.games.mazerunner = { 3103 | wins: Number(statistics[8]) || 0, 3104 | games: Number(statistics[9]) || 0, 3105 | kills: Number(statistics[10]) || 0, 3106 | princess_kills: Number(statistics[11]) || 0, 3107 | }; 3108 | 3109 | data.games.classic_hungergames = { 3110 | wins: Number(statistics[12]) || 0, 3111 | games: Number(statistics[13]) || 0, 3112 | kills: Number(statistics[14]) || 0, 3113 | most_kills: Number(statistics[15]) || 0, 3114 | }; 3115 | 3116 | data.games.kitpvp = { 3117 | best_kill_streak: Number(statistics[16]) || 0, 3118 | casual: { 3119 | kills: Number(statistics[18]) || 0, 3120 | deaths: Number(statistics[19]) || 0, 3121 | }, 3122 | competitive: { 3123 | kills: Number(statistics[21]) || 0, 3124 | deaths: Number(statistics[22]) || 0, 3125 | }, 3126 | arena: { 3127 | kills: Number(statistics[24]) || 0, 3128 | deaths: Number(statistics[25]) || 0, 3129 | elo: Number(statistics[26]) || 0, 3130 | }, 3131 | brackets: { 3132 | games: Number(statistics[28]) || 0, 3133 | wins: Number(statistics[29]) || 0, 3134 | }, 3135 | }; 3136 | 3137 | data.games.prison = { 3138 | blocks_mined: Number(statistics[34]) || 0, 3139 | balance: Number(statistics[35]) || 0, 3140 | kills: Number(statistics[36]) || 0, 3141 | best_kill_streak: Number(statistics[37]) || 0, 3142 | }; 3143 | return resolve(data); 3144 | }) 3145 | .catch((e) => { 3146 | resolve({ 3147 | errors: "Can't fetch stats, Website is probably offline.", 3148 | }); 3149 | console.log(e); 3150 | }); 3151 | }); 3152 | } 3153 | }, 3154 | 3155 | mccentral: (query, type) => { 3156 | if (type === "leaderboard") { 3157 | return new Promise((resolve, reject) => { 3158 | function mccentralLeaderboardName(leaderboard) { 3159 | switch (leaderboard) { 3160 | case "survivalgames": 3161 | return "fsurvival"; 3162 | case "skywars": 3163 | return "fskywars"; 3164 | case "walls": 3165 | return "fwalls"; 3166 | case "ctf": 3167 | return "fctf"; 3168 | case "murdermayhem": 3169 | return "fmurder"; 3170 | case "championbuilder": 3171 | return "fchaps"; 3172 | case "cakewars": 3173 | return "fcakewars"; 3174 | case "uhc": 3175 | return "uhcserver"; 3176 | case "skyblock1": 3177 | return "sbNewReset1"; 3178 | case "skyblock2": 3179 | return "sbNewReset2"; 3180 | case "survival": 3181 | return "survival"; 3182 | case "factions": 3183 | return "facs"; 3184 | case "prison1": 3185 | return "prison"; 3186 | case "prison2": 3187 | return "prison2"; 3188 | case "kitpvp": 3189 | return "nkitpvp"; 3190 | case "arenapvp": 3191 | return "arenapvp2"; 3192 | } 3193 | } 3194 | const leaderboardName = mccentralLeaderboardName(query); 3195 | if (!leaderboardName) 3196 | return resolve({ errors: "Invaid game leaderboard." }); 3197 | fetch( 3198 | `https://mccentral.org/leaderboards-storage/leader/scripts/${leaderboardName}.php?sEcho=1&iColumns=6&sColumns=&iDisplayStart=0&iDisplayLength=25&mDataProp_0=0&mDataProp_1=1&mDataProp_2=2&mDataProp_3=3&mDataProp_4=4&mDataProp_5=5&sSearch=&bRegex=false&sSearch_0=&bRegex_0=false&bSearchable_0=true&sSearch_1=&bRegex_1=false&bSearchable_1=true&sSearch_2=&bRegex_2=false&bSearchable_2=true&sSearch_3=&bRegex_3=false&bSearchable_3=true&sSearch_4=&bRegex_4=false&bSearchable_4=true&sSearch_5=&bRegex_5=false&bSearchable_5=true&iSortCol_0=0&sSortDir_0=asc&iSortingCols=1&bSortable_0=false&bSortable_1=false&bSortable_2=false&bSortable_3=false&bSortable_4=false&bSortable_5=false` 3199 | ) 3200 | .then((res) => res.json()) 3201 | .then((body) => { 3202 | const data = []; 3203 | if (body.aaData.length > 0) { 3204 | body.aaData.forEach((i) => { 3205 | if (leaderboardName === "fsurvival") { 3206 | data.push({ 3207 | username: i[1], 3208 | games: Number(i[2]), 3209 | wins: Number(i[3]), 3210 | kills: Number(i[4]), 3211 | deaths: Number(i[5]), 3212 | }); 3213 | } 3214 | if (leaderboardName === "fskywars") { 3215 | data.push({ 3216 | username: i[1], 3217 | games: Number(i[2]), 3218 | wins: Number(i[3]), 3219 | kills: Number(i[4]), 3220 | deaths: Number(i[5]), 3221 | }); 3222 | } 3223 | if (leaderboardName === "fwalls") { 3224 | data.push({ 3225 | username: i[1], 3226 | games: Number(i[2]), 3227 | wins: Number(i[3]), 3228 | kills: Number(i[4]), 3229 | deaths: Number(i[5]), 3230 | }); 3231 | } 3232 | if (leaderboardName === "fctf") { 3233 | data.push({ 3234 | username: i[1], 3235 | games: Number(i[2]), 3236 | wins: Number(i[3]), 3237 | kills: Number(i[4]), 3238 | deaths: Number(i[5]), 3239 | flags_captured: Number(i[6]), 3240 | }); 3241 | } 3242 | if (leaderboardName === "fmurder") { 3243 | data.push({ 3244 | username: i[1], 3245 | games: Number(i[2]), 3246 | wins: Number(i[3]), 3247 | murderer_kills: Number(i[4]), 3248 | bystander_kills: Number(i[5]), 3249 | karma: Number(i[6]), 3250 | }); 3251 | } 3252 | if (leaderboardName === "fchamps") { 3253 | data.push({ 3254 | username: i[1], 3255 | blocks_placed: i[2], 3256 | blocks_broken: i[3], 3257 | wins: Number(i[4]), 3258 | games: Number(i[5]), 3259 | }); 3260 | } 3261 | if (leaderboardName === "fcakewars") { 3262 | data.push({ 3263 | username: i[1], 3264 | games: Number(i[2]), 3265 | wins: Number(i[3]), 3266 | kills: Number(i[4]), 3267 | deaths: Number(i[5]), 3268 | cakes_destroyed: Number(i[6]), 3269 | }); 3270 | } 3271 | if (leaderboardName === "uhcserver") { 3272 | data.push({ 3273 | username: i[1], 3274 | wins: Number(i[2]), 3275 | kills: Number(i[3]), 3276 | deaths: Number(i[4]), 3277 | gapples: Number(i[5]), 3278 | }); 3279 | } 3280 | if (leaderboardName === "sbNewReset1") { 3281 | data.push({ 3282 | username: i[1], 3283 | level: i[2], 3284 | value: i[3], 3285 | hoppers: Number(i[4]), 3286 | spawners: i[5], 3287 | }); 3288 | } 3289 | if (leaderboardName === "sbNewReset2") { 3290 | data.push({ 3291 | username: i[1], 3292 | level: i[2], 3293 | value: i[3], 3294 | hoppers: Number(i[4]), 3295 | spawners: i[5], 3296 | }); 3297 | } 3298 | if (leaderboardName === "survival") { 3299 | data.push({ 3300 | username: i[1], 3301 | balance: i[2], 3302 | kills: Number(i[3]), 3303 | deaths: Number(i[4]), 3304 | quests: Number(i[5]), 3305 | }); 3306 | } 3307 | if (leaderboardName === "facs") { 3308 | data.push({ 3309 | username: i[1], 3310 | wealth: i[2], 3311 | spawners: Number(i[3]), 3312 | }); 3313 | } 3314 | if (leaderboardName === "prison") { 3315 | data.push({ 3316 | username: i[1], 3317 | prison: i[2], 3318 | kills: Number(i[3]), 3319 | deaths: Number(i[4]), 3320 | blocks_mined: i[5], 3321 | gang: i[6], 3322 | }); 3323 | } 3324 | if (leaderboardName === "prison2") { 3325 | data.push({ 3326 | username: i[1], 3327 | prison: i[2], 3328 | kills: Number(i[3]), 3329 | deaths: Number(i[4]), 3330 | blocks_mined: i[5], 3331 | gang: i[6], 3332 | }); 3333 | } 3334 | if (leaderboardName === "nkitpvp") { 3335 | data.push({ 3336 | username: i[1], 3337 | kills: Number(i[2]), 3338 | deaths: Number(i[3]), 3339 | level: Number(i[4]), 3340 | gapples: Number(i[5]), 3341 | events_won: Number(i[6]), 3342 | }); 3343 | } 3344 | if (leaderboardName === "arenapvp2") { 3345 | data.push({ 3346 | username: i[1], 3347 | duels: Number(i[2]), 3348 | duels_won: Number(i[3]), 3349 | win_ratio: i[4], 3350 | duels_rank: i[5], 3351 | }); 3352 | } 3353 | }); 3354 | resolve(data); 3355 | } else { 3356 | return resolve({ errors: "No leaderboards found." }); 3357 | } 3358 | }) 3359 | .catch((e) => { 3360 | resolve({ 3361 | errors: "Can't fetch stats, Website is probably offline.", 3362 | }); 3363 | console.log(e); 3364 | }); 3365 | }); 3366 | } 3367 | if (type === "player") { 3368 | return new Promise(async (resolve, reject) => { 3369 | const data = { 3370 | survival_games: { 3371 | rank: 0, 3372 | games: 0, 3373 | wins: 0, 3374 | kills: 0, 3375 | deaths: 0, 3376 | }, 3377 | skywars: { 3378 | rank: 0, 3379 | games: 0, 3380 | wins: 0, 3381 | kills: 0, 3382 | deaths: 0, 3383 | }, 3384 | walls: { 3385 | rank: 0, 3386 | games: 0, 3387 | wins: 0, 3388 | kills: 0, 3389 | deaths: 0, 3390 | }, 3391 | ctf: { 3392 | rank: 0, 3393 | games: 0, 3394 | wins: 0, 3395 | kills: 0, 3396 | deaths: 0, 3397 | flags_captured: 0, 3398 | }, 3399 | murder: { 3400 | rank: 0, 3401 | games: 0, 3402 | wins: 0, 3403 | murderer_kills: 0, 3404 | bystander_kills: 0, 3405 | karma: 0, 3406 | }, 3407 | champs: { 3408 | rank: 0, 3409 | blocks_placed: 0, 3410 | blocks_broken: 0, 3411 | wins: 0, 3412 | games: 0, 3413 | }, 3414 | cakewars: { 3415 | rank: 0, 3416 | games: 0, 3417 | wins: 0, 3418 | kills: 0, 3419 | deaths: 0, 3420 | cakes_destroyed: 0, 3421 | }, 3422 | uhc: { 3423 | rank: 0, 3424 | wins: 0, 3425 | kills: 0, 3426 | deaths: 0, 3427 | gapples: 0, 3428 | }, 3429 | skyblock1: { 3430 | rank: 0, 3431 | level: 0, 3432 | value: 0, 3433 | hoppers: 0, 3434 | spawners: 0, 3435 | }, 3436 | skyblock2: { 3437 | rank: 0, 3438 | level: 0, 3439 | value: 0, 3440 | hoppers: 0, 3441 | spawners: 0, 3442 | }, 3443 | survival: { 3444 | rank: 0, 3445 | balance: 0, 3446 | kills: 0, 3447 | deaths: 0, 3448 | quests: 0, 3449 | }, 3450 | factions: { 3451 | rank: 0, 3452 | wealth: 0, 3453 | spawners: 0, 3454 | }, 3455 | prison1: { 3456 | rank: 0, 3457 | prison: 0, 3458 | kills: 0, 3459 | deaths: 0, 3460 | blocks_mined: 0, 3461 | gang: 0, 3462 | }, 3463 | prison2: { 3464 | rank: 0, 3465 | prison: 0, 3466 | kills: 0, 3467 | deaths: 0, 3468 | blocks_mined: 0, 3469 | gang: 0, 3470 | }, 3471 | kitpvp: { 3472 | rank: 0, 3473 | kills: 0, 3474 | deaths: 0, 3475 | level: 0, 3476 | gapples: 0, 3477 | highest_streak: 0, 3478 | events_won: 0, 3479 | }, 3480 | arenapvp: { 3481 | rank: 0, 3482 | duels: 0, 3483 | duels_won: 0, 3484 | win_ratio: 0, 3485 | duels_rank: 0, 3486 | }, 3487 | }; 3488 | const games = [ 3489 | "fsurvival", 3490 | "fskywars", 3491 | "fwalls", 3492 | "fctf", 3493 | "fmurder", 3494 | "fchamps", 3495 | "fcakewars", 3496 | "uhcserver", 3497 | "sbNewReset1", 3498 | "sbNewReset2", 3499 | "survival", 3500 | "facs", 3501 | "prison", 3502 | "prison2", 3503 | "nkitpvp", 3504 | "arenapvp2", 3505 | ]; 3506 | for (let i = 0; i < games.length; i++) { 3507 | await fetch( 3508 | `https://mccentral.org/leaderboards-storage/leader/scripts/${games[i]}.php?sSearch=${query}&bRegex=false&sSearch_0=&bRegex_0=false&bSearchable_0=true&sSearch_1=&bRegex_1=false&bSearchable_1=true&sSearch_2=&bRegex_2=false&bSearchable_2=true&sSearch_3=&bRegex_3=false&bSearchable_3=true&sSearch_4=&bRegex_4=false&bSearchable_4=true&sSearch_5=&bRegex_5=false&bSearchable_5=true&iSortCol_0=0&sSortDir_0=asc&iSortingCols=1&bSortable_0=false&bSortable_1=false&bSortable_2=false&bSortable_3=false&bSortable_4=false&bSortable_5=false` 3509 | ) 3510 | .then((res) => res.json()) 3511 | .then((body) => { 3512 | if ( 3513 | body.aaData.length > 0 && 3514 | body.aaData[0][1].toLowerCase() === query.toLowerCase() 3515 | ) { 3516 | if (games[i] === "fsurvival") { 3517 | data.survival_games.rank = Number(body.aaData[0][0]); 3518 | data.survival_games.games = Number(body.aaData[0][2]); 3519 | data.survival_games.wins = Number(body.aaData[0][3]); 3520 | data.survival_games.kills = Number(body.aaData[0][4]); 3521 | data.survival_games.deaths = Number(body.aaData[0][5]); 3522 | } 3523 | if (games[i] === "fskywars") { 3524 | data.skywars.rank = Number(body.aaData[0][0]); 3525 | data.skywars.games = Number(body.aaData[0][2]); 3526 | data.skywars.wins = Number(body.aaData[0][3]); 3527 | data.skywars.kills = Number(body.aaData[0][4]); 3528 | data.skywars.deaths = Number(body.aaData[0][5]); 3529 | } 3530 | if (games[i] === "fwalls") { 3531 | data.walls.rank = Number(body.aaData[0][0]); 3532 | data.walls.games = Number(body.aaData[0][2]); 3533 | data.walls.wins = Number(body.aaData[0][3]); 3534 | data.walls.kills = Number(body.aaData[0][4]); 3535 | data.walls.deaths = Number(body.aaData[0][5]); 3536 | } 3537 | if (games[i] === "fctf") { 3538 | data.ctf.rank = Number(body.aaData[0][0]); 3539 | data.ctf.games = Number(body.aaData[0][2]); 3540 | data.ctf.wins = Number(body.aaData[0][3]); 3541 | data.ctf.kills = Number(body.aaData[0][4]); 3542 | data.ctf.deaths = Number(body.aaData[0][5]); 3543 | data.ctf.flags_captured = Number(body.aaData[0][6]); 3544 | } 3545 | if (games[i] === "fmurder") { 3546 | data.murder.rank = Number(body.aaData[0][0]); 3547 | data.murder.games = Number(body.aaData[0][2]); 3548 | data.murder.wins = Number(body.aaData[0][3]); 3549 | data.murder.murderer_kills = Number(body.aaData[0][4]); 3550 | data.murder.bystander_kills = Number(body.aaData[0][5]); 3551 | data.murder.karma = Number(body.aaData[0][6]); 3552 | } 3553 | if (games[i] === "fchamps") { 3554 | data.champs.rank = Number(body.aaData[0][0]); 3555 | data.champs.blocks_placed = body.aaData[0][2]; 3556 | data.champs.blocks_broken = body.aaData[0][3]; 3557 | data.champs.wins = Number(body.aaData[0][4]); 3558 | data.champs.games = Number(body.aaData[0][5]); 3559 | } 3560 | if (games[i] === "fcakewars") { 3561 | data.cakewars.rank = Number(body.aaData[0][0]); 3562 | data.cakewars.games = Number(body.aaData[0][2]); 3563 | data.cakewars.wins = Number(body.aaData[0][3]); 3564 | data.cakewars.kills = Number(body.aaData[0][4]); 3565 | data.cakewars.deaths = Number(body.aaData[0][5]); 3566 | data.cakewars.cakes_destroyed = Number(body.aaData[0][6]); 3567 | } 3568 | if (games[i] === "uhcserver") { 3569 | data.uhc.rank = Number(body.aaData[0][0]); 3570 | data.uhc.wins = Number(body.aaData[0][2]); 3571 | data.uhc.kills = Number(body.aaData[0][3]); 3572 | data.uhc.deaths = Number(body.aaData[0][4]); 3573 | data.uhc.gapples = Number(body.aaData[0][5]); 3574 | } 3575 | if (games[i] === "sbNewReset1") { 3576 | data.skyblock1.rank = Number(body.aaData[0][0]); 3577 | data.skyblock1.level = body.aaData[0][2]; 3578 | data.skyblock1.value = body.aaData[0][3]; 3579 | data.skyblock1.hoppers = Number(body.aaData[0][4]); 3580 | data.skyblock1.spawners = body.aaData[0][5]; 3581 | } 3582 | if (games[i] === "sbNewReset2") { 3583 | data.skyblock2.rank = Number(body.aaData[0][0]); 3584 | data.skyblock2.level = body.aaData[0][2]; 3585 | data.skyblock2.value = body.aaData[0][3]; 3586 | data.skyblock2.hoppers = Number(body.aaData[0][4]); 3587 | data.skyblock2.spawners = body.aaData[0][5]; 3588 | } 3589 | if (games[i] === "survival") { 3590 | data.survival.rank = Number(body.aaData[0][0]); 3591 | data.survival.balance = body.aaData[0][2]; 3592 | data.survival.kills = Number(body.aaData[0][3]); 3593 | data.survival.deaths = Number(body.aaData[0][4]); 3594 | data.survival.quests = Number(body.aaData[0][5]); 3595 | } 3596 | if (games[i] === "factions") { 3597 | data.factions.rank = Number(body.aaData[0][0]); 3598 | data.factions.wealth = body.aaData[0][2]; 3599 | data.factions.spawners = Number(body.aaData[0][3]); 3600 | } 3601 | if (games[i] === "prison") { 3602 | data.prison1.rank = Number(body.aaData[0][0]); 3603 | data.prison1.prison = body.aaData[0][2]; 3604 | data.prison1.kills = Number(body.aaData[0][3]); 3605 | data.prison1.deaths = Number(body.aaData[0][4]); 3606 | data.prison1.blocks_mined = body.aaData[0][5]; 3607 | data.prison1.gang = body.aaData[0][6]; 3608 | } 3609 | if (games[i] === "prison2") { 3610 | data.prison2.rank = Number(body.aaData[0][0]); 3611 | data.prison2.prison = body.aaData[0][2]; 3612 | data.prison2.kills = Number(body.aaData[0][3]); 3613 | data.prison2.deaths = Number(body.aaData[0][4]); 3614 | data.prison2.blocks_mined = body.aaData[0][5]; 3615 | data.prison2.gang = body.aaData[0][6]; 3616 | } 3617 | if (games[i] === "nkitpvp") { 3618 | data.kitpvp.rank = Number(body.aaData[0][0]); 3619 | data.kitpvp.kills = Number(body.aaData[0][2]); 3620 | data.kitpvp.deaths = Number(body.aaData[0][3]); 3621 | data.kitpvp.level = Number(body.aaData[0][4]); 3622 | data.kitpvp.gapples = Number(body.aaData[0][5]); 3623 | data.kitpvp.events_won = Number(body.aaData[0][6]); 3624 | } 3625 | if (games[i] === "arenapvp2") { 3626 | data.arenapvp.rank = Number(body.aaData[0][0]); 3627 | data.arenapvp.duels = Number(body.aaData[0][2]); 3628 | data.arenapvp.duels_won = Number(body.aaData[0][3]); 3629 | data.arenapvp.win_ratio = body.aaData[0][4]; 3630 | data.arenapvp.duels_rank = body.aaData[0][5]; 3631 | } 3632 | } 3633 | }) 3634 | .catch((e) => { 3635 | resolve({ 3636 | errors: "Can't fetch stats, Website is probably offline.", 3637 | }); 3638 | console.log(e); 3639 | }); 3640 | } 3641 | return resolve(data); 3642 | }); 3643 | } 3644 | }, 3645 | }; 3646 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mc-stats", 3 | "version": "1.0.8", 4 | "description": "Wrapper for fetching player stats from popular Minecraft networks.", 5 | "author": "Robert (Discord: Robert#0006), Tj (Discord: Tj#0215)", 6 | "license": "MIT", 7 | "keywords": [ 8 | "minecraft", 9 | "hypixel", 10 | "wynncraft", 11 | "hivemc", 12 | "funcraft", 13 | "blocksmc" 14 | ], 15 | "repository": { 16 | "type": "git", 17 | "url": "git://github.com/treboryx/mc-stats.git" 18 | }, 19 | "main": "app.js", 20 | "dependencies": { 21 | "cheerio": "^1.0.0-rc.12", 22 | "moment": "^2.29.4", 23 | "moment-duration-format": "^2.3.2", 24 | "node-fetch": "2.6" 25 | }, 26 | "devDependencies": { 27 | "eslint": "^8.24.0", 28 | "husky": "^8.0.1", 29 | "jest": "^29.1.2" 30 | }, 31 | "scripts": { 32 | "lint": "eslint --fix .", 33 | "test": "node ./test", 34 | "dev": "nodemon ./test" 35 | }, 36 | "husky": { 37 | "hooks": { 38 | "pre-commit": "npm run lint" 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | const mc = require("../app.js"); 2 | 3 | const main = async () => { 4 | mc.comugamers("Jojo1545", "player").then((r) => console.log(r)); 5 | // mc.mccentral("kitpvp", "leaderboard").then(r => console.log(r)); 6 | // mc.munchymc("badboyhalo", "player").then((r) => console.log(r)); 7 | // mc.hypixelPlayer("Dinnerbone").then(r => console.log(r)); 8 | // mc.blocksmc("_IPlozSawdadawd". "player").then(r => console.log(r)); 9 | // mc.funcraft("nathan818").then(r => console.log(r)); 10 | // mc.mineplex("xeiu").then(r => console.log(r)); 11 | // mc.manacube("KaiYara12").then(r => console.log(r)); 12 | // mc.minesaga("doitnowornever").then(r => console.log(r)); 13 | // mc.gommehd("YouBetterGoAfk").then(r => console.log(r)); 14 | // mc.timolia("Flycofx").then((r) => console.log(r)); 15 | // mc.minemen("Cleid").then(r => console.log(r)); 16 | // mc.veltpvp("DissTracks").then(r => console.log(r)); 17 | // mc.universocraft("ImOvee_Idk").then(r => console.log(r)); 18 | // mc.hypixelBoosters().then(r => console.log(r)); 19 | // mc.minemen("NiceTryEfe").then(r => console.log(r)); 20 | // mc.hivemc("Gooogle_it", "profile").then(r => console.log(r)); 21 | // mc.hivemc("jonas2246", "SG").then(r => console.log(r)); 22 | // mc.hivemc("Tutle", "BP").then(r => console.log(r)); 23 | // mc.hivemc("Ingola", "CAI").then(r => console.log(r)); 24 | // mc.hivemc("Endlen", "CR").then(r => console.log(r)); 25 | // mc.hivemc("kaiurii", "DR").then(r => console.log(r)); 26 | // mc.hivemc("Limimin", "HB").then(r => console.log(r)); 27 | // mc.hivemc("Limimin", "HB").then(r => console.log(r)); 28 | // mc.hivemc("Caro", "HERO").then(r => console.log(r)); 29 | // mc.hivemc("Spenken", "HIDE").then(r => console.log(r)); 30 | // mc.hivemc("AslanThePro", "OITC").then(r => console.log(r)); 31 | // mc.hivemc("Demon2921", "SP").then(r => console.log(r)); 32 | // mc.hivemc("HeinzBeans", "TIMV").then(r => console.log(r)); 33 | // mc.hivemc("Rinjani", "SKY").then(r => console.log(r)); 34 | // mc.hivemc("Mcae", "DRAW").then(r => console.log(r)); 35 | // mc.hivemc("Varsel", "SLAP").then(r => console.log(r)); 36 | // mc.hivemc("Mackan__", "EF").then(r => console.log(r)); 37 | // mc.hivemc("Conga_", "MM").then(r => console.log(r)); 38 | // mc.hivemc("ShooterGHP", "GRAV").then(r => console.log(r)); 39 | // mc.hivemc("Bgbros", "RR").then(r => console.log(r)); 40 | // mc.hivemc("RageStateOfMind", "GNT").then(r => console.log(r)); 41 | // mc.hivemc("iiAnass", "SGN").then(r => console.log(r)); 42 | // mc.hivemc("Fcssy", "BD").then(r => console.log(r)); 43 | // mc.hivemc("IDontExquseYou", "SPL").then(r => console.log(r)); 44 | // mc.hivemc("Marleeey", "MIMV").then(r => console.log(r)); 45 | // mc.hivemc("HappyStateOfMind", "BED").then(r => console.log(r)); 46 | // mc.wynncraft("player", "1MCRocker").then(r => console.log(r)); 47 | // mc.wynncraft("guild", "Imperial").then(r => console.log(r)); 48 | }; 49 | 50 | main(); 51 | --------------------------------------------------------------------------------