From 2bd7754e618f40a406b28717598f941babf968ae Mon Sep 17 00:00:00 2001 From: RiftSTW Date: Wed, 11 Oct 2023 19:42:40 -0500 Subject: [PATCH] Initial commit --- INSTALL PACKAGES.bat | 3 + README.md | 26 +++++- index.js | 44 +++++++++ package-lock.json | 209 +++++++++++++++++++++++++++++++++++++++++++ package.json | 26 ++++++ settings.json | 6 ++ start.bat | 3 + 7 files changed, 316 insertions(+), 1 deletion(-) create mode 100644 INSTALL PACKAGES.bat create mode 100644 index.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 settings.json create mode 100644 start.bat diff --git a/INSTALL PACKAGES.bat b/INSTALL PACKAGES.bat new file mode 100644 index 0000000..f64cf46 --- /dev/null +++ b/INSTALL PACKAGES.bat @@ -0,0 +1,3 @@ +@echo off +npm i +pause \ No newline at end of file diff --git a/README.md b/README.md index 4641bce..71d252a 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,26 @@ # FN-RPC -Simple Fortnite Discord RPC +Display your Fortnite Statistics on your Discord Profile! + +#### SETUP GUIDE + +1. Install [Node.JS](https://nodejs.org/en) +2. Run INSTALL PACKAGES.bat +3. Obtain an API Key from [Fortnite-API.com](https://dash.fortnite-api.com/account) +4. Paste your API Key to the apiKey field in settings.json +5. Paste in your Epic Games Account ID to the epicID field in settings.json +6. Run start.bat + +### Common Issues +> The RPC won't connect! + +Make sure you have the Desktop version of Discord, not the browser version. If you use Vesktop (Discord Client with Vencord preinstalled), make sure you have Rich Presence enabled in your Vesktop settings. + +> I keep getting error: "the requested account's stats are not public" + +Launch Fortnite & Go to the Account & Privacy Settings, then set Public Game Stats to ON: + + +> How do I get my Epic Games Account ID? + +Launch Fortnite & Go to the Account & Privacy Settings, then click Copy to Clipboard. + \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..4732bc4 --- /dev/null +++ b/index.js @@ -0,0 +1,44 @@ +const { Client } = require("discord-rpc"); +const rpc = new Client({ transport: "ipc" }); +const axios = require("axios"); + +const { clientID, epicID, apiKey, assets } = require("./settings.json"); + +async function GetStats() { + try { + await axios.get(`https://fortnite-api.com/v2/stats/br/v2/${epicID}`, { + headers: { + 'Authorization': apiKey + } + }).catch(err => { + if (err.response) throw `[ERROR] ${err.response.data.error}, Status Code: ${err.response.data.status}`; + if (err) throw err; + }).then(res => { + let data = res.data.data; + + return setStatus(data.battlePass.level, data.stats.all.overall.wins, data.stats.all.overall.kills, data.stats.all.overall.deaths, data.battlePass.progress, data.account.name); + }); + } catch (err) { + console.error(err); + } +} + +async function setStatus(bp, wins, kills, deaths, progress, username) { + rpc.setActivity({ + details: `👑 ${bp.toLocaleString()} | ${progress}% (${100 - progress}% Left)`, + state: `🏆 ${wins.toLocaleString()} | 🎯 ${kills.toLocaleString()} | 💀 ${deaths.toLocaleString()}`, + largeImageKey: assets.large_img_key, + largeImageText: `Fortnite Stats for: ${username}` + }); + await new Promise((p => setTimeout(p, 60000))); + GetStats(); +} + +rpc.on("ready", async () => { + console.log('FN-RPC is now initalized.'); + GetStats(); +}) + +rpc.login({ + clientId: clientID +}); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..7de833b --- /dev/null +++ b/package-lock.json @@ -0,0 +1,209 @@ +{ + "name": "fn-rpc", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "fn-rpc", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "axios": "^1.5.1", + "discord-rpc": "^4.0.1" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.1.tgz", + "integrity": "sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/discord-rpc": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/discord-rpc/-/discord-rpc-4.0.1.tgz", + "integrity": "sha512-HOvHpbq5STRZJjQIBzwoKnQ0jHplbEWFWlPDwXXKm/bILh4nzjcg7mNqll0UY7RsjFoaXA7e/oYb/4lvpda2zA==", + "dependencies": { + "node-fetch": "^2.6.1", + "ws": "^7.3.1" + }, + "optionalDependencies": { + "register-scheme": "github:devsnek/node-register-scheme" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "optional": true + }, + "node_modules/follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-addon-api": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", + "optional": true + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/register-scheme": { + "version": "0.0.2", + "resolved": "git+ssh://git@github.com/devsnek/node-register-scheme.git#e7cc9a63a1f512565da44cb57316d9fb10750e17", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bindings": "^1.3.0", + "node-addon-api": "^1.3.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..c98583b --- /dev/null +++ b/package.json @@ -0,0 +1,26 @@ +{ + "name": "fn-rpc", + "version": "1.0.0", + "description": "Simple Fortnite Discord RPC", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/RiftSTW/FN-RPC.git" + }, + "keywords": [ + "Fortnite" + ], + "author": "RiftSTW", + "license": "ISC", + "bugs": { + "url": "https://github.com/RiftSTW/FN-RPC/issues" + }, + "homepage": "https://github.com/RiftSTW/FN-RPC#readme", + "dependencies": { + "axios": "^1.5.1", + "discord-rpc": "^4.0.1" + } +} diff --git a/settings.json b/settings.json new file mode 100644 index 0000000..00df46c --- /dev/null +++ b/settings.json @@ -0,0 +1,6 @@ +{ + "clientID": "1161759792507932755", + "epicID": "", + "apiKey": "", + "assets": { "large_img_key": "fn" } +} \ No newline at end of file diff --git a/start.bat b/start.bat new file mode 100644 index 0000000..e5c7e94 --- /dev/null +++ b/start.bat @@ -0,0 +1,3 @@ +@echo off +node index.js +pause \ No newline at end of file