diff --git a/README.md b/README.md index 7dcaac4..5723efc 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ forms.json is a list of the different icon forms, their ingame filenames, and th ## Misc Inevitable misc folder -**For level analysis** +**Level Analysis Stuff (in a separate folder)** blocks.json - The object IDs in the different 'families' of blocks @@ -69,7 +69,11 @@ objectProperties.json - Object property cheatsheet. Low budget version of [AlFas objects.json - IDs for portals, orbs, triggers, and misc stuff -**Not for level analysis** +**Everything Else** + +achievements.json - List of all GD/meltdown/subzero/etc achievements. `parseAchievementPlist.js` automatically creates this file + +achievementTypes.json - An object containing different categories of achievements (stars, shards, vault, etc) and how to identify them colors.json - List of icon colors in RGB format @@ -79,12 +83,16 @@ dragscroll.js - Used on several pages for drag scrolling level.json - An array of the official GD tracks, and also difficulty face stuff for level searching +parseAchievementPlist.js - A script that reads GD's achievement .plist files and converts it into achievements.json + sampleIcons.json - A pool of icons, one of which will randomly appear when visiting the icon kit. Syntax is [Name, ID, Col1, Col2, Glow], secretStuff.json - GJP goes here, needed for level leaderboards. Not included in the repo for obvious reasons settings.js - Tweak small settings here, mainly for local use or GDPS'es +shops.js - A hardcoded list of all the shop icons in GD + sizecheck.js - Excecuted on most pages. Used for the 'page isn't wide enough' message, back button, and a few other things --- diff --git a/api/analyze.js b/api/analyze.js index f0f99c4..9814dde 100644 --- a/api/analyze.js +++ b/api/analyze.js @@ -1,9 +1,9 @@ const zlib = require('zlib') -const properties = require('../misc/objectProperties.json') -const init = require('../misc/initialProperties.json') -const colorStuff = require('../misc/colorProperties.json') -const ids = require('../misc/objects.json') -const blocks = require('../misc/blocks.json') +const blocks = require('../misc/analysis/blocks.json') +const colorStuff = require('../misc/analysis/colorProperties.json') +const init = require('../misc/analysis/initialProperties.json') +const properties = require('../misc/analysis/objectProperties.json') +const ids = require('../misc/analysis/objects.json') module.exports = async (app, req, res, level) => { let unencrypted = level.data.startsWith('kS') // some gdps'es don't encrypt level data diff --git a/api/level.js b/api/level.js index 0ec7f3d..2b3e66b 100644 --- a/api/level.js +++ b/api/level.js @@ -58,7 +58,8 @@ module.exports = async (app, req, res, api, analyze) => { else return fs.readFile('./html/level.html', 'utf8', function (err, data) { let html = data; - level.songName = level.songName.replace(/[^ -~]/g, "") // strip off unsupported characters + let filteredSong = level.songName.replace(/[^ -~]/g, "") // strip off unsupported characters + level.songName = filteredSong || level.songName let variables = Object.keys(level) variables.forEach(x => { let regex = new RegExp(`\\[\\[${x.toUpperCase()}\\]\\]`, "g") diff --git a/api/profile.js b/api/profile.js index dcfad6b..f90777f 100644 --- a/api/profile.js +++ b/api/profile.js @@ -10,10 +10,10 @@ module.exports = async (app, req, res, api, getLevels) => { let skipRequest = accountMode || foundID // 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) - request.post(skipRequest ? "" : app.endpoint + 'getGJUsers20.php', skipRequest ? {} : req.gdParams({ str: username }), function (err1, res1, b1) { - - let searchResult = foundID ? foundID[0] : (accountMode || err1 || b1 == '-1' || b1.startsWith(" { } request.post(app.endpoint + 'getGJLevels21.php', req.gdParams(filters), async function(err, resp, body) { - + if (err || !body || body == '-1' || body.startsWith(" app.parseResponse(x + '|~1~', '~|~')) + let songs = '~' + splitBody[2]; songs = songs.split(':').map(x => app.parseResponse(x, '~|~')) songs.forEach(x => {songList[x['~1']] = x['2']}) authors.forEach(x => { diff --git a/html/iconkit.html b/html/iconkit.html index 038e424..70aa1e9 100644 --- a/html/iconkit.html +++ b/html/iconkit.html @@ -1,7 +1,7 @@ Online Icon Kit - + @@ -432,7 +432,8 @@ fetch('./api/icons').then(res => { let form = $(this).attr('form') || $(this).attr('colType') let iconNumber = $(this).attr('num') || $(this).attr('col') - if (iconNumber == 1 || ((form == "cube") && iconNumber <= 4) || ((form.startsWith('color')) && iconNumber <= 3)) return $('#howto').html("Always unlocked") + if (form == "swing") return $('#howto').html("Coming soon™") + else if (iconNumber == 1 || ((form == "cube") && iconNumber <= 4) || ((form.startsWith('color')) && iconNumber <= 3)) return $('#howto').html("Always unlocked") else if (iconNumber == miniIcon && form == "cube") return $('#howto').html("Legacy mini icon, enable in GD settings") else if (iconNumber == 13 && form == "cube") return $('#howto').html("Click lock on icon kit") diff --git a/html/level.html b/html/level.html index c837374..246848f 100644 --- a/html/level.html +++ b/html/level.html @@ -209,7 +209,7 @@ $('#levelInfo').html($('#levelInfo').html() if (!'[[UPLOADED]]'.startsWith('[')) { $('#levelInfo').html($('#levelInfo').html() - .replace('[[PASS]]', `
Password: ${'[[PASSWORD]]' == '0' ? "No copy" : '[[PASSWORD]]' == 1 ? "Free copy" : '[[PASSWORD]]'}`) + .replace('[[PASS]]', `
Password: ${'[[PASSWORD]]' == '0' || '[[PASSWORD]]'.startsWith("[") ? "No copy" : '[[PASSWORD]]' == 1 ? "Free copy" : '[[PASSWORD]]'}`) .replace('[[LOWDETAIL]]', `
Low Detail: ${[[LDM]] ? "Yes" : "No"}`) .replace('[[TIME1]]', [[EDITORTIME]] == 0 ? "" : `
Editor Time: ${colonize([[EDITORTIME]])}`) .replace('[[TIME2]]', [[TOTALEDITORTIME]] == 0 ? "" : `
Editor Time (+copies): ${colonize([[TOTALEDITORTIME]])}`) diff --git a/html/search.html b/html/search.html index 1b616c2..5a3f569 100644 --- a/html/search.html +++ b/html/search.html @@ -178,10 +178,12 @@ function Append(firstLoad) { accID = x.authorID } + let filteredSong = x.songName.replace(/[^ -~]/g, "") + if (!filteredSong) filteredSong = x.songName $('#searchBox').append(`

