├── .gitignore ├── README.md ├── bun.lockb ├── package-lock.json ├── package.json ├── src ├── config │ └── config.ini ├── index.ts ├── routes │ ├── api.ts │ ├── cloudstorage.ts │ ├── data.ts │ ├── discovery.ts │ ├── eos.ts │ ├── habanero.ts │ ├── lightswitch.ts │ ├── matchmaking.ts │ ├── mcp.ts │ ├── oauth.ts │ ├── storefront.ts │ └── timeline.ts └── utils │ ├── handlers │ ├── errors.ts │ ├── events.ts │ └── getVersion.ts │ ├── logger │ └── logger.ts │ └── startup │ └── loadRoutes.ts ├── start.bat ├── static ├── assets │ ├── Nexa.chunk │ ├── Nexa.manifest │ └── stuff.ini ├── discovery │ ├── events.ts │ ├── latest │ │ ├── brplaylist.json │ │ ├── ltms │ │ │ ├── playlist_defaultduo.json │ │ │ ├── playlist_defaultsolo.json │ │ │ ├── playlist_defaultsquad.json │ │ │ ├── playlist_juno.json │ │ │ ├── playlist_papaya.json │ │ │ └── playlist_trios.json │ │ └── menu.json │ └── menu.json ├── hotfixes │ ├── DefaultEngine.ini │ ├── DefaultGame.ini │ ├── DefaultInput.ini │ └── DefaultRuntimeOptions.ini ├── profiles │ ├── profile_athena.json │ ├── profile_campaign.json │ ├── profile_collections.json │ ├── profile_common_core.json │ ├── profile_common_public.json │ ├── profile_creative.json │ ├── profile_metadata.json │ ├── profile_outpost0.json │ ├── profile_profile0.json │ └── profile_theater0.json └── shop │ ├── keychain.json │ ├── v1.json │ ├── v2.json │ └── v3.json └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore 2 | 3 | # Logs 4 | 5 | logs 6 | _.log 7 | npm-debug.log_ 8 | yarn-debug.log* 9 | yarn-error.log* 10 | lerna-debug.log* 11 | .pnpm-debug.log* 12 | 13 | # Caches 14 | 15 | .cache 16 | 17 | # Diagnostic reports (https://nodejs.org/api/report.html) 18 | 19 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 20 | 21 | # Runtime data 22 | pids 23 | _.pid 24 | _.seed 25 | *.pid.lock 26 | 27 | # Directory for instrumented libs generated by jscoverage/JSCover 28 | 29 | lib-cov 30 | 31 | # Coverage directory used by tools like istanbul 32 | 33 | coverage 34 | *.lcov 35 | 36 | # nyc test coverage 37 | 38 | .nyc_output 39 | 40 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 41 | 42 | .grunt 43 | 44 | # Bower dependency directory (https://bower.io/) 45 | 46 | bower_components 47 | 48 | # node-waf configuration 49 | 50 | .lock-wscript 51 | 52 | # Compiled binary addons (https://nodejs.org/api/addons.html) 53 | 54 | build/Release 55 | 56 | # Dependency directories 57 | 58 | node_modules/ 59 | jspm_packages/ 60 | 61 | # Snowpack dependency directory (https://snowpack.dev/) 62 | 63 | web_modules/ 64 | 65 | # TypeScript cache 66 | 67 | *.tsbuildinfo 68 | 69 | # Optional npm cache directory 70 | 71 | .npm 72 | 73 | # Optional eslint cache 74 | 75 | .eslintcache 76 | 77 | # Optional stylelint cache 78 | 79 | .stylelintcache 80 | 81 | # Microbundle cache 82 | 83 | .rpt2_cache/ 84 | .rts2_cache_cjs/ 85 | .rts2_cache_es/ 86 | .rts2_cache_umd/ 87 | 88 | # Optional REPL history 89 | 90 | .node_repl_history 91 | 92 | # Output of 'npm pack' 93 | 94 | *.tgz 95 | 96 | # Yarn Integrity file 97 | 98 | .yarn-integrity 99 | 100 | # dotenv environment variable files 101 | 102 | .env 103 | .env.development.local 104 | .env.test.local 105 | .env.production.local 106 | .env.local 107 | 108 | # parcel-bundler cache (https://parceljs.org/) 109 | 110 | .parcel-cache 111 | 112 | # Next.js build output 113 | 114 | .next 115 | out 116 | 117 | # Nuxt.js build / generate output 118 | 119 | .nuxt 120 | dist 121 | 122 | # Gatsby files 123 | 124 | # Comment in the public line in if your project uses Gatsby and not Next.js 125 | 126 | # https://nextjs.org/blog/next-9-1#public-directory-support 127 | 128 | # public 129 | 130 | # vuepress build output 131 | 132 | .vuepress/dist 133 | 134 | # vuepress v2.x temp and cache directory 135 | 136 | .temp 137 | 138 | # Docusaurus cache and generated files 139 | 140 | .docusaurus 141 | 142 | # Serverless directories 143 | 144 | .serverless/ 145 | 146 | # FuseBox cache 147 | 148 | .fusebox/ 149 | 150 | # DynamoDB Local files 151 | 152 | .dynamodb/ 153 | 154 | # TernJS port file 155 | 156 | .tern-port 157 | 158 | # Stores VSCode versions used for testing VSCode extensions 159 | 160 | .vscode-test 161 | 162 | # yarn v2 163 | 164 | .yarn/cache 165 | .yarn/unplugged 166 | .yarn/build-state.yml 167 | .yarn/install-state.gz 168 | .pnp.* 169 | 170 | # IntelliJ based IDEs 171 | .idea 172 | 173 | # Finder (MacOS) folder config 174 | .DS_Store 175 | 176 | 177 | 178 | # Nexa 179 | static/profiles/profile_athena.json 180 | static/profiles/* 181 | static/ClientSettings/* 182 | .vscode/settings.json 183 | profiles 184 | profile_athena.json -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nexa 2 | 3 | Nexa is a Fortnite backend for all versions of fortnite! 4 | 5 | This will be finished during my free time 6 | 7 | If you want to contribute just fork this repository and make a pull request! 8 | 9 | > [!TIP] 10 | > Join the discord server for support! https://discord.gg/nexa-1229545680641462282 11 | 12 | > [!WARNING] 13 | > We do not accept any liability for the misuse of this program. Epic Games strictly prohibits the presence of cosmetics not bought from the game's official item shop on private servers, as it breaches the End User License Agreement (EULA). 14 | 15 | ## Todo 16 | 17 | - Complete MCP 18 | 19 | To install bun go [here](https://bun.sh/docs/installation) 20 | 21 | To install dependencies: 22 | 23 | ```bash 24 | bun install 25 | ``` 26 | 27 | To run: 28 | 29 | ```bash 30 | bun run src/index.ts 31 | ``` 32 | 33 | # Used API's 34 | 35 | [NiteStats API](https://nitestats.com/) 36 | 37 | # Credits 38 | 39 | - [Hybrid](https://github.com/HybridFNBR) for Discovery for 26.30+ and MOTD 40 | 41 | - [Zetax](https://github.com/simplyzetax) for Error responses 42 | -------------------------------------------------------------------------------- /bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itztiva/Nexa/050abe8775cbb716bbd0fc6384c6c08f210afac7/bun.lockb -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nexa", 3 | "lockfileVersion": 3, 4 | "requires": true, 5 | "packages": { 6 | "": { 7 | "name": "nexa", 8 | "dependencies": { 9 | "axios": "^1.7.2", 10 | "chalk": "^5.3.0", 11 | "crypto": "^1.0.1", 12 | "hono": "^4.4.6", 13 | "jsonwebtoken": "^9.0.2", 14 | "uuid": "^10.0.0" 15 | }, 16 | "devDependencies": { 17 | "@types/bun": "latest", 18 | "@types/jsonwebtoken": "^9.0.6", 19 | "@types/uuid": "^9.0.8", 20 | "ini": "^4.1.3" 21 | }, 22 | "peerDependencies": { 23 | "typescript": "^5.0.0" 24 | } 25 | }, 26 | "node_modules/@types/bun": { 27 | "version": "1.1.4", 28 | "resolved": "https://registry.npmjs.org/@types/bun/-/bun-1.1.4.tgz", 29 | "integrity": "sha512-ejSuv/3s0hTHj/nkkLzBlHxm4JxOPygbLNi0kzM6ooq8rOiQvIUCv7RRErTaWSfb+QVnKz6x7qlp8N86bGDiIg==", 30 | "dev": true, 31 | "dependencies": { 32 | "bun-types": "1.1.13" 33 | } 34 | }, 35 | "node_modules/@types/jsonwebtoken": { 36 | "version": "9.0.6", 37 | "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.6.tgz", 38 | "integrity": "sha512-/5hndP5dCjloafCXns6SZyESp3Ldq7YjH3zwzwczYnjxIT0Fqzk5ROSYVGfFyczIue7IUEj8hkvLbPoLQ18vQw==", 39 | "dev": true, 40 | "dependencies": { 41 | "@types/node": "*" 42 | } 43 | }, 44 | "node_modules/@types/node": { 45 | "version": "20.12.14", 46 | "dev": true, 47 | "license": "MIT", 48 | "dependencies": { 49 | "undici-types": "~5.26.4" 50 | } 51 | }, 52 | "node_modules/@types/uuid": { 53 | "version": "9.0.8", 54 | "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", 55 | "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", 56 | "dev": true 57 | }, 58 | "node_modules/@types/ws": { 59 | "version": "8.5.10", 60 | "dev": true, 61 | "license": "MIT", 62 | "dependencies": { 63 | "@types/node": "*" 64 | } 65 | }, 66 | "node_modules/asynckit": { 67 | "version": "0.4.0", 68 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 69 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" 70 | }, 71 | "node_modules/axios": { 72 | "version": "1.7.2", 73 | "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", 74 | "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", 75 | "dependencies": { 76 | "follow-redirects": "^1.15.6", 77 | "form-data": "^4.0.0", 78 | "proxy-from-env": "^1.1.0" 79 | } 80 | }, 81 | "node_modules/buffer-equal-constant-time": { 82 | "version": "1.0.1", 83 | "license": "BSD-3-Clause" 84 | }, 85 | "node_modules/bun-types": { 86 | "version": "1.1.13", 87 | "dev": true, 88 | "license": "MIT", 89 | "dependencies": { 90 | "@types/node": "~20.12.8", 91 | "@types/ws": "~8.5.10" 92 | } 93 | }, 94 | "node_modules/chalk": { 95 | "version": "5.3.0", 96 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", 97 | "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", 98 | "engines": { 99 | "node": "^12.17.0 || ^14.13 || >=16.0.0" 100 | }, 101 | "funding": { 102 | "url": "https://github.com/chalk/chalk?sponsor=1" 103 | } 104 | }, 105 | "node_modules/combined-stream": { 106 | "version": "1.0.8", 107 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 108 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 109 | "dependencies": { 110 | "delayed-stream": "~1.0.0" 111 | }, 112 | "engines": { 113 | "node": ">= 0.8" 114 | } 115 | }, 116 | "node_modules/crypto": { 117 | "version": "1.0.1", 118 | "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", 119 | "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==", 120 | "deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in." 121 | }, 122 | "node_modules/delayed-stream": { 123 | "version": "1.0.0", 124 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 125 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", 126 | "engines": { 127 | "node": ">=0.4.0" 128 | } 129 | }, 130 | "node_modules/ecdsa-sig-formatter": { 131 | "version": "1.0.11", 132 | "license": "Apache-2.0", 133 | "dependencies": { 134 | "safe-buffer": "^5.0.1" 135 | } 136 | }, 137 | "node_modules/follow-redirects": { 138 | "version": "1.15.6", 139 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", 140 | "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", 141 | "funding": [ 142 | { 143 | "type": "individual", 144 | "url": "https://github.com/sponsors/RubenVerborgh" 145 | } 146 | ], 147 | "engines": { 148 | "node": ">=4.0" 149 | }, 150 | "peerDependenciesMeta": { 151 | "debug": { 152 | "optional": true 153 | } 154 | } 155 | }, 156 | "node_modules/form-data": { 157 | "version": "4.0.0", 158 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", 159 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", 160 | "dependencies": { 161 | "asynckit": "^0.4.0", 162 | "combined-stream": "^1.0.8", 163 | "mime-types": "^2.1.12" 164 | }, 165 | "engines": { 166 | "node": ">= 6" 167 | } 168 | }, 169 | "node_modules/hono": { 170 | "version": "4.4.6", 171 | "license": "MIT", 172 | "engines": { 173 | "node": ">=16.0.0" 174 | } 175 | }, 176 | "node_modules/ini": { 177 | "version": "4.1.3", 178 | "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", 179 | "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", 180 | "dev": true, 181 | "engines": { 182 | "node": "^14.17.0 || ^16.13.0 || >=18.0.0" 183 | } 184 | }, 185 | "node_modules/jsonwebtoken": { 186 | "version": "9.0.2", 187 | "license": "MIT", 188 | "dependencies": { 189 | "jws": "^3.2.2", 190 | "lodash.includes": "^4.3.0", 191 | "lodash.isboolean": "^3.0.3", 192 | "lodash.isinteger": "^4.0.4", 193 | "lodash.isnumber": "^3.0.3", 194 | "lodash.isplainobject": "^4.0.6", 195 | "lodash.isstring": "^4.0.1", 196 | "lodash.once": "^4.0.0", 197 | "ms": "^2.1.1", 198 | "semver": "^7.5.4" 199 | }, 200 | "engines": { 201 | "node": ">=12", 202 | "npm": ">=6" 203 | } 204 | }, 205 | "node_modules/jwa": { 206 | "version": "1.4.1", 207 | "license": "MIT", 208 | "dependencies": { 209 | "buffer-equal-constant-time": "1.0.1", 210 | "ecdsa-sig-formatter": "1.0.11", 211 | "safe-buffer": "^5.0.1" 212 | } 213 | }, 214 | "node_modules/jws": { 215 | "version": "3.2.2", 216 | "license": "MIT", 217 | "dependencies": { 218 | "jwa": "^1.4.1", 219 | "safe-buffer": "^5.0.1" 220 | } 221 | }, 222 | "node_modules/lodash.includes": { 223 | "version": "4.3.0", 224 | "license": "MIT" 225 | }, 226 | "node_modules/lodash.isboolean": { 227 | "version": "3.0.3", 228 | "license": "MIT" 229 | }, 230 | "node_modules/lodash.isinteger": { 231 | "version": "4.0.4", 232 | "license": "MIT" 233 | }, 234 | "node_modules/lodash.isnumber": { 235 | "version": "3.0.3", 236 | "license": "MIT" 237 | }, 238 | "node_modules/lodash.isplainobject": { 239 | "version": "4.0.6", 240 | "license": "MIT" 241 | }, 242 | "node_modules/lodash.isstring": { 243 | "version": "4.0.1", 244 | "license": "MIT" 245 | }, 246 | "node_modules/lodash.once": { 247 | "version": "4.1.1", 248 | "license": "MIT" 249 | }, 250 | "node_modules/mime-db": { 251 | "version": "1.52.0", 252 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 253 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 254 | "engines": { 255 | "node": ">= 0.6" 256 | } 257 | }, 258 | "node_modules/mime-types": { 259 | "version": "2.1.35", 260 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 261 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 262 | "dependencies": { 263 | "mime-db": "1.52.0" 264 | }, 265 | "engines": { 266 | "node": ">= 0.6" 267 | } 268 | }, 269 | "node_modules/ms": { 270 | "version": "2.1.3", 271 | "license": "MIT" 272 | }, 273 | "node_modules/proxy-from-env": { 274 | "version": "1.1.0", 275 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", 276 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" 277 | }, 278 | "node_modules/safe-buffer": { 279 | "version": "5.2.1", 280 | "funding": [ 281 | { 282 | "type": "github", 283 | "url": "https://github.com/sponsors/feross" 284 | }, 285 | { 286 | "type": "patreon", 287 | "url": "https://www.patreon.com/feross" 288 | }, 289 | { 290 | "type": "consulting", 291 | "url": "https://feross.org/support" 292 | } 293 | ], 294 | "license": "MIT" 295 | }, 296 | "node_modules/semver": { 297 | "version": "7.6.2", 298 | "license": "ISC", 299 | "bin": { 300 | "semver": "bin/semver.js" 301 | }, 302 | "engines": { 303 | "node": ">=10" 304 | } 305 | }, 306 | "node_modules/typescript": { 307 | "version": "5.4.5", 308 | "license": "Apache-2.0", 309 | "peer": true, 310 | "bin": { 311 | "tsc": "bin/tsc", 312 | "tsserver": "bin/tsserver" 313 | }, 314 | "engines": { 315 | "node": ">=14.17" 316 | } 317 | }, 318 | "node_modules/undici-types": { 319 | "version": "5.26.5", 320 | "dev": true, 321 | "license": "MIT" 322 | }, 323 | "node_modules/uuid": { 324 | "version": "10.0.0", 325 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", 326 | "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", 327 | "funding": [ 328 | "https://github.com/sponsors/broofa", 329 | "https://github.com/sponsors/ctavan" 330 | ], 331 | "bin": { 332 | "uuid": "dist/bin/uuid" 333 | } 334 | } 335 | } 336 | } 337 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nexa", 3 | "module": "src/index.ts", 4 | "type": "module", 5 | "devDependencies": { 6 | "@types/bun": "latest", 7 | "@types/jsonwebtoken": "^9.0.6", 8 | "@types/node": "^20.14.4", 9 | "@types/uuid": "^9.0.8", 10 | "ini": "^4.1.3" 11 | }, 12 | "peerDependencies": { 13 | "typescript": "^5.4.5" 14 | }, 15 | "dependencies": { 16 | "@types/ini": "^4.1.1", 17 | "axios": "^1.7.2", 18 | "bun-socket": "^0.0.1", 19 | "chalk": "^5.3.0", 20 | "crypto": "^1.0.1", 21 | "hono": "^4.4.6", 22 | "jsonwebtoken": "^9.0.2", 23 | "uuid": "^10.0.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/config/config.ini: -------------------------------------------------------------------------------- 1 | ; NEXA CONFIG 2 | 3 | ; Can be 2, 3, or 4 || SEASON OG STAGES 4 | RufusStage=4 5 | 6 | ; WATERLEVEL C2 S3 7 | 8 | ; VALUE SHOULD BE 1 - 7 9 | WaterLevel=1 -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { Hono } from "hono"; 2 | import path from "node:path"; 3 | import { loadRoutes } from "./utils/startup/loadRoutes"; 4 | import { Nexa } from "./utils/handlers/errors"; 5 | import logger from "./utils/logger/logger"; 6 | import { cors } from "hono/cors"; 7 | 8 | const app = new Hono({ strict: false }); 9 | 10 | export default app; 11 | 12 | app.use("*", cors()); 13 | 14 | app.notFound((c) => c.json(Nexa.basic.notFound, 404)); 15 | 16 | Bun.serve({ 17 | port: 5353, 18 | fetch: app.fetch, 19 | }); 20 | 21 | app.use(async (c, next) => { 22 | if (c.req.path === "/images/icons/gear.png" || c.req.path === "/favicon.ico") await next(); 23 | else { 24 | await next(); 25 | 26 | logger.backend(`${c.req.path} | ${c.req.method} | Status ${c.res.status}`); 27 | } 28 | }); 29 | 30 | await loadRoutes(path.join(__dirname, "routes"), app); 31 | 32 | logger.backend("Nexa started on port 5353"); 33 | -------------------------------------------------------------------------------- /src/routes/api.ts: -------------------------------------------------------------------------------- 1 | import app from ".."; 2 | import axios from "axios"; 3 | import path from "node:path"; 4 | import fs from "node:fs"; 5 | 6 | export default function () { 7 | app.post("/datarouter/api/v1/public/data", async (c) => { 8 | return c.json([]); 9 | }); 10 | 11 | app.get("/account/api/public/account/*/externalAuths", async (c) => { 12 | return c.json([]); 13 | }); 14 | 15 | app.get("/launcher/api/public/distributionpoints", (c) => { 16 | return c.json({ 17 | distributions: [ 18 | "https://epicgames-download1.akamaized.net/", 19 | "https://download.epicgames.com/", 20 | "https://download2.epicgames.com/", 21 | "https://download3.epicgames.com/", 22 | "https://download4.epicgames.com/", 23 | "https://nexa.ol.epicgames.com/", 24 | ], 25 | }); 26 | }); 27 | 28 | app.post("/api/v1/fortnite-br/interactions/contentHash", async (c) => { 29 | const body: any = c.req.json(); 30 | return c.json({ 31 | sessionId: body.sessionId, 32 | sessionStartTimestamp: body.sessionStartTimestamp, 33 | surfaces: [ 34 | { 35 | surfaceId: "br-motd", 36 | contentMeta: [ 37 | '{"c93adbc7a8a9f94a916de62aa443e2d6":["93eff180-1465-496e-9be4-c02ef810ad82"]}', 38 | ], 39 | events: [ 40 | { 41 | contentHash: "c93adbc7a8a9f94a916de62aa443e2d6", 42 | type: "impression", 43 | count: 1, 44 | timestamp: "2023-12-03T10:17:41.387Z", 45 | lastTimestamp: "2023-12-03T10:17:41.387Z", 46 | }, 47 | ], 48 | }, 49 | ], 50 | }); 51 | }); 52 | 53 | app.get("/fortnite/api/game/v2/world/info", async (c) => { 54 | return c.json({}); 55 | }); 56 | 57 | app.get("/unknown", async (c) => { 58 | return c.json([]); 59 | }); 60 | 61 | app.get("/api/v2/interactions/aggregated/Fortnite/:accountId", async (c) => { 62 | return c.json([]); 63 | }); 64 | 65 | app.get("/content-controls/:accountId", async (c) => { 66 | return c.json({ 67 | data: { 68 | ageGate: 0, 69 | controlsEnabled: false, 70 | maxEpicProfilePrivacy: "none", 71 | principalId: c.req.param("accountId"), 72 | }, 73 | }); 74 | }); 75 | 76 | app.get("/content-controls/:accountId/rules/namespaces/fn", async (c) => { 77 | return c.json([]); 78 | }); 79 | 80 | app.post("/content-controls/:accountId/verify-pin", async (c) => { 81 | return c.json({ 82 | data: { 83 | pinCorrect: true, 84 | }, 85 | }); 86 | }); 87 | 88 | app.get("/fortnite/api/game/v2/privacy/account/:accountId", async (c) => { 89 | return c.json({ 90 | accountId: c.req.param("accountId"), 91 | optOutOfPublicLeaderboards: false, 92 | }); 93 | }); 94 | 95 | app.post("/region/check", async (c) => { 96 | return c.json({ 97 | content_id: "AF9yLAAsklQALFTy", 98 | allowed: true, 99 | resolved: true, 100 | limit: "Res=656", 101 | }); 102 | }); 103 | 104 | app.get("/fortnite/api/game/v2/br-inventory/account", async (c) => { 105 | return c.json({ 106 | stash: { 107 | globalcash: 69, 108 | }, 109 | }); 110 | }); 111 | 112 | app.get( 113 | "/launcher/api/public/assets/:platform/:catalogItemId/:appName", 114 | async (c) => { 115 | const appName = c.req.param("appName"); 116 | const catalogItemId = c.req.param("catalogItemId"); 117 | const platform = c.req.param("platform"); 118 | const label = c.req.query("label"); 119 | return c.json({ 120 | appName: appName, 121 | labelName: `${label}-${platform}`, 122 | buildVersion: `nexa`, 123 | catalogItemId: catalogItemId, 124 | expires: "9988-09-23T23:59:59.999Z", 125 | items: { 126 | MANIFEST: { 127 | signature: "nexa", 128 | distribution: "http://localhost:5535/", 129 | path: `Builds/Fortnite/Content/CloudDir/Nexa.manifest`, 130 | additionalDistributions: [], 131 | }, 132 | }, 133 | assetId: appName, 134 | }); 135 | } 136 | ); 137 | 138 | app.get("/presence/api/v1/_/:accountId/settings/subscriptions", async (c) => { 139 | return c.json([]); 140 | }); 141 | 142 | app.all("/presence/api/v1/*", async (c) => { 143 | return c.json([]); 144 | }); 145 | 146 | app.get("/eulatracking/api/public/agreements/fn/account/*", async (c) => { 147 | return c.json([]); 148 | }); 149 | 150 | app.post("/datarouter/api/v1/public/data/clients", async (c) => { 151 | return c.json([]); 152 | }); 153 | 154 | app.post("/telemetry/data/datarouter/api/v1/public/data", async (c) => { 155 | return c.json([]); 156 | }); 157 | 158 | app.get("/Builds/Fortnite/Content/CloudDir/*", async (c: any) => { 159 | c.header("Content-Type", "application/octet-stream"); 160 | const manifest: any = await fs.promises.readFile( 161 | path.join(__dirname, "..", "..", "static", "assets", "Nexa.manifest") 162 | ); 163 | return c.body(manifest); 164 | }); 165 | 166 | app.get("/Builds/Fortnite/Content/CloudDir/*.ini", async (c: any) => { 167 | const ini: any = fs.readFileSync( 168 | path.join(__dirname, "..", "..", "static", "assets", "stuff.ini") 169 | ); 170 | return c.body(ini); 171 | }); 172 | 173 | app.get( 174 | "/Builds/Fortnite/Content/CloudDir/ChunksV4/:chunknum/*", 175 | async (c) => { 176 | const response = await axios.get( 177 | `https://epicgames-download1.akamaized.net${c.req.path}`, 178 | { 179 | responseType: "stream", 180 | } 181 | ); 182 | c.header("Content-Type", "application/octet-stream"); 183 | 184 | return c.body(response.data); 185 | } 186 | ); 187 | 188 | app.post("/fortnite/api/game/v2/grant_access/*", async (c) => { 189 | c.json({}); 190 | return c.status(204); 191 | }); 192 | 193 | app.get("/fortnite/api/game/v2/enabled_features", async (c) => { 194 | return c.json([]); 195 | }); 196 | 197 | app.post("/fortnite/api/game/v2/tryPlayOnPlatform/account/*", async (c) => { 198 | c.header("Content-Type", "text/plain"); 199 | return c.text("true"); 200 | }); 201 | 202 | app.get("/fortnite/api/v2/versioncheck/*", async (c) => { 203 | return c.json({ 204 | type: "NO_UPDATE", 205 | }); 206 | }); 207 | 208 | app.post("/api/v1/user/setting", async (c) => { 209 | return c.json({}); 210 | }); 211 | 212 | app.get("/fortnite/api/receipts/v1/account/*/receipts", async (c) => { 213 | return c.json([]); 214 | }); 215 | 216 | app.get("/account/api/public/account/:accountId/externalAuths", async (c) => { 217 | c.status(204); 218 | return c.json({}); 219 | }); 220 | 221 | app.post("/fortnite/api/game/v2/tryPlayOnPlatform/account/*", async (c) => { 222 | c.header("Content-Type", "text/plain"); 223 | return c.text("true"); 224 | }); 225 | 226 | app.get("/socialban/api/public/v1/:accountId", async (c) => { 227 | return c.json({}); 228 | }); 229 | 230 | app.get( 231 | "/eulatracking/api/public/agreements/fn/account/:accountId", 232 | async (c) => { 233 | return c.json({}); 234 | } 235 | ); 236 | 237 | app.get("/fortnite/api/game/v2/creative/*", async (c) => { 238 | return c.json({}); 239 | }); 240 | 241 | app.get("/content-controls/:accountId", async (c) => { 242 | return c.json({}); 243 | }); 244 | 245 | app.get("/content-controls/:accountId/rules/namespaces/fn", async (c) => { 246 | return c.json({}); 247 | }); 248 | 249 | app.post("/content-controls/:accountId/verify-pin", async (c) => { 250 | return c.json({}); 251 | }); 252 | 253 | app.get("/api/v2/interactions/aggregated/Fortnite/:accountId", async (c) => { 254 | return c.json({}); 255 | }); 256 | 257 | app.get("/api/v1/namespace/fn/worlds/accessibleTo/:accountid", async (c) => { 258 | return c.json({}); 259 | }); 260 | 261 | app.get("/api/v1/namespace/fn/worlds/accessibleTo/:accountID", async (c) => { 262 | return c.json({}); 263 | }); 264 | 265 | app.post("/api/v1/namespace/fn/worlds/account/:accountId", async (c) => { 266 | return c.json({}); 267 | }); 268 | } 269 | -------------------------------------------------------------------------------- /src/routes/cloudstorage.ts: -------------------------------------------------------------------------------- 1 | import app from ".."; 2 | import crypto from "crypto"; 3 | import fs from "node:fs"; 4 | import path from "node:path"; 5 | import getVersion from "../utils/handlers/getVersion"; 6 | 7 | export default function () { 8 | app.get("/fortnite/api/cloudstorage/system", async (c) => { 9 | try { 10 | const hotfixesDir = path.join(__dirname, "../../static/hotfixes"); 11 | const csFiles: any = []; 12 | 13 | fs.readdirSync(hotfixesDir).forEach((file) => { 14 | const filePath = path.join(hotfixesDir, file); 15 | const f = fs.readFileSync(filePath); 16 | const fileStat = fs.statSync(filePath); 17 | 18 | csFiles.push({ 19 | uniqueFilename: file, 20 | filename: file, 21 | hash: crypto.createHash("sha1").update(f).digest("hex"), 22 | hash256: crypto.createHash("sha256").update(f).digest("hex"), 23 | length: fileStat.size, 24 | contentType: "application/octet-stream", 25 | uploaded: new Date().toISOString(), 26 | storageType: "S3", 27 | storageIds: {}, 28 | doNotCache: true, 29 | }); 30 | }); 31 | 32 | return c.json(csFiles); 33 | } catch (err) { 34 | console.error("Error fetching system cloudstorage:", err); 35 | return c.status(500); 36 | } 37 | }); 38 | 39 | app.get("/fortnite/api/cloudstorage/system/config", async (c) => { 40 | try { 41 | const hotfixesDir = path.join(__dirname, "../../static/hotfixes"); 42 | const csFiles: any = []; 43 | 44 | fs.readdirSync(hotfixesDir).forEach((file) => { 45 | const filePath = path.join(hotfixesDir, file); 46 | const f = fs.readFileSync(filePath); 47 | const fileStat = fs.statSync(filePath); 48 | 49 | csFiles.push({ 50 | uniqueFilename: file, 51 | filename: file, 52 | hash: crypto.createHash("sha1").update(f).digest("hex"), 53 | hash256: crypto.createHash("sha256").update(f).digest("hex"), 54 | length: fileStat.size, 55 | contentType: "application/octet-stream", 56 | uploaded: new Date().toISOString(), 57 | storageType: "S3", 58 | storageIds: {}, 59 | doNotCache: true, 60 | }); 61 | }); 62 | 63 | return c.json(csFiles); 64 | } catch (err) { 65 | console.error("Error fetching system config cloudstorage:", err); 66 | return c.status(500); 67 | } 68 | }); 69 | 70 | app.get("/fortnite/api/cloudstorage/system/:file", async (c) => { 71 | try { 72 | const version = getVersion(c); 73 | const filePath = path.join( 74 | __dirname, 75 | "../../static/hotfixes", 76 | c.req.param("file") 77 | ); 78 | let fileContent = fs.readFileSync(filePath, { encoding: "utf8" }); 79 | 80 | if (c.req.param("file") === "DefaultGame.ini") { 81 | const replacements: { 82 | [key: number]: { find: string; replace: string }; 83 | } = { 84 | 7.3: { 85 | find: "+FrontEndPlaylistData=(PlaylistName=Playlist_Music_Low, PlaylistAccess=(bEnabled=false, CategoryIndex=1, DisplayPriority=-999))", 86 | replace: 87 | "+FrontEndPlaylistData=(PlaylistName=Playlist_Music_Low, PlaylistAccess=(bEnabled=true, CategoryIndex=1, DisplayPriority=-999))", 88 | }, 89 | 7.4: { 90 | find: "+FrontEndPlaylistData=(PlaylistName=Playlist_Music_High, PlaylistAccess=(bEnabled=false, CategoryIndex=1, DisplayPriority=-999))", 91 | replace: 92 | "+FrontEndPlaylistData=(PlaylistName=Playlist_Music_High, PlaylistAccess=(bEnabled=true, CategoryIndex=1, DisplayPriority=-999))", 93 | }, 94 | 8.51: { 95 | find: "+FrontEndPlaylistData=(PlaylistName=Playlist_Music_Med, PlaylistAccess=(bEnabled=false, CategoryIndex=1, DisplayPriority=-999))", 96 | replace: 97 | "+FrontEndPlaylistData=(PlaylistName=Playlist_Music_Med, PlaylistAccess=(bEnabled=true, CategoryIndex=1, DisplayPriority=-999))", 98 | }, 99 | 9.4: { 100 | find: "+FrontEndPlaylistData=(PlaylistName=Playlist_Music_Higher, PlaylistAccess=(bEnabled=false, CategoryIndex=1, DisplayPriority=-999))", 101 | replace: 102 | "+FrontEndPlaylistData=(PlaylistName=Playlist_Music_Higher, PlaylistAccess=(bEnabled=true, CategoryIndex=1, DisplayPriority=-999))", 103 | }, 104 | 9.41: { 105 | find: "+FrontEndPlaylistData=(PlaylistName=Playlist_Music_Higher, PlaylistAccess=(bEnabled=false, CategoryIndex=1, DisplayPriority=-999))", 106 | replace: 107 | "+FrontEndPlaylistData=(PlaylistName=Playlist_Music_Higher, PlaylistAccess=(bEnabled=true, CategoryIndex=1, DisplayPriority=-999))", 108 | }, 109 | 10.4: { 110 | find: "+FrontEndPlaylistData=(PlaylistName=Playlist_Music_Highest, PlaylistAccess=(bEnabled=false, CategoryIndex=1, DisplayPriority=-999))", 111 | replace: 112 | "+FrontEndPlaylistData=(PlaylistName=Playlist_Music_Highest, PlaylistAccess=(bEnabled=true, CategoryIndex=1, DisplayPriority=-999))", 113 | }, 114 | 11.3: { 115 | find: "+FrontEndPlaylistData=(PlaylistName=Playlist_Music_Lowest, PlaylistAccess=(bEnabled=false, CategoryIndex=1, DisplayPriority=-999))", 116 | replace: 117 | "+FrontEndPlaylistData=(PlaylistName=Playlist_Music_Lowest, PlaylistAccess=(bEnabled=true, CategoryIndex=1, DisplayPriority=-999))", 118 | }, 119 | 12.41: { 120 | find: "+FrontEndPlaylistData=(PlaylistName=Playlist_Music_High, PlaylistAccess=(bEnabled=false, CategoryIndex=1, DisplayPriority=-999))", 121 | replace: 122 | "+FrontEndPlaylistData=(PlaylistName=Playlist_Music_High, PlaylistAccess=(bEnabled=true, CategoryIndex=1, DisplayPriority=-999))", 123 | }, 124 | 12.61: { 125 | find: "+FrontEndPlaylistData=(PlaylistName=Playlist_Fritter_64, PlaylistAccess=(bEnabled=false, CategoryIndex=1, DisplayPriority=-999))", 126 | replace: 127 | "+FrontEndPlaylistData=(PlaylistName=Playlist_Fritter_64, PlaylistAccess=(bEnabled=true, CategoryIndex=1, DisplayPriority=-999))", 128 | }, 129 | }; 130 | 131 | const replacement = replacements[version.build]; 132 | if (replacement) { 133 | fileContent = fileContent.replace( 134 | replacement.find, 135 | replacement.replace 136 | ); 137 | } 138 | } 139 | 140 | return c.text(fileContent); 141 | } catch (err) { 142 | console.error("Error fetching system file:", err); 143 | return c.notFound(); 144 | } 145 | }); 146 | 147 | app.get("/fortnite/api/cloudstorage/user/:accountId", async (c) => { 148 | const accountId = c.req.param("accountId"); 149 | try { 150 | let clientSettingsPath = path.join( 151 | __dirname, 152 | "..", 153 | "..", 154 | "static", 155 | "ClientSettings" 156 | ); 157 | if (!fs.existsSync(clientSettingsPath)) fs.mkdirSync(clientSettingsPath); 158 | 159 | const ver = getVersion(c); 160 | 161 | let file = path.join( 162 | clientSettingsPath, 163 | `ClientSettings-${ver.season}.Sav` 164 | ); 165 | 166 | if (fs.existsSync(file)) { 167 | const ParsedFile = fs.readFileSync(file, "latin1"); 168 | const ParsedStats = fs.statSync(file); 169 | 170 | return c.json([ 171 | { 172 | uniqueFilename: "ClientSettings.Sav", 173 | filename: "ClientSettings.Sav", 174 | hash: crypto.createHash("sha1").update(ParsedFile).digest("hex"), 175 | hash256: crypto 176 | .createHash("sha256") 177 | .update(ParsedFile) 178 | .digest("hex"), 179 | length: Buffer.byteLength(ParsedFile), 180 | contentType: "application/octet-stream", 181 | uploaded: ParsedStats.mtime, 182 | storageType: "S3", 183 | storageIds: {}, 184 | accountId: accountId, 185 | doNotCache: false, 186 | }, 187 | ]); 188 | } 189 | 190 | return c.json([]); 191 | } catch (err) { 192 | console.error("Error fetching user cloudstorage:", err); 193 | c.status(500); 194 | return c.json([]); 195 | } 196 | }); 197 | 198 | app.put("/fortnite/api/cloudstorage/user/:accountId/:file", async (c) => { 199 | const filename = c.req.param("file"); 200 | 201 | const clientSettingsPath = path.join( 202 | __dirname, 203 | "..", 204 | "..", 205 | "static", 206 | "ClientSettings" 207 | ); 208 | 209 | if (!fs.existsSync(clientSettingsPath)) { 210 | fs.mkdirSync(clientSettingsPath, { recursive: true }); 211 | } 212 | 213 | if (filename.toLowerCase() !== "clientsettings.sav") { 214 | return c.json([]); 215 | } 216 | 217 | const ver = getVersion(c); 218 | 219 | const file = path.join( 220 | clientSettingsPath, 221 | `ClientSettings-${ver.season}.Sav` 222 | ); 223 | 224 | try { 225 | const body = await c.req.arrayBuffer(); 226 | 227 | fs.writeFileSync(file, Buffer.from(body), "latin1"); 228 | 229 | return c.json([]); 230 | } catch (error) { 231 | console.error("Error writing the file:", error); 232 | 233 | return c.json({ error: "Failed to save the settings" }, 500); 234 | } 235 | }); 236 | 237 | app.get("/fortnite/api/cloudstorage/user/:accountId/:file", async (c) => { 238 | const clientSettingsPath = path.join( 239 | __dirname, 240 | "..", 241 | "..", 242 | "static", 243 | "ClientSettings" 244 | ); 245 | 246 | if (!fs.existsSync(clientSettingsPath)) { 247 | fs.mkdirSync(clientSettingsPath); 248 | } 249 | 250 | const ver = getVersion(c); 251 | 252 | const file = path.join( 253 | clientSettingsPath, 254 | `ClientSettings-${ver.season}.Sav` 255 | ); 256 | 257 | if (fs.existsSync(file)) return c.body(fs.readFileSync(file) as any); 258 | 259 | return c.json([]); 260 | }); 261 | } 262 | -------------------------------------------------------------------------------- /src/routes/data.ts: -------------------------------------------------------------------------------- 1 | import app from "../index"; 2 | import axios from "axios"; 3 | import getVersion from "../utils/handlers/getVersion"; 4 | 5 | export default function () { 6 | app.get("/content/api/pages/fortnite-game", async (c) => { 7 | const version = getVersion(c); 8 | const game: any = await axios.get( 9 | "https://fortnitecontent-website-prod07.ol.epicgames.com/content/api/pages/fortnite-game", 10 | ); 11 | let content: any = game.data; 12 | 13 | content = Object.assign( 14 | {}, 15 | content, 16 | { 17 | emergencynotice: { 18 | news: { 19 | platform_messages: [], 20 | _type: "Battle Royale News", 21 | messages: [ 22 | { 23 | hidden: false, 24 | _type: "CommonUI Simple Message Base", 25 | subgame: "br", 26 | body: "Made by Itztiva \nDiscord: https://discord.gg/nexa-1229545680641462282", 27 | title: "Nexa", 28 | spotlight: false, 29 | }, 30 | ], 31 | }, 32 | "jcr:isCheckedOut": true, 33 | _title: "emergencynotice", 34 | _noIndex: false, 35 | alwaysShow: true, 36 | "jcr:baseVersion": "a7ca237317f1e761d4ee60-7c40-45a8-aa3e-bb0a2ffa9bb5", 37 | _activeDate: "2018-08-06T19:00:26.217Z", 38 | lastModified: "2020-10-30T04:50:59.198Z", 39 | _locale: "en-US", 40 | }, 41 | }, 42 | { 43 | emergencynoticev2: { 44 | "jcr:isCheckedOut": true, 45 | _title: "emergencynoticev2", 46 | _noIndex: false, 47 | emergencynotices: { 48 | _type: "Emergency Notices", 49 | emergencynotices: [ 50 | { 51 | hidden: false, 52 | _type: "CommonUI Emergency Notice Base", 53 | title: "Nexa", 54 | body: "Made by Itztiva \nDiscord: https://discord.gg/nexa-1229545680641462282", 55 | }, 56 | ], 57 | }, 58 | _activeDate: "2018-08-06T19:00:26.217Z", 59 | lastModified: "2021-03-17T15:07:27.924Z", 60 | _locale: "en-US", 61 | }, 62 | battleroyalenewsv2: { 63 | news: { 64 | motds: [ 65 | { 66 | entryType: "Website", 67 | image: 68 | "https://media.discordapp.net/attachments/1241535588394471545/1251931646555324426/Izdelek_brez_naslova_33.png?ex=66705fb4&is=666f0e34&hm=730eb730ea6523eabe6ec8956c9d1fcb06719189f0dbf76358c1f9c55b366143&=&format=webp&quality=lossless&width=1200&height=389", 69 | tileImage: 70 | "https://media.discordapp.net/attachments/1241535588394471545/1251931646555324426/Izdelek_brez_naslova_33.png?ex=66705fb4&is=666f0e34&hm=730eb730ea6523eabe6ec8956c9d1fcb06719189f0dbf76358c1f9c55b366143&=&format=webp&quality=lossless&width=1200&height=389", 71 | videoMute: false, 72 | hidden: false, 73 | tabTitleOverride: "Nexa", 74 | _type: "CommonUI Simple Message MOTD", 75 | title: "Nexa", 76 | body: "Made by Itztiva \nDiscord: https://discord.gg/nexa-1229545680641462282", 77 | videoLoop: false, 78 | videoStreamingEnabled: false, 79 | sortingPriority: 0, 80 | id: "NexaNewsBR", 81 | videoAutoplay: false, 82 | videoFullscreen: false, 83 | spotlight: false, 84 | websiteURL: "https://discord.gg/nexa-1229545680641462282", 85 | websiteButtonText: "Join our discord", 86 | }, 87 | ], 88 | }, 89 | "jcr:isCheckedOut": true, 90 | _title: "battleroyalenewsv2", 91 | header: "", 92 | style: "None", 93 | _noIndex: false, 94 | alwaysShow: false, 95 | "jcr:baseVersion": "a7ca237317f1e704b1a186-6846-4eaa-a542-c2c8ca7e7f29", 96 | _activeDate: "2020-01-21T14:00:00.000Z", 97 | lastModified: "2021-02-10T23:57:48.837Z", 98 | _locale: "en-US", 99 | }, 100 | }, 101 | ); 102 | 103 | if (version.build == 7.4) { 104 | const playlist = content.playlistinformation.playlist_info.playlists; 105 | 106 | for (let i = 0; i < playlist.length; i++) { 107 | if ( 108 | playlist[i].image === 109 | "https://cdn2.unrealengine.com/Fortnite/fortnite-game/playlistinformation/v12/12BR_Cyclone_Astronomical_PlaylistTile_Main-1024x512-ab95f8d30d0742ba1759403320a08e4ea6f0faa0.jpg" && 110 | playlist[i].playlist_name === "Playlist_Music_High" && 111 | playlist[i].description === 112 | "Drop into Sweaty Sands for the ride of your life. (Photosensitivity Warning)" && 113 | playlist[i].display_name === "Travis Scott’s Astronomical" 114 | ) { 115 | playlist[i].image = "https://i.imgur.com/3xoXe4R.png"; 116 | playlist[i].description = 117 | "Fan-made Fortnite Live Event. Not endorsed by Epic Games. Drop into the water planet and enjoy the show.\nEvent Made by bigboitaj2005tajypoo(@jalzod), sizzyleaks & Era Dev Team(@ProjectEraFN)"; 118 | playlist[i].display_name = "ERA FESTIVAL"; 119 | } 120 | } 121 | } 122 | 123 | if (version.build == 8.51) { 124 | const playlist = content.playlistinformation.playlist_info.playlists; 125 | 126 | for (let i = 0; i < playlist.length; i++) { 127 | if ( 128 | playlist[i].image === 129 | "https://cdn2.unrealengine.com/Fortnite/fortnite-game/playlistinformation/v12/12BR_Cyclone_Astronomical_PlaylistTile_Main-1024x512-ab95f8d30d0742ba1759403320a08e4ea6f0faa0.jpg" && 130 | playlist[i].playlist_name === "Playlist_Music_High" && 131 | playlist[i].description === 132 | "Drop into Sweaty Sands for the ride of your life. (Photosensitivity Warning)" && 133 | playlist[i].display_name === "Travis Scott’s Astronomical" 134 | ) { 135 | playlist[i].image = 136 | "https://static.wikia.nocookie.net/fortnite/images/1/1b/Breakthrough_%28Full%29_-_Loading_Screen_-_Fortnite.png/revision/latest/scale-to-width-down/1000?cb=20211112181350"; 137 | playlist[i].description = "The choice is yours!"; 138 | playlist[i].display_name = "The Unvaulting"; 139 | } 140 | } 141 | } 142 | 143 | if (version.build == 9.4 || version.build == 9.41) { 144 | const playlist = content.playlistinformation.playlist_info.playlists; 145 | 146 | for (let i = 0; i < playlist.length; i++) { 147 | if ( 148 | playlist[i].image === 149 | "https://cdn2.unrealengine.com/Fortnite/fortnite-game/playlistinformation/v12/12BR_Cyclone_Astronomical_PlaylistTile_Main-1024x512-ab95f8d30d0742ba1759403320a08e4ea6f0faa0.jpg" && 150 | playlist[i].playlist_name === "Playlist_Music_High" && 151 | playlist[i].description === 152 | "Drop into Sweaty Sands for the ride of your life. (Photosensitivity Warning)" && 153 | playlist[i].display_name === "Travis Scott’s Astronomical" 154 | ) { 155 | playlist[i].image = 156 | "https://i.kinja-img.com/image/upload/c_fit,q_60,w_1315/c0wwjgqh8weurqve8zkb.jpg0"; 157 | playlist[i].description = 158 | "Initiate Island Defense Protocol. Emergency hyperfuel jetpacks have been granted. Take to the skies and find cover on sky platforms."; 159 | playlist[i].display_name = "The Final Showdown"; 160 | } 161 | } 162 | } 163 | 164 | if (version.season === 10) { 165 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "seasonx"; 166 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = ""; 167 | } else if (version.season === 11) { 168 | if (version.build === 11.31 || version.build === 11.4) { 169 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "Winter19"; 170 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = ""; 171 | } else { 172 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "season11"; 173 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = ""; 174 | } 175 | } else if (version.season === 12) { 176 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "season12"; 177 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = ""; 178 | } else if (version.season === 13) { 179 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "season13"; 180 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = ""; 181 | } else if (version.season === 14) { 182 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "season14"; 183 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = ""; 184 | } else if (version.season === 15) { 185 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "season15"; 186 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = ""; 187 | 188 | if (version.build === 15.1) { 189 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "season15xmas"; 190 | content.dynamicbackgrounds.backgrounds.backgrounds[1].stage = "XmasStore2020"; 191 | } 192 | } else if (version.season === 16) { 193 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "season16"; 194 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = ""; 195 | } else if (version.season === 17) { 196 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "season17"; 197 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = ""; 198 | } else if (version.season === 18) { 199 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "season18"; 200 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = ""; 201 | } else if (version.season === 19) { 202 | if (version.build === 19.01) { 203 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "winter2021"; 204 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = 205 | "https://cdn2.unrealengine.com/t-bp19-lobby-xmas-2048x1024-f85d2684b4af.png"; 206 | } else { 207 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "season19"; 208 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = ""; 209 | } 210 | } else if (version.season === 20) { 211 | if (version.build === 20.4) { 212 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "season20"; 213 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = 214 | "https://cdn2.unrealengine.com/t-bp20-40-armadillo-glowup-lobby-2048x2048-2048x2048-3b83b887cc7f.jpg"; 215 | } else { 216 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "season20"; 217 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = 218 | "https://cdn2.unrealengine.com/s20-landscapev4-2048x1024-2494a103ae6c.png"; 219 | } 220 | } else if (version.season === 21) { 221 | if (version.build === 21.3) { 222 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "season2130"; 223 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = 224 | "https://cdn2.unrealengine.com/nss-lobbybackground-2048x1024-f74a14565061.jpg"; 225 | } else { 226 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "season2100"; 227 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = 228 | "https://cdn2.unrealengine.com/s21-lobby-background-2048x1024-2e7112b25dc3.jpg"; 229 | } 230 | } else if (version.season === 22) { 231 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = 232 | "https://cdn2.unrealengine.com/t-bp22-lobby-square-2048x2048-2048x2048-e4e90c6e8018.jpg"; 233 | } else if (version.season === 23) { 234 | if (version.build === 23.1) { 235 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = 236 | "https://cdn2.unrealengine.com/t-bp23-winterfest-lobby-square-2048x2048-2048x2048-277a476e5ca6.png"; 237 | } else { 238 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = 239 | "https://cdn2.unrealengine.com/t-bp23-lobby-2048x1024-2048x1024-26f2c1b27f63.png"; 240 | } 241 | } else if (version.season === 24) { 242 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "defaultnotris"; 243 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = 244 | "https://static.wikia.nocookie.net/fortnite/images/e/e7/Chapter_4_Season_2_-_Lobby_Background_-_Fortnite.png"; 245 | } else if (version.season === 25) { 246 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "defaultnotris"; 247 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = 248 | "https://static.wikia.nocookie.net/fortnite/images/c/ca/Chapter_4_Season_3_-_Lobby_Background_-_Fortnite.png"; 249 | } else if (version.season === 26) { 250 | if (version.build === 26.3) { 251 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "season2630"; 252 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = 253 | "https://cdn2.unrealengine.com/s26-lobby-timemachine-final-2560x1440-a3ce0018e3fa.jpg"; 254 | } else { 255 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "season2600"; 256 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = 257 | "https://cdn2.unrealengine.com/0814-ch4s4-lobby-2048x1024-2048x1024-e3c2cf8d342d.png"; 258 | } 259 | } else if (version.season === 27) { 260 | if (version.build === 27.11) { 261 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "defaultnotris"; 262 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = 263 | "https://cdn2.unrealengine.com/durianlobby2-4096x2048-242a51b6a8ee.jpg"; 264 | } else { 265 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "season2700"; 266 | } 267 | } else if (version.season === 28) { 268 | if (version.build === 28.2) { 269 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "defaultnotris"; 270 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = 271 | "https://cdn2.unrealengine.com/s28-tmnt-lobby-4096x2048-e6c06a310c05.jpg"; 272 | } else { 273 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = 274 | "https://cdn2.unrealengine.com/ch5s1-lobbybg-3640x2048-0974e0c3333c.jpg"; 275 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "defaultnotris"; 276 | } 277 | } else if (version.season === 29) { 278 | if (version.build === 29.2) { 279 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "defaultnotris"; 280 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = 281 | "https://cdn2.unrealengine.com/iceberg-lobby-3840x2160-217bb6ea8af9.jpg"; 282 | } else if (version.build === 29.4) { 283 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "defaultnotris"; 284 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = 285 | "https://cdn2.unrealengine.com/mkart-2940-sw-fnbr-lobby-3840x2160-4f1f1486a54a.jpg"; 286 | } else { 287 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "defaultnotris"; 288 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = 289 | "https://cdn2.unrealengine.com/br-lobby-ch5s2-4096x2304-a0879ccdaafc.jpg"; 290 | } 291 | } else if (version.season === 29) { 292 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = "season3100"; 293 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = 294 | "https://cdn2.unrealengine.com/ch5s4-lobbybg-final-2136x1202-e5885322faf1.jpg"; 295 | } else { 296 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage = ""; 297 | content.dynamicbackgrounds.backgrounds.backgrounds[0].backgroundimage; 298 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage = ""; 299 | content.dynamicbackgrounds.backgrounds.backgrounds[0].stage; 300 | } 301 | 302 | return c.json(content); 303 | }); 304 | // credits to neonite / hybridfnbr 305 | app.post("/api/v1/fortnite-br/surfaces/*/target", async (c) => { 306 | return c.json({ 307 | contentType: "collection", 308 | contentId: "fortnite-br-br-motd-collection", 309 | tcId: "8784961a-44e7-4fd5-82a6-8ef11e8c211d", 310 | contentMeta: '{"c93adbc7a8a9f94a916de62aa443e2d6":["93eff180-1465-496e-9be4-c02ef810ad82"]}', 311 | contentItems: [ 312 | { 313 | contentType: "content-item", 314 | contentId: "93eff180-1465-496e-9be4-c02ef810ad82", 315 | tcId: "5085a6fa-108c-4f0c-abdd-3259c6406890", 316 | contentFields: { 317 | Buttons: [ 318 | { 319 | Action: { 320 | _type: "MotdDiscoveryAction", 321 | category: "set_br_playlists", 322 | islandCode: "set_br_playlists", 323 | shouldOpen: true, 324 | }, 325 | Style: "0", 326 | Text: "Play Now", 327 | _type: "Button", 328 | }, 329 | ], 330 | FullScreenBackground: { 331 | Image: [ 332 | { 333 | width: 1920, 334 | height: 1080, 335 | url: "https://cdn1.epicgames.com/offer/fn/Blade_2560x1440_2560x1440-95718a8046a942675a0bc4d27560e2bb", 336 | }, 337 | { 338 | width: 960, 339 | height: 540, 340 | url: "https://cdn1.epicgames.com/offer/fn/Blade_2560x1440_2560x1440-95718a8046a942675a0bc4d27560e2bb", 341 | }, 342 | ], 343 | _type: "FullScreenBackground", 344 | }, 345 | FullScreenBody: "Made by Itztiva\nDiscord: https://discord.gg/idk", 346 | FullScreenTitle: "Nexa", 347 | TeaserBackground: { 348 | Image: [ 349 | { 350 | width: 1024, 351 | height: 512, 352 | url: "https://cdn1.epicgames.com/offer/fn/Blade_2560x1440_2560x1440-95718a8046a942675a0bc4d27560e2bb", 353 | }, 354 | ], 355 | _type: "TeaserBackground", 356 | }, 357 | TeaserTitle: "Nexa", 358 | VerticalTextLayout: false, 359 | }, 360 | contentSchemaName: "DynamicMotd", 361 | contentHash: "c93adbc7a8a9f94a916de62aa443e2d6", 362 | }, 363 | ], 364 | }); 365 | }); 366 | } 367 | -------------------------------------------------------------------------------- /src/routes/discovery.ts: -------------------------------------------------------------------------------- 1 | import app from ".."; 2 | import getVersion from "../utils/handlers/getVersion"; 3 | import { Nexa } from "../utils/handlers/errors"; 4 | import discoveryResponses from "../../static/discovery/events"; 5 | import path from "node:path"; 6 | import fs from "node:fs"; 7 | import crypto from "crypto"; 8 | 9 | export default function () { 10 | app.get("/fortnite/api/discovery/accessToken/*", async (c) => { 11 | const useragent: any = c.req.header("user-agent"); 12 | if (!useragent) return c.json(Nexa.internal.invalidUserAgent); 13 | const regex = useragent.match(/\+\+Fortnite\+Release-\d+\.\d+/); 14 | return c.json({ 15 | branchName: regex[0], 16 | appId: "Fortnite", 17 | token: `${crypto.randomBytes(10).toString("hex")}=`, 18 | }); 19 | }); 20 | 21 | app.post("/api/v2/discovery/surface/*", async (c) => { 22 | return c.json({ 23 | panels: [ 24 | { 25 | panelName: "Homebar_V3", 26 | panelDisplayName: "Test_EpicsPicksHomebar", 27 | featureTags: ["col:5", "homebar"], 28 | firstPage: { 29 | results: [ 30 | { 31 | lastVisited: null, 32 | linkCode: "reference_byepicnocompetitive_5", 33 | isFavorite: false, 34 | globalCCU: 1, 35 | }, 36 | ], 37 | hasMore: false, 38 | panelTargetName: null, 39 | }, 40 | panelType: "CuratedList", 41 | playHistoryType: null, 42 | }, 43 | { 44 | panelName: "ByEpicNoCompetitive", 45 | panelDisplayName: "By Epic", 46 | featureTags: ["col:5"], 47 | firstPage: { 48 | results: [ 49 | { 50 | lastVisited: null, 51 | linkCode: "set_br_playlists", 52 | isFavorite: false, 53 | globalCCU: 1, 54 | }, 55 | { 56 | lastVisited: null, 57 | linkCode: "playlist_durian", 58 | isFavorite: false, 59 | globalCCU: 1, 60 | }, 61 | { 62 | lastVisited: null, 63 | linkCode: "playlist_papaya", 64 | isFavorite: false, 65 | globalCCU: 1, 66 | }, 67 | { 68 | lastVisited: null, 69 | linkCode: "playlist_juno", 70 | isFavorite: false, 71 | globalCCU: 1, 72 | }, 73 | ], 74 | hasMore: true, 75 | panelTargetName: null, 76 | }, 77 | panelType: "AnalyticsList", 78 | playHistoryType: null, 79 | }, 80 | ], 81 | }); 82 | }); 83 | 84 | app.post("/api/v1/assets/Fortnite/*", async (c) => { 85 | const assets = { 86 | FortCreativeDiscoverySurface: { 87 | meta: { 88 | promotion: 26, 89 | }, 90 | assets: { 91 | CreativeDiscoverySurface_Frontend: { 92 | meta: { 93 | revision: 32, 94 | headRevision: 32, 95 | revisedAt: "2023-04-25T19:30:52.489Z", 96 | promotion: 26, 97 | promotedAt: "2023-04-25T19:31:12.618Z", 98 | }, 99 | assetData: { 100 | AnalyticsId: "v538", 101 | TestCohorts: [ 102 | { 103 | AnalyticsId: "c-1v2_v2_c727", 104 | CohortSelector: "PlayerDeterministic", 105 | PlatformBlacklist: [], 106 | CountryCodeBlocklist: [], 107 | ContentPanels: [ 108 | { 109 | NumPages: 1, 110 | AnalyticsId: "p1114", 111 | PanelType: "AnalyticsList", 112 | AnalyticsListName: "ByEpicNoBigBattle", 113 | CuratedListOfLinkCodes: [], 114 | ModelName: "", 115 | PageSize: 7, 116 | PlatformBlacklist: [], 117 | PanelName: "ByEpicNoBigBattle6Col", 118 | MetricInterval: "", 119 | CountryCodeBlocklist: [], 120 | SkippedEntriesCount: 0, 121 | SkippedEntriesPercent: 0, 122 | SplicedEntries: [], 123 | PlatformWhitelist: [], 124 | MMRegionBlocklist: [], 125 | EntrySkippingMethod: "None", 126 | PanelDisplayName: { 127 | Category: "Game", 128 | NativeCulture: "", 129 | Namespace: "CreativeDiscoverySurface_Frontend", 130 | LocalizedStrings: [], 131 | bIsMinimalPatch: false, 132 | NativeString: "LTMS", 133 | Key: "ByEpicNoBigBattle6Col", 134 | }, 135 | PlayHistoryType: "RecentlyPlayed", 136 | bLowestToHighest: false, 137 | PanelLinkCodeBlacklist: [], 138 | CountryCodeAllowlist: [], 139 | PanelLinkCodeWhitelist: [], 140 | FeatureTags: [], 141 | MMRegionAllowlist: [], 142 | MetricName: "", 143 | }, 144 | { 145 | NumPages: 2, 146 | AnalyticsId: "p969|88dba0c4e2af76447df43d1e31331a3d", 147 | PanelType: "AnalyticsList", 148 | AnalyticsListName: "EventPanel", 149 | CuratedListOfLinkCodes: [], 150 | ModelName: "", 151 | PageSize: 25, 152 | PlatformBlacklist: [], 153 | PanelName: "EventPanel", 154 | MetricInterval: "", 155 | CountryCodeBlocklist: [], 156 | SkippedEntriesCount: 0, 157 | SkippedEntriesPercent: 0, 158 | SplicedEntries: [], 159 | PlatformWhitelist: [], 160 | MMRegionBlocklist: [], 161 | EntrySkippingMethod: "None", 162 | PanelDisplayName: { 163 | Category: "Game", 164 | NativeCulture: "", 165 | Namespace: "CreativeDiscoverySurface_Frontend", 166 | LocalizedStrings: [], 167 | bIsMinimalPatch: false, 168 | NativeString: "Event LTMS", 169 | Key: "EventPanel", 170 | }, 171 | PlayHistoryType: "RecentlyPlayed", 172 | bLowestToHighest: false, 173 | PanelLinkCodeBlacklist: [], 174 | CountryCodeAllowlist: [], 175 | PanelLinkCodeWhitelist: [], 176 | FeatureTags: ["col:6"], 177 | MMRegionAllowlist: [], 178 | MetricName: "", 179 | }, 180 | ], 181 | PlatformWhitelist: [], 182 | SelectionChance: 0.1, 183 | TestName: "testing", 184 | }, 185 | ], 186 | GlobalLinkCodeBlacklist: [], 187 | SurfaceName: "CreativeDiscoverySurface_Frontend", 188 | TestName: "20.10_4/11/2022_hero_combat_popularConsole", 189 | primaryAssetId: "FortCreativeDiscoverySurface:CreativeDiscoverySurface_Frontend", 190 | GlobalLinkCodeWhitelist: [], 191 | }, 192 | }, 193 | }, 194 | }, 195 | }; 196 | 197 | return c.json(assets); 198 | }); 199 | 200 | app.post("/fortnite/api/game/v2/creative/discovery/surface/*", async (c) => { 201 | const Normal = require(`../../static/discovery/menu.json`); 202 | 203 | return c.json(Normal); 204 | }); 205 | 206 | app.post("/api/v1/discovery/surface/*", async (c) => { 207 | const Normal = require(`../../static/discovery/menu.json`); 208 | 209 | return c.json(Normal); 210 | }); 211 | 212 | app.post("/links/api/fn/mnemonic", async (c) => { 213 | const ver = getVersion(c); 214 | const Normal = require(`../../static/discovery/menu.json`); 215 | const Latest = require("../../static/discovery/latest/menu.json"); 216 | 217 | const DefaultLinks = Normal.Panels[0].Pages[0].results.map((result: any) => result.linkData); 218 | 219 | if (ver.build >= 23.5) { 220 | return c.json(Latest); 221 | } else { 222 | return c.json(DefaultLinks); 223 | } 224 | }); 225 | 226 | app.get("/links/api/fn/mnemonic/:playlistId/related", async (c) => { 227 | const playlistId = c.req.param("playlistId"); 228 | return c.json({ 229 | parentLinks: [], 230 | links: { 231 | [playlistId]: { 232 | namespace: "fn", 233 | accountId: "epic", 234 | creatorName: "Epic", 235 | mnemonic: playlistId, 236 | linkType: "BR:Playlist", 237 | metadata: { 238 | image_url: "", 239 | image_urls: { 240 | url_s: "", 241 | url_xs: "", 242 | url_m: "", 243 | url: "", 244 | }, 245 | matchmaking: { 246 | override_playlist: playlistId, 247 | }, 248 | }, 249 | version: 95, 250 | active: true, 251 | disabled: false, 252 | created: "2021-10-01T00:56:45.010Z", 253 | published: "2021-08-03T15:27:20.251Z", 254 | descriptionTags: [], 255 | moderationStatus: "Approved", 256 | }, 257 | }, 258 | }); 259 | }); 260 | } 261 | -------------------------------------------------------------------------------- /src/routes/eos.ts: -------------------------------------------------------------------------------- 1 | import app from ".."; 2 | 3 | export default function () { 4 | app.get("/epic/friends/v1/:accountId/blocklist", async (c) => { 5 | return c.json([]); 6 | }); 7 | 8 | app.all("/v1/epic-settings/public/users/*/values", async (c) => { 9 | return c.json({}); 10 | }); 11 | 12 | app.get("/epic/id/v2/sdk/accounts", async (c) => { 13 | const accountId = c.req.query("accountId"); 14 | return c.json([ 15 | { 16 | accountId: accountId, 17 | displayName: accountId, 18 | preferredLanguage: "en", 19 | cabinedMode: false, 20 | empty: false, 21 | }, 22 | ]); 23 | }); 24 | 25 | app.get("/sdk/v1/*", async (c) => { 26 | return c.json({ 27 | client: { 28 | "RateLimiter.InventoryClient": { 29 | MessageCount: 100, 30 | TimeIntervalInSeconds: 60.0, 31 | }, 32 | BaseService: { 33 | HttpRetryLimit: 4, 34 | HttpRetryResponseCodes: [429, 503, 504], 35 | }, 36 | "RateLimiter.AuthClient": { 37 | MessageCount: 300, 38 | TimeIntervalInSeconds: 60.0, 39 | }, 40 | "RateLimiter.PresenceClient.Operations": { 41 | MessageCount: 3, 42 | TimeIntervalInSeconds: 20.0, 43 | Operation: ["SendUpdate", "SetPresence"], 44 | }, 45 | "RateLimiter.ReceiptValidatorClient": { 46 | MessageCount: 300, 47 | TimeIntervalInSeconds: 60.0, 48 | }, 49 | "RateLimiter.LeaderboardsClient": { 50 | MessageCount: 300, 51 | TimeIntervalInSeconds: 60.0, 52 | }, 53 | "RateLimiter.MetricsClient": { 54 | MessageCount: 300, 55 | TimeIntervalInSeconds: 60.0, 56 | }, 57 | "RateLimiter.StatsClient": { 58 | MessageCount: 300, 59 | TimeIntervalInSeconds: 60.0, 60 | }, 61 | "RateLimiter.SDKConfigClient.Operations": { 62 | MessageCount: 300, 63 | TimeIntervalInSeconds: 60.0, 64 | Operation: ["RequestUpdate"], 65 | }, 66 | "RateLimiter.TitleStorageClient": { 67 | MessageCount: 300, 68 | TimeIntervalInSeconds: 60.0, 69 | }, 70 | "RateLimiter.EcomClient": { 71 | MessageCount: 300, 72 | TimeIntervalInSeconds: 60.0, 73 | }, 74 | "RateLimiter.DataStorageClient.Operations": { 75 | MessageCount: 300, 76 | TimeIntervalInSeconds: 60.0, 77 | Operation: [ 78 | "GetAccessLinks", 79 | "QueryFile", 80 | "QueryFileList", 81 | "CopyFile", 82 | "DeleteFile", 83 | "ReadFile", 84 | "WriteFile", 85 | "DownloadFileRedirected", 86 | "UploadFileRedirected", 87 | ], 88 | }, 89 | LeaderboardsClient: { 90 | MaxUserScoresQueryUserIds: 100, 91 | MaxUserScoresQueryStats: 25, 92 | }, 93 | "RateLimiter.CustomInvitesClient.Operations": { 94 | MessageCount: 50, 95 | TimeIntervalInSeconds: 60.0, 96 | Operation: ["SendCustomInvite"], 97 | }, 98 | HTTP: { 99 | HttpReceiveTimeout: 30, 100 | bEnableHttp: true, 101 | HttpTimeout: 30, 102 | HttpConnectionTimeout: 60, 103 | HttpSendTimeout: 30, 104 | MaxFlushTimeSeconds: 2.0, 105 | }, 106 | "RateLimiter.FriendClient.Operations": { 107 | MessageCount: 300, 108 | TimeIntervalInSeconds: 60.0, 109 | Operation: ["QueryFriends", "SendFriendInvite", "DeleteFriend"], 110 | }, 111 | "RateLimiter.RTCAdminClient": { 112 | MessageCount: 50, 113 | TimeIntervalInSeconds: 60.0, 114 | }, 115 | "RateLimiter.UserInfoClient": { 116 | MessageCount: 300, 117 | TimeIntervalInSeconds: 60.0, 118 | }, 119 | "/Script/Engine.NetworkSettings": { 120 | "n.VerifyPeer": false, 121 | }, 122 | "WebSockets.LibWebSockets": { 123 | ThreadStackSize: 131072, 124 | ThreadTargetFrameTimeInSeconds: 0.0333, 125 | ThreadMinimumSleepTimeInSeconds: 0.0, 126 | }, 127 | StatsClient: { 128 | MaxQueryStatsStatNamesStrLength: 1900, 129 | }, 130 | "RateLimiter.MetricsClient.Operations": { 131 | MessageCount: 300, 132 | TimeIntervalInSeconds: 60.0, 133 | Operation: ["RegisterPlayerBackendSession"], 134 | }, 135 | "RateLimiter.DataStorageClient": { 136 | MessageCount: 300, 137 | TimeIntervalInSeconds: 60.0, 138 | }, 139 | SanitizerClient: { 140 | ReplaceChar: "*", 141 | RequestLimit: 10, 142 | }, 143 | "RateLimiter.ModsClient.Operations": { 144 | MessageCount: 300, 145 | TimeIntervalInSeconds: 60.0, 146 | Operation: [ 147 | "InstallMod", 148 | "UninstallMod", 149 | "UpdateMod", 150 | "EnumerateMods", 151 | ], 152 | }, 153 | "RateLimiter.ReportsClient.Operations": { 154 | MessageCount: 100, 155 | TimeIntervalInSeconds: 60.0, 156 | Operation: ["SendPlayerBehaviorReport"], 157 | }, 158 | "RateLimiter.RTCAdminClient.Operations": { 159 | MessageCount: 50, 160 | TimeIntervalInSeconds: 60.0, 161 | Operation: ["QueryJoinRoomToken", "Kick", "SetParticipantHardMute"], 162 | }, 163 | "RateLimiter.FriendClient": { 164 | MessageCount: 300, 165 | TimeIntervalInSeconds: 60.0, 166 | }, 167 | "RateLimiter.AchievementsClient": { 168 | MessageCount: 100, 169 | TimeIntervalInSeconds: 60.0, 170 | }, 171 | LogFiles: { 172 | PurgeLogsDays: 5, 173 | MaxLogFilesOnDisk: 5, 174 | LogTimes: "SinceStart", 175 | }, 176 | RateLimiter: { 177 | MessageCount: 300, 178 | TimeIntervalInSeconds: 60.0, 179 | }, 180 | "RateLimiter.AntiCheatClient": { 181 | MessageCount: 120, 182 | TimeIntervalInSeconds: 60.0, 183 | }, 184 | "RateLimiter.ProgressionSnapshot": { 185 | MessageCount: 300, 186 | TimeIntervalInSeconds: 60.0, 187 | }, 188 | SessionsClient: { 189 | HeartbeatIntervalSecs: 30, 190 | }, 191 | "RateLimiter.UserInfoClient.Operations": { 192 | MessageCount: 300, 193 | TimeIntervalInSeconds: 60.0, 194 | Operation: [ 195 | "QueryLocalUserInfo", 196 | "QueryUserInfo", 197 | "QueryUserInfoByDisplayName", 198 | "QueryUserInfoByExternalAccount", 199 | ], 200 | }, 201 | LobbyClient: { 202 | InitialResendDelayMs: 100, 203 | MaxConnectionRetries: 3, 204 | LobbySocketURL: 205 | "wss://api.epicgames.dev/lobby/v1/`deploymentId/lobbies/connect", 206 | NumConsecutiveFailuresAllowed: 5, 207 | MaxResendDelayMs: 2000, 208 | WebSocketConnectTaskMaxNetworkWaitSeconds: 15.0, 209 | RecoveryWaitTimeSecs: 2, 210 | InitialRetryDelaySeconds: 5, 211 | MaxSendRetries: 3, 212 | SentMessageTimeout: 5, 213 | HeartbeatIntervalSecs: 30, 214 | MaxRetryIntervalSeconds: 15, 215 | }, 216 | "RateLimiter.SanctionsClient.Operations": { 217 | MessageCount: 300, 218 | TimeIntervalInSeconds: 60.0, 219 | Operation: ["QueryActivePlayerSanctions"], 220 | }, 221 | "UIClient.SocialURLQueryParamNames": { 222 | OSName: "os_name", 223 | ProductId: "product_id", 224 | SDKCLNumber: "sdk_cl_number", 225 | DeploymentId: "deployment_id", 226 | IntegratedPlatformName: "integrated_platform_name", 227 | SDKVersion: "sdk_version", 228 | OSVersion: "os_version", 229 | UserId: "user_id", 230 | ExchangeCode: "exchange_code", 231 | }, 232 | "RateLimiter.LobbyClient.ThrottledOperations": { 233 | MessageCount: 30, 234 | TimeIntervalInSeconds: 60.0, 235 | Operation: [ 236 | "CreateLobby", 237 | "DestroyLobby", 238 | "JoinLobby", 239 | "LeaveLobby", 240 | "HeartbeatLobby", 241 | "UpdateLobby", 242 | "PromoteMember", 243 | "KickLobbyMember", 244 | "SendLobbyInvite", 245 | "RejectLobbyInvite", 246 | "QueryInvites", 247 | "FindLobby", 248 | "RefreshRTCToken", 249 | "HardMuteMember", 250 | ], 251 | }, 252 | "RateLimiter.SessionsClient": { 253 | MessageCount: 300, 254 | TimeIntervalInSeconds: 60.0, 255 | }, 256 | "RateLimiter.KWSClient": { 257 | MessageCount: 20, 258 | TimeIntervalInSeconds: 60.0, 259 | }, 260 | "RateLimiter.PresenceClient": { 261 | MessageCount: 60, 262 | TimeIntervalInSeconds: 60.0, 263 | }, 264 | "RateLimiter.KWSClient.Operations": { 265 | MessageCount: 20, 266 | TimeIntervalInSeconds: 60.0, 267 | Operation: [ 268 | "CreateUser", 269 | "UpdateParentEmail", 270 | "QueryAgeGate", 271 | "QueryPermissions", 272 | "RequestPermissions", 273 | ], 274 | }, 275 | "RateLimiter.InventoryClient.Operations": { 276 | MessageCount: 100, 277 | TimeIntervalInSeconds: 60.0, 278 | Operation: ["Open", "Close"], 279 | }, 280 | "RateLimiter.LeaderboardsClient.Operations": { 281 | MessageCount: 300, 282 | TimeIntervalInSeconds: 60.0, 283 | Operation: [ 284 | "QueryLeaderboardDefinitions", 285 | "QueryLeaderboardRanks", 286 | "QueryLeaderboardUserScores", 287 | ], 288 | }, 289 | "RateLimiter.SanctionsClient": { 290 | MessageCount: 300, 291 | TimeIntervalInSeconds: 60.0, 292 | }, 293 | "Messaging.EpicConnect": { 294 | FailedConnectionDelayMultiplier: 2.5, 295 | ServerHeartbeatIntervalMilliseconds: 0, 296 | FailedConnectionDelayMaxSeconds: 180, 297 | ClientHeartbeatIntervalMilliseconds: 30000, 298 | FailedConnectionDelayIntervalSeconds: 5, 299 | Url: "wss://connect.epicgames.dev", 300 | }, 301 | MetricsClient: { 302 | HttpRetryLimit: 2, 303 | }, 304 | "RateLimiter.TitleStorageClient.Operations": { 305 | MessageCount: 300, 306 | TimeIntervalInSeconds: 60.0, 307 | Operation: ["QueryFile", "QueryFileList", "ReadFile"], 308 | }, 309 | "RateLimiter.AchievementsClient.Operations": { 310 | MessageCount: 100, 311 | TimeIntervalInSeconds: 60.0, 312 | Operation: [ 313 | "QueryDefinitions", 314 | "QueryPlayerAchievements", 315 | "UnlockAchievements", 316 | ], 317 | }, 318 | "Messaging.Stomp": { 319 | ClientHeartbeatIntervalMs: 30000, 320 | RequestedServerHeartbeatIntervalMs: 30000, 321 | Url: "wss://api.epicgames.dev/notifications/v1/`deploymentid`/connect", 322 | BlocklistMessageTypeFilters: ["lobbyinvite"], 323 | }, 324 | TitleStorageClient: { 325 | AccessLinkDurationSeconds: 300, 326 | UnusedCachedFileDaysToLive: 7, 327 | ClearInvalidFileCacheFrequencyDays: 2, 328 | MaxSimultaneousReads: 10, 329 | }, 330 | ConnectClient: { 331 | MaxProductUserIdMappingsQueryUserIds: 128, 332 | MinProductUserIdMappingsUpdateTimeInSeconds: 900.0, 333 | }, 334 | "RateLimiter.LobbyClient.Operations": { 335 | MessageCount: 100, 336 | TimeIntervalInSeconds: 60.0, 337 | Operation: ["GetByLobbyId", "UpdateLobby"], 338 | }, 339 | "RateLimiter.AntiCheatClient.Operations": { 340 | MessageCount: 120, 341 | TimeIntervalInSeconds: 60.0, 342 | Operation: ["QueryServiceStatus", "SendClientMessage"], 343 | }, 344 | EcomClient: { 345 | PurchaseUrl: 346 | "https://launcher-website-prod07.ol.epicgames.com/purchase", 347 | PurchaseCookieName: "EPIC_BEARER_TOKEN", 348 | PurchaseEpicIdUrl: 349 | "https://www.epicgames.com/ecom/payment/v1/purchase", 350 | }, 351 | "RateLimiter.SessionsClient.Operations": { 352 | MessageCount: 300, 353 | TimeIntervalInSeconds: 60.0, 354 | Operation: [ 355 | "UpdateSession", 356 | "JoinSession", 357 | "StartSession", 358 | "EndSession", 359 | "RegisterPlayers", 360 | "SendInvite", 361 | "RejectInvite", 362 | "QueryInvites", 363 | "FindSession", 364 | "DestroySession", 365 | ], 366 | }, 367 | "RateLimiter.StatsClient.Operations": { 368 | MessageCount: 300, 369 | TimeIntervalInSeconds: 60.0, 370 | Operation: ["IngestStat", "QueryStats"], 371 | }, 372 | "RateLimiter.ReceiptValidatorClient.Operations": { 373 | MessageCount: 300, 374 | TimeIntervalInSeconds: 60.0, 375 | Operation: ["VerifyPurchase"], 376 | }, 377 | DataStorageClient: { 378 | AccessLinkDurationSeconds: 300, 379 | MaxSimultaneousReads: 10, 380 | MaxSimultaneousWrites: 10, 381 | }, 382 | "RateLimiter.AuthClient.Operations": { 383 | MessageCount: 300, 384 | TimeIntervalInSeconds: 60.0, 385 | Operation: [ 386 | "VerifyAuth", 387 | "DeletePersistentAuth", 388 | "GenerateClientAuth", 389 | "LinkAccount", 390 | "QueryIdToken", 391 | "VerifyIdToken", 392 | ], 393 | }, 394 | P2PClient: { 395 | IceServers: [ 396 | "stun:stun.l.google.com:19302", 397 | "stun:turn.rtcp.on.epicgames.com:3478", 398 | "turn:turn.rtcp.on.epicgames.com:3478", 399 | ], 400 | P2PMinPort: 7777, 401 | P2PMaxPort: 7876, 402 | }, 403 | "RateLimiter.LobbyClient": { 404 | MessageCount: 30, 405 | TimeIntervalInSeconds: 60.0, 406 | }, 407 | SDKAnalytics: { 408 | BaseUrl: "https://api.epicgames.dev/telemetry/data/", 409 | DevPhase: 2, 410 | AppEnvironment: "Production", 411 | UploadType: "sdkevents", 412 | }, 413 | "RateLimiter.ConnectClient": { 414 | MessageCount: 300, 415 | TimeIntervalInSeconds: 60.0, 416 | }, 417 | "AntiCheat.GameplayData": { 418 | Url: "wss://api.epicgames.dev/cerberus-edge/v1/", 419 | }, 420 | AuthClient: { 421 | AccountPortalURLLocaleSuffix: "lang=`code", 422 | PollInterval: 5, 423 | RefreshTokenThreshold: 100.0, 424 | VPCRegisterURL: 425 | "https://epicgames.com/id/register/quick/minor/await?code=`challenge_id&display=embedded", 426 | AuthorizeContinuationEndpoint: 427 | "https://epicgames.com/id/login?continuation=`continuation&prompt=skip_merge%20skip_upgrade", 428 | AuthorizeCodeEndpoint: 429 | "https://epicgames.com/id/authorize?client_id=`client_id&response_type=code&scope=`scope&redirect_uri=`redirect_uri&display=popup&prompt=login", 430 | AuthorizeContinuationEmbeddedEndpoint: 431 | "https://epicgames.com/id/embedded/login?continuation=`continuation&prompt=skip_merge%20skip_upgrade", 432 | VerifyTokenInterval: 60.0, 433 | PollExpiresIn: 300, 434 | IdTokenCacheMinExpirySeconds: 300, 435 | AuthorizeEndpoint: 436 | "https://epicgames.com/id/authorize?exchange_code=`exchange_code&scope=`scope&prompt=skip_merge%20skip_upgrade", 437 | AccountPortalScheme: "eos.`client_id://epic/auth", 438 | bOfflineAccountToken: true, 439 | }, 440 | "RateLimiter.ProgressionSnapshot.Operations": { 441 | MessageCount: 300, 442 | TimeIntervalInSeconds: 60.0, 443 | Operation: ["SubmitSnapshot", "DeleteSnapshot"], 444 | }, 445 | XMPP: { 446 | bEnabled: true, 447 | bEnableWebsockets: true, 448 | ThreadStackSize: 131072, 449 | }, 450 | "RateLimiter.AntiCheatServer.Operations": { 451 | MessageCount: 100000, 452 | TimeIntervalInSeconds: 60.0, 453 | Operation: ["QueryServiceStatus", "SendClientMessage"], 454 | }, 455 | "Core.Log": { 456 | LogEOS: "verbose", 457 | LogEOSMessaging: "verbose", 458 | LogEOSConnect: "verbose", 459 | LogEOSAuth: "verbose", 460 | LogHttpSerialization: "verbose", 461 | LogCore: "verbose", 462 | LogHttp: "warning", 463 | LogStomp: "verbose", 464 | LogXmpp: "verbose", 465 | LogEOSSessions: "verbose", 466 | }, 467 | UIClient: { 468 | FriendsURL: 469 | "https://epic-social-game-overlay-prod.ol.epicgames.com/index.html", 470 | SocialSPAClientId: "cf27c69fe66441e8a8a4e8faf396ee4c", 471 | VPCURLLocaleSuffix: "&lang=`code", 472 | FriendsURLExchangeCodeSuffix: "?exchange_code=`exchange_code", 473 | VPCURL: 474 | "https://epicgames.com/id/overlay/quick/minor/verify?code=`challenge_id", 475 | }, 476 | "RateLimiter.AntiCheatServer": { 477 | MessageCount: 100000, 478 | TimeIntervalInSeconds: 60.0, 479 | }, 480 | "Messaging.XMPP": { 481 | ReconnectionDelayJitter: 1.5, 482 | PingTimeout: 30, 483 | ReconnectionDelayBase: 4.0, 484 | ServerPort: 443, 485 | bPrivateChatFriendsOnly: true, 486 | ReconnectionDelayMax: 300.0, 487 | Domain: "prod.ol.epicgames.com", 488 | ReconnectionDelayBackoffExponent: 2.0, 489 | ServerAddr: "wss://xmpp-service-prod.ol.epicgames.com", 490 | PingInterval: 60, 491 | }, 492 | "RateLimiter.SDKConfigClient": { 493 | MessageCount: 300, 494 | TimeIntervalInSeconds: 60.0, 495 | }, 496 | "RateLimiter.EcomClient.Operations": { 497 | MessageCount: 300, 498 | TimeIntervalInSeconds: 60.0, 499 | Operation: [ 500 | "QueryOwnership", 501 | "QueryOwnershipToken", 502 | "QueryEntitlement", 503 | "QueryOffer", 504 | "RedeemEntitlements", 505 | "Checkout", 506 | ], 507 | }, 508 | PresenceClient: { 509 | EpicConnectNotificationWaitTime: 99999995.0, 510 | PresenceQueryTimeoutSeconds: 1.0, 511 | bSetOfflineOnLogoutEnabled: false, 512 | PresenceAutoUpdateInSeconds: 999999600.0, 513 | bSetOfflineOnShutdownEnabled: false, 514 | }, 515 | "RateLimiter.CustomInvitesClient": { 516 | MessageCount: 50, 517 | TimeIntervalInSeconds: 60.0, 518 | }, 519 | "RateLimiter.ModsClient": { 520 | MessageCount: 300, 521 | TimeIntervalInSeconds: 60.0, 522 | }, 523 | "RateLimiter.ConnectClient.Operations": { 524 | MessageCount: 300, 525 | TimeIntervalInSeconds: 60.0, 526 | Operation: [ 527 | "LoginAccount", 528 | "CreateAccount", 529 | "LinkAccount", 530 | "UnlinkAccount", 531 | "CreateDeviceId", 532 | "DeleteDeviceId", 533 | "TransferDeviceIdAccount", 534 | "QueryExternalAccountMappings", 535 | "QueryProductUserIdMappings", 536 | "VerifyIdToken", 537 | ], 538 | }, 539 | "RateLimiter.AuthClient.SensitiveOperations": { 540 | MessageCount: 12, 541 | TimeIntervalInSeconds: 60.0, 542 | Operation: ["GenerateUserAuth"], 543 | }, 544 | "RateLimiter.ReportsClient": { 545 | MessageCount: 100, 546 | TimeIntervalInSeconds: 60.0, 547 | }, 548 | }, 549 | services: { 550 | RTCService: { 551 | BaseUrl: "https://api.epicgames.dev/rtc", 552 | }, 553 | DataStorageService: { 554 | BaseUrl: "https://api.epicgames.dev/datastorage", 555 | }, 556 | AccountsEpicIdService: { 557 | BaseUrl: "https://api.epicgames.dev", 558 | }, 559 | MetricsService: { 560 | BaseUrl: "https://api.epicgames.dev/datarouter", 561 | }, 562 | EcommerceService: { 563 | BaseUrl: 564 | "https://ecommerceintegration-public-service-ecomprod02.ol.epicgames.com/ecommerceintegration", 565 | }, 566 | KWSService: { 567 | BaseUrl: "https://api.epicgames.dev/kws", 568 | }, 569 | AntiCheatService: { 570 | BaseUrl: "https://api.epicgames.dev/anticheat", 571 | }, 572 | LobbyService: { 573 | BaseUrl: "https://api.epicgames.dev/lobby", 574 | }, 575 | StatsAchievementsService: { 576 | BaseUrl: "https://api.epicgames.dev/stats", 577 | }, 578 | PriceEngineService: { 579 | BaseUrl: 580 | "https://priceengine-public-service-ecomprod01.ol.epicgames.com/priceengine", 581 | }, 582 | AccountsService: { 583 | BaseUrl: "https://egp-idsoc-proxy-prod.ol.epicgames.com/account", 584 | RedirectUrl: "accounts.epicgames.com", 585 | }, 586 | EcommerceEpicIdService: { 587 | BaseUrl: "https://api.epicgames.dev/epic/ecom", 588 | }, 589 | PaymentEpicIdService: { 590 | BaseUrl: "https://api.epicgames.dev/epic/payment", 591 | }, 592 | SanctionsService: { 593 | BaseUrl: "https://api.epicgames.dev/sanctions", 594 | }, 595 | FriendService: { 596 | BaseUrl: "https://egp-idsoc-proxy-prod.ol.epicgames.com/friends", 597 | }, 598 | ReceiptValidatorService: { 599 | BaseUrl: "https://api.epicgames.dev/receipt-validator", 600 | }, 601 | FriendEpicIdService: { 602 | BaseUrl: "https://api.epicgames.dev/epic/friends", 603 | }, 604 | CatalogService: { 605 | BaseUrl: 606 | "https://catalog-public-service-prod06.ol.epicgames.com/catalog", 607 | }, 608 | EOSAuthService: { 609 | BaseUrl: "https://api.epicgames.dev", 610 | }, 611 | SessionsService: { 612 | BaseUrl: "https://api.epicgames.dev/matchmaking", 613 | }, 614 | ModsService: { 615 | BaseUrl: "https://api.epicgames.dev/mods", 616 | }, 617 | ReportsService: { 618 | BaseUrl: "https://api.epicgames.dev/player-reports", 619 | }, 620 | ProgressionSnapshotService: { 621 | BaseUrl: "https://api.epicgames.dev/snapshots", 622 | }, 623 | CustomInvitesService: { 624 | BaseUrl: "https://api.epicgames.dev/notifications", 625 | }, 626 | PresenceService: { 627 | BaseUrl: "https://api.epicgames.dev/epic/presence", 628 | }, 629 | TitleStorageService: { 630 | BaseUrl: "https://api.epicgames.dev/titlestorage", 631 | }, 632 | StatsIngestService: { 633 | BaseUrl: "https://api.epicgames.dev/ingestion/stats", 634 | }, 635 | LeaderboardsService: { 636 | BaseUrl: "https://api.epicgames.dev/leaderboards", 637 | }, 638 | InventoryService: { 639 | BaseUrl: "https://api.epicgames.dev/inventory", 640 | }, 641 | }, 642 | watermark: -934553538, 643 | }); 644 | }); 645 | } 646 | -------------------------------------------------------------------------------- /src/routes/habanero.ts: -------------------------------------------------------------------------------- 1 | import app from ".."; 2 | 3 | export default function () { 4 | app.get("/api/v1/games/fortnite/trackprogress/:accountId", async (c) => { 5 | return c.json([ 6 | { 7 | gameId: "fortnite", 8 | trackguid: "hEKWqj", 9 | accountId: c.req.param("accountId"), 10 | rankingType: "ranked-zb", 11 | lastUpdated: "1970-01-01T00:00:00Z", 12 | currentDivision: 0, 13 | highestDivision: 0, 14 | promotionProgress: 0, 15 | currentPlayerRanking: null, 16 | }, 17 | { 18 | gameId: "fortnite", 19 | trackguid: "OiK9k9", 20 | accountId: c.req.param("accountId"), 21 | rankingType: "ranked-br", 22 | lastUpdated: "2023-11-05T19:51:28.002Z", 23 | currentDivision: 9, 24 | highestDivision: 18, 25 | promotionProgress: 0.88, 26 | currentPlayerRanking: null, 27 | }, 28 | ]); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /src/routes/lightswitch.ts: -------------------------------------------------------------------------------- 1 | import app from ".."; 2 | 3 | // DO NOT CHANGE ANY OF THIS 4 | export default function () { 5 | app.get("/lightswitch/api/service/Fortnite/status", async (c) => { 6 | return c.json({ 7 | serviceInstanceId: "fortnite", 8 | status: "UP", 9 | message: "Fortnite is online", 10 | maintenanceUri: null, 11 | overrideCatalogIds: ["a7f138b2e51945ffbfdacc1af0541053"], 12 | allowedActions: [], 13 | banned: false, 14 | launcherInfoDTO: { 15 | appName: "Fortnite", 16 | catalogItemId: "4fe75bbc5a674f4f9b356b5c90567da5", 17 | namespace: "fn", 18 | }, 19 | }); 20 | }); 21 | 22 | app.get("/lightswitch/api/service/bulk/status", async (c) => { 23 | return c.json([ 24 | { 25 | serviceInstanceId: "fortnite", 26 | status: "UP", 27 | message: "fortnite is up.", 28 | maintenanceUri: null, 29 | overrideCatalogIds: ["a7f138b2e51945ffbfdacc1af0541053"], 30 | allowedActions: ["PLAY", "DOWNLOAD"], 31 | banned: false, 32 | launcherInfoDTO: { 33 | appName: "Fortnite", 34 | catalogItemId: "4fe75bbc5a674f4f9b356b5c90567da5", 35 | namespace: "fn", 36 | }, 37 | }, 38 | ]); 39 | }); 40 | } 41 | -------------------------------------------------------------------------------- /src/routes/matchmaking.ts: -------------------------------------------------------------------------------- 1 | import app from ".."; 2 | import jwt from "jsonwebtoken"; 3 | import getVersion from "../utils/handlers/getVersion"; 4 | 5 | export default function () { 6 | app.get("/waitingroom/api/waitingroom", async (c) => { 7 | return c.json([]); 8 | }); 9 | app.get("/fortnite/api/matchmaking/session/findPlayer/:id", async (c) => { 10 | return c.json([]); 11 | }); 12 | 13 | app.get("/fortnite/api/game/v2/matchmakingservice/ticket/player/*", async (c) => { 14 | const bucketId: any = c.req.query("bucketId"); 15 | const playerMatchmakingKey = c.req.query("player.option.customKey"); 16 | const playerPlaylist = bucketId.split(":")[3]; 17 | const playerRegion = bucketId.split(":")[2]; 18 | const ver = getVersion(c); 19 | 20 | const mmData = jwt.sign( 21 | { 22 | region: playerRegion, 23 | playlist: playerPlaylist, 24 | type: typeof playerMatchmakingKey === "string" ? "custom" : "normal", 25 | key: typeof playerMatchmakingKey === "string" ? playerMatchmakingKey : undefined, 26 | bucket: bucketId, 27 | version: `${ver.build}`, 28 | }, 29 | "LVe51Izk03lzceNf1ZGZs0glGx5tKh7f", 30 | ); 31 | var data = mmData.split("."); 32 | return c.json({ 33 | serviceUrl: "ws://127.0.0.1:5555", 34 | ticketType: "mms-player", 35 | payload: data[0] + "." + data[1], 36 | signature: undefined, 37 | }); 38 | }); 39 | 40 | app.post("/fortnite/api/matchmaking/session/:SessionId/join", async (c) => { 41 | return c.json([]); 42 | }); 43 | } 44 | -------------------------------------------------------------------------------- /src/routes/mcp.ts: -------------------------------------------------------------------------------- 1 | import app from ".."; 2 | import fs from "node:fs"; 3 | import path from "node:path"; 4 | import { v4 as uuidv4 } from "uuid"; 5 | 6 | const userpath = new Set(); 7 | const profilesDir = path.join(__dirname, "..", "..", "static", "profiles"); 8 | 9 | export default function () { 10 | app.post("/fortnite/api/game/v2/profile/:accountId/client/:operation", async (c) => { 11 | const body = await c.req.json(); 12 | let MultiUpdate: any = []; 13 | let profileChanges: any = []; 14 | let BaseRevision = 0; 15 | let profile: any; 16 | 17 | const query = c.req.query(); 18 | 19 | if (!query.profileId) { 20 | return c.text("Profile ID not found", 404); 21 | } 22 | 23 | const profileId = query.profileId; 24 | 25 | const files = fs.readdirSync(profilesDir); 26 | files.forEach((file) => { 27 | if (file.endsWith(".json")) { 28 | const profiles = require(path.join(profilesDir, file)); 29 | if (!profiles.rvn) profiles.rvn = 0; 30 | if (!profiles.items) profiles.items = {}; 31 | if (!profiles.stats) profiles.stats = {}; 32 | if (!profiles.stats.attributes) profiles.stats.attributes = {}; 33 | if (!profiles.commandRevision) profiles.commandRevision = 0; 34 | 35 | const profilePath = path.join(profilesDir, `profile_${profileId}.json`); 36 | 37 | if (!fs.existsSync(profilePath)) { 38 | fs.writeFileSync(profilePath, JSON.stringify(profiles, null, 2)); 39 | } 40 | 41 | if (file === `profile_${profileId}.json`) { 42 | profile = fs.existsSync(profilePath) 43 | ? JSON.parse(fs.readFileSync(profilePath, "utf8")) 44 | : profiles; 45 | } 46 | } 47 | }); 48 | 49 | BaseRevision = profile ? profile.rvn : 0; 50 | 51 | switch (c.req.param("operation")) { 52 | case "QueryProfile": 53 | break; 54 | case "RedeemRealMoneyPurchases": 55 | break; 56 | case "SetHardcoreModifier": 57 | break; 58 | case "AthenaPinQuest": 59 | break; 60 | case "MarkNewQuestNotificationSent": 61 | break; 62 | case "SetMtxPlatform": 63 | break; 64 | case "ClientQuestLogin": 65 | break; 66 | case "RefreshExpeditions": 67 | break; 68 | case "SetAffiliateName": 69 | const { affiliateName } = await c.req.json(); 70 | profile.stats.attributes.mtx_affiliate_set_time = new Date().toISOString(); 71 | profile.stats.attributes.mtx_affiliate = affiliateName; 72 | profileChanges.push({ 73 | changeType: "statModified", 74 | name: "mtx_affiliate_set_time", 75 | value: profile.stats.attributes.mtx_affiliate_set_time, 76 | }); 77 | 78 | profileChanges.push({ 79 | changeType: "statModified", 80 | name: "mtx_affiliate", 81 | value: profile.stats.attributes.mtx_affiliate, 82 | }); 83 | profile.rvn += 1; 84 | profile.commandRevision += 1; 85 | break; 86 | case "SetCosmeticLockerBanner": // br banner 2 87 | profile.stats.attributes.banner_icon = body.homebaseBannerIconId; 88 | profile.stats.attributes.banner_color = body.homebaseBannerColorId; 89 | 90 | profileChanges.push({ 91 | changeType: "statModified", 92 | name: "banner_icon", 93 | value: profile.stats.attributes.banner_icon, 94 | }); 95 | 96 | profileChanges.push({ 97 | changeType: "statModified", 98 | name: "banner_color", 99 | value: profile.stats.attributes.banner_color, 100 | }); 101 | profile.rvn += 1; 102 | profile.commandRevision += 1; 103 | break; 104 | case "SetBattleRoyaleBanner": // br banner 1 105 | profile.stats.attributes.banner_icon = body.homebaseBannerIconId; 106 | profile.stats.attributes.banner_color = body.homebaseBannerColorId; 107 | 108 | profileChanges.push({ 109 | changeType: "statModified", 110 | name: "banner_icon", 111 | value: profile.stats.attributes.banner_icon, 112 | }); 113 | 114 | profileChanges.push({ 115 | changeType: "statModified", 116 | name: "banner_color", 117 | value: profile.stats.attributes.banner_color, 118 | }); 119 | profile.rvn += 1; 120 | profile.commandRevision += 1; 121 | break; 122 | case "EquipBattleRoyaleCustomization": // br locker 1 123 | let statName; 124 | let itemToSlot; 125 | let itemToSlotID = body.itemToSlot; 126 | 127 | switch (body.slotName) { 128 | case "Character": 129 | statName = "favorite_character"; 130 | itemToSlot = body.itemToSlot; 131 | profile.stats.attributes[statName] = itemToSlot; 132 | profileChanges.push({ 133 | changeType: "statModified", 134 | name: statName, 135 | value: profile.stats.attributes[statName], 136 | }); 137 | break; 138 | case "Backpack": 139 | statName = "favorite_backpack"; 140 | itemToSlot = body.itemToSlot; 141 | profile.stats.attributes[statName] = itemToSlot; 142 | profileChanges.push({ 143 | changeType: "statModified", 144 | name: statName, 145 | value: profile.stats.attributes[statName], 146 | }); 147 | break; 148 | case "Pickaxe": 149 | statName = "favorite_pickaxe"; 150 | itemToSlot = body.itemToSlot; 151 | profile.stats.attributes[statName] = itemToSlot; 152 | profileChanges.push({ 153 | changeType: "statModified", 154 | name: statName, 155 | value: profile.stats.attributes[statName], 156 | }); 157 | break; 158 | case "Glider": 159 | statName = "favorite_glider"; 160 | itemToSlot = body.itemToSlot; 161 | profile.stats.attributes[statName] = itemToSlot; 162 | profileChanges.push({ 163 | changeType: "statModified", 164 | name: statName, 165 | value: profile.stats.attributes[statName], 166 | }); 167 | break; 168 | case "SkyDiveContrail": 169 | statName = "favorite_skydivecontrail"; 170 | itemToSlot = body.itemToSlot; 171 | profile.stats.attributes[statName] = itemToSlot; 172 | profileChanges.push({ 173 | changeType: "statModified", 174 | name: statName, 175 | value: profile.stats.attributes[statName], 176 | }); 177 | break; 178 | case "MusicPack": 179 | statName = "favorite_musicpack"; 180 | itemToSlot = body.itemToSlot; 181 | profile.stats.attributes[statName] = itemToSlot; 182 | profileChanges.push({ 183 | changeType: "statModified", 184 | name: statName, 185 | value: profile.stats.attributes[statName], 186 | }); 187 | break; 188 | case "LoadingScreen": 189 | statName = "favorite_loadingscreen"; 190 | itemToSlot = body.itemToSlot; 191 | profile.stats.attributes[statName] = itemToSlot; 192 | profileChanges.push({ 193 | changeType: "statModified", 194 | name: statName, 195 | value: profile.stats.attributes[statName], 196 | }); 197 | break; 198 | case "Dance": 199 | case "ItemWrap": 200 | const bIsDance = body.slotName === "Dance"; 201 | statName = bIsDance ? "favorite_dance" : "favorite_itemwraps"; 202 | let arr = profile.stats.attributes[statName] || []; 203 | if (body.indexWithinSlot === -1) { 204 | arr = []; 205 | for (let i = 0; i < (bIsDance ? 6 : 7); ++i) { 206 | arr[i] = body.itemToSlot; 207 | } 208 | } else { 209 | arr[body.indexWithinSlot || 0] = body.itemToSlot; 210 | } 211 | for (let i = 0; i < arr.length; ++i) { 212 | if (arr[i] == null) { 213 | arr[i] = ""; 214 | } 215 | } 216 | profile.stats.attributes[statName] = arr; 217 | profileChanges.push({ 218 | changeType: "statModified", 219 | name: statName, 220 | value: profile.stats.attributes[statName], 221 | }); 222 | break; 223 | default: 224 | break; 225 | } 226 | let Variants = body.variantUpdates; 227 | if (Array.isArray(Variants)) { 228 | if (!profile.items[itemToSlotID]) { 229 | profile.items[itemToSlotID] = { attributes: { variants: [] } }; 230 | } 231 | for (let i in Variants) { 232 | if (typeof Variants[i] != "object") continue; 233 | if (!Variants[i].channel) continue; 234 | if (!Variants[i].active) continue; 235 | 236 | let index = profile.items[itemToSlotID].attributes.variants.findIndex( 237 | (x: any) => x.channel == Variants[i].channel, 238 | ); 239 | 240 | if (index === -1) { 241 | profile.items[itemToSlotID].attributes.variants.push({ 242 | channel: Variants[i].channel, 243 | active: Variants[i].active, 244 | owned: Variants[i].owned || [], 245 | }); 246 | } else { 247 | profile.items[itemToSlotID].attributes.variants[index].active = Variants[i].active; 248 | } 249 | } 250 | 251 | profileChanges.push({ 252 | changeType: "itemAttrChanged", 253 | itemId: itemToSlotID, 254 | attributeName: "variants", 255 | attributeValue: profile.items[itemToSlotID].attributes.variants, 256 | }); 257 | } 258 | profile.rvn += 1; 259 | profile.commandRevision += 1; 260 | break; 261 | case "SetCosmeticLockerSlot": // br locker 2 262 | if (body.category && body.lockerItem && body.itemToSlot) { 263 | let itemToSlot = body.itemToSlot; 264 | switch (body.category) { 265 | case "Character": 266 | profile.items[body.lockerItem].attributes.locker_slots_data.slots.Character.items = [ 267 | itemToSlot, 268 | ]; 269 | break; 270 | case "Backpack": 271 | profile.items[body.lockerItem].attributes.locker_slots_data.slots.Backpack.items = [ 272 | itemToSlot, 273 | ]; 274 | break; 275 | case "Pickaxe": 276 | profile.items[body.lockerItem].attributes.locker_slots_data.slots.Pickaxe.items = [ 277 | itemToSlot, 278 | ]; 279 | break; 280 | case "Glider": 281 | profile.items[body.lockerItem].attributes.locker_slots_data.slots.Glider.items = [ 282 | itemToSlot, 283 | ]; 284 | break; 285 | case "SkyDiveContrail": 286 | profile.items[ 287 | body.lockerItem 288 | ].attributes.locker_slots_data.slots.SkyDiveContrail.items = [itemToSlot]; 289 | break; 290 | case "MusicPack": 291 | profile.items[body.lockerItem].attributes.locker_slots_data.slots.MusicPack.items = [ 292 | itemToSlot, 293 | ]; 294 | break; 295 | case "LoadingScreen": 296 | profile.items[ 297 | body.lockerItem 298 | ].attributes.locker_slots_data.slots.LoadingScreen.items = [itemToSlot]; 299 | break; 300 | case "Dance": 301 | const indexWithinSlot = body.slotIndex || 0; 302 | if (indexWithinSlot >= 0) { 303 | profile.items[body.lockerItem].attributes.locker_slots_data.slots.Dance.items[ 304 | indexWithinSlot 305 | ] = itemToSlot; 306 | } 307 | break; 308 | case "ItemWrap": 309 | const indexWithinWrap = body.slotIndex || 0; 310 | if (indexWithinWrap >= 0) { 311 | profile.items[body.lockerItem].attributes.locker_slots_data.slots.ItemWrap.items[ 312 | indexWithinWrap 313 | ] = itemToSlot; 314 | } 315 | break; 316 | default: 317 | break; 318 | } 319 | 320 | profile.rvn += 1; 321 | profile.commandRevision += 1; 322 | 323 | profileChanges.push({ 324 | changeType: "itemAttrChanged", 325 | itemId: body.lockerItem, 326 | attributeName: "locker_slots_data", 327 | attributeValue: profile.items[body.lockerItem].attributes.locker_slots_data, 328 | }); 329 | } 330 | break; 331 | case "ClaimMfaEnabled": 332 | break; 333 | case "PutModularCosmeticLoadout": // br locker 3 334 | const { loadoutType, presetId, loadoutData } = await c.req.json(); 335 | if (!profile.stats.attributes.hasOwnProperty("loadout_presets")) { 336 | profile.stats.attributes.loadout_presets = {}; 337 | 338 | profileChanges.push({ 339 | changeType: "statModified", 340 | name: "loadout_presets", 341 | value: {}, 342 | }); 343 | } 344 | 345 | if (!profile.stats.attributes.loadout_presets.hasOwnProperty(loadoutType)) { 346 | const newLoadout = uuidv4(); 347 | 348 | profile.items[newLoadout] = { 349 | templateId: loadoutType, 350 | attributes: {}, 351 | quantity: 1, 352 | }; 353 | 354 | profileChanges.push({ 355 | changeType: "itemAdded", 356 | itemId: newLoadout, 357 | item: profile.items[newLoadout], 358 | }); 359 | 360 | profile.stats.attributes.loadout_presets[loadoutType] = { 361 | [presetId]: newLoadout, 362 | }; 363 | 364 | profileChanges.push({ 365 | changeType: "statModified", 366 | name: "loadout_presets", 367 | value: profile.stats.attributes.loadout_presets, 368 | }); 369 | } 370 | 371 | const loadoutID = profile.stats.attributes.loadout_presets[loadoutType][presetId]; 372 | if (profile.items[loadoutID]) { 373 | profile.items[loadoutID].attributes = JSON.parse(loadoutData); 374 | 375 | profileChanges.push({ 376 | changeType: "itemAttrChanged", 377 | itemId: loadoutID, 378 | attributeName: "slots", 379 | attributeValue: profile.items[loadoutID].attributes.slots, 380 | }); 381 | } 382 | break; 383 | break; 384 | default: 385 | break; 386 | } 387 | 388 | profileChanges.push({ 389 | changeType: "fullProfileUpdate", 390 | profile: profile, 391 | }); 392 | 393 | const profilePath = path.join(profilesDir, `profile_${profileId}.json`); 394 | fs.writeFileSync(profilePath, JSON.stringify(profile, null, 2)); 395 | 396 | const response = { 397 | profileRevision: profile ? profile.rvn || 0 : 0, 398 | profileId: query.profileId, 399 | profileChangesBaseRevision: BaseRevision, 400 | profileChanges: profileChanges, 401 | profileCommandRevision: profile ? profile.commandRevision || 0 : 0, 402 | serverTime: new Date().toISOString(), 403 | multiUpdate: MultiUpdate, 404 | responseVersion: 1, 405 | }; 406 | 407 | userpath.add(profileId); 408 | 409 | return c.json(response); 410 | }); 411 | } 412 | -------------------------------------------------------------------------------- /src/routes/oauth.ts: -------------------------------------------------------------------------------- 1 | import app from ".."; 2 | import { Nexa } from "../utils/handlers/errors"; 3 | import jwt from "jsonwebtoken"; 4 | import logger from "../utils/logger/logger"; 5 | 6 | interface requestBody { 7 | [key: string]: any; 8 | } 9 | 10 | export default function () { 11 | app.post("/account/api/oauth/token", async (c) => { 12 | const body: requestBody = await c.req.parseBody(); 13 | let accountId = body.username || "nexa"; 14 | if (accountId.includes("@")) { 15 | accountId = accountId.split("@")[0]; 16 | } 17 | 18 | let t = jwt.sign( 19 | { 20 | email: accountId, 21 | password: "Nexapassword", 22 | type: "access", 23 | }, 24 | "NexaKey" 25 | ); 26 | 27 | return c.json({ 28 | access_token: `eg1~${t}`, 29 | expires_in: 28800, 30 | expires_at: "9999-12-02T01:12:01.100Z", 31 | token_type: "bearer", 32 | refresh_token: `eg1~${t}`, 33 | refresh_expires: 86400, 34 | refresh_expires_at: "9999-12-02T01:12:01.100Z", 35 | account_id: accountId, 36 | client_id: "clientId", 37 | internal_client: true, 38 | client_service: "fortnite", 39 | displayName: accountId, 40 | app: "fortnite", 41 | in_app_id: accountId, 42 | device_id: "deviceId", 43 | }); 44 | }); 45 | 46 | app.post("/auth/v1/oauth/token", async (c) => { 47 | let access_token = jwt.sign( 48 | { 49 | clientId: "ec684b8c687f479fadea3cb2ad83f5c6", 50 | role: "GameClient", 51 | productId: "prod-fn", 52 | iss: "eos", 53 | env: "prod", 54 | organizationId: "o-aa83a0a9bc45e98c80c1b1c9d92e9e", 55 | features: [], 56 | deploymentId: "62a9473a2dca46b29ccf17577fcf42d7", 57 | sandboxId: "fn", 58 | tokenType: "clientToken", 59 | exp: 9668532724, 60 | iat: 1668529124, 61 | jti: "1b10b89e6fea4c45a083fe04f9a71fc3", 62 | }, 63 | "NexaKey" 64 | ); 65 | return c.json({ 66 | access_token: access_token, 67 | token_type: "bearer", 68 | expires_at: "9999-12-31T23:59:59.999Z", 69 | features: ["AntiCheat", "Connect", "Ecom"], 70 | organization_id: "o-aa83a0a9bc45e98c80c1b1c9d92e9e", 71 | product_id: "prod-fn", 72 | sandbox_id: "fn", 73 | deployment_id: "62a9473a2dca46b29ccf17577fcf42d7", 74 | expires_in: 115200, 75 | }); 76 | }); 77 | 78 | app.post("/publickey/v2/publickey", async (c) => { 79 | return c.json([]); 80 | }); 81 | 82 | app.post("/epic/oauth/v2/token", async (c) => { 83 | const body: any = await c.req.parseBody(); 84 | const JWT = body.refresh_token.replace("eg1~", ""); 85 | let decoded; 86 | 87 | try { 88 | decoded = jwt.verify(JWT, "NexaKey") as jwt.JwtPayload; 89 | } catch (err) { 90 | throw err; 91 | } 92 | 93 | let access_token = jwt.sign( 94 | { 95 | sub: decoded.email, 96 | pfsid: "fn", 97 | iss: "https://api.epicgames.dev/epic/oauth/v1", 98 | dn: decoded.email, 99 | nonce: "n-01/jkXYh/9P5JimUEpSisDyK3Xw=", 100 | pfpid: "prod-fn", 101 | sec: 1, 102 | aud: "ec684b8c687f479fadea3cb2ad83f5c6", 103 | pfdid: "62a9473a2dca46b29ccf17577fcf42d7", 104 | t: "epic_id", 105 | scope: c.req.param("scope"), 106 | appid: "fghi4567FNFBKFz3E4TROb0bmPS8h1GW", 107 | exp: 9668536326, 108 | iat: 1668529126, 109 | jti: "c01f29504dcd42f9b68cf55759392928", 110 | }, 111 | "NexaKey" 112 | ); 113 | 114 | let refresh_token = jwt.sign( 115 | { 116 | sub: decoded.email, 117 | pfsid: "fn", 118 | iss: "https://api.epicgames.dev/epic/oauth/v1", 119 | dn: decoded.email, 120 | pfpid: "prod-fn", 121 | aud: "ec684b8c687f479fadea3cb2ad83f5c6", 122 | pfdid: "62a9473a2dca46b29ccf17577fcf42d7", 123 | t: "epic_id", 124 | appid: "fghi4567FNFBKFz3E4TROb0bmPS8h1GW", 125 | scope: c.req.param("scope"), 126 | exp: 9668557926, 127 | iat: 1668529126, 128 | jti: "c01f29504dcd42f9b68cf55759392928", 129 | }, 130 | "NexaKey" 131 | ); 132 | 133 | let id_token = jwt.sign( 134 | { 135 | sub: decoded.email, 136 | pfsid: "fn", 137 | iss: "https://api.epicgames.dev/epic/oauth/v1", 138 | dn: decoded.email, 139 | nonce: "n-e3Kcqw0hulXkbebFRBL8o5AwL3M=", 140 | pfpid: "prod-fn", 141 | aud: "ec684b8c687f479fadea3cb2ad83f5c6", 142 | pfdid: "62a9473a2dca46b29ccf17577fcf42d7", 143 | t: "id_token", 144 | appid: "fghi4567FNFBKFz3E4TROb0bmPS8h1GW", 145 | exp: 9668536326, 146 | iat: 1668529126, 147 | jti: "c01f29504dcd42f9b68cf55759392928", 148 | }, 149 | "NexaKey" 150 | ); 151 | 152 | return c.json({ 153 | scope: "basic_profile friends_list openid presence", 154 | token_type: "bearer", 155 | acr: "AAL1", 156 | access_token: "eg1~" + access_token, 157 | expires_in: 7200, 158 | expires_at: "9999-12-31T23:59:59.999Z", 159 | refresh_token: "eg1~" + refresh_token, 160 | refresh_expires_in: 28800, 161 | refresh_expires_at: "9999-12-31T23:59:59.999Z", 162 | account_id: decoded.email, 163 | client_id: "ec684b8c687f479fadea3cb2ad83f5c6", 164 | application_id: "fghi4567FNFBKFz3E4TROb0bmPS8h1GW", 165 | selected_account_id: decoded.email, 166 | id_token: id_token, 167 | merged_accounts: [], 168 | auth_time: new Date().toISOString(), 169 | }); 170 | }); 171 | 172 | app.get("/account/api/oauth/verify", async (c) => { 173 | const body: requestBody = await c.req.parseBody(); 174 | const authorization = c.req.header("authorization"); 175 | 176 | let accountId = body.username || "Nexa"; 177 | if (accountId.includes("@")) { 178 | accountId = accountId.split("@")[0]; 179 | } 180 | 181 | return c.json({ 182 | token: authorization, 183 | session_id: "9a1f5e80b47d2c3e6f8a0dc592b4fe7d", 184 | token_type: "bearer", 185 | client_id: "clientId", 186 | internal_client: true, 187 | client_service: "fortnite", 188 | account_id: accountId, 189 | expires_in: 28800, 190 | expires_at: "9999-12-02T01:12:01.100Z", 191 | auth_method: "exchange_code", 192 | displayName: accountId, 193 | app: "fortnite", 194 | in_app_id: accountId, 195 | device_id: "deviceId", 196 | }); 197 | }); 198 | 199 | app.delete("/account/api/oauth/sessions/kill/*", async (c) => { 200 | c.status(204); 201 | return c.json({}); 202 | }); 203 | 204 | app.get("/account/api/public/account/:accountId", async (c) => { 205 | let accountId = c.req.param("accountId"); 206 | 207 | if (accountId.includes("@")) { 208 | accountId = accountId.split("@")[0]; 209 | } 210 | 211 | return c.json({ 212 | id: accountId, 213 | displayName: accountId, 214 | name: accountId, 215 | email: accountId + "@nexa.com", 216 | failedLoginAttempts: 0, 217 | lastLogin: new Date().toISOString(), 218 | numberOfDisplayNameChanges: 0, 219 | ageGroup: "UNKNOWN", 220 | headless: false, 221 | country: "US", 222 | lastName: "Server", 223 | preferredLanguage: "en", 224 | canUpdateDisplayName: false, 225 | tfaEnabled: false, 226 | emailVerified: true, 227 | minorVerified: false, 228 | minorExpected: false, 229 | minorStatus: "NOT_MINOR", 230 | cabinedMode: false, 231 | hasHashedEmail: false, 232 | }); 233 | }); 234 | 235 | app.get("/account/api/public/account", async (c) => { 236 | const response = []; 237 | 238 | const query = c.req.query("accountId"); 239 | 240 | if (typeof query === "string") { 241 | let accountId = query; 242 | if (accountId.includes("@")) { 243 | accountId = accountId.split("@")[0]; 244 | } 245 | response.push({ 246 | id: accountId, 247 | displayName: accountId, 248 | externalAuths: {}, 249 | }); 250 | } 251 | 252 | if (Array.isArray(query)) { 253 | for (let accountId of query) { 254 | if (accountId.includes("@")) { 255 | accountId = accountId.split("@")[0]; 256 | } 257 | response.push({ 258 | id: accountId, 259 | displayName: accountId, 260 | externalAuths: {}, 261 | }); 262 | } 263 | } 264 | 265 | return c.json(response); 266 | }); 267 | } 268 | -------------------------------------------------------------------------------- /src/routes/storefront.ts: -------------------------------------------------------------------------------- 1 | import app from ".."; 2 | import axios from "axios"; 3 | import getVersion from "../utils/handlers/getVersion"; 4 | import path from "path"; 5 | import fs from "fs"; 6 | import { Nexa } from "../utils/handlers/errors"; 7 | 8 | const keychain = await Bun.file("static/shop/keychain.json").json(); 9 | 10 | export default function () { 11 | app.get("/fortnite/api/storefront/v2/keychain", async (c) => { 12 | return c.json(keychain); 13 | }); 14 | 15 | app.get("/catalog/api/shared/bulk/offers", async (c) => { 16 | return c.json([]); 17 | }); 18 | 19 | app.get("/fortnite/api/storeaccess/v1/request_access/:accountId", async (c) => { 20 | return c.json([]); 21 | }); 22 | 23 | app.get("/affiliate/api/public/affiliates/slug/:affiliateName", async (c) => { 24 | const affiliateName = c.req.param("affiliateName"); 25 | return c.json({ 26 | id: "aabbccddeeff11223344556677889900", 27 | slug: affiliateName, 28 | displayName: affiliateName, 29 | status: "ACTIVE", 30 | verified: true, 31 | }); 32 | }); 33 | 34 | app.get("/fortnite/api/storefront/v2/catalog", async (c) => { 35 | const useragent: any = c.req.header("user-agent"); 36 | if (!useragent) return c.json(Nexa.internal.invalidUserAgent); 37 | 38 | const v1 = JSON.parse( 39 | fs.readFileSync(path.join(__dirname, "../../static/shop/v1.json"), "utf8"), 40 | ); // to build 26.2 41 | const v2 = JSON.parse( 42 | fs.readFileSync(path.join(__dirname, "../../static/shop/v2.json"), "utf8"), 43 | ); // to build 30.00 44 | const v3 = JSON.parse( 45 | fs.readFileSync(path.join(__dirname, "../../static/shop/v3.json"), "utf8"), 46 | ); // latest 47 | 48 | const ver = getVersion(c); 49 | 50 | switch (true) { 51 | case ver.build >= 30.1: 52 | return c.json(v3); 53 | case ver.build >= 26.3: 54 | return c.json(v2); 55 | default: 56 | return c.json(v1); 57 | } 58 | }); 59 | } 60 | -------------------------------------------------------------------------------- /src/routes/timeline.ts: -------------------------------------------------------------------------------- 1 | import app from ".."; 2 | import eventsManager from '../utils/handlers/events' 3 | import getVersion from "../utils/handlers/getVersion"; 4 | 5 | export default function () { 6 | app.get("/fortnite/api/calendar/v1/timeline", async (c) => { 7 | const ver = getVersion(c); 8 | const Events = eventsManager.getEvents(ver); 9 | 10 | const idk = new Date(); 11 | const dUTC = new Date( 12 | Date.UTC( 13 | idk.getUTCFullYear(), 14 | idk.getUTCMonth(), 15 | idk.getUTCDate(), 16 | 24, 17 | 0, 18 | 0, 19 | 0 20 | ) 21 | ); 22 | const midnight = new Date(dUTC.getTime() - 60000); 23 | const isoDate = midnight.toISOString(); 24 | 25 | return c.json({ 26 | channels: { 27 | "client-matchmaking": { 28 | states: [], 29 | cacheExpire: "9999-01-01T00:00:00.000Z", 30 | }, 31 | "client-events": { 32 | states: [ 33 | { 34 | validFrom: "0001-01-01T00:00:00.000Z", 35 | activeEvents: Events, 36 | state: { 37 | activeStorefronts: [], 38 | eventNamedWeights: {}, 39 | seasonNumber: ver.season, 40 | seasonTemplateId: `AthenaSeason:athenaseason${ver.season}`, 41 | matchXpBonusPoints: 0, 42 | seasonBegin: "2020-01-01T00:00:00Z", 43 | seasonEnd: "9999-01-01T00:00:00Z", 44 | seasonDisplayedEnd: "9999-01-01T00:00:00Z", 45 | weeklyStoreEnd: isoDate, 46 | stwEventStoreEnd: "9999-01-01T00:00:00.000Z", 47 | stwWeeklyStoreEnd: "9999-01-01T00:00:00.000Z", 48 | sectionStoreEnds: { 49 | Featured: isoDate, 50 | }, 51 | dailyStoreEnd: isoDate, 52 | }, 53 | }, 54 | ], 55 | cacheExpire: isoDate, 56 | }, 57 | }, 58 | eventsTimeOffsetHrs: 0, 59 | cacheIntervalMins: 10, 60 | currentTime: new Date().toISOString(), 61 | }); 62 | }); 63 | } -------------------------------------------------------------------------------- /src/utils/handlers/events.ts: -------------------------------------------------------------------------------- 1 | import ini from "ini"; 2 | import fs from "node:fs"; 3 | import path from "node:path"; 4 | 5 | var config = ini.parse(fs.readFileSync(path.join(__dirname, "../../config/config.ini"), "utf-8")); 6 | 7 | function createEvent(eventType: any) { 8 | return { 9 | eventType, 10 | activeUntil: "9999-01-01T00:00:00.000Z", 11 | activeSince: "2020-01-01T00:00:00.000Z", 12 | }; 13 | } 14 | 15 | function getEvents(ver: any) { 16 | let events = [ 17 | createEvent(`EventFlag.Season${ver.season}`), 18 | createEvent(`EventFlag.${ver.lobby}`), 19 | ]; 20 | 21 | if (ver.build == 4.5) { 22 | events.push(createEvent("EventFlag.BR_S4_Geode_Countdown")); 23 | } 24 | 25 | if (ver.build == 7.2) { 26 | events.push(createEvent("EventFlag.LTM_14DaysOfFortnite")); 27 | events.push(createEvent("P1")); 28 | } 29 | 30 | if (ver.build == 7.3) { 31 | events.push(createEvent("F0")); 32 | events.push(createEvent("FEST_POSTER")); 33 | } 34 | 35 | if (ver.build == 8.51) { 36 | events.push(createEvent("EventFlag.UnvaultingCountdown")); 37 | events.push(createEvent("GWS1")); 38 | } 39 | 40 | if (ver.build == 9.4) { 41 | events.push(createEvent("CDTime")); 42 | } 43 | 44 | if (ver.season === 10) { 45 | events.push(createEvent("EventFlag.S10_Mystery")); 46 | } 47 | 48 | if (ver.build == 10.4) { 49 | events.push(createEvent("NN1")); 50 | } 51 | 52 | if (ver.season === 11) { 53 | events = events.concat([ 54 | createEvent("EventFlag.LTE_CoinCollectXP"), 55 | createEvent("EventFlag.LTE_Fortnitemares2019"), 56 | createEvent("EventFlag.LTE_Galileo_Feats"), 57 | createEvent("EventFlag.LTE_Galileo"), 58 | createEvent("EventFlag.LTE_WinterFest2019"), 59 | ]); 60 | 61 | if (ver.build >= 11.2) { 62 | events.push(createEvent("EventFlag.Starlight")); 63 | } 64 | 65 | if (ver.build < 11.3) { 66 | events = events.concat([ 67 | createEvent("EventFlag.Season11.Fortnitemares.Quests.Phase1"), 68 | createEvent("EventFlag.Season11.Fortnitemares.Quests.Phase2"), 69 | createEvent("EventFlag.Season11.Fortnitemares.Quests.Phase3"), 70 | createEvent("EventFlag.Season11.Fortnitemares.Quests.Phase4"), 71 | createEvent("EventFlag.StormKing.Landmark"), 72 | ]); 73 | } else { 74 | events = events.concat([ 75 | createEvent("EventFlag.HolidayDeco"), 76 | createEvent("EventFlag.Season11.WinterFest.Quests.Phase1"), 77 | createEvent("EventFlag.Season11.WinterFest.Quests.Phase2"), 78 | createEvent("EventFlag.Season11.WinterFest.Quests.Phase3"), 79 | createEvent("EventFlag.Season11.Frostnite"), 80 | ]); 81 | } 82 | 83 | if (ver.build === 11.31 || ver.build === 11.4) { 84 | events = events.concat([ 85 | createEvent("EventFlag.Winterfest.Tree"), 86 | createEvent("EventFlag.LTE_WinterFest"), 87 | createEvent("EventFlag.LTE_WinterFest2019"), 88 | ]); 89 | } 90 | 91 | if (ver.build == 12.41) { 92 | events.push(createEvent("JCD01")); 93 | } 94 | 95 | if (ver.build == 12.61) { 96 | events.push(createEvent("FLA01")); 97 | } 98 | 99 | if (ver.season == 13) { 100 | if (config.WaterLevel == 1) { 101 | events.push(createEvent("WL1")); 102 | } 103 | if (config.WaterLevel == 2) { 104 | events.push(createEvent("WL2")); 105 | } 106 | if (config.WaterLevel == 3) { 107 | events.push(createEvent("WL3")); 108 | } 109 | if (config.WaterLevel == 4) { 110 | events.push(createEvent("WL4")); 111 | } 112 | if (config.WaterLevel == 5) { 113 | events.push(createEvent("WL5")); 114 | } 115 | if (config.WaterLevel == 6) { 116 | events.push(createEvent("WL6")); 117 | } 118 | if (config.WaterLevel == 7) { 119 | events.push(createEvent("WL7")); 120 | } 121 | } 122 | 123 | if (ver.build == 13.4) { 124 | events.push(createEvent("SM1")); 125 | } 126 | 127 | if (ver.build == 14.6) { 128 | events.push(createEvent("FLA01")); 129 | } 130 | 131 | if (ver.build == 17.3) { 132 | events.push(createEvent("BEL01")); 133 | events.push(createEvent("BEL02")); 134 | events.push(createEvent("BEP02")); 135 | events.push(createEvent("BPLS")); 136 | events.push(createEvent("BTP")); 137 | events.push(createEvent("BAP")); 138 | events.push(createEvent("BTL01")); 139 | } 140 | 141 | if (ver.build == 17.5) { 142 | events.push(createEvent("KEL01")); 143 | events.push(createEvent("KEL02")); 144 | } 145 | 146 | if (ver.build == 18.4 || ver.season == 18) { 147 | events.push(createEvent("GGL01")); 148 | events.push(createEvent("GGL02")); // Chapter 2 Finale Event (Countdown) 149 | events.push(createEvent("LCCS02")); 150 | events.push(createEvent("LCCS01")); 151 | events.push(createEvent("LCCSP01")); 152 | events.push(createEvent("CTCS01")); 153 | events.push(createEvent("GCFP01")); 154 | events.push(createEvent("GCMFP01")); 155 | events.push(createEvent("CSAWS01")); 156 | events.push(createEvent("CSAWS02")); 157 | events.push(createEvent("CSAWS03")); 158 | events.push(createEvent("CSAWS04")); 159 | events.push(createEvent("CSAWS05")); 160 | } 161 | 162 | if (ver.build == 20.4) { 163 | // Collision Event 164 | events.push(createEvent("AL01")); 165 | events.push(createEvent("AL02")); 166 | } 167 | 168 | if (ver.build == 21.4) { 169 | // Dragon Ball 170 | events.push(createEvent("Event_S21_Stamina")); 171 | } 172 | 173 | if (ver.build == 22.4) { 174 | // Fracture Event 175 | events.push(createEvent("RL01")); 176 | } 177 | 178 | if (ver.build == 23.1) { 179 | // Winterfest 2022 180 | events.push(createEvent("CalendarEvent_Season23_Winterfest")); 181 | events.push(createEvent("EventFlag.LTE_WinterFestTab")); 182 | } 183 | 184 | if (ver.build == 23.5) { 185 | // Most Wanted tab 186 | events.push(createEvent("EventFlag.Event_Vaultbreakers")); 187 | } 188 | 189 | if (ver.build == 24.4) { 190 | // Star Wars 2023 tab 191 | events.push(createEvent("EventFlag.Event_PlotTwist")); 192 | } 193 | 194 | if (ver.build == 25.3) { 195 | // Jujutsu Kaisen tab 196 | events.push(createEvent("EventFlag.Event_BelongTreaty")); 197 | } 198 | 199 | if (ver.build == 27.11) { 200 | // Durian Event 201 | events.push(createEvent("DL01")); 202 | events.push(createEvent("DL02")); 203 | 204 | if (config.RufusStage == 2) { 205 | events.push(createEvent("RufusWeek2")); 206 | } 207 | if (config.RufusStage == 3) { 208 | events.push(createEvent("RufusWeek3")); 209 | } 210 | if (config.RufusStage == 4) { 211 | events.push(createEvent("RufusWeek4")); 212 | } 213 | } 214 | 215 | if (ver.build == 28.1) { 216 | // TMNT Tab countdown 217 | events.push(createEvent("EventFlag.Event_LinedNotebook_Teaser")); 218 | } 219 | 220 | if (ver.build == 28.2) { 221 | // TMNT mini pass 222 | events.push(createEvent("EventFlag.Event_LinedNotebook")); 223 | } 224 | 225 | if (ver.build == 28.3) { 226 | //Pre-Emergence Event 227 | events.push(createEvent("CH5S1CPPE")); 228 | } 229 | 230 | if (ver.build == 29.0) { 231 | events.push(createEvent("EventFlag.Event_S29_SeasonalActivation")); 232 | } 233 | 234 | if (ver.build == 29.2 || ver.build == 29.3) { 235 | events.push(createEvent("EventFlag.Event_S29_ColdDay")); 236 | events.push(createEvent("AtlaShrines")); 237 | events.push(createEvent("AtlaScrolls")); 238 | events.push(createEvent("AtlaChests")); 239 | } 240 | 241 | if (ver.build == 29.4) { 242 | events.push(createEvent("EventFlag.Event_Osiris")); 243 | events.push(createEvent("SUPERSPORT_BUILDUP_1")); 244 | events.push(createEvent("SUPERSPORT_BUILDUP_2")); 245 | events.push(createEvent("SUPERSPORT_BUILDUP_3")); 246 | events.push(createEvent("SUPERSPORT_CHARGE_1")); 247 | events.push(createEvent("SUPERSPORT_STRIKE_1")); 248 | events.push(createEvent("SUPERSPORT_CHARGE_2")); 249 | events.push(createEvent("SUPERSPORT_STRIKE_2")); 250 | events.push(createEvent("SUPERSPORT_CHARGE_3")); 251 | events.push(createEvent("SUPERSPORT_STRIKE_3")); 252 | events.push(createEvent("SUPERSPORT_SANDSTORM")); 253 | events.push(createEvent("SUPERSPORT_LIGHT_2")); 254 | } 255 | } 256 | 257 | return events; 258 | } 259 | 260 | export default { 261 | getEvents, 262 | createEvent, 263 | }; 264 | -------------------------------------------------------------------------------- /src/utils/handlers/getVersion.ts: -------------------------------------------------------------------------------- 1 | import app from "../.."; 2 | 3 | interface Version { 4 | season: number; 5 | build: number; 6 | CL: string; 7 | lobby: string; 8 | } 9 | 10 | export default function getVersion(c: any): Version { 11 | let ver: Version = { season: 0, build: 0.0, CL: "0", lobby: "" }; 12 | 13 | if (c.req.header("user-agent")) { 14 | let CL = ""; 15 | let userAgentParts = c.req.header("user-agent").split("-"); 16 | CL = userAgentParts[userAgentParts.length - 1].split(" ")[0].split(",")[0]; 17 | 18 | let buildIndex = c.req.header("user-agent").indexOf("Release-"); 19 | if (buildIndex !== -1) { 20 | let build = c.req.header("user-agent") 21 | .substring(buildIndex + 8) 22 | .split("-")[0]; 23 | let buildP = build.split("."); 24 | ver.season = parseInt(buildP[0], 10); 25 | ver.build = parseFloat(`${buildP[0]}.${buildP[1]}${buildP[2]}`); 26 | ver.CL = CL; 27 | ver.lobby = `LobbySeason${ver.season}`; 28 | } 29 | } 30 | return ver; 31 | } 32 | -------------------------------------------------------------------------------- /src/utils/logger/logger.ts: -------------------------------------------------------------------------------- 1 | import chalk from "chalk"; 2 | 3 | export default { 4 | backend(...messages: string[]) { 5 | console.log(`\x1b[37m[\x1b[96mBACKEND\x1b[0m\x1b[37m]`, ...messages); 6 | }, 7 | 8 | debug(...messages: string[]) { 9 | console.log(`\x1b[37m[\x1b[36mDEBUG\x1b[0m\x1b[37m]`, ...messages); 10 | }, 11 | 12 | error: (...args: unknown[]) => { 13 | console.log( 14 | chalk.bgRed(" ERROR "), 15 | ...args.map((arg) => 16 | typeof arg === "string" ? chalk.gray(arg) : chalk.gray(JSON.stringify(arg)), 17 | ), 18 | ); 19 | }, 20 | }; -------------------------------------------------------------------------------- /src/utils/startup/loadRoutes.ts: -------------------------------------------------------------------------------- 1 | import { readdir } from "fs/promises"; 2 | import { join } from "path"; 3 | import { Hono } from "hono"; 4 | import logger from "../logger/logger"; 5 | 6 | // thanks skies 7 | 8 | async function loadRoute(directory: string, file: string): Promise { 9 | try { 10 | const RouteModule = await import(join(directory, file)); 11 | const defaultExport = RouteModule.default; 12 | 13 | if (defaultExport && typeof defaultExport === "function") { 14 | defaultExport(); 15 | } else { 16 | logger.error(`${file} does not export a valid route initializer`); 17 | } 18 | } catch (error) { 19 | logger.error(`Error loading route ${file}: ${(error as Error).message}`); 20 | } 21 | } 22 | 23 | export async function loadRoutes(directory: string, app: Hono): Promise { 24 | try { 25 | const files = await readdir(directory); 26 | const routedFiles = files.filter((name) => name.endsWith(".ts") || name.endsWith(".js")); 27 | 28 | await Promise.all(routedFiles.map((file) => loadRoute(directory, file))); 29 | } catch (error) { 30 | logger.error(`Failed to load routes: ${error}`); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /start.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | bun install >nul 2>&1 3 | 4 | if %errorlevel% neq 0 ( 5 | echo Failed to install dependencies. 6 | exit /b %errorlevel% 7 | ) 8 | 9 | bun run src/index.ts 10 | -------------------------------------------------------------------------------- /static/assets/Nexa.chunk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itztiva/Nexa/050abe8775cbb716bbd0fc6384c6c08f210afac7/static/assets/Nexa.chunk -------------------------------------------------------------------------------- /static/assets/Nexa.manifest: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itztiva/Nexa/050abe8775cbb716bbd0fc6384c6c08f210afac7/static/assets/Nexa.manifest -------------------------------------------------------------------------------- /static/assets/stuff.ini: -------------------------------------------------------------------------------- 1 | [Nexa.manifest,FortniteCreative] 2 | DeltaDownloadSize="0" 3 | DownloadSize="0" 4 | [Nexa.manifest,FortniteCampaign] 5 | DeltaDownloadSize="0" 6 | DownloadSize="0" 7 | [Nexa.manifest,Lang.pl] 8 | DeltaDownloadSize="0" 9 | DownloadSize="0" 10 | [Nexa.manifest,Lang.es-419Optional] 11 | DeltaDownloadSize="0" 12 | DownloadSize="0" 13 | [Nexa.manifest,StartupOptional] 14 | DeltaDownloadSize="0" 15 | DownloadSize="0" 16 | [Nexa.manifest,FortniteCampaignTutorial] 17 | DeltaDownloadSize="0" 18 | DownloadSize="0" 19 | [Nexa.manifest,Lang.allOptional] 20 | DeltaDownloadSize="0" 21 | DownloadSize="0" 22 | [Nexa.manifest,Lang.itOptional] 23 | DeltaDownloadSize="0" 24 | DownloadSize="0" 25 | [Nexa.manifest,Lang.es-419] 26 | DeltaDownloadSize="0" 27 | DownloadSize="0" 28 | [Nexa.manifest,KairosCapture] 29 | DeltaDownloadSize="0" 30 | DownloadSize="0" 31 | [Nexa.manifest,FortniteBR] 32 | DeltaDownloadSize="0" 33 | DownloadSize="0" 34 | [Nexa.manifest,FortniteCreativeOptional] 35 | DeltaDownloadSize="0" 36 | DownloadSize="0" 37 | [Nexa.manifest,Lang.zh-CN] 38 | DeltaDownloadSize="0" 39 | DownloadSize="0" 40 | [Nexa.manifest,Lang.ruOptional] 41 | DeltaDownloadSize="0" 42 | DownloadSize="0" 43 | [Nexa.manifest,Lang.frOptional] 44 | DeltaDownloadSize="0" 45 | DownloadSize="0" 46 | [Nexa.manifest,Lang.deOptional] 47 | DeltaDownloadSize="0" 48 | DownloadSize="0" 49 | [Nexa.manifest,Lang.de] 50 | DeltaDownloadSize="0" 51 | DownloadSize="0" 52 | [Nexa.manifest,FortniteBROptional] 53 | DeltaDownloadSize="0" 54 | DownloadSize="0" 55 | [Nexa.manifest,FortniteCampaignOptional] 56 | DeltaDownloadSize="0" 57 | DownloadSize="0" 58 | [Nexa.manifest,FortniteCampaignTutorialOptional] 59 | DeltaDownloadSize="0" 60 | DownloadSize="0" 61 | [Nexa.manifest,Lang.ru] 62 | DeltaDownloadSize="0" 63 | DownloadSize="0" 64 | [Nexa.manifest,Lang.plOptional] 65 | DeltaDownloadSize="0" 66 | DownloadSize="0" 67 | [Nexa.manifest,Lang.fr] 68 | DeltaDownloadSize="0" 69 | DownloadSize="0" 70 | [Nexa.manifest,Lang.es-ESOptional] 71 | DeltaDownloadSize="0" 72 | DownloadSize="0" 73 | [Nexa.manifest,KairosCaptureOptional] 74 | DeltaDownloadSize="0" 75 | DownloadSize="0" 76 | [Nexa.manifest,Lang.all] 77 | DeltaDownloadSize="0" 78 | DownloadSize="0" 79 | [Nexa.manifest,Lang.zh-CNOptional] 80 | DeltaDownloadSize="0" 81 | DownloadSize="0" 82 | [Nexa.manifest,Lang.it] 83 | DeltaDownloadSize="0" 84 | DownloadSize="0" 85 | [Nexa.manifest,Lang.es-ES] 86 | DeltaDownloadSize="0" 87 | DownloadSize="0" 88 | [Nexa.manifest,Startup] 89 | DeltaDownloadSize="0" 90 | DownloadSize="0" 91 | -------------------------------------------------------------------------------- /static/discovery/events.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | discoveryResponses : { 3 | ver2240 : { 4 | "Panels": [ 5 | { 6 | "PanelName": "ByEpicNoBigBattle6Col", 7 | "Pages": [ 8 | { 9 | "results": [ 10 | { 11 | "linkData": { 12 | "namespace": "fn", 13 | "mnemonic": "playlist_radish", 14 | "linkType": "BR:Playlist", 15 | "active": true, 16 | "disabled": false, 17 | "version": 95, 18 | "moderationStatus": "Unmoderated", 19 | "accountId": "epic", 20 | "creatorName": "Epic", 21 | "descriptionTags": [], 22 | "metadata": { 23 | "image_url": "https://media.discordapp.net/attachments/1026187180885950498/1127989038045999145/LoadingScreen_Event.png", 24 | "matchmaking": { 25 | "override_playlist": "playlist_radish" 26 | } 27 | } 28 | }, 29 | "lastVisited": null, 30 | "linkCode": "playlist_radish", 31 | "isFavorite": false 32 | }, 33 | { 34 | "linkData": { 35 | "namespace": "fn", 36 | "mnemonic": "playlist_defaultsolo", 37 | "linkType": "BR:Playlist", 38 | "active": true, 39 | "disabled": false, 40 | "version": 95, 41 | "moderationStatus": "Unmoderated", 42 | "accountId": "epic", 43 | "creatorName": "Epic", 44 | "descriptionTags": [], 45 | "metadata": { 46 | "image_url": "https://cdn2.unrealengine.com/25br-solo-1920-1920x1080-f447350aee68.jpg", 47 | "matchmaking": { 48 | "override_playlist": "playlist_defaultsolo" 49 | } 50 | } 51 | }, 52 | "lastVisited": null, 53 | "linkCode": "playlist_defaultsolo", 54 | "isFavorite": false 55 | }, 56 | { 57 | "linkData": { 58 | "namespace": "fn", 59 | "mnemonic": "playlist_defaultduo", 60 | "linkType": "BR:Playlist", 61 | "active": true, 62 | "disabled": false, 63 | "version": 95, 64 | "moderationStatus": "Unmoderated", 65 | "accountId": "epic", 66 | "creatorName": "Epic", 67 | "descriptionTags": [], 68 | "metadata": { 69 | "image_url": "https://cdn2.unrealengine.com/25br-duos-1920-1920x1080-8b0ad8cc6fd4.jpg", 70 | "matchmaking": { 71 | "override_playlist": "playlist_defaultduo" 72 | } 73 | } 74 | }, 75 | "lastVisited": null, 76 | "linkCode": "playlist_defaultduo", 77 | "isFavorite": false 78 | }, 79 | { 80 | "linkData": { 81 | "namespace": "fn", 82 | "mnemonic": "playlist_trios", 83 | "linkType": "BR:Playlist", 84 | "active": true, 85 | "disabled": false, 86 | "version": 95, 87 | "moderationStatus": "Unmoderated", 88 | "accountId": "epic", 89 | "creatorName": "Epic", 90 | "descriptionTags": [], 91 | "metadata": { 92 | "image_url": "https://cdn2.unrealengine.com/25br-trios-1920-1920x1080-9866e812b10c.jpg", 93 | "matchmaking": { 94 | "override_playlist": "playlist_trios" 95 | } 96 | } 97 | }, 98 | "lastVisited": null, 99 | "linkCode": "playlist_trios", 100 | "isFavorite": false 101 | }, 102 | { 103 | "linkData": { 104 | "namespace": "fn", 105 | "mnemonic": "playlist_defaultsquad", 106 | "linkType": "BR:Playlist", 107 | "active": true, 108 | "disabled": false, 109 | "version": 95, 110 | "moderationStatus": "Unmoderated", 111 | "accountId": "epic", 112 | "creatorName": "Epic", 113 | "descriptionTags": [], 114 | "metadata": { 115 | "image_url": "https://cdn2.unrealengine.com/25br-squads-1920-1920x1080-d515b42c587f.jpg", 116 | "matchmaking": { 117 | "override_playlist": "playlist_defaultsquad" 118 | } 119 | } 120 | }, 121 | "lastVisited": null, 122 | "linkCode": "playlist_defaultsquad", 123 | "isFavorite": false 124 | }, 125 | { 126 | "linkData": { 127 | "namespace": "fn", 128 | "mnemonic": "playlist_papaya", 129 | "linkType": "BR:Playlist", 130 | "active": true, 131 | "disabled": false, 132 | "version": 95, 133 | "moderationStatus": "Unmoderated", 134 | "accountId": "epic", 135 | "creatorName": "Epic", 136 | "descriptionTags": [], 137 | "metadata": { 138 | "image_url": "https://cdn2.unrealengine.com/partyroyale-1920-1920x1080-7001724bc7ab.jpg", 139 | "matchmaking": { 140 | "override_playlist": "playlist_papaya" 141 | } 142 | } 143 | }, 144 | "lastVisited": null, 145 | "linkCode": "playlist_papaya", 146 | "isFavorite": false 147 | } 148 | ], 149 | "hasMore": false 150 | } 151 | ] 152 | } 153 | ], 154 | "TestCohorts": [ 155 | "testing" 156 | ], 157 | "ModeSets": {} 158 | }, 159 | ver2040 : { 160 | "Panels": [ 161 | { 162 | "PanelName": "ByEpicNoBigBattle6Col", 163 | "Pages": [ 164 | { 165 | "results": [ 166 | { 167 | "linkData": { 168 | "namespace": "fn", 169 | "mnemonic": "playlist_armadillo", 170 | "linkType": "BR:Playlist", 171 | "active": true, 172 | "disabled": false, 173 | "version": 95, 174 | "moderationStatus": "Unmoderated", 175 | "accountId": "epic", 176 | "creatorName": "Epic", 177 | "descriptionTags": [], 178 | "metadata": { 179 | "image_url": "https://cdn2.unrealengine.com/20br-armadillo-creativetile-tile-1920x1080-1920x1080-f40652491ad0.jpg", 180 | "matchmaking": { 181 | "override_playlist": "playlist_armadillo" 182 | } 183 | } 184 | }, 185 | "lastVisited": null, 186 | "linkCode": "playlist_armadillo", 187 | "isFavorite": false 188 | }, 189 | { 190 | "linkData": { 191 | "namespace": "fn", 192 | "mnemonic": "playlist_defaultsolo", 193 | "linkType": "BR:Playlist", 194 | "active": true, 195 | "disabled": false, 196 | "version": 95, 197 | "moderationStatus": "Unmoderated", 198 | "accountId": "epic", 199 | "creatorName": "Epic", 200 | "descriptionTags": [], 201 | "metadata": { 202 | "image_url": "https://cdn2.unrealengine.com/25br-solo-1920-1920x1080-f447350aee68.jpg", 203 | "matchmaking": { 204 | "override_playlist": "playlist_defaultsolo" 205 | } 206 | } 207 | }, 208 | "lastVisited": null, 209 | "linkCode": "playlist_defaultsolo", 210 | "isFavorite": false 211 | }, 212 | { 213 | "linkData": { 214 | "namespace": "fn", 215 | "mnemonic": "playlist_defaultduo", 216 | "linkType": "BR:Playlist", 217 | "active": true, 218 | "disabled": false, 219 | "version": 95, 220 | "moderationStatus": "Unmoderated", 221 | "accountId": "epic", 222 | "creatorName": "Epic", 223 | "descriptionTags": [], 224 | "metadata": { 225 | "image_url": "https://cdn2.unrealengine.com/25br-duos-1920-1920x1080-8b0ad8cc6fd4.jpg", 226 | "matchmaking": { 227 | "override_playlist": "playlist_defaultduo" 228 | } 229 | } 230 | }, 231 | "lastVisited": null, 232 | "linkCode": "playlist_defaultduo", 233 | "isFavorite": false 234 | }, 235 | { 236 | "linkData": { 237 | "namespace": "fn", 238 | "mnemonic": "playlist_trios", 239 | "linkType": "BR:Playlist", 240 | "active": true, 241 | "disabled": false, 242 | "version": 95, 243 | "moderationStatus": "Unmoderated", 244 | "accountId": "epic", 245 | "creatorName": "Epic", 246 | "descriptionTags": [], 247 | "metadata": { 248 | "image_url": "https://cdn2.unrealengine.com/25br-trios-1920-1920x1080-9866e812b10c.jpg", 249 | "matchmaking": { 250 | "override_playlist": "playlist_trios" 251 | } 252 | } 253 | }, 254 | "lastVisited": null, 255 | "linkCode": "playlist_trios", 256 | "isFavorite": false 257 | }, 258 | { 259 | "linkData": { 260 | "namespace": "fn", 261 | "mnemonic": "playlist_defaultsquad", 262 | "linkType": "BR:Playlist", 263 | "active": true, 264 | "disabled": false, 265 | "version": 95, 266 | "moderationStatus": "Unmoderated", 267 | "accountId": "epic", 268 | "creatorName": "Epic", 269 | "descriptionTags": [], 270 | "metadata": { 271 | "image_url": "https://cdn2.unrealengine.com/25br-squads-1920-1920x1080-d515b42c587f.jpg", 272 | "matchmaking": { 273 | "override_playlist": "playlist_defaultsquad" 274 | } 275 | } 276 | }, 277 | "lastVisited": null, 278 | "linkCode": "playlist_defaultsquad", 279 | "isFavorite": false 280 | }, 281 | { 282 | "linkData": { 283 | "namespace": "fn", 284 | "mnemonic": "playlist_papaya", 285 | "linkType": "BR:Playlist", 286 | "active": true, 287 | "disabled": false, 288 | "version": 95, 289 | "moderationStatus": "Unmoderated", 290 | "accountId": "epic", 291 | "creatorName": "Epic", 292 | "descriptionTags": [], 293 | "metadata": { 294 | "image_url": "https://cdn2.unrealengine.com/partyroyale-1920-1920x1080-7001724bc7ab.jpg", 295 | "matchmaking": { 296 | "override_playlist": "playlist_papaya" 297 | } 298 | } 299 | }, 300 | "lastVisited": null, 301 | "linkCode": "playlist_papaya", 302 | "isFavorite": false 303 | } 304 | ], 305 | "hasMore": false 306 | } 307 | ] 308 | } 309 | ], 310 | "TestCohorts": [ 311 | "testing" 312 | ], 313 | "ModeSets": {} 314 | }, 315 | ver19 : { 316 | "Panels": [ 317 | { 318 | "PanelName": "ByEpicNoBigBattle6Col", 319 | "Pages": [ 320 | { 321 | "results": [ 322 | { 323 | "linkData": { 324 | "namespace": "fn", 325 | "mnemonic": "playlist_pumpkin", 326 | "linkType": "BR:Playlist", 327 | "active": true, 328 | "disabled": false, 329 | "version": 95, 330 | "moderationStatus": "Unmoderated", 331 | "accountId": "epic", 332 | "creatorName": "Epic", 333 | "descriptionTags": [], 334 | "metadata": { 335 | "image_url": "https://media.discordapp.net/attachments/1026187180885950498/1127972681040535672/image.png", 336 | "matchmaking": { 337 | "override_playlist": "playlist_pumpkin" 338 | } 339 | } 340 | }, 341 | "lastVisited": null, 342 | "linkCode": "playlist_pumpkin", 343 | "isFavorite": false 344 | }, 345 | { 346 | "linkData": { 347 | "namespace": "fn", 348 | "mnemonic": "playlist_defaultsolo", 349 | "linkType": "BR:Playlist", 350 | "active": true, 351 | "disabled": false, 352 | "version": 95, 353 | "moderationStatus": "Unmoderated", 354 | "accountId": "epic", 355 | "creatorName": "Epic", 356 | "descriptionTags": [], 357 | "metadata": { 358 | "image_url": "https://cdn2.unrealengine.com/25br-solo-1920-1920x1080-f447350aee68.jpg", 359 | "matchmaking": { 360 | "override_playlist": "playlist_defaultsolo" 361 | } 362 | } 363 | }, 364 | "lastVisited": null, 365 | "linkCode": "playlist_defaultsolo", 366 | "isFavorite": false 367 | }, 368 | { 369 | "linkData": { 370 | "namespace": "fn", 371 | "mnemonic": "playlist_defaultduo", 372 | "linkType": "BR:Playlist", 373 | "active": true, 374 | "disabled": false, 375 | "version": 95, 376 | "moderationStatus": "Unmoderated", 377 | "accountId": "epic", 378 | "creatorName": "Epic", 379 | "descriptionTags": [], 380 | "metadata": { 381 | "image_url": "https://cdn2.unrealengine.com/25br-duos-1920-1920x1080-8b0ad8cc6fd4.jpg", 382 | "matchmaking": { 383 | "override_playlist": "playlist_defaultduo" 384 | } 385 | } 386 | }, 387 | "lastVisited": null, 388 | "linkCode": "playlist_defaultduo", 389 | "isFavorite": false 390 | }, 391 | { 392 | "linkData": { 393 | "namespace": "fn", 394 | "mnemonic": "playlist_trios", 395 | "linkType": "BR:Playlist", 396 | "active": true, 397 | "disabled": false, 398 | "version": 95, 399 | "moderationStatus": "Unmoderated", 400 | "accountId": "epic", 401 | "creatorName": "Epic", 402 | "descriptionTags": [], 403 | "metadata": { 404 | "image_url": "https://cdn2.unrealengine.com/25br-trios-1920-1920x1080-9866e812b10c.jpg", 405 | "matchmaking": { 406 | "override_playlist": "playlist_trios" 407 | } 408 | } 409 | }, 410 | "lastVisited": null, 411 | "linkCode": "playlist_trios", 412 | "isFavorite": false 413 | }, 414 | { 415 | "linkData": { 416 | "namespace": "fn", 417 | "mnemonic": "playlist_defaultsquad", 418 | "linkType": "BR:Playlist", 419 | "active": true, 420 | "disabled": false, 421 | "version": 95, 422 | "moderationStatus": "Unmoderated", 423 | "accountId": "epic", 424 | "creatorName": "Epic", 425 | "descriptionTags": [], 426 | "metadata": { 427 | "image_url": "https://cdn2.unrealengine.com/25br-squads-1920-1920x1080-d515b42c587f.jpg", 428 | "matchmaking": { 429 | "override_playlist": "playlist_defaultsquad" 430 | } 431 | } 432 | }, 433 | "lastVisited": null, 434 | "linkCode": "playlist_defaultsquad", 435 | "isFavorite": false 436 | }, 437 | { 438 | "linkData": { 439 | "namespace": "fn", 440 | "mnemonic": "playlist_papaya", 441 | "linkType": "BR:Playlist", 442 | "active": true, 443 | "disabled": false, 444 | "version": 95, 445 | "moderationStatus": "Unmoderated", 446 | "accountId": "epic", 447 | "creatorName": "Epic", 448 | "descriptionTags": [], 449 | "metadata": { 450 | "image_url": "https://cdn2.unrealengine.com/partyroyale-1920-1920x1080-7001724bc7ab.jpg", 451 | "matchmaking": { 452 | "override_playlist": "playlist_papaya" 453 | } 454 | } 455 | }, 456 | "lastVisited": null, 457 | "linkCode": "playlist_papaya", 458 | "isFavorite": false 459 | } 460 | ], 461 | "hasMore": false 462 | } 463 | ] 464 | } 465 | ], 466 | "TestCohorts": [ 467 | "testing" 468 | ], 469 | "ModeSets": {} 470 | }, 471 | ver1840 : { 472 | "Panels": [ 473 | { 474 | "PanelName": "ByEpicNoBigBattle6Col", 475 | "Pages": [ 476 | { 477 | "results": [ 478 | { 479 | "linkData": { 480 | "namespace": "fn", 481 | "mnemonic": "playlist_guava", 482 | "linkType": "BR:Playlist", 483 | "active": true, 484 | "disabled": false, 485 | "version": 95, 486 | "moderationStatus": "Unmoderated", 487 | "accountId": "epic", 488 | "creatorName": "Epic", 489 | "descriptionTags": [], 490 | "metadata": { 491 | "image_url": "https://cdn2.unrealengine.com/18br-guava-playlisttile-1920x1080-1920x1080-e66a6a0a08cf.jpg", 492 | "matchmaking": { 493 | "override_playlist": "playlist_guava" 494 | } 495 | } 496 | }, 497 | "lastVisited": null, 498 | "linkCode": "playlist_guava", 499 | "isFavorite": false 500 | }, 501 | { 502 | "linkData": { 503 | "namespace": "fn", 504 | "mnemonic": "playlist_defaultsolo", 505 | "linkType": "BR:Playlist", 506 | "active": true, 507 | "disabled": false, 508 | "version": 95, 509 | "moderationStatus": "Unmoderated", 510 | "accountId": "epic", 511 | "creatorName": "Epic", 512 | "descriptionTags": [], 513 | "metadata": { 514 | "image_url": "https://cdn2.unrealengine.com/25br-solo-1920-1920x1080-f447350aee68.jpg", 515 | "matchmaking": { 516 | "override_playlist": "playlist_defaultsolo" 517 | } 518 | } 519 | }, 520 | "lastVisited": null, 521 | "linkCode": "playlist_defaultsolo", 522 | "isFavorite": false 523 | }, 524 | { 525 | "linkData": { 526 | "namespace": "fn", 527 | "mnemonic": "playlist_defaultduo", 528 | "linkType": "BR:Playlist", 529 | "active": true, 530 | "disabled": false, 531 | "version": 95, 532 | "moderationStatus": "Unmoderated", 533 | "accountId": "epic", 534 | "creatorName": "Epic", 535 | "descriptionTags": [], 536 | "metadata": { 537 | "image_url": "https://cdn2.unrealengine.com/25br-duos-1920-1920x1080-8b0ad8cc6fd4.jpg", 538 | "matchmaking": { 539 | "override_playlist": "playlist_defaultduo" 540 | } 541 | } 542 | }, 543 | "lastVisited": null, 544 | "linkCode": "playlist_defaultduo", 545 | "isFavorite": false 546 | }, 547 | { 548 | "linkData": { 549 | "namespace": "fn", 550 | "mnemonic": "playlist_trios", 551 | "linkType": "BR:Playlist", 552 | "active": true, 553 | "disabled": false, 554 | "version": 95, 555 | "moderationStatus": "Unmoderated", 556 | "accountId": "epic", 557 | "creatorName": "Epic", 558 | "descriptionTags": [], 559 | "metadata": { 560 | "image_url": "https://cdn2.unrealengine.com/25br-trios-1920-1920x1080-9866e812b10c.jpg", 561 | "matchmaking": { 562 | "override_playlist": "playlist_trios" 563 | } 564 | } 565 | }, 566 | "lastVisited": null, 567 | "linkCode": "playlist_trios", 568 | "isFavorite": false 569 | }, 570 | { 571 | "linkData": { 572 | "namespace": "fn", 573 | "mnemonic": "playlist_defaultsquad", 574 | "linkType": "BR:Playlist", 575 | "active": true, 576 | "disabled": false, 577 | "version": 95, 578 | "moderationStatus": "Unmoderated", 579 | "accountId": "epic", 580 | "creatorName": "Epic", 581 | "descriptionTags": [], 582 | "metadata": { 583 | "image_url": "https://cdn2.unrealengine.com/25br-squads-1920-1920x1080-d515b42c587f.jpg", 584 | "matchmaking": { 585 | "override_playlist": "playlist_defaultsquad" 586 | } 587 | } 588 | }, 589 | "lastVisited": null, 590 | "linkCode": "playlist_defaultsquad", 591 | "isFavorite": false 592 | }, 593 | { 594 | "linkData": { 595 | "namespace": "fn", 596 | "mnemonic": "playlist_papaya", 597 | "linkType": "BR:Playlist", 598 | "active": true, 599 | "disabled": false, 600 | "version": 95, 601 | "moderationStatus": "Unmoderated", 602 | "accountId": "epic", 603 | "creatorName": "Epic", 604 | "descriptionTags": [], 605 | "metadata": { 606 | "image_url": "https://cdn2.unrealengine.com/partyroyale-1920-1920x1080-7001724bc7ab.jpg", 607 | "matchmaking": { 608 | "override_playlist": "playlist_papaya" 609 | } 610 | } 611 | }, 612 | "lastVisited": null, 613 | "linkCode": "playlist_papaya", 614 | "isFavorite": false 615 | } 616 | ], 617 | "hasMore": false 618 | } 619 | ] 620 | } 621 | ], 622 | "TestCohorts": [ 623 | "testing" 624 | ], 625 | "ModeSets": {} 626 | }, 627 | ver1750 : { 628 | "Panels": [ 629 | { 630 | "PanelName": "ByEpicNoBigBattle6Col", 631 | "Pages": [ 632 | { 633 | "results": [ 634 | { 635 | "linkData": { 636 | "namespace": "fn", 637 | "mnemonic": "playlist_kiwi", 638 | "linkType": "BR:Playlist", 639 | "active": true, 640 | "disabled": false, 641 | "version": 95, 642 | "moderationStatus": "Unmoderated", 643 | "accountId": "epic", 644 | "creatorName": "Epic", 645 | "descriptionTags": [], 646 | "metadata": { 647 | "image_url": "https://cdn2.unrealengine.com/17br-kiwi-keyart-motd-1920x1080-1920x1080-50ccef17c86f.jpg", 648 | "matchmaking": { 649 | "override_playlist": "playlist_kiwi" 650 | } 651 | } 652 | }, 653 | "lastVisited": null, 654 | "linkCode": "playlist_kiwi", 655 | "isFavorite": false 656 | }, 657 | { 658 | "linkData": { 659 | "namespace": "fn", 660 | "mnemonic": "playlist_defaultsolo", 661 | "linkType": "BR:Playlist", 662 | "active": true, 663 | "disabled": false, 664 | "version": 95, 665 | "moderationStatus": "Unmoderated", 666 | "accountId": "epic", 667 | "creatorName": "Epic", 668 | "descriptionTags": [], 669 | "metadata": { 670 | "image_url": "https://cdn2.unrealengine.com/25br-solo-1920-1920x1080-f447350aee68.jpg", 671 | "matchmaking": { 672 | "override_playlist": "playlist_defaultsolo" 673 | } 674 | } 675 | }, 676 | "lastVisited": null, 677 | "linkCode": "playlist_defaultsolo", 678 | "isFavorite": false 679 | }, 680 | { 681 | "linkData": { 682 | "namespace": "fn", 683 | "mnemonic": "playlist_defaultduo", 684 | "linkType": "BR:Playlist", 685 | "active": true, 686 | "disabled": false, 687 | "version": 95, 688 | "moderationStatus": "Unmoderated", 689 | "accountId": "epic", 690 | "creatorName": "Epic", 691 | "descriptionTags": [], 692 | "metadata": { 693 | "image_url": "https://cdn2.unrealengine.com/25br-duos-1920-1920x1080-8b0ad8cc6fd4.jpg", 694 | "matchmaking": { 695 | "override_playlist": "playlist_defaultduo" 696 | } 697 | } 698 | }, 699 | "lastVisited": null, 700 | "linkCode": "playlist_defaultduo", 701 | "isFavorite": false 702 | }, 703 | { 704 | "linkData": { 705 | "namespace": "fn", 706 | "mnemonic": "playlist_trios", 707 | "linkType": "BR:Playlist", 708 | "active": true, 709 | "disabled": false, 710 | "version": 95, 711 | "moderationStatus": "Unmoderated", 712 | "accountId": "epic", 713 | "creatorName": "Epic", 714 | "descriptionTags": [], 715 | "metadata": { 716 | "image_url": "https://cdn2.unrealengine.com/25br-trios-1920-1920x1080-9866e812b10c.jpg", 717 | "matchmaking": { 718 | "override_playlist": "playlist_trios" 719 | } 720 | } 721 | }, 722 | "lastVisited": null, 723 | "linkCode": "playlist_trios", 724 | "isFavorite": false 725 | }, 726 | { 727 | "linkData": { 728 | "namespace": "fn", 729 | "mnemonic": "playlist_defaultsquad", 730 | "linkType": "BR:Playlist", 731 | "active": true, 732 | "disabled": false, 733 | "version": 95, 734 | "moderationStatus": "Unmoderated", 735 | "accountId": "epic", 736 | "creatorName": "Epic", 737 | "descriptionTags": [], 738 | "metadata": { 739 | "image_url": "https://cdn2.unrealengine.com/25br-squads-1920-1920x1080-d515b42c587f.jpg", 740 | "matchmaking": { 741 | "override_playlist": "playlist_defaultsquad" 742 | } 743 | } 744 | }, 745 | "lastVisited": null, 746 | "linkCode": "playlist_defaultsquad", 747 | "isFavorite": false 748 | }, 749 | { 750 | "linkData": { 751 | "namespace": "fn", 752 | "mnemonic": "playlist_papaya", 753 | "linkType": "BR:Playlist", 754 | "active": true, 755 | "disabled": false, 756 | "version": 95, 757 | "moderationStatus": "Unmoderated", 758 | "accountId": "epic", 759 | "creatorName": "Epic", 760 | "descriptionTags": [], 761 | "metadata": { 762 | "image_url": "https://cdn2.unrealengine.com/partyroyale-1920-1920x1080-7001724bc7ab.jpg", 763 | "matchmaking": { 764 | "override_playlist": "playlist_papaya" 765 | } 766 | } 767 | }, 768 | "lastVisited": null, 769 | "linkCode": "playlist_papaya", 770 | "isFavorite": false 771 | } 772 | ], 773 | "hasMore": false 774 | } 775 | ] 776 | } 777 | ], 778 | "TestCohorts": [ 779 | "testing" 780 | ], 781 | "ModeSets": {} 782 | }, 783 | } 784 | 785 | } -------------------------------------------------------------------------------- /static/discovery/latest/brplaylist.json: -------------------------------------------------------------------------------- 1 | { 2 | "namespace": "fn", 3 | "accountId": "epic", 4 | "creatorName": "Epic", 5 | "mnemonic": "set_br_playlists", 6 | "linkType": "ModeSet", 7 | "metadata": { 8 | "image_url": "https://cdn2.unrealengine.com/ogbr-logo-1920-1920x1080-642ac8e12fc1.jpg", 9 | "image_urls": { 10 | "url_s": "https://cdn2.unrealengine.com/ogbr-logo-480-480x270-2d0521c07edc.jpg", 11 | "url_xs": "https://cdn2.unrealengine.com/ogbr-logo-256-256x144-25b34d79ca46.jpg", 12 | "url_m": "https://cdn2.unrealengine.com/ogbr-logo-640-640x360-50590a2dfe12.jpg", 13 | "url": "https://cdn2.unrealengine.com/ogbr-logo-1920-1920x1080-642ac8e12fc1.jpg" 14 | }, 15 | "title": "Battle Royale", 16 | "locale": "en", 17 | "video_vuid": "CaGHsWoMJxMGUDasbB", 18 | "sub_link_codes": [ 19 | "playlist_defaultsolo", 20 | "playlist_defaultduo", 21 | "playlist_trios", 22 | "playlist_defaultsquad" 23 | ], 24 | "alt_title": { 25 | "de": "Battle Royale", 26 | "ru": "Королевская битва", 27 | "ko": "배틀로얄", 28 | "pt-BR": "Battle Royale", 29 | "it": "Battaglia reale", 30 | "fr": "Battle Royale", 31 | "zh-CN": "", 32 | "es": "Battle Royale", 33 | "es-MX": "Batalla campal", 34 | "zh": "", 35 | "ar": "باتل رويال", 36 | "zh-Hant": "", 37 | "ja": "バトルロイヤル", 38 | "pl": "Battle Royale", 39 | "es-419": "Batalla campal", 40 | "tr": "Battle Royale" 41 | }, 42 | "alt_tagline": { 43 | "de": "Überlebe allein in einer Schlacht bis auf den letzten Spieler.", 44 | "ru": "Отправляйтесь на битву в одиночку и переживите всех соперников.", 45 | "ko": "죽느냐 사느냐... 혼자서 싸우는 서바이벌 혈투!", 46 | "pt-BR": "Entre sozinho em uma batalha para ser o último sobrevivente.", 47 | "it": "Combatti in solitaria fino a diventare l'ultimo superstite.", 48 | "fr": "Combattez en solitaire et soyez le dernier survivant.", 49 | "zh-CN": "", 50 | "es": "Entra en solitario en un combate para ser el último en pie.", 51 | "es-MX": "Entra por tu cuenta a un combate y pelea hasta que solo quedes tú en pie.", 52 | "zh": "", 53 | "ar": "خُض المعركة بمفردك لتصبح آخر من يتبقى من اللاعبين.", 54 | "zh-Hant": "", 55 | "ja": "単身でバトルに飛び込み、最後の1人になるまで生き残れ。", 56 | "pl": "Walcz samotnie w bitwie do ostatniego.", 57 | "es-419": "Entra por tu cuenta a un combate y pelea hasta que solo quedes tú en pie.", 58 | "tr": "Savaşa tek başına gir ve hayatta kalan son kişi ol." 59 | }, 60 | "product_tag": "Product.BR.Build", 61 | "fallback_links": { 62 | "graceful": "playlist_respawn_24_alt" 63 | }, 64 | "tagline": "The battle is building! \r\n Drop into the Battle Royale. Loot, build, explore, and fight in a game of 100 players competing to be the last one standing.", 65 | "corresponding_sets": { 66 | "ranked": "set_habanero_playlists" 67 | }, 68 | "default_sub_link_code": "playlist_defaultsquad" 69 | }, 70 | "version": 1, 71 | "active": true, 72 | "disabled": false, 73 | "created": "2022-06-30T17:57:54.767Z", 74 | "published": "2023-11-16T17:00:34.973Z", 75 | "descriptionTags": [], 76 | "moderationStatus": "Approved", 77 | "lastActivatedDate": "2022-06-30T17:57:54.770Z", 78 | "discoveryIntent": "PUBLIC" 79 | } -------------------------------------------------------------------------------- /static/discovery/latest/ltms/playlist_defaultduo.json: -------------------------------------------------------------------------------- 1 | { 2 | "namespace": "fn", 3 | "accountId": "epic", 4 | "creatorName": "Epic", 5 | "mnemonic": "playlist_defaultduo", 6 | "linkType": "BR:Playlist", 7 | "metadata": { 8 | "parent_set": "set_br_playlists", 9 | "favorite_override": "set_br_playlists", 10 | "play_history_override": "set_br_playlists", 11 | "alt_title": { 12 | "de": "Duo", 13 | "ru": "Парные сражения", 14 | "ko": "듀오", 15 | "pt-BR": "Duplas", 16 | "en": "Duo", 17 | "it": "Coppie", 18 | "fr": "Duos", 19 | "zh-CN": "", 20 | "es": "Dúos", 21 | "es-MX": "En dúo", 22 | "zh": "", 23 | "ar": "ثنائي", 24 | "zh-Hant": "", 25 | "ja": "デュオ", 26 | "pl": "Pary", 27 | "es-419": "En dúo", 28 | "tr": "Çiftli" 29 | }, 30 | "image_url": "https://cdn2.unrealengine.com/ogbr-duos-640-640x360-bae457925977.jpg", 31 | "product_tag": "Product.BR.Build.Duo", 32 | "image_urls": { 33 | "url_s": "https://cdn2.unrealengine.com/ogbr-duos-640-640x360-bae457925977.jpg", 34 | "url_xs": "https://cdn2.unrealengine.com/ogbr-duos-640-640x360-bae457925977.jpg", 35 | "url_m": "https://cdn2.unrealengine.com/ogbr-duos-640-640x360-bae457925977.jpg", 36 | "url": "https://cdn2.unrealengine.com/ogbr-duos-640-640x360-bae457925977.jpg" 37 | }, 38 | "matchmaking": { 39 | "override_playlist": "playlist_defaultduo" 40 | }, 41 | "video_vuid": "taqdZkWyokbCyEFWld", 42 | "title": "Duo" 43 | }, 44 | "version": 95, 45 | "active": true, 46 | "disabled": false, 47 | "created": "2021-10-01T00:56:46.389Z", 48 | "published": "2023-11-03T08:25:34.690Z", 49 | "descriptionTags": [], 50 | "moderationStatus": "Unmoderated" 51 | } -------------------------------------------------------------------------------- /static/discovery/latest/ltms/playlist_defaultsolo.json: -------------------------------------------------------------------------------- 1 | { 2 | "namespace": "fn", 3 | "accountId": "epic", 4 | "creatorName": "Epic", 5 | "mnemonic": "playlist_defaultsolo", 6 | "linkType": "BR:Playlist", 7 | "metadata": { 8 | "parent_set": "set_br_playlists", 9 | "favorite_override": "set_br_playlists", 10 | "play_history_override": "set_br_playlists", 11 | "alt_title": { 12 | "de": "Solo", 13 | "ru": "В одиночку", 14 | "ko": "솔로", 15 | "pt-BR": "Solo", 16 | "en": "Solo", 17 | "it": "Singolo", 18 | "fr": "Solo", 19 | "zh-CN": "", 20 | "es": "En solitario", 21 | "es-MX": "En solitario", 22 | "zh": "", 23 | "ar": "فردي", 24 | "zh-Hant": "", 25 | "ja": "ソロ", 26 | "pl": "Solo", 27 | "es-419": "En solitario", 28 | "tr": "Tekli" 29 | }, 30 | "image_url": "https://cdn2.unrealengine.com/ogbr-solo-640-640x360-0f92e118028a.jpg", 31 | "product_tag": "Product.BR.Build.Solo", 32 | "image_urls": { 33 | "url_s": "https://cdn2.unrealengine.com/ogbr-solo-640-640x360-0f92e118028a.jpg", 34 | "url_xs": "https://cdn2.unrealengine.com/ogbr-solo-640-640x360-0f92e118028a.jpg", 35 | "url_m": "https://cdn2.unrealengine.com/ogbr-solo-640-640x360-0f92e118028a.jpg", 36 | "url": "https://cdn2.unrealengine.com/ogbr-solo-640-640x360-0f92e118028a.jpg" 37 | }, 38 | "matchmaking": { 39 | "override_playlist": "playlist_defaultsolo" 40 | }, 41 | "video_vuid": "taqdZkWyokbCyEFWld", 42 | "title": "Solo" 43 | }, 44 | "version": 95, 45 | "active": true, 46 | "disabled": false, 47 | "created": "2021-10-01T00:56:43.870Z", 48 | "published": "2023-11-03T08:26:11.189Z", 49 | "descriptionTags": [], 50 | "moderationStatus": "Unmoderated" 51 | } -------------------------------------------------------------------------------- /static/discovery/latest/ltms/playlist_defaultsquad.json: -------------------------------------------------------------------------------- 1 | { 2 | "namespace": "fn", 3 | "accountId": "epic", 4 | "creatorName": "Epic", 5 | "mnemonic": "playlist_defaultsquad", 6 | "linkType": "BR:Playlist", 7 | "metadata": { 8 | "parent_set": "set_br_playlists", 9 | "favorite_override": "set_br_playlists", 10 | "play_history_override": "set_br_playlists", 11 | "alt_title": { 12 | "de": "Team", 13 | "ru": "Бои отрядов", 14 | "ko": "스쿼드", 15 | "pt-BR": "Esquadrões", 16 | "en": "Squad", 17 | "it": "Squadre", 18 | "fr": "Sections", 19 | "zh-CN": "", 20 | "es": "Escuadrones", 21 | "es-MX": "En escuadrón", 22 | "zh": "", 23 | "ar": "فِرق", 24 | "zh-Hant": "", 25 | "ja": "スクワッド", 26 | "pl": "Oddziały", 27 | "es-419": "En escuadrón", 28 | "tr": "Ekipli" 29 | }, 30 | "image_url": "https://cdn2.unrealengine.com/ogbr-squads-640-640x360-6231add9fe53.jpg", 31 | "product_tag": "Product.BR.Build.Squad", 32 | "image_urls": { 33 | "url_s": "https://cdn2.unrealengine.com/ogbr-squads-640-640x360-6231add9fe53.jpg", 34 | "url_xs": "https://cdn2.unrealengine.com/ogbr-squads-640-640x360-6231add9fe53.jpg", 35 | "url_m": "https://cdn2.unrealengine.com/ogbr-squads-640-640x360-6231add9fe53.jpg", 36 | "url": "https://cdn2.unrealengine.com/ogbr-squads-640-640x360-6231add9fe53.jpg" 37 | }, 38 | "tagline": "", 39 | "matchmaking": { 40 | "override_playlist": "playlist_defaultsquad" 41 | }, 42 | "video_vuid": "taqdZkWyokbCyEFWld", 43 | "title": "Squad" 44 | }, 45 | "version": 95, 46 | "active": true, 47 | "disabled": false, 48 | "created": "2021-10-01T00:56:42.938Z", 49 | "published": "2023-11-03T08:25:06.100Z", 50 | "descriptionTags": [], 51 | "moderationStatus": "Unmoderated" 52 | } -------------------------------------------------------------------------------- /static/discovery/latest/ltms/playlist_juno.json: -------------------------------------------------------------------------------- 1 | { 2 | "namespace": "fn", 3 | "accountId": "epic", 4 | "creatorName": "Epic", 5 | "mnemonic": "playlist_juno", 6 | "linkType": "BR:Playlist", 7 | "metadata": { 8 | "lobby_background_image_urls": { 9 | "url": "https://cdn2.unrealengine.com/juno-lobby-2560x1440-b8beae672ffb.png" 10 | }, 11 | "frontend_plugin": "JunoFrontendUI", 12 | "image_url": "https://cdn2.unrealengine.com/legofn-disco-1920-1920x1080-c5f52d11a179.jpg", 13 | "requiresArbitratedWorldId": true, 14 | "image_urls": { 15 | "url_s": "https://cdn2.unrealengine.com/legofn-disco-480-480x270-c55546b444b3.jpg", 16 | "url_xs": "https://cdn2.unrealengine.com/legofn-disco-270-270x152-78c11b5032db.jpg", 17 | "url_m": "https://cdn2.unrealengine.com/legofn-disco-640-640x360-75aa197e5b17.jpg", 18 | "url": "https://cdn2.unrealengine.com/legofn-disco-1920-1920x1080-c5f52d11a179.jpg" 19 | }, 20 | "matchmaking": { 21 | "override_playlist": "playlist_juno" 22 | }, 23 | "title": "LEGO Fortnite", 24 | "alt_title": { 25 | "ar": "LEGO Fortnite", 26 | "de": "LEGO Fortnite", 27 | "ru": "LEGO Fortnite", 28 | "ko": "\ub808\uace0 \ud3ec\ud2b8\ub098\uc774\ud2b8", 29 | "pt-BR": "LEGO Fortnite", 30 | "ja": "LEGO Fortnite", 31 | "it": "LEGO Fortnite", 32 | "fr": "LEGO Fortnite", 33 | "pl": "LEGO Fortnite", 34 | "es": "LEGO Fortnite", 35 | "es-419": "LEGO Fortnite", 36 | "tr": "LEGO Fortnite" 37 | }, 38 | "alt_tagline": { 39 | "ar": "\u0627\u0633\u062a\u0643\u0634\u0641 \u0639\u0648\u0627\u0644\u0645 \u0645\u0641\u062a\u0648\u062d\u0629 \u0634\u0627\u0633\u0639\u0629 \u062d\u064a\u062b \u064a\u062a\u0644\u0627\u0642\u0649 \u0633\u062d\u0631 \u0628\u0646\u0627\u0621 LEGO\u00ae \u0648Fortnite. \u0627\u0639\u062b\u0631 \u0639\u0644\u0649 \u0623\u0641\u0636\u0644 \u0645\u063a\u0627\u0645\u0631\u0629 LEGO \u0644\u0644\u0646\u062c\u0627\u0629 \u0641\u064a Fortnite!", 40 | "de": "Erkunde riesige offene Welten, in denen die Magie des Bauens von LEGO\u00ae und Fortnite aufeinandertreffen. In Fortnite findest du das ultimative LEGO-Abenteuer, in dem sich alles ums \u00dcberleben und Crafting dreht!", 41 | "ru": "\u0418\u0441\u0441\u043b\u0435\u0434\u0443\u0439\u0442\u0435 \u043e\u0433\u0440\u043e\u043c\u043d\u044b\u0435 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0435 \u043c\u0438\u0440\u044b, \u0433\u0434\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u044f\u044e\u0442\u0441\u044f \u0447\u0443\u0434\u0435\u0441\u0430 \u0441\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u0430 LEGO\u00ae \u0438 \u043f\u0440\u0438\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f Fortnite. \u041e\u0442\u043f\u0440\u0430\u0432\u044c\u0442\u0435\u0441\u044c \u0432 \u043d\u0435\u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c\u043e\u0435 \u043f\u0443\u0442\u0435\u0448\u0435\u0441\u0442\u0432\u0438\u0435 \u0441 LEGO\u00ae \u0432 Fortnite \u0438 \u0441\u0434\u0435\u043b\u0430\u0439\u0442\u0435 \u0432\u0441\u0451, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0436\u0438\u0442\u044c!", 42 | "ko": "\ub808\uace0\u00ae \uc870\ub9bd\uc758 \ub9c8\ubc95\uacfc \ud3ec\ud2b8\ub098\uc774\ud2b8\uac00 \ub9cc\ub098\ub294 \uad11\ub300\ud55c \uc624\ud508 \uc6d4\ub4dc\ub97c \ud0d0\ud5d8\ud574 \ubcf4\uc138\uc694. \ud3ec\ud2b8\ub098\uc774\ud2b8\uc5d0\uc11c \uad81\uadf9\uc758 \uc11c\ubc14\uc774\ubc8c \ud06c\ub798\ud504\ud305 \ub808\uace0 \uc5b4\ub4dc\ubca4\ucc98\ub97c \ub9cc\ub098 \ubcf4\uc138\uc694!", 43 | "pt-BR": "Explore vastos mundos abertos onde a magia da constru\u00e7\u00e3o LEGO\u00ae encontra o Fortnite. Descubra a mais completa aventura LEGO\u00ae de cria\u00e7\u00e3o e sobreviv\u00eancia no Fortnite!", 44 | "ja": "LEGO\u00ae\u306e\u5efa\u7bc9\u306e\u9b54\u6cd5\u3068\u30d5\u30a9\u30fc\u30c8\u30ca\u30a4\u30c8\u304c\u51fa\u4f1a\u3046\u3001\u5e83\u5927\u306a\u30aa\u30fc\u30d7\u30f3\u30ef\u30fc\u30eb\u30c9\u3092\u63a2\u7d22\u3057\u3088\u3046\u3002 \u7a76\u6975\u306e\u30b5\u30d0\u30a4\u30d0\u30eb\u30fb\u30af\u30e9\u30d5\u30c8LEGO\u30a2\u30c9\u30d9\u30f3\u30c1\u30e3\u30fc\u3092\u30d5\u30a9\u30fc\u30c8\u30ca\u30a4\u30c8\u3067\uff01", 45 | "it": "Esplora vasti mondi aperti dove Fortnite incontra la magia delle costruzioni LEGO\u00ae. L'avventura LEGO definitiva ti aspetta in Fortnite!", 46 | "fr": "Explorez de vastes mondes ouverts o\u00f9 les univers de Fortnite et LEGO\u00ae s'entrem\u00ealent pour un r\u00e9sultat haut en couleur ! Vivez une formidable exp\u00e9rience de survie et de construction LEGO dans Fortnite !", 47 | "pl": "Eksploruj rozleg\u0142e, otwarte \u015bwiaty, w kt\u00f3rych magia budowania LEGO\u00ae \u0142\u0105czy si\u0119 z Fortnite. Odkryj w Fortnite niesamowit\u0105 przygod\u0119 LEGO z elementami przetrwania i wytwarzania!", 48 | "es": "Explora gigantescos mundos abiertos en los que la magia de la construcci\u00f3n de LEGO\u00ae se mezcla con Fortnite. \u00a1Descubre la aventura de supervivencia y construcci\u00f3n definitiva de LEGO en Fortnite!", 49 | "es-419": "Explora vastos mundos abiertos donde la magia de la construcci\u00f3n de LEGO\u00ae y Fortnite se fusionan. \u00a1Descubre la aventura de supervivencia y fabricaci\u00f3n definitiva de LEGO\u00ae en Fortnite!", 50 | "tr": "B\u00fcy\u00fcl\u00fc LEGO\u00ae yap\u0131lar\u0131n\u0131n Fortnite ile bulu\u015ftu\u011fu muazzam a\u00e7\u0131k d\u00fcnyalar\u0131 ke\u015ffet. Hayatta kalma ve \u00fcretim temal\u0131 muhte\u015fem bir LEGO maceras\u0131 \u015fimdi Fortnite'ta!" 51 | }, 52 | "feature_flags": [ 53 | "has_custom_ui" 54 | ], 55 | "product_tag": "Product.Juno", 56 | "tagline": "Explore vast, open worlds where the magic of LEGO\u00ae building and Fortnite collide. Find the ultimate survival crafting LEGO adventure in Fortnite!" 57 | }, 58 | "version": 1, 59 | "active": true, 60 | "disabled": false, 61 | "created": "2022-08-11T20:17:42.128Z", 62 | "published": "2023-11-07T23:01:02.564Z", 63 | "descriptionTags": [], 64 | "moderationStatus": "Unmoderated", 65 | "lastActivatedDate": "2022-08-11T20:17:42.132Z", 66 | "discoveryIntent": "PUBLIC" 67 | } -------------------------------------------------------------------------------- /static/discovery/latest/ltms/playlist_papaya.json: -------------------------------------------------------------------------------- 1 | { 2 | "namespace": "fn", 3 | "accountId": "epic", 4 | "creatorName": "Epic", 5 | "mnemonic": "playlist_papaya", 6 | "linkType": "BR:Playlist", 7 | "metadata": { 8 | "alt_title": { 9 | "de": "Party Royale", 10 | "ru": "Королевская вечеринка", 11 | "ko": "파티로얄", 12 | "pt-BR": "Festa Royale", 13 | "it": "Party Reale", 14 | "fr": "Fête royale", 15 | "zh-CN": "", 16 | "es": "Fiesta magistral", 17 | "es-MX": "Fiesta campal", 18 | "zh": "", 19 | "ar": "الحفل الملكي", 20 | "zh-Hant": "", 21 | "ja": "パーティーロイヤル", 22 | "pl": "Królewska Impreza", 23 | "es-419": "Fiesta campal", 24 | "tr": "Çılgın Parti" 25 | }, 26 | "image_url": "https://cdn2.unrealengine.com/partyroyale-1920-1920x1080-7001724bc7ab.jpg", 27 | "image_urls": { 28 | "url_s": "https://cdn2.unrealengine.com/partyroyale-480-480x270-a4ce24699034.jpg", 29 | "url_xs": "https://cdn2.unrealengine.com/partyroyale-256-256x144-932b805e9fb7.jpg", 30 | "url_m": "https://cdn2.unrealengine.com/partyroyale-640-640x360-983da0123af2.jpg", 31 | "url": "https://cdn2.unrealengine.com/partyroyale-1920-1920x1080-7001724bc7ab.jpg" 32 | }, 33 | "matchmaking": { 34 | "override_playlist": "playlist_papaya" 35 | }, 36 | "title": "Party Royale" 37 | }, 38 | "version": 95, 39 | "active": true, 40 | "disabled": false, 41 | "created": "2021-10-01T00:56:45.010Z", 42 | "published": "2023-11-15T23:18:49.208Z", 43 | "descriptionTags": [], 44 | "moderationStatus": "Approved", 45 | "discoveryIntent": "PUBLIC" 46 | } -------------------------------------------------------------------------------- /static/discovery/latest/ltms/playlist_trios.json: -------------------------------------------------------------------------------- 1 | { 2 | "namespace": "fn", 3 | "accountId": "epic", 4 | "creatorName": "Epic", 5 | "mnemonic": "playlist_trios", 6 | "linkType": "BR:Playlist", 7 | "metadata": { 8 | "parent_set": "set_br_playlists", 9 | "favorite_override": "set_br_playlists", 10 | "play_history_override": "set_br_playlists", 11 | "alt_title": { 12 | "de": "Trio", 13 | "ru": "Трио", 14 | "ko": "트리오", 15 | "pt-BR": "Trios", 16 | "en": "Trio", 17 | "it": "Terzetti", 18 | "fr": "Trios", 19 | "zh-CN": "", 20 | "es": "Tríos", 21 | "es-MX": "En trío", 22 | "zh": "", 23 | "ar": "ثلاثي", 24 | "zh-Hant": "", 25 | "ja": "トリオ", 26 | "pl": "Trójki", 27 | "es-419": "En trío", 28 | "tr": "Üçlü" 29 | }, 30 | "image_url": "https://cdn2.unrealengine.com/ogbr-trios-640-640x360-522fe9b4f8fb.jpg", 31 | "product_tag": "Product.BR.Build.Trio", 32 | "image_urls": { 33 | "url_s": "https://cdn2.unrealengine.com/ogbr-trios-640-640x360-522fe9b4f8fb.jpg", 34 | "url_xs": "https://cdn2.unrealengine.com/ogbr-trios-640-640x360-522fe9b4f8fb.jpg", 35 | "url_m": "https://cdn2.unrealengine.com/ogbr-trios-640-640x360-522fe9b4f8fb.jpg", 36 | "url": "https://cdn2.unrealengine.com/ogbr-trios-640-640x360-522fe9b4f8fb.jpg" 37 | }, 38 | "matchmaking": { 39 | "override_playlist": "playlist_trios" 40 | }, 41 | "video_vuid": "taqdZkWyokbCyEFWld", 42 | "title": "Trio" 43 | }, 44 | "version": 95, 45 | "active": true, 46 | "disabled": false, 47 | "created": "2021-10-01T00:56:45.053Z", 48 | "published": "2023-11-03T08:28:43.403Z", 49 | "descriptionTags": [], 50 | "moderationStatus": "Unmoderated" 51 | } -------------------------------------------------------------------------------- /static/discovery/menu.json: -------------------------------------------------------------------------------- 1 | { 2 | "Panels": [ 3 | { 4 | "PanelName": "ByEpicNoBigBattle6Col", 5 | "Pages": [ 6 | { 7 | "results": [ 8 | { 9 | "linkData": { 10 | "namespace": "fn", 11 | "mnemonic": "playlist_papaya", 12 | "linkType": "BR:Playlist", 13 | "active": true, 14 | "disabled": false, 15 | "version": 95, 16 | "moderationStatus": "Unmoderated", 17 | "accountId": "epic", 18 | "creatorName": "Epic", 19 | "descriptionTags": [], 20 | "metadata": { 21 | "image_url": "https://cdn2.unrealengine.com/partyroyale-1920-1920x1080-7001724bc7ab.jpg", 22 | "matchmaking": { 23 | "override_playlist": "playlist_papaya" 24 | } 25 | } 26 | }, 27 | "lastVisited": null, 28 | "linkCode": "playlist_papaya", 29 | "isFavorite": false 30 | }, 31 | { 32 | "linkData": { 33 | "namespace": "fn", 34 | "mnemonic": "playlist_defaultsolo", 35 | "linkType": "BR:Playlist", 36 | "active": true, 37 | "disabled": false, 38 | "version": 95, 39 | "moderationStatus": "Unmoderated", 40 | "accountId": "epic", 41 | "creatorName": "Epic", 42 | "descriptionTags": [], 43 | "metadata": { 44 | "image_url": "https://cdn2.unrealengine.com/25br-solo-1920-1920x1080-f447350aee68.jpg", 45 | "matchmaking": { 46 | "override_playlist": "playlist_defaultsolo" 47 | } 48 | } 49 | }, 50 | "lastVisited": null, 51 | "linkCode": "playlist_defaultsolo", 52 | "isFavorite": false 53 | }, 54 | { 55 | "linkData": { 56 | "namespace": "fn", 57 | "mnemonic": "playlist_defaultduo", 58 | "linkType": "BR:Playlist", 59 | "active": true, 60 | "disabled": false, 61 | "version": 95, 62 | "moderationStatus": "Unmoderated", 63 | "accountId": "epic", 64 | "creatorName": "Epic", 65 | "descriptionTags": [], 66 | "metadata": { 67 | "image_url": "https://cdn2.unrealengine.com/25br-duos-1920-1920x1080-8b0ad8cc6fd4.jpg", 68 | "matchmaking": { 69 | "override_playlist": "playlist_defaultduo" 70 | } 71 | } 72 | }, 73 | "lastVisited": null, 74 | "linkCode": "playlist_defaultduo", 75 | "isFavorite": false 76 | }, 77 | { 78 | "linkData": { 79 | "namespace": "fn", 80 | "mnemonic": "playlist_trios", 81 | "linkType": "BR:Playlist", 82 | "active": true, 83 | "disabled": false, 84 | "version": 95, 85 | "moderationStatus": "Unmoderated", 86 | "accountId": "epic", 87 | "creatorName": "Epic", 88 | "descriptionTags": [], 89 | "metadata": { 90 | "image_url": "https://cdn2.unrealengine.com/25br-trios-1920-1920x1080-9866e812b10c.jpg", 91 | "matchmaking": { 92 | "override_playlist": "playlist_trios" 93 | } 94 | } 95 | }, 96 | "lastVisited": null, 97 | "linkCode": "playlist_trios", 98 | "isFavorite": false 99 | }, 100 | { 101 | "linkData": { 102 | "namespace": "fn", 103 | "mnemonic": "playlist_defaultsquad", 104 | "linkType": "BR:Playlist", 105 | "active": true, 106 | "disabled": false, 107 | "version": 95, 108 | "moderationStatus": "Unmoderated", 109 | "accountId": "epic", 110 | "creatorName": "Epic", 111 | "descriptionTags": [], 112 | "metadata": { 113 | "image_url": "https://cdn2.unrealengine.com/25br-squads-1920-1920x1080-d515b42c587f.jpg", 114 | "matchmaking": { 115 | "override_playlist": "playlist_defaultsquad" 116 | } 117 | } 118 | }, 119 | "lastVisited": null, 120 | "linkCode": "playlist_defaultsquad", 121 | "isFavorite": false 122 | } 123 | ], 124 | "hasMore": false 125 | } 126 | ] 127 | } 128 | ], 129 | "TestCohorts": [ 130 | "testing" 131 | ], 132 | "ModeSets": {} 133 | } -------------------------------------------------------------------------------- /static/hotfixes/DefaultEngine.ini: -------------------------------------------------------------------------------- 1 | [Core.Log] 2 | LogScheduledEvents=NoLogging 3 | LogSparksSongCatalog=NoLogging 4 | LogPrm=NoLogging 5 | LogIas=NoLogging 6 | LogEOSSDK=NoLogging 7 | LogFortCreativeDiscoverySurfaceManager=NoLogging 8 | LogGarbage=NoLogging 9 | LogQos=NoLogging 10 | 11 | [/Script/Qos.QosRegionManager] 12 | NumTestsPerRegion=1 13 | PingTimeout=0.1 14 | ForceRegionId="EU" 15 | 16 | [ConsoleVariables] 17 | Store.EnableCatabaScreen=1 18 | Store.EnableCatabaHighlights=1 19 | FortPlaylistManager.CachedPlaylistsEnabled=1 20 | Fort.Rollback.UseCosmeticFlowOnlyWhereRequired=1 21 | Athena.Frontend.ShowMPLobbyOnboardingModal=0 22 | Sparks.Catalog.MidiDecryptionKey="KbSsGNCQFmVZJE4VVIvUwRuY0zrVf3sNm//2zrfPYUU=" 23 | Fort.Rollback.DisableRarityTags=0 24 | CMS.DisableFileCache=true 25 | 26 | [OnlineSubsystemMcp] 27 | bUsePartySystemV2=false -------------------------------------------------------------------------------- /static/hotfixes/DefaultGame.ini: -------------------------------------------------------------------------------- 1 | [/Script/FortniteGame.FortGameInstance] 2 | bBattleRoyaleMatchmakingEnabled=true 3 | !FrontEndPlaylistData=ClearArray 4 | +FrontEndPlaylistData=(PlaylistName=Playlist_Buffet, PlaylistAccess=(bEnabled=true, CategoryIndex=1, DisplayPriority=-999)) 5 | +FrontEndPlaylistData=(PlaylistName=Playlist_Kiwi, PlaylistAccess=(bEnabled=true, CategoryIndex=1, DisplayPriority=-999)) 6 | +FrontEndPlaylistData=(PlaylistName=Playlist_Yogurt, PlaylistAccess=(bEnabled=true, CategoryIndex=1, DisplayPriority=-999)) 7 | +FrontEndPlaylistData=(PlaylistName=Playlist_Junior_32, PlaylistAccess=(bEnabled=true, CategoryIndex=1, DisplayPriority=-999)) 8 | +FrontEndPlaylistData=(PlaylistName=Playlist_Guava, PlaylistAccess=(bEnabled=true, CategoryIndex=1, DisplayPriority=-999)) 9 | +FrontEndPlaylistData=(PlaylistName=Playlist_Buffet, PlaylistAccess=(bEnabled=true, CategoryIndex=1, DisplayPriority=-999)) 10 | +FrontEndPlaylistData=(PlaylistName=Playlist_Fritter_64, PlaylistAccess=(bEnabled=false, CategoryIndex=1, DisplayPriority=-999)) 11 | +FrontEndPlaylistData=(PlaylistName=Playlist_Music_High, PlaylistAccess=(bEnabled=false, CategoryIndex=1, DisplayPriority=-999)) 12 | +FrontEndPlaylistData=(PlaylistName=Playlist_Music_Highest, PlaylistAccess=(bEnabled=false, CategoryIndex=1, DisplayPriority=-999)) 13 | +FrontEndPlaylistData=(PlaylistName=Playlist_Music_Higher, PlaylistAccess=(bEnabled=false, CategoryIndex=1, DisplayPriority=-999)) 14 | +FrontEndPlaylistData=(PlaylistName=Playlist_Music_Med, PlaylistAccess=(bEnabled=false, CategoryIndex=1, DisplayPriority=-999)) 15 | +FrontEndPlaylistData=(PlaylistName=Playlist_Music_Low, PlaylistAccess=(bEnabled=false, CategoryIndex=1, DisplayPriority=-999)) 16 | +FrontEndPlaylistData=(PlaylistName=Playlist_Music_Lowest, PlaylistAccess=(bEnabled=false, CategoryIndex=1, DisplayPriority=-999)) 17 | +FrontEndPlaylistData=(PlaylistName=Playlist_Music_Lower, PlaylistAccess=(bEnabled=false, CategoryIndex=1, DisplayPriority=-999)) 18 | +FrontEndPlaylistData=(PlaylistName=Playlist_Pumpkin, PlaylistAccess=(bEnabled=true, CategoryIndex=1, DisplayPriority=-999)) 19 | +FrontEndPlaylistData=(PlaylistName=Playlist_Armadillo, PlaylistAccess=(bEnabled=true, CategoryIndex=1, DisplayPriority=-999)) 20 | +FrontEndPlaylistData=(PlaylistName=Playlist_Radish, PlaylistAccess=(bEnabled=true, CategoryIndex=1, DisplayPriority=-999)) 21 | +FrontEndPlaylistData=(PlaylistName=Playlist_DefaultSolo, PlaylistAccess=(bEnabled=true, CategoryIndex=0, DisplayPriority=1, bIsDefaultPlaylist=true)) 22 | +FrontEndPlaylistData=(PlaylistName=Playlist_Papaya, PlaylistAccess=(bEnabled=true, CategoryIndex=0, DisplayPriority=2, bIsDefaultPlaylist=true)) 23 | +FrontEndPlaylistData=(PlaylistName=Playlist_BattleLab, PlaylistAccess=(bEnabled=true, bIsDefaultPlaylist=true, bDisplayAsLimitedTime=false, DisplayPriority=0, CategoryIndex=3)) 24 | +FrontEndPlaylistData=(PlaylistName=Playlist_PlaygroundV2, PlaylistAccess=(bEnabled=true, CategoryIndex=0, DisplayPriority=4, bIsDefaultPlaylist=true)) 25 | +PlaylistOverrides=(PlaylistName=Playlist_DefaultSolo, bEnabled=true) 26 | +PlaylistOverrides=(PlaylistName=Playlist_DefaultDuo, bEnabled=true) 27 | +PlaylistOverrides=(PlaylistName=Playlist_DefaultSquad, bEnabled=true) 28 | +PlaylistOverrides=(PlaylistName=Playlist_Carmine, bEnabled=true) 29 | 30 | [VoiceChatManager] 31 | bEnabled=true 32 | bObtainJoinTokenFromPartyService=false 33 | MaxRetries=0 34 | VoiceChatImplementation= 35 | 36 | [/Script/FortniteGame.FortOnlineAccount] 37 | bEnableEulaCheck=false 38 | bPromptUserAndReverifyAuthToken=false 39 | 40 | [/Script/Account.OnlineAccountCommon] 41 | bEnableWaitingRoom=false 42 | 43 | [EpicPurchaseFlow] 44 | bUsePaymentWeb=false 45 | bEnabled=true 46 | 47 | [/Script/FortniteGame.FortAnalyticsConfig] 48 | UrlEndpoint="" 49 | !AltDomains="Clear" 50 | b50v50ForceEnabled=true 51 | bPlatoonForceEnabled=true 52 | bShootingTest3Enabled=true 53 | bEvent1ForceEnabled=true 54 | bEvent2ForceEnabled=true 55 | bEvent3ForceEnabled=true 56 | bEvent4ForceEnabled=true 57 | bEvent5ForceEnabled=true 58 | bEvent6ForceEnabled=true 59 | bEvent7ForceEnabled=true 60 | bEvent8ForceEnabled=true -------------------------------------------------------------------------------- /static/hotfixes/DefaultInput.ini: -------------------------------------------------------------------------------- 1 | [/Script/Engine.InputSettings] 2 | +ConsoleKeys=Tilde 3 | +ConsoleKeys=F8 -------------------------------------------------------------------------------- /static/hotfixes/DefaultRuntimeOptions.ini: -------------------------------------------------------------------------------- 1 | 2 | [/Script/FortniteGame.FortRuntimeOptions] 3 | !ExperimentalCohortPercent=ClearArray 4 | !AthenaStarterGameMode=ClearArray 5 | !HiddenSettings=ClearArray 6 | !DisabledFrontendNavigationTabs=ClearArray 7 | bShowStoreBanner=true 8 | bEnableCatabaDynamicBackground=true 9 | bShouldAllowNightNightMode=true 10 | bForceEverybodyToGoNightNight=false 11 | bEnableSocialTab=false 12 | bSkipTrailerMovie=true 13 | bEnableRufusOnePageShop=false 14 | bIsOutOfSeasonMode=false 15 | bHabaneroEnabled=false 16 | +AthenaStarterGameMode="Playlist_DefaultSolo" 17 | +AthenaStarterGameMode="Playlist_DefaultDuo" 18 | +AthenaStarterGameMode="Playlist_DefaultSquad" 19 | +ExperimentalCohortPercent=(CohortPercent=100,ExperimentNum=14) 20 | +ExperimentalCohortPercent=(CohortPercent=100,ExperimentNum=15) 21 | +ExperimentalCohortPercent=(CohortPercent=100,ExperimentNum=20) 22 | +ExperimentalCohortPercent=(CohortPercent=100,ExperimentNum=21) 23 | +ExperimentalCohortPercent=(CohortPercent=100,ExperimentNum=22) 24 | +ExperimentalCohortPercent=(CohortPercent=100,ExperimentNum=23) 25 | +ExperimentalCohortPercent=(CohortPercent=100,ExperimentNum=24) 26 | +ExperimentalBucketPercentList=(ExperimentNum=35,Name="AllowShopBillboardOfferGroups",BucketPercents=(0,100)) 27 | +ExperimentalBucketPercentList=(ExperimentNum=36,Name="AllowShopBillboardOfferGroups_2",BucketPercents=(0,100)) 28 | +ExperimentalBucketPercentList=(ExperimentNum=37,Name="AllowShopBillboardOfferGroups_3",BucketPercents=(0,100)) 29 | +ExperimentalBucketPercentList=(ExperimentNum=38,Name="AllowShopBillboardOfferGroups_4",BucketPercents=(0,100)) 30 | +ExperimentalBucketPercentList=(ExperimentNum=39,Name="AllowShopBillboardOfferGroups_5",BucketPercents=(0,100)) 31 | +ExperimentalBucketPercentList=(ExperimentNum=40,Name="AllowShopBillboardOfferGroups_6",BucketPercents=(0,100)) 32 | +ExperimentalBucketPercentList=(ExperimentNum=41,Name="AllowShopBillboardOfferGroups_7",BucketPercents=(0,100)) 33 | +ExperimentalBucketPercentList=(ExperimentNum=42,Name="AllowShopBillboardOfferGroups_8",BucketPercents=(0,100)) 34 | +ExperimentalBucketPercentList=(ExperimentNum=43,Name="AllowShopBillboardOfferGroups_9",BucketPercents=(0,100)) 35 | +ExperimentalBucketPercentList=(ExperimentNum=44,Name="AllowShopBillboardOfferGroups_10",BucketPercents=(0,100)) 36 | +ExperimentalBucketPercentList=(ExperimentNum=45,Name="AllowShopBillboardOfferGroups_11",BucketPercents=(0,100)) 37 | +ExperimentalBucketPercentList=(ExperimentNum=46,Name="AllowShopBillboardOfferGroups_12",BucketPercents=(0,100)) 38 | -------------------------------------------------------------------------------- /static/profiles/profile_campaign.json: -------------------------------------------------------------------------------- 1 | { 2 | "created": "", 3 | "updated": "", 4 | "rvn": 0, 5 | "wipeNumber": 1, 6 | "accountId": "", 7 | "profileId": "campaign", 8 | "version": "no_version", 9 | "items": { 10 | "Token:Moonlight": { 11 | "templateId": "Token:Moonlight", 12 | "attributes": { 13 | "item_seen": true 14 | }, 15 | "quantity": 1 16 | } 17 | }, 18 | "stats": { 19 | "attributes": { 20 | "inventory_limit_bonus": 0 21 | } 22 | }, 23 | "commandRevision": 0 24 | } -------------------------------------------------------------------------------- /static/profiles/profile_collections.json: -------------------------------------------------------------------------------- 1 | { 2 | "created": "", 3 | "updated": "", 4 | "rvn": 0, 5 | "wipeNumber": 1, 6 | "accountId": "", 7 | "profileId": "collections", 8 | "version": "no_version", 9 | "items": { 10 | "Token:Moonlight": { 11 | "templateId": "Token:Moonlight", 12 | "attributes": { 13 | "item_seen": true 14 | }, 15 | "quantity": 1 16 | } 17 | }, 18 | "stats": { 19 | "attributes": { 20 | "inventory_limit_bonus": 0 21 | } 22 | }, 23 | "commandRevision": 0 24 | } -------------------------------------------------------------------------------- /static/profiles/profile_common_core.json: -------------------------------------------------------------------------------- 1 | { 2 | "created": "", 3 | "updated": "", 4 | "rvn": 3, 5 | "wipeNumber": 1, 6 | "accountId": "", 7 | "profileId": "common_core", 8 | "version": "no_version", 9 | "items": { 10 | "Currency:MtxPurchased": { 11 | "templateId": "Currency:MtxPurchased", 12 | "attributes": { 13 | "platform": "EpicPC" 14 | }, 15 | "quantity": 0 16 | }, 17 | "HomebaseBannerColor:DefaultColor1": { 18 | "templateId": "HomebaseBannerColor:DefaultColor1", 19 | "attributes": { 20 | "item_seen": true 21 | }, 22 | "quantity": 1 23 | }, 24 | "HomebaseBannerColor:DefaultColor2": { 25 | "templateId": "HomebaseBannerColor:DefaultColor2", 26 | "attributes": { 27 | "item_seen": true 28 | }, 29 | "quantity": 1 30 | }, 31 | "HomebaseBannerColor:DefaultColor3": { 32 | "templateId": "HomebaseBannerColor:DefaultColor3", 33 | "attributes": { 34 | "item_seen": true 35 | }, 36 | "quantity": 1 37 | }, 38 | "HomebaseBannerColor:DefaultColor4": { 39 | "templateId": "HomebaseBannerColor:DefaultColor4", 40 | "attributes": { 41 | "item_seen": true 42 | }, 43 | "quantity": 1 44 | }, 45 | "HomebaseBannerColor:DefaultColor5": { 46 | "templateId": "HomebaseBannerColor:DefaultColor5", 47 | "attributes": { 48 | "item_seen": true 49 | }, 50 | "quantity": 1 51 | }, 52 | "HomebaseBannerColor:DefaultColor6": { 53 | "templateId": "HomebaseBannerColor:DefaultColor6", 54 | "attributes": { 55 | "item_seen": true 56 | }, 57 | "quantity": 1 58 | }, 59 | "HomebaseBannerColor:DefaultColor7": { 60 | "templateId": "HomebaseBannerColor:DefaultColor7", 61 | "attributes": { 62 | "item_seen": true 63 | }, 64 | "quantity": 1 65 | }, 66 | "HomebaseBannerColor:DefaultColor8": { 67 | "templateId": "HomebaseBannerColor:DefaultColor8", 68 | "attributes": { 69 | "item_seen": true 70 | }, 71 | "quantity": 1 72 | }, 73 | "HomebaseBannerColor:DefaultColor9": { 74 | "templateId": "HomebaseBannerColor:DefaultColor9", 75 | "attributes": { 76 | "item_seen": true 77 | }, 78 | "quantity": 1 79 | }, 80 | "HomebaseBannerColor:DefaultColor10": { 81 | "templateId": "HomebaseBannerColor:DefaultColor10", 82 | "attributes": { 83 | "item_seen": true 84 | }, 85 | "quantity": 1 86 | }, 87 | "HomebaseBannerColor:DefaultColor11": { 88 | "templateId": "HomebaseBannerColor:DefaultColor11", 89 | "attributes": { 90 | "item_seen": true 91 | }, 92 | "quantity": 1 93 | }, 94 | "HomebaseBannerColor:DefaultColor12": { 95 | "templateId": "HomebaseBannerColor:DefaultColor12", 96 | "attributes": { 97 | "item_seen": true 98 | }, 99 | "quantity": 1 100 | }, 101 | "HomebaseBannerColor:DefaultColor13": { 102 | "templateId": "HomebaseBannerColor:DefaultColor13", 103 | "attributes": { 104 | "item_seen": true 105 | }, 106 | "quantity": 1 107 | }, 108 | "HomebaseBannerColor:DefaultColor14": { 109 | "templateId": "HomebaseBannerColor:DefaultColor14", 110 | "attributes": { 111 | "item_seen": true 112 | }, 113 | "quantity": 1 114 | }, 115 | "HomebaseBannerColor:DefaultColor15": { 116 | "templateId": "HomebaseBannerColor:DefaultColor15", 117 | "attributes": { 118 | "item_seen": true 119 | }, 120 | "quantity": 1 121 | }, 122 | "HomebaseBannerColor:DefaultColor16": { 123 | "templateId": "HomebaseBannerColor:DefaultColor16", 124 | "attributes": { 125 | "item_seen": true 126 | }, 127 | "quantity": 1 128 | }, 129 | "HomebaseBannerColor:DefaultColor17": { 130 | "templateId": "HomebaseBannerColor:DefaultColor17", 131 | "attributes": { 132 | "item_seen": true 133 | }, 134 | "quantity": 1 135 | }, 136 | "HomebaseBannerColor:DefaultColor18": { 137 | "templateId": "HomebaseBannerColor:DefaultColor18", 138 | "attributes": { 139 | "item_seen": true 140 | }, 141 | "quantity": 1 142 | }, 143 | "HomebaseBannerColor:DefaultColor19": { 144 | "templateId": "HomebaseBannerColor:DefaultColor19", 145 | "attributes": { 146 | "item_seen": true 147 | }, 148 | "quantity": 1 149 | }, 150 | "HomebaseBannerColor:DefaultColor20": { 151 | "templateId": "HomebaseBannerColor:DefaultColor20", 152 | "attributes": { 153 | "item_seen": true 154 | }, 155 | "quantity": 1 156 | }, 157 | "HomebaseBannerColor:DefaultColor21": { 158 | "templateId": "HomebaseBannerColor:DefaultColor21", 159 | "attributes": { 160 | "item_seen": true 161 | }, 162 | "quantity": 1 163 | }, 164 | "HomebaseBannerIcon:StandardBanner1": { 165 | "templateId": "HomebaseBannerIcon:StandardBanner1", 166 | "attributes": { 167 | "item_seen": true 168 | }, 169 | "quantity": 1 170 | }, 171 | "HomebaseBannerIcon:StandardBanner2": { 172 | "templateId": "HomebaseBannerIcon:StandardBanner2", 173 | "attributes": { 174 | "item_seen": true 175 | }, 176 | "quantity": 1 177 | }, 178 | "HomebaseBannerIcon:StandardBanner3": { 179 | "templateId": "HomebaseBannerIcon:StandardBanner3", 180 | "attributes": { 181 | "item_seen": true 182 | }, 183 | "quantity": 1 184 | }, 185 | "HomebaseBannerIcon:StandardBanner4": { 186 | "templateId": "HomebaseBannerIcon:StandardBanner4", 187 | "attributes": { 188 | "item_seen": true 189 | }, 190 | "quantity": 1 191 | }, 192 | "HomebaseBannerIcon:StandardBanner5": { 193 | "templateId": "HomebaseBannerIcon:StandardBanner5", 194 | "attributes": { 195 | "item_seen": true 196 | }, 197 | "quantity": 1 198 | }, 199 | "HomebaseBannerIcon:StandardBanner6": { 200 | "templateId": "HomebaseBannerIcon:StandardBanner6", 201 | "attributes": { 202 | "item_seen": true 203 | }, 204 | "quantity": 1 205 | }, 206 | "HomebaseBannerIcon:StandardBanner7": { 207 | "templateId": "HomebaseBannerIcon:StandardBanner7", 208 | "attributes": { 209 | "item_seen": true 210 | }, 211 | "quantity": 1 212 | }, 213 | "HomebaseBannerIcon:StandardBanner8": { 214 | "templateId": "HomebaseBannerIcon:StandardBanner8", 215 | "attributes": { 216 | "item_seen": true 217 | }, 218 | "quantity": 1 219 | }, 220 | "HomebaseBannerIcon:StandardBanner9": { 221 | "templateId": "HomebaseBannerIcon:StandardBanner9", 222 | "attributes": { 223 | "item_seen": true 224 | }, 225 | "quantity": 1 226 | }, 227 | "HomebaseBannerIcon:StandardBanner10": { 228 | "templateId": "HomebaseBannerIcon:StandardBanner10", 229 | "attributes": { 230 | "item_seen": true 231 | }, 232 | "quantity": 1 233 | }, 234 | "HomebaseBannerIcon:StandardBanner11": { 235 | "templateId": "HomebaseBannerIcon:StandardBanner11", 236 | "attributes": { 237 | "item_seen": true 238 | }, 239 | "quantity": 1 240 | }, 241 | "HomebaseBannerIcon:StandardBanner12": { 242 | "templateId": "HomebaseBannerIcon:StandardBanner12", 243 | "attributes": { 244 | "item_seen": true 245 | }, 246 | "quantity": 1 247 | }, 248 | "HomebaseBannerIcon:StandardBanner13": { 249 | "templateId": "HomebaseBannerIcon:StandardBanner13", 250 | "attributes": { 251 | "item_seen": true 252 | }, 253 | "quantity": 1 254 | }, 255 | "HomebaseBannerIcon:StandardBanner14": { 256 | "templateId": "HomebaseBannerIcon:StandardBanner14", 257 | "attributes": { 258 | "item_seen": true 259 | }, 260 | "quantity": 1 261 | }, 262 | "HomebaseBannerIcon:StandardBanner15": { 263 | "templateId": "HomebaseBannerIcon:StandardBanner15", 264 | "attributes": { 265 | "item_seen": true 266 | }, 267 | "quantity": 1 268 | }, 269 | "HomebaseBannerIcon:StandardBanner16": { 270 | "templateId": "HomebaseBannerIcon:StandardBanner16", 271 | "attributes": { 272 | "item_seen": true 273 | }, 274 | "quantity": 1 275 | }, 276 | "HomebaseBannerIcon:StandardBanner17": { 277 | "templateId": "HomebaseBannerIcon:StandardBanner17", 278 | "attributes": { 279 | "item_seen": true 280 | }, 281 | "quantity": 1 282 | }, 283 | "HomebaseBannerIcon:StandardBanner18": { 284 | "templateId": "HomebaseBannerIcon:StandardBanner18", 285 | "attributes": { 286 | "item_seen": true 287 | }, 288 | "quantity": 1 289 | }, 290 | "HomebaseBannerIcon:StandardBanner19": { 291 | "templateId": "HomebaseBannerIcon:StandardBanner19", 292 | "attributes": { 293 | "item_seen": true 294 | }, 295 | "quantity": 1 296 | }, 297 | "HomebaseBannerIcon:StandardBanner20": { 298 | "templateId": "HomebaseBannerIcon:StandardBanner20", 299 | "attributes": { 300 | "item_seen": true 301 | }, 302 | "quantity": 1 303 | }, 304 | "HomebaseBannerIcon:StandardBanner21": { 305 | "templateId": "HomebaseBannerIcon:StandardBanner21", 306 | "attributes": { 307 | "item_seen": true 308 | }, 309 | "quantity": 1 310 | }, 311 | "HomebaseBannerIcon:StandardBanner22": { 312 | "templateId": "HomebaseBannerIcon:StandardBanner22", 313 | "attributes": { 314 | "item_seen": true 315 | }, 316 | "quantity": 1 317 | }, 318 | "HomebaseBannerIcon:StandardBanner23": { 319 | "templateId": "HomebaseBannerIcon:StandardBanner23", 320 | "attributes": { 321 | "item_seen": true 322 | }, 323 | "quantity": 1 324 | }, 325 | "HomebaseBannerIcon:StandardBanner24": { 326 | "templateId": "HomebaseBannerIcon:StandardBanner24", 327 | "attributes": { 328 | "item_seen": true 329 | }, 330 | "quantity": 1 331 | }, 332 | "HomebaseBannerIcon:StandardBanner25": { 333 | "templateId": "HomebaseBannerIcon:StandardBanner25", 334 | "attributes": { 335 | "item_seen": true 336 | }, 337 | "quantity": 1 338 | }, 339 | "HomebaseBannerIcon:StandardBanner26": { 340 | "templateId": "HomebaseBannerIcon:StandardBanner26", 341 | "attributes": { 342 | "item_seen": true 343 | }, 344 | "quantity": 1 345 | }, 346 | "HomebaseBannerIcon:StandardBanner27": { 347 | "templateId": "HomebaseBannerIcon:StandardBanner27", 348 | "attributes": { 349 | "item_seen": true 350 | }, 351 | "quantity": 1 352 | }, 353 | "HomebaseBannerIcon:StandardBanner28": { 354 | "templateId": "HomebaseBannerIcon:StandardBanner28", 355 | "attributes": { 356 | "item_seen": true 357 | }, 358 | "quantity": 1 359 | }, 360 | "HomebaseBannerIcon:StandardBanner29": { 361 | "templateId": "HomebaseBannerIcon:StandardBanner29", 362 | "attributes": { 363 | "item_seen": true 364 | }, 365 | "quantity": 1 366 | }, 367 | "HomebaseBannerIcon:StandardBanner30": { 368 | "templateId": "HomebaseBannerIcon:StandardBanner30", 369 | "attributes": { 370 | "item_seen": true 371 | }, 372 | "quantity": 1 373 | }, 374 | "HomebaseBannerIcon:StandardBanner31": { 375 | "templateId": "HomebaseBannerIcon:StandardBanner31", 376 | "attributes": { 377 | "item_seen": true 378 | }, 379 | "quantity": 1 380 | } 381 | }, 382 | "stats": { 383 | "attributes": { 384 | "survey_data": {}, 385 | "personal_offers": {}, 386 | "intro_game_played": true, 387 | "import_friends_claimed": {}, 388 | "mtx_purchase_history": { 389 | "refundsUsed": 0, 390 | "refundCredits": 3, 391 | "purchases": [] 392 | }, 393 | "undo_cooldowns": [], 394 | "mtx_affiliate_set_time": "2024-12-13T03:51:56.381Z", 395 | "inventory_limit_bonus": 0, 396 | "current_mtx_platform": "EpicPC", 397 | "mtx_affiliate": "f", 398 | "forced_intro_played": "Coconut", 399 | "weekly_purchases": {}, 400 | "daily_purchases": {}, 401 | "ban_history": {}, 402 | "in_app_purchases": {}, 403 | "permissions": [], 404 | "undo_timeout": "min", 405 | "monthly_purchases": {}, 406 | "allowed_to_send_gifts": true, 407 | "mfa_enabled": true, 408 | "allowed_to_receive_gifts": true, 409 | "gift_history": {} 410 | } 411 | }, 412 | "commandRevision": 2 413 | } -------------------------------------------------------------------------------- /static/profiles/profile_common_public.json: -------------------------------------------------------------------------------- 1 | { 2 | "created": "", 3 | "updated": "", 4 | "rvn": 1, 5 | "wipeNumber": 1, 6 | "accountId": "", 7 | "profileId": "common_public", 8 | "version": "12", 9 | "items": { 10 | "Token:Moonlight": { 11 | "templateId": "Token:Moonlight", 12 | "attributes": { 13 | "item_seen": true 14 | }, 15 | "quantity": 1 16 | } 17 | }, 18 | "stats": { 19 | "attributes": { 20 | "inventory_limit_bonus": 0 21 | } 22 | }, 23 | "commandRevision": 0 24 | } -------------------------------------------------------------------------------- /static/profiles/profile_creative.json: -------------------------------------------------------------------------------- 1 | { 2 | "created": "", 3 | "updated": "", 4 | "rvn": 0, 5 | "wipeNumber": 1, 6 | "accountId": "", 7 | "profileId": "creative", 8 | "version": "no_version", 9 | "items": { 10 | "Token:Solora": { 11 | "templateId": "Token:Moonlight", 12 | "attributes": { 13 | "item_seen": true 14 | }, 15 | "quantity": 1 16 | } 17 | }, 18 | "stats": { 19 | "attributes": { 20 | "inventory_limit_bonus": 0 21 | } 22 | }, 23 | "commandRevision": 0 24 | } -------------------------------------------------------------------------------- /static/profiles/profile_metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "created": "", 3 | "updated": "", 4 | "rvn": 0, 5 | "wipeNumber": 1, 6 | "accountId": "", 7 | "profileId": "metadata", 8 | "version": "no_version", 9 | "items": { 10 | "Token:Moonlight": { 11 | "templateId": "Token:Moonlight", 12 | "attributes": { 13 | "item_seen": true 14 | }, 15 | "quantity": 1 16 | } 17 | }, 18 | "stats": { 19 | "attributes": { 20 | "inventory_limit_bonus": 0 21 | } 22 | }, 23 | "commandRevision": 0 24 | } -------------------------------------------------------------------------------- /static/profiles/profile_outpost0.json: -------------------------------------------------------------------------------- 1 | { 2 | "created": "", 3 | "updated": "", 4 | "rvn": 0, 5 | "wipeNumber": 1, 6 | "accountId": "", 7 | "profileId": "outpost0", 8 | "version": "no_version", 9 | "items": { 10 | "Token:Moonlight": { 11 | "templateId": "Token:Moonlight", 12 | "attributes": { 13 | "item_seen": true 14 | }, 15 | "quantity": 1 16 | } 17 | }, 18 | "stats": { 19 | "attributes": { 20 | "inventory_limit_bonus": 0 21 | } 22 | }, 23 | "commandRevision": 0 24 | } -------------------------------------------------------------------------------- /static/profiles/profile_theater0.json: -------------------------------------------------------------------------------- 1 | { 2 | "created": "", 3 | "updated": "", 4 | "rvn": 0, 5 | "wipeNumber": 1, 6 | "accountId": "", 7 | "profileId": "theater0", 8 | "version": "no_version", 9 | "items": { 10 | "Token:Moonlight": { 11 | "templateId": "Token:Moonlight", 12 | "attributes": { 13 | "item_seen": true 14 | }, 15 | "quantity": 1 16 | } 17 | }, 18 | "stats": { 19 | "attributes": { 20 | "inventory_limit_bonus": 0 21 | } 22 | }, 23 | "commandRevision": 0 24 | } -------------------------------------------------------------------------------- /static/shop/v2.json: -------------------------------------------------------------------------------- 1 | { 2 | "refreshIntervalHrs": 99, 3 | "dailyPurchaseHrs": 24, 4 | "expiration": "9999-12-11T01:00:00.000Z", 5 | "storefronts": [ 6 | { 7 | "name": "BRWeeklyStorefront", 8 | "catalogEntries": [ 9 | { 10 | "devName": "[VIRTUAL]1 x Funny Thing for -9 MtxCurrency", 11 | "fulfillmentIds": [], 12 | "dailyLimit": -1, 13 | "weeklyLimit": -1, 14 | "monthlyLimit": -1, 15 | "categories": [], 16 | "prices": [ 17 | { 18 | "currencyType": "MtxCurrency", 19 | "currencySubType": "", 20 | "regularPrice": -999999, 21 | "dynamicRegularPrice": -999999, 22 | "finalPrice": -999999, 23 | "saleExpiration": "9999-12-31T23:59:59", 24 | "basePrice": -999999 25 | } 26 | ], 27 | "matchFilter": "", 28 | "filterWeight": 0.0, 29 | "appStoreId": [], 30 | "requirements": [ 31 | { 32 | "requirementType": "DenyOnItemOwnership", 33 | "minQuantity": 1, 34 | "requiredId": "AthenaCharacter:Character_RareDelightSail" 35 | } 36 | ], 37 | "offerType": "StaticPrice", 38 | "giftInfo": { 39 | "bIsEnabled": true, 40 | "forcedGiftBoxTemplateId": "", 41 | "purchaseRequirements": [], 42 | "giftRecordIds": [] 43 | }, 44 | "refundable": true, 45 | "itemGrants": [ 46 | { 47 | "quantity": 10, 48 | "templateId": "AthenaCharacter:Character_RareDelightSail" 49 | } 50 | ], 51 | "additionalGrants": [], 52 | "sortPriority": -2, 53 | "catalogGroupPriority": 0, 54 | "offerId": "v2:/kw8GEziSd4OlkuH1e3MBlH463Ai3VBc29Cn5nOTBYJNks", 55 | "meta": { 56 | "AnalyticOfferGroupId": "ISTHISNEEDED??", 57 | "FirstSeen": "31/12/9999", 58 | "NewDisplayAssetPath": "/Game/Catalog/NewDisplayAssets/S28/DAv2_Character_RareDelightSail.DAv2_Character_RareDelightSail", 59 | "SectionId": "Daily", 60 | "LayoutId": "Daily.1", 61 | "TileSize": "Size_1_x_2" 62 | }, 63 | "metaInfo": [ 64 | { 65 | "key": "NewDisplayAssetPath", 66 | "value": "/Game/Catalog/NewDisplayAssets/S28/DAv2_Character_RareDelightSail.DAv2_Character_RareDelightSail" 67 | }, 68 | { 69 | "key": "SectionId", 70 | "value": "Daily" 71 | }, 72 | { 73 | "key": "TileSize", 74 | "value": "Size_1_x_2" 75 | }, 76 | { 77 | "key": "LayoutId", 78 | "value": "Daily.1" 79 | } 80 | ], 81 | "displayAssetPath": "/Game/Catalog/DisplayAssets/DA_Featured_Character_RareDelightSail.DA_Featured_Character_RareDelightSail" 82 | } 83 | ] 84 | }, 85 | { 86 | "name": "TokensForGiftableItems", 87 | "catalogEntries": [ 88 | { 89 | "offerId": "02A0B24240C2528B435EF4817E89070F", 90 | "devName": "Glow Select", 91 | "offerType": "StaticPrice", 92 | "prices": [ 93 | { 94 | "currencyType": "RealMoney", 95 | "currencySubType": "", 96 | "regularPrice": 0, 97 | "dynamicRegularPrice": -1, 98 | "finalPrice": 0, 99 | "saleExpiration": "9999-12-31T23:59:59.999Z", 100 | "basePrice": 0 101 | } 102 | ], 103 | "categories": [], 104 | "dailyLimit": -1, 105 | "weeklyLimit": -1, 106 | "monthlyLimit": -1, 107 | "refundable": false, 108 | "appStoreId": [ 109 | "", 110 | "", 111 | "", 112 | "", 113 | "", 114 | "", 115 | "", 116 | "", 117 | "", 118 | "sam_glow", 119 | "", 120 | "" 121 | ], 122 | "requirements": [ 123 | { 124 | "requirementType": "DenyOnFulfillment", 125 | "requiredId": "230FA67742DD9570005A8C82D81A33FC", 126 | "minQuantity": 1 127 | } 128 | ], 129 | "metaInfo": [], 130 | "catalogGroup": "", 131 | "catalogGroupPriority": 0, 132 | "sortPriority": 0, 133 | "title": "Glow", 134 | "shortDescription": "", 135 | "description": "The aura of victory glows bright.", 136 | "displayAssetPath": "/Game/Catalog/DisplayAssets/DA_Featured_CID_479_Athena_Commando_F_Davinci.DA_Featured_CID_479_Athena_Commando_F_Davinci", 137 | "itemGrants": [ 138 | { 139 | "templateId": "Token:giftglowtoken", 140 | "quantity": 1, 141 | "attributes": {} 142 | } 143 | ] 144 | } 145 | ] 146 | }, 147 | { 148 | "name": "BRSeason11", 149 | "catalogEntries": [ 150 | { 151 | "offerId": "571D433C47E98F020EF099894CAF3B6A", 152 | "devName": "BR.Season11.BattlePass.01", 153 | "offerType": "StaticPrice", 154 | "prices": [ 155 | { 156 | "currencyType": "MtxCurrency", 157 | "currencySubType": "", 158 | "regularPrice": 950, 159 | "dynamicRegularPrice": -1, 160 | "finalPrice": 950, 161 | "saleExpiration": "9999-12-31T23:59:59.999Z", 162 | "basePrice": 950 163 | } 164 | ], 165 | "categories": [], 166 | "dailyLimit": -1, 167 | "weeklyLimit": -1, 168 | "monthlyLimit": -1, 169 | "refundable": false, 170 | "appStoreId": [ 171 | "", 172 | "", 173 | "", 174 | "", 175 | "", 176 | "", 177 | "", 178 | "", 179 | "", 180 | "", 181 | "", 182 | "" 183 | ], 184 | "requirements": [ 185 | { 186 | "requirementType": "DenyOnFulfillment", 187 | "requiredId": "571D433C47E98F020EF099894CAF3B6A", 188 | "minQuantity": 1 189 | } 190 | ], 191 | "metaInfo": [ 192 | { 193 | "key": "Preroll", 194 | "value": "False" 195 | } 196 | ], 197 | "catalogGroup": "", 198 | "catalogGroupPriority": 0, 199 | "sortPriority": 1, 200 | "title": "Battle Pass", 201 | "shortDescription": "Chapter 2 - Season 1", 202 | "description": "Chapter 2 - Season 1 through February 6. \n\nInstantly get these items\n \u2022 Turk | Riptide Outfit\n \u2022 Journey | Hazard Outfit\n\n\nPlay to level up your Battle Pass, unlocking over 100 rewards !\n \u2022 Fusion and 4 more Outfits\n \u2022 1,500 V-Bucks\n \u2022 7 Emotes\n \u2022 6 Wraps\n \u2022 6 Harvesting Tools\n \u2022 5 Gliders\n \u2022 6 Back Blings\n \u2022 5 Contrails\n \u2022 8 Sprays\n \u2022 3 Music Tracks\n \u2022 16 Loading Screens\n \u2022 and so much more!\nWant it all faster? You can use V-Bucks to buy rewards any time!", 203 | "displayAssetPath": "/Game/Catalog/DisplayAssets/DA_BR_Season11_BattlePass.DA_BR_Season11_BattlePass", 204 | "itemGrants": [] 205 | }, 206 | { 207 | "offerId": "70DBDA11425B10AF7A005D82DB54BC59", 208 | "devName": "BR.Season11.SingleTier.01", 209 | "offerType": "StaticPrice", 210 | "prices": [ 211 | { 212 | "currencyType": "MtxCurrency", 213 | "currencySubType": "", 214 | "regularPrice": 150, 215 | "dynamicRegularPrice": -1, 216 | "finalPrice": 150, 217 | "saleExpiration": "9999-12-31T23:59:59.999Z", 218 | "basePrice": 150 219 | } 220 | ], 221 | "categories": [], 222 | "dailyLimit": -1, 223 | "weeklyLimit": -1, 224 | "monthlyLimit": -1, 225 | "refundable": false, 226 | "appStoreId": [ 227 | "", 228 | "", 229 | "", 230 | "", 231 | "", 232 | "", 233 | "", 234 | "", 235 | "", 236 | "", 237 | "", 238 | "" 239 | ], 240 | "requirements": [], 241 | "metaInfo": [ 242 | { 243 | "key": "Preroll", 244 | "value": "False" 245 | } 246 | ], 247 | "catalogGroup": "", 248 | "catalogGroupPriority": 0, 249 | "sortPriority": 0, 250 | "title": "Battle Pass Level", 251 | "shortDescription": "", 252 | "description": "Get great rewards now!", 253 | "displayAssetPath": "", 254 | "itemGrants": [] 255 | }, 256 | { 257 | "offerId": "93E992BC45D487A943D769845441ABA5", 258 | "devName": "BR.Season11.BattleBundle.01", 259 | "offerType": "StaticPrice", 260 | "prices": [ 261 | { 262 | "currencyType": "MtxCurrency", 263 | "currencySubType": "", 264 | "regularPrice": 4700, 265 | "dynamicRegularPrice": -1, 266 | "finalPrice": 2800, 267 | "saleType": "PercentOff", 268 | "saleExpiration": "9999-12-31T23:59:59.999Z", 269 | "basePrice": 2800 270 | } 271 | ], 272 | "categories": [], 273 | "dailyLimit": -1, 274 | "weeklyLimit": -1, 275 | "monthlyLimit": -1, 276 | "refundable": false, 277 | "appStoreId": [ 278 | "", 279 | "", 280 | "", 281 | "", 282 | "", 283 | "", 284 | "", 285 | "", 286 | "", 287 | "", 288 | "", 289 | "" 290 | ], 291 | "requirements": [ 292 | { 293 | "requirementType": "DenyOnFulfillment", 294 | "requiredId": "571D433C47E98F020EF099894CAF3B6A", 295 | "minQuantity": 1 296 | }, 297 | { 298 | "requirementType": "DenyOnItemOwnership", 299 | "requiredId": "Token:athena_s11_nobattlebundleoption_token", 300 | "minQuantity": 1 301 | } 302 | ], 303 | "metaInfo": [ 304 | { 305 | "key": "Preroll", 306 | "value": "False" 307 | } 308 | ], 309 | "catalogGroup": "", 310 | "catalogGroupPriority": 0, 311 | "sortPriority": 0, 312 | "title": "Battle Bundle", 313 | "shortDescription": "Battle Pass + 25 levels!", 314 | "description": "Chapter 2 - Season 1 through February 6.\n\nInstantly get these items\n \u2022 Turk | Riptide Outfit\n \u2022 Journey | Hazard Outfit\n \u2022 Rippley | Sludge Outfit\n \u2022 Respect The Peace Emote\n \u2022 Sky Trawler Glider\n \u2022 Riptide Wrap\n \u2022 Slurpstream Contrails\n \u2022 Storm Shredder Music Track\n \u2022 400 V-Bucks \n \u2022 and more!\n\nPlay to level up your Battle Pass, unlocking over 75 rewards!\n \u2022 4 more Outfits\n \u2022 1,200 V-Bucks\n \u2022 5 Emotes\n \u2022 5 Wraps\n \u2022 5 Harvesting Tools\n \u2022 4 Gliders\n \u2022 4 Back Blings\n \u2022 4 Contrails\n \u2022 5 Sprays\n \u2022 2 Music Tracks\n \u2022 13 Loading Screens\n \u2022 and so much more!\nWant it all faster? You can use V-Bucks to buy rewards any time!", 315 | "displayAssetPath": "/Game/Catalog/DisplayAssets/DA_BR_Season11_BattlePassWithLevels.DA_BR_Season11_BattlePassWithLevels", 316 | "itemGrants": [] 317 | } 318 | ] 319 | }, 320 | { 321 | "name": "BRSeason12", 322 | "catalogEntries": [] 323 | }, 324 | { 325 | "name": "BRDailyStorefront", 326 | "catalogEntries": [] 327 | } 328 | ] 329 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | // Enable latest features 4 | "lib": ["ESNext", "DOM"], 5 | "target": "ESNext", 6 | "module": "ESNext", 7 | "moduleDetection": "force", 8 | "jsx": "react-jsx", 9 | "allowJs": true, 10 | 11 | // Bundler mode 12 | "moduleResolution": "bundler", 13 | "allowImportingTsExtensions": true, 14 | "verbatimModuleSyntax": true, 15 | "noEmit": true, 16 | 17 | // Best practices 18 | "strict": true, 19 | "skipLibCheck": true, 20 | "noFallthroughCasesInSwitch": true, 21 | 22 | // Some stricter flags (disabled by default) 23 | "noUnusedLocals": false, 24 | "noUnusedParameters": false, 25 | "noPropertyAccessFromIndexSignature": false 26 | } 27 | } 28 | --------------------------------------------------------------------------------