A lot of refactoring, and etc #232

Open
Rudxain wants to merge 62 commits from Rudxain/patch-1 into master
9 changed files with 231 additions and 233 deletions
Showing only changes of commit ae3c59f7dd - Show all commits

View file

@ -17,18 +17,18 @@ module.exports = async (app, req, res, level) => {
let levelString = unencrypted ? level.data : Buffer.from(level.data, 'base64')
if (unencrypted) {
const raw_data = level.data;
const response_data = analyze_level(level, raw_data);
return res.send(response_data);
} else {
const raw_data = level.data
const response_data = analyze_level(level, raw_data)
return res.send(response_data)
}
else {
zlib.unzip(levelString, (err, buffer) => {
if (err) { return res.status(500).send("-2"); }
if (err) return res.status(500).send("-2")
const raw_data = buffer.toString();
const response_data = analyze_level(level, raw_data);
return res.send(response_data);
});
const raw_data = buffer.toString()
const response_data = analyze_level(level, raw_data)
return res.send(response_data)
})
}
}
@ -40,22 +40,22 @@ function sortObj(obj, sortBy) {
}
function parse_obj(obj, splitter, name_arr, valid_only) {
const s_obj = obj.split(splitter);
let robtop_obj = {};
const s_obj = obj.split(splitter)
let robtop_obj = {}
// semi-useless optimization depending on where at node js you're at
for (let i = 0, obj_l = s_obj.length; i < obj_l; i += 2) {
let k_name = s_obj[i];
let k_name = s_obj[i]
if (s_obj[i] in name_arr) {
if (!valid_only) k_name = name_arr[s_obj[i]];
robtop_obj[k_name] = s_obj[i + 1];
if (!valid_only) k_name = name_arr[s_obj[i]]
robtop_obj[k_name] = s_obj[i + 1]
}
}
return robtop_obj;
return robtop_obj
}
function analyze_level(level, rawData) {
let response = {};
let response = {}
let blockCounts = {}
let miscCounts = {}
@ -63,62 +63,58 @@ function analyze_level(level, rawData) {
let highDetail = 0
let alphaTriggers = []
let misc_objects = {};
let block_ids = {};
let misc_objects = {}
let block_ids = {}
for (const [name, object_ids] of Object.entries(ids.misc)) {
const copied_ids = object_ids.slice(1);
const copied_ids = object_ids.slice(1)
// funny enough, shift effects the original id list
copied_ids.forEach((object_id) => {
misc_objects[object_id] = name;
});
copied_ids.forEach(object_id => { misc_objects[object_id] = name })
}
for (const [name, object_ids] of Object.entries(blocks)) {
object_ids.forEach((object_id) => {
block_ids[object_id] = name;
});
object_ids.forEach(object_id => { block_ids[object_id] = name })
}
const data = rawData.split(";");
const header = data.shift();
const data = rawData.split(";")
const header = data.shift()
let level_portals = [];
let level_coins = [];
let level_text = [];
let level_portals = []
let level_coins = []
let level_text = []
let orb_array = {};
let trigger_array = {};
let orb_array = {}
let trigger_array = {}
let last = 0
const obj_length = data.length;
const obj_length = data.length
for (let i = 0; i < obj_length; ++i) {
obj = parse_obj(data[i], ',', properties);
obj = parse_obj(data[i], ',', properties)
let id = obj.id
if (id in ids.portals) {
obj.portal = ids.portals[id];
level_portals.push(obj);
obj.portal = ids.portals[id]
level_portals.push(obj)
} else if (id in ids.coins) {
obj.coin = ids.coins[id];
level_coins.push(obj);
obj.coin = ids.coins[id]
level_coins.push(obj)
} else if (id in ids.orbs) {
obj.orb = ids.orbs[id];
obj.orb = ids.orbs[id]
if (obj.orb in orb_array) {
orb_array[obj.orb]++;
orb_array[obj.orb]++
} else {
orb_array[obj.orb] = 1;
orb_array[obj.orb] = 1
}
} else if (id in ids.triggers) {
obj.trigger = ids.triggers[id];
obj.trigger = ids.triggers[id]
if (obj.trigger in trigger_array) {
trigger_array[obj.trigger]++;
trigger_array[obj.trigger]++
} else {
trigger_array[obj.trigger] = 1;
trigger_array[obj.trigger] = 1
}
}
@ -130,32 +126,30 @@ function analyze_level(level, rawData) {
if (obj.highDetail == 1) highDetail++
if (id in misc_objects) {
const name = misc_objects[id];
const name = misc_objects[id]
if (name in miscCounts) {
miscCounts[name][0] += 1;
miscCounts[name][0] += 1
} else {
miscCounts[name] = [1, ids.misc[name][0]];
miscCounts[name] = [1, ids.misc[name][0]]
}
}
if (id in block_ids) {
const name = block_ids[id];
const name = block_ids[id]
if (name in blockCounts) {
blockCounts[name] += 1;
blockCounts[name]++
} else {
blockCounts[name] = 1;
blockCounts[name] = 1
}
}
if (obj.x) { // sometimes the field doesn't exist
last = Math.max(last, obj.x);
}
// sometimes the field doesn't exist
if (obj.x) last = Math.max(last, obj.x)
if (obj.trigger == "Alpha") { // invisible triggers
alphaTriggers.push(obj)
}
// invisible triggers
if (obj.trigger == "Alpha") alphaTriggers.push(obj)
data[i] = obj;
data[i] = obj
}
let invisTriggers = []
@ -166,7 +160,7 @@ function analyze_level(level, rawData) {
&& tr.opacity == 0 && tr.duration == 0
&& alphaTriggers.filter(x => x.targetGroupID == tr.targetGroupID).length == 1
)
invisTriggers.push(Number(tr.targetGroupID));
invisTriggers.push(Number(tr.targetGroupID))
})
response.level = {};
@ -176,15 +170,18 @@ function analyze_level(level, rawData) {
response.highDetail = highDetail
response.settings = {}
response.portals = level_portals.sort(function (a, b) {return parseInt(a.x) - parseInt(b.x)}).map(x => x.portal + " " + Math.floor(x.x / (Math.max(last, 529.0) + 340.0) * 100) + "%").join(", ")
response.coins = level_coins.sort(function (a, b) {return parseInt(a.x) - parseInt(b.x)}).map(x => Math.floor(x.x / (Math.max(last, 529.0) + 340.0) * 100))
// I have no idea what to name this lmao
let WTF = x => Math.floor(x.x / (Math.max(last, 529) + 340) * 100)
response.portals = level_portals.sort((a, b) => parseInt(a.x) - parseInt(b.x)).map(x => x.portal + " " + WTF(x) + "%").join(", ")
response.coins = level_coins.sort((a, b) => parseInt(a.x) - parseInt(b.x)).map(WTF)
response.coinsVerified = level.verifiedCoins
let sum = arr => arr.reduce((a, x) => a + x, 0)
response.orbs = orb_array
response.orbs.total = Object.values(orb_array).reduce((a, x) => a + x, 0); // we already have an array of objects, use it
response.orbs.total = sum(Object.values(orb_array)) // we already have an array of objects, use it
response.triggers = trigger_array
response.triggers.total = Object.values(trigger_array).reduce((a, x) => a + x, 0);
response.triggers.total = sum(Object.values(trigger_array))
response.triggerGroups = {}
response.blocks = sortObj(blockCounts)
@ -203,24 +200,24 @@ function analyze_level(level, rawData) {
// find alpha group with the most objects
response.invisibleGroup = triggerKeys.find(x => invisTriggers.includes(x))
response.text = level_text.sort(function (a, b) {return parseInt(a.x) - parseInt(b.x)}).map(x => [Buffer.from(x.message, 'base64').toString(), Math.round(x.x / last * 99) + "%"])
response.text = level_text.sort((a, b) => parseInt(a.x) - parseInt(b.x)).map(x => [Buffer.from(x.message, 'base64').toString(), Math.round(x.x / last * 99) + "%"])
const header_response = parse_header(header);
response.settings = header_response.settings;
response.colors = header_response.colors;
const header_response = parse_header(header)
response.settings = header_response.settings
response.colors = header_response.colors
response.dataLength = rawData.length
response.data = rawData
return response;
return response
}
function parse_header(header) {
let response = {};
response.settings = {};
response.colors = [];
let response = {}
response.settings = {}
response.colors = []
const header_keyed = parse_obj(header, ',', init.values, true);
const header_keyed = parse_obj(header, ',', init.values, true)
Object.keys(header_keyed).forEach(x => {
let val = init.values[x]
@ -229,41 +226,38 @@ function parse_header(header) {
switch (val[1]) {
case 'list':
val = init[(val[0] + "s")][property];
break;
break
case 'number':
val = Number(property);
break;
break
case 'bump':
val = Number(property) + 1;
break;
break
case 'bool':
val = property != "0";
break;
break
case 'extra-legacy-color': { // scope?
// you can only imagine my fear when i discovered this was a thing
// these literally are keys set the value, and to convert this to the color list we have to do this fun messy thing that shouldn't exist
// since i wrote the 1.9 color before this, a lot of explaination will be there instead
const colorInfo = name.split('-');
const color = colorInfo[2]; // r,g,b
const channel = colorInfo[1];
const colorInfo = name.split('-')
const color = colorInfo[2] // r,g,b
const channel = colorInfo[1]
// first we create the color object
if (color == 'r') response.colors.push({"channel": channel, "opacity": 1})
if (color == 'r') {
// first we create the color object
response.colors.push({"channel": channel, "opacity": 1});
}
// from here we touch the color object
let currentChannel = response.colors.find(k => k.channel == channel);
if (color == 'blend') {
currentChannel.blending = true; // only one color has blending though lol
} else if (color == 'pcol' && property != 0) {
currentChannel.pColor = property;
}
currentChannel[color] = property;
break;
let currentChannel = response.colors.find(k => k.channel == channel)
if (color == 'blend') currentChannel.blending = true // only one color has blending though lol
else if (color == 'pcol' && property != 0) currentChannel.pColor = property
currentChannel[color] = property
break
}
case 'legacy-color': {
// if a level has a legacy color, we can assume that it does not have a kS38 at all
const color = parse_obj(property, "_", colorStuff.properties);
const color = parse_obj(property, "_", colorStuff.properties)
let colorObj = color
@ -275,15 +269,15 @@ function parse_header(header) {
colorObj.channel = colorVal
// from here stuff can continue as normal, ish
if (colorObj.pColor == "-1" || colorObj.pColor == "0") delete colorObj.pColor;
colorObj.opacity = 1; // 1.9 colors don't have this!
if (colorObj.blending && colorObj.blending == '1') colorObj.blending = true; // 1.9 colors manage to always think they're blending - they're not
else delete colorObj.blending;
if (colorObj.pColor == "-1" || colorObj.pColor == "0") delete colorObj.pColor
colorObj.opacity = 1 // 1.9 colors don't have this!
if (colorObj.blending && colorObj.blending == '1') colorObj.blending = true // 1.9 colors manage to always think they're blending - they're not
else delete colorObj.blending
if (colorVal == '3DL') { response.colors.splice(4, 0, colorObj); } // hardcode the position of 3DL, it typically goes at the end due to how RobTop make the headers
else if (colorVal == 'Line') { colorObj.blending = true; response.colors.push(colorObj); } // in line with 2.1 behavior
else { response.colors.push(colorObj); } // bruh whatever was done to make the color list originally was long
break;
if (colorVal == '3DL') response.colors.splice(4, 0, colorObj) // hardcode the position of 3DL, it typically goes at the end due to how RobTop make the headers
else if (colorVal == 'Line') { colorObj.blending = true; response.colors.push(colorObj) } // in line with 2.1 behavior
else response.colors.push(colorObj) // bruh whatever was done to make the color list originally was long
break
}
case 'colors': {
let colorList = property.split("|")
@ -293,9 +287,9 @@ function parse_header(header) {
if (!color.channel) return colorList = colorList.filter((h, i) => y != i)
if (colorStuff.channels[colorObj.channel]) colorObj.channel = colorStuff.channels[colorObj.channel]
if (colorObj.channel > 1000) return;
if (colorObj.channel > 1000) return
if (colorStuff.channels[colorObj.copiedChannel]) colorObj.copiedChannel = colorStuff.channels[colorObj.copiedChannel]
if (colorObj.copiedChannel > 1000) delete colorObj.copiedChannel;
if (colorObj.copiedChannel > 1000) delete colorObj.copiedChannel
if (colorObj.pColor == "-1") delete colorObj.pColor
if (colorObj.blending) colorObj.blending = true
if (colorObj.copiedHSV) {
@ -308,16 +302,16 @@ function parse_header(header) {
}
colorObj.opacity = +Number(colorObj.opacity).toFixed(2)
colorList[y] = colorObj
});
})
// we assume this is only going to be run once so... some stuff can go here
colorList = colorList.filter(x => typeof x == "object")
if (!colorList.find(x => x.channel == "Obj")) colorList.push({"r": "255", "g": "255", "b": "255", "channel": "Obj", "opacity": "1"})
const specialSort = ["BG", "G", "G2", "Line", "Obj", "3DL"]
let specialColors = colorList.filter(x => isNaN(x.channel)).sort(function (a, b) {return specialSort.indexOf( a.channel ) > specialSort.indexOf( b.channel ) } )
let regularColors = colorList.filter(x => !isNaN(x.channel)).sort(function(a, b) {return (+a.channel) - (+b.channel) } );
let specialColors = colorList.filter(x => isNaN(x.channel)).sort((a, b) => specialSort.indexOf(a.channel) > specialSort.indexOf(b.channel))
let regularColors = colorList.filter(x => !isNaN(x.channel)).sort((a, b) => +a.channel - +b.channel)
response.colors = specialColors.concat(regularColors)
break;
break
}
}
response.settings[name] = val
@ -332,9 +326,9 @@ function parse_header(header) {
Object.keys(response.settings).filter(k => {
// this should be parsed into color list instead
if (k.includes('legacy')) delete response.settings[k];
});
if (k.includes('legacy')) delete response.settings[k]
})
delete response.settings['colors'];
return response;
delete response.settings['colors']
return response
}

View file

@ -1,3 +1,4 @@
"use strict";
const Player = require('../classes/Player.js')
module.exports = async (app, req, res) => {
@ -8,8 +9,8 @@ module.exports = async (app, req, res) => {
if (count > 1000) count = 1000
let params = {
userID : req.params.id,
accountID : req.params.id,
userID : req.params.id,
accountID : req.params.id,
levelID: req.params.id,
page: +req.query.page || 0,
count,
@ -20,7 +21,7 @@ module.exports = async (app, req, res) => {
if (req.query.type == "commentHistory") { path = "getGJCommentHistory"; delete params.levelID }
else if (req.query.type == "profile") path = "getGJAccountComments20"
req.gdRequest(path, req.gdParams(params), function(err, resp, body) {
req.gdRequest(path, req.gdParams(params), function(err, resp, body) {
if (err) return res.sendError()
@ -32,7 +33,7 @@ module.exports = async (app, req, res) => {
if (!comments.length) return res.status(204).send([])
let pages = body.split('#')[1].split(":")
let lastPage = +Math.ceil(+pages[0] / +pages[2]);
let lastPage = +Math.ceil(+pages[0] / +pages[2])
let commentArray = []
@ -41,7 +42,7 @@ module.exports = async (app, req, res) => {
var x = c[0] //comment info
var y = c[1] //account info
if (!x[2]) return;
if (!x[2]) return
let comment = {}
comment.content = Buffer.from(x[2], 'base64').toString();
@ -50,9 +51,9 @@ module.exports = async (app, req, res) => {
comment.date = (x[9] || "?") + req.timestampSuffix
if (comment.content.endsWith("⍟") || comment.content.endsWith("☆")) {
comment.content = comment.content.slice(0, -1)
comment.browserColor = true
comment.browserColor = true
}
if (req.query.type != "profile") {
let commentUser = new Player(y)
Object.keys(commentUser).forEach(k => {
@ -74,7 +75,7 @@ module.exports = async (app, req, res) => {
commentArray.push(comment)
})
})
return res.send(commentArray)

View file

@ -1,3 +1,4 @@
"use strict";
const request = require('request')
const fs = require('fs')
const Level = require('../classes/Level.js')
@ -5,27 +6,27 @@ const Level = require('../classes/Level.js')
module.exports = async (app, req, res, api, ID, analyze) => {
function rejectLevel() {
if (!api) return res.redirect('search/' + req.params.id)
else return res.sendError()
return !api ? res.redirect('search/' + req.params.id) : res.sendError()
}
if (req.offline) {
if (!api && levelID < 0) return res.redirect('/')
return rejectLevel()
return !api && levelID < 0 ? res.redirect('/') : rejectLevel()
}
let levelID = ID || req.params.id
if (levelID == "daily") levelID = -1
else if (levelID == "weekly") levelID = -2
else levelID = levelID.replace(/[^0-9]/g, "")
levelID = (
levelID == "daily" ? -1 :
levelID == "weekly" ? -2 :
levelID.replace(/\D/g, "")
)
req.gdRequest('downloadGJLevel22', { levelID }, function (err, resp, body) {
if (err) {
if (analyze && api && req.server.downloadsDisabled) return res.status(403).send("-3")
else if (!api && levelID < 0) return res.redirect(`/?daily=${levelID * -1}`)
else return rejectLevel()
}
if (err) return (
analyze && api && req.server.downloadsDisabled ? res.status(403).send("-3")
: !api && levelID < 0 ? res.redirect(`/?daily=${levelID * -1}`)
: rejectLevel()
)
let authorData = body.split("#")[3] // daily/weekly only, most likely
@ -72,7 +73,7 @@ module.exports = async (app, req, res, api, ID, analyze) => {
if (api) return res.send(level)
else return fs.readFile('./html/level.html', 'utf8', function (err, data) {
let html = data;
let html = data
let variables = Object.keys(level)
variables.forEach(x => {
let regex = new RegExp(`\\[\\[${x.toUpperCase()}\\]\\]`, "g")
@ -89,7 +90,7 @@ module.exports = async (app, req, res, api, ID, analyze) => {
level.nextDaily = +dailyTime
level.nextDailyTimestamp = Math.round((Date.now() + (+dailyTime * 1000)) / 100000) * 100000
return sendLevel()
})
})
}
else if (req.server.demonList && level.difficulty == "Extreme Demon") {

View file

@ -1,3 +1,4 @@
"use strict";
let cache = {}
let gauntletNames = ["Fire", "Ice", "Poison", "Shadow", "Lava", "Bonus", "Chaos", "Demon", "Time", "Crystal", "Magic", "Spike", "Monster", "Doom", "Death"]
@ -6,7 +7,8 @@ module.exports = async (app, req, res) => {
if (req.offline) return res.sendError()
let cached = cache[req.id]
if (app.config.cacheGauntlets && cached && cached.data && cached.indexed + 2000000 > Date.now()) return res.send(cached.data) // half hour cache
if (app.config.cacheGauntlets && cached && cached.data && cached.indexed + 2000000 > Date.now())
return res.send(cached.data) // half hour cache
req.gdRequest('getGJGauntlets21', {}, function (err, resp, body) {
@ -14,9 +16,10 @@ module.exports = async (app, req, res) => {
let gauntlets = body.split('#')[0].split('|').map(x => app.parseResponse(x)).filter(x => x[3])
let gauntletList = gauntlets.map(x => ({ id: +x[1], name: gauntletNames[+x[1] - 1] || "Unknown", levels: x[3].split(",") }))
if (app.config.cacheGauntlets) cache[req.id] = {data: gauntletList, indexed: Date.now()}
if (app.config.cacheGauntlets)
cache[req.id] = {data: gauntletList, indexed: Date.now()}
res.send(gauntletList)
})
}

View file

@ -1,3 +1,4 @@
"use strict";
const request = require('request')
const fs = require('fs')
const Level = require('../classes/Level.js')
@ -5,17 +6,14 @@ const Level = require('../classes/Level.js')
module.exports = async (app, req, res, api, analyze) => {
function rejectLevel() {
if (!api) return res.redirect('search/' + req.params.id)
else return res.sendError()
return !api ? res.redirect('search/' + req.params.id) : res.sendError()
}
if (req.offline) return rejectLevel()
let levelID = req.params.id
if (levelID == "daily") return app.run.download(app, req, res, api, 'daily', analyze)
else if (levelID == "weekly") return app.run.download(app, req, res, api, 'weekly', analyze)
else if (levelID.match(/[^0-9]/)) return rejectLevel()
else levelID = levelID.replace(/[^0-9]/g, "")
if (levelID == "daily" || levelID == "weekly") return app.run.download(app, req, res, api, levelID, analyze)
else if (/\D/.test(levelID)) return rejectLevel()
if (analyze || req.query.hasOwnProperty("download")) return app.run.download(app, req, res, api, levelID, analyze)
@ -23,9 +21,10 @@ module.exports = async (app, req, res, api, analyze) => {
if (err || body.startsWith("##")) return rejectLevel()
let preRes = body.split('#')[0].split('|', 10)
let author = body.split('#')[1].split('|')[0].split(':')
let song = '~' + body.split('#')[2];
const bodySplit = body.split('#') // IDK how to name it lol -Rudxain
let preRes = bodySplit[0].split('|', 10)
let author = bodySplit[1].split('|')[0].split(':')
let song = '~' + bodySplit[2]
song = app.parseResponse(song, '~|~')
let levelInfo = app.parseResponse(preRes.find(x => x.startsWith(`1:${levelID}`)) || preRes[0])
@ -40,7 +39,7 @@ module.exports = async (app, req, res, api, analyze) => {
if (api) return res.send(level)
else return fs.readFile('./html/level.html', 'utf8', function (err, data) {
let html = data;
let html = data
let filteredSong = level.songName.replace(/[^ -~]/g, "") // strip off unsupported characters
level.songName = filteredSong || level.songName
let variables = Object.keys(level)

View file

@ -1,12 +1,14 @@
"use strict";
let difficulties = ["auto", "easy", "normal", "hard", "harder", "insane", "demon", "demon-easy", "demon-medium", "demon-insane", "demon-extreme"]
let cache = {}
module.exports = async (app, req, res) => {
if (req.offline) return res.sendError()
let cached = cache[req.id]
if (app.config.cacheMapPacks && cached && cached.data && cached.indexed + 5000000 > Date.now()) return res.send(cached.data) // 1.5 hour cache
if (app.config.cacheMapPacks && cached && cached.data && cached.indexed + 5000000 > Date.now())
return res.send(cached.data) // 1.5 hour cache
let params = { count: 250, page: 0 }
let packs = []
@ -23,7 +25,7 @@ module.exports = async (app, req, res) => {
params.page++
return mapPackLoop()
}
let mappacks = packs.map(x => ({ // "packs.map()" laugh now please
id: +x[1],
name: x[2],

View file

@ -1,13 +1,15 @@
"use strict";
const fs = require('fs')
const Player = require('../classes/Player.js')
module.exports = async (app, req, res, api, getLevels) => {
if (req.offline) {
if (!api) return res.redirect('/search/' + req.params.id)
else return res.sendError()
function rejectLevel() {
// this variant has an extra "/"
return !api ? res.redirect('/search/' + req.params.id) : res.sendError()
}
if (req.offline) return rejectLevel()
let username = getLevels || req.params.id
let probablyID
if (username.endsWith(".") && req.isGDPS) {
@ -20,7 +22,7 @@ module.exports = async (app, req, res, api, getLevels) => {
let searchResult;
// if you're searching by account id, an intentional error is caused to skip the first request to the gd servers. see i pulled a sneaky on ya. (fuck callbacks man)
req.gdRequest(skipRequest ? "" : 'getGJUsers20', skipRequest ? {} : { str: username, page: 0 }, function (err1, res1, b1) {
req.gdRequest(skipRequest ? "" : 'getGJUsers20', skipRequest ? {} : { str: username, page: 0 }, function (err1, res1, b1) {
if (foundID) searchResult = foundID[0]
else if (accountMode || err1 || b1 == '-1' || b1.startsWith("<") || !b1) searchResult = probablyID ? username : req.params.id
@ -28,7 +30,7 @@ module.exports = async (app, req, res, api, getLevels) => {
else { // GDPS's return multiple users, GD no longer does this
let userResults = b1.split("|").map(x => app.parseResponse(x))
searchResult = userResults.find(x => x[1].toLowerCase() == username.toLowerCase() || x[2] == username) || ""
if (searchResult) searchResult = searchResult[16]
searchResult &&= searchResult[16]
}
if (getLevels) {
@ -40,20 +42,17 @@ module.exports = async (app, req, res, api, getLevels) => {
let account = app.parseResponse(body || "")
let dumbGDPSError = req.isGDPS && (!account[16] || account[1].toLowerCase() == "undefined")
if (err2 || dumbGDPSError) {
if (!api) return res.redirect('/search/' + req.params.id)
else return res.sendError()
}
if (err2 || dumbGDPSError) return rejectLevel()
if (!foundID) app.userCache(req.id, account[16], account[2], account[1])
let userData = new Player(account)
let userData = new Player(account)
if (api) return res.send(userData)
else fs.readFile('./html/profile.html', 'utf8', function(err, data) {
let html = data;
let html = data
let variables = Object.keys(userData)
variables.forEach(x => {
let regex = new RegExp(`\\[\\[${x.toUpperCase()}\\]\\]`, "g")
@ -61,7 +60,6 @@ module.exports = async (app, req, res, api, getLevels) => {
})
return res.send(html)
})
})
})
}
})
}

View file

@ -1,94 +1,92 @@
"use strict";
const request = require('request')
const music = require('../misc/music.json')
const Level = require('../classes/Level.js')
let demonList = {}
module.exports = async (app, req, res) => {
const {query} = req
if (req.offline) return res.status(500).send(query.hasOwnProperty("err") ? "err" : "-1")
if (req.offline) return res.status(500).send(req.query.hasOwnProperty("err") ? "err" : "-1")
let demonMode = req.query.hasOwnProperty("demonlist") || req.query.hasOwnProperty("demonList") || req.query.type == "demonlist" || req.query.type == "demonList"
let demonMode = query.hasOwnProperty("demonlist") || query.hasOwnProperty("demonList") || query.type == "demonlist" || query.type == "demonList"
if (demonMode) {
if (!req.server.demonList) return res.sendError(400)
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) {
let demonStr = req.server.demonList + 'api/v2/demons/listed/?limit=100'
return request.get(demonStr, function (err1, resp1, list1) {
if (err1) return res.sendError()
else return request.get(req.server.demonList + 'api/v2/demons/listed/?limit=100&after=100', function (err2, resp2, list2) {
else return request.get(demonStr + '&after=100', function (err2, resp2, list2) {
if (err2) return res.sendError()
demonList[req.id] = {list: JSON.parse(list1).concat(JSON.parse(list2)).map(x => String(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)
})
})
}
}
let amount = 10;
let count = req.isGDPS ? 10 : +req.query.count
if (count && count > 0) {
if (count > 500) amount = 500
else amount = count;
}
let amount = 10
let count = req.isGDPS ? 10 : +query.count
if (count && count > 0) amount = Math.min(count, 500)
let filters = {
str: req.params.text,
diff: req.query.diff,
demonFilter: req.query.demonFilter,
page: req.query.page || 0,
gauntlet: req.query.gauntlet || 0,
len: req.query.length,
song: req.query.songID,
followed: req.query.creators,
diff: query.diff,
demonFilter: query.demonFilter,
page: query.page || 0,
gauntlet: query.gauntlet || 0,
len: query.length,
song: query.songID,
followed: query.creators,
featured: req.query.hasOwnProperty("featured") ? 1 : 0,
originalOnly: req.query.hasOwnProperty("original") ? 1 : 0,
twoPlayer: req.query.hasOwnProperty("twoPlayer") ? 1 : 0,
coins: req.query.hasOwnProperty("coins") ? 1 : 0,
epic: req.query.hasOwnProperty("epic") ? 1 : 0,
star: req.query.hasOwnProperty("starred") ? 1 : 0,
noStar: req.query.hasOwnProperty("noStar") ? 1 : 0,
customSong: req.query.hasOwnProperty("customSong") ? 1 : 0,
featured: query.hasOwnProperty("featured") ? 1 : 0,
originalOnly: query.hasOwnProperty("original") ? 1 : 0,
twoPlayer: query.hasOwnProperty("twoPlayer") ? 1 : 0,
coins: query.hasOwnProperty("coins") ? 1 : 0,
epic: query.hasOwnProperty("epic") ? 1 : 0,
star: query.hasOwnProperty("starred") ? 1 : 0,
noStar: query.hasOwnProperty("noStar") ? 1 : 0,
customSong: query.hasOwnProperty("customSong") ? 1 : 0,
type: req.query.type || 0,
type: query.type || 0,
count: amount
}
if (req.query.type) {
let filterCheck = req.query.type.toLowerCase()
switch(filterCheck) {
case 'mostdownloaded': filters.type = 1; break;
case 'mostliked': filters.type = 2; break;
case 'trending': filters.type = 3; break;
case 'recent': filters.type = 4; break;
case 'featured': filters.type = 6; break;
case 'magic': filters.type = 7; break;
case 'awarded': filters.type = 11; break;
case 'starred': filters.type = 11; break;
case 'halloffame': filters.type = 16; break;
case 'hof': filters.type = 16; break;
case 'gdw': filters.type = 17; break;
case 'gdworld': filters.type = 17; break;
if (query.type) {
let filterCheck = query.type.toLowerCase()
let typeMap = {
'mostdownloaded': 1, 'mostliked': 2,
'trending': 3, 'recent': 4,
'featured': 6, 'magic': 7,
'awarded': 11, 'starred': 11,
'halloffame': 16, 'hof': 16,
'gdw': 17, 'gdworld': 17
}
if (typeMap.hasOwnProperty(filterCheck)) // JIC there's no match
filters.type = typeMap[filterCheck]
}
if (req.query.hasOwnProperty("user")) {
if (query.hasOwnProperty("user")) {
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)
}
else if ( !(/^\d*$/).test(filters.str) ) return app.run.profile(app, req, res, null, req.params.text)
}
if (req.query.hasOwnProperty("creators")) filters.type = 12
if (query.hasOwnProperty("creators")) filters.type = 12
let listSize = 10
if (demonMode || req.query.gauntlet || req.query.type == "saved" || ["mappack", "list", "saved"].some(x => req.query.hasOwnProperty(x))) {
if (demonMode || query.gauntlet || query.type == "saved" || ["mappack", "list", "saved"].some(x => query.hasOwnProperty(x))) {
filters.type = 10
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)
if (!filters.str.length) return res.sendError(400)
filters.str = filters.str.map(x => String(Number(x) + (+req.query.l || 0))).join()
filters.str = filters.str.map(x => String(Number(x) + (+query.l || 0))).join()
filters.page = 0
}
@ -103,25 +101,25 @@ module.exports = async (app, req, res) => {
let authorList = {}
let songList = {}
let authors = splitBody[1].split('|')
let songs = splitBody[2]; songs = songs.split('~:~').map(x => app.parseResponse(`~${x}~`, '~|~'))
let songs = splitBody[2].split('~:~').map(x => app.parseResponse(`~${x}~`, '~|~'))
songs.forEach(x => {songList[x['~1']] = x['2']})
authors.forEach(x => {
if (x.startsWith('~')) return
let arr = x.split(':')
authorList[arr[0]] = [arr[1], arr[2]]})
if (x.startsWith('~')) return
let arr = x.split(':')
authorList[arr[0]] = [arr[1], arr[2]]
})
let levelArray = preRes.map(x => app.parseResponse(x)).filter(x => x[1])
let parsedLevels = []
levelArray.forEach((x, y) => {
let songSearch = songs.find(y => y['~1'] == x[35]) || []
let level = new Level(x, req.server).getSongInfo(songSearch)
if (!level.id) return
level.author = authorList[x[6]] ? authorList[x[6]][0] : "-";
level.accountID = authorList[x[6]] ? authorList[x[6]][1] : "0";
level.author = authorList[x[6]] ? authorList[x[6]][0] : "-"
level.accountID = authorList[x[6]] ? authorList[x[6]][1] : "0"
if (demonMode) {
if (!y) level.demonList = req.server.demonList
@ -133,21 +131,21 @@ module.exports = async (app, req, res) => {
//this is broken if you're not on page 0, blame robtop
if (filters.page == 0 && y == 0 && splitBody[3]) {
let pages = splitBody[3].split(":");
let pages = splitBody[3].split(":")
if (filters.gauntlet) { // gauntlet page stuff
level.results = levelArray.length
level.results = levelArray.length
level.pages = 1
}
else if (filters.type == 10) { // custom page stuff
level.results = listSize
level.pages = +Math.ceil(listSize / (amount || 10))
level.pages = Math.ceil(listSize / (amount || 10))
}
else { // normal page stuff
level.results = +pages[0];
level.pages = +pages[0] == 9999 ? 1000 : +Math.ceil(pages[0] / amount);
level.results = +pages[0]
level.pages = +pages[0] == 9999 ? 1000 : Math.ceil(pages[0] / amount)
}
}

View file

@ -1,10 +1,12 @@
"use strict";
module.exports = async (app, req, res) => {
if (req.offline) return res.sendError()
let songID = req.params.song
req.gdRequest('getGJSongInfo', {songID: songID}, function(err, resp, body) {
if (err) return res.sendError(400)
return res.send(!body.startsWith("-") && body.length > 10)
return err ?
res.sendError(400) :
res.send(!body.startsWith("-") && body.length > 10)
})
}