${x.name}

${hasAuthor ? `By ${x.author}` : `By ${x.author}`}

${x.copiedID == '0' ? "" : ''}${x.large ? '' : ''}

-

${x.songName.replace(/[^ -~]/g, "")}

+

${filteredSong}

${x.length} ${x.downloads} diff --git a/index.js b/index.js index be2e732..e80187c 100644 --- a/index.js +++ b/index.js @@ -53,7 +53,11 @@ app.use(function(req, res, next) { req.gdParams = function(obj={}) { Object.keys(app.config.params).forEach(x => { if (!obj[x]) obj[x] = app.config.params[x] }) let ip = req.headers['x-real-ip'] || req.headers['x-forwarded-for'] - return {form: obj, headers: app.config.ipForwarding && ip ? {'x-forwarded-for': ip, 'x-real-ip': ip} : {}} + let params = {form: obj, headers: app.config.ipForwarding && ip ? {'x-forwarded-for': ip, 'x-real-ip': ip} : {}} + for (let sub in app.config.substitutions) { + if (params.form[sub]) { params.form[app.config.substitutions[sub]] = params.form[sub]; delete params.form[sub] } + } + return params } next() }) @@ -96,6 +100,7 @@ catch(e) { app.parseResponse = function (responseBody, splitter) { if (!responseBody || responseBody == "-1") return {}; + if (responseBody.startsWith("\nWarning:")) responseBody = responseBody.split("\n").slice(2).join("\n") // GDPS'es are wild let response = responseBody.split('#')[0].split(splitter || ':'); let res = {}; for (let i = 0; i < response.length; i += 2) { diff --git a/misc/blocks.json b/misc/analysis/blocks.json similarity index 100% rename from misc/blocks.json rename to misc/analysis/blocks.json diff --git a/misc/colorProperties.json b/misc/analysis/colorProperties.json similarity index 100% rename from misc/colorProperties.json rename to misc/analysis/colorProperties.json diff --git a/misc/initialProperties.json b/misc/analysis/initialProperties.json similarity index 100% rename from misc/initialProperties.json rename to misc/analysis/initialProperties.json diff --git a/misc/objectProperties.json b/misc/analysis/objectProperties.json similarity index 100% rename from misc/objectProperties.json rename to misc/analysis/objectProperties.json diff --git a/misc/objects.json b/misc/analysis/objects.json similarity index 100% rename from misc/objects.json rename to misc/analysis/objects.json diff --git a/settings.js b/settings.js index b9d42ae..d7de740 100644 --- a/settings.js +++ b/settings.js @@ -4,7 +4,7 @@ module.exports = { port: 2000, // Port to host website on - endpoint: "http://boomlings.com/database/", // Server endpoint to send requests to + endpoint: "http://boomlings.com/database/", // Server endpoint to send requests to, must end with a slash params: { // Always send this stuff to the servers secret: 'Wmfd2893gb7', @@ -22,5 +22,8 @@ module.exports = { base64descriptions: true, // Are level descriptions encoded in Base64? xorPasswords: true, // Are level passwords XOR encrypted? timestampSuffix: " ago", // Suffix to add after timestamps, if any. + substitutions: { // Any parameters that are renamed on the GDPS should be listed here, e.g. { levelID: "abcde" } + // levelID: "oiuyhxp4w9I" + } } \ No newline at end of file