Custom demon lists + Better account caching
This commit is contained in:
parent
24dccb1e93
commit
de053955e8
23 changed files with 121 additions and 59 deletions
|
@ -58,17 +58,17 @@ There's also a few optional values for fine-tuning. I'll add more over time
|
|||
|
||||
[string] **timestampSuffix:** A string to append at the end of timestamps. Vanilla GD uses " ago"
|
||||
|
||||
[string] **demonList:** The URL of the server's Demon List API, if it has one (e.g. `http://pointercrate.com/` - make sure it ends with a slash!)
|
||||
|
||||
[bool] **downloadsDisabled:** (Greys out all forms of downloading on the frontend (daily, weekly, analysis, etc). I love you too RobTop <3
|
||||
|
||||
[bool] **onePointNine:** Makes a bunch of fancy changes to better fit 1.9 servers. (removes orbs/diamonds, hides some pointless buttons, etc)
|
||||
|
||||
[bool] **weeklyLeaderboard:** Enables the lost but not forgotten Weekly Leaderboard, for servers that still milk it
|
||||
|
||||
[object] **substitutions:** A list of parameter substitutions, because some servers
|
||||
rename/obfuscate them. (e.g. `{ "levelID": "oiuyhxp4w9I" }`)
|
||||
[object] **substitutions:** A list of parameter substitutions, because some servers rename/obfuscate them. (e.g. `{ "levelID": "oiuyhxp4w9I" }`)
|
||||
|
||||
[object] **overrides:** A list of endpoint substitutions, because some servers
|
||||
use renamed or older versions. (e.g. `{ "getGJLevels21": "dorabaeChooseLevel42" }`)
|
||||
[object] **overrides:** A list of endpoint substitutions, because some servers use renamed or older versions. (e.g. `{ "getGJLevels21": "dorabaeChooseLevel42" }`)
|
||||
|
||||
|
||||
|
||||
|
@ -77,6 +77,7 @@ use renamed or older versions. (e.g. `{ "getGJLevels21": "dorabaeChooseLevel42"
|
|||
|
||||
|
||||
GDBrowser has a lot of folders. [citation needed]
|
||||
|
||||
I pride myself in keeping my files neat, without doing the whole `src/main/data/stuff/code/homework/newfolder/util/actualcode` garbage
|
||||
|
||||
|
||||
|
|
|
@ -145,7 +145,7 @@ function analyze_level(level, rawData) {
|
|||
}
|
||||
|
||||
response.level = {
|
||||
name: level.name, id: level.id, author: level.author, authorID: level.authorID, accountID: level.accountID, large: level.large
|
||||
name: level.name, id: level.id, author: level.author, playerID: level.playerID, accountID: level.accountID, large: level.large
|
||||
}
|
||||
|
||||
response.objects = data.length - 2
|
||||
|
|
|
@ -66,6 +66,7 @@ module.exports = async (app, req, res) => {
|
|||
col2: +y[11],
|
||||
glow: +y[15] > 1
|
||||
}
|
||||
app.userCache(req.id, comment.accountID, comment.playerID, comment.username)
|
||||
}
|
||||
|
||||
if (i == 0 && req.query.type != "commentHistory") {
|
||||
|
|
|
@ -27,10 +27,10 @@ module.exports = async (app, req, res, api, ID, analyze) => {
|
|||
let levelInfo = app.parseResponse(body)
|
||||
let level = new Level(levelInfo, req.server, true)
|
||||
|
||||
let foundID = app.accountCache[Object.keys(app.accountCache).find(x => app.accountCache[x][1] == level.authorID)]
|
||||
if (foundID) foundID = foundID.filter(x => x != level.authorID)
|
||||
let foundID = app.accountCache[Object.keys(app.accountCache).find(x => app.accountCache[x][1] == level.playerID)]
|
||||
if (foundID) foundID = foundID.filter(x => x != level.playerID)
|
||||
|
||||
req.gdRequest(authorData ? "" : 'getGJUsers20', { str: level.authorID }, function (err1, res1, b1) {
|
||||
req.gdRequest(authorData ? "" : 'getGJUsers20', { str: level.playerID }, function (err1, res1, b1) {
|
||||
let gdSearchResult = authorData ? "" : app.parseResponse(b1)
|
||||
req.gdRequest(authorData ? "" : 'getGJUserInfo20', { targetAccountID: gdSearchResult[16] }, function (err2, res2, b2) {
|
||||
|
||||
|
@ -51,6 +51,8 @@ module.exports = async (app, req, res, api, ID, analyze) => {
|
|||
level.accountID = "0"
|
||||
}
|
||||
|
||||
if (level.author != "-") app.userCache(req.id, level.accountID, level.playerID, level.author)
|
||||
|
||||
req.gdRequest('getGJSongInfo', { songID: level.customSong }, function (err, resp, songRes) {
|
||||
|
||||
if (!err && songRes != '-1') {
|
||||
|
@ -105,8 +107,8 @@ module.exports = async (app, req, res, api, ID, analyze) => {
|
|||
})
|
||||
}
|
||||
|
||||
else if (!level.gdps && level.difficulty == "Extreme Demon") {
|
||||
request.get('https://www.pointercrate.com/api/v2/demons/?name=' + level.name.trim(), function (err, resp, demonList) {
|
||||
else if (req.server.demonList && level.difficulty == "Extreme Demon") {
|
||||
request.get(req.server.demonList + 'api/v2/demons/?name=' + level.name.trim(), function (err, resp, demonList) {
|
||||
if (err) return sendLevel()
|
||||
let demon = JSON.parse(demonList)
|
||||
if (demon[0] && demon[0].position) level.demonList = demon[0].position
|
||||
|
|
|
@ -367,7 +367,7 @@ module.exports = async (app, req, res) => {
|
|||
}
|
||||
|
||||
let accountMode = !req.query.hasOwnProperty("player") && Number(req.params.id)
|
||||
let foundID = app.accountCache[req.id][username.toLowerCase()]
|
||||
let foundID = app.userCache(req.id, username)
|
||||
let skipRequest = accountMode || foundID
|
||||
let forceGD = req.query.hasOwnProperty("forceGD")
|
||||
|
||||
|
@ -380,7 +380,7 @@ module.exports = async (app, req, res) => {
|
|||
|
||||
if (err2 || !body2 || body2 == '-1' || body2.startsWith("<")) return buildIcon();
|
||||
let iconData = app.parseResponse(body2)
|
||||
if (!foundID && !forceGD && app.config.cacheAccountIDs) app.accountCache[req.id][username.toLowerCase()] = [iconData[16], iconData[2], iconData[1]]
|
||||
if (!foundID && !forceGD) app.userCache(req.id, iconData[16], iconData[2], iconData[1])
|
||||
return buildIcon(iconData, userCode);
|
||||
|
||||
})
|
||||
|
|
|
@ -29,7 +29,10 @@ module.exports = async (app, req, res, post) => {
|
|||
let leaderboard = JSON.parse(tab.getCell(1, cellIndex).value)
|
||||
|
||||
let gdFormatting = ""
|
||||
leaderboard.forEach(x => gdFormatting += `1:${x.username}:2:${x.playerID}:13:${x.coins}:17:${x.usercoins}:6:${x.rank}:9:${x.icon.icon}:10:${x.icon.col1}:11:${x.icon.col2}:14:${forms.indexOf(x.icon.form)}:15:${x.icon.glow ? 2 : 0}:16:${x.accountID}:3:${x.stars}:8:${x.cp}:46:${x.diamonds}:4:${x.demons}|`)
|
||||
leaderboard.forEach(x => {
|
||||
app.userCache(req.id, x.accountID, x.playerID, x.username)
|
||||
gdFormatting += `1:${x.username}:2:${x.playerID}:13:${x.coins}:17:${x.usercoins}:6:${x.rank}:9:${x.icon.icon}:10:${x.icon.col1}:11:${x.icon.col2}:14:${forms.indexOf(x.icon.form)}:15:${x.icon.glow ? 2 : 0}:16:${x.accountID}:3:${x.stars}:8:${x.cp}:46:${x.diamonds}:4:${x.demons}|`
|
||||
})
|
||||
caches[modMode ? 1 : 0][type] = JSON.stringify(leaderboard)
|
||||
caches[2][type] = gdFormatting
|
||||
lastIndex[modMode ? 1 : 0][type] = Date.now()
|
||||
|
|
|
@ -30,6 +30,7 @@ module.exports = async (app, req, res) => {
|
|||
x.percent = +x[3]
|
||||
x.coins = +x[13]
|
||||
x.playerID = x[2]
|
||||
x.accountID = x[16]
|
||||
x.date = x[42] + req.timestampSuffix
|
||||
x.icon = {
|
||||
form: ['icon', 'ship', 'ball', 'ufo', 'wave', 'robot', 'spider'][+x[14]],
|
||||
|
@ -39,6 +40,7 @@ module.exports = async (app, req, res) => {
|
|||
glow: +x[15] > 1
|
||||
}
|
||||
keys.forEach(k => delete x[k])
|
||||
app.userCache(req.id, x.accountID, x.playerID, x.username)
|
||||
})
|
||||
|
||||
return res.send(scores.slice(0, amount))
|
||||
|
|
|
@ -40,6 +40,7 @@ module.exports = async (app, req, res) => {
|
|||
glow: +x[15] > 1
|
||||
}
|
||||
keys.forEach(k => delete x[k])
|
||||
app.userCache(req.id, x.accountID, x.playerID, x.username)
|
||||
})
|
||||
return res.send(scores)
|
||||
})
|
||||
|
|
|
@ -50,7 +50,7 @@ module.exports = async (app, req, res, api, analyze) => {
|
|||
level.songID = "Level " + [parseInt(levelInfo[12]) + 1]
|
||||
}
|
||||
|
||||
if (level.author != "-" && app.config.cacheAccountIDs) app.accountCache[req.id][level.author.toLowerCase()] = [level.accountID, level.authorID, level.author]
|
||||
if (level.author != "-") app.userCache(req.id, level.accountID, level.playerID, level.author)
|
||||
|
||||
if (req.isGDPS) level.gdps = (req.onePointNine ? "1.9/" : "") + req.endpoint
|
||||
if (req.onePointNine) {
|
||||
|
@ -77,8 +77,8 @@ module.exports = async (app, req, res, api, analyze) => {
|
|||
})
|
||||
}
|
||||
|
||||
if (!level.gdps && level.difficulty == "Extreme Demon") {
|
||||
request.get('http://www.pointercrate.com/api/v2/demons/?name=' + level.name.trim(), function (err, resp, demonList) {
|
||||
if (req.server.demonList && level.difficulty == "Extreme Demon") {
|
||||
request.get(req.server.demonList + 'api/v2/demons/?name=' + level.name.trim(), function (err, resp, demonList) {
|
||||
if (err) return sendLevel()
|
||||
let demon = JSON.parse(demonList)
|
||||
if (demon[0] && demon[0].position) level.demonList = demon[0].position
|
||||
|
|
|
@ -34,6 +34,7 @@ module.exports = async (app, req, res, api) => {
|
|||
msg.browserColor = true
|
||||
}
|
||||
|
||||
app.userCache(req.id, msg.accountID, msg.playerID, msg.author)
|
||||
messageArray.push(msg)
|
||||
})
|
||||
return res.status(200).send(messageArray)
|
||||
|
|
|
@ -5,7 +5,7 @@ module.exports = async (app, req, res, api, getLevels) => {
|
|||
if (req.offline) return res.send("-1")
|
||||
let username = getLevels || req.params.id
|
||||
let accountMode = !req.query.hasOwnProperty("player") && Number(req.params.id)
|
||||
let foundID = app.accountCache[req.id][username.toLowerCase()]
|
||||
let foundID = app.userCache(req.id, username)
|
||||
let skipRequest = accountMode || foundID
|
||||
let searchResult;
|
||||
|
||||
|
@ -36,7 +36,7 @@ module.exports = async (app, req, res, api, getLevels) => {
|
|||
else return res.send("-1")
|
||||
}
|
||||
|
||||
if (!foundID && app.config.cacheAccountIDs) app.accountCache[req.id][username.toLowerCase()] = [account[16], account[2], account[1]]
|
||||
if (!foundID) app.userCache(req.id, account[16], account[2], account[1])
|
||||
|
||||
let userData = {
|
||||
username: account[1] || "[MISSINGNO.]",
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
const request = require('request')
|
||||
const levels = require('../misc/level.json').music
|
||||
const Level = require('../classes/Level.js')
|
||||
let demonList = {list: [], lastUpdated: 0}
|
||||
let demonList = {}
|
||||
// list: [], lastUpdated: 0
|
||||
|
||||
module.exports = async (app, req, res) => {
|
||||
|
||||
|
@ -9,13 +10,14 @@ module.exports = async (app, req, res) => {
|
|||
|
||||
let demonMode = req.query.hasOwnProperty("demonlist") || req.query.hasOwnProperty("demonList") || req.query.type == "demonlist" || req.query.type == "demonList"
|
||||
if (demonMode) {
|
||||
if (req.isGDPS) return res.send('-1')
|
||||
if (!demonList.list.length || demonList.lastUpdated + 600000 < Date.now()) { // 10 minute cache
|
||||
return request.get('http://www.pointercrate.com/api/v2/demons/listed/?limit=100', function (err1, resp1, list1) {
|
||||
if (!req.server.demonList) return res.send('-1')
|
||||
let dList = demonList[req.id]
|
||||
if (!dList || !dList.list.length || dList.lastUpdated + 600000 < Date.now()) { // 10 minute cache
|
||||
return request.get(req.server.demonList + 'api/v2/demons/listed/?limit=100', function (err1, resp1, list1) {
|
||||
if (err1) return res.send("-1")
|
||||
else return request.get('http://www.pointercrate.com/api/v2/demons/listed/?limit=100&after=100', function (err2, resp2, list2) {
|
||||
else return request.get(req.server.demonList + 'api/v2/demons/listed/?limit=100&after=100', function (err2, resp2, list2) {
|
||||
if (err2) return res.send("-1")
|
||||
demonList = {list: JSON.parse(list1).concat(JSON.parse(list2)).map(x => x.level_id), lastUpdated: Date.now()}
|
||||
demonList[req.id] = {list: JSON.parse(list1).concat(JSON.parse(list2)).map(x => String(x.level_id)), lastUpdated: Date.now()}
|
||||
return app.run.search(app, req, res)
|
||||
})
|
||||
})
|
||||
|
@ -74,7 +76,7 @@ module.exports = async (app, req, res) => {
|
|||
}
|
||||
|
||||
if (req.query.hasOwnProperty("user")) {
|
||||
let accountCheck = app.accountCache[req.id][filters.str.toLowerCase()]
|
||||
let accountCheck = app.userCache(req.id, filters.str)
|
||||
filters.type = 5
|
||||
if (accountCheck) filters.str = accountCheck[1]
|
||||
else if (!filters.str.match(/^[0-9]*$/)) return app.run.profile(app, req, res, null, req.params.text)
|
||||
|
@ -85,7 +87,7 @@ module.exports = async (app, req, res) => {
|
|||
let listSize = 10
|
||||
if (demonMode || req.query.gauntlet || req.query.type == "saved" || ["mappack", "list", "saved"].some(x => req.query.hasOwnProperty(x))) {
|
||||
filters.type = 10
|
||||
filters.str = demonMode ? demonList.list : filters.str.split(",")
|
||||
filters.str = demonMode ? demonList[req.id].list : filters.str.split(",")
|
||||
listSize = filters.str.length
|
||||
filters.str = filters.str.slice(filters.page*amount, filters.page*amount + amount).join()
|
||||
filters.page = 0
|
||||
|
@ -139,7 +141,12 @@ module.exports = async (app, req, res) => {
|
|||
level.diamonds = 0
|
||||
}
|
||||
|
||||
if (level.author != "-" && app.config.cacheAccountIDs) app.accountCache[req.id][level.author.toLowerCase()] = [level.accountID, level.authorID, level.author]
|
||||
if (demonMode) {
|
||||
if (!y) level.demonList = req.server.demonList
|
||||
level.demonPosition = demonList[req.id].list.indexOf(level.id) + 1
|
||||
}
|
||||
|
||||
if (level.author != "-" && app.config.cacheAccountIDs) app.userCache(req.id, level.accountID, level.playerID, level.author)
|
||||
|
||||
//this is broken if you're not on page 0, blame robtop
|
||||
if (filters.page == 0 && y == 0) {
|
||||
|
|
|
@ -1243,7 +1243,7 @@ input::-webkit-inner-spin-button {
|
|||
transform-origin:left top
|
||||
}
|
||||
}
|
||||
@keyframes bounceButton {
|
||||
@keyframes menuBounce {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
@ -1256,4 +1256,18 @@ input::-webkit-inner-spin-button {
|
|||
100% {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
}
|
||||
@keyframes bounceButton {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.12);
|
||||
}
|
||||
75% {
|
||||
transform: scale(1.06);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ class Level {
|
|||
this.id = levelInfo[1];
|
||||
this.description = Buffer.from(levelInfo[3], "base64").toString() || "(No description provided)";
|
||||
this.author = author[1] || "-"
|
||||
this.authorID = levelInfo[6]
|
||||
this.playerID = levelInfo[6]
|
||||
this.accountID = author[2] || 0
|
||||
this.difficulty = difficulty[levelInfo[9]]
|
||||
this.downloads = +levelInfo[10]
|
||||
|
|
|
@ -120,7 +120,7 @@
|
|||
<p>id: The ID of the level</p>
|
||||
<p>description: The description</p>
|
||||
<p>author: The name of the level's author (appears lower down in response)</p>
|
||||
<p>authorID: The ID of the level's author</p>
|
||||
<p>playerID: The unique player ID of the level's author</p>
|
||||
<p>accountID: The account ID of the level's author. An ID of 0 indicates a green (unregistered) user</p>
|
||||
<p>difficulty: The difficulty of the level (as a string). Includes demon rating</p>
|
||||
<p>downloads: Number of downloads</p>
|
||||
|
@ -503,7 +503,7 @@
|
|||
<p>levelID: The ID of the level</p>
|
||||
<p>browserColor: If the comment was posted through GDBrowser</p>
|
||||
<p class="red">username: The commenter's username</p>
|
||||
<p class="red">playerID: The commenter's ID</p>
|
||||
<p class="red">playerID: The commenter's player ID</p>
|
||||
<p class="red">accountID: The commenter's account ID</p>
|
||||
<p class="red">percent: The commenter's percent on the level, if provided</p>
|
||||
<p class="red">color: The RGB font color of the comment. Note that the yellow author text is not included</p>
|
||||
|
|
|
@ -184,7 +184,7 @@ Fetch(target).then(lvl => {
|
|||
if (lvl.accountID == undefined) $('#levelAuthor').remove()
|
||||
else if (lvl.accountID == 0) {
|
||||
$('#levelAuthor').addClass("green").addClass("unregistered")
|
||||
$('#authorLink').attr('href', '../search/' + lvl.authorID + "?user")
|
||||
$('#authorLink').attr('href', '../search/' + lvl.playerID + "?user")
|
||||
}
|
||||
else $('#authorLink').attr('href', '../u/' + lvl.author)
|
||||
$('#levelName').text(lvl.name || ("Nonexistent level " + lvlID))
|
||||
|
@ -265,7 +265,7 @@ fetch(`../api${!history ? window.location.pathname : "/comments/" + lvl.playerID
|
|||
<p class="commentPercent inline">${x.percent ? x.percent + "%" : ""}</p>
|
||||
|
||||
<div class="commentAlign">
|
||||
<p class="pre commentText" style="color: rgb(${!history && x.playerID == lvl.authorID ? "255,255,75" : x.browserColor ? "255,180,255" : x.color})">${clean(x.content)}</p>
|
||||
<p class="pre commentText" style="color: rgb(${!history && x.playerID == lvl.playerID ? "255,255,75" : x.browserColor ? "255,180,255" : x.color})">${clean(x.content)}</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="commentDate" id="date-${x.ID}">${x.date}</p>
|
||||
|
@ -290,7 +290,7 @@ fetch(`../api${!history ? window.location.pathname : "/comments/" + lvl.playerID
|
|||
<p class="commentPercent inline">${x.percent ? x.percent + "%" : ""}</p>
|
||||
|
||||
<div class="commentAlign">
|
||||
<p class="pre commentText" style="color: rgb(${!history && x.playerID == lvl.authorID ? "255,255,75" : x.browserColor ? "255,180,255" : x.color})">${clean(x.content)}</p>
|
||||
<p class="pre commentText" style="color: rgb(${!history && x.playerID == lvl.playerID ? "255,255,75" : x.browserColor ? "255,180,255" : x.color})">${clean(x.content)}</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="commentDate compactDate" id="date-${x.ID}">${x.date}</p>
|
||||
|
|
|
@ -78,7 +78,7 @@ let max = 250
|
|||
let trophies = [1, 5, 10, 25, 50, 100, max]
|
||||
|
||||
let demonID = Math.round(window.location.pathname.split('/')[2])
|
||||
if (!demonID || demonID > max || demonID < 1) window.location.href = "../../../"
|
||||
let illegal = (!demonID || demonID > max || demonID < 1)
|
||||
|
||||
if (demonID > 1) $('#pageDown').attr('href', `./${demonID - 1}`)
|
||||
else $('#pageDown').hide()
|
||||
|
@ -86,7 +86,10 @@ else $('#pageDown').hide()
|
|||
if (demonID < max) $('#pageUp').attr('href', `./${demonID + 1}`)
|
||||
else $('#pageUp').hide()
|
||||
|
||||
fetch(`https://pointercrate.com/api/v1/demons/${demonID}/`).then(res => res.json()).then(demonRes => {
|
||||
Fetch(`../api/gdps?current=1`).then(server => {
|
||||
if (illegal || !server.demonList) return $('#loading').hide();
|
||||
|
||||
fetch(`${server.demonList}api/v1/demons/${demonID}/`).then(res => res.json()).then(demonRes => {
|
||||
let demon = demonRes.data
|
||||
if (!demon.id) window.location.href = "../../../"
|
||||
|
||||
|
@ -94,7 +97,7 @@ fetch(`https://pointercrate.com/api/v1/demons/${demonID}/`).then(res => res.json
|
|||
$('#header').html(`${demon.name} <span class="smallerer" style="vertical-align: middle">(#${demonID})</span>`)
|
||||
$('#meta-title').attr('content', "Demon Leaderboard for " + demon.name)
|
||||
$('#meta-desc').attr('content', 'View the challengers and victors of' + demon.name)
|
||||
$('#pointercrate').attr('href', `https://pointercrate.com/demonlist/${demonID}`)
|
||||
$('#pointercrate').attr('href', `${server.demonList}demonlist/${demonID}`)
|
||||
|
||||
demon.records.forEach((x, y) => {
|
||||
|
||||
|
@ -123,6 +126,8 @@ fetch(`https://pointercrate.com/api/v1/demons/${demonID}/`).then(res => res.json
|
|||
})
|
||||
|
||||
$('#loading').hide();
|
||||
}).catch(e => $('#loading').hide())
|
||||
|
||||
})
|
||||
|
||||
$(document).keydown(function(k) {
|
||||
|
|
|
@ -110,7 +110,7 @@
|
|||
<div class="diffDiv gdButton demonDiff" diff=4><img src="../assets/difficulties/demon-insane.png" style="width: 95%"><h3 class="mini center smallTextWoo">Insane</h3></div>
|
||||
<div class="diffDiv gdButton demonDiff" diff=5><img src="../assets/difficulties/demon-extreme.png" style="width: 100%"><h3 class="mini center smallTextWoo">Extreme</h3></div>
|
||||
<div class="diffDiv gdButton goBack" diff=-2 style="margin-left: 2.3%; filter: none"><img src="../assets/difficulties/demon.png" style="width: 90%"><h3 class="mini">Demon</h3></div>
|
||||
<a id="demonList" href="./search/*?type=demonlist"><div class="gdButton diffDiv" style="filter: none"><img src="../assets/trophy2.png" style="width: 95%"><h3 class="yellow mini center">List</h3></div></a>
|
||||
<a id="demonList" style="display: none" href="./search/*?type=demonlist"><div class="gdButton diffDiv" style="filter: none"><img src="../assets/trophy2.png" style="width: 95%"><h3 class="yellow mini center">List</h3></div></a>
|
||||
</div>
|
||||
|
||||
<div class="transparentBox center" style="width: 115vh; height: 6%; margin: 0.5% auto 1% auto; padding-top: 1%; padding-bottom: 0.5%;">
|
||||
|
@ -264,13 +264,13 @@ $('#listLevels, #listName').on('input blur', function (event) {
|
|||
})
|
||||
|
||||
// some gdps magic
|
||||
Fetch(`../api/gdps`).then(res => {
|
||||
Fetch(`../api/gdps?current=1`).then(res => {
|
||||
if (onePointNine) {
|
||||
$('#userSearch').hide()
|
||||
$('#followedSearch').addClass('menuDisabled')
|
||||
$('#levelName').css('width', '76%')
|
||||
}
|
||||
if (gdps) $('#demonList').hide()
|
||||
if (res.demonList) $('#demonList').show()
|
||||
})
|
||||
|
||||
</script>
|
|
@ -276,11 +276,11 @@ if ([[COINS]] > 0) $("#coins").append(`<img src="../assets/${coinColor}.png" hei
|
|||
if ([[COINS]] > 1) $("#coins").append(`<img class="squeeze" src="../assets/${coinColor}.png" height="5%">`)
|
||||
if ([[COINS]] > 2) $("#coins").append(`<img class="squeeze" src="../assets/${coinColor}.png" height="5%">`)
|
||||
|
||||
if ("[[GDPS]]".startsWith("1.9/")) $("#authorLink").attr('href', '/search/[[AUTHORID]]?user')
|
||||
if ("[[GDPS]]".startsWith("1.9/")) $("#authorLink").attr('href', '/search/[[PLAYERID]]?user')
|
||||
|
||||
if ("[[ACCOUNTID]]" == "0") {
|
||||
$("#authorName").addClass("green").addClass("unregistered")
|
||||
$("#authorLink").attr('href', '/search/[[AUTHORID]]?user')
|
||||
$("#authorLink").attr('href', '/search/[[PLAYERID]]?user')
|
||||
}
|
||||
|
||||
if (window.location.pathname == "/weekly") {
|
||||
|
|
|
@ -222,7 +222,7 @@
|
|||
let password;
|
||||
let page = 0;
|
||||
let messageID = 0;
|
||||
let authorID = 0;
|
||||
let playerID = 0;
|
||||
let messages = [];
|
||||
let messageStatus = {};
|
||||
let cache = {};
|
||||
|
@ -247,7 +247,7 @@
|
|||
$('#msgList').html('')
|
||||
messages.forEach((x, y) => {
|
||||
$('#msgList').append(`
|
||||
<div messageID=${x.id} authorID="${x.accountID}" ${x.browserColor ? 'browserColor="true" ' : ""}class="commentBG gdMessage">
|
||||
<div messageID=${x.id} playerID="${x.accountID}" ${x.browserColor ? 'browserColor="true" ' : ""}class="commentBG gdMessage">
|
||||
<h3 style="color: ${x.browserColor ? 'rgb(120, 200, 255)' : 'white'}; font-size: ${x.subject.length > 35 ? "3" : x.subject.length > 30 ? "3.5" : x.subject.length > 25 ? "3.75" : "4"}vh">${x.subject}${x.unread ? " <span style='color:#00E600'>!</span>" : ""}</h3>
|
||||
<h3 class="gold gdButton msgAuthor hitbox fit"><a href="../u/${x.author}" target="_blank">From: ${x.author}</a></h3>
|
||||
<p class="msgDate">${x.date}</p>
|
||||
|
@ -298,7 +298,7 @@
|
|||
if (res == "-1" || !res) return;
|
||||
$('#replyAuthor').html(`<a href="../u/${res.username}" target="_blank">To: ${res.username}</a>`)
|
||||
messageStatus[res.accountID] = [res.messages, res.username]
|
||||
authorID = res.accountID
|
||||
playerID = res.accountID
|
||||
if (res.messages == "all") $('#messageStatus').html(`<span style="color:yellow">${res.username}</span> has messages <span style="color:lime">enabled</span>`)
|
||||
else if (res.messages == "friends") $('#messageStatus').html(`<span style="color:yellow">${res.username}</span> has messages set to <span style="color:orange">friends only</span>`)
|
||||
else {
|
||||
|
@ -351,7 +351,7 @@
|
|||
|
||||
$(document).on('click', '.gdMessage', function () {
|
||||
messageID = $(this).attr('messageID')
|
||||
authorID = $(this).attr('authorID')
|
||||
playerID = $(this).attr('playerID')
|
||||
let subject = $(this).find('h3:first')
|
||||
subject.html(subject.html().replace('<span style="color:#00E600">!</span>', "")) //lazy way to mark as read
|
||||
|
||||
|
@ -460,9 +460,9 @@
|
|||
})
|
||||
|
||||
$('#replyButton').click(function() {
|
||||
if (!messageStatus[authorID]) return;
|
||||
let status = messageStatus[authorID][0]
|
||||
let name = messageStatus[authorID][1]
|
||||
if (!messageStatus[playerID]) return;
|
||||
let status = messageStatus[playerID][0]
|
||||
let name = messageStatus[playerID][1]
|
||||
$('#postMessage').removeClass('grayscale')
|
||||
if (status == "all") $('#messageStatus').html(`<span style="color:yellow">${name}</span> has messages <span style="color:lime">enabled</span>`)
|
||||
else if (status == "friends") $('#messageStatus').html(`<span style="color:yellow">${name}</span> has messages set to <span style="color:orange">friends only</span>`)
|
||||
|
@ -477,14 +477,14 @@
|
|||
$('#postMessage').click(function () {
|
||||
let subject = $('#postSubject').val()
|
||||
let message = $('#postContent').val()
|
||||
if (!subject || !message || !messageStatus[authorID] || messageStatus[authorID][0] == "off") return;
|
||||
if (!subject || !message || !messageStatus[playerID] || messageStatus[playerID][0] == "off") return;
|
||||
allowEsc = false
|
||||
$('#reply-loading').show()
|
||||
$('#reply-sent').hide()
|
||||
$('#reply-error').hide()
|
||||
$('#postingMessage').show()
|
||||
|
||||
$.post("../sendMessage/", { password, accountID, subject, message, targetID: authorID, color: true })
|
||||
$.post("../sendMessage/", { password, accountID, subject, message, targetID: playerID, color: true })
|
||||
.done(msg => {
|
||||
$('#reply-loading').hide()
|
||||
$('#reply-sent').show()
|
||||
|
|
|
@ -132,6 +132,7 @@ let results = 0
|
|||
let legalPages = true
|
||||
let superSearch = ['*', '*?type=mostliked', '*?type=mostdownloaded', '*?type=recent'].includes(window.location.href.split('/')[4].toLowerCase())
|
||||
|
||||
let demonListLink = "https://pointercrate.com/"
|
||||
let searchFilters = `../api/search/${type == 'saved' ? JSON.parse(localStorage.getItem('saved') || '[]').reverse().toString() : accID || path}?page=[PAGE]${count ? "" : "&count=10"}${window.location.search.replace(/\?/g, "&").replace("page", "nope")}`
|
||||
|
||||
if (type == "followed") {
|
||||
|
@ -169,21 +170,25 @@ function Append(firstLoad) {
|
|||
if ((pages && page+1 >= pages) || (!pages && res.length < 9 && type != "recent")) $('#pageUp').hide()
|
||||
else $('#pageUp').show()
|
||||
|
||||
if (demonList) {
|
||||
demonListLink = res[0].demonList
|
||||
res = res.sort(function(a, b){return a.demonPosition - b.demonPosition});
|
||||
}
|
||||
|
||||
res.forEach((x, y) => {
|
||||
let hasAuthor = (x.accountID != "0")
|
||||
let userSearch = (type == 5 || typeof userMode == 'string')
|
||||
if (demonList) x.demonID = (res.length * page) + y + 1
|
||||
if (y == 0 && userSearch) {
|
||||
$('#header').text(((x.author == "-" ? "Someone" : x.author)) + (x.author.toLowerCase().endsWith('s') ? "'" : "'s") + " levels")
|
||||
document.title = $('#header').text()
|
||||
accID = x.authorID
|
||||
accID = x.playerID
|
||||
}
|
||||
|
||||
let filteredSong = x.songName.replace(/[^ -~]/g, "")
|
||||
if (!filteredSong) filteredSong = x.songName
|
||||
$('#searchBox').append(`<div class="searchresult">
|
||||
<h1 class="lessspaced pre">${x.name}</h1>
|
||||
<h2 class="lessSpaced pre smaller inline gdButton ${hasAuthor ? "" : "green unregistered"}">${hasAuthor && !onePointNine ? `<a href="../u/${x.author}">By ${x.author}</a>` : `<a ${userSearch ? "" : `href="../search/${x.authorID}?user"`}>By ${x.author}</a>`}</h2><h2 class="inline" style="margin-left: 1.5%; transform:translateY(30%)"> ${x.copiedID == '0' ? "" : '<img class="valign sideSpace" src="../assets/copied.png" height="12%">'}${x.large ? '<img class="valign sideSpaceD" src="../assets/large.png" height="12%">' : ''}</h2>
|
||||
<h2 class="lessSpaced pre smaller inline gdButton ${hasAuthor ? "" : "green unregistered"}">${hasAuthor && !onePointNine ? `<a href="../u/${x.author}">By ${x.author}</a>` : `<a ${userSearch ? "" : `href="../search/${x.playerID}?user"`}>By ${x.author}</a>`}</h2><h2 class="inline" style="margin-left: 1.5%; transform:translateY(30%)"> ${x.copiedID == '0' ? "" : '<img class="valign sideSpace" src="../assets/copied.png" height="12%">'}${x.large ? '<img class="valign sideSpaceD" src="../assets/large.png" height="12%">' : ''}</h2>
|
||||
<h3 class="lessSpaced pre ${x.customSong == 0 ? "blue" : "whatIfItWasPurple"}" style="overflow: hidden; max-height: 19%">${filteredSong}</h3>
|
||||
<h3 class="lessSpaced">
|
||||
<img class="valign" src="../assets/time.png" height="14%"> ${x.length}
|
||||
|
@ -197,7 +202,7 @@ function Append(firstLoad) {
|
|||
<h3>${x.difficulty.includes('Demon') ? "Demon" : x.difficulty}</h3>
|
||||
${x.stars != 0 && !demonList ? `<h3>${x.stars}<img class="valign sideSpaceB" src="../assets/star.png" height="35%" style="transform:translateY(-8%)"></h3>` : ""}
|
||||
|
||||
${demonList ? `<h3 class="yellow">#${x.demonID}</h3>` : ""}
|
||||
${demonList ? `<h3 class="yellow">#${x.demonPosition}</h3>` : ""}
|
||||
|
||||
<div id="coins" style="margin-top: 3%">
|
||||
${x.coins > 0 ? `<img src="../assets/${x.verifiedCoins ? 'silver' : 'brown'}coin.png" height="50%">` : ""}
|
||||
|
@ -207,8 +212,8 @@ function Append(firstLoad) {
|
|||
</div>
|
||||
<div class="center" style="position:absolute; right: 7%; transform:translateY(-${demonList ? 19.5 : 16.25}vh); height: 10%">
|
||||
<a title="View level" href="../${x.id}""><img style="margin-bottom: 4.5%" class="valign gdButton" src="../assets/view.png" height="105%"></a>
|
||||
${demonList ? `<br><a title="View leaderboard" href="../demon/${x.demonID}""><img class="valign gdButton" src="../assets/trophyButton.png" height="110%"></a>
|
||||
<a title="View on Pointercrate" href="https://pointercrate.com/demonlist/${x.demonID}" target=_blank><img class="valign gdButton" src="../assets/demonButton.png" height="110%"></a>` : "" }
|
||||
${demonList ? `<br><a title="View leaderboard" href="../demon/${x.demonPosition}""><img class="valign gdButton" src="../assets/trophyButton.png" height="110%"></a>
|
||||
<a title="View on Pointercrate" href="${demonListLink}demonlist/${x.demonPosition}" target=_blank><img class="valign gdButton" src="../assets/demonButton.png" height="110%"></a>` : "" }
|
||||
</div>
|
||||
</div>`)
|
||||
})
|
||||
|
|
11
index.js
11
index.js
|
@ -119,6 +119,14 @@ app.timeSince = function(id, time) {
|
|||
return `${app.actuallyWorked[id] ? "" : "~"}${minsPassed}m ${secsPassed}s`
|
||||
}
|
||||
|
||||
app.userCache = function(id, accountID, playerID, name) {
|
||||
if (!app.config.cacheAccountIDs) return
|
||||
if (!playerID) return app.accountCache[id][accountID.toLowerCase()]
|
||||
let cacheStuff = [accountID, playerID, name]
|
||||
app.accountCache[id][name.toLowerCase()] = cacheStuff
|
||||
return cacheStuff
|
||||
}
|
||||
|
||||
app.run = {}
|
||||
directories.forEach(d => {
|
||||
fs.readdirSync('./api/' + d).forEach(x => {if (x.includes('.')) app.run[x.split('.')[0]] = require('./api/' + d + "/" + x) })
|
||||
|
@ -280,7 +288,8 @@ app.get("/:id", function(req, res) { app.run.level(app, req, res) })
|
|||
// MISC
|
||||
|
||||
app.get("/icon/:text", function(req, res) { app.run.icon(app, req, res) })
|
||||
app.get("/api/gdps", function(req, res) { res.send(app.servers) })
|
||||
app.get("/api/userCache", function(req, res) { res.send(app.accountCache) })
|
||||
app.get("/api/gdps", function(req, res) { res.send(req.query.hasOwnProperty("current") ? req.server : app.servers) })
|
||||
app.get("/api/achievements", function(req, res) { res.send({achievements, types: achievementTypes, shopIcons, colors: colorList }) })
|
||||
app.get('/api/icons', function(req, res) {
|
||||
let sample = [JSON.stringify(sampleIcons[Math.floor(Math.random() * sampleIcons.length)].slice(1))]
|
||||
|
|
13
servers.json
13
servers.json
|
@ -7,7 +7,8 @@
|
|||
"id": "",
|
||||
"endpoint": "http://boomlings.com/database/",
|
||||
"timestampSuffix": " ago",
|
||||
"downloadsDisabled": true
|
||||
"downloadsDisabled": true,
|
||||
"demonList": "https://pointercrate.com/"
|
||||
},
|
||||
|
||||
{
|
||||
|
@ -33,6 +34,7 @@
|
|||
"endpoint": "http://absolllute.com/gdps/gdapi/",
|
||||
"onePointNine": true,
|
||||
"weeklyLeaderboard": true,
|
||||
"demonList": "https://pointercrate.xyze.dev/",
|
||||
"overrides": {
|
||||
"getGJMapPacks21": "getGJMapPacks",
|
||||
"getGJScores20": "getGJScores",
|
||||
|
@ -56,5 +58,14 @@
|
|||
"authorLink": "https://www.youtube.com/channel/UCG5I4-KAW3Kwzam4svLJWBA",
|
||||
"id": "wgdps",
|
||||
"endpoint": "http://wyliegdps02.7m.pl/database/"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "CnekGDPS",
|
||||
"link": "cnekgdps.7m.pl/index.html/",
|
||||
"author": "Cnek",
|
||||
"authorLink": "https://www.youtube.com/channel/UCDgrf89BjVyrUYSxFIDxafw",
|
||||
"id": "cnekgdps",
|
||||
"endpoint": "http://cnekgdps.7m.pl/cnekgdpsdtb/"
|
||||
}
|
||||
]
|
Loading…
Reference in a new issue