More analysis features + optimizations

- Modules are now required BEFORE exports
- Added object count to level analysis
- Added option to hide duplicate portals in analysis
- Removed LOADMODULES.js because it's gross
This commit is contained in:
GDColon 2019-10-16 18:47:53 -04:00
parent 19427e80eb
commit 30be2d1d61
15 changed files with 79 additions and 65 deletions

View file

@ -59,8 +59,6 @@ mapPacks.json - The IDs for the levels in map packs. I can't believe I have to h
XOR.js - Decrypts ciphered GD passwords. I stole the code from somewhere so uh if you wrote it, please don't hunt me down
LOADMODULES.js - Allows the API to run the /api files in a cooler way
---
happy painting and god bless.

View file

@ -1,6 +1,6 @@
module.exports = async (app, req, res) => {
const request = require('request')
const request = require('request')
module.exports = async (app, req, res) => {
request.get(`https://gdleaderboards.com/incl/lbxml.php`, function (err, resp, topPlayers) {
idArray = topPlayers.split(",")

View file

@ -1,6 +1,11 @@
module.exports = async (app, req, res, level) => {
const pako = require('pako')
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')
module.exports = async (app, req, res, level) => {
let levelString = new Buffer(level.data, 'base64')
let buffer;
@ -12,12 +17,6 @@ catch(e) { return res.send("-1") }
let rawData = buffer.toString('utf8')
let data = rawData
let properties = require('../misc/objectProperties.json')
let init = require('../misc/initialProperties.json')
let colorStuff = require('../misc/colorProperties.json')
let ids = require('../misc/objects.json')
let blocks = require('../misc/blocks.json')
let blockNames = Object.keys(blocks)
let miscNames = Object.keys(ids.misc)
let blockCounts = {}
@ -70,6 +69,8 @@ response.level = {
name: level.name, id: level.id, author: level.author, authorID: level.authorID, accountID: level.accountID, large: level.large
}
response.objects = data.length - 2
response.portals = data.filter(x => x.portal).sort(function (a, b) {return parseInt(a.x) - parseInt(b.x)}).map(x => x.portal).join(", ")
response.orbs = {}

View file

@ -1,6 +1,6 @@
module.exports = async (app, req, res) => {
const request = require('request')
const request = require('request')
module.exports = async (app, req, res) => {
let params = {
userID : req.params.id,

View file

@ -1,7 +1,7 @@
module.exports = async (app, req, res, api, ID, analyze) => {
const request = require('request')
const fs = require('fs')
const request = require('request')
const fs = require('fs')
module.exports = async (app, req, res, api, ID, analyze) => {
let orbs = [0, 0, 50, 75, 125, 175, 225, 275, 350, 425, 500]
let length = ['Tiny', 'Short', 'Medium', 'Long', 'XL']

View file

@ -1,14 +1,13 @@
const request = require('request')
const Jimp = require('jimp');
const plist = require('plist');
const fs = require('fs');
const path = require('path');
const icons = plist.parse(fs.readFileSync("./icons/GJ_GameSheet02-uhd.plist", 'utf8')).frames
const colors = require('../misc/colors.json')
module.exports = async (app, req, res) => {
const request = require('request')
const Jimp = require('jimp');
const plist = require('plist');
const fs = require('fs');
const fsExtra = require('fs-extra')
const path = require('path');
let icons = plist.parse(fs.readFileSync("./icons/GJ_GameSheet02-uhd.plist", 'utf8')).frames
let colors = require('../misc/colors.json')
let username = req.params.text
let form = 'player'

View file

@ -1,6 +1,6 @@
module.exports = async (app, req, res) => {
const request = require('request')
const request = require('request')
module.exports = async (app, req, res) => {
let amount = 100;
let count = req.query.count ? parseInt(req.query.count) : null

View file

@ -1,6 +1,7 @@
module.exports = async (app, req, res) => {
const request = require('request')
const request = require('request')
module.exports = async (app, req, res) => {
let amount = 100;
let count = req.query.count ? parseInt(req.query.count) : null

View file

@ -1,7 +1,7 @@
module.exports = async (app, req, res, api, analyze) => {
const request = require('request')
const fs = require('fs')
const request = require('request')
const fs = require('fs')
module.exports = async (app, req, res, api, analyze) => {
let orbs = [0, 0, 50, 75, 125, 175, 225, 275, 350, 425, 500]
let length = ['Tiny', 'Short', 'Medium', 'Long', 'XL']
@ -47,7 +47,7 @@ module.exports = async (app, req, res, api, analyze) => {
downloads: levelInfo[10],
likes: levelInfo[14],
disliked : levelInfo[14] < 0,
length: length[levelInfo[15]],
length: length[levelInfo[15]] || "?",
stars: levelInfo[18],
orbs: orbs[levelInfo[18]],
diamonds: levelInfo[18] < 2 ? 0 : parseInt(levelInfo[18]) + 2,

View file

@ -1,7 +1,7 @@
module.exports = async (app, req, res, api, getLevels) => {
const request = require('request')
const fs = require('fs')
const request = require('request')
const fs = require('fs')
module.exports = async (app, req, res, api, getLevels) => {
request.post('http://boomlings.com/database/getGJUsers20.php', {
form: {

View file

@ -1,11 +1,11 @@
module.exports = async (app, req, res) => {
const request = require('request')
const orbs = [0, 0, 50, 75, 125, 175, 225, 275, 350, 425, 500]
const difficulty = {0: 'Unrated', 10: 'Easy', 20: 'Normal', 30: 'Hard', 40: 'Harder', 50: 'Insane'}
const length = ['Tiny', 'Short', 'Medium', 'Long', 'XL']
const mapPacks = require('../misc/mapPacks.json')
const levels = require('../misc/level.json').music
const request = require('request')
const orbs = [0, 0, 50, 75, 125, 175, 225, 275, 350, 425, 500]
const difficulty = {0: 'Unrated', 10: 'Easy', 20: 'Normal', 30: 'Hard', 40: 'Harder', 50: 'Insane'}
const length = ['Tiny', 'Short', 'Medium', 'Long', 'XL']
const mapPacks = require('../misc/mapPacks.json')
const levels = require('../misc/level.json').music
module.exports = async (app, req, res) => {
let amount = 10;
let count = req.query.count ? parseInt(req.query.count) : null
@ -102,23 +102,23 @@ module.exports = async (app, req, res) => {
x.difficulty = difficulty[x[9]];
x.downloads = x[10];
x.likes = x[14];
x.disliked = x[14] < 0
x.length = length[x[15]];
x.disliked = x[14] < 0;
x.length = length[x[15]] || "?";
x.stars = x[18];
x.orbs = orbs[x[18]],
x.orbs = orbs[x[18]];
x.diamonds = x[18] < 2 ? 0 : parseInt(x[18]) + 2,
x.featured = x[19] > 0;
x.epic = x[42] == 1;
x.version = x[5];
x.copiedID = x[30];
x.officialSong = x[12] != 0 ? parseInt(x[12]) + 1 : 0,
x.customSong = x[35],
x.officialSong = x[12] != 0 ? parseInt(x[12]) + 1 : 0;
x.customSong = x[35];
x.coins = x[37];
x.verifiedCoins = x[38] == 1;
x.starsRequested = x[39];
x.objects = x[45];
x.large = x[45] > 40000;
x.cp = (x.stars > 0) + x.featured + x.epic
x.cp = (x.stars > 0) + x.featured + x.epic;
if (x[17] == 1) x.difficulty += ' Demon'
if (x.difficulty == "Insane Demon") x.difficulty = "Extreme Demon"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9 KiB

View file

@ -23,13 +23,18 @@
<div id="analysisDiv" style="margin-top: 2%; display:none">
<h2 id="levelName"></h2>
<h3 id="objectCount"></h3>
<h1 class="topMargin">Portal order</h1>
<div class="transparentBox analysis" id="portals"></div>
<div>
<div class="portalSetting"><h3><input checked type="checkbox" class="portalToggle" id="box1" portal="form"> <label for="box1" class="gdcheckbox gdButton portalButton"></label>Form Portals</h3></div>
<div class="portalSetting"><h3><input checked type="checkbox" class="portalToggle" id="box2" portal="size"> <label for="box2" class="gdcheckbox gdButton portalButton"></label>Size Portals</h3></div>
<div class="portalSetting"><h3><input checked type="checkbox" class="portalToggle" id="box3" portal="speed"><label for="box3" class="gdcheckbox gdButton portalButton"></label>Speed Portals</h3></div>
<div class="portalSetting"><h3><input checked type="checkbox" class="portalToggle" id="box4" portal="misc"> <label for="box4" class="gdcheckbox gdButton portalButton"></label>Misc Portals</h3></div>
<br><div style="height: 1.5%"></div>
<div class="portalSetting"><h3><input checked type="checkbox" class="portalToggle" id="box4" portal="mirror"><label for="box4" class="gdcheckbox gdButton portalButton"></label>Mirror Portals</h3></div>
<div class="portalSetting"><h3><input checked type="checkbox" class="portalToggle" id="box5" portal="dual"> <label for="box5" class="gdcheckbox gdButton portalButton"></label>Dual Portals</h3></div>
<div class="portalSetting"><h3><input checked type="checkbox" class="portalToggle" id="box6" portal="dupe"> <label for="box6" class="gdcheckbox gdButton portalButton"></label>Duplicates</h3></div>
</div>
<h1 class="topMargin2" id="triggerText">Triggers</h1>
@ -70,25 +75,26 @@ let disabledPortals = []
let formPortals = ['cube', 'ship', 'ball', 'ufo', 'wave', 'robot', 'spider']
let speedPortals = ['-1x', '1x', '2x', '3x', '4x']
let sizePortals = ['mini', 'big']
let miscPortals = ['dual', 'single', 'mirrorOn', 'mirrorOff']
let dualPortals = ['dual', 'single']
let mirrorPortals = ['mirrorOn', 'mirrorOff']
fetch(`../api${window.location.pathname}`).then(res => res.json()).then(res => {
if (!res.level) return window.location.href = window.location.href.replace("analyze", "search")
$('#levelName').text(res.level.name)
$('#objectCount').text(res.objects + " objects")
document.title = "Analysis of " + res.level.name
$('#meta-title').attr('content', "Analysis of " + res.level.name)
$('#meta-desc').attr('content', `${res.portals.split(",").length}x portals, ${res.orbs.total || 0}x orbs, ${res.triggers.total || 0}x triggers, ${res.misc.glow || 0}x glow...`)
let portalList = res.portals.split(", ")
let portals = portalList
let triggerList = Object.keys(res.triggers)
let orbList = Object.keys(res.orbs)
let miscList = Object.keys(res.misc)
let blockList = Object.keys(res.blocks)
let colorList = Object.keys(res.colors)
let portals = res.portals.split(", ")
function appendPortals() {
$('#portals').html("")
if (res.settings.gamemode && res.settings.gamemode != "cube" && !disabledPortals.includes('form')) $('#portals').append(`<img class="portalImage" src="../objects/portal-${res.settings.gamemode}.png" style="margin: 1.3% 0.8%"><img class="divider portalImage" src="../assets/divider.png" style="margin: 1.3% 0.8%">`)
@ -140,11 +146,17 @@ appendPortals()
if ($(this).prop('checked')) disabledPortals = disabledPortals.filter(x => x != $(this).attr('portal'))
else disabledPortals.push($(this).attr('portal'))
portals = portalList
portals = res.portals.split(", ")
if (disabledPortals.includes('form')) portals = portals.filter(x => !formPortals.includes(x))
if (disabledPortals.includes('speed')) portals = portals.filter(x => !speedPortals.includes(x))
if (disabledPortals.includes('size')) portals = portals.filter(x => !sizePortals.includes(x))
if (disabledPortals.includes('misc')) portals = portals.filter(x => !miscPortals.includes(x))
if (disabledPortals.includes('dual')) portals = portals.filter(x => !dualPortals.includes(x))
if (disabledPortals.includes('mirror')) portals = portals.filter(x => !mirrorPortals.includes(x))
if (disabledPortals.includes('dupe')) {
portals.forEach((x, y) => {if (portals[y+1] && portals[y+1] == x) portals[y] = null;})
portals = portals.filter(x => x != null)
}
appendPortals()
})
@ -159,7 +171,6 @@ appendPortals()
$('#levelCode').focus().select()
})
$('#loadingDiv').hide()
$('#analysisDiv').show()

View file

@ -155,7 +155,7 @@ $('#difficultytext').html('[[DIFFICULTY]]'.replace(' ', "<br>"))
$('#levelInfo').html($('#levelInfo').html()
.replace('[[ORIGINALINFO]]', [[COPIEDID]] == "0" ? "" : `<br>Original: <a class="youCanClickThis" href="/[[COPIEDID]]"><font color="aqua">[[COPIEDID]]</font></a>`)
.replace('[[OBJECTINFO]]', [[OBJECTS]] == "0" ? "" : `<br>Objects: <font color="yellow">[[OBJECTS]]</font>`)
.replace('[[OBJECTINFO]]', '[[OBJECTS]]' == "0" ? "" : `<br>Objects: <font color="yellow">[[OBJECTS]]</font>`)
.replace('[[REQUESTED]]', [[STARSREQUESTED]] == "0" ? "" : `<br>Stars Requested: <font color="yellow">[[STARSREQUESTED]]</font>`))
if (!'[[UPLOADED]]'.startsWith('[')) {

View file

@ -1,4 +1,3 @@
// cd C:\Users\Craig\Desktop\Projects\Robotop
const express = require('express');
const path = require('path');
const fs = require("fs")
@ -6,10 +5,10 @@ const timeout = require('connect-timeout')
const fsExtra = require("fs-extra")
fsExtra.emptyDirSync('./icons/cache')
let local = __dirname.includes('Craig')
let api = true;
let gdicons = fs.readdirSync('./icons/iconkit')
//clear icon cache every ten minutes
setInterval(function(){ fsExtra.emptyDirSync('./icons/cache') }, 600000);
const app = express();
@ -20,13 +19,17 @@ app.use(haltOnTimedout)
app.use(require('cookie-parser')());
app.set('json spaces', 2)
const secrets = require("./misc/secretStuff.json")
app.modules = { LOADMODULES: require("./misc/LOADMODULES.js") };
app.modules = app.modules.LOADMODULES();
app.modules = {}
fs.readdirSync('./api').forEach(x => {
app.modules[x.split('.')[0]] = require('./api/' + x)
})
app.secret = 'Wmfd2893gb7'
const secrets = require("./misc/secretStuff.json")
app.id = secrets.id
app.gjp = secrets.gjp
//these are the only two things in secretStuff.json, both are only used for level leaderboards
function haltOnTimedout (req, res, next) {
if (!req.timedout) next()
@ -40,6 +43,7 @@ app.parseResponse = function (responseBody, splitter) {
res[response[i]] = response[i + 1]}
return res }
//xss bad
app.clean = function(text) {if (typeof text != "string") return text; else return text.replace(/&/g, "&#38;").replace(/</g, "&#60;").replace(/>/g, "&#62;").replace(/=/g, "&#61;").replace(/"/g, "&#34;").replace(/'/g, "&#39;")}
console.log("Site online!")
@ -191,4 +195,4 @@ app.get('*', function(req, res) {
res.redirect('/search/404%20')
});
app.listen(2000);
app.listen(2000);