From 52d1869f8b5510dab338fcabcefa48b86980a9f1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Patrick=20Sch=C3=B6nberger?= Date: Thu, 13 Dec 2018 10:57:10 +0100 Subject: [PATCH] sass server champions und regionen matches angefangen --- html/index.html | 6 +- html/script.js | 29 +++-- html/style.css | 273 ++++++++++++++++++++++++++++------------------ html/style.sass | 158 +++++++++++++++++++++++++++ index.js | 143 +++++++++++++++++++----- package-lock.json | 23 ++++ package.json | 1 + 7 files changed, 488 insertions(+), 145 deletions(-) create mode 100644 html/style.sass diff --git a/html/index.html b/html/index.html index d35e28f..25d8fce 100644 --- a/html/index.html +++ b/html/index.html @@ -2,6 +2,7 @@ + Advanced League of Legends Match History & Statistics @@ -23,7 +24,7 @@ -->
@@ -36,10 +37,11 @@
+
diff --git a/html/script.js b/html/script.js index 25f1565..a10dd69 100644 --- a/html/script.js +++ b/html/script.js @@ -1,8 +1,14 @@ function getRegions() { - return [ "euw", "na", "kr", "br" ]; + $.ajax("/lol/regions") + .done((data) => { + app.regions = JSON.parse(data); + }); } function getChampions() { - return [ {name: "Aatrox"}, {name: "Annie"}, {name: "Braum"}, {name: "Not"} ]; + $.ajax("/lol/champions") + .done((data) => { + app.champions = JSON.parse(data); + }); } function getMatchProps() { return [ @@ -11,10 +17,10 @@ function getMatchProps() { ]; } function getMatches() { - return [ - {champ: "Xerath", lane: "Middle"}, - {champ: "Quinn", lane: "Bottom"}, - ]; + $.ajax("/lol/matches?region=" + app.region + "&summoner=" + app.summoner); + .done((data) => { + app.matches = JSON.parse(data); + }); } function getInfo() { app.summoner = $("#nameinput").val(); @@ -92,10 +98,10 @@ let app = new Vue({ summoner: "", region: "", view: "", - regions: getRegions(), - champions: getChampions(), - matchprops: getMatchProps(), - matches: getMatches(), + regions: [], + champions: [], + matchprops: [], + matches: [], }, methods: { submit: function() { @@ -113,6 +119,7 @@ let app = new Vue({ setUrl(); }, refreshHistory: function() { + getMatches(); }, }, }); @@ -145,4 +152,6 @@ window.addEventListener('popstate', () => { window.addEventListener('load', () => { let view = parseUrl(); setView(view); + getRegions(); + getChampions(); }); diff --git a/html/style.css b/html/style.css index b012d22..6145c2d 100644 --- a/html/style.css +++ b/html/style.css @@ -1,70 +1,40 @@ body { - font-family: 'Noto Sans SC', sans-serif; + font-family: "Noto Sans SC", sans-serif; font-weight: bold; padding: 0px; margin: 0px; } + #background { position: fixed; width: 100%; height: 100%; - background-color: rgb(200, 50, 50); + background-color: #c83232; box-shadow: 0 0 400px rgba(0, 0, 0, 0.6) inset; } -input, select, button { - font-size:inherit; - border: none; -} -@keyframes startup { - 0% { - top: 50%; - transform: translate(-50%, -50%); - width: 65%; - } - 100% { - top: 0%; - transform: translate(-50%, 0%); - width: calc(100% - 20px); - } -} -@keyframes startdown { - 100% { - top: 50%; - transform: translate(-50%, -50%); - width: 65%; - } - 0% { - top: 0%; - transform: translate(-50%, 0%); - width: calc(100% - 20px); - } -} -#start.slideup { - animation: startup 0.3s forwards linear; -} -#start.slidedown { - animation: startdown 0.3s forwards linear; -} -#start.up { - top: 0%; - transform: translate(-50%, 0%); - width: calc(100% - 20px); -} -#start.down { - top: 50%; - transform: translate(-50%, -50%); - width: 65%; -} + #start { position: absolute; - width: 65%; - left: 50%; + margin: 7px; + left: calc(50% - 7px); top: 50%; transform: translate(-50%, -50%); - padding: 10px; text-align: center; background-color: transparent; - font-size: 5rem; + border-radius: 4px; + background-color: white; + box-shadow: 1px 1px 40px rgba(0, 0, 0, 0.8); +} + +@media only screen and (orientation: landscape) { + #start { + width: 65%; + } +} +@media only screen and (orientation: portrait) { + #start { + width: 85%; + } } #title { width: 100%; @@ -72,89 +42,176 @@ input, select, button { text-shadow: 1px 1px 40px black; user-select: none; } + #inputpanel { - border-radius: 5px; - width: calc(100% - 20px); - height: 50px; - background-color: white; - padding: 10px; - box-shadow: 1px 1px 40px rgba(0, 0, 0, 0.8); - font-size: 2rem; + width: calc(100% - 14px); + height: 7vmin; + font-size: 4.5vmin; position: relative; + margin: 7px; } -#regionselect { - width: 110px; - height: 50px; + +#matchhistory, #stats { + position: absolute; + font-size: 2.5vmin; + width: calc(100% - 14px); + min-height: calc(100% - (7vmin + 21px) - 14px); + margin: 7px; + top: calc(7vmin + 21px); + background-color: white; + border-radius: 4px; + text-align: center; +} + +#historyfilters { position: relative; - top: 0px; - padding: 0px 0px 0px 10px; - margin: 5px; + width: calc(100% - 14px); + height: calc(21vmin + 14px); + margin: 7px; +} + +#matchlist { + width: calc(100% - 14px); + margin: 7px; + height: auto; +} + +hr { + margin: 0; +} + +select { text-align: center; - background-color: rgb(200, 50, 50); +} + +select:hover { + background-color: #b41e1e; +} + +select > option { + background-color: #c83232; +} + +input { + border: none; + outline: none; + font-size: inherit; +} + +button, select { + vertical-align: baseline; + width: 18vmin; + height: 7vmin; + background-color: #c83232; color: white; - border-radius: 5px; + border-radius: 4px; border: none; outline: none; + font-size: inherit; +} + +button:hover { + background-color: #b41e1e; +} + +.bottom-right { + position: absolute; + right: 0px; + bottom: 0px; +} + +#regionselect { text-transform: uppercase; position: absolute; - left: 5px; - top: 5px; + left: 0; z-index: 1; } -#regionselect:hover { - background-color: rgb(180, 30, 30); -} -#regionselect>option { - background-color: rgb(200, 50, 50); -} + #nameinput { text-align: center; border-bottom: 1px solid lightgray; - outline: none; - margin: 5px; - width: calc(100% - 220px - 10px); - height: 50px; + width: calc(100% - 36vmin); + height: 7vmin; position: absolute; - left: 110px; - top: 5px; + left: 18vmin; + top: 0px; } + #gobutton, #statsbutton, #historybutton { position: absolute; - top: 5px; - right: 5px; + margin: 0px; + top: 0px; + right: 0px; z-index: 1; } + #refreshbutton { position: absolute; - right: 5px; - bottom: 5px; + right: 0px; + bottom: 0px; } -button { - vertical-align: baseline; - margin: 5px; - width: 110px; - height: 50px; - background-color: rgb(200, 50, 50); - color: white; - border-radius: 5px; - outline: none; + +@keyframes startup { + 0% { + top: 50%; + transform: translate(-50%, -50%); + @media only screen and (orientation: landscape) { + width: 65%; + } + @media only screen and (orientation: portrait) { + width: 85%; + } + } + 100% { + top: 0%; + transform: translate(-50%, 0%); + width: calc(100% - 14px); + } +} +@keyframes startdown { + 100% { + top: 50%; + transform: translate(-50%, -50%); + @media only screen and (orientation: landscape) { + width: 65%; + } + @media only screen and (orientation: portrait) { + width: 85%; + } + } + 0% { + top: 0%; + transform: translate(-50%, 0%); + width: calc(100% - 14px); + } } -#gobutton:hover { - background-color: rgba(180, 30, 30); +#start.slideup { + animation: startup 0.3s forwards linear; } -#matchhistory, #stats { - position: absolute; - width: calc(100% - 20px); - min-height: calc(100% - 90px - 10px); - margin: 10px; - top: 80px; - background-color: white; - border-radius: 5px; - text-align: center; - overflow: visible; + +#start.slidedown { + animation: startdown 0.3s forwards linear; } -.bottom-right { - position: absolute; - right: 0px; - bottom: 0px; + +#start.up { + top: 0; + width: calc(100% - 14px); + transform: translate(-50%, 0%); +} + +#start.down { + top: 50%; + transform: translate(-50%, -50%); +} +@media only screen and (orientation: landscape) { + #start.down { + width: 65%; + } +} +@media only screen and (orientation: portrait) { + #start.down { + width: 85%; + } } + +/*# sourceMappingURL=style.css.map */ diff --git a/html/style.sass b/html/style.sass new file mode 100644 index 0000000..cf15189 --- /dev/null +++ b/html/style.sass @@ -0,0 +1,158 @@ +$widget-width: 18vmin +$widget-height: 7vmin +$color1: rgb(200, 50, 50) +$color1-dark: rgb(180, 30, 30) +$color2: white +$font-size1: 4.5vmin +$font-size2: 2.5vmin +$margin: 7px +$border: 4px + +body + font-family: 'Noto Sans SC', sans-serif + font-weight: bold + padding: 0px + margin: 0px +#background + position: fixed + width: 100% + height: 100% + background-color: $color1 + box-shadow: 0 0 400px rgba(0, 0, 0, 0.6) inset +#start + position: absolute + margin: $margin + left: calc(50% - #{$margin}) + top: 50% + transform: translate(-50%, -50%) + text-align: center + background-color: transparent + border-radius: $border + background-color: $color2 + box-shadow: 1px 1px 40px rgba(0, 0, 0, 0.8) +@media only screen and (orientation: landscape) + #start + width: 65% +@media only screen and (orientation: portrait) + #start + width: 85% +#title + width: 100% + color: $color2 + text-shadow: 1px 1px 40px black + user-select: none +#inputpanel + width: calc(100% - #{2 * $margin}) + height: $widget-height + font-size: $font-size1 + position: relative + margin: $margin +#matchhistory, #stats + position: absolute + font-size: $font-size2 + width: calc(100% - #{2 * $margin}) + min-height: calc(100% - (#{$widget-height} + #{3 * $margin}) - #{2 * $margin}) + margin: $margin + top: calc(#{$widget-height} + #{3 * $margin}) + background-color: $color2 + border-radius: $border + text-align: center +#historyfilters + position: relative + width: calc(100% - #{2 * $margin}) + height: calc(#{3 * $widget-height} + #{2 * $margin}) + margin: $margin +#matchlist + width: calc(100% - #{2 * $margin}) + margin: $margin + height: auto +hr + margin: 0 +select + text-align: center +select:hover + background-color: $color1-dark +select>option + background-color: $color1 +input + border: none + outline: none + font-size: inherit +button, select + vertical-align: baseline + width: $widget-width + height: $widget-height + background-color: $color1 + color: $color2 + border-radius: $border + border: none + outline: none + font-size: inherit +button:hover + background-color: $color1-dark +.bottom-right + position: absolute + right: 0px + bottom: 0px +#regionselect + text-transform: uppercase + position: absolute + left: 0 + z-index: 1 +#nameinput + text-align: center + border-bottom: 1px solid lightgray + width: calc(100% - #{2 * $widget-width}) + height: $widget-height + position: absolute + left: $widget-width + top: 0px +#gobutton, #statsbutton, #historybutton + position: absolute + margin: 0px + top: 0px + right: 0px + z-index: 1 +#refreshbutton + position: absolute + right: 0px + bottom: 0px +@keyframes startup + 0% + top: 50% + transform: translate(-50%, -50%) + @media only screen and (orientation: landscape) + width: 65% + @media only screen and (orientation: portrait) + width: 85% + 100% + top: 0% + transform: translate(-50%, 0%) + width: calc(100% - #{2 * $margin}) +@keyframes startdown + 100% + top: 50% + transform: translate(-50%, -50%) + @media only screen and (orientation: landscape) + width: 65% + @media only screen and (orientation: portrait) + width: 85% + 0% + top: 0% + transform: translate(-50%, 0%) + width: calc(100% - #{2 * $margin}) +#start.slideup + animation: startup 0.3s forwards linear +#start.slidedown + animation: startdown 0.3s forwards linear +#start.up + top: 0 + width: calc(100% - #{2 * $margin}) + transform: translate(-50%, 0%) +#start.down + top: 50% + transform: translate(-50%, -50%) + @media only screen and (orientation: landscape) + width: 65% + @media only screen and (orientation: portrait) + width: 85% diff --git a/index.js b/index.js index 3cc465e..e9cc8c5 100644 --- a/index.js +++ b/index.js @@ -1,8 +1,16 @@ const express = require("express") -const JavaScriptObfuscator = require("javascript-obfuscator"); const fs = require("fs") +const request = require("request-promise-native") const app = express() const port = 3000 +const sleep = require('util').promisify(setTimeout) + +const patch = "8.24.1"; +const key = "RGAPI-c6cae96a-c4b0-4842-9017-ddd736f3f628"; +let appRateLimit1; +let appRateLimit120; +let appRateLimitCount1; +let appRateLimitCount120; let rules = [ ["/lol", "index.html"], @@ -10,36 +18,121 @@ let rules = [ ["/lol/style.css", "style.css"], ]; -let obfuscateJs = false; - -function obfuscate(data) { - let obfResult = JavaScriptObfuscator.obfuscate( - String(data), - { - compact: true, - identifierNamesGenerator: "mangled", - } - ); - - return obfResult.getObfuscatedCode(); -} - for (i in rules) { let path = rules[i][0]; let file = rules[i][1]; app.get(path, (req, res) => { - if (file.endsWith(".js") && obfuscateJs) { - fs.readFile("html/" + file, (err, data) => { - if (err) throw err; - - let obf = obfuscate(data); - res.send(obf); - }); - } else { - res.sendFile(__dirname + "/html/" + file); - } + res.sendFile(__dirname + "/html/" + file); + }); +} + +async function riotRequest(region, url, params, retries) { + if (retries < 1) throw "Error too many tries"; + let req = "https://" + regions[region] + url + "?api_key=" + key; + for (p in params) { + req += "&" + p + "=" + params[p]; + } + try { + let result = await request({uri: req, resolveWithFullResponse: true, json: true}); + let appRateLimit = result.headers["x-app-rate-limit"]; + let appRateLimitCount = result.headers["x-app-rate-limit-count"]; + appRateLimit1 = appRateLimit.split(",")[0].split(":")[0]; + appRateLimit120 = appRateLimit.split(",")[1].split(":")[0]; + appRateLimitCount1 = appRateLimitCount.split(",")[0].split(":")[0]; + appRateLimitCount120 = appRateLimitCount.split(",")[1].split(":")[0]; + let delay1 = 1000 / (appRateLimit1 - 1); + let delay120 = 120000 / (appRateLimit120 - 1); + await sleep(Math.max(delay1, delay120)); + console.log(Math.max(delay1, delay120)); + return result.body; + } catch (err) { + console.log(err.message); + return await riotRequest(region, url, params, retries - 1); + } +} + +async function getAllMatches(region, accountId) { + let matches = []; + let totalGames; + let bI = 0, eI = 99; + + do { + let m = await riotRequest(region, "/lol/match/v4/matchlists/by-account/" + accountId, { beginIndex: bI, endIndex: eI }, 5); + console.log(m); + totalGames = m.totalGames; + matches = matches.concat(m.matches); + console.log("Added games " + bI + " to " + eI + ", " + matches.length + " of " + totalGames); + bI = eI + 1; + eI += 100; + } while (bI <= totalGames); + + return matches; +} + +// Static Data +// ----------- + +const regions = { + "BR": "br1.api.riotgames.com", + "EUNE": "eun1.api.riotgames.com", + "EUW": "euw1.api.riotgames.com", + "JP": "jp1.api.riotgames.com", + "KR": "kr.api.riotgames.com", + "LAN": "la1.api.riotgames.com", + "LAS": "la2.api.riotgames.com", + "NA": "na1.api.riotgames.com", + "OCE": "oc1.api.riotgames.com", + "TR": "tr1.api.riotgames.com", + "RU": "ru.api.riotgames.com", + "PBE": "pbe1.api.riotgames.com", +}; +app.get("/lol/regions", (req, res) => { + res.send(JSON.stringify(regions)); +}); +let champions = null; +function getChampions(cb) { + request("http://ddragon.leagueoflegends.com/cdn/" + patch + "/data/en_US/champion.json", (err, res, body) => { + champions = JSON.parse(body).data; + cb(); }); } +app.get("/lol/champions", (req, res) => { + if (champions == null) + getChampions(() => { + res.send(JSON.stringify(Object.keys(champions))); + }); + else + res.send(JSON.stringify(Object.keys(champions))); +}); +let users = {}; +if (fs.existsSync("users.js")) { + fs.readFile("users.js", (err, data) => { + users = JSON.parse(data); + }); +} +app.get("/lol/matches", async (req, res) => { + let region = req.query.region; + let summoner = req.query.summoner; + let regionUrl = regions[region]; + try { + let data = await riotRequest(region, "/lol/summoner/v4/summoners/by-name/" + summoner, {}, 5); + let accountId = data.accountId; + if (users[accountId]) { + res.send(JSON.stringify(users[accountId])); + return; + } + let matches = await getAllMatches(region, accountId); + users[accountId] = matches; + fs.writeFile("users.js", JSON.stringify(users), (err) => { + console.log("Error writing file: " + err); + }); + res.send(matches); + } catch (err) { + console.log(err); + } +}); + +// ----------- app.listen(port, () => { console.log("Listening on port %d", port) diff --git a/package-lock.json b/package-lock.json index cedffb8..6f5b311 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1421,6 +1421,24 @@ "uuid": "^3.3.2" } }, + "request-promise-core": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", + "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", + "requires": { + "lodash": "^4.13.1" + } + }, + "request-promise-native": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz", + "integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=", + "requires": { + "request-promise-core": "1.1.1", + "stealthy-require": "^1.1.0", + "tough-cookie": ">=2.3.3" + } + }, "restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", @@ -1573,6 +1591,11 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" + }, "string-template": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/string-template/-/string-template-1.0.0.tgz", diff --git a/package.json b/package.json index 3cf8065..aabe1b7 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "express": "^4.16.4", "javascript-obfuscator": "^0.18.1", "request": "^2.88.0", + "request-promise-native": "^1.0.5", "sqlite3": "^4.0.4" }, "devDependencies": {}, -- 2.50.1