UNPKG

@fnlb-project/fnbr

Version:

A library to interact with Epic Games' Fortnite HTTP and XMPP services

219 lines 7.23 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.chunk = exports.resolveAuthObject = exports.resolveAuthString = exports.parseStatKey = exports.createDefaultInputTypeStats = exports.parseM3U8File = exports.parseBlurlStream = exports.createPartyInvitation = exports.getRandomDefaultCharacter = exports.makeSnakeCase = exports.makeCamelCase = void 0; const tslib_1 = require("tslib"); /* eslint-disable no-restricted-syntax */ const zlib_1 = tslib_1.__importDefault(require("zlib")); const fs_1 = require("fs"); const defaultCharacters = [ 'CID_A_272_Athena_Commando_F_Prime', 'CID_A_273_Athena_Commando_F_Prime_B', 'CID_A_274_Athena_Commando_F_Prime_C', 'CID_A_275_Athena_Commando_F_Prime_D', 'CID_A_276_Athena_Commando_F_Prime_E', 'CID_A_277_Athena_Commando_F_Prime_F', 'CID_A_278_Athena_Commando_F_Prime_G', 'CID_A_279_Athena_Commando_M_Prime', 'CID_A_280_Athena_Commando_M_Prime_B', 'CID_A_281_Athena_Commando_M_Prime_C', 'CID_A_282_Athena_Commando_M_Prime_D', 'CID_A_283_Athena_Commando_M_Prime_E', 'CID_A_284_Athena_Commando_M_Prime_F', 'CID_A_285_Athena_Commando_M_Prime_G', ]; const makeCamelCase = (obj) => { const returnObj = {}; Object.keys(obj).forEach((k) => { returnObj[k.split('_').map((s, i) => (i > 0 ? `${s.charAt(0).toUpperCase()}${s.slice(1)}` : s)).join('')] = obj[k]; }); return returnObj; }; exports.makeCamelCase = makeCamelCase; const makeSnakeCase = (obj) => { const returnObj = {}; Object.keys(obj).forEach((k) => { returnObj[k.replace(/[A-Z]/g, (l) => `_${l.toLowerCase()}`)] = obj[k]; }); return returnObj; }; exports.makeSnakeCase = makeSnakeCase; const getRandomDefaultCharacter = () => defaultCharacters[Math.floor(Math.random() * defaultCharacters.length)]; exports.getRandomDefaultCharacter = getRandomDefaultCharacter; const createPartyInvitation = (clientUserId, pingerId, data) => { const member = data.members.find((m) => m.account_id === pingerId); const partyMeta = data.meta; const memberMeta = member.meta; const meta = { 'urn:epic:conn:type_s': 'game', 'urn:epic:cfg:build-id_s': partyMeta['urn:epic:cfg:build-id_s'], 'urn:epic:invite:platformdata_s': '', }; if (memberMeta.Platform_j) { meta['Platform_j'] = JSON.parse(memberMeta.Platform_j).Platform.platformStr; } if (memberMeta['urn:epic:member:dn_s']) meta['urn:epic:member:dn_s'] = memberMeta['urn:epic:member:dn_s']; return { party_id: data.id, sent_by: pingerId, sent_to: clientUserId, sent_at: data.sent, updated_at: data.sent, expires_at: data.expies_at, status: 'SENT', meta, }; }; exports.createPartyInvitation = createPartyInvitation; const parseBlurlStream = (stream) => new Promise((res) => { zlib_1.default.inflate(stream.slice(8), (_err, buffer) => { const data = JSON.parse(buffer.toString()); res(data); }); }); exports.parseBlurlStream = parseBlurlStream; const parseM3U8FileLine = (line) => { const [key, value] = line.replace(/^#EXT-X-/, '').split(/:(.+)/); let output; if (value.includes(',')) { output = {}; let store = ''; let isString = false; for (const char of value.split('')) { if (char === '"') { isString = !isString; } else if (char === ',' && !isString) { const [vK, vV] = store.split(/=(.+)/); output[vK] = vV.replace(/(^"|"$)/g, ''); store = ''; } else { store += char; } } } else { output = value; } return [key, output]; }; const parseM3U8File = (data) => { const output = { streams: [], }; let streamInf; for (const line of data.split(/\n/).slice(1)) { if (line.startsWith('#EXT-X-STREAM-INF:')) { [, streamInf] = parseM3U8FileLine(line); } else if (line.startsWith('#EXT-X-')) { const [key, value] = parseM3U8FileLine(line); output[key] = value; } else if (!line.startsWith('#') && streamInf && line.length > 0) { output.streams.push({ data: streamInf, url: line, }); streamInf = undefined; } } return output; }; exports.parseM3U8File = parseM3U8File; const defaultStats = { score: 0, scorePerMin: 0, scorePerMatch: 0, wins: 0, top3: 0, top5: 0, top6: 0, top10: 0, top12: 0, top25: 0, kills: 0, killsPerMin: 0, killsPerMatch: 0, deaths: 0, kd: 0, matches: 0, winRate: 0, minutesPlayed: 0, playersOutlived: 0, lastModified: undefined, }; const createDefaultInputTypeStats = () => ({ overall: { ...defaultStats }, solo: { ...defaultStats }, duo: { ...defaultStats }, squad: { ...defaultStats }, ltm: { ...defaultStats }, }); exports.createDefaultInputTypeStats = createDefaultInputTypeStats; const parseStatKey = (key, value) => { switch (key) { case 'lastmodified': return ['lastModified', new Date(value * 1000)]; case 'placetop25': return ['top25', value]; case 'placetop12': return ['top12', value]; case 'placetop10': return ['top10', value]; case 'placetop6': return ['top6', value]; case 'placetop5': return ['top5', value]; case 'placetop3': return ['top3', value]; case 'placetop1': return ['wins', value]; case 'playersoutlived': return ['playersOutlived', value]; case 'minutesplayed': return ['minutesPlayed', value]; case 'matchesplayed': return ['matches', value]; default: return [key, value]; } }; exports.parseStatKey = parseStatKey; const resolveAuthString = async (str) => { switch (typeof str) { case 'function': return str(); case 'string': if (str.length === 32 || str.startsWith('eg1')) { return str; } return fs_1.promises.readFile(str, 'utf8'); default: throw new TypeError(`The type "${typeof str}" does not resolve to a valid auth string`); } }; exports.resolveAuthString = resolveAuthString; const resolveAuthObject = async (obj) => { switch (typeof obj) { case 'function': return obj(); case 'string': return JSON.parse(await fs_1.promises.readFile(obj, 'utf8')); case 'object': return obj; default: throw new TypeError(`The type "${typeof obj}" does not resolve to a valid auth object`); } }; exports.resolveAuthObject = resolveAuthObject; const chunk = (array, maxSize) => { const chunkedArray = []; for (let i = 0; i < array.length; i += maxSize) { chunkedArray.push(array.slice(i, i + maxSize)); } return chunkedArray; }; exports.chunk = chunk; //# sourceMappingURL=Util.js.map