A lot of refactoring, and etc #232
316
api/analyze.js
|
@ -1,3 +1,4 @@
|
||||||
|
"use strict";
|
||||||
const zlib = require('zlib')
|
const zlib = require('zlib')
|
||||||
const blocks = require('../misc/analysis/blocks.json')
|
const blocks = require('../misc/analysis/blocks.json')
|
||||||
const colorStuff = require('../misc/analysis/colorProperties.json')
|
const colorStuff = require('../misc/analysis/colorProperties.json')
|
||||||
|
@ -7,121 +8,130 @@ const ids = require('../misc/analysis/objects.json')
|
||||||
|
|
||||||
module.exports = async (app, req, res, level) => {
|
module.exports = async (app, req, res, level) => {
|
||||||
|
|
||||||
if (!level) {
|
level ||= {
|
||||||
level = {
|
name: (req.body.name || "Unnamed").slice(0, 64),
|
||||||
name: (req.body.name || "Unnamed").slice(0, 64),
|
data: (req.body.data || "")
|
||||||
data: (req.body.data || "")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let unencrypted = level.data.startsWith('kS') // some gdps'es don't encrypt level data
|
let unencrypted = level.data.startsWith('kS') // some gdps'es don't encrypt level data
|
||||||
let levelString = unencrypted ? level.data : Buffer.from(level.data, 'base64')
|
let levelString = unencrypted ? level.data : Buffer.from(level.data, 'base64')
|
||||||
|
|
||||||
if (unencrypted) {
|
if (unencrypted) {
|
||||||
const raw_data = level.data;
|
const raw_data = level.data
|
||||||
|
const response_data = analyze_level(level, raw_data)
|
||||||
const response_data = analyze_level(level, raw_data);
|
return res.send(response_data)
|
||||||
return res.send(response_data);
|
}
|
||||||
} else {
|
else {
|
||||||
zlib.unzip(levelString, (err, buffer) => {
|
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 raw_data = buffer.toString()
|
||||||
const response_data = analyze_level(level, raw_data);
|
const response_data = analyze_level(level, raw_data)
|
||||||
return res.send(response_data);
|
return res.send(response_data)
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function sortObj(obj, sortBy) {
|
/**
|
||||||
var sorted = {}
|
* Sorts any `Object` by its keys
|
||||||
var keys = !sortBy ? Object.keys(obj).sort((a,b) => obj[b] - obj[a]) : Object.keys(obj).sort((a,b) => obj[b][sortBy] - obj[a][sortBy])
|
* @param {{}} obj
|
||||||
|
* @param {PropertyKey} [sortBy] optional inner key to sort
|
||||||
|
*/
|
||||||
|
const sortObj = (obj, sortBy) => {
|
||||||
|
let keys = Object.keys(obj)
|
||||||
|
.sort((a,b) => sortBy ? obj[b][sortBy] - obj[a][sortBy] : obj[b] - obj[a])
|
||||||
|
let sorted = {}
|
||||||
keys.forEach(x => {sorted[x] = obj[x]})
|
keys.forEach(x => {sorted[x] = obj[x]})
|
||||||
return sorted
|
return sorted
|
||||||
}
|
}
|
||||||
|
|
||||||
function parse_obj(obj, splitter, name_arr, valid_only) {
|
/**
|
||||||
const s_obj = obj.split(splitter);
|
* game-object (**not** JS `Object`) parser
|
||||||
let robtop_obj = {};
|
* @param {string} obj
|
||||||
|
* @param {string} splitter
|
||||||
|
* @param {string[]} name_arr
|
||||||
|
* @param {boolean} [valid_only]
|
||||||
|
*/
|
||||||
|
const parse_obj = (obj, splitter, name_arr, valid_only) => {
|
||||||
|
const s_obj = obj.split(splitter)
|
||||||
|
let robtop_obj = {}
|
||||||
|
|
||||||
// semi-useless optimization depending on where at node js you're at
|
// 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) {
|
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 (s_obj[i] in name_arr) {
|
||||||
if (!valid_only) {
|
if (!valid_only) k_name = name_arr[s_obj[i]]
|
||||||
k_name = name_arr[s_obj[i]];
|
robtop_obj[k_name] = s_obj[i + 1]
|
||||||
}
|
|
||||||
robtop_obj[k_name] = s_obj[i + 1];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return robtop_obj;
|
return robtop_obj
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {{}} level
|
||||||
|
* @param {string} rawData
|
||||||
|
*/
|
||||||
function analyze_level(level, rawData) {
|
function analyze_level(level, rawData) {
|
||||||
let response = {};
|
let response = {};
|
||||||
|
|
||||||
let blockCounts = {}
|
let blockCounts = {};
|
||||||
let miscCounts = {}
|
let miscCounts = {};
|
||||||
let triggerGroups = []
|
/**@type {string[]}*/
|
||||||
|
let triggerGroups = [];
|
||||||
let highDetail = 0
|
let highDetail = 0
|
||||||
let alphaTriggers = []
|
/**@type {{}[]}*/
|
||||||
|
let alphaTriggers = [];
|
||||||
|
|
||||||
let misc_objects = {};
|
let misc_objects = {};
|
||||||
let block_ids = {};
|
let block_ids = {};
|
||||||
|
|
||||||
for (const [name, object_ids] of Object.entries(ids.misc)) {
|
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
|
// funny enough, shift effects the original id list
|
||||||
copied_ids.forEach((object_id) => {
|
copied_ids.forEach(object_id => { misc_objects[object_id] = name })
|
||||||
misc_objects[object_id] = name;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const [name, object_ids] of Object.entries(blocks)) {
|
for (const [name, object_ids] of Object.entries(blocks))
|
||||||
object_ids.forEach((object_id) => {
|
object_ids.forEach(object_id => { block_ids[object_id] = name });
|
||||||
block_ids[object_id] = name;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = rawData.split(";");
|
/**@type {(string|{})[]}*/
|
||||||
const header = data.shift();
|
const data = rawData.split(";")
|
||||||
|
const header = data.shift()
|
||||||
|
|
||||||
let level_portals = [];
|
let level_portals = [];
|
||||||
let level_coins = [];
|
let level_coins = [];
|
||||||
let level_text = [];
|
let level_text = [];
|
||||||
|
|
||||||
|
// "why are these Objects instead of Arrays?" @Rudxain
|
||||||
let orb_array = {};
|
let orb_array = {};
|
||||||
let trigger_array = {};
|
let trigger_array = {};
|
||||||
|
|
||||||
let last = 0;
|
let last = 0
|
||||||
|
|
||||||
const obj_length = data.length;
|
const obj_length = data.length
|
||||||
for (let i = 0; i < obj_length; ++i) {
|
for (let i = 0; i < obj_length; ++i) {
|
||||||
obj = parse_obj(data[i], ',', properties);
|
let obj = parse_obj(data[i], ',', properties)
|
||||||
|
|
||||||
let id = obj.id
|
let {id} = obj
|
||||||
|
|
||||||
if (id in ids.portals) {
|
if (id in ids.portals) {
|
||||||
obj.portal = ids.portals[id];
|
obj.portal = ids.portals[id]
|
||||||
level_portals.push(obj);
|
level_portals.push(obj)
|
||||||
} else if (id in ids.coins) {
|
} else if (id in ids.coins) {
|
||||||
obj.coin = ids.coins[id];
|
obj.coin = ids.coins[id]
|
||||||
level_coins.push(obj);
|
level_coins.push(obj)
|
||||||
} else if (id in ids.orbs) {
|
} else if (id in ids.orbs) {
|
||||||
obj.orb = ids.orbs[id];
|
obj.orb = ids.orbs[id]
|
||||||
|
|
||||||
if (obj.orb in orb_array) {
|
const orb = orb_array[obj.orb]
|
||||||
orb_array[obj.orb]++;
|
orb_array[obj.orb] = orb ? +orb + 1 : 1
|
||||||
} else {
|
|
||||||
orb_array[obj.orb] = 1;
|
|
||||||
}
|
|
||||||
} else if (id in ids.triggers) {
|
} else if (id in ids.triggers) {
|
||||||
obj.trigger = ids.triggers[id];
|
obj.trigger = ids.triggers[id]
|
||||||
|
|
||||||
if (obj.trigger in trigger_array) {
|
if (obj.trigger in trigger_array) {
|
||||||
trigger_array[obj.trigger]++;
|
trigger_array[obj.trigger]++
|
||||||
} else {
|
} else {
|
||||||
trigger_array[obj.trigger] = 1;
|
trigger_array[obj.trigger] = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,60 +140,66 @@ function analyze_level(level, rawData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj.triggerGroups) obj.triggerGroups.split('.').forEach(x => triggerGroups.push(x))
|
if (obj.triggerGroups) obj.triggerGroups.split('.').forEach(x => triggerGroups.push(x))
|
||||||
if (obj.highDetail == 1) highDetail += 1
|
if (obj.highDetail == 1) highDetail++
|
||||||
|
|
||||||
if (id in misc_objects) {
|
if (id in misc_objects) {
|
||||||
const name = misc_objects[id];
|
const name = misc_objects[id]
|
||||||
if (name in miscCounts) {
|
if (name in miscCounts) {
|
||||||
miscCounts[name][0] += 1;
|
miscCounts[name][0]++
|
||||||
} else {
|
} else {
|
||||||
miscCounts[name] = [1, ids.misc[name][0]];
|
miscCounts[name] = [1, ids.misc[name][0]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id in block_ids) {
|
if (id in block_ids) {
|
||||||
const name = block_ids[id];
|
const name = block_ids[id]
|
||||||
if (name in blockCounts) {
|
if (name in blockCounts) {
|
||||||
blockCounts[name] += 1;
|
blockCounts[name]++
|
||||||
} else {
|
} else {
|
||||||
blockCounts[name] = 1;
|
blockCounts[name] = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj.x) { // sometimes the field doesn't exist
|
// sometimes the field doesn't exist
|
||||||
last = Math.max(last, obj.x);
|
if (obj.x) last = Math.max(last, obj.x)
|
||||||
}
|
|
||||||
|
|
||||||
if (obj.trigger == "Alpha") { // invisible triggers
|
// invisible triggers
|
||||||
alphaTriggers.push(obj)
|
if (obj.trigger == "Alpha") alphaTriggers.push(obj)
|
||||||
}
|
|
||||||
|
|
||||||
data[i] = obj;
|
data[i] = obj
|
||||||
}
|
}
|
||||||
|
|
||||||
let invisTriggers = []
|
let invisTriggers = []
|
||||||
alphaTriggers.forEach(tr => {
|
alphaTriggers.forEach(tr => {
|
||||||
if (tr.x < 500 && !tr.touchTriggered && !tr.spawnTriggered && tr.opacity == 0 && tr.duration == 0
|
if (
|
||||||
&& alphaTriggers.filter(x => x.targetGroupID == tr.targetGroupID).length == 1) invisTriggers.push(Number(tr.targetGroupID))
|
tr.x < 500
|
||||||
|
&& !tr.touchTriggered && !tr.spawnTriggered
|
||||||
|
&& tr.opacity == 0 && tr.duration == 0
|
||||||
|
&& alphaTriggers.filter(x => x.targetGroupID == tr.targetGroupID).length == 1
|
||||||
|
)
|
||||||
|
invisTriggers.push(Number(tr.targetGroupID))
|
||||||
})
|
})
|
||||||
|
|
||||||
response.level = {
|
response.level = {};
|
||||||
name: level.name, id: level.id, author: level.author, playerID: level.playerID, accountID: level.accountID, large: level.large
|
['name', 'id', 'author', 'playerID', 'accountID', 'large'].forEach(k => {response.level[k] = level[k]})
|
||||||
}
|
|
||||||
|
|
||||||
response.objects = data.length - 2
|
response.objects = data.length - 2
|
||||||
response.highDetail = highDetail
|
response.highDetail = highDetail
|
||||||
response.settings = {}
|
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(", ")
|
// "I have no idea what to name this lmao" @Rudxain
|
||||||
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))
|
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
|
response.coinsVerified = level.verifiedCoins
|
||||||
|
|
||||||
|
/**@param {number[]} arr*/
|
||||||
|
const sum = arr => arr.reduce((a, x) => a + x, 0)
|
||||||
response.orbs = orb_array
|
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 = 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.triggerGroups = {}
|
||||||
response.blocks = sortObj(blockCounts)
|
response.blocks = sortObj(blockCounts)
|
||||||
|
@ -191,7 +207,7 @@ function analyze_level(level, rawData) {
|
||||||
response.colors = []
|
response.colors = []
|
||||||
|
|
||||||
triggerGroups.forEach(x => {
|
triggerGroups.forEach(x => {
|
||||||
if (response.triggerGroups['Group ' + x]) response.triggerGroups['Group ' + x] += 1
|
if (response.triggerGroups['Group ' + x]) response.triggerGroups['Group ' + x]++
|
||||||
else response.triggerGroups['Group ' + x] = 1
|
else response.triggerGroups['Group ' + x] = 1
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -202,99 +218,113 @@ function analyze_level(level, rawData) {
|
||||||
// find alpha group with the most objects
|
// find alpha group with the most objects
|
||||||
response.invisibleGroup = triggerKeys.find(x => invisTriggers.includes(x))
|
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);
|
const header_response = parse_header(header)
|
||||||
response.settings = header_response.settings;
|
response.settings = header_response.settings
|
||||||
response.colors = header_response.colors;
|
response.colors = header_response.colors
|
||||||
|
|
||||||
response.dataLength = rawData.length
|
response.dataLength = rawData.length
|
||||||
response.data = rawData
|
response.data = rawData
|
||||||
|
|
||||||
return response;
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
function parse_header(header) {
|
function parse_header(/**@type {string}*/ header) {
|
||||||
let response = {};
|
let response = {}
|
||||||
response.settings = {};
|
response.settings = {}
|
||||||
response.colors = [];
|
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 => {
|
Object.keys(header_keyed).forEach(k => {
|
||||||
let val = init.values[x]
|
let val = init.values[k]
|
||||||
|
/**@type {string}*/
|
||||||
let name = val[0]
|
let name = val[0]
|
||||||
let property = header_keyed[x]
|
let property = header_keyed[k]
|
||||||
switch (val[1]) {
|
switch (val[1]) {
|
||||||
case 'list':
|
case 'list':
|
||||||
val = init[(val[0] + "s")][property];
|
val = init[(val[0] + "s")][property];
|
||||||
break;
|
break
|
||||||
case 'number':
|
case 'number':
|
||||||
val = Number(property);
|
val = Number(property);
|
||||||
break;
|
break
|
||||||
case 'bump':
|
case 'bump':
|
||||||
val = Number(property) + 1;
|
val = Number(property) + 1;
|
||||||
break;
|
break
|
||||||
case 'bool':
|
case 'bool':
|
||||||
val = property != "0";
|
val = property != "0";
|
||||||
break;
|
break
|
||||||
case 'extra-legacy-color': { // scope?
|
case 'extra-legacy-color': { // scope?
|
||||||
// you can only imagine my fear when i discovered this was a thing
|
// 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
|
// 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
|
// since i wrote the 1.9 color before this, a lot of explaination will be there instead
|
||||||
const colorInfo = name.split('-');
|
const colorInfo = name.split('-')
|
||||||
const color = colorInfo[2]; // r,g,b
|
/** r,g,b */
|
||||||
const channel = colorInfo[1];
|
const color = colorInfo[2]
|
||||||
|
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
|
// from here we touch the color object
|
||||||
let currentChannel = response.colors.find(k => k.channel == channel);
|
let currentChannel = response.colors.find(k => k.channel == channel)
|
||||||
if (color == 'blend') {
|
if (color == 'blend') currentChannel.blending = true // only one color has blending though lol
|
||||||
currentChannel.blending = true; // only one color has blending though lol
|
if (color == 'pcol' && property != 0) currentChannel.pColor = property
|
||||||
} else if (color == 'pcol' && property != 0) {
|
|
||||||
currentChannel.pColor = property;
|
currentChannel[color] = property
|
||||||
}
|
break
|
||||||
currentChannel[color] = property;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case 'legacy-color': {
|
case 'legacy-color': {
|
||||||
// if a level has a legacy color, we can assume that it does not have a kS38 at all
|
// 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
|
let colorObj = color
|
||||||
|
|
||||||
// so here we parse the color to something understandable by the rest
|
// so here we parse the color to something understandable by the rest
|
||||||
// slightly smart naming but it is also pretty gross
|
// slightly smart naming but it is also pretty gross
|
||||||
// in a sense - the name would be something like legacy-G -> G
|
// in a sense - the name would be something like legacy-G -> G
|
||||||
const colorVal = name.split('-').pop()
|
const colorVal = name.split('-').at(-1)
|
||||||
|
|
||||||
colorObj.channel = colorVal
|
colorObj.channel = colorVal
|
||||||
|
|
||||||
// from here stuff can continue as normal, ish
|
// from here stuff can continue as normal, ish
|
||||||
if (colorObj.pColor == "-1" || colorObj.pColor == "0") delete colorObj.pColor;
|
if (colorObj.pColor == "-1" || colorObj.pColor == "0")
|
||||||
colorObj.opacity = 1; // 1.9 colors don't have this!
|
delete colorObj.pColor
|
||||||
if (colorObj.blending && colorObj.blending == '1') colorObj.blending = true; // 1.9 colors manage to always think they're blending - they're not
|
colorObj.opacity = 1 // 1.9 colors don't have this!
|
||||||
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
|
if (colorObj?.blending === '1')
|
||||||
else if (colorVal == 'Line') { colorObj.blending = true; response.colors.push(colorObj); } // in line with 2.1 behavior
|
colorObj.blending = true // 1.9 colors manage to always think they're blending - they're not
|
||||||
else { response.colors.push(colorObj); } // bruh whatever was done to make the color list originally was long
|
else
|
||||||
break;
|
delete colorObj.blending
|
||||||
|
|
||||||
|
switch (colorVal) {
|
||||||
|
case '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
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'Line': {
|
||||||
|
colorObj.blending = true; response.colors.push(colorObj) // in line with 2.1 behavior
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
response.colors.push(colorObj) // bruh whatever was done to make the color list originally was long
|
||||||
|
break
|
||||||
|
}
|
||||||
|
break
|
||||||
}
|
}
|
||||||
case 'colors': {
|
case 'colors': {
|
||||||
let colorList = property.split("|")
|
let colorList = property.split("|")
|
||||||
colorList.forEach((x, y) => {
|
colorList.forEach((x, y) => {
|
||||||
const color = parse_obj(x, "_", colorStuff.properties)
|
const color = parse_obj(x, "_", colorStuff.properties)
|
||||||
let colorObj = color
|
let colorObj = color
|
||||||
if (!color.channel) return colorList = colorList.filter((h, i) => y != i)
|
if (!color.channel) return colorList = colorList.filter((_, i) => y != i)
|
||||||
|
|
||||||
if (colorStuff.channels[colorObj.channel]) colorObj.channel = colorStuff.channels[colorObj.channel]
|
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 (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.pColor == "-1") delete colorObj.pColor
|
||||||
if (colorObj.blending) colorObj.blending = true
|
if (colorObj.blending) colorObj.blending = true
|
||||||
if (colorObj.copiedHSV) {
|
if (colorObj.copiedHSV) {
|
||||||
|
@ -303,37 +333,39 @@ function parse_header(header) {
|
||||||
hsv.forEach((x, y) => { colorObj.copiedHSV[colorStuff.hsv[y]] = x })
|
hsv.forEach((x, y) => { colorObj.copiedHSV[colorStuff.hsv[y]] = x })
|
||||||
colorObj.copiedHSV['s-checked'] = colorObj.copiedHSV['s-checked'] == 1
|
colorObj.copiedHSV['s-checked'] = colorObj.copiedHSV['s-checked'] == 1
|
||||||
colorObj.copiedHSV['v-checked'] = colorObj.copiedHSV['v-checked'] == 1
|
colorObj.copiedHSV['v-checked'] = colorObj.copiedHSV['v-checked'] == 1
|
||||||
if (colorObj.copyOpacity == 1) colorObj.copyOpacity = true
|
if (colorObj.copyOpacity == 1) colorObj.copyOpacity = true
|
||||||
}
|
}
|
||||||
colorObj.opacity = +Number(colorObj.opacity).toFixed(2)
|
colorObj.opacity = +Number(colorObj.opacity).toFixed(2)
|
||||||
colorList[y] = colorObj
|
colorList[y] = colorObj
|
||||||
});
|
})
|
||||||
// we assume this is only going to be run once so... some stuff can go here
|
// we assume this is only going to be run once so... some stuff can go here
|
||||||
colorList = colorList.filter(x => typeof x == "object")
|
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"})
|
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"]
|
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 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(function(a, b) {return (+a.channel) - (+b.channel) } );
|
let regularColors = colorList.filter(x => !isNaN(x.channel)).sort((a, b) => a.channel - b.channel)
|
||||||
response.colors = specialColors.concat(regularColors)
|
response.colors = specialColors.concat(regularColors)
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
response.settings[name] = val
|
response.settings[name] = val
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!response.settings.ground || response.settings.ground > 17) response.settings.ground = 1
|
if (!response.settings.ground || response.settings.ground > 17)
|
||||||
if (!response.settings.background || response.settings.background > 20) response.settings.background = 1
|
response.settings.ground = 1
|
||||||
if (!response.settings.font) response.settings.font = 1
|
if (!response.settings.background || response.settings.background > 20)
|
||||||
|
response.settings.background = 1
|
||||||
|
if (!response.settings.font)
|
||||||
|
response.settings.font = 1
|
||||||
|
|
||||||
if (response.settings.alternateLine == 2) response.settings.alternateLine = true
|
response.settings.alternateLine = response.settings.alternateLine == 2
|
||||||
else response.settings.alternateLine = false
|
|
||||||
|
|
||||||
Object.keys(response.settings).filter(k => {
|
Object.keys(response.settings).filter(k => {
|
||||||
// this should be parsed into color list instead
|
// 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'];
|
delete response.settings['colors']
|
||||||
return response;
|
return response
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
"use strict";
|
||||||
const Player = require('../classes/Player.js')
|
const Player = require('../classes/Player.js')
|
||||||
|
|
||||||
module.exports = async (app, req, res) => {
|
module.exports = async (app, req, res) => {
|
||||||
|
@ -8,8 +9,8 @@ module.exports = async (app, req, res) => {
|
||||||
if (count > 1000) count = 1000
|
if (count > 1000) count = 1000
|
||||||
|
|
||||||
let params = {
|
let params = {
|
||||||
userID : req.params.id,
|
userID : req.params.id,
|
||||||
accountID : req.params.id,
|
accountID : req.params.id,
|
||||||
levelID: req.params.id,
|
levelID: req.params.id,
|
||||||
page: +req.query.page || 0,
|
page: +req.query.page || 0,
|
||||||
count,
|
count,
|
||||||
|
@ -20,7 +21,7 @@ module.exports = async (app, req, res) => {
|
||||||
if (req.query.type == "commentHistory") { path = "getGJCommentHistory"; delete params.levelID }
|
if (req.query.type == "commentHistory") { path = "getGJCommentHistory"; delete params.levelID }
|
||||||
else if (req.query.type == "profile") path = "getGJAccountComments20"
|
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()
|
if (err) return res.sendError()
|
||||||
|
|
||||||
|
@ -32,7 +33,7 @@ module.exports = async (app, req, res) => {
|
||||||
if (!comments.length) return res.status(204).send([])
|
if (!comments.length) return res.status(204).send([])
|
||||||
|
|
||||||
let pages = body.split('#')[1].split(":")
|
let pages = body.split('#')[1].split(":")
|
||||||
let lastPage = +Math.ceil(+pages[0] / +pages[2]);
|
let lastPage = +Math.ceil(+pages[0] / +pages[2])
|
||||||
|
|
||||||
let commentArray = []
|
let commentArray = []
|
||||||
|
|
||||||
|
@ -41,7 +42,7 @@ module.exports = async (app, req, res) => {
|
||||||
var x = c[0] //comment info
|
var x = c[0] //comment info
|
||||||
var y = c[1] //account info
|
var y = c[1] //account info
|
||||||
|
|
||||||
if (!x[2]) return;
|
if (!x[2]) return
|
||||||
|
|
||||||
let comment = {}
|
let comment = {}
|
||||||
comment.content = Buffer.from(x[2], 'base64').toString();
|
comment.content = Buffer.from(x[2], 'base64').toString();
|
||||||
|
@ -50,9 +51,9 @@ module.exports = async (app, req, res) => {
|
||||||
comment.date = (x[9] || "?") + req.timestampSuffix
|
comment.date = (x[9] || "?") + req.timestampSuffix
|
||||||
if (comment.content.endsWith("⍟") || comment.content.endsWith("☆")) {
|
if (comment.content.endsWith("⍟") || comment.content.endsWith("☆")) {
|
||||||
comment.content = comment.content.slice(0, -1)
|
comment.content = comment.content.slice(0, -1)
|
||||||
comment.browserColor = true
|
comment.browserColor = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req.query.type != "profile") {
|
if (req.query.type != "profile") {
|
||||||
let commentUser = new Player(y)
|
let commentUser = new Player(y)
|
||||||
Object.keys(commentUser).forEach(k => {
|
Object.keys(commentUser).forEach(k => {
|
||||||
|
@ -74,7 +75,7 @@ module.exports = async (app, req, res) => {
|
||||||
|
|
||||||
commentArray.push(comment)
|
commentArray.push(comment)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return res.send(commentArray)
|
return res.send(commentArray)
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
"use strict";
|
||||||
const request = require('request')
|
const request = require('request')
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const Level = require('../classes/Level.js')
|
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) => {
|
module.exports = async (app, req, res, api, ID, analyze) => {
|
||||||
|
|
||||||
function rejectLevel() {
|
function rejectLevel() {
|
||||||
if (!api) return res.redirect('search/' + req.params.id)
|
return !api ? res.redirect('search/' + req.params.id) : res.sendError()
|
||||||
else return res.sendError()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req.offline) {
|
if (req.offline) {
|
||||||
if (!api && levelID < 0) return res.redirect('/')
|
return !api && levelID < 0 ? res.redirect('/') : rejectLevel()
|
||||||
return rejectLevel()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let levelID = ID || req.params.id
|
let levelID = ID || req.params.id
|
||||||
if (levelID == "daily") levelID = -1
|
levelID = (
|
||||||
else if (levelID == "weekly") levelID = -2
|
levelID == "daily" ? -1 :
|
||||||
else levelID = levelID.replace(/[^0-9]/g, "")
|
levelID == "weekly" ? -2 :
|
||||||
|
levelID.replace(/\D/g, "")
|
||||||
|
)
|
||||||
|
|
||||||
req.gdRequest('downloadGJLevel22', { levelID }, function (err, resp, body) {
|
req.gdRequest('downloadGJLevel22', { levelID }, function (err, resp, body) {
|
||||||
|
|
||||||
if (err) {
|
if (err) return (
|
||||||
if (analyze && api && req.server.downloadsDisabled) return res.status(403).send("-3")
|
analyze && api && req.server.downloadsDisabled ? res.status(403).send("-3")
|
||||||
else if (!api && levelID < 0) return res.redirect(`/?daily=${levelID * -1}`)
|
: !api && levelID < 0 ? res.redirect(`/?daily=${levelID * -1}`)
|
||||||
else return rejectLevel()
|
: rejectLevel()
|
||||||
}
|
)
|
||||||
|
|
||||||
let authorData = body.split("#")[3] // daily/weekly only, most likely
|
let authorData = body.split("#")[3] // daily/weekly only, most likely
|
||||||
|
|
||||||
|
@ -43,7 +44,7 @@ module.exports = async (app, req, res, api, ID, analyze) => {
|
||||||
if (err2 && (foundID || authorData)) {
|
if (err2 && (foundID || authorData)) {
|
||||||
let authorInfo = foundID || authorData.split(":")
|
let authorInfo = foundID || authorData.split(":")
|
||||||
level.author = authorInfo[1] || "-"
|
level.author = authorInfo[1] || "-"
|
||||||
level.accountID = authorInfo[0] && authorInfo[0].includes(",") ? "0" : authorInfo[0]
|
level.accountID = authorInfo[0]?.includes(",") ? "0" : authorInfo[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (!err && b2 != '-1') {
|
else if (!err && b2 != '-1') {
|
||||||
|
@ -72,7 +73,7 @@ module.exports = async (app, req, res, api, ID, analyze) => {
|
||||||
if (api) return res.send(level)
|
if (api) return res.send(level)
|
||||||
|
|
||||||
else return fs.readFile('./html/level.html', 'utf8', function (err, data) {
|
else return fs.readFile('./html/level.html', 'utf8', function (err, data) {
|
||||||
let html = data;
|
let html = data
|
||||||
let variables = Object.keys(level)
|
let variables = Object.keys(level)
|
||||||
variables.forEach(x => {
|
variables.forEach(x => {
|
||||||
let regex = new RegExp(`\\[\\[${x.toUpperCase()}\\]\\]`, "g")
|
let regex = new RegExp(`\\[\\[${x.toUpperCase()}\\]\\]`, "g")
|
||||||
|
@ -89,7 +90,7 @@ module.exports = async (app, req, res, api, ID, analyze) => {
|
||||||
level.nextDaily = +dailyTime
|
level.nextDaily = +dailyTime
|
||||||
level.nextDailyTimestamp = Math.round((Date.now() + (+dailyTime * 1000)) / 100000) * 100000
|
level.nextDailyTimestamp = Math.round((Date.now() + (+dailyTime * 1000)) / 100000) * 100000
|
||||||
return sendLevel()
|
return sendLevel()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (req.server.demonList && level.difficulty == "Extreme Demon") {
|
else if (req.server.demonList && level.difficulty == "Extreme Demon") {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
"use strict";
|
||||||
let cache = {}
|
let cache = {}
|
||||||
let gauntletNames = ["Fire", "Ice", "Poison", "Shadow", "Lava", "Bonus", "Chaos", "Demon", "Time", "Crystal", "Magic", "Spike", "Monster", "Doom", "Death"]
|
let gauntletNames = ["Fire", "Ice", "Poison", "Shadow", "Lava", "Bonus", "Chaos", "Demon", "Time", "Crystal", "Magic", "Spike", "Monster", "Doom", "Death"]
|
||||||
|
|
||||||
|
@ -6,17 +7,19 @@ module.exports = async (app, req, res) => {
|
||||||
if (req.offline) return res.sendError()
|
if (req.offline) return res.sendError()
|
||||||
|
|
||||||
let cached = cache[req.id]
|
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) {
|
req.gdRequest('getGJGauntlets21', {}, function (err, resp, body) {
|
||||||
|
|
||||||
if (err) return res.sendError()
|
if (err) return res.sendError()
|
||||||
let gauntlets = body.split('#')[0].split('|').map(x => app.parseResponse(x)).filter(x => x[3])
|
let gauntlets = body.split('#', 1)[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(",") }))
|
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)
|
res.send(gauntletList)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
const {GoogleSpreadsheet} = require('google-spreadsheet');
|
"use strict";
|
||||||
const sheet = new GoogleSpreadsheet('1ADIJvAkL0XHGBDhO7PP9aQOuK3mPIKB2cVPbshuBBHc'); // accurate leaderboard spreadsheet
|
const {GoogleSpreadsheet} = require('google-spreadsheet')
|
||||||
|
const sheet = new GoogleSpreadsheet('1ADIJvAkL0XHGBDhO7PP9aQOuK3mPIKB2cVPbshuBBHc') // accurate leaderboard spreadsheet
|
||||||
|
|
||||||
let indexes = ["stars", "coins", "demons", "diamonds"]
|
let indexes = ["stars", "coins", "demons", "diamonds"]
|
||||||
|
|
||||||
|
@ -9,39 +10,41 @@ let caches = [{"stars": null, "coins": null, "demons": null, "diamonds": null},
|
||||||
|
|
||||||
module.exports = async (app, req, res, post) => {
|
module.exports = async (app, req, res, post) => {
|
||||||
|
|
||||||
// Accurate leaderboard returns 418 because private servers do not use.
|
// Accurate leaderboard returns 418 because private servers do not use.
|
||||||
if (req.isGDPS) return res.status(418).send("-2")
|
if (req.isGDPS) return res.status(418).send("-2")
|
||||||
if (!app.sheetsKey) return res.status(500).send([])
|
if (!app.sheetsKey) return res.status(500).send([])
|
||||||
let gdMode = post || req.query.hasOwnProperty("gd")
|
const gdMode = post || req.query.hasOwnProperty("gd")
|
||||||
let modMode = !gdMode && req.query.hasOwnProperty("mod")
|
const modMode = !gdMode && req.query.hasOwnProperty("mod")
|
||||||
let cache = caches[gdMode ? 2 : modMode ? 1 : 0]
|
let cache = caches[gdMode ? 2 : modMode ? 1 : 0]
|
||||||
|
|
||||||
let type = req.query.type ? req.query.type.toLowerCase() : 'stars'
|
let type = req.query.type ? req.query.type.toLowerCase() : 'stars'
|
||||||
if (type == "usercoins") type = "coins"
|
if (type == "usercoins") type = "coins"
|
||||||
if (!indexes.includes(type)) type = "stars"
|
if (!indexes.includes(type)) type = "stars"
|
||||||
if (lastIndex[modMode ? 1 : 0][type] + 600000 > Date.now() && cache[type]) return res.send(gdMode ? cache[type] : JSON.parse(cache[type])) // 10 min cache
|
if (lastIndex[modMode ? 1 : 0][type] + 600000 > Date.now() && cache[type])
|
||||||
|
return res.send(gdMode ? cache[type] : JSON.parse(cache[type])) // 10 min cache
|
||||||
|
|
||||||
sheet.useApiKey(app.sheetsKey)
|
sheet.useApiKey(app.sheetsKey)
|
||||||
sheet.loadInfo().then(async () => {
|
sheet.loadInfo().then(async () => {
|
||||||
let tab = sheet.sheetsById[1555821000]
|
let tab = sheet.sheetsById[1555821000]
|
||||||
await tab.loadCells('A2:H2')
|
await tab.loadCells('A2:H2')
|
||||||
|
|
||||||
let cellIndex = indexes.findIndex(x => type == x)
|
let cellIndex = indexes.indexOf(type)
|
||||||
if (modMode) cellIndex += indexes.length
|
if (modMode) cellIndex += indexes.length
|
||||||
|
|
||||||
let cell = tab.getCell(1, cellIndex).value
|
let cell = tab.getCell(1, cellIndex).value
|
||||||
if (!cell || typeof cell != "string" || cell.startsWith("GoogleSpreadsheetFormulaError")) { console.log("Spreadsheet Error:"); console.log(cell); return res.sendError() }
|
if (!cell || typeof cell != "string" || cell.startsWith("GoogleSpreadsheetFormulaError")) {
|
||||||
let leaderboard = JSON.parse(cell.replace(/~( |$)/g, ""))
|
console.log("Spreadsheet Error:"); console.log(cell); return res.sendError()
|
||||||
|
}
|
||||||
let gdFormatting = ""
|
let leaderboard = JSON.parse(cell.replace(/~( |$)/g, ""))
|
||||||
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()
|
|
||||||
return res.send(gdMode ? gdFormatting : leaderboard)
|
|
||||||
|
|
||||||
|
let gdFormatting = ""
|
||||||
|
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()
|
||||||
|
return res.send(gdMode ? gdFormatting : leaderboard)
|
||||||
})
|
})
|
||||||
}
|
}
|
|
@ -1,12 +1,15 @@
|
||||||
|
"use strict";
|
||||||
const request = require('request')
|
const request = require('request')
|
||||||
|
|
||||||
module.exports = async (app, req, res) => {
|
module.exports = async (app, req, res) => {
|
||||||
|
|
||||||
// Accurate leaderboard returns 418 because Private servers do not use.
|
// Accurate leaderboard returns 418 because Private servers do not use.
|
||||||
if (req.isGDPS) return res.status(418).send("0")
|
if (req.isGDPS) return res.status(418).send("0")
|
||||||
|
|
||||||
request.post('http://robtopgames.com/Boomlings/get_scores.php', {
|
request.post(
|
||||||
form : { secret: app.config.params.secret || "Wmfd2893gb7", name: "Player" } }, function(err, resp, body) {
|
'http://robtopgames.com/Boomlings/get_scores.php',
|
||||||
|
{ form : { secret: app.config.params.secret || "Wmfd2893gb7", name: "Player" } },
|
||||||
|
function(err, resp, body) {
|
||||||
|
|
||||||
if (err || !body || body == 0) return res.status(500).send("0")
|
if (err || !body || body == 0) return res.status(500).send("0")
|
||||||
|
|
||||||
|
@ -24,7 +27,7 @@ module.exports = async (app, req, res) => {
|
||||||
score: +scores.slice(3, 10),
|
score: +scores.slice(3, 10),
|
||||||
boomling: +visuals.slice(5, 7),
|
boomling: +visuals.slice(5, 7),
|
||||||
boomlingLevel: +visuals.slice(2, 4),
|
boomlingLevel: +visuals.slice(2, 4),
|
||||||
powerups: [+visuals.slice(7, 9), +visuals.slice(9, 11), +visuals.slice(11, 13)].map(x => (x > 8 || x < 1) ? 0 : x),
|
powerups: [+visuals.slice(7, 9), +visuals.slice(9, 11), +visuals.slice(11, 13)].map(x => (x > 8 || x < 1) ? 0 : x),
|
||||||
|
|
||||||
unknownVisual: +visuals.slice(0, 2),
|
unknownVisual: +visuals.slice(0, 2),
|
||||||
unknownScore: +scores.slice(0, 1),
|
unknownScore: +scores.slice(0, 1),
|
||||||
|
@ -34,10 +37,10 @@ module.exports = async (app, req, res) => {
|
||||||
if (!user.boomling || user.boomling > 66 || user.boomling < 0) user.boomling = 0
|
if (!user.boomling || user.boomling > 66 || user.boomling < 0) user.boomling = 0
|
||||||
if (!user.boomlingLevel || user.boomlingLevel > 25 || user.boomlingLevel < 1) user.boomlingLevel = 25
|
if (!user.boomlingLevel || user.boomlingLevel > 25 || user.boomlingLevel < 1) user.boomlingLevel = 25
|
||||||
|
|
||||||
users.push(user)
|
users.push(user)
|
||||||
})
|
})
|
||||||
|
|
||||||
return res.send(users)
|
return res.send(users)
|
||||||
|
}
|
||||||
})
|
)
|
||||||
}
|
}
|
|
@ -1,53 +1,50 @@
|
||||||
const colors = require('../../iconkit/sacredtexts/colors.json');
|
"use strict";
|
||||||
|
const colors = require('../../iconkit/sacredtexts/colors.json')
|
||||||
|
|
||||||
module.exports = async (app, req, res) => {
|
module.exports = async (app, req, res) => {
|
||||||
|
|
||||||
if (req.offline) return res.sendError()
|
if (req.offline) return res.sendError()
|
||||||
|
|
||||||
let amount = 100;
|
let amount = 100
|
||||||
let count = req.query.count ? parseInt(req.query.count) : null
|
let count = req.query.count ? parseInt(req.query.count) : null
|
||||||
if (count && count > 0) {
|
if (count && count > 0) amount = Math.min(count, 200)
|
||||||
if (count > 200) amount = 200
|
|
||||||
else amount = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
let params = {
|
let params = {
|
||||||
levelID: req.params.id,
|
levelID: req.params.id,
|
||||||
accountID: app.id,
|
accountID: app.id,
|
||||||
gjp: app.gjp,
|
gjp: app.gjp,
|
||||||
type: req.query.hasOwnProperty("week") ? "2" : "1",
|
type: req.query.hasOwnProperty("week") ? "2" : "1",
|
||||||
}
|
}
|
||||||
|
|
||||||
req.gdRequest('getGJLevelScores211', params, function(err, resp, body) {
|
req.gdRequest('getGJLevelScores211', params, function(err, resp, body) {
|
||||||
|
|
||||||
if (err) return res.status(500).send({error: true, lastWorked: app.timeSince(req.id)})
|
if (err) return res.status(500).send({error: true, lastWorked: app.timeSince(req.id)})
|
||||||
scores = body.split('|').map(x => app.parseResponse(x)).filter(x => x[1])
|
scores = body.split('|').map(x => app.parseResponse(x)).filter(x => x[1])
|
||||||
if (!scores.length) return res.status(500).send([])
|
if (!scores.length) return res.status(500).send([])
|
||||||
else app.trackSuccess(req.id)
|
app.trackSuccess(req.id)
|
||||||
|
|
||||||
scores.forEach(x => {
|
scores.forEach(x => {
|
||||||
let keys = Object.keys(x)
|
let keys = Object.keys(x)
|
||||||
x.rank = x[6]
|
x.rank = x[6]
|
||||||
x.username = x[1]
|
x.username = x[1]
|
||||||
x.percent = +x[3]
|
x.percent = +x[3]
|
||||||
x.coins = +x[13]
|
x.coins = +x[13]
|
||||||
x.playerID = x[2]
|
x.playerID = x[2]
|
||||||
x.accountID = x[16]
|
x.accountID = x[16]
|
||||||
x.date = x[42] + req.timestampSuffix
|
x.date = x[42] + req.timestampSuffix
|
||||||
x.icon = {
|
x.icon = {
|
||||||
form: ['icon', 'ship', 'ball', 'ufo', 'wave', 'robot', 'spider'][+x[14]],
|
form: ['icon', 'ship', 'ball', 'ufo', 'wave', 'robot', 'spider'][+x[14]],
|
||||||
icon: +x[9],
|
icon: +x[9],
|
||||||
col1: +x[10],
|
col1: +x[10],
|
||||||
col2: +x[11],
|
col2: +x[11],
|
||||||
glow: +x[15] > 1,
|
glow: +x[15] > 1,
|
||||||
col1RGB: colors[x[10]] || colors["0"],
|
col1RGB: colors[x[10]] || colors["0"],
|
||||||
col2RGB: colors[x[11]] || colors["3"]
|
col2RGB: colors[x[11]] || colors["3"]
|
||||||
}
|
}
|
||||||
keys.forEach(k => delete x[k])
|
keys.forEach(k => delete x[k])
|
||||||
app.userCache(req.id, x.accountID, x.playerID, x.username)
|
app.userCache(req.id, x.accountID, x.playerID, x.username)
|
||||||
})
|
})
|
||||||
|
|
||||||
return res.send(scores.slice(0, amount))
|
return res.send(scores.slice(0, amount))
|
||||||
|
})
|
||||||
})
|
|
||||||
}
|
}
|
|
@ -1,33 +1,35 @@
|
||||||
|
"use strict";
|
||||||
const Player = require('../../classes/Player.js')
|
const Player = require('../../classes/Player.js')
|
||||||
|
|
||||||
module.exports = async (app, req, res) => {
|
module.exports = async (app, req, res) => {
|
||||||
|
|
||||||
if (req.offline) return res.sendError()
|
if (req.offline) return res.sendError()
|
||||||
|
|
||||||
let amount = 100;
|
let amount = 100
|
||||||
let count = req.query.count ? parseInt(req.query.count) : null
|
let count = req.query.count ? parseInt(req.query.count) : 0
|
||||||
if (count && count > 0) {
|
if (count > 0) amount = Math.min(count, 10000)
|
||||||
if (count > 10000) amount = 10000
|
|
||||||
else amount = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
let params = {count: amount, type: "top"}
|
let params = {count: amount, type: "top"}
|
||||||
|
|
||||||
if (["creators", "creator", "cp"].some(x => req.query.hasOwnProperty(x) || req.query.type == x)) params.type = "creators"
|
let isInQuery = (...args) => args.some(x => req.query.hasOwnProperty(x) || req.query.type == x)
|
||||||
else if (["week", "weekly"].some(x => req.query.hasOwnProperty(x) || req.query.type == x)) params.type = "week"
|
|
||||||
else if (["global", "relative"].some(x => req.query.hasOwnProperty(x) || req.query.type == x)) {
|
|
||||||
params.type = "relative"
|
|
||||||
params.accountID = req.query.accountID
|
|
||||||
}
|
|
||||||
|
|
||||||
req.gdRequest('getGJScores20', params, function(err, resp, body) {
|
if (isInQuery("creators", "creator", "cp"))
|
||||||
|
params.type = "creators"
|
||||||
|
else if (isInQuery("week", "weekly"))
|
||||||
|
params.type = "week"
|
||||||
|
else if (isInQuery("global", "relative")) {
|
||||||
|
params.type = "relative"
|
||||||
|
params.accountID = req.query.accountID
|
||||||
|
}
|
||||||
|
|
||||||
if (err) return res.sendError()
|
req.gdRequest('getGJScores20', params, function(err, resp, body) {
|
||||||
scores = body.split('|').map(x => app.parseResponse(x)).filter(x => x[1])
|
|
||||||
if (!scores.length) return res.sendError()
|
|
||||||
|
|
||||||
scores = scores.map(x => new Player(x))
|
if (err) return res.sendError()
|
||||||
scores.forEach(x => app.userCache(req.id, x.accountID, x.playerID, x.username))
|
scores = body.split('|').map(x => app.parseResponse(x)).filter(x => x[1])
|
||||||
return res.send(scores.slice(0, amount))
|
if (!scores.length) return res.sendError()
|
||||||
})
|
|
||||||
|
scores = scores.map(x => new Player(x))
|
||||||
|
scores.forEach(x => app.userCache(req.id, x.accountID, x.playerID, x.username))
|
||||||
|
return res.send(scores.slice(0, amount))
|
||||||
|
})
|
||||||
}
|
}
|
20
api/level.js
|
@ -1,3 +1,4 @@
|
||||||
|
"use strict";
|
||||||
const request = require('request')
|
const request = require('request')
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const Level = require('../classes/Level.js')
|
const Level = require('../classes/Level.js')
|
||||||
|
@ -5,17 +6,14 @@ const Level = require('../classes/Level.js')
|
||||||
module.exports = async (app, req, res, api, analyze) => {
|
module.exports = async (app, req, res, api, analyze) => {
|
||||||
|
|
||||||
function rejectLevel() {
|
function rejectLevel() {
|
||||||
if (!api) return res.redirect('search/' + req.params.id)
|
return !api ? res.redirect('search/' + req.params.id) : res.sendError()
|
||||||
else return res.sendError()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req.offline) return rejectLevel()
|
if (req.offline) return rejectLevel()
|
||||||
|
|
||||||
let levelID = req.params.id
|
let levelID = req.params.id
|
||||||
if (levelID == "daily") return app.run.download(app, req, res, api, 'daily', analyze)
|
if (levelID == "daily" || levelID == "weekly") return app.run.download(app, req, res, api, levelID, analyze)
|
||||||
else if (levelID == "weekly") return app.run.download(app, req, res, api, 'weekly', analyze)
|
else if (/\D/.test(levelID)) return rejectLevel()
|
||||||
else if (levelID.match(/[^0-9]/)) return rejectLevel()
|
|
||||||
else levelID = levelID.replace(/[^0-9]/g, "")
|
|
||||||
|
|
||||||
if (analyze || req.query.hasOwnProperty("download")) return app.run.download(app, req, res, api, levelID, analyze)
|
if (analyze || req.query.hasOwnProperty("download")) return app.run.download(app, req, res, api, levelID, analyze)
|
||||||
|
|
||||||
|
@ -23,9 +21,11 @@ module.exports = async (app, req, res, api, analyze) => {
|
||||||
|
|
||||||
if (err || body.startsWith("##")) return rejectLevel()
|
if (err || body.startsWith("##")) return rejectLevel()
|
||||||
|
|
||||||
let preRes = body.split('#')[0].split('|', 10)
|
// "revolutionary name XD" @Rudxain
|
||||||
let author = body.split('#')[1].split('|')[0].split(':')
|
const bodySplit = body.split('#')
|
||||||
let song = '~' + body.split('#')[2];
|
let preRes = bodySplit[0].split('|', 10)
|
||||||
|
let author = bodySplit[1].split('|', 1)[0].split(':')
|
||||||
|
let song = '~' + bodySplit[2]
|
||||||
song = app.parseResponse(song, '~|~')
|
song = app.parseResponse(song, '~|~')
|
||||||
|
|
||||||
let levelInfo = app.parseResponse(preRes.find(x => x.startsWith(`1:${levelID}`)) || preRes[0])
|
let levelInfo = app.parseResponse(preRes.find(x => x.startsWith(`1:${levelID}`)) || preRes[0])
|
||||||
|
@ -40,7 +40,7 @@ module.exports = async (app, req, res, api, analyze) => {
|
||||||
if (api) return res.send(level)
|
if (api) return res.send(level)
|
||||||
|
|
||||||
else return fs.readFile('./html/level.html', 'utf8', function (err, data) {
|
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
|
let filteredSong = level.songName.replace(/[^ -~]/g, "") // strip off unsupported characters
|
||||||
level.songName = filteredSong || level.songName
|
level.songName = filteredSong || level.songName
|
||||||
let variables = Object.keys(level)
|
let variables = Object.keys(level)
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
|
"use strict";
|
||||||
let difficulties = ["auto", "easy", "normal", "hard", "harder", "insane", "demon", "demon-easy", "demon-medium", "demon-insane", "demon-extreme"]
|
let difficulties = ["auto", "easy", "normal", "hard", "harder", "insane", "demon", "demon-easy", "demon-medium", "demon-insane", "demon-extreme"]
|
||||||
let cache = {}
|
let cache = {}
|
||||||
|
|
||||||
module.exports = async (app, req, res) => {
|
module.exports = async (app, req, res) => {
|
||||||
|
|
||||||
if (req.offline) return res.sendError()
|
if (req.offline) return res.sendError()
|
||||||
|
|
||||||
let cached = cache[req.id]
|
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 params = { count: 250, page: 0 }
|
||||||
let packs = []
|
let packs = []
|
||||||
|
|
||||||
|
@ -15,7 +17,7 @@ module.exports = async (app, req, res) => {
|
||||||
|
|
||||||
if (err) return res.sendError()
|
if (err) return res.sendError()
|
||||||
|
|
||||||
let newPacks = body.split('#')[0].split('|').map(x => app.parseResponse(x)).filter(x => x[2])
|
let newPacks = body.split('#', 1)[0].split('|').map(x => app.parseResponse(x)).filter(x => x[2])
|
||||||
packs = packs.concat(newPacks)
|
packs = packs.concat(newPacks)
|
||||||
|
|
||||||
// not all GDPS'es support the count param, which means recursion time!!!
|
// not all GDPS'es support the count param, which means recursion time!!!
|
||||||
|
@ -23,7 +25,7 @@ module.exports = async (app, req, res) => {
|
||||||
params.page++
|
params.page++
|
||||||
return mapPackLoop()
|
return mapPackLoop()
|
||||||
}
|
}
|
||||||
|
|
||||||
let mappacks = packs.map(x => ({ // "packs.map()" laugh now please
|
let mappacks = packs.map(x => ({ // "packs.map()" laugh now please
|
||||||
id: +x[1],
|
id: +x[1],
|
||||||
name: x[2],
|
name: x[2],
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
"use strict";
|
||||||
module.exports = async (app, req, res) => {
|
module.exports = async (app, req, res) => {
|
||||||
|
const send = (msg, c=400) => res.status(c).send(msg)
|
||||||
|
|
||||||
if (req.method !== 'POST') return res.status(405).send("Method not allowed.")
|
if (req.method !== 'POST') return send("Method not allowed.", 405)
|
||||||
|
|
||||||
if (!req.body.accountID) return res.status(400).send("No account ID provided!")
|
if (!req.body.accountID) return send("No account ID provided!")
|
||||||
if (!req.body.password) return res.status(400).send("No password provided!")
|
if (!req.body.password) return send("No password provided!")
|
||||||
|
|
||||||
let params = {
|
let params = {
|
||||||
accountID: req.body.accountID,
|
accountID: req.body.accountID,
|
||||||
|
@ -13,11 +15,11 @@ module.exports = async (app, req, res) => {
|
||||||
|
|
||||||
req.gdRequest('getGJUserInfo20', params, function (err, resp, body) {
|
req.gdRequest('getGJUserInfo20', params, function (err, resp, body) {
|
||||||
|
|
||||||
if (err) return res.status(400).send(`Error counting messages! Messages get blocked a lot so try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`)
|
if (err) return send(`Error counting messages! Messages get blocked a lot so try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`)
|
||||||
else app.trackSuccess(req.id)
|
app.trackSuccess(req.id)
|
||||||
let count = app.parseResponse(body)[38]
|
let count = app.parseResponse(body)[38]
|
||||||
if (!count) return res.status(400).send("Error fetching unread messages!")
|
if (!count) return send("Error fetching unread messages!")
|
||||||
else res.send(count)
|
res.send(count)
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,23 +1,26 @@
|
||||||
|
"use strict";
|
||||||
module.exports = async (app, req, res) => {
|
module.exports = async (app, req, res) => {
|
||||||
|
const send = (msg, c=400) => res.status(c).send(msg)
|
||||||
|
|
||||||
if (req.method !== 'POST') return res.status(405).send("Method not allowed.")
|
if (req.method !== 'POST') return send("Method not allowed.", 405)
|
||||||
|
|
||||||
if (!req.body.accountID) return res.status(400).send("No account ID provided!")
|
if (!req.body.accountID) return send("No account ID provided!")
|
||||||
if (!req.body.password) return res.status(400).send("No password provided!")
|
if (!req.body.password) return send("No password provided!")
|
||||||
if (!req.body.id) return res.status(400).send("No message ID(s) provided!")
|
if (!req.body.id) return send("No message ID(s) provided!")
|
||||||
|
|
||||||
let params = {
|
let params = {
|
||||||
accountID: req.body.accountID,
|
accountID: req.body.accountID,
|
||||||
gjp: app.xor.encrypt(req.body.password, 37526),
|
gjp: app.xor.encrypt(req.body.password, 37526),
|
||||||
|
// serialize to CSV if needed
|
||||||
messages: Array.isArray(req.body.id) ? req.body.id.map(x => x.trim()).join(",") : req.body.id,
|
messages: Array.isArray(req.body.id) ? req.body.id.map(x => x.trim()).join(",") : req.body.id,
|
||||||
}
|
}
|
||||||
|
|
||||||
let deleted = params.messages.split(",").length
|
let deleted = params.messages.split(",").length // CSV record count
|
||||||
|
|
||||||
req.gdRequest('deleteGJMessages20', params, function (err, resp, body) {
|
req.gdRequest('deleteGJMessages20', params, function (err, resp, body) {
|
||||||
|
|
||||||
if (body != 1) return res.status(400).send(`The Geometry Dash servers refused to delete the message! Try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`)
|
if (body != 1) return send(`The Geometry Dash servers refused to delete the message! Try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`)
|
||||||
else res.send(`${deleted == 1 ? "1 message" : `${deleted} messages`} deleted!`)
|
res.send(`${deleted} message${deleted == 1 ? "" : "s"} deleted!`)
|
||||||
app.trackSuccess(req.id)
|
app.trackSuccess(req.id)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
"use strict";
|
||||||
module.exports = async (app, req, res) => {
|
module.exports = async (app, req, res) => {
|
||||||
|
const send = (msg, c=400) => res.status(c).send(msg)
|
||||||
|
|
||||||
if (req.method !== 'POST') return res.status(405).send("Method not allowed.")
|
if (req.method !== 'POST') return send("Method not allowed.", 405)
|
||||||
|
|
||||||
if (!req.body.accountID) return res.status(400).send("No account ID provided!")
|
if (!req.body.accountID) return send("No account ID provided!")
|
||||||
if (!req.body.password) return res.status(400).send("No password provided!")
|
if (!req.body.password) return send("No password provided!")
|
||||||
|
|
||||||
let params = req.gdParams({
|
let params = req.gdParams({
|
||||||
accountID: req.body.accountID,
|
accountID: req.body.accountID,
|
||||||
|
@ -13,24 +15,25 @@ module.exports = async (app, req, res) => {
|
||||||
|
|
||||||
req.gdRequest('downloadGJMessage20', params, function (err, resp, body) {
|
req.gdRequest('downloadGJMessage20', params, function (err, resp, body) {
|
||||||
|
|
||||||
if (err) return res.status(400).send(`Error fetching message! Try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`)
|
if (err) return send(`Error fetching message! Try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`)
|
||||||
else app.trackSuccess(req.id)
|
app.trackSuccess(req.id)
|
||||||
|
|
||||||
let x = app.parseResponse(body)
|
let x = app.parseResponse(body)
|
||||||
let msg = {}
|
let subject = Buffer.from(x[4], "base64").toString().replace(/^Re: ☆/, "Re: ")
|
||||||
msg.id = x[1];
|
let msg = {
|
||||||
msg.playerID = x[3]
|
id: x[1],
|
||||||
msg.accountID = x[2]
|
playerID: x[3],
|
||||||
msg.author = x[6]
|
accountID: x[2],
|
||||||
msg.subject = Buffer.from(x[4], "base64").toString().replace(/^Re: ☆/, "Re: ")
|
author: x[6],
|
||||||
msg.content = app.xor.decrypt(x[5], 14251)
|
subject,
|
||||||
msg.date = x[7] + req.timestampSuffix
|
content: app.xor.decrypt(x[5], 14251),
|
||||||
if (msg.subject.endsWith("☆") || msg.subject.startsWith("☆")) {
|
date: x[7] + req.timestampSuffix
|
||||||
if (msg.subject.endsWith("☆")) msg.subject = msg.subject.slice(0, -1)
|
}
|
||||||
else msg.subject = msg.subject.slice(1)
|
if (/^☆|☆$/.test(subject)) {
|
||||||
msg.browserColor = true
|
msg.subject = subject.slice(...(subject.endsWith("☆") ? [0, -1] : [1]))
|
||||||
}
|
msg.browserColor = true
|
||||||
|
}
|
||||||
|
|
||||||
return res.send(msg)
|
return res.send(msg)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
|
"use strict";
|
||||||
module.exports = async (app, req, res) => {
|
module.exports = async (app, req, res) => {
|
||||||
|
const send = (msg, c=400) => res.status(c).send(msg)
|
||||||
|
|
||||||
if (req.method !== 'POST') return res.status(405).send("Method not allowed.")
|
if (req.method !== 'POST') return send("Method not allowed.", 405)
|
||||||
|
|
||||||
if (req.body.count) return app.run.countMessages(app, req, res)
|
if (req.body.count) return app.run.countMessages(app, req, res)
|
||||||
if (!req.body.accountID) return res.status(400).send("No account ID provided!")
|
if (!req.body.accountID) return send("No account ID provided!")
|
||||||
if (!req.body.password) return res.status(400).send("No password provided!")
|
if (!req.body.password) return send("No password provided!")
|
||||||
|
|
||||||
let params = req.gdParams({
|
let params = req.gdParams({
|
||||||
accountID: req.body.accountID,
|
accountID: req.body.accountID,
|
||||||
|
@ -15,26 +17,26 @@ module.exports = async (app, req, res) => {
|
||||||
|
|
||||||
req.gdRequest('getGJMessages20', params, function (err, resp, body) {
|
req.gdRequest('getGJMessages20', params, function (err, resp, body) {
|
||||||
|
|
||||||
if (err) return res.status(400).send(`Error fetching messages! Messages get blocked a lot so try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`)
|
if (err) return send(`Error fetching messages! Messages get blocked a lot so try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`)
|
||||||
else app.trackSuccess(req.id)
|
else app.trackSuccess(req.id)
|
||||||
|
|
||||||
let messages = body.split("|").map(msg => app.parseResponse(msg))
|
let messages = body.split("|").map(msg => app.parseResponse(msg))
|
||||||
let messageArray = []
|
let messageArray = []
|
||||||
messages.forEach(x => {
|
messages.forEach(x => {
|
||||||
let msg = {}
|
let subject = Buffer.from(x[4], "base64").toString().replace(/^Re: ☆/, "Re: ")
|
||||||
|
let msg = {
|
||||||
msg.id = x[1];
|
id: x[1],
|
||||||
msg.playerID = x[3]
|
playerID: x[3],
|
||||||
msg.accountID = x[2]
|
accountID: x[2],
|
||||||
msg.author = x[6]
|
author: x[6],
|
||||||
msg.subject = Buffer.from(x[4], "base64").toString().replace(/^Re: ☆/, "Re: ")
|
subject,
|
||||||
msg.date = x[7] + req.timestampSuffix
|
date: x[7] + req.timestampSuffix,
|
||||||
msg.unread = x[8] != "1"
|
unread: x[8] != "1"
|
||||||
if (msg.subject.endsWith("☆") || msg.subject.startsWith("☆")) {
|
}
|
||||||
if (msg.subject.endsWith("☆")) msg.subject = msg.subject.slice(0, -1)
|
if (/^☆|☆$/.test(subject)) {
|
||||||
else msg.subject = msg.subject.slice(1)
|
msg.subject = subject.slice(...(subject.endsWith("☆") ? [0, -1] : [1]))
|
||||||
msg.browserColor = true
|
msg.browserColor = true
|
||||||
}
|
}
|
||||||
|
|
||||||
app.userCache(req.id, msg.accountID, msg.playerID, msg.author)
|
app.userCache(req.id, msg.accountID, msg.playerID, msg.author)
|
||||||
messageArray.push(msg)
|
messageArray.push(msg)
|
||||||
|
|
|
@ -1,25 +1,33 @@
|
||||||
|
"use strict";
|
||||||
module.exports = async (app, req, res) => {
|
module.exports = async (app, req, res) => {
|
||||||
|
const send = (msg, c=400) => res.status(c).send(msg)
|
||||||
|
|
||||||
if (req.method !== 'POST') return res.status(405).send("Method not allowed.")
|
if (req.method !== 'POST') return send("Method not allowed.", 405)
|
||||||
|
|
||||||
if (!req.body.targetID) return res.status(400).send("No target ID provided!")
|
if (!req.body.targetID) return send("No target ID provided!")
|
||||||
if (!req.body.message) return res.status(400).send("No message provided!")
|
if (!req.body.message) return send("No message provided!")
|
||||||
if (!req.body.accountID) return res.status(400).send("No account ID provided!")
|
if (!req.body.accountID) return send("No account ID provided!")
|
||||||
if (!req.body.password) return res.status(400).send("No password provided!")
|
if (!req.body.password) return send("No password provided!")
|
||||||
|
|
||||||
let subject = Buffer.from(req.body.subject ? (req.body.color ? "☆" : "") + (req.body.subject.slice(0, 50)) : (req.body.color ? "☆" : "") + "No subject").toString('base64').replace(/\//g, '_').replace(/\+/g, "-")
|
let subject = Buffer.from(
|
||||||
|
(req.body.color ? "☆" : "") + (req.body.subject ? req.body.subject.slice(0, 50) : "No subject")
|
||||||
|
).toString('base64url')
|
||||||
let body = app.xor.encrypt(req.body.message.slice(0, 300), 14251)
|
let body = app.xor.encrypt(req.body.message.slice(0, 300), 14251)
|
||||||
|
|
||||||
let params = req.gdParams({
|
let params = req.gdParams({
|
||||||
accountID: req.body.accountID,
|
accountID: req.body.accountID,
|
||||||
gjp: app.xor.encrypt(req.body.password, 37526),
|
gjp: app.xor.encrypt(req.body.password, 37526),
|
||||||
toAccountID: req.body.targetID,
|
toAccountID: req.body.targetID,
|
||||||
subject, body,
|
subject, body
|
||||||
})
|
})
|
||||||
|
|
||||||
req.gdRequest('uploadGJMessage20', params, function (err, resp, body) {
|
req.gdRequest('uploadGJMessage20', params, function (err, resp, body) {
|
||||||
if (body != 1) return res.status(400).send(`The Geometry Dash servers refused to send the message! Try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`)
|
if (body != 1) return send(
|
||||||
else res.send('Message sent!')
|
`The Geometry Dash servers refused to send the message! `+
|
||||||
|
`Try again later, or make sure your username and password are entered correctly. `+
|
||||||
|
`Last worked: ${app.timeSince(req.id)} ago.`
|
||||||
|
)
|
||||||
|
res.send('Message sent!')
|
||||||
app.trackSuccess(req.id)
|
app.trackSuccess(req.id)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,31 @@
|
||||||
|
"use strict";
|
||||||
const crypto = require('crypto')
|
const crypto = require('crypto')
|
||||||
function sha1(data) { return crypto.createHash("sha1").update(data, "binary").digest("hex"); }
|
const sha1 = data => crypto.createHash("sha1").update(data, "binary").digest("hex")
|
||||||
|
|
||||||
module.exports = async (app, req, res) => {
|
module.exports = async (app, req, res) => {
|
||||||
|
const send = (msg, c=400) => res.status(c).send(msg)
|
||||||
|
|
||||||
if (req.method !== 'POST') return res.status(405).send("Method not allowed.")
|
if (req.method !== 'POST') return send("Method not allowed.", 405)
|
||||||
|
|
||||||
|
if (!req.body.ID) return send("No ID provided!")
|
||||||
|
if (!req.body.accountID) return send("No account ID provided!")
|
||||||
|
if (!req.body.password) return send("No password provided!")
|
||||||
|
if (!req.body.like) return send("No like flag provided! (1=like, 0=dislike)")
|
||||||
|
if (!req.body.type) return send("No type provided! (1=level, 2=comment, 3=profile")
|
||||||
|
if (!req.body.extraID) return send("No extra ID provided! (this should be a level ID, account ID, or '0' for levels")
|
||||||
|
/*
|
||||||
|
// A compound error message is more helpful, but IDK if this may cause bugs,
|
||||||
|
// so this is commented-out
|
||||||
|
let errMsg = ""
|
||||||
|
if (!req.body.ID) errMsg += "No ID provided!\n"
|
||||||
|
if (!req.body.accountID) errMsg += "No account ID provided!\n"
|
||||||
|
if (!req.body.password) errMsg += "No password provided!\n"
|
||||||
|
if (!req.body.like) errMsg += "No like flag provided! (1=like, 0=dislike)\n"
|
||||||
|
if (!req.body.type) errMsg += "No type provided! (1=level, 2=comment, 3=profile\n"
|
||||||
|
if (!req.body.extraID) errMsg += "No extra ID provided! (this should be a level ID, account ID, or '0' for levels)\n"
|
||||||
|
if (errMsg) return send(errMsg)
|
||||||
|
*/
|
||||||
|
|
||||||
if (!req.body.ID) return res.status(400).send("No ID provided!")
|
|
||||||
if (!req.body.accountID) return res.status(400).send("No account ID provided!")
|
|
||||||
if (!req.body.password) return res.status(400).send("No password provided!")
|
|
||||||
if (!req.body.like) return res.status(400).send("No like flag provided! (1=like, 0=dislike)")
|
|
||||||
if (!req.body.type) return res.status(400).send("No type provided! (1=level, 2=comment, 3=profile")
|
|
||||||
if (!req.body.extraID) return res.status(400).send("No extra ID provided! (this should be a level ID, account ID, or '0' for levels")
|
|
||||||
|
|
||||||
let params = {
|
let params = {
|
||||||
udid: '0',
|
udid: '0',
|
||||||
uuid: '0',
|
uuid: '0',
|
||||||
|
@ -25,14 +39,15 @@ module.exports = async (app, req, res) => {
|
||||||
params.special = req.body.extraID.toString()
|
params.special = req.body.extraID.toString()
|
||||||
params.type = req.body.type.toString()
|
params.type = req.body.type.toString()
|
||||||
|
|
||||||
let chk = params.special + params.itemID + params.like + params.type + params.rs + params.accountID + params.udid + params.uuid + "ysg6pUrtjn0J"
|
let chk = "";
|
||||||
|
['special', 'itemID', 'like', 'type', 'rs', 'accountID', 'udid', 'uuid'].forEach(k => chk += params[k])
|
||||||
|
chk += "ysg6pUrtjn0J"
|
||||||
chk = sha1(chk)
|
chk = sha1(chk)
|
||||||
chk = app.xor.encrypt(chk, 58281)
|
chk = app.xor.encrypt(chk, 58281)
|
||||||
|
|
||||||
params.chk = chk
|
params.chk = chk
|
||||||
|
|
||||||
req.gdRequest('likeGJItem211', params, function (err, resp, body) {
|
req.gdRequest('likeGJItem211', params, function (err, resp, body) {
|
||||||
if (err) return res.status(400).send(`The Geometry Dash servers rejected your vote! Try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`)
|
if (err) return send(`The Geometry Dash servers rejected your vote! Try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`)
|
||||||
else app.trackSuccess(req.id)
|
else app.trackSuccess(req.id)
|
||||||
res.send((params.like == 1 ? 'Successfully liked!' : 'Successfully disliked!') + " (this will only take effect if this is your first time doing so)")
|
res.send((params.like == 1 ? 'Successfully liked!' : 'Successfully disliked!') + " (this will only take effect if this is your first time doing so)")
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,31 +1,46 @@
|
||||||
|
"use strict";
|
||||||
const crypto = require('crypto')
|
const crypto = require('crypto')
|
||||||
function sha1(data) { return crypto.createHash("sha1").update(data, "binary").digest("hex"); }
|
const sha1 = data => crypto.createHash("sha1").update(data, "binary").digest("hex")
|
||||||
|
|
||||||
Bruh Bruh
|
|||||||
let rateLimit = {};
|
let rateLimit = {}
|
||||||
let cooldown = 15000 // GD has a secret rate limit and doesn't return -1 when a comment is rejected, so this keeps track
|
let cooldown = 15000 // GD has a secret rate limit and doesn't return -1 when a comment is rejected, so this keeps track
|
||||||
|
|
||||||
|
// converts timestamp miliseconds to s (wrapped-around minutes)
|
||||||
function getTime(time) {
|
function getTime(time) {
|
||||||
let seconds = Math.ceil(time / 1000);
|
let seconds = Math.ceil(time / 1000)
|
||||||
seconds = seconds % 60;
|
seconds %= 60
|
||||||
return seconds}
|
return seconds
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = async (app, req, res) => {
|
module.exports = async (app, req, res) => {
|
||||||
|
const send = (msg, c=400) => res.status(c).send(msg)
|
||||||
|
|
||||||
if (req.method !== 'POST') return res.status(405).send("Method not allowed.")
|
if (req.method !== 'POST') return send("Method not allowed.", 405)
|
||||||
|
|
||||||
if (!req.body.comment) return res.status(400).send("No comment provided!")
|
if (!req.body.comment) return send("No comment provided!")
|
||||||
if (!req.body.username) return res.status(400).send("No username provided!")
|
if (!req.body.username) return send("No username provided!")
|
||||||
if (!req.body.levelID) return res.status(400).send("No level ID provided!")
|
if (!req.body.levelID) return send("No level ID provided!")
|
||||||
if (!req.body.accountID) return res.status(400).send("No account ID provided!")
|
if (!req.body.accountID) return send("No account ID provided!")
|
||||||
if (!req.body.password) return res.status(400).send("No password provided!")
|
if (!req.body.password) return send("No password provided!")
|
||||||
|
/*
|
||||||
|
// A compound error message is more helpful, but IDK if this may cause bugs,
|
||||||
|
// so this is commented-out
|
||||||
|
let errMsg = ""
|
||||||
|
if (!req.body.comment) errMsg += "No comment provided!\n"
|
||||||
|
if (!req.body.username) errMsg += "No username provided!\n"
|
||||||
|
if (!req.body.levelID) errMsg += "No level ID provided!\n"
|
||||||
|
if (!req.body.accountID) errMsg += "No account ID provided!\n"
|
||||||
|
if (!req.body.password) errMsg += "No password provided!\n"
|
||||||
|
if (errMsg) return send(errMsg)
|
||||||
|
*/
|
||||||
|
|
||||||
if (req.body.comment.includes('\n')) return res.status(400).send("Comments cannot contain line breaks!")
|
if (req.body.comment.includes('\n')) return send("Comments cannot contain line breaks!")
|
||||||
|
|
||||||
|
if (rateLimit[req.body.username]) return send(`Please wait ${getTime(rateLimit[req.body.username] + cooldown - Date.now())} seconds before posting another comment!`)
|
||||||
|
|
||||||
if (rateLimit[req.body.username]) return res.status(400).send(`Please wait ${getTime(rateLimit[req.body.username] + cooldown - Date.now())} seconds before posting another comment!`)
|
|
||||||
|
|
||||||
let params = { percent: 0 }
|
let params = { percent: 0 }
|
||||||
|
|
||||||
params.comment = Buffer.from(req.body.comment + (req.body.color ? "☆" : "")).toString('base64').replace(/\//g, '_').replace(/\+/g, "-")
|
params.comment = Buffer.from(req.body.comment + (req.body.color ? "☆" : "")).toString('base64url')
|
||||||
params.gjp = app.xor.encrypt(req.body.password, 37526)
|
params.gjp = app.xor.encrypt(req.body.password, 37526)
|
||||||
params.levelID = req.body.levelID.toString()
|
params.levelID = req.body.levelID.toString()
|
||||||
params.accountID = req.body.accountID.toString()
|
params.accountID = req.body.accountID.toString()
|
||||||
|
@ -40,15 +55,22 @@ module.exports = async (app, req, res) => {
|
||||||
params.chk = chk
|
params.chk = chk
|
||||||
|
|
||||||
req.gdRequest('uploadGJComment21', params, function (err, resp, body) {
|
req.gdRequest('uploadGJComment21', params, function (err, resp, body) {
|
||||||
if (err) return res.status(400).send(`The Geometry Dash servers rejected your comment! Try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`)
|
if (err) return send(
|
||||||
|
`The Geometry Dash servers rejected your comment! `+
|
||||||
|
`Try again later, or make sure your username and password are entered correctly. `+
|
||||||
|
`Last worked: ${app.timeSince(req.id)} ago.`
|
||||||
|
)
|
||||||
if (body.startsWith("temp")) {
|
if (body.startsWith("temp")) {
|
||||||
let banStuff = body.split("_")
|
let banStuff = body.split("_")
|
||||||
return res.status(400).send(`You have been banned from commenting for ${(parseInt(banStuff[1]) / 86400).toFixed(0)} days. Reason: ${banStuff[2] || "None"}`)
|
return send(
|
||||||
|
`You have been banned from commenting for ${(parseInt(banStuff[1]) / 86400).toFixed(0)} days. `+
|
||||||
|
`Reason: ${banStuff[2] || "None"}`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
res.send(`Comment posted to level ${params.levelID} with ID ${body}`)
|
res.send(`Comment posted to level ${params.levelID} with ID ${body}`)
|
||||||
app.trackSuccess(req.id)
|
app.trackSuccess(req.id)
|
||||||
rateLimit[req.body.username] = Date.now();
|
rateLimit[req.body.username] = Date.now()
|
||||||
setTimeout(() => {delete rateLimit[req.body.username]; }, cooldown);
|
setTimeout(() => {delete rateLimit[req.body.username]}, cooldown);
|
||||||
})
|
})
|
||||||
}
|
}
|
|
@ -1,20 +1,32 @@
|
||||||
|
"use strict";
|
||||||
const crypto = require('crypto')
|
const crypto = require('crypto')
|
||||||
function sha1(data) { return crypto.createHash("sha1").update(data, "binary").digest("hex"); }
|
const sha1 = data => crypto.createHash("sha1").update(data, "binary").digest("hex")
|
||||||
|
|
||||||
Use of a broken or weak cryptographic algorithmSensitive data from an access to username is used in a broken or weak cryptographic algorithm. ## Use of a broken or weak cryptographic algorithm
Sensitive data from [an access to username](1) is used in a broken or weak cryptographic algorithm.
Sensitive data from [an access to userName](2) is used in a broken or weak cryptographic algorithm.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/74)
LMAO I just changed the function to arrow fn LMAO I just changed the function to arrow fn
|
|||||||
module.exports = async (app, req, res) => {
|
module.exports = async (app, req, res) => {
|
||||||
|
const send = (msg, c=400) => res.status(c).send(msg)
|
||||||
|
|
||||||
if (req.method !== 'POST') return res.status(405).send("Method not allowed.")
|
if (req.method !== 'POST') return send("Method not allowed.", 405)
|
||||||
|
|
||||||
if (!req.body.comment) return res.status(400).send("No comment provided!")
|
if (!req.body.comment) return send("No comment provided!")
|
||||||
if (!req.body.username) return res.status(400).send("No username provided!")
|
if (!req.body.username) return send("No username provided!")
|
||||||
if (!req.body.accountID) return res.status(400).send("No account ID provided!")
|
if (!req.body.accountID) return send("No account ID provided!")
|
||||||
if (!req.body.password) return res.status(400).send("No password provided!")
|
if (!req.body.password) return send("No password provided!")
|
||||||
|
/*
|
||||||
|
// A compound error message is more helpful, but IDK if this may cause bugs,
|
||||||
|
// so this is commented-out
|
||||||
|
let errMsg = ""
|
||||||
|
if (!req.body.comment) errMsg += "No comment provided!\n"
|
||||||
|
if (!req.body.username) errMsg += "No username provided!\n"
|
||||||
|
if (!req.body.accountID) errMsg += "No account ID provided!\n"
|
||||||
|
if (!req.body.password) errMsg += "No password provided!\n"
|
||||||
|
if (errMsg) return send(errMsg)
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (req.body.comment.includes('\n')) return send("Profile posts cannot contain line breaks!")
|
||||||
|
|
||||||
if (req.body.comment.includes('\n')) return res.status(400).send("Profile posts cannot contain line breaks!")
|
|
||||||
|
|
||||||
let params = { cType: '1' }
|
let params = { cType: '1' }
|
||||||
|
|
||||||
params.comment = Buffer.from(req.body.comment.slice(0, 190) + (req.body.color ? "☆" : "")).toString('base64').replace(/\//g, '_').replace(/\+/g, "-")
|
params.comment = Buffer.from(req.body.comment.slice(0, 190) + (req.body.color ? "☆" : "")).toString('base64url')
|
||||||
params.gjp = app.xor.encrypt(req.body.password, 37526)
|
params.gjp = app.xor.encrypt(req.body.password, 37526)
|
||||||
params.accountID = req.body.accountID.toString()
|
params.accountID = req.body.accountID.toString()
|
||||||
params.userName = req.body.username
|
params.userName = req.body.username
|
||||||
|
@ -25,10 +37,10 @@ module.exports = async (app, req, res) => {
|
||||||
params.chk = chk
|
params.chk = chk
|
||||||
|
|
||||||
req.gdRequest('uploadGJAccComment20', params, function (err, resp, body) {
|
req.gdRequest('uploadGJAccComment20', params, function (err, resp, body) {
|
||||||
if (err) return res.status(400).send(`The Geometry Dash servers rejected your profile post! Try again later, or make sure your username and password are entered correctly. Try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`)
|
if (err) return send(`The Geometry Dash servers rejected your profile post! Try again later, or make sure your username and password are entered correctly. Try again later, or make sure your username and password are entered correctly. Last worked: ${app.timeSince(req.id)} ago.`)
|
||||||
else if (body.startsWith("temp")) {
|
else if (body.startsWith("temp")) {
|
||||||
let banStuff = body.split("_")
|
let banStuff = body.split("_")
|
||||||
return res.status(400).send(`You have been banned from commenting for ${(parseInt(banStuff[1]) / 86400).toFixed(0)} days. Reason: ${banStuff[2] || "None"}`)
|
return send(`You have been banned from commenting for ${(parseInt(banStuff[1]) / 86400).toFixed(0)} days. Reason: ${banStuff[2] || "None"}`)
|
||||||
}
|
}
|
||||||
else app.trackSuccess(req.id)
|
else app.trackSuccess(req.id)
|
||||||
res.send(`Comment posted to ${params.userName} with ID ${body}`)
|
res.send(`Comment posted to ${params.userName} with ID ${body}`)
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
|
"use strict";
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const Player = require('../classes/Player.js')
|
const Player = require('../classes/Player.js')
|
||||||
|
|
||||||
module.exports = async (app, req, res, api, getLevels) => {
|
module.exports = async (app, req, res, api, getLevels) => {
|
||||||
|
function rejectLevel() {
|
||||||
if (req.offline) {
|
// this variant has an extra "/"
|
||||||
if (!api) return res.redirect('/search/' + req.params.id)
|
return !api ? res.redirect('/search/' + req.params.id) : res.sendError()
|
||||||
else return res.sendError()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (req.offline) return rejectLevel()
|
||||||
|
|
||||||
let username = getLevels || req.params.id
|
let username = getLevels || req.params.id
|
||||||
let probablyID
|
let probablyID
|
||||||
if (username.endsWith(".") && req.isGDPS) {
|
if (username.endsWith(".") && req.isGDPS) {
|
||||||
|
@ -17,18 +19,18 @@ module.exports = async (app, req, res, api, getLevels) => {
|
||||||
let accountMode = !req.query.hasOwnProperty("player") && Number(req.params.id)
|
let accountMode = !req.query.hasOwnProperty("player") && Number(req.params.id)
|
||||||
let foundID = app.userCache(req.id, username)
|
let foundID = app.userCache(req.id, username)
|
||||||
let skipRequest = accountMode || foundID || probablyID
|
let skipRequest = accountMode || foundID || probablyID
|
||||||
let searchResult;
|
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)
|
// 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]
|
if (foundID) searchResult = foundID[0]
|
||||||
else if (accountMode || err1 || b1 == '-1' || b1.startsWith("<") || !b1) searchResult = probablyID ? username : req.params.id
|
else if (accountMode || err1 || b1 == '-1' || b1.startsWith("<") || !b1) searchResult = probablyID ? username : req.params.id
|
||||||
else if (!req.isGDPS) searchResult = app.parseResponse(b1.split("|")[0])[16]
|
else if (!req.isGDPS) searchResult = app.parseResponse(b1.split("|", 1)[0])[16]
|
||||||
else { // GDPS's return multiple users, GD no longer does this
|
else { // GDPS's return multiple users, GD no longer does this
|
||||||
let userResults = b1.split("|").map(x => app.parseResponse(x))
|
let userResults = b1.split("|").map(x => app.parseResponse(x))
|
||||||
searchResult = userResults.find(x => x[1].toLowerCase() == username.toLowerCase() || x[2] == username) || ""
|
searchResult = userResults.find(x => x[1].toLowerCase() == username.toLowerCase() || x[2] == username) || ""
|
||||||
if (searchResult) searchResult = searchResult[16]
|
searchResult &&= searchResult[16]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getLevels) {
|
if (getLevels) {
|
||||||
|
@ -40,20 +42,17 @@ module.exports = async (app, req, res, api, getLevels) => {
|
||||||
|
|
||||||
let account = app.parseResponse(body || "")
|
let account = app.parseResponse(body || "")
|
||||||
let dumbGDPSError = req.isGDPS && (!account[16] || account[1].toLowerCase() == "undefined")
|
let dumbGDPSError = req.isGDPS && (!account[16] || account[1].toLowerCase() == "undefined")
|
||||||
|
|
||||||
if (err2 || dumbGDPSError) {
|
if (err2 || dumbGDPSError) return rejectLevel()
|
||||||
if (!api) return res.redirect('/search/' + req.params.id)
|
|
||||||
else return res.sendError()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!foundID) app.userCache(req.id, account[16], account[2], account[1])
|
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)
|
if (api) return res.send(userData)
|
||||||
|
|
||||||
else fs.readFile('./html/profile.html', 'utf8', function(err, data) {
|
else fs.readFile('./html/profile.html', 'utf8', function(err, data) {
|
||||||
let html = data;
|
let html = data
|
||||||
let variables = Object.keys(userData)
|
let variables = Object.keys(userData)
|
||||||
variables.forEach(x => {
|
variables.forEach(x => {
|
||||||
let regex = new RegExp(`\\[\\[${x.toUpperCase()}\\]\\]`, "g")
|
let regex = new RegExp(`\\[\\[${x.toUpperCase()}\\]\\]`, "g")
|
||||||
|
@ -61,7 +60,6 @@ module.exports = async (app, req, res, api, getLevels) => {
|
||||||
})
|
})
|
||||||
return res.send(html)
|
return res.send(html)
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
})
|
||||||
|
}
|
124
api/search.js
|
@ -1,94 +1,92 @@
|
||||||
|
"use strict";
|
||||||
const request = require('request')
|
const request = require('request')
|
||||||
const music = require('../misc/music.json')
|
|
||||||
const Level = require('../classes/Level.js')
|
const Level = require('../classes/Level.js')
|
||||||
let demonList = {}
|
let demonList = {}
|
||||||
|
|
||||||
module.exports = async (app, req, res) => {
|
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 = query.hasOwnProperty("demonlist") || query.hasOwnProperty("demonList") || query.type == "demonlist" || query.type == "demonList"
|
||||||
|
|
||||||
let demonMode = req.query.hasOwnProperty("demonlist") || req.query.hasOwnProperty("demonList") || req.query.type == "demonlist" || req.query.type == "demonList"
|
|
||||||
if (demonMode) {
|
if (demonMode) {
|
||||||
if (!req.server.demonList) return res.sendError(400)
|
if (!req.server.demonList) return res.sendError(400)
|
||||||
let dList = demonList[req.id]
|
let dList = demonList[req.id]
|
||||||
if (!dList || !dList.list.length || dList.lastUpdated + 600000 < Date.now()) { // 10 minute cache
|
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()
|
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()
|
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)
|
return app.run.search(app, req, res)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let amount = 10;
|
let amount = 10
|
||||||
let count = req.isGDPS ? 10 : +req.query.count
|
let count = req.isGDPS ? 10 : +query.count
|
||||||
if (count && count > 0) {
|
if (count && count > 0) amount = Math.min(count, 500)
|
||||||
if (count > 500) amount = 500
|
|
||||||
else amount = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
let filters = {
|
let filters = {
|
||||||
str: req.params.text,
|
str: req.params.text,
|
||||||
|
|
||||||
diff: req.query.diff,
|
diff: query.diff,
|
||||||
demonFilter: req.query.demonFilter,
|
demonFilter: query.demonFilter,
|
||||||
page: req.query.page || 0,
|
page: query.page || 0,
|
||||||
gauntlet: req.query.gauntlet || 0,
|
gauntlet: query.gauntlet || 0,
|
||||||
len: req.query.length,
|
len: query.length,
|
||||||
song: req.query.songID,
|
song: query.songID,
|
||||||
followed: req.query.creators,
|
followed: query.creators,
|
||||||
|
|
||||||
featured: req.query.hasOwnProperty("featured") ? 1 : 0,
|
featured: query.hasOwnProperty("featured") ? 1 : 0,
|
||||||
originalOnly: req.query.hasOwnProperty("original") ? 1 : 0,
|
originalOnly: query.hasOwnProperty("original") ? 1 : 0,
|
||||||
twoPlayer: req.query.hasOwnProperty("twoPlayer") ? 1 : 0,
|
twoPlayer: query.hasOwnProperty("twoPlayer") ? 1 : 0,
|
||||||
coins: req.query.hasOwnProperty("coins") ? 1 : 0,
|
coins: query.hasOwnProperty("coins") ? 1 : 0,
|
||||||
epic: req.query.hasOwnProperty("epic") ? 1 : 0,
|
epic: query.hasOwnProperty("epic") ? 1 : 0,
|
||||||
star: req.query.hasOwnProperty("starred") ? 1 : 0,
|
star: query.hasOwnProperty("starred") ? 1 : 0,
|
||||||
noStar: req.query.hasOwnProperty("noStar") ? 1 : 0,
|
noStar: query.hasOwnProperty("noStar") ? 1 : 0,
|
||||||
customSong: req.query.hasOwnProperty("customSong") ? 1 : 0,
|
customSong: query.hasOwnProperty("customSong") ? 1 : 0,
|
||||||
|
|
||||||
type: req.query.type || 0,
|
type: query.type || 0,
|
||||||
count: amount
|
count: amount
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req.query.type) {
|
if (query.type) {
|
||||||
let filterCheck = req.query.type.toLowerCase()
|
let filterCheck = query.type.toLowerCase()
|
||||||
switch(filterCheck) {
|
let typeMap = {
|
||||||
case 'mostdownloaded': filters.type = 1; break;
|
'mostdownloaded': 1, 'mostliked': 2,
|
||||||
case 'mostliked': filters.type = 2; break;
|
'trending': 3, 'recent': 4,
|
||||||
case 'trending': filters.type = 3; break;
|
'featured': 6, 'magic': 7,
|
||||||
case 'recent': filters.type = 4; break;
|
'awarded': 11, 'starred': 11,
|
||||||
case 'featured': filters.type = 6; break;
|
'halloffame': 16, 'hof': 16,
|
||||||
case 'magic': filters.type = 7; break;
|
'gdw': 17, 'gdworld': 17
|
||||||
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 (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)
|
let accountCheck = app.userCache(req.id, filters.str)
|
||||||
filters.type = 5
|
filters.type = 5
|
||||||
if (accountCheck) filters.str = accountCheck[1]
|
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
|
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.type = 10
|
||||||
filters.str = demonMode ? demonList[req.id].list : filters.str.split(",")
|
filters.str = demonMode ? demonList[req.id].list : filters.str.split(",")
|
||||||
listSize = filters.str.length
|
listSize = filters.str.length
|
||||||
filters.str = filters.str.slice(filters.page*amount, filters.page*amount + amount)
|
filters.str = filters.str.slice(filters.page*amount, filters.page*amount + amount)
|
||||||
if (!filters.str.length) return res.sendError(400)
|
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
|
filters.page = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,25 +101,25 @@ module.exports = async (app, req, res) => {
|
||||||
let authorList = {}
|
let authorList = {}
|
||||||
let songList = {}
|
let songList = {}
|
||||||
let authors = splitBody[1].split('|')
|
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']})
|
songs.forEach(x => {songList[x['~1']] = x['2']})
|
||||||
|
|
||||||
authors.forEach(x => {
|
authors.forEach(x => {
|
||||||
if (x.startsWith('~')) return
|
if (x.startsWith('~')) return
|
||||||
let arr = x.split(':')
|
let arr = x.split(':')
|
||||||
authorList[arr[0]] = [arr[1], arr[2]]})
|
authorList[arr[0]] = [arr[1], arr[2]]
|
||||||
|
})
|
||||||
|
|
||||||
let levelArray = preRes.map(x => app.parseResponse(x)).filter(x => x[1])
|
let levelArray = preRes.map(x => app.parseResponse(x)).filter(x => x[1])
|
||||||
let parsedLevels = []
|
let parsedLevels = []
|
||||||
|
|
||||||
levelArray.forEach((x, y) => {
|
levelArray.forEach((x, y) => {
|
||||||
|
|
||||||
let songSearch = songs.find(y => y['~1'] == x[35]) || []
|
let songSearch = songs.find(y => y['~1'] == x[35]) || []
|
||||||
|
|
||||||
let level = new Level(x, req.server).getSongInfo(songSearch)
|
let level = new Level(x, req.server).getSongInfo(songSearch)
|
||||||
if (!level.id) return
|
if (!level.id) return
|
||||||
level.author = authorList[x[6]] ? authorList[x[6]][0] : "-";
|
level.author = authorList[x[6]] ? authorList[x[6]][0] : "-"
|
||||||
level.accountID = authorList[x[6]] ? authorList[x[6]][1] : "0";
|
level.accountID = authorList[x[6]] ? authorList[x[6]][1] : "0"
|
||||||
|
|
||||||
if (demonMode) {
|
if (demonMode) {
|
||||||
if (!y) level.demonList = req.server.demonList
|
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
|
//this is broken if you're not on page 0, blame robtop
|
||||||
if (filters.page == 0 && y == 0 && splitBody[3]) {
|
if (filters.page == 0 && y == 0 && splitBody[3]) {
|
||||||
let pages = splitBody[3].split(":");
|
let pages = splitBody[3].split(":")
|
||||||
|
|
||||||
if (filters.gauntlet) { // gauntlet page stuff
|
if (filters.gauntlet) { // gauntlet page stuff
|
||||||
level.results = levelArray.length
|
level.results = levelArray.length
|
||||||
level.pages = 1
|
level.pages = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (filters.type == 10) { // custom page stuff
|
else if (filters.type == 10) { // custom page stuff
|
||||||
level.results = listSize
|
level.results = listSize
|
||||||
level.pages = +Math.ceil(listSize / (amount || 10))
|
level.pages = Math.ceil(listSize / (amount || 10))
|
||||||
}
|
}
|
||||||
|
|
||||||
else { // normal page stuff
|
else { // normal page stuff
|
||||||
level.results = +pages[0];
|
level.results = +pages[0]
|
||||||
level.pages = +pages[0] == 9999 ? 1000 : +Math.ceil(pages[0] / amount);
|
level.pages = +pages[0] == 9999 ? 1000 : Math.ceil(pages[0] / amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
|
"use strict";
|
||||||
module.exports = async (app, req, res) => {
|
module.exports = async (app, req, res) => {
|
||||||
|
|
||||||
if (req.offline) return res.sendError()
|
if (req.offline) return res.sendError()
|
||||||
|
|
||||||
let songID = req.params.song
|
let songID = req.params.song
|
||||||
req.gdRequest('getGJSongInfo', {songID: songID}, function(err, resp, body) {
|
req.gdRequest('getGJSongInfo', {songID: songID}, function(err, resp, body) {
|
||||||
if (err) return res.sendError(400)
|
return err
|
||||||
return res.send(!body.startsWith("-") && body.length > 10)
|
? res.sendError(400)
|
||||||
|
: res.send(!body.startsWith("-") && body.length > 10)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,7 +184,7 @@ h2 {
|
||||||
.brownBox {
|
.brownBox {
|
||||||
border: 2.5vh solid transparent;
|
border: 2.5vh solid transparent;
|
||||||
border-radius: 3vh;
|
border-radius: 3vh;
|
||||||
background-color: #995533;
|
background-color: #953;
|
||||||
border-image: url('../../assets/brownbox.png') 10% round;
|
border-image: url('../../assets/brownbox.png') 10% round;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,4 +205,4 @@ h2 {
|
||||||
-webkit-transform: rotate(360deg);
|
-webkit-transform: rotate(360deg);
|
||||||
transform: rotate(360deg)
|
transform: rotate(360deg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,9 +54,9 @@ img, .noSelect {
|
||||||
}
|
}
|
||||||
|
|
||||||
.supercenter {
|
.supercenter {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translate(-50%,-50%);
|
transform: translate(-50%,-50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,7 +252,7 @@ textarea::-webkit-scrollbar {
|
||||||
width: 1.5vh;
|
width: 1.5vh;
|
||||||
background: #6d3c24;
|
background: #6d3c24;
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea::-webkit-scrollbar-thumb {
|
textarea::-webkit-scrollbar-thumb {
|
||||||
background: rgb(83, 47, 28);
|
background: rgb(83, 47, 28);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
@ -345,7 +345,7 @@ input::-webkit-outer-spin-button, input::-webkit-inner-spin-button {
|
||||||
border-width: 2.5vh;
|
border-width: 2.5vh;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-radius: 3vh;
|
border-radius: 3vh;
|
||||||
background-color: #995533;
|
background-color: #953;
|
||||||
border-image: url('../../assets/brownbox.png') 10% round;
|
border-image: url('../../assets/brownbox.png') 10% round;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,7 +353,7 @@ input::-webkit-outer-spin-button, input::-webkit-inner-spin-button {
|
||||||
border-width: 2.5vh;
|
border-width: 2.5vh;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-radius: 3vh;
|
border-radius: 3vh;
|
||||||
background-color: #334499;
|
background-color: #349;
|
||||||
border-image: url('../../assets/bluebox.png') 10% round;
|
border-image: url('../../assets/bluebox.png') 10% round;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,8 +563,8 @@ input::-webkit-outer-spin-button, input::-webkit-inner-spin-button {
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup {
|
.popup {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
display: none;
|
display: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
top: 0; left: 0; right: 0; bottom: 0;
|
top: 0; left: 0; right: 0; bottom: 0;
|
||||||
|
@ -619,9 +619,9 @@ input::-webkit-outer-spin-button, input::-webkit-inner-spin-button {
|
||||||
}
|
}
|
||||||
|
|
||||||
#scoreTabs {
|
#scoreTabs {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
top: 2.45%;
|
top: 2.45%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-left: -13.5vh
|
margin-left: -13.5vh
|
||||||
}
|
}
|
||||||
|
@ -629,13 +629,13 @@ input::-webkit-outer-spin-button, input::-webkit-inner-spin-button {
|
||||||
#searchBox {
|
#searchBox {
|
||||||
background-color: rgb(173, 115, 76);
|
background-color: rgb(173, 115, 76);
|
||||||
width: 122vh;
|
width: 122vh;
|
||||||
height: 75%;
|
height: 75%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#searchBox::-webkit-scrollbar, #statusDiv::-webkit-scrollbar, #commentBox::-webkit-scrollbar {
|
#searchBox::-webkit-scrollbar, #statusDiv::-webkit-scrollbar, #commentBox::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.searchResult {
|
.searchResult {
|
||||||
|
@ -703,7 +703,7 @@ input::-webkit-outer-spin-button, input::-webkit-inner-spin-button {
|
||||||
|
|
||||||
|
|
||||||
.comment h2, .smallGold {
|
.comment h2, .smallGold {
|
||||||
background: -webkit-linear-gradient(#e28000, #ffee44);
|
background: -webkit-linear-gradient(#e28000, #fe4);
|
||||||
background-clip: text;
|
background-clip: text;
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
|
@ -902,7 +902,7 @@ input::-webkit-outer-spin-button, input::-webkit-inner-spin-button {
|
||||||
background-color: #BE6F3F;
|
background-color: #BE6F3F;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
scrollbar-width: none;
|
scrollbar-width: none;
|
||||||
-ms-overflow-style: none;
|
-ms-overflow-style: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#msgList::-webkit-scrollbar {
|
#msgList::-webkit-scrollbar {
|
||||||
|
@ -1029,7 +1029,7 @@ input::-webkit-outer-spin-button, input::-webkit-inner-spin-button {
|
||||||
}
|
}
|
||||||
|
|
||||||
.analysis::-webkit-scrollbar-thumb, .levelCode::-webkit-scrollbar-thumb {
|
.analysis::-webkit-scrollbar-thumb, .levelCode::-webkit-scrollbar-thumb {
|
||||||
background: rgba(0, 0, 0, 0.3);
|
background: rgba(0, 0, 0, 0.3);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1292,7 +1292,7 @@ input::-webkit-outer-spin-button, input::-webkit-inner-spin-button {
|
||||||
.gdpslogo {
|
.gdpslogo {
|
||||||
margin-bottom: 0%;
|
margin-bottom: 0%;
|
||||||
border-radius: 10%;
|
border-radius: 10%;
|
||||||
filter: drop-shadow(0.5vh 0.5vh 0.15vh rgba(0, 0, 0, 0.6))
|
filter: drop-shadow(0.5vh 0.5vh 0.15vh rgba(0, 0, 0, 0.6))
|
||||||
}
|
}
|
||||||
|
|
||||||
.menuDisabled, .downloadDisabled {
|
.menuDisabled, .downloadDisabled {
|
||||||
|
@ -1311,14 +1311,14 @@ input::-webkit-outer-spin-button, input::-webkit-inner-spin-button {
|
||||||
|
|
||||||
cr { color: #ff5a5a }
|
cr { color: #ff5a5a }
|
||||||
co { color: #ffa54b }
|
co { color: #ffa54b }
|
||||||
cy { color: #ffff00 }
|
cy { color: #ff0 }
|
||||||
cg { color: #40e348 }
|
cg { color: #40e348 }
|
||||||
ca { color: #00ffff }
|
ca { color: #0ff }
|
||||||
cb { color: #60abef }
|
cb { color: #60abef }
|
||||||
cp { color: #ff00ff }
|
cp { color: #f0f }
|
||||||
|
|
||||||
.red {
|
.red {
|
||||||
color: #ff0000 !important;
|
color: #f00 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.yellow {
|
.yellow {
|
||||||
|
@ -1350,11 +1350,11 @@ cp { color: #ff00ff }
|
||||||
}
|
}
|
||||||
|
|
||||||
.brightblue {
|
.brightblue {
|
||||||
color: #99ffff
|
color: #9ff
|
||||||
}
|
}
|
||||||
|
|
||||||
.brightred {
|
.brightred {
|
||||||
color: #ffaaaa;
|
color: #faa;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gray {
|
.gray {
|
||||||
|
@ -1380,10 +1380,10 @@ cp { color: #ff00ff }
|
||||||
@-moz-keyframes spin { 100% { -moz-transform: rotate(360deg); } }
|
@-moz-keyframes spin { 100% { -moz-transform: rotate(360deg); } }
|
||||||
@-webkit-keyframes spin { 100% { -webkit-transform: rotate(360deg); } }
|
@-webkit-keyframes spin { 100% { -webkit-transform: rotate(360deg); } }
|
||||||
|
|
||||||
@keyframes spin {
|
@keyframes spin {
|
||||||
100% {
|
100% {
|
||||||
-webkit-transform: rotate(360deg);
|
-webkit-transform: rotate(360deg);
|
||||||
transform:rotate(360deg); }
|
transform:rotate(360deg); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes boxAnimator {
|
@keyframes boxAnimator {
|
||||||
|
@ -1434,11 +1434,11 @@ cp { color: #ff00ff }
|
||||||
* Also disabled on devices that may be slow to render new frames for performance optimization
|
* Also disabled on devices that may be slow to render new frames for performance optimization
|
||||||
*/
|
*/
|
||||||
@media screen and
|
@media screen and
|
||||||
(prefers-reduced-motion: reduce),
|
(prefers-reduced-motion: reduce),
|
||||||
(update: slow) {
|
(update: slow) {
|
||||||
*, *::before, *::after {
|
*, *::before, *::after {
|
||||||
animation-duration: 0.001ms !important;
|
animation-duration: 0.001ms !important;
|
||||||
animation-iteration-count: 1 !important;
|
animation-iteration-count: 1 !important;
|
||||||
transition-duration: 0.001ms !important;
|
transition-duration: 0.001ms !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background-color: 555555;
|
background-color: #555;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
|
@ -144,9 +144,9 @@ input:focus, select:focus, textarea:focus, button:focus {
|
||||||
}
|
}
|
||||||
|
|
||||||
.supercenter {
|
.supercenter {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translate(-50%,-50%);
|
transform: translate(-50%,-50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +194,7 @@ input:focus, select:focus, textarea:focus, button:focus {
|
||||||
padding: 10 10 10 10;
|
padding: 10 10 10 10;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#symbols p {
|
#symbols p {
|
||||||
|
@ -238,8 +238,8 @@ input:focus, select:focus, textarea:focus, button:focus {
|
||||||
#generate {
|
#generate {
|
||||||
font-family: "Roboto";
|
font-family: "Roboto";
|
||||||
border: rgba(0, 0, 0, 0);
|
border: rgba(0, 0, 0, 0);
|
||||||
background-color: #88FF33;
|
background-color: #8F3;
|
||||||
box-shadow: 2px 2px 3px #66AA22;
|
box-shadow: 2px 2px 3px #6A2;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
color: black;
|
color: black;
|
||||||
padding: 10px 15px 10px 15px;
|
padding: 10px 15px 10px 15px;
|
||||||
|
@ -259,8 +259,8 @@ input:focus, select:focus, textarea:focus, button:focus {
|
||||||
.miniButton {
|
.miniButton {
|
||||||
font-family: "Roboto";
|
font-family: "Roboto";
|
||||||
border: rgba(0, 0, 0, 0);
|
border: rgba(0, 0, 0, 0);
|
||||||
background-color: #88FF33;
|
background-color: #8F3;
|
||||||
box-shadow: 1.5px 1.5px 2px #66AA22;
|
box-shadow: 1.5px 1.5px 2px #6A2;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
color: black;
|
color: black;
|
||||||
padding: 7px 9px 7px 9px;
|
padding: 7px 9px 7px 9px;
|
||||||
|
@ -375,11 +375,11 @@ input:focus, select:focus, textarea:focus, button:focus {
|
||||||
#colors::-webkit-scrollbar, #iconKitParent::-webkit-scrollbar {
|
#colors::-webkit-scrollbar, #iconKitParent::-webkit-scrollbar {
|
||||||
width: 9px;
|
width: 9px;
|
||||||
height: 10px;
|
height: 10px;
|
||||||
background: rgba(0, 0, 0, 0.5);
|
background: rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
#colors::-webkit-scrollbar-thumb, #iconKitParent::-webkit-scrollbar-thumb {
|
#colors::-webkit-scrollbar-thumb, #iconKitParent::-webkit-scrollbar-thumb {
|
||||||
background: rgb(185, 185, 185);
|
background: rgb(185, 185, 185);
|
||||||
}
|
}
|
||||||
|
|
||||||
#iconKitParent {
|
#iconKitParent {
|
||||||
|
@ -394,7 +394,7 @@ input:focus, select:focus, textarea:focus, button:focus {
|
||||||
|
|
||||||
.iconColor div {
|
.iconColor div {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#gdfloor {
|
#gdfloor {
|
||||||
|
@ -423,13 +423,13 @@ input:focus, select:focus, textarea:focus, button:focus {
|
||||||
}
|
}
|
||||||
|
|
||||||
#iconprogressbar {
|
#iconprogressbar {
|
||||||
background: rgba(0, 0, 0, 0.5);
|
background: rgba(0, 0, 0, 0.5);
|
||||||
height: 7px;
|
height: 7px;
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#iconloading {
|
#iconloading {
|
||||||
background: rgba(255, 255, 255, 0.5);
|
background: rgba(255, 255, 255, 0.5);
|
||||||
height: 7px;
|
height: 7px;
|
||||||
width: 0%;
|
width: 0%;
|
||||||
}
|
}
|
||||||
|
@ -447,8 +447,8 @@ body::-webkit-scrollbar {
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup {
|
.popup {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
display: none;
|
display: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
top: 0; left: 0; right: 0; bottom: 0;
|
top: 0; left: 0; right: 0; bottom: 0;
|
||||||
|
@ -459,7 +459,7 @@ body::-webkit-scrollbar {
|
||||||
.brownBox {
|
.brownBox {
|
||||||
border: 17px solid rgba(0, 0, 0, 0);
|
border: 17px solid rgba(0, 0, 0, 0);
|
||||||
border-radius: 25px;
|
border-radius: 25px;
|
||||||
background-color: #995533;
|
background-color: #953;
|
||||||
border-image: url('../../assets/brownbox.png') 10% round;
|
border-image: url('../../assets/brownbox.png') 10% round;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -686,4 +686,4 @@ input[type="range"]::-webkit-slider-thumb:active { background-image: url("../../
|
||||||
|
|
||||||
@-moz-keyframes spin { 100% { -moz-transform: rotate(360deg); } }
|
@-moz-keyframes spin { 100% { -moz-transform: rotate(360deg); } }
|
||||||
@-webkit-keyframes spin { 100% { -webkit-transform: rotate(360deg); } }
|
@-webkit-keyframes spin { 100% { -webkit-transform: rotate(360deg); } }
|
||||||
@keyframes spin { 100% { -webkit-transform: rotate(360deg); transform:rotate(360deg); } }
|
@keyframes spin { 100% { -webkit-transform: rotate(360deg); transform:rotate(360deg); } }
|
||||||
|
|
|
@ -1,16 +1,19 @@
|
||||||
const XOR = require(__dirname + "/../classes/XOR");
|
"use strict";
|
||||||
const music = require(__dirname + "/../misc/music.json");
|
const XOR = require("./XOR")
|
||||||
|
const music = require("../misc/music.json")
|
||||||
|
|
||||||
let orbs = [0, 0, 50, 75, 125, 175, 225, 275, 350, 425, 500]
|
let orbs = [0, 0, 50, 75, 125, 175, 225, 275, 350, 425, 500]
|
||||||
let length = ['Tiny', 'Short', 'Medium', 'Long', 'XL']
|
let length = ['Tiny', 'Short', 'Medium', 'Long', 'XL']
|
||||||
|
// this can't be shortened with a loop
|
||||||
let difficulty = { 0: 'Unrated', 10: 'Easy', 20: 'Normal', 30: 'Hard', 40: 'Harder', 50: 'Insane' }
|
let difficulty = { 0: 'Unrated', 10: 'Easy', 20: 'Normal', 30: 'Hard', 40: 'Harder', 50: 'Insane' }
|
||||||
let demonTypes = { 3: "Easy", 4: "Medium", 5: "Insane", 6: "Extreme" }
|
let demonTypes = { 3: "Easy", 4: "Medium", 5: "Insane", 6: "Extreme" }
|
||||||
|
let dailyLimit = 100000
|
||||||
|
|
||||||
class Level {
|
class Level {
|
||||||
constructor(levelInfo, server, download, author = []) {
|
constructor(levelInfo, server, download, author = []) {
|
||||||
this.name = levelInfo[2] || "-";
|
this.name = levelInfo[2] || "-"
|
||||||
this.id = levelInfo[1] || 0;
|
this.id = levelInfo[1] || 0
|
||||||
this.description = Buffer.from((levelInfo[3] || ""), "base64").toString() || "(No description provided)";
|
this.description = Buffer.from((levelInfo[3] || ""), "base64").toString() || "(No description provided)"
|
||||||
this.author = author[1] || "-"
|
this.author = author[1] || "-"
|
||||||
this.playerID = levelInfo[6] || 0
|
this.playerID = levelInfo[6] || 0
|
||||||
this.accountID = author[2] || 0
|
this.accountID = author[2] || 0
|
||||||
|
@ -29,8 +32,8 @@ class Level {
|
||||||
if (levelInfo[29]) this.updated = levelInfo[29] + (server.timestampSuffix || "")
|
if (levelInfo[29]) this.updated = levelInfo[29] + (server.timestampSuffix || "")
|
||||||
if (levelInfo[46]) this.editorTime = +levelInfo[46] || 0
|
if (levelInfo[46]) this.editorTime = +levelInfo[46] || 0
|
||||||
if (levelInfo[47]) this.totalEditorTime = +levelInfo[47] || 0
|
if (levelInfo[47]) this.totalEditorTime = +levelInfo[47] || 0
|
||||||
if (levelInfo[27]) this.password = levelInfo[27];
|
if (levelInfo[27]) this.password = levelInfo[27]
|
||||||
this.version = +levelInfo[5] || 0;
|
this.version = +levelInfo[5] || 0
|
||||||
this.copiedID = levelInfo[30] || "0"
|
this.copiedID = levelInfo[30] || "0"
|
||||||
this.twoPlayer = levelInfo[31] > 0
|
this.twoPlayer = levelInfo[31] > 0
|
||||||
this.officialSong = +levelInfo[35] ? 0 : parseInt(levelInfo[12]) + 1
|
this.officialSong = +levelInfo[35] ? 0 : parseInt(levelInfo[12]) + 1
|
||||||
|
@ -39,21 +42,24 @@ class Level {
|
||||||
this.verifiedCoins = levelInfo[38] > 0
|
this.verifiedCoins = levelInfo[38] > 0
|
||||||
this.starsRequested = +levelInfo[39] || 0
|
this.starsRequested = +levelInfo[39] || 0
|
||||||
this.ldm = levelInfo[40] > 0
|
this.ldm = levelInfo[40] > 0
|
||||||
if (+levelInfo[41] > 100000) this.weekly = true
|
if (+levelInfo[41] > dailyLimit) this.weekly = true
|
||||||
if (+levelInfo[41]) { this.dailyNumber = (+levelInfo[41] > 100000 ? +levelInfo[41] - 100000 : +levelInfo[41]); this.nextDaily = null; this.nextDailyTimestamp = null }
|
if (+levelInfo[41]) {
|
||||||
|
this.dailyNumber = (+levelInfo[41] > dailyLimit ? +levelInfo[41] - dailyLimit : +levelInfo[41])
|
||||||
|
this.nextDaily = null
|
||||||
|
this.nextDailyTimestamp = null
|
||||||
|
}
|
||||||
this.objects = +levelInfo[45] || 0
|
this.objects = +levelInfo[45] || 0
|
||||||
this.large = levelInfo[45] > 40000;
|
this.large = levelInfo[45] > 40000
|
||||||
this.cp = Number((this.stars > 0) + this.featured + this.epic)
|
this.cp = Number((this.stars > 0) + this.featured + this.epic)
|
||||||
|
|
||||||
if (levelInfo[17] > 0) this.difficulty = (demonTypes[levelInfo[43]] || "Hard") + " Demon"
|
if (levelInfo[17] > 0) this.difficulty = (demonTypes[levelInfo[43]] || "Hard") + " Demon"
|
||||||
if (levelInfo[25] > 0) this.difficulty = 'Auto'
|
if (levelInfo[25] > 0) this.difficulty = 'Auto'
|
||||||
this.difficultyFace = `${levelInfo[17] != 1 ? this.difficulty.toLowerCase() : `demon-${this.difficulty.toLowerCase().split(' ')[0]}`}${this.epic ? '-epic' : `${this.featured ? '-featured' : ''}`}`
|
this.difficultyFace = `${levelInfo[17] != 1 ? this.difficulty.toLowerCase() : `demon-${this.difficulty.toLowerCase().split(' ', 1)[0]}`}${this.epic ? '-epic' : `${this.featured ? '-featured' : ''}`}`
|
||||||
|
|
||||||
if (this.password && this.password != 0) {
|
if (this.password && this.password != 0) {
|
||||||
let xor = new XOR();
|
let xor = new XOR()
|
||||||
let pass = xor.decrypt(this.password, 26364);
|
let pass = xor.decrypt(this.password, 26364)
|
||||||
if (pass.length > 1) this.password = pass.slice(1);
|
this.password = pass.length > 1 ? pass.slice(1) : pass
|
||||||
else this.password = pass;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server.onePointNine) {
|
if (server.onePointNine) {
|
||||||
|
@ -83,9 +89,9 @@ class Level {
|
||||||
this.songSize = "0MB"
|
this.songSize = "0MB"
|
||||||
this.songID = "Level " + this.officialSong
|
this.songID = "Level " + this.officialSong
|
||||||
}
|
}
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Level;
|
module.exports = Level
|
|
@ -1,4 +1,4 @@
|
||||||
const colors = require('../iconkit/sacredtexts/colors.json');
|
const colors = require('../iconkit/sacredtexts/colors.json')
|
||||||
|
|
||||||
class Player {
|
class Player {
|
||||||
constructor(account) {
|
constructor(account) {
|
||||||
|
|
|
@ -1,5 +1,16 @@
|
||||||
|
//https://nodejs.org/docs/latest/api/buffer.html#buffers-and-character-encodings
|
||||||
|
//both only work on "binary strings" and "URI-safe B64"
|
||||||
|
let toB64 = str => Buffer.from(str).toString('base64url')
|
||||||
|
let fromB64 = str => Buffer.from(str, 'base64').toString()
|
||||||
|
|
||||||
|
const defKey = 37526
|
||||||
|
|
||||||
module.exports = class XOR {
|
module.exports = class XOR {
|
||||||
xor(str, key) { return String.fromCodePoint(...str.split('').map((char, i) => char.charCodeAt(0) ^ key.toString().charCodeAt(i % key.toString().length))) }
|
xor(str, key) {
|
||||||
encrypt(str, key = 37526) { return Buffer.from(this.xor(str, key)).toString('base64').replace(/./gs, c => ({'/': '_', '+': '-'}[c] || c)); }
|
key = key.toString()
|
||||||
decrypt(str, key = 37526) { return this.xor(Buffer.from(str.replace(/./gs, c => ({'/': '_', '+': '-'}[c] || c)), 'base64').toString(), key) }
|
return String.fromCodePoint(...str.split('')
|
||||||
}
|
.map((c, i) => c.charCodeAt(0) ^ key.charCodeAt(i % key.length)))
|
||||||
|
}
|
||||||
|
encrypt(str, key = defKey) { return toB64(this.xor(str, key)) }
|
||||||
|
decrypt(str, key = defKey) { return this.xor(fromB64(str), key) }
|
||||||
|
}
|
|
@ -21,23 +21,23 @@
|
||||||
|
|
||||||
<div id="rewardLabel">
|
<div id="rewardLabel">
|
||||||
<img filter="rewardFilter" class="achSelect selectAll" style="margin: 0% 2% 1.9% 0%" class="gdButton inline" src="../assets/select-all.png" height="5%">
|
<img filter="rewardFilter" class="achSelect selectAll" style="margin: 0% 2% 1.9% 0%" class="gdButton inline" src="../assets/select-all.png" height="5%">
|
||||||
<h1 class="smaller inline" style="margin-bottom: 1.5%">Reward</h1>
|
<h1 class="smaller inline" style="margin-bottom: 1.5%">Reward</h1>
|
||||||
<img filter="rewardFilter" class="achSelect selectNone" style="margin: 0% 0% 1.9% 2%" class="gdButton inline" src="../assets/select-none.png" height="5%">
|
<img filter="rewardFilter" class="achSelect selectNone" style="margin: 0% 0% 1.9% 2%" class="gdButton inline" src="../assets/select-none.png" height="5%">
|
||||||
</div>
|
</div>
|
||||||
<div id="forms"></div>
|
<div id="forms"></div>
|
||||||
|
|
||||||
<div id="typeLabel">
|
<div id="typeLabel">
|
||||||
<img filter="typeFilter" class="achSelect selectAll" style="margin: 0% 2% 1.4% 0%" class="gdButton inline" src="../assets/select-all.png" height="5%">
|
<img filter="typeFilter" class="achSelect selectAll" style="margin: 0% 2% 1.4% 0%" class="gdButton inline" src="../assets/select-all.png" height="5%">
|
||||||
<h1 class="smaller inline" style="margin-top: 3%; margin-bottom: 1%">Requirement</h1>
|
<h1 class="smaller inline" style="margin-top: 3%; margin-bottom: 1%">Requirement</h1>
|
||||||
<img filter="typeFilter" class="achSelect selectNone" style="margin: 0% 0% 1.4% 2%" class="gdButton inline" src="../assets/select-none.png" height="5%">
|
<img filter="typeFilter" class="achSelect selectNone" style="margin: 0% 0% 1.4% 2%" class="gdButton inline" src="../assets/select-none.png" height="5%">
|
||||||
</div>
|
</div>
|
||||||
<div id="types"></div>
|
<div id="types"></div>
|
||||||
|
|
||||||
<div id="gameLabel">
|
<div id="gameLabel">
|
||||||
<img filter="gameFilter" class="achSelect selectAll" style="margin: 0% 2% 1.8% 0%" class="gdButton inline" src="../assets/select-all.png" height="5%">
|
<img filter="gameFilter" class="achSelect selectAll" style="margin: 0% 2% 1.8% 0%" class="gdButton inline" src="../assets/select-all.png" height="5%">
|
||||||
<h1 class="smaller inline" style="margin-top: 1%; margin-bottom: 1.3%">Game</h1>
|
<h1 class="smaller inline" style="margin-top: 1%; margin-bottom: 1.3%">Game</h1>
|
||||||
<img filter="gameFilter" class="achSelect selectNone" style="margin: 0% 0% 1.8% 2%" class="gdButton inline" src="../assets/select-none.png" height="5%">
|
<img filter="gameFilter" class="achSelect selectNone" style="margin: 0% 0% 1.8% 2%" class="gdButton inline" src="../assets/select-none.png" height="5%">
|
||||||
</div>
|
</div>
|
||||||
<div id="games">
|
<div id="games">
|
||||||
<img class="gdButton achFilter gameFilter" src="../assets/achievements/gd.png" height="12%" style="margin: 0% 1%" title="Geometry Dash" filter="gd">
|
<img class="gdButton achFilter gameFilter" src="../assets/achievements/gd.png" height="12%" style="margin: 0% 1%" title="Geometry Dash" filter="gd">
|
||||||
<img class="gdButton achFilter gameFilter" src="../assets/achievements/gdm.png" height="12%" style="margin: 0% 1%" title="Geometry Dash Meltdown" filter="meltdown">
|
<img class="gdButton achFilter gameFilter" src="../assets/achievements/gdm.png" height="12%" style="margin: 0% 1%" title="Geometry Dash Meltdown" filter="meltdown">
|
||||||
|
@ -59,7 +59,7 @@
|
||||||
<div id="searchBox" class="supercenter dragscroll" style="width: 128vh">
|
<div id="searchBox" class="supercenter dragscroll" style="width: 128vh">
|
||||||
<div style="height: 4.5%"></div>
|
<div style="height: 4.5%"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="epicbox supercenter gs" style="width: 126vh; height: 80%; pointer-events: none"></div>
|
<div class="epicbox supercenter gs" style="width: 126vh; height: 80%; pointer-events: none"></div>
|
||||||
|
|
||||||
<div class="center" style="position:absolute; top: 8%; left: 0%; right: 0%">
|
<div class="center" style="position:absolute; top: 8%; left: 0%; right: 0%">
|
||||||
|
@ -79,10 +79,10 @@
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||||
<script type="text/javascript" src="../global.js?v=1"></script>
|
<script type="text/javascript" src="./global.js?v=1"></script>
|
||||||
<script type="text/javascript" src="../dragscroll.js"></script>
|
<script type="text/javascript" src="./dragscroll.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
"use strict";
|
||||||
let disabledFilters = {reward: [], type: [], game: []}
|
let disabledFilters = {reward: [], type: [], game: []}
|
||||||
let forms = ["icon", "ship", "ball", "ufo", "wave", "robot", "spider"]
|
let forms = ["icon", "ship", "ball", "ufo", "wave", "robot", "spider"]
|
||||||
let gameColors = {gd: "255,200,0", meltdown: "255, 100, 0", world: "100,220,0", subzero: "0,255,255"}
|
let gameColors = {gd: "255,200,0", meltdown: "255, 100, 0", world: "100,220,0", subzero: "0,255,255"}
|
||||||
|
@ -99,7 +99,7 @@ function append(reset=true) {
|
||||||
$('#searchBox').html(`<div style="height: 4.5%"></div>`)
|
$('#searchBox').html(`<div style="height: 4.5%"></div>`)
|
||||||
achievements.forEach(x => {
|
achievements.forEach(x => {
|
||||||
|
|
||||||
let iconImg = `"`;
|
let iconImg = `"`
|
||||||
if (forms.includes(x.rewardType)) iconImg = `../iconkit/premade/${x.rewardType}_${x.rewardID}.png" width="90%" title="${x.rewardType}_${x.rewardID < 10 ? "0" : ""}${x.rewardID}"`
|
if (forms.includes(x.rewardType)) iconImg = `../iconkit/premade/${x.rewardType}_${x.rewardID}.png" width="90%" title="${x.rewardType}_${x.rewardID < 10 ? "0" : ""}${x.rewardID}"`
|
||||||
else if (x.rewardType.startsWith("color")) {
|
else if (x.rewardType.startsWith("color")) {
|
||||||
let col = colors[x.rewardID]
|
let col = colors[x.rewardID]
|
||||||
|
@ -129,8 +129,7 @@ Object.keys(ach.types).forEach(x => {
|
||||||
$('#types').append(`<img class="gdButton achFilter typeFilter" filter="${ach.types[x][1].join(" ")}" src="../assets/achievements/${x}.png" title="${ach.types[x][0]}" height="8.5%" style="margin: 0.6% 0.4%">`)
|
$('#types').append(`<img class="gdButton achFilter typeFilter" filter="${ach.types[x][1].join(" ")}" src="../assets/achievements/${x}.png" title="${ach.types[x][0]}" height="8.5%" style="margin: 0.6% 0.4%">`)
|
||||||
})
|
})
|
||||||
|
|
||||||
achievements = ach.achievements
|
{achievements, colors} = ach
|
||||||
colors = ach.colors
|
|
||||||
append()
|
append()
|
||||||
|
|
||||||
function label(labelName) {
|
function label(labelName) {
|
||||||
|
@ -148,23 +147,23 @@ function label(labelName) {
|
||||||
|
|
||||||
$(labelFilter).click(function() {
|
$(labelFilter).click(function() {
|
||||||
let filters = $(this).attr('filter').split(" ")
|
let filters = $(this).attr('filter').split(" ")
|
||||||
|
let args
|
||||||
if (!$(this).hasClass('achDeselected')) {
|
if (!$(this).hasClass('achDeselected')) {
|
||||||
$(this).addClass('achDeselected')
|
$(this).addClass('achDeselected')
|
||||||
filters.forEach(x => disabledFilters[labelName].push(x))
|
filters.forEach(x => disabledFilters[labelName].push(x))
|
||||||
if (labelName == "reward") $(this).attr('src', $(this).attr('src').replace("_on", "_off"))
|
args = ['_on', '_off']
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$(this).removeClass('achDeselected')
|
$(this).removeClass('achDeselected')
|
||||||
filters.forEach(x => disabledFilters[labelName] = disabledFilters[labelName].filter(y => y != x))
|
filters.forEach(x => disabledFilters[labelName] = disabledFilters[labelName].filter(y => y != x))
|
||||||
if (labelName == "reward") $(this).attr('src', $(this).attr('src').replace("_off", "_on"))
|
args = ['_off', '_on']
|
||||||
}
|
}
|
||||||
|
if (labelName == "reward") $(this).attr('src', $(this).attr('src').replace(...args))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
label("reward")
|
const labels = ['reward', 'type', 'game']
|
||||||
label("type")
|
labels.forEach(label)
|
||||||
label("game")
|
|
||||||
|
|
||||||
$(document).on('click', '.selectNone', function() { $(`.${$(this).attr('filter')}:not(.achDeselected)`).trigger('click'); $('#selectNone').hide(); $('#selectAll').show() })
|
$(document).on('click', '.selectNone', function() { $(`.${$(this).attr('filter')}:not(.achDeselected)`).trigger('click'); $('#selectNone').hide(); $('#selectAll').show() })
|
||||||
$(document).on('click', '.selectAll', function() { $(`.${$(this).attr('filter')}.achDeselected`).trigger('click'); $('#selectNone').show(); $('#selectAll').hide() })
|
$(document).on('click', '.selectAll', function() { $(`.${$(this).attr('filter')}.achDeselected`).trigger('click'); $('#selectNone').show(); $('#selectAll').hide() })
|
||||||
|
@ -173,23 +172,20 @@ $('#submitFilters').click(function() {
|
||||||
|
|
||||||
$('.popup').hide()
|
$('.popup').hide()
|
||||||
|
|
||||||
if (!$('.rewardFilter:not(.achDeselected)').length) $('#rewardLabel .selectAll').trigger('click')
|
labels.forEach(x => {
|
||||||
if (!$('.typeFilter:not(.achDeselected)').length) $('#typeLabel .selectAll').trigger('click')
|
if (!$(`.${x}Filter:not(.achDeselected)`).length) $(`#${x}Label .selectAll`).trigger('click')
|
||||||
if (!$('.gameFilter:not(.achDeselected)').length) $('#gameLabel .selectAll').trigger('click')
|
})
|
||||||
|
|
||||||
achievements = ach.achievements
|
achievements = ach.achievements
|
||||||
.filter(x => !disabledFilters.reward.includes(x.rewardType))
|
.filter(x => !disabledFilters.reward.includes(x.rewardType))
|
||||||
.filter(x => !disabledFilters.type.some(y => x.id.startsWith(y)))
|
.filter(x => !disabledFilters.type.some(y => x.id.startsWith(y)))
|
||||||
.filter(x => !disabledFilters.game.includes(x.game))
|
.filter(x => !disabledFilters.game.includes(x.game))
|
||||||
append()
|
append()
|
||||||
})
|
})
|
||||||
|
|
||||||
$('#check').click(function() {
|
$('#check').click(() => {
|
||||||
completed = !completed
|
$('#check').attr('src', `../assets/check-o${completed = !completed ? 'n' : 'ff'}.png`)
|
||||||
if (completed) $('#check').attr('src', '../assets/check-on.png')
|
|
||||||
else $('#check').attr('src', '../assets/check-off.png')
|
|
||||||
append(false)
|
append(false)
|
||||||
})
|
})
|
||||||
}))
|
}))
|
||||||
|
|
||||||
</script>
|
</script>
|
|
@ -3,11 +3,12 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta property="og:type" content="website">
|
<meta property="og:type" content="website">
|
||||||
<meta id="meta-title" property="og:title" content="Level Analysis">
|
<meta id="meta-title" property="og:title" content="Level Analysis">
|
||||||
<meta id="meta-desc" property="og:description" content="Analyze a Geometry Dash level and view it's objects, portals, color channels, code, and more!">
|
<meta id="meta-desc" property="og:description" content="Analyze a Geometry Dash level and view it's objects, portals, color channels, code, and more!">
|
||||||
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/cp.png">
|
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/cp.png">
|
||||||
<meta name="twitter:card" content="summary">
|
<meta name="twitter:card" content="summary">
|
||||||
<link href="../assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
<link href="../assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script>
|
||||||
|
<script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3')</script>
|
||||||
<link rel="icon" href="../assets/cp.png">
|
<link rel="icon" href="../assets/cp.png">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
@ -100,25 +101,27 @@
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||||
<script type="text/javascript" src="../global.js"></script>
|
<script type="text/javascript" src="/misc/global.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
function clean(text) {return text.toString().replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/=/g, "=").replace(/"/g, """).replace(/'/g, "'")}
|
function clean(text) {return text.toString().replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/=/g, "=").replace(/"/g, """).replace(/'/g, "'")}
|
||||||
|
|
||||||
let disabledPortals = []
|
let disabledPortals = []
|
||||||
let altTriggerSort = false
|
let altTriggerSort = false
|
||||||
let formPortals = ['cube', 'ship', 'ball', 'ufo', 'wave', 'robot', 'spider']
|
const PORTALS = {
|
||||||
let speedPortals = ['-1x', '1x', '2x', '3x', '4x']
|
form: ['cube', 'ship', 'ball', 'ufo', 'wave', 'robot', 'spider'],
|
||||||
let sizePortals = ['mini', 'big']
|
speed: ['-1x', '1x', '2x', '3x', '4x'],
|
||||||
let dualPortals = ['dual', 'single']
|
size: ['mini', 'big'],
|
||||||
let mirrorPortals = ['mirrorOn', 'mirrorOff']
|
dual: ['dual', 'single'],
|
||||||
|
mirror: ['mirrorOn', 'mirrorOff']
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch(`/api${window.location.pathname}`).then(res => res.json()).then(res => {
|
||||||
|
|
||||||
fetch(`../api${window.location.pathname}`).then(res => res.json()).then(res => {
|
|
||||||
|
|
||||||
if (!res.level) {
|
if (!res.level) {
|
||||||
switch(res) {
|
switch(res) {
|
||||||
case -1: $('#errorMessage').html("This level could not be be <cr>downloaded</cr>. Either the servers rejected the request, or the level simply <co>doesn't exist at all</co>."); break;
|
case -1: $('#errorMessage').html("This level could not be be <cr>downloaded</cr>. Either the servers rejected the request, or the level simply <co>doesn't exist at all</co>."); break
|
||||||
case -2: $('#errorMessage').html("This level's data appears to be <cr>corrupt</cr> and cannot be <cy>parsed</cy>. It most likely won't load in GD."); break;
|
case -2: $('#errorMessage').html("This level's data appears to be <cr>corrupt</cr> and cannot be <cy>parsed</cy>. It most likely won't load in GD."); break
|
||||||
case -3: $('#errorMessage').html("This level's data could not be obtained because <ca>RobTop</ca> has disabled <cg>level downloading</cg>."); break;
|
case -3: $('#errorMessage').html("This level's data could not be obtained because <ca>RobTop</ca> has disabled <cg>level downloading</cg>."); break;
|
||||||
}
|
}
|
||||||
popupEsc = false
|
popupEsc = false
|
||||||
|
@ -129,8 +132,8 @@ fetch(`../api${window.location.pathname}`).then(res => res.json()).then(res => {
|
||||||
$('#objectCount').text(commafy(res.objects) + " objects")
|
$('#objectCount').text(commafy(res.objects) + " objects")
|
||||||
document.title = "Analysis of " + res.level.name
|
document.title = "Analysis of " + res.level.name
|
||||||
|
|
||||||
$('#meta-title').attr('content', "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...`)
|
$('#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 hdPercent = (res.highDetail / res.objects) * 100
|
let hdPercent = (res.highDetail / res.objects) * 100
|
||||||
|
@ -216,7 +219,7 @@ function appendTriggerGroups() {
|
||||||
})
|
})
|
||||||
|
|
||||||
miscList.forEach(x => {
|
miscList.forEach(x => {
|
||||||
if (x == "objects") return;
|
if (x == "objects") return
|
||||||
else $('#misc').append(`<div class="inline miscDiv"><img height="40%" src='../assets/objects/${x.slice(0, -1)}.png'><h3 style="padding-top: 15%">x${commafy(res.misc[x][0])}<br>${res.misc[x][1]}</h3></div>`)
|
else $('#misc').append(`<div class="inline miscDiv"><img height="40%" src='../assets/objects/${x.slice(0, -1)}.png'><h3 style="padding-top: 15%">x${commafy(res.misc[x][0])}<br>${res.misc[x][1]}</h3></div>`)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -259,11 +262,8 @@ function appendTriggerGroups() {
|
||||||
else disabledPortals.push($(this).attr('portal'))
|
else disabledPortals.push($(this).attr('portal'))
|
||||||
|
|
||||||
portals = res.portals.split(", ").map(x => x.split(" "))
|
portals = res.portals.split(", ").map(x => x.split(" "))
|
||||||
if (disabledPortals.includes('form')) portals = portals.filter(x => !formPortals.includes(x[0]))
|
for (let P in PORTALS)
|
||||||
if (disabledPortals.includes('speed')) portals = portals.filter(x => !speedPortals.includes(x[0]))
|
if (disabledPortals.includes(P)) portals = portals.filter(x => !PORTALS[P].includes(x[0]))
|
||||||
if (disabledPortals.includes('size')) portals = portals.filter(x => !sizePortals.includes(x[0]))
|
|
||||||
if (disabledPortals.includes('dual')) portals = portals.filter(x => !dualPortals.includes(x[0]))
|
|
||||||
if (disabledPortals.includes('mirror')) portals = portals.filter(x => !mirrorPortals.includes(x[0]))
|
|
||||||
|
|
||||||
if (disabledPortals.includes('dupe')) {
|
if (disabledPortals.includes('dupe')) {
|
||||||
portals.reverse().forEach((x, y) => {if (portals[y+1] && portals[y+1][0] == x[0]) portals[y][0] = null;})
|
portals.reverse().forEach((x, y) => {if (portals[y+1] && portals[y+1][0] == x[0]) portals[y][0] = null;})
|
||||||
|
@ -293,7 +293,8 @@ function appendTriggerGroups() {
|
||||||
hsv.s = Number(hsv.s).toFixed(2)
|
hsv.s = Number(hsv.s).toFixed(2)
|
||||||
hsv.v = Number(hsv.v).toFixed(2)
|
hsv.v = Number(hsv.v).toFixed(2)
|
||||||
}
|
}
|
||||||
let hex = "#" + ((1 << 24) + (+col.r << 16) + (+col.g << 8) + +col.b).toString(16).slice(1)
|
// padded (fixed-size) RGB hex
|
||||||
|
let hex = "#" + ((1 << 24) | (col.r << 16) | (col.g << 8) | col.b).toString(16).slice(1) // remove sentinel nibble
|
||||||
$('#colorStuff').html(`
|
$('#colorStuff').html(`
|
||||||
<h2 class="slightlySmaller">${isNaN(col.channel) ? col.channel : "Color " + col.channel}</h2>
|
<h2 class="slightlySmaller">${isNaN(col.channel) ? col.channel : "Color " + col.channel}</h2>
|
||||||
<div class="colorSection">
|
<div class="colorSection">
|
||||||
|
@ -343,6 +344,5 @@ function appendTriggerGroups() {
|
||||||
$('#loadingDiv').hide()
|
$('#loadingDiv').hide()
|
||||||
$('#analysisDiv').show()
|
$('#analysisDiv').show()
|
||||||
|
|
||||||
});
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
<head>
|
<head>
|
||||||
<title>GD Level Browser API</title>
|
<title>GD Level Browser API</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link rel="icon" href="../assets/difficulties/auto.png">
|
<link rel="icon" href="/assets/difficulties/auto.png">
|
||||||
<link href="../assets/css/api.css" type="text/css" rel="stylesheet">
|
<link href="/assets/css/api.css" type="text/css" rel="stylesheet">
|
||||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.js"></script>
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.js"></script>
|
||||||
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,600,700,800&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,600,700,800&display=swap" rel="stylesheet">
|
||||||
|
|
||||||
<meta id="meta-title" property="og:title" content="GDBrowser API">
|
<meta id="meta-title" property="og:title" content="GDBrowser API">
|
||||||
<meta id="meta-desc" property="og:description" content="It's basically the Geometry Dash API, but not terrible!">
|
<meta id="meta-desc" property="og:description" content="It's basically the Geometry Dash API, but not terrible!">
|
||||||
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/difficulties/auto.png">
|
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/difficulties/auto.png">
|
||||||
|
@ -35,22 +35,22 @@
|
||||||
// smooth scrolling through anchors
|
// smooth scrolling through anchors
|
||||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||||||
anchor.addEventListener('click', function(e) {
|
anchor.addEventListener('click', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault()
|
||||||
document.querySelector(this.getAttribute('href')).scrollIntoView({
|
document.querySelector(this.getAttribute('href')).scrollIntoView({
|
||||||
behavior: 'smooth'
|
behavior: 'smooth'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// menu button
|
// menu button
|
||||||
document.getElementById('menu-btn').onclick = function(){
|
document.getElementById('menu-btn').onclick = function(){
|
||||||
document.getElementsByClassName('header-links')[0].classList.toggle('hid');
|
document.getElementsByClassName('header-links')[0].classList.toggle('hid')
|
||||||
document.getElementById('menu-btn').classList.toggle('active');
|
document.getElementById('menu-btn').classList.toggle('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
for(let i = 0; i < document.getElementsByClassName('header-link').length; i++){
|
for(let i = 0; i < document.getElementsByClassName('header-link').length; i++){
|
||||||
document.getElementsByClassName('header-link')[i].onclick = function(){
|
document.getElementsByClassName('header-link')[i].onclick = function(){
|
||||||
document.getElementsByClassName('header-links')[0].classList.toggle('hid');
|
document.getElementsByClassName('header-links')[0].classList.toggle('hid')
|
||||||
document.getElementById('menu-btn').classList.toggle('active');
|
document.getElementById('menu-btn').classList.toggle('active');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
<head>
|
<head>
|
||||||
<title>GD Level Browser API</title>
|
<title>GD Level Browser API</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link rel="icon" href="../assets/difficulties/auto.png">
|
<link rel="icon" href="/assets/difficulties/auto.png">
|
||||||
<link href="../assets/css/api.css" type="text/css" rel="stylesheet">
|
<link href="/assets/css/api.css" type="text/css" rel="stylesheet">
|
||||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.js"></script>
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.js"></script>
|
||||||
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,600,700,800&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,600,700,800&display=swap" rel="stylesheet">
|
||||||
|
|
||||||
<meta id="meta-title" property="og:title" content="GDBrowser API">
|
<meta id="meta-title" property="og:title" content="GDBrowser API">
|
||||||
<meta id="meta-desc" property="og:description" content="It's basically the Geometry Dash API, but not terrible!">
|
<meta id="meta-desc" property="og:description" content="It's basically the Geometry Dash API, but not terrible!">
|
||||||
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/difficulties/auto.png">
|
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/difficulties/auto.png">
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
<div class="main-header-wrap">
|
<div class="main-header-wrap">
|
||||||
<div class="main-header">
|
<div class="main-header">
|
||||||
<div class="header-drawer" id="menu-btn">
|
<div class="header-drawer" id="menu-btn">
|
||||||
<img src="../assets/menu-ic.svg" alt="Menu" id="menu-btn-img">
|
<img src="/assets/menu-ic.svg" alt="Menu" id="menu-btn-img">
|
||||||
</div>
|
</div>
|
||||||
<div class="header-links hid">
|
<div class="header-links hid">
|
||||||
<a class="header-link" href="#intro">Introduction</a>
|
<a class="header-link" href="#intro">Introduction</a>
|
||||||
|
@ -37,24 +37,24 @@
|
||||||
<div class="category-content">
|
<div class="category-content">
|
||||||
<a class="header-link" href="#profile">Profiles</a>
|
<a class="header-link" href="#profile">Profiles</a>
|
||||||
<a class="header-link" href="#leaderboard">Leaderboards</a>
|
<a class="header-link" href="#leaderboard">Leaderboards</a>
|
||||||
<a class="header-link" href="#comments">Comments & Posts</a>
|
<a class="header-link" href="#comments">Comments & Posts</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="header-category">
|
<div class="header-category">
|
||||||
<div class="category-name">Account</div>
|
<div class="category-name">Account</div>
|
||||||
<div class="category-content">
|
<div class="category-content">
|
||||||
<a class="header-link" href="#commenting">Commenting</a>
|
<a class="header-link" href="#commenting">Commenting</a>
|
||||||
<a class="header-link" href="#profileposting">Profile Posting</a>
|
<a class="header-link" href="#profileposting">Profile Posting</a>
|
||||||
<a class="header-link" href="#liking">Liking</a>
|
<a class="header-link" href="#liking">Liking</a>
|
||||||
<a class="header-link" href="#messages">Messages</a>
|
<a class="header-link" href="#messages">Messages</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="header-category">
|
<div class="header-category">
|
||||||
<div class="category-name">Misc</div>
|
<div class="category-name">Misc</div>
|
||||||
<div class="category-content">
|
<div class="category-content">
|
||||||
<a class="header-link" href="#analyze">Level Analysis</a>
|
<a class="header-link" href="#analyze">Level Analysis</a>
|
||||||
<a class="header-link" href="#artist">Song Verification</a>
|
<a class="header-link" href="#artist">Song Verification</a>
|
||||||
<a class="header-link" href="#icons">Icons</a>
|
<a class="header-link" href="#icons">Icons</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -186,7 +186,7 @@
|
||||||
<main>
|
<main>
|
||||||
|
|
||||||
<div id="profile" class="anchor"></div>
|
<div id="profile" class="anchor"></div>
|
||||||
|
|
||||||
<div class="main-block">
|
<div class="main-block">
|
||||||
<h1>Profiles</h1>
|
<h1>Profiles</h1>
|
||||||
<p>/api/profile/username-or-id</p>
|
<p>/api/profile/username-or-id</p>
|
||||||
|
@ -244,7 +244,7 @@
|
||||||
<main>
|
<main>
|
||||||
|
|
||||||
<div id="search" class="anchor"></div>
|
<div id="search" class="anchor"></div>
|
||||||
|
|
||||||
<div class="main-block">
|
<div class="main-block">
|
||||||
<h1>Searching</h1>
|
<h1>Searching</h1>
|
||||||
<p>/api/search/search-query</p>
|
<p>/api/search/search-query</p>
|
||||||
|
@ -540,10 +540,10 @@
|
||||||
<div class="main-block">
|
<div class="main-block">
|
||||||
<h1>Commenting (usually broken)</h1>
|
<h1>Commenting (usually broken)</h1>
|
||||||
<p>POST: /postComment</p>
|
<p>POST: /postComment</p>
|
||||||
|
|
||||||
<p>Leaves a comment on a level. This one is a POST request!</p>
|
<p>Leaves a comment on a level. This one is a POST request!</p>
|
||||||
<p>*Commenting has a rate limit of 15 seconds</p>
|
<p>*Commenting has a rate limit of 15 seconds</p>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<p class="reveal" onclick="revealSection('#params-commenting')"><b>Parameters (6)</b></p>
|
<p class="reveal" onclick="revealSection('#params-commenting')"><b>Parameters (6)</b></p>
|
||||||
<div class="subdiv" id="params-commenting">
|
<div class="subdiv" id="params-commenting">
|
||||||
|
@ -555,7 +555,7 @@
|
||||||
<p>percent: The percent shown on the comment (optional)</p>
|
<p>percent: The percent shown on the comment (optional)</p>
|
||||||
<p>color: If the comment should have a special pink color on GDBrowser (optional)</p>
|
<p>color: If the comment should have a special pink color on GDBrowser (optional)</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
<p class="reveal" onclick="revealSection('#request-commenting')"><b>Example</b></p>
|
<p class="reveal" onclick="revealSection('#request-commenting')"><b>Example</b></p>
|
||||||
|
@ -571,7 +571,7 @@
|
||||||
<br>
|
<br>
|
||||||
<p>If a status of 200 is returned, then the comment was successfully posted. Otherwise, a 400 will return with an error message.</p>
|
<p>If a status of 200 is returned, then the comment was successfully posted. Otherwise, a 400 will return with an error message.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="seperator"></div>
|
<div class="seperator"></div>
|
||||||
</main>
|
</main>
|
||||||
|
@ -581,9 +581,9 @@
|
||||||
<div class="main-block">
|
<div class="main-block">
|
||||||
<h1>Profile Posting (usually broken)</h1>
|
<h1>Profile Posting (usually broken)</h1>
|
||||||
<p>POST: /postProfileComment</p>
|
<p>POST: /postProfileComment</p>
|
||||||
|
|
||||||
<p>Leaves a profile post. This one is a POST request!</p>
|
<p>Leaves a profile post. This one is a POST request!</p>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<p class="reveal" onclick="revealSection('#params-profileposting')"><b>Parameters (5)</b></p>
|
<p class="reveal" onclick="revealSection('#params-profileposting')"><b>Parameters (5)</b></p>
|
||||||
<div class="subdiv" id="params-profileposting">
|
<div class="subdiv" id="params-profileposting">
|
||||||
|
@ -593,7 +593,7 @@
|
||||||
<p>password: Your password (as plain text)</p>
|
<p>password: Your password (as plain text)</p>
|
||||||
<p>color: If the comment should have a special pink color on GDBrowser (optional)</p>
|
<p>color: If the comment should have a special pink color on GDBrowser (optional)</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
<p class="reveal" onclick="revealSection('#request-profileposting')"><b>Example</b></p>
|
<p class="reveal" onclick="revealSection('#request-profileposting')"><b>Example</b></p>
|
||||||
|
@ -607,7 +607,7 @@
|
||||||
<br>
|
<br>
|
||||||
<p>If a status of 200 is returned, then the profile post was successfully posted. Otherwise, a 400 will return with an error message.</p>
|
<p>If a status of 200 is returned, then the profile post was successfully posted. Otherwise, a 400 will return with an error message.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="seperator"></div>
|
<div class="seperator"></div>
|
||||||
</main>
|
</main>
|
||||||
|
@ -618,9 +618,9 @@
|
||||||
<div class="main-block">
|
<div class="main-block">
|
||||||
<h1>Liking (usually broken)</h1>
|
<h1>Liking (usually broken)</h1>
|
||||||
<p>POST: /like</p>
|
<p>POST: /like</p>
|
||||||
|
|
||||||
<p>Likes/dislikes level, comment, or post. This one is a POST request!</p>
|
<p>Likes/dislikes level, comment, or post. This one is a POST request!</p>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<p class="reveal" onclick="revealSection('#params-liking')"><b>Parameters (6)</b></p>
|
<p class="reveal" onclick="revealSection('#params-liking')"><b>Parameters (6)</b></p>
|
||||||
<div class="subdiv" id="params-liking">
|
<div class="subdiv" id="params-liking">
|
||||||
|
@ -631,7 +631,7 @@
|
||||||
<p>accountID: Your account ID</p>
|
<p>accountID: Your account ID</p>
|
||||||
<p>password: Your password (as plain text)</p>
|
<p>password: Your password (as plain text)</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
<p class="reveal" onclick="revealSection('#request-liking')"><b>Example</b></p>
|
<p class="reveal" onclick="revealSection('#request-liking')"><b>Example</b></p>
|
||||||
|
@ -649,7 +649,7 @@
|
||||||
<p>A status of 200 will return if everything goes well, otherwise a 400 will return with an error message.<br>
|
<p>A status of 200 will return if everything goes well, otherwise a 400 will return with an error message.<br>
|
||||||
Liking a comment multiple times on the same account will return a 200, but not actually increase the in-game like counter.</p>
|
Liking a comment multiple times on the same account will return a 200, but not actually increase the in-game like counter.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="seperator"></div>
|
<div class="seperator"></div>
|
||||||
</main>
|
</main>
|
||||||
|
@ -665,7 +665,7 @@
|
||||||
<b>/sendMessage</b> (sends a message)</p>
|
<b>/sendMessage</b> (sends a message)</p>
|
||||||
|
|
||||||
<p>I decided to put all 4 of these requests in one section because they're fairly similar ¯\_(ツ)_/¯</p>
|
<p>I decided to put all 4 of these requests in one section because they're fairly similar ¯\_(ツ)_/¯</p>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<p class="reveal" onclick="revealSection('#params-msg')"><b>Parameters</b></p>
|
<p class="reveal" onclick="revealSection('#params-msg')"><b>Parameters</b></p>
|
||||||
<div class="subdiv" id="params-msg">
|
<div class="subdiv" id="params-msg">
|
||||||
|
@ -687,7 +687,7 @@
|
||||||
<p>message: The content of the message, max 300 characters</p>
|
<p>message: The content of the message, max 300 characters</p>
|
||||||
<p>color: If the message should have a special pink color on GDBrowser (optional)</p>
|
<p>color: If the message should have a special pink color on GDBrowser (optional)</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
<p class="reveal" onclick="revealSection('#request-msg')"><b>Example</b></p>
|
<p class="reveal" onclick="revealSection('#request-msg')"><b>Example</b></p>
|
||||||
|
@ -699,7 +699,7 @@
|
||||||
&accountID=106255<br>
|
&accountID=106255<br>
|
||||||
&password=KitsuneColon333<br>
|
&password=KitsuneColon333<br>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
<p>Read message with ID of 177013:</p>
|
<p>Read message with ID of 177013:</p>
|
||||||
<p>POST /messages/177013<br>
|
<p>POST /messages/177013<br>
|
||||||
?accountID=106255<br>
|
?accountID=106255<br>
|
||||||
|
@ -712,7 +712,7 @@
|
||||||
&id=177013<br>
|
&id=177013<br>
|
||||||
&password=KitsuneColon333<br>
|
&password=KitsuneColon333<br>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
<p>Send "Hello!" to Tubular9:</p>
|
<p>Send "Hello!" to Tubular9:</p>
|
||||||
<p>POST /sendMessage<br>
|
<p>POST /sendMessage<br>
|
||||||
?accountID=106255<br>
|
?accountID=106255<br>
|
||||||
|
@ -877,22 +877,22 @@
|
||||||
// smooth scrolling through anchors
|
// smooth scrolling through anchors
|
||||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||||||
anchor.addEventListener('click', function(e) {
|
anchor.addEventListener('click', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault()
|
||||||
document.querySelector(this.getAttribute('href')).scrollIntoView({
|
document.querySelector(this.getAttribute('href')).scrollIntoView({
|
||||||
behavior: 'smooth'
|
behavior: 'smooth'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// menu button
|
// menu button
|
||||||
document.getElementById('menu-btn').onclick = function(){
|
document.getElementById('menu-btn').onclick = function(){
|
||||||
document.getElementsByClassName('header-links')[0].classList.toggle('hid');
|
document.getElementsByClassName('header-links')[0].classList.toggle('hid')
|
||||||
document.getElementById('menu-btn').classList.toggle('active');
|
document.getElementById('menu-btn').classList.toggle('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
for(let i = 0; i < document.getElementsByClassName('header-link').length; i++){
|
for(let i = 0; i < document.getElementsByClassName('header-link').length; i++){
|
||||||
document.getElementsByClassName('header-link')[i].onclick = function(){
|
document.getElementsByClassName('header-link')[i].onclick = function(){
|
||||||
document.getElementsByClassName('header-links')[0].classList.toggle('hid');
|
document.getElementsByClassName('header-links')[0].classList.toggle('hid')
|
||||||
document.getElementById('menu-btn').classList.toggle('active');
|
document.getElementById('menu-btn').classList.toggle('active');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script>
|
||||||
<script>window.dataLayer = window.dataLayer || []; function gtag() { dataLayer.push(arguments); } gtag('js', new Date()); gtag('config', 'UA-135255146-3');</script>
|
<script>window.dataLayer = window.dataLayer || []; function gtag() { dataLayer.push(arguments); } gtag('js', new Date()); gtag('config', 'UA-135255146-3');</script>
|
||||||
<link rel="icon" href="../assets/folder.png">
|
<link rel="icon" href="/assets/folder.png">
|
||||||
<meta name="robots" content="noindex">
|
<meta name="robots" content="noindex">
|
||||||
<meta id="meta-desc" property="og:description" content='i only upload high quality geometry dash asset rips'>
|
<meta id="meta-desc" property="og:description" content='i only upload high quality geometry dash asset rips'>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
background-image: linear-gradient(#2b2b2b, #171717) !important;
|
background-image: linear-gradient(#2b2b2b, #171717) !important
|
||||||
margin-left: 12px;
|
margin-left: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,16 +21,16 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
h1, p {
|
h1, p {
|
||||||
color: white;
|
color: white
|
||||||
font-family: aller, helvetica, arial;
|
font-family: aller, helvetica, arial
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
width: 300px;
|
width: 300px
|
||||||
display: inline-block;
|
display: inline-block
|
||||||
margin: 0 5 4 5;
|
margin: 0 5 4 5
|
||||||
font-family: aller, helvetica, arial;
|
font-family: aller, helvetica, arial
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<head>
|
<head>
|
||||||
<title>Boomlings Leaderboard</title>
|
<title>Boomlings Leaderboard</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link href="../assets/css/boomlings.css?v=1" type="text/css" rel="stylesheet">
|
<link href="/assets/css/boomlings.css?v=1" type="text/css" rel="stylesheet">
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script>
|
||||||
<script>window.dataLayer = window.dataLayer || []; function gtag() { dataLayer.push(arguments); } gtag('js', new Date()); gtag('config', 'UA-135255146-3');</script>
|
<script>window.dataLayer = window.dataLayer || []; function gtag() { dataLayer.push(arguments); } gtag('js', new Date()); gtag('config', 'UA-135255146-3');</script>
|
||||||
<link rel="icon" href="../assets/boomlings/red.png">
|
<link rel="icon" href="/assets/boomlings/red.png">
|
||||||
<meta id="meta-title" property="og:title" content="Boomlings Leaderboard">
|
<meta id="meta-title" property="og:title" content="Boomlings Leaderboard">
|
||||||
<meta id="meta-desc" property="og:description" content='"Never ask me for anything ever again." - Masahiro Sakurai (probably)'>
|
<meta id="meta-desc" property="og:description" content='"Never ask me for anything ever again." - Masahiro Sakurai (probably)'>
|
||||||
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/boomlings/red.png">
|
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/boomlings/red.png">
|
||||||
|
@ -22,19 +22,19 @@
|
||||||
<div id="borderbox" class="supercenter dragscroll"></div>
|
<div id="borderbox" class="supercenter dragscroll"></div>
|
||||||
|
|
||||||
<div class="supercenter" id="loading" style="height: 10%; top: 47%; display: none;">
|
<div class="supercenter" id="loading" style="height: 10%; top: 47%; display: none;">
|
||||||
<img class="spin noSelect" src="../assets/loading.png" height="105%">
|
<img class="spin noSelect" src="/assets/loading.png" height="105%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; top: 2%; left: 1.5%; width: 10%; height: 25%; pointer-events: none">
|
<div style="position:absolute; top: 2%; left: 1.5%; width: 10%; height: 25%; pointer-events: none">
|
||||||
<img class="gdButton yesClick" id="backButton" src="../assets/back.png" height="30%" onclick="backButton()">
|
<img class="gdButton yesClick" id="backButton" src="/assets/back.png" height="30%" onclick="backButton()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 0%; left: 0%; width: 100%">
|
<div style="position:absolute; bottom: 0%; left: 0%; width: 100%">
|
||||||
<img class="cornerPiece" src="../assets/corner.png" width=7%;>
|
<img class="cornerPiece" src="/assets/corner.png" width=7%;>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 0%; right: 0%; width: 100%; text-align: right;">
|
<div style="position:absolute; bottom: 0%; right: 0%; width: 100%; text-align: right;">
|
||||||
<img class="cornerPiece" src="../assets/corner.png" width=7%; style="transform: scaleX(-1)">
|
<img class="cornerPiece" src="/assets/corner.png" width=7%; style="transform: scaleX(-1)">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -42,14 +42,14 @@
|
||||||
</body>
|
</body>
|
||||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||||
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery.lazy/1.7.9/jquery.lazy.min.js"></script>
|
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery.lazy/1.7.9/jquery.lazy.min.js"></script>
|
||||||
<script type="text/javascript" src="../global.js?v=1"></script>
|
<script type="text/javascript" src="/misc/global.js?v=1"></script>
|
||||||
<script type="text/javascript" src="../dragscroll.js"></script>
|
<script type="text/javascript" src="/misc/dragscroll.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
$('#boomerbox').html('')
|
$('#boomerbox').html('')
|
||||||
$('#loading').show()
|
$('#loading').show()
|
||||||
|
|
||||||
fetch(`../api/boomlings`).then(res => res.json()).then(res => {
|
fetch(`/api/boomlings`).then(res => res.json()).then(res => {
|
||||||
|
|
||||||
if (res == "0") res = []
|
if (res == "0") res = []
|
||||||
$('#boomerbox').html('')
|
$('#boomerbox').html('')
|
||||||
|
@ -59,19 +59,19 @@
|
||||||
|
|
||||||
$('#boomerbox').append(`<div class="inline leaderboardSlot">
|
$('#boomerbox').append(`<div class="inline leaderboardSlot">
|
||||||
<div class="flex" style="width: 7vh; height: 100%"><h1 class="rankNumber" style="width: inherit">${x.rank}</h1></div>
|
<div class="flex" style="width: 7vh; height: 100%"><h1 class="rankNumber" style="width: inherit">${x.rank}</h1></div>
|
||||||
<img src="../assets/boomlings/icons/${x.boomling}.png" style="width: 12vh; align-self: center">
|
<img src="/assets/boomlings/icons/${x.boomling}.png" style="width: 12vh; align-self: center">
|
||||||
|
|
||||||
<p class="flex username" style="width: 48%">${x.name}</p>
|
<p class="flex username" style="width: 48%">${x.name}</p>
|
||||||
|
|
||||||
<div class="flex" style="width: 22%">
|
<div class="flex" style="width: 22%">
|
||||||
<h1 class="level">Level ${x.level}<br><span class="score">${x.score}</span>
|
<h1 class="level">Level ${x.level}<br><span class="score">${x.score}</span>
|
||||||
<img class="powerup inline" height="20%" src="../assets/boomlings/powerups/${x.powerups[0]}.png">` +
|
<img class="powerup inline" height="20%" src="/assets/boomlings/powerups/${x.powerups[0]}.png">` +
|
||||||
`<img class="powerup inline" height="20%" src="../assets/boomlings/powerups/${x.powerups[1]}.png">` +
|
`<img class="powerup inline" height="20%" src="/assets/boomlings/powerups/${x.powerups[1]}.png">` +
|
||||||
`<img class="powerup inline" height="20%" src="../assets/boomlings/powerups/${x.powerups[2]}.png">
|
`<img class="powerup inline" height="20%" src="/assets/boomlings/powerups/${x.powerups[2]}.png">
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<img src="../assets/boomlings/levels/${x.boomlingLevel}.png" style="width: 6.5%; align-self: center">
|
<img src="/assets/boomlings/levels/${x.boomlingLevel}.png" style="width: 6.5%; align-self: center">
|
||||||
</div>`)
|
</div>`)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
<head>
|
<head>
|
||||||
<title>Coming Soon...</title>
|
<title>Coming Soon...</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link href="../assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
<link href="/assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
||||||
<link rel="icon" href="../assets/coin.png">
|
<link rel="icon" href="/assets/coin.png">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="levelBG">
|
<body class="levelBG">
|
||||||
<div class="supercenter" style="height: 70%;">
|
<div class="supercenter" style="height: 70%;">
|
||||||
<h1>Coming soon!</h1>
|
<h1>Coming soon!</h1>
|
||||||
<br>
|
<br>
|
||||||
<img src="../assets/javi.png" style="width: 400px; border-radius: 20px; border: 2px solid black;">
|
<img src="/assets/javi.png" style="width: 400px; border-radius: 20px; border: 2px solid black;">
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
<div class="gdbutton">
|
<div class="gdbutton">
|
||||||
<a href="https://twitter.com/TheRealGDColon"><img class="inline"src="../assets/twitter.png" width=6%> <h2 class="inline" style="margin-left: 2%;">stay updated</h2></a>
|
<a href="https://twitter.com/TheRealGDColon"><img class="inline"src="/assets/twitter.png" width=6%> <h2 class="inline" style="margin-left: 2%;">stay updated</h2></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
|
@ -1,9 +1,9 @@
|
||||||
<head>
|
<head>
|
||||||
<title>Comments</title>
|
<title>Comments</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link href="../assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
<link href="/assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
||||||
<link rel="icon" href="../assets/like.png">
|
<link rel="icon" href="/assets/like.png">
|
||||||
<meta id="meta-title" property="og:title" content="Level Comments">
|
<meta id="meta-title" property="og:title" content="Level Comments">
|
||||||
<meta id="meta-desc" property="og:description" content="View the comments of a Geometry Dash level!">
|
<meta id="meta-desc" property="og:description" content="View the comments of a Geometry Dash level!">
|
||||||
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/like.png">
|
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/like.png">
|
||||||
|
@ -28,16 +28,16 @@
|
||||||
<div style="min-height: 16%; max-height: 16%">
|
<div style="min-height: 16%; max-height: 16%">
|
||||||
<p id="message" style="padding: 0% 10%; margin-top: 1.5%"></p>
|
<p id="message" style="padding: 0% 10%; margin-top: 1.5%"></p>
|
||||||
</div>
|
</div>
|
||||||
<img src="../assets/btn-cancel.png" height=10%; class="postButton gdButton center" style="margin-right: 1%" onclick="$('#postComment').hide(); $('textarea').val('')">
|
<img src="/assets/btn-cancel.png" height=10%; class="postButton gdButton center" style="margin-right: 1%" onclick="$('#postComment').hide(); $('textarea').val('')">
|
||||||
<img src="../assets/btn-submit.png" type="submit" height=10%; class="postButton gdButton center" style="margin-left: 1%" id="submitComment">
|
<img src="/assets/btn-submit.png" type="submit" height=10%; class="postButton gdButton center" style="margin-left: 1%" id="submitComment">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="popup" id="likeComment">
|
<div class="popup" id="likeComment">
|
||||||
<div class="brownbox bounce center supercenter" style="height: 75%; width: 100vh">
|
<div class="brownbox bounce center supercenter" style="height: 75%; width: 100vh">
|
||||||
<h1 class="smaller center" style="font-size: 5.5vh">Vote</h1>
|
<h1 class="smaller center" style="font-size: 5.5vh">Vote</h1>
|
||||||
<img src="../assets/smashLike.png" id="likebtn" class="inline gdButton likeButton"><!--
|
<img src="/assets/smashLike.png" id="likebtn" class="inline gdButton likeButton"><!--
|
||||||
--><img src="../assets/smashDislike.png" id="dislikebtn" class="inline gdButton likeButton youAreNotTheOne">
|
--><img src="/assets/smashDislike.png" id="dislikebtn" class="inline gdButton likeButton youAreNotTheOne">
|
||||||
<form action="nothing lol">
|
<form action="nothing lol">
|
||||||
<h3 class="center">GD Username</h3>
|
<h3 class="center">GD Username</h3>
|
||||||
<input type="text" name="gdbrowser" id="like-username" maxlength="50" style="height: 8vh; width: 90%; text-align: center; margin-top: 0.5%">
|
<input type="text" name="gdbrowser" id="like-username" maxlength="50" style="height: 8vh; width: 90%; text-align: center; margin-top: 0.5%">
|
||||||
|
@ -47,17 +47,17 @@
|
||||||
<div style="min-height: 18%; max-height: 18%">
|
<div style="min-height: 18%; max-height: 18%">
|
||||||
<p id="likeMessage" style="padding: 0% 10%; margin-top: 2.5%"></p>
|
<p id="likeMessage" style="padding: 0% 10%; margin-top: 2.5%"></p>
|
||||||
</div>
|
</div>
|
||||||
<img src="../assets/btn-cancel.png" height=10%; class="postButton gdButton center" style="margin-right: 1%" onclick="$('#likeComment').hide(); $('#likebtn').trigger('click');">
|
<img src="/assets/btn-cancel.png" height=10%; class="postButton gdButton center" style="margin-right: 1%" onclick="$('#likeComment').hide(); $('#likebtn').trigger('click');">
|
||||||
<img src="../assets/btn-submit.png" type="submit" height=10%; class="postButton gdButton center" style="margin-left: 1%" id="submitVote">
|
<img src="/assets/btn-submit.png" type="submit" height=10%; class="postButton gdButton center" style="margin-left: 1%" id="submitVote">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 0%; left: 0%; width: 100%">
|
<div style="position:absolute; bottom: 0%; left: 0%; width: 100%">
|
||||||
<img class="cornerPiece" src="../assets/corner.png" width=7%;>
|
<img class="cornerPiece" src="/assets/corner.png" width=7%;>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 0%; right: 0%; width: 100%; text-align: right;">
|
<div style="position:absolute; bottom: 0%; right: 0%; width: 100%; text-align: right;">
|
||||||
<img class="cornerPiece" src="../assets/corner.png" width=7%; style="transform: scaleX(-1)">
|
<img class="cornerPiece" src="/assets/corner.png" width=7%; style="transform: scaleX(-1)">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="text-align: right; position:absolute; top: 1%; right: 1.25%">
|
<div style="text-align: right; position:absolute; top: 1%; right: 1.25%">
|
||||||
|
@ -69,39 +69,39 @@
|
||||||
<div class="lightBox center dragscroll" id="commentBox" style="margin: 4.5% auto; width: 115vh; height: 86%; background-color: #934E27"></div>
|
<div class="lightBox center dragscroll" id="commentBox" style="margin: 4.5% auto; width: 115vh; height: 86%; background-color: #934E27"></div>
|
||||||
|
|
||||||
<div class="supercenter" style="left: 97%; top: 15.5%; height: 8.5%">
|
<div class="supercenter" style="left: 97%; top: 15.5%; height: 8.5%">
|
||||||
<img class="gdButton" id="lastPage" src="../assets/double-arrow.png" height="90%">
|
<img class="gdButton" id="lastPage" src="/assets/double-arrow.png" height="90%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="supercenter" id="firstPage" style="left: 97%; top: 27.5%; height: 8.5%; display: none;">
|
<div class="supercenter" id="firstPage" style="left: 97%; top: 27.5%; height: 8.5%; display: none;">
|
||||||
<img class="gdButton refreshBtn" src="../assets/double-arrow.png" style="transform: scaleX(-1);" height="90%">
|
<img class="gdButton refreshBtn" src="/assets/double-arrow.png" style="transform: scaleX(-1);" height="90%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="supercenter" id="refreshButton" style="left: 97%; top: 27.5%; height: 10%">
|
<div class="supercenter" id="refreshButton" style="left: 97%; top: 27.5%; height: 10%">
|
||||||
<img class="gdButton refreshBtn" src="../assets/refresh.png" height="90%">
|
<img class="gdButton refreshBtn" src="/assets/refresh.png" height="90%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="supercenter" style="left: 3%; top: 15%; height: 10%">
|
<div class="supercenter" style="left: 3%; top: 15%; height: 10%">
|
||||||
<img class="gdButton" id="topSort" src="../assets/sort-likes.png" height="90%">
|
<img class="gdButton" id="topSort" src="/assets/sort-likes.png" height="90%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="supercenter" style="left: 3%; top: 25.5%; height: 10%">
|
<div class="supercenter" style="left: 3%; top: 25.5%; height: 10%">
|
||||||
<img class="gdButton" id="timeSort" src="../assets/sort-time.png" height="90%">
|
<img class="gdButton" id="timeSort" src="/assets/sort-time.png" height="90%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="supercenter" style="left: 3%; top: 36%; height: 10%">
|
<div class="supercenter" style="left: 3%; top: 36%; height: 10%">
|
||||||
<img class="gdButton" id="compactMode" src="../assets/compact-off.png" height="90%">
|
<img class="gdButton" id="compactMode" src="/assets/compact-off.png" height="90%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="supercenter" style="left: 3%; top: 63%; height: 11%">
|
<div class="supercenter" style="left: 3%; top: 63%; height: 11%">
|
||||||
<img class="gdButton" id="autoMode" src="../assets/playbutton.png" height="90%">
|
<img class="gdButton" id="autoMode" src="/assets/playbutton.png" height="90%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="supercenter" id="pageDown" style="left: 3%; top: 50%; height: 10%; display: none;">
|
<div class="supercenter" id="pageDown" style="left: 3%; top: 50%; height: 10%; display: none;">
|
||||||
<img class="gdButton" src="../assets/arrow-left.png" height="95%">
|
<img class="gdButton" src="/assets/arrow-left.png" height="95%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="supercenter" id="pageUp" style="left: 97%; top: 50%; height: 10%;">
|
<div class="supercenter" id="pageUp" style="left: 97%; top: 50%; height: 10%;">
|
||||||
<img class="gdButton" src="../assets/arrow-right.png" height="95%">
|
<img class="gdButton" src="/assets/arrow-right.png" height="95%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="supercenter" style="top: 4.8%; height: 10%; width: 100%;">
|
<div class="supercenter" style="top: 4.8%; height: 10%; width: 100%;">
|
||||||
|
@ -114,15 +114,15 @@
|
||||||
<h2 class="smallGold inline" id="levelVersion"></h2>
|
<h2 class="smallGold inline" id="levelVersion"></h2>
|
||||||
<a id="levelLink"><h2 class="smallGold inline gdButton" id="levelID" style="margin-left: 6vh"></h2></a>
|
<a id="levelLink"><h2 class="smallGold inline gdButton" id="levelID" style="margin-left: 6vh"></h2></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="leaveComment" style="display: none; position:absolute;bottom: 0%;right: 0%;width: 14%;text-align: right;transform: translate(30%, 40%);">
|
<div id="leaveComment" style="display: none; position:absolute;bottom: 0%;right: 0%;width: 14%;text-align: right;transform: translate(30%, 40%);">
|
||||||
<img class="gdButton" src="../assets/comment.png" width="60%" onclick="$('#content').trigger('input'); $('#postComment').show();">
|
<img class="gdButton" src="/assets/comment.png" width="60%" onclick="$('#content').trigger('input'); $('#postComment').show();">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; top: 2%; left: 1.5%; width: 10%; height: 25%; pointer-events: none">
|
<div style="position:absolute; top: 2%; left: 1.5%; width: 10%; height: 25%; pointer-events: none">
|
||||||
<img class="gdButton yesClick" id="backButton" src="../assets/back.png" height="30%" onclick="backButton()">
|
<img class="gdButton yesClick" id="backButton" src="/assets/back.png" height="30%" onclick="backButton()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -130,9 +130,9 @@
|
||||||
</body>
|
</body>
|
||||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/6.2.2/browser/pixi.js"></script>
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/6.2.2/browser/pixi.js"></script>
|
||||||
<script type="text/javascript" src="../iconkit/icon.js"></script>
|
<script type="text/javascript" src="/iconkit/icon.js"></script>
|
||||||
<script type="text/javascript" src="../global.js?v=1"></script>
|
<script type="text/javascript" src="/misc/global.js?v=1"></script>
|
||||||
<script type="text/javascript" src="../dragscroll.js"></script>
|
<script type="text/javascript" src="/misc/dragscroll.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
let {mode, compact} = JSON.parse(localStorage.getItem('commentPreset') || '{"mode": "top", "compact": true}')
|
let {mode, compact} = JSON.parse(localStorage.getItem('commentPreset') || '{"mode": "top", "compact": true}')
|
||||||
|
@ -150,13 +150,13 @@ let auto = false
|
||||||
let interval = null
|
let interval = null
|
||||||
let commentCache = {}
|
let commentCache = {}
|
||||||
|
|
||||||
let target = `../api/level/${lvlID}`
|
let target = `/api/level/${lvlID}`
|
||||||
if (lvlID > 999999999 || lvlID < -999999999) window.location.href = window.location.href.replace("comments", "search")
|
if (lvlID > 999999999 || lvlID < -999999999) window.location.href = window.location.href.replace("comments", "search")
|
||||||
if (!Number.isInteger(+lvlID)) {history = true; target = `../api/profile/${lvlID}`}
|
if (!Number.isInteger(+lvlID)) {history = true; target = `/api/profile/${lvlID}`}
|
||||||
else lvlID = Math.round(+lvlID)
|
else lvlID = Math.round(+lvlID)
|
||||||
|
|
||||||
if (mode == "top") { mode = "top"; $('#topSort').attr('src', "../assets/sort-likes-on.png") }
|
if (mode == "top") { mode = "top"; $('#topSort').attr('src', "/assets/sort-likes-on.png") }
|
||||||
else $('#timeSort').attr('src', "../assets/sort-time-on.png")
|
else $('#timeSort').attr('src', "/assets/sort-time-on.png")
|
||||||
|
|
||||||
function clean(text) {return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/=/g, "=").replace(/"/g, """).replace(/'/g, "'")}
|
function clean(text) {return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/=/g, "=").replace(/"/g, """).replace(/'/g, "'")}
|
||||||
|
|
||||||
|
@ -197,7 +197,7 @@ function buildComments(lvl) {
|
||||||
if (!lvl.name) $('#leaveComment').hide()
|
if (!lvl.name) $('#leaveComment').hide()
|
||||||
$('#levelAuthor').text("By " + (lvl.author || "-"))
|
$('#levelAuthor').text("By " + (lvl.author || "-"))
|
||||||
$('#levelID').text("ID: " + lvlID)
|
$('#levelID').text("ID: " + lvlID)
|
||||||
if (lvl.accountID && lvl.author != "-")
|
if (lvl.accountID && lvl.author != "-")
|
||||||
if (lvl.id) $('#levelLink').attr('href', '../' + lvl.id)
|
if (lvl.id) $('#levelLink').attr('href', '../' + lvl.id)
|
||||||
else $('#levelID').removeClass("gdButton")
|
else $('#levelID').removeClass("gdButton")
|
||||||
$('#levelVersion').text("Version: " + (lvl.version || 0))
|
$('#levelVersion').text("Version: " + (lvl.version || 0))
|
||||||
|
@ -211,10 +211,10 @@ function buildComments(lvl) {
|
||||||
|
|
||||||
function appendComments(auto, noCache) {
|
function appendComments(auto, noCache) {
|
||||||
|
|
||||||
if (loadingComments) return;
|
if (loadingComments) return
|
||||||
else loadingComments = true;
|
else loadingComments = true
|
||||||
|
|
||||||
if (!auto) $('#commentBox').html(`<div class="supercenter" id="loading" style="height: 12%;"><img class="spin noSelect" src="../assets/loading.png" height="105%"></div>`)
|
if (!auto) $('#commentBox').html(`<div class="supercenter" id="loading" style="height: 12%;"><img class="spin noSelect" src="/assets/loading.png" height="105%"></div>`)
|
||||||
|
|
||||||
if (page == 0) {
|
if (page == 0) {
|
||||||
$('#pageDown').hide()
|
$('#pageDown').hide()
|
||||||
|
@ -230,13 +230,12 @@ else {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!noCache && commentCache[page]) addComments(commentCache[page])
|
if (!noCache && commentCache[page]) addComments(commentCache[page])
|
||||||
fetch(`../api${!history ? window.location.pathname : "/comments/" + lvl.playerID}?count=${compact && !auto ? 20 : 10}&page=${page}${history ? "&type=commentHistory" : ""}&${mode}`).then((res) => {
|
fetch(
|
||||||
if (res.status === 204) return [];
|
`/api${!history ? window.location.pathname : "/comments/" + lvl.playerID}?count=${compact && !auto ? 20 : 10}&page=${page}${history ? "&type=commentHistory" : ""}&${mode}`
|
||||||
return res.json();
|
).then(res => res.status === 204 ? [] : res.json()).then(addComments)
|
||||||
}).then(addComments)
|
|
||||||
|
|
||||||
function addComments(res) {
|
function addComments(res) {
|
||||||
|
|
||||||
if (history && lvl.commentHistory != "all") $('#pageUp').hide()
|
if (history && lvl.commentHistory != "all") $('#pageUp').hide()
|
||||||
|
|
||||||
if (res == -1 || (history && lvl.commentHistory != "all")) {
|
if (res == -1 || (history && lvl.commentHistory != "all")) {
|
||||||
|
@ -275,7 +274,7 @@ function addComments(res) {
|
||||||
<gdicon class="commentIcon inline" cacheID=${x.playerID} iconID=${x.icon.icon} iconForm="${x.icon.form}" col1="${x.icon.col1}" col2="${x.icon.col2}" glow="${x.icon.glow}"></gdicon>
|
<gdicon class="commentIcon inline" cacheID=${x.playerID} iconID=${x.icon.icon} iconForm="${x.icon.form}" col1="${x.icon.col1}" col2="${x.icon.col2}" glow="${x.icon.glow}"></gdicon>
|
||||||
<a href=../${x.accountID == "0" ? `search/${x.playerID}?user` : `../u/${x.accountID}.`}>
|
<a href=../${x.accountID == "0" ? `search/${x.playerID}?user` : `../u/${x.accountID}.`}>
|
||||||
<h2 class="inline gdButton ${x.accountID == "0" ? "green unregistered" : ""}">${userName}</h2></a>
|
<h2 class="inline gdButton ${x.accountID == "0" ? "green unregistered" : ""}">${userName}</h2></a>
|
||||||
${modNumber > 0 ? `<img class="inline" src="../assets/mod${modNumber > 2 ? "-extra" : modNumber == 2 ? "-elder" : ""}.png" style="margin-left: 1%; width: 3.5%">` : ""}
|
${modNumber > 0 ? `<img class="inline" src="/assets/mod${modNumber > 2 ? "-extra" : modNumber == 2 ? "-elder" : ""}.png" style="margin-left: 1%; width: 3.5%">` : ""}
|
||||||
<p class="commentPercent inline">${x.percent ? x.percent + "%" : ""}</p>
|
<p class="commentPercent inline">${x.percent ? x.percent + "%" : ""}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -287,14 +286,14 @@ function addComments(res) {
|
||||||
<div class="commentLikes">
|
<div class="commentLikes">
|
||||||
${history ? `<h3 style="margin-right: 1.5vh; pointer-events: all;" class="gold inline"><a href="../${x.levelID}">(${x.levelID})</a></h3>` : ""}
|
${history ? `<h3 style="margin-right: 1.5vh; pointer-events: all;" class="gold inline"><a href="../${x.levelID}">(${x.levelID})</a></h3>` : ""}
|
||||||
<div class="inline gdButton likeComment" commentID="${x.ID}" ${x.levelID ? `levelID="${x.levelID}"` : ""}">
|
<div class="inline gdButton likeComment" commentID="${x.ID}" ${x.levelID ? `levelID="${x.levelID}"` : ""}">
|
||||||
<img id="thumb-${x.ID}" class="inline gdButton" ${x.likes < 0 ? "style='transform: translateY(25%); margin-right: 0.4%'" : ""} src="../assets/${x.likes < 0 ? "dis" : ""}like.png" height=20%>
|
<img id="thumb-${x.ID}" class="inline gdButton" ${x.likes < 0 ? "style='transform: translateY(25%); margin-right: 0.4%'" : ""} src="/assets/${x.likes < 0 ? "dis" : ""}like.png" height=20%>
|
||||||
</div>
|
</div>
|
||||||
<h3 id="likes-${x.ID}" class="inline">${x.likes}</h3>
|
<h3 id="likes-${x.ID}" class="inline">${x.likes}</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>`
|
</div>`
|
||||||
|
|
||||||
////// COMPACT MODE //////
|
////// COMPACT MODE //////
|
||||||
|
|
||||||
: `
|
: `
|
||||||
<div class="commentBG compactBG ${bgCol}">
|
<div class="commentBG compactBG ${bgCol}">
|
||||||
<div class="comment compact" commentID="${x.ID}">
|
<div class="comment compact" commentID="${x.ID}">
|
||||||
|
@ -302,7 +301,7 @@ function addComments(res) {
|
||||||
<gdicon class="commentIcon inline" cacheID=${x.playerID} iconID=${x.icon.icon} iconForm="${x.icon.form}" col1="${x.icon.col1}" col2="${x.icon.col2}" glow="${x.icon.glow}"></gdicon>
|
<gdicon class="commentIcon inline" cacheID=${x.playerID} iconID=${x.icon.icon} iconForm="${x.icon.form}" col1="${x.icon.col1}" col2="${x.icon.col2}" glow="${x.icon.glow}"></gdicon>
|
||||||
<a href=../${x.accountID == "0" ? `search/${x.playerID}?user` : `../u/${x.accountID}.`}>
|
<a href=../${x.accountID == "0" ? `search/${x.playerID}?user` : `../u/${x.accountID}.`}>
|
||||||
<h2 class="inline gdButton ${x.accountID == "0" ? "green unregistered" : ""}">${userName}</h2></a>
|
<h2 class="inline gdButton ${x.accountID == "0" ? "green unregistered" : ""}">${userName}</h2></a>
|
||||||
${modNumber > 0 ? `<img class="inline" src="../assets/mod${modNumber > 2 ? "-extra" : modNumber == 2 ? "-elder" : ""}.png" style="margin-left: 1.2%; width: 3.2%">` : ""}
|
${modNumber > 0 ? `<img class="inline" src="/assets/mod${modNumber > 2 ? "-extra" : modNumber == 2 ? "-elder" : ""}.png" style="margin-left: 1.2%; width: 3.2%">` : ""}
|
||||||
<p class="commentPercent inline">${x.percent ? x.percent + "%" : ""}</p>
|
<p class="commentPercent inline">${x.percent ? x.percent + "%" : ""}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -314,7 +313,7 @@ function addComments(res) {
|
||||||
<div class="commentLikes">
|
<div class="commentLikes">
|
||||||
${history ? `<h3 style="margin-right: 0.5vh; pointer-events: all;" class="gold inline"><a href="../${x.levelID}">(${x.levelID})</a></h3>` : ""}
|
${history ? `<h3 style="margin-right: 0.5vh; pointer-events: all;" class="gold inline"><a href="../${x.levelID}">(${x.levelID})</a></h3>` : ""}
|
||||||
<div class="inline gdButton likeComment" commentID="${x.ID}"${x.levelID ? `levelID="${x.levelID}"` : ""}>
|
<div class="inline gdButton likeComment" commentID="${x.ID}"${x.levelID ? `levelID="${x.levelID}"` : ""}>
|
||||||
<img id="thumb-${x.ID}" class="inline" ${x.likes < 0 ? "style='transform: translateY(15%); margin-right: 0.4%'" : ""} src="../assets/${x.likes < 0 ? "dis" : ""}like.png" height=27%>
|
<img id="thumb-${x.ID}" class="inline" ${x.likes < 0 ? "style='transform: translateY(15%); margin-right: 0.4%'" : ""} src="/assets/${x.likes < 0 ? "dis" : ""}like.png" height=27%>
|
||||||
</div>
|
</div>
|
||||||
<h3 id="likes-${x.ID}" class="inline">${x.likes}</h3>
|
<h3 id="likes-${x.ID}" class="inline">${x.likes}</h3>
|
||||||
</div>
|
</div>
|
||||||
|
@ -331,7 +330,7 @@ function addComments(res) {
|
||||||
$(this).css('font-size', (3.5 - (overflow)) + 'vh')
|
$(this).css('font-size', (3.5 - (overflow)) + 'vh')
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
})
|
||||||
|
|
||||||
renderIcons()
|
renderIcons()
|
||||||
$('#loading').hide()
|
$('#loading').hide()
|
||||||
|
@ -356,39 +355,39 @@ function resetSort() {
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#topSort').click(function() {
|
$('#topSort').click(function() {
|
||||||
if (mode == "top" || loadingComments) return;
|
if (mode == "top" || loadingComments) return
|
||||||
resetSort()
|
resetSort()
|
||||||
mode = "top";
|
mode = "top";
|
||||||
$('#timeSort').attr('src', "../assets/sort-time.png")
|
$('#timeSort').attr('src', "/assets/sort-time.png")
|
||||||
$('#topSort').attr('src', "../assets/sort-likes-on.png")
|
$('#topSort').attr('src', "/assets/sort-likes-on.png")
|
||||||
appendComments()
|
appendComments()
|
||||||
})
|
})
|
||||||
|
|
||||||
$('#timeSort').click(function() {
|
$('#timeSort').click(function() {
|
||||||
if (mode == "time" || loadingComments) return;
|
if (mode == "time" || loadingComments) return
|
||||||
resetSort()
|
resetSort()
|
||||||
mode = "time";
|
mode = "time";
|
||||||
$('#timeSort').attr('src', "../assets/sort-time-on.png")
|
$('#timeSort').attr('src', "/assets/sort-time-on.png")
|
||||||
$('#topSort').attr('src', "../assets/sort-likes.png")
|
$('#topSort').attr('src', "/assets/sort-likes.png")
|
||||||
appendComments()
|
appendComments()
|
||||||
})
|
})
|
||||||
|
|
||||||
$('#compactMode').click(function() {
|
$('#compactMode').click(function() {
|
||||||
if (loadingComments) return;
|
if (loadingComments) return
|
||||||
compact = !compact
|
compact = !compact
|
||||||
lastPage = 0;
|
castPage = 0;
|
||||||
page = 0;
|
page = 0;
|
||||||
$('#compactMode').attr('src', `../assets/compact-${compact ? "on" : "off"}.png`)
|
$('#compactMode').attr('src', `../assets/compact-${compact ? "on" : "off"}.png`)
|
||||||
appendComments()
|
appendComments()
|
||||||
})
|
})
|
||||||
|
|
||||||
$('#autoMode').click(function() {
|
$('#autoMode').click(function() {
|
||||||
if (loadingComments) return;
|
if (loadingComments) return
|
||||||
auto = !auto
|
auto = !auto
|
||||||
mode = "time"
|
mode = "time"
|
||||||
page = 0;
|
page = 0;
|
||||||
$('#timeSort').attr('src', "../assets/sort-time-on.png")
|
$('#timeSort').attr('src', "/assets/sort-time-on.png")
|
||||||
$('#topSort').attr('src', "../assets/sort-likes.png")
|
$('#topSort').attr('src', "/assets/sort-likes.png")
|
||||||
|
|
||||||
if (auto) {
|
if (auto) {
|
||||||
document.title = "[LIVE] " + document.title
|
document.title = "[LIVE] " + document.title
|
||||||
|
@ -407,8 +406,8 @@ $('#autoMode').click(function() {
|
||||||
|
|
||||||
$(document).on('click', '.refreshBtn', function () {
|
$(document).on('click', '.refreshBtn', function () {
|
||||||
if (loadingComments) return
|
if (loadingComments) return
|
||||||
lastPage = 0;
|
lastPage = 0
|
||||||
page = 0;
|
page = 0
|
||||||
appendComments(false, true)
|
appendComments(false, true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -430,7 +429,7 @@ $('#submitComment').click(function() {
|
||||||
$('.postbutton').hide()
|
$('.postbutton').hide()
|
||||||
allowEsc = false
|
allowEsc = false
|
||||||
|
|
||||||
fetch(`../api/profile/${username}`).then(res => res.json()).then(res => {
|
fetch(`/api/profile/${username}`).then(res => res.json()).then(res => {
|
||||||
if (!res || res == "-1") {allowEsc = true; $('.postbutton').show(); return $('#message').text("The username you provided doesn't exist!")}
|
if (!res || res == "-1") {allowEsc = true; $('.postbutton').show(); return $('#message').text("The username you provided doesn't exist!")}
|
||||||
else accountID = res.accountID
|
else accountID = res.accountID
|
||||||
|
|
||||||
|
@ -440,13 +439,13 @@ $('#submitComment').click(function() {
|
||||||
$('#postComment').hide()
|
$('#postComment').hide()
|
||||||
$('.postbutton').show()
|
$('.postbutton').show()
|
||||||
$('#message').html(messageText)
|
$('#message').html(messageText)
|
||||||
$('#timeSort').attr('src', "../assets/sort-time-on.png")
|
$('#timeSort').attr('src', "/assets/sort-time-on.png")
|
||||||
$('#topSort').attr('src', "../assets/sort-likes.png")
|
$('#topSort').attr('src', "/assets/sort-likes.png")
|
||||||
allowEsc = true
|
allowEsc = true
|
||||||
mode = "time"
|
mode = "time"
|
||||||
page = 0
|
page = 0
|
||||||
appendComments()
|
appendComments()
|
||||||
})
|
})
|
||||||
.fail(e => {allowEsc = true; $('.postbutton').show();$('#message').text(e.responseText.includes("DOCTYPE") ? "Something went wrong..." : e.responseText)})
|
.fail(e => {allowEsc = true; $('.postbutton').show();$('#message').text(e.responseText.includes("DOCTYPE") ? "Something went wrong..." : e.responseText)})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -465,7 +464,7 @@ $('#dislikebtn').click(function() {
|
||||||
|
|
||||||
let commentID = 0
|
let commentID = 0
|
||||||
let lvID = 0
|
let lvID = 0
|
||||||
let likeCount, likeImg;
|
let likeCount, likeImg
|
||||||
let likedComments;
|
let likedComments;
|
||||||
|
|
||||||
$(document).on('click', '.likeComment', function(cmnt) {
|
$(document).on('click', '.likeComment', function(cmnt) {
|
||||||
|
@ -473,7 +472,7 @@ $(document).on('click', '.likeComment', function(cmnt) {
|
||||||
commentID = $(this).attr('commentID')
|
commentID = $(this).attr('commentID')
|
||||||
|
|
||||||
likedComments = localStorage.likedComments ? JSON.parse(localStorage.likedComments) : []
|
likedComments = localStorage.likedComments ? JSON.parse(localStorage.likedComments) : []
|
||||||
if (likedComments.includes(commentID)) return;
|
if (likedComments.includes(commentID)) return
|
||||||
|
|
||||||
lvID = $(this).attr('levelID') || 0
|
lvID = $(this).attr('levelID') || 0
|
||||||
likeImg = $(this).find('img')
|
likeImg = $(this).find('img')
|
||||||
|
@ -483,7 +482,7 @@ $(document).on('click', '.likeComment', function(cmnt) {
|
||||||
|
|
||||||
$('#submitVote').click(function() {
|
$('#submitVote').click(function() {
|
||||||
|
|
||||||
if (likedComments.includes(commentID)) return $('#likeMessage').text("You've already liked/disliked this comment!");
|
if (likedComments.includes(commentID)) return $('#likeMessage').text("You've already liked/disliked this comment!")
|
||||||
|
|
||||||
let ID = commentID
|
let ID = commentID
|
||||||
let username = $('#like-username').val()
|
let username = $('#like-username').val()
|
||||||
|
@ -491,14 +490,14 @@ $('#submitVote').click(function() {
|
||||||
let extraID = lvID || window.location.pathname.split('/')[2]
|
let extraID = lvID || window.location.pathname.split('/')[2]
|
||||||
let accountID = 0
|
let accountID = 0
|
||||||
let likeType = like ? "1" : "0"
|
let likeType = like ? "1" : "0"
|
||||||
|
|
||||||
if (!ID || !username || !password || loadingComments) return $('#postComment').hide()
|
if (!ID || !username || !password || loadingComments) return $('#postComment').hide()
|
||||||
|
|
||||||
$('#likeMessage').text(like ? "Liking..." : "Disliking... :(")
|
$('#likeMessage').text(like ? "Liking..." : "Disliking... :(")
|
||||||
$('.postbutton').hide()
|
$('.postbutton').hide()
|
||||||
allowEsc = false
|
allowEsc = false
|
||||||
|
|
||||||
fetch(`../api/profile/${username}`).then(res => res.json()).then(res => {
|
fetch(`/api/profile/${username}`).then(res => res.json()).then(res => {
|
||||||
if (!res || res == "-1") {allowEsc = true; $('.postbutton').show(); return $('#likeMessage').text("The username you provided doesn't exist!")}
|
if (!res || res == "-1") {allowEsc = true; $('.postbutton').show(); return $('#likeMessage').text("The username you provided doesn't exist!")}
|
||||||
else accountID = res.accountID
|
else accountID = res.accountID
|
||||||
|
|
||||||
|
@ -506,8 +505,8 @@ $('#submitVote').click(function() {
|
||||||
.done(x => {
|
.done(x => {
|
||||||
let newCount = parseInt(likeCount.text()) + (like ? 1 : -1)
|
let newCount = parseInt(likeCount.text()) + (like ? 1 : -1)
|
||||||
likeCount.text(newCount)
|
likeCount.text(newCount)
|
||||||
if (newCount < 0) likeImg.attr('src', '../assets/dislike.png').css('transform', compact ? 'translateY(15%)' : 'translateY(25%)')
|
if (newCount < 0) likeImg.attr('src', '/assets/dislike.png').css('transform', compact ? 'translateY(15%)' : 'translateY(25%)')
|
||||||
else likeImg.attr('src', '../assets/like.png').removeAttr('style')
|
else likeImg.attr('src', '/assets/like.png').removeAttr('style')
|
||||||
$('#likeComment').hide()
|
$('#likeComment').hide()
|
||||||
$('#likebtn').trigger('click')
|
$('#likebtn').trigger('click')
|
||||||
$('.postbutton').show()
|
$('.postbutton').show()
|
||||||
|
@ -515,7 +514,7 @@ $('#submitVote').click(function() {
|
||||||
allowEsc = true
|
allowEsc = true
|
||||||
likedComments.push(commentID)
|
likedComments.push(commentID)
|
||||||
localStorage.setItem('likedComments', JSON.stringify(likedComments))
|
localStorage.setItem('likedComments', JSON.stringify(likedComments))
|
||||||
})
|
})
|
||||||
.fail(e => {allowEsc = true; $('.postbutton').show();$('#likeMessage').text(e.responseText.includes("DOCTYPE") ? "Something went wrong..." : e.responseText)})
|
.fail(e => {allowEsc = true; $('.postbutton').show();$('#likeMessage').text(e.responseText.includes("DOCTYPE") ? "Something went wrong..." : e.responseText)})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -534,12 +533,12 @@ $(document).keydown(function(k) {
|
||||||
if (k.which == 13) k.preventDefault() //enter
|
if (k.which == 13) k.preventDefault() //enter
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loadingComments || $('.popup').is(":visible")) return;
|
if (loadingComments || $('.popup').is(":visible")) return
|
||||||
|
|
||||||
if (k.which == 37 && $('#pageDown').is(":visible")) { //left
|
if (k.which == 37 && $('#pageDown').is(":visible")) { //left
|
||||||
$('#pageDown').trigger('click')
|
$('#pageDown').trigger('click')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (k.which == 39 && $('#pageUp').is(":visible")) { //right
|
if (k.which == 39 && $('#pageUp').is(":visible")) { //right
|
||||||
$('#pageUp').trigger('click')
|
$('#pageUp').trigger('click')
|
||||||
}
|
}
|
||||||
|
@ -548,4 +547,3 @@ $(document).keydown(function(k) {
|
||||||
};
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<head>
|
<head>
|
||||||
<title>Demon Leaderboard</title>
|
<title>Demon Leaderboard</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link href="../assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
<link href="/assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
||||||
<link rel="icon" href="../assets/trophy-demon.png">
|
<link rel="icon" href="/assets/trophy-demon.png">
|
||||||
<meta id="meta-title" property="og:title" content="Demon Leaderboard">
|
<meta id="meta-title" property="og:title" content="Demon Leaderboard">
|
||||||
<meta id="meta-desc" property="og:description" content="View the victors of a very hard Geometry Dash level!">
|
<meta id="meta-desc" property="og:description" content="View the victors of a very hard Geometry Dash level!">
|
||||||
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/trophy-demon.png">
|
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/trophy-demon.png">
|
||||||
|
@ -24,22 +24,22 @@
|
||||||
<p class="bigger center" style="margin-top: 1vh">
|
<p class="bigger center" style="margin-top: 1vh">
|
||||||
Usernames may <cy>differ</cy> from what is used in GD
|
Usernames may <cy>differ</cy> from what is used in GD
|
||||||
</p>
|
</p>
|
||||||
<img src="../assets/ok.png" width=15%; class="gdButton center" onclick="$('.popup').hide()">
|
<img src="/assets/ok.png" width=15%; class="gdButton center" onclick="$('.popup').hide()">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 0%; left: 0%; width: 100%">
|
<div style="position:absolute; bottom: 0%; left: 0%; width: 100%">
|
||||||
<img class="cornerPiece grayscale" src="../assets/corner.png" width=7%;>
|
<img class="cornerPiece grayscale" src="/assets/corner.png" width=7%;>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 0%; right: 0%; width: 100%; text-align: right;">
|
<div style="position:absolute; bottom: 0%; right: 0%; width: 100%; text-align: right;">
|
||||||
<img class="cornerPiece grayscale" src="../assets/corner.png" width=7%; style="transform: scaleX(-1)">
|
<img class="cornerPiece grayscale" src="/assets/corner.png" width=7%; style="transform: scaleX(-1)">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="searchBox" class="supercenter dragscroll"; style="width: 124vh">
|
<div id="searchBox" class="supercenter dragscroll"; style="width: 124vh">
|
||||||
<div style="height: 4.5%"></div>
|
<div style="height: 4.5%"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="epicbox supercenter gs" style="width: 126vh; height: 80%; pointer-events: none"></div>
|
<div class="epicbox supercenter gs" style="width: 126vh; height: 80%; pointer-events: none"></div>
|
||||||
|
|
||||||
<div class="center" style="position:absolute; top: 8%; left: 0%; right: 0%">
|
<div class="center" style="position:absolute; top: 8%; left: 0%; right: 0%">
|
||||||
|
@ -47,35 +47,35 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position: absolute; left: 7%; top: 45%; height: 10%;">
|
<div style="position: absolute; left: 7%; top: 45%; height: 10%;">
|
||||||
<a id="pageDown"><img class="gdButton" src="../assets/arrow-left.png" height="90%"></a>
|
<a id="pageDown"><img class="gdButton" src="/assets/arrow-left.png" height="90%"></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position: absolute; right: 7%; top: 45%; height: 10%;">
|
<div style="position: absolute; right: 7%; top: 45%; height: 10%;">
|
||||||
<a id="pageUp"><img class="gdButton" src="../assets/arrow-right.png" height="90%"></a>
|
<a id="pageUp"><img class="gdButton" src="/assets/arrow-right.png" height="90%"></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; top: 2%; left: 1.5%; width: 10%; height: 25%; pointer-events: none">
|
<div style="position:absolute; top: 2%; left: 1.5%; width: 10%; height: 25%; pointer-events: none">
|
||||||
<img class="gdButton yesClick" id="backButton" src="../assets/back.png" height="30%" onclick="backButton()">
|
<img class="gdButton yesClick" id="backButton" src="/assets/back.png" height="30%" onclick="backButton()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="supercenter" id="loading" style="height: 10%; top: 47%">
|
<div class="supercenter" id="loading" style="height: 10%; top: 47%">
|
||||||
<img class="spin noSelect" src="../assets/loading.png" height="105%">
|
<img class="spin noSelect" src="/assets/loading.png" height="105%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; top: 3%; right: 2%; text-align: right; width: 20%;">
|
<div style="position:absolute; top: 3%; right: 2%; text-align: right; width: 20%;">
|
||||||
<a target="_blank" id="pointercrate"><img class="inline gdButton" src="../assets/demonButton.png" width="23%" style="margin-right: 4%"></a>
|
<a target="_blank" id="pointercrate"><img class="inline gdButton" src="/assets/demonButton.png" width="23%" style="margin-right: 4%"></a>
|
||||||
<img id="creditsButton" class="inline gdButton" src="../assets/credits.png" width="25%" onclick="$('#infoDiv').show()">
|
<img id="creditsButton" class="inline gdButton" src="/assets/credits.png" width="25%" onclick="$('#infoDiv').show()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 5.5%; right: 3.5%; text-align: right; width: 18%;">
|
<div style="position:absolute; bottom: 5.5%; right: 3.5%; text-align: right; width: 18%;">
|
||||||
<a id="realLeaderboardLink"><img class="gdButton" src="../assets/leaderboard.png" width="35%"></a>
|
<a id="realLeaderboardLink"><img class="gdButton" src="/assets/leaderboard.png" width="35%"></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||||
<script type="text/javascript" src="../global.js?v=1"></script>
|
<script type="text/javascript" src="/misc/global.js?v=1"></script>
|
||||||
<script type="text/javascript" src="../dragscroll.js"></script>
|
<script type="text/javascript" src="../dragscroll.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ let max = 250
|
||||||
let trophies = [1, 5, 10, 25, 50, 100, max]
|
let trophies = [1, 5, 10, 25, 50, 100, max]
|
||||||
|
|
||||||
let demonID = Math.round(window.location.pathname.split('/')[2])
|
let demonID = Math.round(window.location.pathname.split('/')[2])
|
||||||
let illegal = (!demonID || demonID > max || demonID < 1)
|
let illegal = (!demonID || demonID > max || demonID < 1)
|
||||||
|
|
||||||
if (demonID > 1) $('#pageDown').attr('href', `./${demonID - 1}`)
|
if (demonID > 1) $('#pageDown').attr('href', `./${demonID - 1}`)
|
||||||
else $('#pageDown').hide()
|
else $('#pageDown').hide()
|
||||||
|
@ -91,8 +91,8 @@ else $('#pageDown').hide()
|
||||||
if (demonID < max) $('#pageUp').attr('href', `./${demonID + 1}`)
|
if (demonID < max) $('#pageUp').attr('href', `./${demonID + 1}`)
|
||||||
else $('#pageUp').hide()
|
else $('#pageUp').hide()
|
||||||
|
|
||||||
Fetch(`../api/gdps?current=1`).then(server => {
|
Fetch(`/api/gdps?current=1`).then(server => {
|
||||||
if (illegal || !server.demonList) return $('#loading').hide();
|
if (illegal || !server.demonList) return $('#loading').hide()
|
||||||
|
|
||||||
fetch(`${server.demonList}api/v2/demons/listed?after=${demonID-1}&before=${demonID+1}`).then(res => res.json()).then(rawDemon => {
|
fetch(`${server.demonList}api/v2/demons/listed?after=${demonID-1}&before=${demonID+1}`).then(res => res.json()).then(rawDemon => {
|
||||||
|
|
||||||
|
@ -116,16 +116,16 @@ fetch(`${server.demonList}api/v2/demons/listed?after=${demonID-1}&before=${demon
|
||||||
if (x.video && x.video.includes("youtube.com")) videoIcon = "youtube"
|
if (x.video && x.video.includes("youtube.com")) videoIcon = "youtube"
|
||||||
else if (x.video && x.video.includes("twitch.tv")) videoIcon = "twitch"
|
else if (x.video && x.video.includes("twitch.tv")) videoIcon = "twitch"
|
||||||
|
|
||||||
$('#searchBox').append(`<div class="searchresult leaderboardSlot" style="align-items: center; padding-left: 1vh; height: 15%; width: 100%; position: relative;">
|
$('#searchBox').append(`<div class="searchresult leaderboardSlot" style="align-items: center; padding-left: 1vh; height: 15%; width: 100%; position: relative;">
|
||||||
|
|
||||||
<h2 class="center" style="width: 12%; margin: 0% 0% 0% 0.5%; transform: scale(${1 - (Math.max(0, String(y+1).length - 1) * 0.2)}">${y+1}</h2>
|
<h2 class="center" style="width: 12%; margin: 0% 0% 0% 0.5%; transform: scale(${1 - (Math.max(0, String(y+1).length - 1) * 0.2)}">${y+1}</h2>
|
||||||
<img class="inline spaced" src="../assets/trophies/${trophies.findIndex(z => y+1 <= z) + 1}.png" style="margin-bottom: 0%; height: 80%;">
|
<img class="inline spaced" src="/assets/trophies/${trophies.findIndex(z => y+1 <= z) + 1}.png" style="margin-bottom: 0%; height: 80%;">
|
||||||
<h2 class="small gdButton" style="font-size: 6.5vh; margin-right: 3%; margin-left: 3%"><a href="../u/${x.player.name}">${x.player.name}</a></h2>
|
<h2 class="small gdButton" style="font-size: 6.5vh; margin-right: 3%; margin-left: 3%"><a href="../u/${x.player.name}">${x.player.name}</a></h2>
|
||||||
<h3 class="lessSpaced" style="font-size: 4vh; margin-top: 1.3%; margin-right: 2%">${x.progress}%</h3>
|
<h3 class="lessSpaced" style="font-size: 4vh; margin-top: 1.3%; margin-right: 2%">${x.progress}%</h3>
|
||||||
|
|
||||||
<div style="${!x.video ? "display: none; " : ""}position:absolute; margin-top: 1.5%; width: 12.5%; height: 90%; right: 0%;">
|
<div style="${!x.video ? "display: none; " : ""}position:absolute; margin-top: 1.5%; width: 12.5%; height: 90%; right: 0%;">
|
||||||
<a target="_blank" href="${x.video}">
|
<a target="_blank" href="${x.video}">
|
||||||
<img class="gdButton inline spaced" src="../assets/${videoIcon}.png" height="80%">
|
<img class="gdButton inline spaced" src="/assets/${videoIcon}.png" height="80%">
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<head>
|
<head>
|
||||||
<title>Level Search</title>
|
<title>Level Search</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link href="../assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
<link href="/assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
||||||
<link rel="icon" href="../assets/coin.png">
|
<link rel="icon" href="/assets/coin.png">
|
||||||
<meta id="meta-title" property="og:title" content="Level Search">
|
<meta id="meta-title" property="og:title" content="Level Search">
|
||||||
<meta id="meta-desc" property="og:description" content="Search for Geometry Dash levels, and filter by length, difficulty, song + more!">
|
<meta id="meta-desc" property="og:description" content="Search for Geometry Dash levels, and filter by length, difficulty, song + more!">
|
||||||
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/coin.png">
|
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/coin.png">
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
<div id="filters" class="popup">
|
<div id="filters" class="popup">
|
||||||
<div id="filterStuff" class="brownBox bounce center supercenter" style="width: 101vh; height: 50%; padding-top: 0.3%; padding-bottom: 3.5%; padding-left: 1%">
|
<div id="filterStuff" class="brownBox bounce center supercenter" style="width: 101vh; height: 50%; padding-top: 0.3%; padding-bottom: 3.5%; padding-left: 1%">
|
||||||
<img class="gdButton" src="../assets/close.png" width="9%" style="position: absolute; top: -8.5%; left: -5.5vh" onclick="$('#filters').hide()">
|
<img class="gdButton" src="/assets/close.png" width="9%" style="position: absolute; top: -8.5%; left: -5.5vh" onclick="$('#filters').hide()">
|
||||||
<h1 style="margin-bottom: 4%">Advanced Options</h1><br>
|
<h1 style="margin-bottom: 4%">Advanced Options</h1><br>
|
||||||
<div><h1><input type="checkbox" id="box-featured" url="&featured"><label for="box-featured" class="gdcheckbox gdButton"></label>Featured</h1></div>
|
<div><h1><input type="checkbox" id="box-featured" url="&featured"><label for="box-featured" class="gdcheckbox gdButton"></label>Featured</h1></div>
|
||||||
<div><h1><input type="checkbox" id="box-epic" url="&epic"><label for="box-epic" class="gdcheckbox gdButton"></label>Epic</h1></div>
|
<div><h1><input type="checkbox" id="box-epic" url="&epic"><label for="box-epic" class="gdcheckbox gdButton"></label>Epic</h1></div>
|
||||||
|
@ -25,21 +25,21 @@
|
||||||
<div><h1><input type="checkbox" id="box-2player" url="&twoPlayer"><label for="box-2player" class="gdcheckbox gdButton"></label>2-Player</h1></div>
|
<div><h1><input type="checkbox" id="box-2player" url="&twoPlayer"><label for="box-2player" class="gdcheckbox gdButton"></label>2-Player</h1></div>
|
||||||
<div style="margin-bottom: 5%"><h1><input type="checkbox" id="box-coins" url="&coins"><label for="box-coins" class="gdcheckbox gdButton"></label>Coins</h1></div>
|
<div style="margin-bottom: 5%"><h1><input type="checkbox" id="box-coins" url="&coins"><label for="box-coins" class="gdcheckbox gdButton"></label>Coins</h1></div>
|
||||||
<h1 class="smallerer lessSpaced">Song</h1>
|
<h1 class="smallerer lessSpaced">Song</h1>
|
||||||
<img id="normalSong" class="gdButton inline gray" style="margin-right: 0.5%" src="../assets/song-normal.png" height="8%">
|
<img id="normalSong" class="gdButton inline gray" style="margin-right: 0.5%" src="/assets/song-normal.png" height="8%">
|
||||||
<img id="customSong" class="gdButton inline" style="margin-left: 0.5%" src="../assets/song-custom.png" height="8%">
|
<img id="customSong" class="gdButton inline" style="margin-left: 0.5%" src="/assets/song-custom.png" height="8%">
|
||||||
<br>
|
<br>
|
||||||
<input id="songID" type="number" placeholder="Custom Song ID" style="height: 15%; width: 70%; text-align: center; margin-top: 2%">
|
<input id="songID" type="number" placeholder="Custom Song ID" style="height: 15%; width: 70%; text-align: center; margin-top: 2%">
|
||||||
<div id="songSelect" style="width: 100%; display: none; margin-top: 3%; text-align: center">
|
<div id="songSelect" style="width: 100%; display: none; margin-top: 3%; text-align: center">
|
||||||
<img style="width: 4%" id="songDown" class="gdButton inline valign songChange" jump="-1" src="../assets/whitearrow-left.png">
|
<img style="width: 4%" id="songDown" class="gdButton inline valign songChange" jump="-1" src="/assets/whitearrow-left.png">
|
||||||
<h1 class="inline valign smallerer center" id="songName" style="min-width: 60%"></h1>
|
<h1 class="inline valign smallerer center" id="songName" style="min-width: 60%"></h1>
|
||||||
<img style="width: 4%" id="songUp" class="gdButton inline valign songChange" jump="1" id="nextSong" src="../assets/whitearrow-right.png">
|
<img style="width: 4%" id="songUp" class="gdButton inline valign songChange" jump="1" id="nextSong" src="/assets/whitearrow-right.png">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="customlist" class="popup">
|
<div id="customlist" class="popup">
|
||||||
<div class="brownBox bounce center supercenter" style="width: 100vh; height: 56%; padding-top: 0.3%; padding-bottom: 3.5%; padding-left: 1%">
|
<div class="brownBox bounce center supercenter" style="width: 100vh; height: 56%; padding-top: 0.3%; padding-bottom: 3.5%; padding-left: 1%">
|
||||||
<img class="gdButton" src="../assets/close.png" width="9%" style="position: absolute; top: -8.5%; left: -5.5vh" onclick="$('#customlist').hide()">
|
<img class="gdButton" src="/assets/close.png" width="9%" style="position: absolute; top: -8.5%; left: -5.5vh" onclick="$('#customlist').hide()">
|
||||||
<h1>Custom List</h1><br>
|
<h1>Custom List</h1><br>
|
||||||
<p id="listInfo" style="margin-top: 1%; margin-bottom: 1.5%">Paste a <cy>comma-separated</cy> list of <ca>Level IDs</ca> to create a custom list!</p>
|
<p id="listInfo" style="margin-top: 1%; margin-bottom: 1.5%">Paste a <cy>comma-separated</cy> list of <ca>Level IDs</ca> to create a custom list!</p>
|
||||||
<textarea id="listLevels" placeholder="18025697, 23189196, 27786218, 27728679, 25706351" style="margin-bottom: 2%; font-size: 2.5vh"></textarea>
|
<textarea id="listLevels" placeholder="18025697, 23189196, 27786218, 27728679, 25706351" style="margin-bottom: 2%; font-size: 2.5vh"></textarea>
|
||||||
|
@ -53,24 +53,24 @@
|
||||||
<input id="pageSize" type="number" value="10" style="font-size: 4vh; height: 13%; width: 45%; text-align: center;">
|
<input id="pageSize" type="number" value="10" style="font-size: 4vh; height: 13%; width: 45%; text-align: center;">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a id="listLink"><img src="../assets/btn-submit.png" type="submit" height=12.5%; class="disabled gdButton" style="margin-left: 1%" id="createList"></a>
|
<a id="listLink"><img src="/assets/btn-submit.png" type="submit" height=12.5%; class="disabled gdButton" style="margin-left: 1%" id="createList"></a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 0%; left: 0%; width: 100%">
|
<div style="position:absolute; bottom: 0%; left: 0%; width: 100%">
|
||||||
<img class="cornerPiece" src="../assets/corner.png" width=7%;>
|
<img class="cornerPiece" src="/assets/corner.png" width=7%;>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 0%; right: 0%; width: 100%; text-align: right;">
|
<div style="position:absolute; bottom: 0%; right: 0%; width: 100%; text-align: right;">
|
||||||
<img class="cornerPiece" src="../assets/corner.png" width=7%; style="transform: scaleX(-1); pointer-events: none">
|
<img class="cornerPiece" src="/assets/corner.png" width=7%; style="transform: scaleX(-1); pointer-events: none">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="transparentBox center" style="width: 115vh; height: 9%; margin: 1.5% auto 1% auto; padding-bottom: 0.2%">
|
<div class="transparentBox center" style="width: 115vh; height: 9%; margin: 1.5% auto 1% auto; padding-bottom: 0.2%">
|
||||||
<div>
|
<div>
|
||||||
<input type="text" id="levelName" placeholder="Enter a level, user, or ID" maxlength=20>
|
<input type="text" id="levelName" placeholder="Enter a level, user, or ID" maxlength=20>
|
||||||
<img search="0" src="../assets/search.png" id="searchBtn" width="20%" class="valign gdButton levelSearch" style="margin-left: 1%; margin-bottom: 2.2%">
|
<img search="0" src="/assets/search.png" id="searchBtn" width="20%" class="valign gdButton levelSearch" style="margin-left: 1%; margin-bottom: 2.2%">
|
||||||
<img id="userSearch" src="../assets/search-user.png" width="9.6%" class="valign gdButton" style="margin-left: 1%; margin-bottom: 2.2%">
|
<img id="userSearch" src="/assets/search-user.png" width="9.6%" class="valign gdButton" style="margin-left: 1%; margin-bottom: 2.2%">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -79,17 +79,17 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="transparentBox center" style="width: 115vh; height: 35%; margin: 0.5% auto 1% auto; padding-top: 1.1%">
|
<div class="transparentBox center" style="width: 115vh; height: 35%; margin: 0.5% auto 1% auto; padding-top: 1.1%">
|
||||||
<img src="../assets/btn-top.png" height="27%" class="valign gdButton spaced levelSearch" search="mostdownloaded">
|
<img src="/assets/btn-top.png" height="27%" class="valign gdButton spaced levelSearch" search="mostdownloaded">
|
||||||
<span style="margin-right: 3%"></span>
|
<span style="margin-right: 3%"></span>
|
||||||
<img src="../assets/btn-liked.png" height="27%" class="valign gdButton spaced levelSearch" search="mostliked">
|
<img src="/assets/btn-liked.png" height="27%" class="valign gdButton spaced levelSearch" search="mostliked">
|
||||||
<br>
|
<br>
|
||||||
<img src="../assets/btn-trending.png" height="27%" class="valign gdButton spaced levelSearch" search="trending">
|
<img src="/assets/btn-trending.png" height="27%" class="valign gdButton spaced levelSearch" search="trending">
|
||||||
<img src="../assets/btn-recent.png" height="27%" class="valign gdButton spaced levelSearch" search="recent" style="margin-left: 2%; margin-right: 2%">
|
<img src="/assets/btn-recent.png" height="27%" class="valign gdButton spaced levelSearch" search="recent" style="margin-left: 2%; margin-right: 2%">
|
||||||
<img src="../assets/btn-magic.png" height="27%" class="valign gdButton spaced levelSearch" search="magic">
|
<img src="/assets/btn-magic.png" height="27%" class="valign gdButton spaced levelSearch" search="magic">
|
||||||
<br>
|
<br>
|
||||||
<img src="../assets/btn-awarded.png" height="27%" class="valign gdButton levelSearch" search="awarded">
|
<img src="/assets/btn-awarded.png" height="27%" class="valign gdButton levelSearch" search="awarded">
|
||||||
<img src="../assets/btn-featured.png" height="27%" class="valign gdButton levelSearch" search="featured" style="margin: 0% 2%">
|
<img src="/assets/btn-featured.png" height="27%" class="valign gdButton levelSearch" search="featured" style="margin: 0% 2%">
|
||||||
<img src="../assets/btn-followed.png" height="27%" id="followedSearch" class="valign gdButton levelSearch" search="followed">
|
<img src="/assets/btn-followed.png" height="27%" id="followedSearch" class="valign gdButton levelSearch" search="followed">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="center">
|
<div class="center">
|
||||||
|
@ -97,56 +97,56 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="difficulties" class="transparentBox center" style="width: 115vh; height: 12%; margin: 0.5% auto 1% auto; padding-top: 1%; padding-bottom: 1%;">
|
<div id="difficulties" class="transparentBox center" style="width: 115vh; height: 12%; margin: 0.5% auto 1% auto; padding-top: 1%; padding-bottom: 1%;">
|
||||||
<div class="diffDiv gdButton" diff="-1"><img src="../assets/difficulties/unrated.png"><h3 class="mini">N/A</h3></div>
|
<div class="diffDiv gdButton" diff="-1"><img src="/assets/difficulties/unrated.png"><h3 class="mini">N/A</h3></div>
|
||||||
<div class="diffDiv gdButton" diff=1><img src="../assets/difficulties/easy.png"><h3 class="mini">Easy</h3></div>
|
<div class="diffDiv gdButton" diff=1><img src="/assets/difficulties/easy.png"><h3 class="mini">Easy</h3></div>
|
||||||
<div class="diffDiv gdButton" diff=2><img src="../assets/difficulties/normal.png"><h3 class="mini">Normal</h3></div>
|
<div class="diffDiv gdButton" diff=2><img src="/assets/difficulties/normal.png"><h3 class="mini">Normal</h3></div>
|
||||||
<div class="diffDiv gdButton" diff=3><img src="../assets/difficulties/hard.png"><h3 class="mini">Hard</h3></div>
|
<div class="diffDiv gdButton" diff=3><img src="/assets/difficulties/hard.png"><h3 class="mini">Hard</h3></div>
|
||||||
<div class="diffDiv gdButton" diff=4><img src="../assets/difficulties/harder.png"><h3 class="mini">Harder</h3></div>
|
<div class="diffDiv gdButton" diff=4><img src="/assets/difficulties/harder.png"><h3 class="mini">Harder</h3></div>
|
||||||
<div class="diffDiv gdButton" diff=5><img src="../assets/difficulties/insane.png"><h3 class="mini">Insane</h3></div>
|
<div class="diffDiv gdButton" diff=5><img src="/assets/difficulties/insane.png"><h3 class="mini">Insane</h3></div>
|
||||||
|
|
||||||
<div class="diffDiv gdButton" id="demonBtn" diff=-2><img src="../assets/difficulties/demon.png" style="width: 85%"><h3 class="mini">Demon</h3></div>
|
<div class="diffDiv gdButton" id="demonBtn" diff=-2><img src="/assets/difficulties/demon.png" style="width: 85%"><h3 class="mini">Demon</h3></div>
|
||||||
|
|
||||||
<!-- <div class="diffDiv gdButton" style="filter: brightness(100%)" id="demonBtn" diff=-2><img class="darkDiff" src="../assets/difficulties/demon.png" style="width: 85%"><h3 class="darkDiff mini">Demon</h3> -->
|
<!-- <div class="diffDiv gdButton" style="filter: brightness(100%)" id="demonBtn" diff=-2><img class="darkDiff" src="/assets/difficulties/demon.png" style="width: 85%"><h3 class="darkDiff mini">Demon</h3> -->
|
||||||
<!-- <img src="../assets/exclamation.png" style="position: absolute; width: 19%; left: 86%; bottom: 68%"></div> -->
|
<!-- <img src="/assets/exclamation.png" style="position: absolute; width: 19%; left: 86%; bottom: 68%"></div> -->
|
||||||
|
|
||||||
<div class="diffDiv gdButton" diff=-3><img src="../assets/difficulties/auto.png"><h3 class="mini">Auto</h3></div>
|
<div class="diffDiv gdButton" diff=-3><img src="/assets/difficulties/auto.png"><h3 class="mini">Auto</h3></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="demons" class="transparentBox" style="display: none; width: 115vh; height: 12%; margin: 0.5% auto 1% auto; padding-top: 0.6%; padding-bottom: 1.4%;">
|
<div id="demons" class="transparentBox" style="display: none; width: 115vh; height: 12%; margin: 0.5% auto 1% auto; padding-top: 0.6%; padding-bottom: 1.4%;">
|
||||||
<div class="diffDiv gdButton demonDiff" diff=1 style="margin-left: 3.5%"><img src="../assets/difficulties/demon-easy.png" style="width: 90%"><h3 class="mini center">Easy</h3></div>
|
<div class="diffDiv gdButton demonDiff" diff=1 style="margin-left: 3.5%"><img src="/assets/difficulties/demon-easy.png" style="width: 90%"><h3 class="mini center">Easy</h3></div>
|
||||||
<div class="diffDiv gdButton demonDiff" diff=2><img src="../assets/difficulties/demon-medium.png" style="width: 90%"><h3 class="mini center smallTextWoo">Medium</h3></div>
|
<div class="diffDiv gdButton demonDiff" diff=2><img src="/assets/difficulties/demon-medium.png" style="width: 90%"><h3 class="mini center smallTextWoo">Medium</h3></div>
|
||||||
<div class="diffDiv gdButton demonDiff" diff=3><img src="../assets/difficulties/demon-hard.png" style="width: 90%"><h3 class="mini center">Hard</h3></div>
|
<div class="diffDiv gdButton demonDiff" diff=3><img src="/assets/difficulties/demon-hard.png" style="width: 90%"><h3 class="mini center">Hard</h3></div>
|
||||||
<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=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 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>
|
<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" 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>
|
<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>
|
||||||
|
|
||||||
<div class="transparentBox center" style="width: 115vh; height: 6%; margin: 0.5% auto 1% auto; padding-top: 1%; padding-bottom: 0.5%;">
|
<div class="transparentBox center" style="width: 115vh; height: 6%; margin: 0.5% auto 1% auto; padding-top: 1%; padding-bottom: 0.5%;">
|
||||||
<!-- <div class="lengthDiv" style="pointer-events: none" len=0><h1 class="gdButton smaller" style="pointer-events: none"><img src="../assets/time.png" height="90%" style="pointer-events: none"></h1></div> -->
|
<!-- <div class="lengthDiv" style="pointer-events: none" len=0><h1 class="gdButton smaller" style="pointer-events: none"><img src="/assets/time.png" height="90%" style="pointer-events: none"></h1></div> -->
|
||||||
<div class="lengthDiv" len=0><h1 class="gdButton smaller">Tiny</h1></div>
|
<div class="lengthDiv" len=0><h1 class="gdButton smaller">Tiny</h1></div>
|
||||||
<div class="lengthDiv" len=1><h1 class="gdButton smaller">Short</h1></div>
|
<div class="lengthDiv" len=1><h1 class="gdButton smaller">Short</h1></div>
|
||||||
<div class="lengthDiv" len=2><h1 class="gdButton smaller">Medium</h1></div>
|
<div class="lengthDiv" len=2><h1 class="gdButton smaller">Medium</h1></div>
|
||||||
<div class="lengthDiv" len=3><h1 class="gdButton smaller">Long</h1></div>
|
<div class="lengthDiv" len=3><h1 class="gdButton smaller">Long</h1></div>
|
||||||
<div class="lengthDiv" len=4><h1 class="gdButton smaller">XL</h1></div>
|
<div class="lengthDiv" len=4><h1 class="gdButton smaller">XL</h1></div>
|
||||||
<div class="lengthDiv" id="starCheck"><img src="../assets/star.png" class="gdButton" height="90%"></div>
|
<div class="lengthDiv" id="starCheck"><img src="/assets/star.png" class="gdButton" height="90%"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; top: 2%; left: 1.5%; width: 10%; height: 25%; pointer-events: none">
|
<div style="position:absolute; top: 2%; left: 1.5%; width: 10%; height: 25%; pointer-events: none">
|
||||||
<img class="gdButton yesClick" id="backButton" src="../assets/back.png" height="30%" onclick="backButton()">
|
<img class="gdButton yesClick" id="backButton" src="/assets/back.png" height="30%" onclick="backButton()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; top: 2%; right: 1.5%; width: 10%; text-align: right">
|
<div style="position:absolute; top: 2%; right: 1.5%; width: 10%; text-align: right">
|
||||||
<img class="gdButton" style="margin-bottom: 12%" src="../assets/close.png" width="60%" onclick="clearFilters()">
|
<img class="gdButton" style="margin-bottom: 12%" src="/assets/close.png" width="60%" onclick="clearFilters()">
|
||||||
<img class="gdButton" style="margin-bottom: 12%" id="showFilters" src="../assets/plus.png" width="60%" onclick="$('#filters').show()">
|
<img class="gdButton" style="margin-bottom: 12%" id="showFilters" src="/assets/plus.png" width="60%" onclick="$('#filters').show()">
|
||||||
<img class="gdButton" src="../assets/listbutton.png" width="60%" onclick="$('#customlist').show()">
|
<img class="gdButton" src="/assets/listbutton.png" width="60%" onclick="$('#customlist').show()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||||
<script type="text/javascript" src="../global.js?v=1"></script>
|
<script type="text/javascript" src="/misc/global.js?v=1"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
let filters = []
|
let filters = []
|
||||||
|
@ -174,7 +174,7 @@ $('.levelSearch').click(function() {
|
||||||
let difficulties = []
|
let difficulties = []
|
||||||
$('.diffDiv').each(function() {if ($(this).hasClass('selectedFilter')) difficulties.push($(this).attr('diff'))})
|
$('.diffDiv').each(function() {if ($(this).hasClass('selectedFilter')) difficulties.push($(this).attr('diff'))})
|
||||||
demonFilter = demonMode && difficulties[0] > 0
|
demonFilter = demonMode && difficulties[0] > 0
|
||||||
|
|
||||||
if (!difficulties.length) url += ""
|
if (!difficulties.length) url += ""
|
||||||
else if (!demonFilter) url += "&diff=" + undupe(difficulties).join(",")
|
else if (!demonFilter) url += "&diff=" + undupe(difficulties).join(",")
|
||||||
else url += "&diff=-2&demonFilter=" + difficulties[0]
|
else url += "&diff=-2&demonFilter=" + difficulties[0]
|
||||||
|
@ -212,15 +212,15 @@ function getDiffFilters() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function showDemonDiffs() {
|
function showDemonDiffs() {
|
||||||
$('#difficulties').hide();
|
$('#difficulties').hide()
|
||||||
$('#demons').show();
|
$('#demons').show()
|
||||||
demonMode = true;
|
demonMode = true
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideDemonDiffs() {
|
function hideDemonDiffs() {
|
||||||
$('#difficulties').show();
|
$('#difficulties').show()
|
||||||
$('#demons').hide();
|
$('#demons').hide()
|
||||||
demonMode = false;
|
demonMode = false
|
||||||
}
|
}
|
||||||
|
|
||||||
$('.diffDiv').click(function() {
|
$('.diffDiv').click(function() {
|
||||||
|
@ -262,16 +262,16 @@ $('.lengthDiv').click(function() {
|
||||||
$(document).keydown(function(k) {
|
$(document).keydown(function(k) {
|
||||||
let searchFocus = $(':focus-visible').length == 1 && $(':focus-visible').first().attr('id') == "levelName"
|
let searchFocus = $(':focus-visible').length == 1 && $(':focus-visible').first().attr('id') == "levelName"
|
||||||
if ((!$(':focus-visible').length || searchFocus) && k.which == 13) { // enter
|
if ((!$(':focus-visible').length || searchFocus) && k.which == 13) { // enter
|
||||||
if (!$('#customlist').is(':hidden')) k.preventDefault();
|
if (!$('#customlist').is(':hidden')) k.preventDefault()
|
||||||
else if ($('#filters').is(':hidden')) $('#searchBtn').trigger('click')
|
else if ($('#filters').is(':hidden')) $('#searchBtn').trigger('click')
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#pageSize').on('input blur', function (event) {
|
$('#pageSize').on('input blur', function (event) {
|
||||||
var x = +$(this).val(); var max = 250; var min = 1
|
var x = +$(this).val(); var max = 250; var min = 1
|
||||||
if (event.type == "input") { if (x > max || x < min) $(this).addClass('red'); else $(this).removeClass('red')}
|
if (event.type == "input") { if (x > max || x < min) $(this).addClass('red'); else $(this).removeClass('red')}
|
||||||
else {
|
else {
|
||||||
$(this).val(Math.max(Math.min(Math.floor(x), max), min));
|
$(this).val(clamp(Math.floor(x), min, max))
|
||||||
$(this).removeClass('red')
|
$(this).removeClass('red')
|
||||||
}
|
}
|
||||||
$('#listLevels').trigger('input')
|
$('#listLevels').trigger('input')
|
||||||
|
@ -279,7 +279,7 @@ $('#pageSize').on('input blur', function (event) {
|
||||||
|
|
||||||
let listMsg = $('#listInfo').html()
|
let listMsg = $('#listInfo').html()
|
||||||
$('#listLevels, #listName').on('input blur', function (event) {
|
$('#listLevels, #listName').on('input blur', function (event) {
|
||||||
let levels = $('#listLevels').val().replace(/\n| /g, ",").split(",").map(x => x.replace(/[^0-9]/g, "")).filter(x => +x > 0 && +x < 100000000000)
|
let levels = $('#listLevels').val().replace(/\n| /g, ",").split(",").map(x => x.replace(/\D/g, "")).filter(x => +x > 0 && +x < 10**11)
|
||||||
levels = undupe(levels)
|
levels = undupe(levels)
|
||||||
|
|
||||||
if (levels.length > 1 && levels.length <= 100) {
|
if (levels.length > 1 && levels.length <= 100) {
|
||||||
|
@ -376,11 +376,11 @@ else if (+savedFilters.song && +savedFilters.song > 0) $('#songID').val(savedFil
|
||||||
|
|
||||||
checkExtraFilters()
|
checkExtraFilters()
|
||||||
|
|
||||||
Fetch(`../api/music`).then(music => {
|
Fetch(`/api/music`).then(music => {
|
||||||
|
|
||||||
$('#songName').html("1: " + music[1][0])
|
$('#songName').html("1: " + music[1][0])
|
||||||
|
|
||||||
$(document).on('click', '.songChange', function () {
|
$(document).on('click', '.songChange', function () {
|
||||||
officialSong += Number($(this).attr('jump'))
|
officialSong += Number($(this).attr('jump'))
|
||||||
if (officialSong < 1) officialSong = 1
|
if (officialSong < 1) officialSong = 1
|
||||||
$('#songName').html(`${officialSong}: ${music[officialSong] ? music[officialSong][0] : officialSong == 69 ? "Nice" : "Unknown"}`)
|
$('#songName').html(`${officialSong}: ${music[officialSong] ? music[officialSong][0] : officialSong == 69 ? "Nice" : "Unknown"}`)
|
||||||
|
@ -395,10 +395,10 @@ Fetch(`../api/music`).then(music => {
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).keydown(function(k) {
|
$(document).keydown(function(k) {
|
||||||
if (customSong) return;
|
if (customSong) return
|
||||||
if (k.which == 37) $('#songDown').trigger('click') // left
|
if (k.which == 37) $('#songDown').trigger('click') // left
|
||||||
if (k.which == 39) $('#songUp').trigger('click') // right
|
if (k.which == 39) $('#songUp').trigger('click') // right
|
||||||
});
|
})
|
||||||
|
|
||||||
if (onePointNine) {
|
if (onePointNine) {
|
||||||
$('#userSearch').hide()
|
$('#userSearch').hide()
|
||||||
|
@ -406,7 +406,7 @@ Fetch(`../api/music`).then(music => {
|
||||||
$('#levelName').css('width', '76%')
|
$('#levelName').css('width', '76%')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gdps) Fetch(`../api/gdps?current=1`).then(res => { if (res.demonList) $('#demonList').show() })
|
if (gdps) Fetch(`/api/gdps?current=1`).then(res => { if (res.demonList) $('#demonList').show() })
|
||||||
else $('#demonList').show()
|
else $('#demonList').show()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<head>
|
<head>
|
||||||
<title>Gauntlets</title>
|
<title>Gauntlets</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link href="../assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
<link href="/assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
||||||
<link rel="icon" href="../assets/gauntlet.png">
|
<link rel="icon" href="/assets/gauntlet.png">
|
||||||
<meta id="meta-title" property="og:title" content="Gauntlets">
|
<meta id="meta-title" property="og:title" content="Gauntlets">
|
||||||
<meta id="meta-desc" property="og:description" content="Because RobTop wanted to leave behind the monstrosity that is Map Packs.">
|
<meta id="meta-desc" property="og:description" content="Because RobTop wanted to leave behind the monstrosity that is Map Packs.">
|
||||||
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/gauntlet.png">
|
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/gauntlet.png">
|
||||||
|
@ -15,34 +15,34 @@
|
||||||
<div id="everything" class="center" style="width: 100%; height: 100%;">
|
<div id="everything" class="center" style="width: 100%; height: 100%;">
|
||||||
|
|
||||||
<div style="position:absolute; top: 2%; left: -1.95%; width: 10%; height: 25%; pointer-events: none">
|
<div style="position:absolute; top: 2%; left: -1.95%; width: 10%; height: 25%; pointer-events: none">
|
||||||
<img class="gdButton yesClick" id="backButton" src="../assets/back.png" height="30%" onclick="backButton()">
|
<img class="gdButton yesClick" id="backButton" src="/assets/back.png" height="30%" onclick="backButton()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="center" width="100%" style="margin-top: 2.5%; margin-bottom: 1%;">
|
<div class="center" width="100%" style="margin-top: 2.5%; margin-bottom: 1%;">
|
||||||
<img src="../assets/gauntlets.png" width="50%">
|
<img src="/assets/gauntlets.png" width="50%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<img id="loading" style="margin-top: 1%" class="spin noSelect" src="../assets/loading.png" height="12%">
|
<img id="loading" style="margin-top: 1%" class="spin noSelect" src="/assets/loading.png" height="12%">
|
||||||
|
|
||||||
<div id="gauntletList">
|
<div id="gauntletList">
|
||||||
<br>
|
<br>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||||
<script type="text/javascript" src="../global.js?v=1"></script>
|
<script type="text/javascript" src="/misc/global.js?v=1"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
fetch('../api/gauntlets').then(res => res.json()).then(gauntlets => {
|
fetch('/api/gauntlets').then(res => res.json()).then(gauntlets => {
|
||||||
$('#loading').hide()
|
$('#loading').hide()
|
||||||
gauntlets.forEach((x, y) => {
|
gauntlets.forEach((x, y) => {
|
||||||
$('#gauntletList').append(`
|
$('#gauntletList').append(`
|
||||||
<div class="gauntlet">
|
<div class="gauntlet">
|
||||||
<a href="../search/*?gauntlet=${x.id}">
|
<a href="../search/*?gauntlet=${x.id}">
|
||||||
<img src="../assets/gauntlets/${x.name.toLowerCase()}.png" height="300%"><br>
|
<img src="/assets/gauntlets/${x.name.toLowerCase()}.png" height="300%"><br>
|
||||||
<h3 class="gauntletText"">${x.name}<br>Gauntlet</h3></div></a>`)
|
<h3 class="gauntletText"">${x.name}<br>Gauntlet</h3></div></a>`)
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<head>
|
<head>
|
||||||
<title>GD Multiverse Navigation Terminal</title>
|
<title>GD Multiverse Navigation Terminal</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link href="../assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
<link href="/assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
||||||
<link rel="icon" href="../assets/unlock.png">
|
<link rel="icon" href="/assets/unlock.png">
|
||||||
<meta id="meta-title" property="og:title" content="GD Multiverse Navigation Terminal">
|
<meta id="meta-title" property="og:title" content="GD Multiverse Navigation Terminal">
|
||||||
<meta id="meta-desc" property="og:description" content="That's uhh... that's just fancy talk for GDPS Browser. Select a popular GD private server and view its levels, creators, packs, leaderboards, and more!">
|
<meta id="meta-desc" property="og:description" content="That's uhh... that's just fancy talk for GDPS Browser. Select a popular GD private server and view its levels, creators, packs, leaderboards, and more!">
|
||||||
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/unlock.png">
|
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/unlock.png">
|
||||||
|
@ -26,43 +26,43 @@
|
||||||
Please note that I only add <cg>relatively large</cg> servers to the list.
|
Please note that I only add <cg>relatively large</cg> servers to the list.
|
||||||
Servers which are <cr>inactive</cr> or have <cr>few levels/members</cr> will not be accepted.
|
Servers which are <cr>inactive</cr> or have <cr>few levels/members</cr> will not be accepted.
|
||||||
</p>
|
</p>
|
||||||
<img src="../assets/ok.png" width=15%; class="gdButton center" onclick="$('.popup').hide()">
|
<img src="/assets/ok.png" width=15%; class="gdButton center" onclick="$('.popup').hide()">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="searchBox" class="supercenter dragscroll"; style="width: 127vh"></div>
|
<div id="searchBox" class="supercenter dragscroll"; style="width: 127vh"></div>
|
||||||
|
|
||||||
<div class="epicbox supercenter gs" style="width: 126vh; height: 80%; pointer-events: none"></div>
|
<div class="epicbox supercenter gs" style="width: 126vh; height: 80%; pointer-events: none"></div>
|
||||||
|
|
||||||
<div class="center" style="position:absolute; top: 8%; left: 0%; right: 0%">
|
<div class="center" style="position:absolute; top: 8%; left: 0%; right: 0%">
|
||||||
<h1 class="pre" id="header">GD Private Servers</h1>
|
<h1 class="pre" id="header">GD Private Servers</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; top: 2%; left: 1.5%; width: 10%; height: 25%; pointer-events: none">
|
<div style="position:absolute; top: 2%; left: 1.5%; width: 10%; height: 25%; pointer-events: none">
|
||||||
<img class="gdButton yesClick" id="backButton" src="../assets/back.png" height="30%" onclick="backButton()">
|
<img class="gdButton yesClick" id="backButton" src="/assets/back.png" height="30%" onclick="backButton()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="supercenter" id="loading" style="height: 10%; top: 47%">
|
<div class="supercenter" id="loading" style="height: 10%; top: 47%">
|
||||||
<img class="spin noSelect" src="../assets/loading.png" height="105%">
|
<img class="spin noSelect" src="/assets/loading.png" height="105%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position: absolute; left: 7%; top: 45%; height: 10%;">
|
<div style="position: absolute; left: 7%; top: 45%; height: 10%;">
|
||||||
<img class="gdButton" id="pageDown" src="../assets/arrow-left.png" style="display: none"; height="90%">
|
<img class="gdButton" id="pageDown" src="/assets/arrow-left.png" style="display: none"; height="90%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position: absolute; right: 7%; top: 45%; height: 10%;">
|
<div style="position: absolute; right: 7%; top: 45%; height: 10%;">
|
||||||
<img class="gdButton" id="pageUp" src="../assets/arrow-right.png" style="display: none"; height="90%">
|
<img class="gdButton" id="pageUp" src="/assets/arrow-right.png" style="display: none"; height="90%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; top: 3%; right: 2%; text-align: right; width: 20%;">
|
<div style="position:absolute; top: 3%; right: 2%; text-align: right; width: 20%;">
|
||||||
<img id="plusButton" class="inline gdButton" src="../assets/plus.png" width="25%" onclick="$('#infoDiv').show()">
|
<img id="plusButton" class="inline gdButton" src="/assets/plus.png" width="25%" onclick="$('#infoDiv').show()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||||
<script type="text/javascript" src="../global.js?v=1"></script>
|
<script type="text/javascript" src="/misc/global.js?v=1"></script>
|
||||||
<script type="text/javascript" src="../dragscroll.js"></script>
|
<script type="text/javascript" src="../dragscroll.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ let page = 1
|
||||||
let localhost = window.location.hostname == "localhost"
|
let localhost = window.location.hostname == "localhost"
|
||||||
let host = window.location.host.split(".").slice(-2).join(".")
|
let host = window.location.host.split(".").slice(-2).join(".")
|
||||||
|
|
||||||
Fetch('../api/gdps').then(servers => {
|
Fetch('/api/gdps').then(servers => {
|
||||||
|
|
||||||
let currentServer = servers.find(x => x.id == gdps)
|
let currentServer = servers.find(x => x.id == gdps)
|
||||||
servers = [currentServer].concat(servers.filter(x => x.id != gdps)).filter(x => x)
|
servers = [currentServer].concat(servers.filter(x => x.id != gdps)).filter(x => x)
|
||||||
|
@ -89,15 +89,15 @@ Fetch('../api/gdps').then(servers => {
|
||||||
|
|
||||||
serverPage.forEach(x => {
|
serverPage.forEach(x => {
|
||||||
$('#searchBox').append(`<div class="searchresult" style="height: 19%; padding-top: 1.2%">
|
$('#searchBox').append(`<div class="searchresult" style="height: 19%; padding-top: 1.2%">
|
||||||
<h1 class="lessspaced blue" style="color: ${(gdps || "") == x.id ? "#00DDFF" : "white"}">${x.name}</h1>
|
<h1 class="lessspaced blue" style="color: ${(gdps || "") == x.id ? "#0DF" : "white"}">${x.name}</h1>
|
||||||
<h2 class="lessSpaced smaller inline gdButton"><a href="${x.authorLink}" target="_blank">By ${x.author}</a></h2>
|
<h2 class="lessSpaced smaller inline gdButton"><a href="${x.authorLink}" target="_blank">By ${x.author}</a></h2>
|
||||||
|
|
||||||
<div class="center" style="position:absolute; height: 10%; width: 12.5%; left: 3%; transform:translateY(-160%)">
|
<div class="center" style="position:absolute; height: 10%; width: 12.5%; left: 3%; transform:translateY(-160%)">
|
||||||
<a href="${x.link}" target="_blank"><img class="gdButton spaced gdpslogo" src="../assets/gdps/${x.id || "gd"}_icon.png" height="130%"></a>
|
<a href="${x.link}" target="_blank"><img class="gdButton spaced gdpslogo" src="/assets/gdps/${x.id || "gd"}_icon.png" height="130%"></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="center" style="position:absolute; right: 7%; transform:translateY(-150%); height: 10%">
|
<div class="center" style="position:absolute; right: 7%; transform:translateY(-150%); height: 10%">
|
||||||
<a href="http://${x.id || ""}${x.id && localhost ? ".x" : ""}${x.id ? "." : ""}${host}"><img style="margin-bottom: 4.5%" class="valign gdButton" src="../assets/view.png" height="105%"></a>
|
<a href="http://${x.id || ""}${x.id && localhost ? ".x" : ""}${x.id ? "." : ""}${host}"><img style="margin-bottom: 4.5%" class="valign gdButton" src="/assets/view.png" height="105%"></a>
|
||||||
</div>
|
</div>
|
||||||
</div>`)
|
</div>`)
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<head>
|
<head>
|
||||||
<title>Geometry Dash Browser!</title>
|
<title>Geometry Dash Browser!</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link href="../assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
<link href="/assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
||||||
<link rel="icon" href="../assets/coin.png">
|
<link rel="icon" href="/assets/coin.png">
|
||||||
<meta id="meta-title" property="og:title" content="Geometry Dash Browser!">
|
<meta id="meta-title" property="og:title" content="Geometry Dash Browser!">
|
||||||
<meta id="meta-desc" property="og:description" content="Browse all of Geometry Dash's online features, right from this handy little website! Levels, profiles, leaderboards, comments, and more!">
|
<meta id="meta-desc" property="og:description" content="Browse all of Geometry Dash's online features, right from this handy little website! Levels, profiles, leaderboards, comments, and more!">
|
||||||
<meta id="meta-image" name="og:image" content="https://gdbrowser.com/assets/coin.png" itemprop="image">
|
<meta id="meta-image" name="og:image" content="https://gdbrowser.com/assets/coin.png" itemprop="image">
|
||||||
|
@ -18,76 +18,76 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 0%; left: 0%; width: 100%; pointer-events: none">
|
<div style="position:absolute; bottom: 0%; left: 0%; width: 100%; pointer-events: none">
|
||||||
<img class="cornerPiece" src="../assets/corner.png" width=7%;>
|
<img class="cornerPiece" src="/assets/corner.png" width=7%;>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; top: 0%; left: 0%; width: 100%; pointer-events: none">
|
<div style="position:absolute; top: 0%; left: 0%; width: 100%; pointer-events: none">
|
||||||
<img class="cornerPiece" src="../assets/corner.png" width=7%; style="transform: scaleY(-1)">
|
<img class="cornerPiece" src="/assets/corner.png" width=7%; style="transform: scaleY(-1)">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; top: 1.7%; right: 2%; text-align: right; width: 10%;">
|
<div style="position:absolute; top: 1.7%; right: 2%; text-align: right; width: 10%;">
|
||||||
<img id="creditsButton" class="gdButton" src="../assets/credits.png" width="60%" onclick="loadCredits()">
|
<img id="creditsButton" class="gdButton" src="/assets/credits.png" width="60%" onclick="loadCredits()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="menu-achievements" style="position:absolute; top: 5.5%; left: 3%; width: 12%;">
|
<div class="menu-achievements" style="position:absolute; top: 5.5%; left: 3%; width: 12%;">
|
||||||
<a href="../achievements"><img class="gdButton" src="../assets/achievements.png" width="40%"></a>
|
<a href="../achievements"><img class="gdButton" src="/assets/achievements.png" width="40%"></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="menu-messages" style="position:absolute; top: -1.7%; left: 11%; text-align: left; width: 10%;">
|
<div class="menu-messages" style="position:absolute; top: -1.7%; left: 11%; text-align: left; width: 10%;">
|
||||||
<a href="../messages"><img class="iconRope" src="../assets/messagerope.png" width="40%"></a>
|
<a href="../messages"><img class="iconRope" src="/assets/messagerope.png" width="40%"></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; top: -1.5%; right: 10%; text-align: right; width: 10%;">
|
<div style="position:absolute; top: -1.5%; right: 10%; text-align: right; width: 10%;">
|
||||||
<a href="../iconkit"><img class="iconRope" src="../assets/iconrope.png" width="40%"></a>
|
<a href="../iconkit"><img class="iconRope" src="/assets/iconrope.png" width="40%"></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="dl" style="display: none; position:absolute; top: 15%; right: 0.5%; text-align: center; width: 17%">
|
<div id="dl" style="display: none; position:absolute; top: 15%; right: 0.5%; text-align: center; width: 17%">
|
||||||
<h1 class="smaller" style="margin-bottom: 1%">Note</h1>
|
<h1 class="smaller" style="margin-bottom: 1%">Note</h1>
|
||||||
<p style="font-size: 2.2vh; margin-top: 1.2%"><ca>Level downloading</ca> has been <cr>blocked</cr> by RobTop.
|
<p style="font-size: 2.2vh; margin-top: 1.2%"><ca>Level downloading</ca> has been <cr>blocked</cr> by RobTop.
|
||||||
<cy>Level analysis, daily levels, and downloading extra info</cy> will <cg>not work</cg> until he chooses to unblock downloads.
|
<cy>Level analysis, daily levels, and downloading extra info</cy> will <cg>not work</cg> until he chooses to unblock downloads.
|
||||||
These features still work <ca><a class="underline" target="_blank" href="https://github.com/GDColon/GDBrowser">locally</a></ca> and on <ca><a class="underline" href="../gdps">private servers</a></ca></p>
|
These features still work <ca><a class="underline" target="_blank" href="https://github.com/GDColon/GDBrowser">locally</a></ca> and on <ca><a class="underline" href="../gdps">private servers</a></ca></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="supercenter center" id="menuButtons" style="bottom: 5%;">
|
<div class="supercenter center" id="menuButtons" style="bottom: 5%;">
|
||||||
<table>
|
<table>
|
||||||
<tr class="menuButtonList">
|
<tr class="menuButtonList">
|
||||||
<td><a tabindex="1" href="./search/*?type=saved"><img class="menubutton menu-saved" src="../assets/category-saved.png" title="Saved Levels"></a></td>
|
<td><a tabindex="1" href="./search/*?type=saved"><img class="menubutton menu-saved" src="/assets/category-saved.png" title="Saved Levels"></a></td>
|
||||||
<td><a tabindex="1" href="./daily"><img class="menubutton menu-daily" src="../assets/category-daily.png" title="Daily Level"></a></td>
|
<td><a tabindex="1" href="./daily"><img class="menubutton menu-daily" src="/assets/category-daily.png" title="Daily Level"></a></td>
|
||||||
<td style="display: block" id="menu_weekly"><a tabindex="1" href="./weekly"><img class="menubutton menu-weekly" src="../assets/category-weekly.png" title="Weekly Demon"></a></td>
|
<td style="display: block" id="menu_weekly"><a tabindex="1" href="./weekly"><img class="menubutton menu-weekly" src="/assets/category-weekly.png" title="Weekly Demon"></a></td>
|
||||||
<td style="display: none" id="menu_featured"><a tabindex="1" href="./search/*?type=featured"><img class="menubutton menu-featured" src="../assets/category-featured.png" title="Featured"></a></td>
|
<td style="display: none" id="menu_featured"><a tabindex="1" href="./search/*?type=featured"><img class="menubutton menu-featured" src="/assets/category-featured.png" title="Featured"></a></td>
|
||||||
<td><a tabindex="1" href="./gauntlets"><img class="menubutton menu-gauntlets" src="../assets/category-gauntlets.png" title="Gauntlets"></a></td>
|
<td><a tabindex="1" href="./gauntlets"><img class="menubutton menu-gauntlets" src="/assets/category-gauntlets.png" title="Gauntlets"></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="menuButtonList">
|
<tr class="menuButtonList">
|
||||||
<td><a tabindex="1" href="./leaderboard"><img class="menubutton menu-leaderboard" src="../assets/category-scores.png" title="Scores"></a></td>
|
<td><a tabindex="1" href="./leaderboard"><img class="menubutton menu-leaderboard" src="/assets/category-scores.png" title="Scores"></a></td>
|
||||||
<!-- <img src="./assets/exclamation.png" style="position: absolute; height: 18%; left: 3.5%; bottom: 23%; pointer-events: none; z-index: 50;"> -->
|
<!-- <img src="./assets/exclamation.png" style="position: absolute; height: 18%; left: 3.5%; bottom: 23%; pointer-events: none; z-index: 50;"> -->
|
||||||
<td><a tabindex="1" href="./search/*?type=hof"><img class="menubutton menu-hof" src="../assets/category-hof.png" title="Hall Of Fame"></a></td>
|
<td><a tabindex="1" href="./search/*?type=hof"><img class="menubutton menu-hof" src="/assets/category-hof.png" title="Hall Of Fame"></a></td>
|
||||||
<td><a tabindex="1" href="./mappacks"><img class="menubutton menu-mappacks" src="../assets/category-packs.png" title="Map Packs"></a></td>
|
<td><a tabindex="1" href="./mappacks"><img class="menubutton menu-mappacks" src="/assets/category-packs.png" title="Map Packs"></a></td>
|
||||||
<td><a tabindex="1" href="./search"><img class="menubutton menu-search" src="../assets/category-search.png" title="Search"></a></td>
|
<td><a tabindex="1" href="./search"><img class="menubutton menu-search" src="/assets/category-search.png" title="Search"></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<p style="margin-bottom: 2%">Website created by <a class="menuLink" href="https://twitter.com/TheRealGDColon" title="Colon">Colon</a> :<br>Pretty much everything other than that belongs to <a class="menuLink" href="http://robtopgames.com" title="RobTop Games">RobTop Games</a>.</p>
|
<p style="margin-bottom: 2%">Website created by <a class="menuLink" href="https://twitter.com/TheRealGDColon" title="Colon">Colon</a> :<br>Pretty much everything other than that belongs to <a class="menuLink" href="http://robtopgames.com" title="RobTop Games">RobTop Games</a>.</p>
|
||||||
<p style="margin-top: 0%"><a class="menuLink" href="https://gdcolon.com/tools" title="GD Tools">GD Tools</a>
|
<p style="margin-top: 0%"><a class="menuLink" href="https://gdcolon.com/tools" title="GD Tools">GD Tools</a>
|
||||||
|
|
||||||
<a class="menuLink" href="https://gdcolon.com" title="API">More Projects</a>
|
<a class="menuLink" href="https://gdcolon.com" title="API">More Projects</a>
|
||||||
|
|
||||||
<a class="menuLink" href="https://github.com/GDColon/GDBrowser" title="GitHub">GitHub</a>
|
<a class="menuLink" href="https://github.com/GDColon/GDBrowser" title="GitHub">GitHub</a>
|
||||||
|
|
||||||
<a class="menuLink" href="https://store.steampowered.com/app/322170/Geometry_Dash/" title="Buy Geometry Dash!">Buy Geometry Dash!</a></p>
|
<a class="menuLink" href="https://store.steampowered.com/app/322170/Geometry_Dash/" title="Buy Geometry Dash!">Buy Geometry Dash!</a></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 17%; right: 7%; width: 9%; text-align: right; pointer-events: none">
|
<div style="position:absolute; bottom: 17%; right: 7%; width: 9%; text-align: right; pointer-events: none">
|
||||||
<img src="../assets/privateservers.png" width=85%;">
|
<img src="/assets/privateservers.png" width=85%;">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 2.5%; right: 1.5%; text-align: right; width: 18%;">
|
<div style="position:absolute; bottom: 2.5%; right: 1.5%; text-align: right; width: 18%;">
|
||||||
<a href="../gdps" title="GD Private Servers"><img class="gdButton" src="../assets/basement.png" width="40%"></a>
|
<a href="../gdps" title="GD Private Servers"><img class="gdButton" src="/assets/basement.png" width="40%"></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="center" width="100%" style="margin-top: 2%">
|
<div class="center" width="100%" style="margin-top: 2%">
|
||||||
<img src="../assets/gdlogo.png" height="11.5%"><br>
|
<img src="/assets/gdlogo.png" height="11.5%"><br>
|
||||||
<img id="browserlogo" src="../assets/browser.png" height="7%" style="margin: 0.5% 0% 0% 30%">
|
<img id="browserlogo" src="/assets/browser.png" height="7%" style="margin: 0.5% 0% 0% 30%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="noDaily" style="display: none;">
|
<div id="noDaily" style="display: none;">
|
||||||
|
@ -101,12 +101,12 @@
|
||||||
</body>
|
</body>
|
||||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/6.2.2/browser/pixi.js"></script>
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/6.2.2/browser/pixi.js"></script>
|
||||||
<script type="text/javascript" src="../iconkit/icon.js"></script>
|
<script type="text/javascript" src="/iconkit/icon.js"></script>
|
||||||
<script type="text/javascript" src="../global.js?v=1"></script>
|
<script type="text/javascript" src="/misc/global.js?v=1"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
let page = 1
|
let page = 1
|
||||||
$('#browserlogo').css('filter', `hue-rotate(${Math.floor(Math.random() * (330 - 60)) + 60}deg) saturate(${Math.floor(Math.random() * (150 - 100)) + 100}%)`)
|
$('#browserlogo').css('filter', `hue-rotate(${Math.floor(randRange(60, 330))}deg) saturate(${Math.floor(randRange(100, 150))}%)`)
|
||||||
|
|
||||||
let xButtonPos = '43%'
|
let xButtonPos = '43%'
|
||||||
let lastPage
|
let lastPage
|
||||||
|
@ -126,7 +126,7 @@ function loadCredits() {
|
||||||
$('#credits').show()
|
$('#credits').show()
|
||||||
if (page == lastPage) $('#closeCredits').css('height', '52%')
|
if (page == lastPage) $('#closeCredits').css('height', '52%')
|
||||||
else $('#closeCredits').css('height', xButtonPos)
|
else $('#closeCredits').css('height', xButtonPos)
|
||||||
$('.creditsIcon:not(".creditLoaded"):visible').each(async function() { // only load icons when necessary
|
$('.creditsIcon:not(".creditLoaded"):visible').each(async function() { // only load icons when necessary
|
||||||
$(this).addClass('creditLoaded')
|
$(this).addClass('creditLoaded')
|
||||||
let profile = await Fetch(`./api/profile/${$(this).attr('ign')}?forceGD=1`).catch(e => {}) || {}
|
let profile = await Fetch(`./api/profile/${$(this).attr('ign')}?forceGD=1`).catch(e => {}) || {}
|
||||||
$(this).append(`<gdicon cacheID=${profile.playerID} iconID=${profile.icon} col1="${profile.col1}" col2="${profile.col2}" glow="${profile.glow}"></gdicon>`)
|
$(this).append(`<gdicon cacheID=${profile.playerID} iconID=${profile.icon} col1="${profile.col1}" col2="${profile.col2}" glow="${profile.glow}"></gdicon>`)
|
||||||
|
@ -140,19 +140,19 @@ Fetch(`./api/credits`).then(async res => {
|
||||||
lastPage = res.credits.length + 1
|
lastPage = res.credits.length + 1
|
||||||
res.credits.forEach(async (x, y) => {
|
res.credits.forEach(async (x, y) => {
|
||||||
$('#credits').append(`<div id="credits${y+1}" class="subCredits" style="display: none;">
|
$('#credits').append(`<div id="credits${y+1}" class="subCredits" style="display: none;">
|
||||||
<img class="gdButton" src="../assets/arrow-left.png" style="${y == 0 ? "display: none; " : ""}position: absolute; top: 45%; right: 75%; width: 4.5%" tabindex="0" onclick="page -= 1; loadCredits()">
|
<img class="gdButton" src="/assets/arrow-left.png" style="${y == 0 ? "display: none; " : ""}position: absolute; top: 45%; right: 75%; width: 4.5%" tabindex="0" onclick="page -= 1; loadCredits()">
|
||||||
<div class="brownBox center supercenter" style="width: 80vh; height: 43%; padding-top: 1.5%; padding-bottom: 3.5%;">
|
<div class="brownBox center supercenter" style="width: 80vh; height: 43%; padding-top: 1.5%; padding-bottom: 3.5%;">
|
||||||
<h1>${x.header}</h1>
|
<h1>${x.header}</h1>
|
||||||
<h2 style="margin-bottom: 1.5%; margin-top: 1.5%" class="gdButton biggerShadow"><a href="https://gdbrowser.com/u/${x.ign || x.name}" title=${x.name}>${x.name}</h2></a>
|
<h2 style="margin-bottom: 1.5%; margin-top: 1.5%" class="gdButton biggerShadow"><a href="https://gdbrowser.com/u/${x.ign || x.name}" title=${x.name}>${x.name}</h2></a>
|
||||||
|
|
||||||
<div class="creditsIcon" ign="${x.ign || x.name}"></div>
|
<div class="creditsIcon" ign="${x.ign || x.name}"></div>
|
||||||
|
|
||||||
<a target=_blank href="${x.youtube[0]}" title="YouTube"><img src="../assets/${x.youtube[1]}.png" width="11%" class="gdButton"></a>
|
<a target=_blank href="${x.youtube[0]}" title="YouTube"><img src="/assets/${x.youtube[1]}.png" width="11%" class="gdButton"></a>
|
||||||
<a target=_blank href="${x.twitter[0]}" title="Twitter"><img src="../assets/${x.twitter[1]}.png" width="11%" class="sideSpace gdButton"></a>
|
<a target=_blank href="${x.twitter[0]}" title="Twitter"><img src="/assets/${x.twitter[1]}.png" width="11%" class="sideSpace gdButton"></a>
|
||||||
<a target=_blank href="${x.github[0]}" title="GitHub"><img src="../assets/${x.github[1]}.png" width="11%" class="sideSpace gdButton"></a>
|
<a target=_blank href="${x.github[0]}" title="GitHub"><img src="/assets/${x.github[1]}.png" width="11%" class="sideSpace gdButton"></a>
|
||||||
<br>
|
<br>
|
||||||
</div>
|
</div>
|
||||||
<img class="gdButton" src="../assets/arrow-right.png" style="position: absolute; top: 45%; left: 75%; width: 4.5%" tabindex="0" onclick="page += 1; loadCredits()">
|
<img class="gdButton" src="/assets/arrow-right.png" style="position: absolute; top: 45%; left: 75%; width: 4.5%" tabindex="0" onclick="page += 1; loadCredits()">
|
||||||
</div>`)
|
</div>`)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ Fetch(`./api/credits`).then(async res => {
|
||||||
<div id="specialthanks" class="brownBox center supercenter" style="width: 80vh; height: 55%; padding-top: 1.5%; padding-bottom: 3.5%;">
|
<div id="specialthanks" class="brownBox center supercenter" style="width: 80vh; height: 55%; padding-top: 1.5%; padding-bottom: 3.5%;">
|
||||||
<h1>Special Thanks!</h1><br>
|
<h1>Special Thanks!</h1><br>
|
||||||
</div>
|
</div>
|
||||||
<img class="gdButton" src="../assets/arrow-left.png" style="position: absolute; top: 45%; right: 75%; width: 4.5%" tabindex="0" onclick="page -= 1; loadCredits()">
|
<img class="gdButton" src="/assets/arrow-left.png" style="position: absolute; top: 45%; right: 75%; width: 4.5%" tabindex="0" onclick="page -= 1; loadCredits()">
|
||||||
</div>`)
|
</div>`)
|
||||||
|
|
||||||
res.specialThanks.forEach(async (x, y) => {
|
res.specialThanks.forEach(async (x, y) => {
|
||||||
|
@ -173,7 +173,7 @@ Fetch(`./api/credits`).then(async res => {
|
||||||
|
|
||||||
|
|
||||||
$('#credits').append(`<div id="closeCredits" class="center supercenter" style="z-index: 10; width: 80vh; height: ${xButtonPos}%; pointer-events: none;">
|
$('#credits').append(`<div id="closeCredits" class="center supercenter" style="z-index: 10; width: 80vh; height: ${xButtonPos}%; pointer-events: none;">
|
||||||
<img class="closeWindow gdButton" src="../assets/close.png" width="14%" style="position: absolute; top: -24%; left: -7vh; pointer-events: all;" tabindex="0" onclick="$('#credits').hide(); page = 1;" title="Close"></div>`)
|
<img class="closeWindow gdButton" src="/assets/close.png" width="14%" style="position: absolute; top: -24%; left: -7vh; pointer-events: all;" tabindex="0" onclick="$('#credits').hide(); page = 1;" title="Close"></div>`)
|
||||||
|
|
||||||
$(document).keydown(function(k) {
|
$(document).keydown(function(k) {
|
||||||
|
|
||||||
|
@ -182,11 +182,11 @@ Fetch(`./api/credits`).then(async res => {
|
||||||
if (k.which == 37 && page > 1) { //left
|
if (k.which == 37 && page > 1) { //left
|
||||||
page -= 1; loadCredits();
|
page -= 1; loadCredits();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (k.which == 39 && page < lastPage) { //right
|
if (k.which == 39 && page < lastPage) { //right
|
||||||
page += 1; loadCredits();
|
page += 1; loadCredits();
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
<head>
|
<head>
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
||||||
<title>Online Icon Kit</title>
|
<title>Online Icon Kit</title>
|
||||||
<link href="../assets/css/iconkit.css?v=3" type="text/css" rel="stylesheet">
|
<link href="/assets/css/iconkit.css?v=3" type="text/css" rel="stylesheet">
|
||||||
<meta name="viewport" content="width=1024">
|
<meta name="viewport" content="width=1024">
|
||||||
<meta property="og:description" content="Build and save your very own Geometry Dash icons, right from the internet!">
|
<meta property="og:description" content="Build and save your very own Geometry Dash icons, right from the internet!">
|
||||||
<meta property="og:title" content="Geometry Dash Online Icon Kit">
|
<meta property="og:title" content="Geometry Dash Online Icon Kit">
|
||||||
<meta property="og:type" content="website">
|
<meta property="og:type" content="website">
|
||||||
<meta name="og:image" itemprop="image" content="https://gdbrowser.com/assets/icon.png">
|
<meta name="og:image" itemprop="image" content="https://gdbrowser.com/assets/icon.png">
|
||||||
<meta name="theme-color" content="#CCFF55">
|
<meta name="theme-color" content="#CF5">
|
||||||
<meta name="twitter:card" content="summary">
|
<meta name="twitter:card" content="summary">
|
||||||
<link rel="icon" href="../assets/icon.png">
|
<link rel="icon" href="/assets/icon.png">
|
||||||
</link>
|
</link>
|
||||||
</head>
|
</head>
|
||||||
<body style="background: linear-gradient(rgb(139, 139, 139), rgb(100, 100, 100)) no-repeat center center fixed;" onbeforeunload="sessionStorage.setItem('prevUrl', window.location.href)">
|
<body style="background: linear-gradient(rgb(139, 139, 139), rgb(100, 100, 100)) no-repeat center center fixed;" onbeforeunload="sessionStorage.setItem('prevUrl', window.location.href)">
|
||||||
|
@ -21,11 +21,11 @@
|
||||||
<p id="copyFrom" class="white" style="font-size: 24px; margin: 10px auto 5px auto"></p>
|
<p id="copyFrom" class="white" style="font-size: 24px; margin: 10px auto 5px auto"></p>
|
||||||
<input type="text" name="gdbrowser" id="playerName" autocomplete="off" placeholder="Username" maxlength="32" style="height: 58px; width: 90%; text-align: center; margin-top: 25px; margin-bottom: 10px;">
|
<input type="text" name="gdbrowser" id="playerName" autocomplete="off" placeholder="Username" maxlength="32" style="height: 58px; width: 90%; text-align: center; margin-top: 25px; margin-bottom: 10px;">
|
||||||
<div id="copyForms"></div>
|
<div id="copyForms"></div>
|
||||||
<img src="../assets/ok.png" height=55px; class="postButton gdButton center" style="margin-top: 30px" id="fetchUser">
|
<img src="/assets/ok.png" height=55px; class="postButton gdButton center" style="margin-top: 30px" id="fetchUser">
|
||||||
<img class="gdButton xButton" src="../assets/close.png" width="70px" onclick="$('#steal').hide()">
|
<img class="gdButton xButton" src="/assets/close.png" width="70px" onclick="$('#steal').hide()">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="popup" data-nosnippet id="settings">
|
<div class="popup" data-nosnippet id="settings">
|
||||||
<div class="brownbox bounce center supercenter" style="height: 380px; width: 820px">
|
<div class="brownbox bounce center supercenter" style="height: 380px; width: 820px">
|
||||||
<h1 class="center gold" style="margin-top: 10px; margin-bottom: 20px;">Settings</h1>
|
<h1 class="center gold" style="margin-top: 10px; margin-bottom: 20px;">Settings</h1>
|
||||||
|
@ -33,10 +33,10 @@
|
||||||
<div class="help" help="Removes the clear dome on top of UFOs"><input type="checkbox" class="iconsetting" id="box-ufo"><label for="box-ufo" class="gdcheckbox gdButton"></label><h2>No UFO Dome</h2></div>
|
<div class="help" help="Removes the clear dome on top of UFOs"><input type="checkbox" class="iconsetting" id="box-ufo"><label for="box-ufo" class="gdcheckbox gdButton"></label><h2>No UFO Dome</h2></div>
|
||||||
<div class="help" help="Sorts the colors by internal ID instead of their in-game order"><input type="checkbox" class="iconsetting" id="box-sort"><label for="box-sort" class="gdcheckbox gdButton"></label><h2>Unsort Colors</h2></div>
|
<div class="help" help="Sorts the colors by internal ID instead of their in-game order"><input type="checkbox" class="iconsetting" id="box-sort"><label for="box-sort" class="gdcheckbox gdButton"></label><h2>Unsort Colors</h2></div>
|
||||||
<div class="help" help="Allows robots to play spider animations and vice versa"><input type="checkbox" class="iconsetting" id="box-cursed"><label for="box-cursed" class="gdcheckbox gdButton"></label><h2>Cursed animations</h2></div>
|
<div class="help" help="Allows robots to play spider animations and vice versa"><input type="checkbox" class="iconsetting" id="box-cursed"><label for="box-cursed" class="gdcheckbox gdButton"></label><h2>Cursed animations</h2></div>
|
||||||
</div>
|
</div>
|
||||||
<p class="white" id="helpText" style="font-size: 24px; margin-bottom: 0;">(Hover over a setting for information)</p>
|
<p class="white" id="helpText" style="font-size: 24px; margin-bottom: 0;">(Hover over a setting for information)</p>
|
||||||
<img src="../assets/ok.png" height=55px; class="postButton gdButton center" style="margin-top: 30px" onclick="$('#settings').hide()">
|
<img src="/assets/ok.png" height=55px; class="postButton gdButton center" style="margin-top: 30px" onclick="$('#settings').hide()">
|
||||||
<img class="gdButton xButton" src="../assets/close.png" width="70px" onclick="$('#settings').hide()">
|
<img class="gdButton xButton" src="/assets/close.png" width="70px" onclick="$('#settings').hide()">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -45,14 +45,14 @@
|
||||||
<h1 class="center gold" style="margin-top: 12px">Enable 2.2 icons?</h1>
|
<h1 class="center gold" style="margin-top: 12px">Enable 2.2 icons?</h1>
|
||||||
<p style="font-size: 26px; color: white; width: 620px; margin: 17px auto">The newest update for Geometry Dash Lite revealed 500 new icons across all forms. Enabling this setting will reveal all these icons, however they will be lower quality since no UHD textures were provided.</p>
|
<p style="font-size: 26px; color: white; width: 620px; margin: 17px auto">The newest update for Geometry Dash Lite revealed 500 new icons across all forms. Enabling this setting will reveal all these icons, however they will be lower quality since no UHD textures were provided.</p>
|
||||||
<p style="font-size: 30px; color: yellow">THIS WILL REVEAL <u>EVERY</u> ICON.<br>PRESS CANCEL IF YOU DON'T WANT TO BE SPOILED!!!</p>
|
<p style="font-size: 30px; color: yellow">THIS WILL REVEAL <u>EVERY</u> ICON.<br>PRESS CANCEL IF YOU DON'T WANT TO BE SPOILED!!!</p>
|
||||||
<img src="../assets/iconkitbuttons/btn-reveal.png" height=60px; style="margin-right: 33px" class="gdButton center" onclick="clickedSpoilerWarning = true; toggleSpoilers(); $('#spoilerwarning').hide()">
|
<img src="/assets/iconkitbuttons/btn-reveal.png" height=60px; style="margin-right: 33px" class="gdButton center" onclick="clickedSpoilerWarning = true; toggleSpoilers(); $('#spoilerwarning').hide()">
|
||||||
<img src="../assets/btn-cancel.png" height=60px; class="gdButton center" onclick="$('#spoilerwarning').hide()">
|
<img src="/assets/btn-cancel.png" height=60px; class="gdButton center" onclick="$('#spoilerwarning').hide()">
|
||||||
<img class="gdButton xButton" src="../assets/close.png" width="70px" onclick="$('#spoilerwarning').hide()">
|
<img class="gdButton xButton" src="/assets/close.png" width="70px" onclick="$('#spoilerwarning').hide()">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<img id="iconkitlogo" src="../assets/iconkit.png" style="margin: 7px 0px; height: 50px"><br>
|
<img id="iconkitlogo" src="/assets/iconkit.png" style="margin: 7px 0px; height: 50px"><br>
|
||||||
<h2 style="margin: 5 auto 0 auto; display: none; height: 45px" id="howto"><span style='color: #aaaaaa'>(hover over an icon for info)</span></h2>
|
<h2 style="margin: 5 auto 0 auto; display: none; height: 45px" id="howto"><span style='color: #aaa'>(hover over an icon for info)</span></h2>
|
||||||
|
|
||||||
<div id="iconbox">
|
<div id="iconbox">
|
||||||
<canvas id="result" style="transform: translateY(-35px)">
|
<canvas id="result" style="transform: translateY(-35px)">
|
||||||
|
@ -60,14 +60,14 @@
|
||||||
|
|
||||||
<hr id="gdfloor">
|
<hr id="gdfloor">
|
||||||
<div id="menuButtons" style="height: 65px; margin: 0 0 8 0;">
|
<div id="menuButtons" style="height: 65px; margin: 0 0 8 0;">
|
||||||
<button class="blankButton menuButton" id="customColors" title="Settings" onclick="$('#settings').show()"><img src="../assets/iconkitbuttons/cog.png" width=60px></button>
|
<button class="blankButton menuButton" id="customColors" title="Settings" onclick="$('#settings').show()"><img src="/assets/iconkitbuttons/cog.png" width=60px></button>
|
||||||
<button class="blankButton menuButton" onclick="icon.psdExport()" title="Download layered PSD"><img src="../assets/iconkitbuttons/psd.png" width=60px></button>
|
<button class="blankButton menuButton" onclick="icon.psdExport()" title="Download layered PSD"><img src="/assets/iconkitbuttons/psd.png" width=60px></button>
|
||||||
<button class="blankButton menuButton" id="copyToClipboard" title="Copy to clipboard"><img src="../assets/iconkitbuttons/copy.png" width=60px></button>
|
<button class="blankButton menuButton" id="copyToClipboard" title="Copy to clipboard"><img src="/assets/iconkitbuttons/copy.png" width=60px></button>
|
||||||
<button class="blankButton menuButton" onclick="icon.pngExport()" title="Download icon"><img src="../assets/iconkitbuttons/save.png" width=60px></a></button>
|
<button class="blankButton menuButton" onclick="icon.pngExport()" title="Download icon"><img src="/assets/iconkitbuttons/save.png" width=60px></a></button>
|
||||||
<button class="blankButton menuButton" id="getUserIcon" title="Get player icon"><img src="../assets/iconkitbuttons/steal.png" width=60px></button>
|
<button class="blankButton menuButton" id="getUserIcon" title="Get player icon"><img src="/assets/iconkitbuttons/steal.png" width=60px></button>
|
||||||
<button class="blankButton menuButton" id="randomIcon" title="Random Icon"><img src="../assets/iconkitbuttons/shuffle.png" width=60px></button>
|
<button class="blankButton menuButton" id="randomIcon" title="Random Icon"><img src="/assets/iconkitbuttons/shuffle.png" width=60px></button>
|
||||||
<button class="blankButton menuButton" id="unlockIcon" title="Unlock details"><img id="lock" src="../assets/iconkitbuttons/unlock.png" width=60px></button>
|
<button class="blankButton menuButton" id="unlockIcon" title="Unlock details"><img id="lock" src="/assets/iconkitbuttons/unlock.png" width=60px></button>
|
||||||
<button class="blankButton menuButton" onclick="clickedSpoilerWarning ? toggleSpoilers() : $('#spoilerwarning').show()" title="2.2 icons (spoilers!!!)"><img id="newIconBtn" src="../assets/iconkitbuttons/spoilers.png" width=60px></button>
|
<button class="blankButton menuButton" onclick="clickedSpoilerWarning ? toggleSpoilers() : $('#spoilerwarning').show()" title="2.2 icons (spoilers!!!)"><img id="newIconBtn" src="/assets/iconkitbuttons/spoilers.png" width=60px></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="iconTabs"></div><br>
|
<div id="iconTabs"></div><br>
|
||||||
|
@ -79,12 +79,12 @@
|
||||||
|
|
||||||
<div style="width: 1200px; margin: 0 auto; position: relative; right: 42px">
|
<div style="width: 1200px; margin: 0 auto; position: relative; right: 42px">
|
||||||
<div style="padding-top: 15px; width: 75px; vertical-align: top;" class="colTypes inline">
|
<div style="padding-top: 15px; width: 75px; vertical-align: top;" class="colTypes inline">
|
||||||
<button id="cc1" class="colorLabel blankButton" onclick="$('#cp1').trigger('click')" title="Primary Color"><img src="../assets/col1.png"></button><input type="color" id="cp1" class="colorPicker">
|
<button id="cc1" class="colorLabel blankButton" onclick="$('#cp1').trigger('click')" title="Primary Color"><img src="/assets/col1.png"></button><input type="color" id="cp1" class="colorPicker">
|
||||||
<button id="cc2" class="colorLabel blankButton" onclick="$('#cp2').trigger('click')" title="Secondary Color"><img src="../assets/col2.png"></button><input type="color" id="cp2" class="colorPicker">
|
<button id="cc2" class="colorLabel blankButton" onclick="$('#cp2').trigger('click')" title="Secondary Color"><img src="/assets/col2.png"></button><input type="color" id="cp2" class="colorPicker">
|
||||||
<div class="colorSplit" style="height: 12.5px"></div>
|
<div class="colorSplit" style="height: 12.5px"></div>
|
||||||
<button id="ccG" class="colorLabel blankButton" onclick="$('#cpG').trigger('click')" title="Glow Color"><img src="../assets/colG.png"></button><input type="color" id="cpG" class="colorPicker">
|
<button id="ccG" class="colorLabel blankButton" onclick="$('#cpG').trigger('click')" title="Glow Color"><img src="/assets/colG.png"></button><input type="color" id="cpG" class="colorPicker">
|
||||||
<button id="ccW" class="colorLabel blankButton" onclick="$('#cpW').trigger('click')" title="White Highlights" style="display: none"><img src="../assets/colW.png" style="background-color: rgb(255, 255, 255)";></button><input type="color" id="cpW" class="colorPicker">
|
<button id="ccW" class="colorLabel blankButton" onclick="$('#cpW').trigger('click')" title="White Highlights" style="display: none"><img src="/assets/colW.png" style="background-color: rgb(255, 255, 255)";></button><input type="color" id="cpW" class="colorPicker">
|
||||||
<button id="ccU" class="colorLabel blankButton" onclick="$('#cpU').trigger('click')" title="UFO Dome" style="display: none"><img src="../assets/colU.png" style="background-color: rgb(255, 255, 255)";></button><input type="color" id="cpU" class="colorPicker">
|
<button id="ccU" class="colorLabel blankButton" onclick="$('#cpU').trigger('click')" title="UFO Dome" style="display: none"><img src="/assets/colU.png" style="background-color: rgb(255, 255, 255)";></button><input type="color" id="cpU" class="colorPicker">
|
||||||
</div>
|
</div>
|
||||||
<div id="colors" class="inline iconKit">
|
<div id="colors" class="inline iconKit">
|
||||||
<div id="col1"></div>
|
<div id="col1"></div>
|
||||||
|
@ -116,27 +116,32 @@
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="hideIfSmall" style="position:absolute; top: 20px; left: 20px; width: 64px; height: 64px; pointer-events: none">
|
<div class="hideIfSmall" style="position:absolute; top: 20px; left: 20px; width: 64px; height: 64px; pointer-events: none">
|
||||||
<img class="gdButton" style="pointer-events: all" id="backButton" src="../assets/back.png" height="100%" onclick="backButton()">
|
<img class="gdButton" style="pointer-events: all" id="backButton" src="/assets/back.png" height="100%" onclick="backButton()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="hideIfSmall" id="extraInfo" style="position:absolute; top: 20px; right: 15px"></div>
|
<div class="hideIfSmall" id="extraInfo" style="position:absolute; top: 20px; right: 15px"></div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
|
||||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/6.2.2/browser/pixi.js"></script>
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/6.2.2/browser/pixi.min.js"></script>
|
||||||
<script type="text/javascript" src="./libs/ag-psd.js"></script>
|
<script type="text/javascript" src="./libs/ag-psd.js"></script>
|
||||||
<script type="text/javascript" src="./libs/pixi-ease.js"></script>
|
<script type="text/javascript" src="./libs/pixi-ease.js"></script>
|
||||||
<script type="text/javascript" src="./libs/imagesloaded.js"></script>
|
<script type="text/javascript" src="./libs/imagesloaded.js"></script>
|
||||||
<script type="text/javascript" src="./icon.js"></script>
|
<script type="text/javascript" src="./icon.js"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
"use strict";
|
||||||
|
// these 3 fns are available in `global.js`
|
||||||
|
const clamp = (x, min, max) => x < min ? min : (x > max ? max : x)
|
||||||
|
const randRange = (min, max) => Math.random() * (max - min) + +min
|
||||||
|
const randInt = (min, max) => Math.floor(randRange(min, max))
|
||||||
|
|
||||||
// hi there hello! this code is really old, so it's shit. i should rewrite it some time omg
|
// hi there hello! this code is really old, so it's shit. i should rewrite it some time omg
|
||||||
|
|
||||||
$('.hidden').show();
|
$('.hidden').show()
|
||||||
|
// avoid possible name collision with isMobile.js (AJAX Node module)
|
||||||
let mobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)
|
let is_mobile = /Android|webOS|iPhone|iP[ao]d|BlackBerry/i.test(navigator.userAgent)
|
||||||
let currentForm = 'icon'
|
let currentForm = 'icon'
|
||||||
let glowbtnformCopy = 'icon'
|
let glowbtnformCopy = 'icon'
|
||||||
const yOffsets = { ball: -10, ufo: 30, spider: 7, swing: -15 }
|
const yOffsets = { ball: -10, ufo: 30, spider: 7, swing: -15 }
|
||||||
|
@ -149,7 +154,7 @@ let selectedCol2 = 3
|
||||||
let selectedColG = 3
|
let selectedColG = 3
|
||||||
let selectedColW = null
|
let selectedColW = null
|
||||||
let selectedColU = null
|
let selectedColU = null
|
||||||
let enableGlow = 0
|
let enableGlow = false
|
||||||
|
|
||||||
let enableSpoilers = false
|
let enableSpoilers = false
|
||||||
let clickedSpoilerWarning = false
|
let clickedSpoilerWarning = false
|
||||||
|
@ -164,25 +169,28 @@ let animationMultiplier = 1
|
||||||
|
|
||||||
let icon = null
|
let icon = null
|
||||||
|
|
||||||
let iconCanvas = document.getElementById('result');
|
let iconCanvas = document.getElementById('result')
|
||||||
let app = new PIXI.Application({ view: iconCanvas, width: 300, height: 300, backgroundAlpha: 0 });
|
let app = new PIXI.Application({ view: iconCanvas, width: 300, height: 300, backgroundAlpha: 0 })
|
||||||
|
|
||||||
if (mobile) $('#logo').attr('width', '80%');
|
if (is_mobile) $('#logo').attr('width', '80%')
|
||||||
|
|
||||||
let iconSettings = (localStorage.iconkit || "").split(",")
|
let iconSettings = (localStorage.iconkit || "").split(",")
|
||||||
iconSettings.forEach(x => {
|
iconSettings.forEach(x => {
|
||||||
$(`#box-${x}`).prop('checked', true)
|
$(`#box-${x}`).prop('checked', true)
|
||||||
})
|
})
|
||||||
|
|
||||||
function capitalize(str) { return str[0].toUpperCase() + str.substr(1) }
|
let capitalize = str => str[0].toUpperCase() + str.substr(1)
|
||||||
function randInt(min, max) { return Math.floor(Math.random() * (max - min + 1) ) + min }
|
function colorBG(e, c, hex) {
|
||||||
function colorBG(e, c, hex) {
|
|
||||||
$(`#cc${e} img`).css('background-color', hex ? `#${c}` : `rgb(${c.r}, ${c.g}, ${c.b})`)
|
$(`#cc${e} img`).css('background-color', hex ? `#${c}` : `rgb(${c.r}, ${c.g}, ${c.b})`)
|
||||||
if (!hex) $(`#cp${e}`).val(toHexCode(rgbToDecimal(c.r, c.g, c.b)))
|
if (!hex) $(`#cp${e}`).val(toHexCode(rgb2Pac(c.r, c.g, c.b)))
|
||||||
}
|
}
|
||||||
function colorSplit() {
|
function colorSplit() {
|
||||||
if ($("#colG").is(':visible') || $("#colW").is(':visible') || $("#colU").is(':visible')) $('.colorSplit').show()
|
$('.colorSplit')[
|
||||||
else $('.colorSplit').hide()
|
$("#colG").is(':visible') ||
|
||||||
|
$("#colW").is(':visible') ||
|
||||||
|
$("#colU").is(':visible')
|
||||||
|
? "show" : "hide"
|
||||||
|
]()
|
||||||
}
|
}
|
||||||
|
|
||||||
function setColor(type, col) {
|
function setColor(type, col) {
|
||||||
|
@ -215,10 +223,9 @@ function checkWhite() {
|
||||||
// check if animation selector should be visible
|
// check if animation selector should be visible
|
||||||
function checkAnimation() {
|
function checkAnimation() {
|
||||||
let animationData = iconData.robotAnimations.animations[selectedForm]
|
let animationData = iconData.robotAnimations.animations[selectedForm]
|
||||||
if (animationData && !$(`#robotAnimation[form="${selectedForm}"]`).is(":visible")) {
|
if (animationData && !$(`#robotAnimation[form="${selectedForm}"]`).is(":visible"))
|
||||||
appendAnimations(selectedForm, animationData)
|
appendAnimations(selectedForm, animationData)
|
||||||
}
|
if (!animationData) $('#animationOptions').hide()
|
||||||
else if (!animationData) $('#animationOptions').hide()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function animationSort(anim) {
|
function animationSort(anim) {
|
||||||
|
@ -249,8 +256,8 @@ function setExtras() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($('#colG').is(":visible") && (getCol(selectedColG) != getCol(selectedCol2))) extraInfo["Glow"] = extraColString(selectedColG)
|
if ($('#colG').is(":visible") && (getCol(selectedColG) != getCol(selectedCol2))) extraInfo["Glow"] = extraColString(selectedColG)
|
||||||
if ($('#colW').is(":visible") && (getCol(selectedColW) != 0xffffff)) extraInfo["White"] = extraColString(selectedColW)
|
if ($('#colW').is(":visible") && (getCol(selectedColW) != WHITE)) extraInfo["White"] = extraColString(selectedColW)
|
||||||
if ($('#colU').is(":visible") && (getCol(selectedColU) != 0xffffff)) extraInfo["UFO Dome"] = extraColString(selectedColU)
|
if ($('#colU').is(":visible") && (getCol(selectedColU) != WHITE)) extraInfo["UFO Dome"] = extraColString(selectedColU)
|
||||||
|
|
||||||
let foundCredit = iconStuff.iconCredits.find(x => x.form == selectedForm && x.id == selectedIcon)
|
let foundCredit = iconStuff.iconCredits.find(x => x.form == selectedForm && x.id == selectedIcon)
|
||||||
if (foundCredit) extraInfo["🎨 Artist"] = foundCredit.name
|
if (foundCredit) extraInfo["🎨 Artist"] = foundCredit.name
|
||||||
|
@ -265,8 +272,8 @@ function setExtras() {
|
||||||
|
|
||||||
function extraColString(col) {
|
function extraColString(col) {
|
||||||
let realCol = getCol(col)
|
let realCol = getCol(col)
|
||||||
let hexCol = toHexCode(realCol)
|
let hexCol = toHexCode(realCol)
|
||||||
let foundGDCol = Object.entries(iconStuff.colors).find(x => rgbToDecimal(x[1]) == realCol)
|
let foundGDCol = Object.entries(iconStuff.colors).find(x => rgb2Pac(x[1]) == realCol)
|
||||||
return foundGDCol ? `${foundGDCol[0]} (${hexCol})` : hexCol
|
return foundGDCol ? `${foundGDCol[0]} (${hexCol})` : hexCol
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,194 +281,198 @@ function getCol(id) {
|
||||||
return parseIconColor(id, iconStuff.colors)
|
return parseIconColor(id, iconStuff.colors)
|
||||||
}
|
}
|
||||||
|
|
||||||
function toHexCode(decimal) {
|
function toHexCode(pack) {
|
||||||
return "#" + decimal.toString(16).padStart(6, "0")
|
return "#" + pack.toString(16).padStart(6, "0")
|
||||||
}
|
}
|
||||||
|
|
||||||
let iconData = null
|
let iconData = null
|
||||||
fetch('../api/icons').then(res => res.json()).then(sacredTexts => {
|
fetch('/api/icons').then(res => res.json()).then(sacredTexts => {
|
||||||
fetch('../api/iconkit').then(res => res.json()).then(iconKitData => {
|
fetch('/api/iconkit').then(res => res.json()).then(iconKitData => {
|
||||||
|
|
||||||
iconStuff = Object.assign(sacredTexts, iconKitData)
|
iconStuff = Object.assign(sacredTexts, iconKitData)
|
||||||
iconData = sacredTexts
|
iconData = sacredTexts
|
||||||
|
|
||||||
let forms = Object.keys(iconStuff.forms)
|
let forms = Object.keys(iconStuff.forms)
|
||||||
|
|
||||||
forms.forEach(form => {
|
forms.forEach(form => {
|
||||||
let spoil = ["swing", "jetpack"].includes(form)
|
let spoil = ["swing", "jetpack"].includes(form)
|
||||||
$("#iconTabs").append(`<button form="${form}"${spoil ? `isnew="true" style="display: none"` : ""} title="${iconStuff.forms[form].name}" class="blankButton iconTabButton"><img src="../assets/iconkitbuttons/${form}_off.png" style="width: 50px"></button>`)
|
$("#iconTabs").append(`<button form="${form}"${spoil ? `isnew="true" style="display: none"` : ""} title="${iconStuff.forms[form].name}" class="blankButton iconTabButton"><img src="/assets/iconkitbuttons/${form}_off.png" style="width: 50px"></button>`)
|
||||||
$("#copyForms").append(`<button form="${form}"${spoil ? `isnew="true" style="display: none"` : ""} title="${iconStuff.forms[form].name}" class="blankButton copyForm"><img src="../assets/iconkitbuttons/${form}_off.png" style="width: 50px"></button>`)
|
$("#copyForms").append(`<button form="${form}"${spoil ? `isnew="true" style="display: none"` : ""} title="${iconStuff.forms[form].name}" class="blankButton copyForm"><img src="/assets/iconkitbuttons/${form}_off.png" style="width: 50px"></button>`)
|
||||||
})
|
})
|
||||||
$("#iconTabs").append(`<button title="Glow" class="blankButton glowToggle" id="glowbtn"><img id="glow" src="../assets/iconkitbuttons/streak_off.png" style="width: 50px"></button>`)
|
$("#iconTabs").append(`<button title="Glow" class="blankButton glowToggle" id="glowbtn"><img id="glow" src="/assets/iconkitbuttons/streak_off.png" style="width: 50px"></button>`)
|
||||||
|
|
||||||
forms.forEach(form => {$("#iconKitParent").append(`<div id="${form}s" class="iconContainer"></div>`)})
|
forms.forEach(form => {$("#iconKitParent").append(`<div id="${form}s" class="iconContainer"></div>`)})
|
||||||
|
|
||||||
if (iconStuff.noCopy) $('#getUserIcon').remove()
|
if (iconStuff.noCopy) $('#getUserIcon').remove()
|
||||||
else if (iconStuff.server) {
|
else if (iconStuff.server) {
|
||||||
$('#copyFrom').html(`Copying from the <cy>${iconStuff.server}</cy> servers`)
|
$('#copyFrom').html(`Copying from the <cy>${iconStuff.server}</cy> servers`)
|
||||||
$('#stealBox').css('height', '385px')
|
$('#stealBox').css('height', '385px')
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateIcon(cb) {
|
function generateIcon(cb) {
|
||||||
let noDome = selectedForm == "ufo" && iconSettings.includes("ufo")
|
//let noDome = selectedForm == "ufo" && iconSettings.includes("ufo")
|
||||||
let foundForm = parseIconForm(selectedForm)
|
let foundForm = parseIconForm(selectedForm)
|
||||||
|
|
||||||
loadIconLayers(foundForm, selectedIcon, function(l, sprites, isNew) {
|
loadIconLayers(foundForm, selectedIcon, function(l, sprites, isNew) {
|
||||||
let iconArgs = {app, form: foundForm, id: selectedIcon, col1: getCol(selectedCol1), col2: getCol(selectedCol2), glow: enableGlow > 0, new: isNew}
|
let iconArgs = {app, form: foundForm, id: selectedIcon, col1: getCol(selectedCol1), col2: getCol(selectedCol2), glow: enableGlow, new: isNew}
|
||||||
if (selectedCol2 != selectedColG) iconArgs.colG = getCol(selectedColG)
|
if (selectedCol2 != selectedColG) iconArgs.colG = getCol(selectedColG)
|
||||||
if (selectedColW) iconArgs.colW = getCol(selectedColW)
|
if (selectedColW) iconArgs.colW = getCol(selectedColW)
|
||||||
if (selectedColU) iconArgs.colU = getCol(selectedColU)
|
if (selectedColU) iconArgs.colU = getCol(selectedColU)
|
||||||
if (iconSettings.includes("ufo")) iconArgs.noUFODome = true
|
if (iconSettings.includes("ufo")) iconArgs.noUFODome = true
|
||||||
if (animationMultiplier != 1) iconArgs.animationSpeed = animationMultiplier
|
if (animationMultiplier != 1) iconArgs.animationSpeed = animationMultiplier
|
||||||
if (currentAnimation.form && (iconSettings.includes("cursed") || currentAnimation.form == selectedForm)) {
|
if (currentAnimation.form && (iconSettings.includes("cursed") || currentAnimation.form == selectedForm)) {
|
||||||
iconArgs.animation = currentAnimation.name
|
iconArgs.animation = currentAnimation.name
|
||||||
iconArgs.animationForm = currentAnimation.form
|
iconArgs.animationForm = currentAnimation.form
|
||||||
}
|
|
||||||
|
|
||||||
icon = new Icon(iconArgs)
|
|
||||||
icon.sprite.position.set(app.renderer.width / 2, (app.renderer.height / 2) + (yOffsets[selectedForm] || 0))
|
|
||||||
updateDetails()
|
|
||||||
checkWhite()
|
|
||||||
|
|
||||||
if (cb) cb()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function filterIcon(name) {
|
|
||||||
return iconStuff.previewIcons.concat(iconStuff.newPreviewIcons).filter(x => x.startsWith(name)).sort(function (a,b) {return a.replace(/[^0-9]/g, "") - b.replace(/[^0-9]/g, "");})
|
|
||||||
}
|
|
||||||
|
|
||||||
function appendIcon(form, formName) {
|
|
||||||
|
|
||||||
let imagesLoaded = 0
|
|
||||||
let totalLoaded = 0
|
|
||||||
let formContainer = $('#' + formName + 's')
|
|
||||||
|
|
||||||
let hasMini = form[0].endsWith("_0.png")
|
|
||||||
if (hasMini) form.shift()
|
|
||||||
|
|
||||||
form.forEach(function (i, p) {
|
|
||||||
let newOne = iconStuff.newPreviewIcons.includes(i)
|
|
||||||
formContainer.append(`<button num="${p + 1}" form="${formName}"${newOne ? ` isnew="true"${enableSpoilers ? "" : ` style="display: none"`}` : ""} class="blankButton iconButton" id="${formName}-${p + 1}"><img src="./${newOne ? "new" : ""}premade/${i}" title="${capitalize(formName)} ${p + 1}"></button>`)
|
|
||||||
})
|
|
||||||
|
|
||||||
if (hasMini) formContainer.append(`<button num="0" form="${formName}" class="blankButton iconButton" id="${formName}-0"><img src="./premade/${formName}_0.png" title="Mini ${formName}"></button>`)
|
|
||||||
|
|
||||||
formContainer.imagesLoaded(function() {}).progress(function() {
|
|
||||||
imagesLoaded += 1;
|
|
||||||
totalLoaded = imagesLoaded / formContainer.find('img').length * 100
|
|
||||||
$('#iconloading').css('width', `${totalLoaded}%`)
|
|
||||||
}
|
}
|
||||||
)}
|
|
||||||
|
|
||||||
function loadColors(devmode) {
|
icon = new Icon(iconArgs)
|
||||||
let colTypes = [1, 2, "G", "W", "U"]
|
icon.sprite.position.set(app.renderer.width / 2, (app.renderer.height / 2) + (yOffsets[selectedForm] || 0))
|
||||||
colTypes.forEach(x => $(`#col${x}`).html(""))
|
updateDetails()
|
||||||
iconStuff.colorOrder.forEach(function (p, n) {
|
checkWhite()
|
||||||
if (iconSettings.includes("sort")) p = n;
|
|
||||||
colTypes.forEach(c => {
|
if (cb) cb()
|
||||||
let colRGB = iconStuff.colors[p]
|
})
|
||||||
$(`#col${c}`).append(`<button col=${p} colType=color${c} class="blankButton color${c} iconColor" title="Color ${p} (#${toHexCode(rgbToDecimal(colRGB))})" id="col${c}-${p}"><div style="background-color: rgb(${colRGB.r}, ${colRGB.g}, ${colRGB.b})"></button>`)
|
}
|
||||||
})
|
|
||||||
|
function filterIcon(name) {
|
||||||
|
return (
|
||||||
|
iconStuff.previewIcons.concat(iconStuff.newPreviewIcons)
|
||||||
|
.filter(x => x.startsWith(name))
|
||||||
|
.sort( (a,b) => a.replace(/\D/g, "") - b.replace(/\D/g, "") )
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendIcon(form, formName) {
|
||||||
|
|
||||||
|
let imagesLoaded = 0
|
||||||
|
let totalLoaded = 0
|
||||||
|
let formContainer = $(`#${formName}s`)
|
||||||
|
|
||||||
|
let hasMini = form[0].endsWith("_0.png")
|
||||||
|
if (hasMini) form.shift()
|
||||||
|
|
||||||
|
form.forEach((i, p) => {
|
||||||
|
let newOne = iconStuff.newPreviewIcons.includes(i)
|
||||||
|
formContainer.append(`<button num="${p + 1}" form="${formName}"${newOne ? ` isnew="true"${enableSpoilers ? "" : ` style="display: none"`}` : ""} class="blankButton iconButton" id="${formName}-${p + 1}"><img src="/iconkit/${newOne ? "new" : ""}premade/${i}" title="${capitalize(formName)} ${p + 1}"></button>`)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (hasMini) formContainer.append(`<button num="0" form="${formName}" class="blankButton iconButton" id="${formName}-0"><img src="/iconkit/premade/${formName}_0.png" title="Mini ${formName}"></button>`)
|
||||||
|
|
||||||
|
formContainer.imagesLoaded(function() {}).progress(function() {
|
||||||
|
imagesLoaded++;
|
||||||
|
totalLoaded = imagesLoaded / formContainer.find('img').length * 100
|
||||||
|
$('#iconloading').css('width', `${totalLoaded}%`)
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
|
||||||
|
function loadColors(devmode) {
|
||||||
|
let colTypes = [1, 2, "G", "W", "U"]
|
||||||
|
colTypes.forEach(x => $(`#col${x}`).html(""))
|
||||||
|
iconStuff.colorOrder.forEach(function (p, n) {
|
||||||
|
if (iconSettings.includes("sort")) p = n
|
||||||
|
colTypes.forEach(c => {
|
||||||
|
let colRGB = iconStuff.colors[p]
|
||||||
|
$(`#col${c}`).append(`<button col=${p} colType=color${c} class="blankButton color${c} iconColor" title="Color ${p} (#${toHexCode(rgb2Pac(colRGB))})" id="col${c}-${p}"><div style="background-color: rgb(${colRGB.r}, ${colRGB.g}, ${colRGB.b})"></button>`)
|
||||||
})
|
})
|
||||||
$('#col1').append("<span style='min-width: 10px'></span>")
|
})
|
||||||
}
|
$('#col1').append("<span style='min-width: 10px'></span>")
|
||||||
|
}
|
||||||
|
|
||||||
loadColors()
|
loadColors()
|
||||||
let icons = filterIcon('icon');
|
let icons = filterIcon('icon')
|
||||||
|
|
||||||
let sample = JSON.parse(iconStuff.sample);
|
|
||||||
enableGlow = sample[3] * 2;
|
|
||||||
[selectedIcon, selectedCol1, selectedCol2] = sample;
|
|
||||||
selectedColG = selectedCol2
|
|
||||||
|
|
||||||
$('body').imagesLoaded(function () {
|
let sample = JSON.parse(iconStuff.sample)
|
||||||
appendIcon(icons, "icon")
|
enableGlow = !!(sample[3] * 2);
|
||||||
$(`[num="${sample[0]}"][form="icon"]`).addClass('iconSelected');
|
[eselectedIcon, selectedCol1, selectedCol2] = sample
|
||||||
|
selectedColG = selectedCol2
|
||||||
|
|
||||||
|
$('body').imagesLoaded(function () {
|
||||||
|
appendIcon(icons, "icon")
|
||||||
|
$(`[num="${sample[0]}"][form="icon"]`).addClass('iconSelected');
|
||||||
|
})
|
||||||
|
|
||||||
|
$(`.color1[col="${sample[1]}"]`).addClass('iconSelected');
|
||||||
|
$(`.color2[col="${sample[2]}"]`).addClass('iconSelected');
|
||||||
|
$(`.colorG[col="${sample[2]}"]`).addClass('iconSelected');
|
||||||
|
$('.colorW[col="12"]').addClass('iconSelected');
|
||||||
|
$('.colorU[col="12"]').addClass('iconSelected')
|
||||||
|
|
||||||
|
colorBG(1, iconStuff.colors[sample[1]])
|
||||||
|
colorBG(2, iconStuff.colors[sample[2]])
|
||||||
|
colorBG('G', iconStuff.colors[sample[2]])
|
||||||
|
|
||||||
|
$('.colorLabel img').show()
|
||||||
|
|
||||||
|
generateIcon(() => { icon.glow = enableGlow = false } ) // disable glow after first generated
|
||||||
|
|
||||||
|
$(document).on('click', '.iconTabButton', function() {
|
||||||
|
let form = $(this).attr('form')
|
||||||
|
let formElement = `#${form}s`
|
||||||
|
|
||||||
|
currentForm = form
|
||||||
|
|
||||||
|
$('.iconTabButton').each(function() {
|
||||||
|
$(this).children().first().attr('src', $(this).children().first().attr('src').replace('_on', '_off'))
|
||||||
})
|
})
|
||||||
|
|
||||||
$(`.color1[col="${sample[1]}"]`).addClass('iconSelected');
|
let img = $(this).children().first()
|
||||||
$(`.color2[col="${sample[2]}"]`).addClass('iconSelected');
|
img.attr('src', img.attr('src').replace('_off', '_on'));
|
||||||
$(`.colorG[col="${sample[2]}"]`).addClass('iconSelected');
|
|
||||||
$('.colorW[col="12"]').addClass('iconSelected');
|
|
||||||
$('.colorU[col="12"]').addClass('iconSelected');
|
|
||||||
|
|
||||||
colorBG(1, iconStuff.colors[sample[1]])
|
$('#iconKitParent').each(function() { $(this).children().not('#iconprogressbar').hide() })
|
||||||
colorBG(2, iconStuff.colors[sample[2]])
|
|
||||||
colorBG('G', iconStuff.colors[sample[2]])
|
|
||||||
|
|
||||||
$('.colorLabel img').show()
|
if ($(formElement).html() == "") appendIcon(filterIcon(form), form)
|
||||||
|
|
||||||
generateIcon(() => { icon.glow = false; enableGlow = 0 } ) // disable glow after first generated
|
$(formElement).show()
|
||||||
|
})
|
||||||
|
|
||||||
$(document).on('click', '.iconTabButton', function () {
|
$('#iconTabs').find('.iconTabButton')
|
||||||
let form = $(this).attr('form')
|
.first().children()
|
||||||
let formElement = '#' + form + 's'
|
.first().attr(
|
||||||
|
'src',
|
||||||
|
$('.iconTabButton').first().children()
|
||||||
|
.first().attr('src').replace('_off', '_on')
|
||||||
|
)
|
||||||
|
|
||||||
currentForm = form
|
function setGlowAttr(glow) {
|
||||||
|
$("#glow").attr('src', $("#glow").attr('src').replace( ...(glow ? ['_off', '_on'] : ['_on', '_off']) ))
|
||||||
|
}
|
||||||
|
|
||||||
$('.iconTabButton').each(function(x, y) {
|
$("#randomIcon").click(function() {
|
||||||
$(this).children().first().attr('src', $(this).children().first().attr('src').replace('_on', '_off'))
|
|
||||||
})
|
|
||||||
|
|
||||||
let img = $(this).children().first()
|
let iconPool = iconStuff.previewIcons.concat(enableSpoilers ? iconStuff.newPreviewIcons : [])
|
||||||
img.attr('src', img.attr('src').replace('_off', '_on'));
|
let pickedIcon = iconPool[randInt(0, iconPool.length)].split(".", 1)[0].split("_")
|
||||||
|
let [randomForm, randomID] = pickedIcon
|
||||||
|
|
||||||
$('#iconKitParent').each(function(x, y) { $(this).children().not('#iconprogressbar').hide() })
|
let colorCount = Object.keys(iconStuff.colors).length
|
||||||
|
selectedForm = randomForm
|
||||||
|
selectedIcon = randomID
|
||||||
|
selectedCol1 = randInt(0, colorCount)
|
||||||
|
selectedCol2 = randInt(0, colorCount)
|
||||||
|
selectedColW = null
|
||||||
|
selectedColU = null
|
||||||
|
enableGlow = !randInt(0, 3) // 1 in 3 chance of glow
|
||||||
|
generateIcon()
|
||||||
|
|
||||||
if ($(formElement).html() == "") appendIcon(filterIcon(form), form)
|
$('#glow').attr('src', '/assets/iconkitbuttons/streak_off.png')
|
||||||
|
|
||||||
$(formElement).show()
|
|
||||||
})
|
|
||||||
|
|
||||||
$('#iconTabs').find('.iconTabButton').first().children().first().attr('src', $('.iconTabButton').first().children().first().attr('src').replace('_off', '_on'))
|
$(`.iconTabButton[form=${selectedForm}]`).trigger('click')
|
||||||
|
$(`#${selectedForm}-${selectedIcon}`).trigger('click')
|
||||||
|
$(`#col1-${selectedCol1}`).trigger('click')
|
||||||
|
$(`#col2-${selectedCol2}`).trigger('click')
|
||||||
|
$(`#colG-${selectedCol2}`).trigger('click')
|
||||||
|
$('#colW-12').trigger('click')
|
||||||
|
$('#colU-12').trigger('click')
|
||||||
|
setGlowAttr(enableGlow)
|
||||||
|
})
|
||||||
|
|
||||||
$("#randomIcon").click(function() {
|
$('#glowbtn').click(function() {
|
||||||
|
setGlowAttr(enableGlow)
|
||||||
let iconPool = iconStuff.previewIcons.concat(enableSpoilers ? iconStuff.newPreviewIcons : [])
|
enableGlow = !enableGlow
|
||||||
let pickedIcon = iconPool[Math.floor(Math.random() * iconPool.length)].split(".")[0].split("_")
|
icon.setGlow(enableGlow, false)
|
||||||
let [randomForm, randomID] = pickedIcon
|
|
||||||
|
|
||||||
let colorCount = Object.keys(iconStuff.colors).length
|
|
||||||
selectedForm = randomForm
|
|
||||||
selectedIcon = randomID
|
|
||||||
selectedCol1 = randInt(0, colorCount - 1)
|
|
||||||
selectedCol2 = randInt(0, colorCount - 1)
|
|
||||||
selectedColW = null
|
|
||||||
selectedColU = null
|
|
||||||
enableGlow = randInt(0, 2) == 1 ? 1 : 0 // 1 in 3 chance of glow
|
|
||||||
generateIcon()
|
|
||||||
|
|
||||||
$('#glow').attr('src', '../assets/iconkitbuttons/streak_off.png')
|
|
||||||
|
|
||||||
$(`.iconTabButton[form=${selectedForm}]`).trigger('click')
|
|
||||||
$(`#${selectedForm}-${selectedIcon}`).trigger('click')
|
|
||||||
$(`#col1-${selectedCol1}`).trigger('click')
|
|
||||||
$(`#col2-${selectedCol2}`).trigger('click')
|
|
||||||
$(`#colG-${selectedCol2}`).trigger('click')
|
|
||||||
$('#colW-12').trigger('click')
|
|
||||||
$('#colU-12').trigger('click')
|
|
||||||
if (enableGlow == 1) $("#glow").attr('src', $("#glow").attr('src').replace('_off', '_on'))
|
|
||||||
else $("#glow").attr('src', $("#glow").attr('src').replace('_on', '_off'))
|
|
||||||
})
|
|
||||||
|
|
||||||
$('#glowbtn').click(function () {
|
|
||||||
|
|
||||||
if (enableGlow) {
|
|
||||||
$("#glow").attr('src', $("#glow").attr('src').replace('_on', '_off'))
|
|
||||||
enableGlow = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
$("#glow").attr('src', $("#glow").attr('src').replace('_off', '_on'))
|
|
||||||
enableGlow = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
icon.setGlow(enableGlow > 0, false)
|
|
||||||
updateDetails()
|
updateDetails()
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
$(document).on('click', '.copyForm', function () {
|
$(document).on('click', '.copyForm', function () {
|
||||||
$('.copyForm').each(function(x, y) {$(this).children().first().attr('src', $(this).children().first().attr('src').replace('_on', '_off'))})
|
$('.copyForm').each(function(x, y) {$(this).children().first().attr('src', $(this).children().first().attr('src').replace('_on', '_off'))})
|
||||||
formCopy = $(this).attr('form')
|
formCopy = $(this).attr('form')
|
||||||
|
@ -471,10 +482,10 @@ fetch('../api/iconkit').then(res => res.json()).then(iconKitData => {
|
||||||
|
|
||||||
$(document).on('click', '.iconButton', function () {
|
$(document).on('click', '.iconButton', function () {
|
||||||
$(".iconButton").removeClass("iconSelected");
|
$(".iconButton").removeClass("iconSelected");
|
||||||
$(this).addClass('iconSelected');
|
$(this).addClass('iconSelected')
|
||||||
let oldForm = selectedForm
|
let oldForm = selectedForm
|
||||||
selectedIcon = $(this).attr('num');
|
selectedIcon = $(this).attr('num')
|
||||||
selectedForm = $(this).attr('form');
|
selectedForm = $(this).attr('form')
|
||||||
|
|
||||||
if (selectedForm == "ufo") { $('#colU').show(); $('#ccU').show() }
|
if (selectedForm == "ufo") { $('#colU').show(); $('#ccU').show() }
|
||||||
else { $('#colU').hide(); $('#ccU').hide(); $(`#colU-12`).trigger('click'); }
|
else { $('#colU').hide(); $('#ccU').hide(); $(`#colU-12`).trigger('click'); }
|
||||||
|
@ -488,99 +499,99 @@ fetch('../api/iconkit').then(res => res.json()).then(iconKitData => {
|
||||||
|
|
||||||
$(document).on('click', '.color1', function () {
|
$(document).on('click', '.color1', function () {
|
||||||
$(".color1").removeClass("iconSelected");
|
$(".color1").removeClass("iconSelected");
|
||||||
$(this).addClass('iconSelected');
|
$(this).addClass('iconSelected')
|
||||||
selectedCol1 = $(this).attr('col');
|
selectedCol1 = $(this).attr('col')
|
||||||
colorBG(1, iconStuff.colors[$(this).attr('col')]);
|
colorBG(1, iconStuff.colors[$(this).attr('col')])
|
||||||
setColor("1", selectedCol1)
|
setColor("1", selectedCol1)
|
||||||
})
|
})
|
||||||
|
|
||||||
$(document).on('click', '.color2', function () {
|
$(document).on('click', '.color2', function () {
|
||||||
$(".color2").removeClass("iconSelected");
|
$(".color2").removeClass("iconSelected");
|
||||||
$(this).addClass('iconSelected');
|
$(this).addClass('iconSelected')
|
||||||
selectedCol2 = $(this).attr('col');
|
selectedCol2 = $(this).attr('col')
|
||||||
colorBG(2, iconStuff.colors[$(this).attr('col')]);
|
colorBG(2, iconStuff.colors[$(this).attr('col')]);
|
||||||
$(`#colG-${$(this).attr('col')}`).trigger('click')
|
$(`#colG-${$(this).attr('col')}`).trigger('click')
|
||||||
selectedColG = $(this).attr('col');
|
selectedColG = $(this).attr('col')
|
||||||
setColor("2", selectedCol2)
|
setColor("2", selectedCol2)
|
||||||
})
|
})
|
||||||
|
|
||||||
$(document).on('click', '.colorG', function () {
|
$(document).on('click', '.colorG', function () {
|
||||||
$(".colorG").removeClass("iconSelected");
|
$(".colorG").removeClass("iconSelected");
|
||||||
$(this).addClass('iconSelected');
|
$(this).addClass('iconSelected')
|
||||||
selectedColG = $(this).attr('col');
|
selectedColG = $(this).attr('col')
|
||||||
colorBG('G', iconStuff.colors[$(this).attr('col')]);
|
colorBG('G', iconStuff.colors[$(this).attr('col')])
|
||||||
setColor("g", selectedColG)
|
setColor("g", selectedColG)
|
||||||
})
|
})
|
||||||
|
|
||||||
$(document).on('click', '.colorW', function () {
|
$(document).on('click', '.colorW', function () {
|
||||||
$(".colorW").removeClass("iconSelected");
|
$(".colorW").removeClass("iconSelected");
|
||||||
$(this).addClass('iconSelected');
|
$(this).addClass('iconSelected')
|
||||||
selectedColW = $(this).attr('col');
|
selectedColW = $(this).attr('col')
|
||||||
if (selectedColW == 12) selectedColW = null
|
if (selectedColW == 12) selectedColW = null
|
||||||
colorBG('W', iconStuff.colors[$(this).attr('col')]);
|
colorBG('W', iconStuff.colors[$(this).attr('col')])
|
||||||
setColor("w", selectedColW)
|
setColor("w", selectedColW)
|
||||||
})
|
})
|
||||||
|
|
||||||
$(document).on('click', '.colorU', function () {
|
$(document).on('click', '.colorU', function () {
|
||||||
$(".colorU").removeClass("iconSelected");
|
$(".colorU").removeClass("iconSelected");
|
||||||
$(this).addClass('iconSelected');
|
$(this).addClass('iconSelected')
|
||||||
selectedColU = $(this).attr('col');
|
selectedColU = $(this).attr('col')
|
||||||
if (selectedColU == 12) selectedColU = null
|
if (selectedColU == 12) selectedColU = null
|
||||||
colorBG('U', iconStuff.colors[$(this).attr('col')]);
|
colorBG('U', iconStuff.colors[$(this).attr('col')])
|
||||||
setColor("u", selectedColU)
|
setColor("u", selectedColU)
|
||||||
})
|
})
|
||||||
|
|
||||||
$("#cp1").on('input change', function() {
|
$("#cp1").on('input change', function() {
|
||||||
colorBG(1, $(this).val(), true);
|
colorBG(1, $(this).val(), true);
|
||||||
$(".color1").removeClass("iconSelected");
|
$(".color1").removeClass("iconSelected")
|
||||||
selectedCol1 = $('#cp1').val().slice(1)
|
selectedCol1 = $('#cp1').val().slice(1)
|
||||||
setColor("1", selectedCol1)
|
setColor("1", selectedCol1)
|
||||||
})
|
})
|
||||||
|
|
||||||
$("#cp2").on('input change', function() {
|
$("#cp2").on('input change', function() {
|
||||||
colorBG(2, $(this).val(), true);
|
colorBG(2, $(this).val(), true);
|
||||||
$(".color2").removeClass("iconSelected");
|
$(".color2").removeClass("iconSelected")
|
||||||
selectedCol2 = $('#cp2').val().slice(1)
|
selectedCol2 = $('#cp2').val().slice(1)
|
||||||
setColor("2", selectedCol2)
|
setColor("2", selectedCol2)
|
||||||
})
|
})
|
||||||
|
|
||||||
$("#cpG").on('input change', function() {
|
$("#cpG").on('input change', function() {
|
||||||
colorBG('G', $(this).val(), true);
|
colorBG('G', $(this).val(), true);
|
||||||
$(".colorG").removeClass("iconSelected");
|
$(".colorG").removeClass("iconSelected")
|
||||||
selectedColG = $('#cpG').val().slice(1)
|
selectedColG = $('#cpG').val().slice(1)
|
||||||
setColor("g", selectedColG)
|
setColor("g", selectedColG)
|
||||||
})
|
})
|
||||||
|
|
||||||
$("#cpW").on('input change', function() {
|
$("#cpW").on('input change', function() {
|
||||||
colorBG('W', $(this).val(), true);
|
colorBG('W', $(this).val(), true);
|
||||||
$(".colorW").removeClass("iconSelected");
|
$(".colorW").removeClass("iconSelected")
|
||||||
selectedColW = $('#cpW').val().slice(1)
|
selectedColW = $('#cpW').val().slice(1)
|
||||||
setColor("w", selectedColW)
|
setColor("w", selectedColW)
|
||||||
})
|
})
|
||||||
|
|
||||||
$("#cpU").on('input change', function() {
|
$("#cpU").on('input change', function() {
|
||||||
colorBG('U', $(this).val(), true);
|
colorBG('U', $(this).val(), true);
|
||||||
$(".colorU").removeClass("iconSelected");
|
$(".colorU").removeClass("iconSelected")
|
||||||
selectedColU = $('#cpU').val().slice(1)
|
selectedColU = $('#cpU').val().slice(1)
|
||||||
setColor("u", selectedColU)
|
setColor("u", selectedColU)
|
||||||
})
|
})
|
||||||
|
|
||||||
$("#getUserIcon").click(function() {
|
$("#getUserIcon").click(function() {
|
||||||
$(`.copyForm[form=${currentForm}]`).trigger('click')
|
$(`.copyForm[form=${currentForm}]`).trigger('click')
|
||||||
$('#steal').show();
|
$('#steal').show();
|
||||||
$('#playerName').focus()
|
$('#playerName').focus()
|
||||||
$('#playerName').select()
|
$('#playerName').select()
|
||||||
})
|
})
|
||||||
|
|
||||||
$('#copyToClipboard').click(function() {
|
$('#copyToClipboard').click(function() {
|
||||||
if ($(this).hasClass('greyedOut')) return
|
if ($(this).hasClass('greyedOut')) return
|
||||||
icon.copyToClipboard()
|
icon.copyToClipboard()
|
||||||
let copyIcon = $(this).find('img')
|
let copyIcon = $(this).find('img')
|
||||||
$(this).addClass('greyedOut')
|
$(this).addClass('greyedOut')
|
||||||
copyIcon.attr('src', '../assets/iconkitbuttons/copied.png')
|
copyIcon.attr('src', '/assets/iconkitbuttons/copied.png')
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
$(this).removeClass('greyedOut')
|
$(this).removeClass('greyedOut')
|
||||||
copyIcon.attr('src', '../assets/iconkitbuttons/copy.png')
|
copyIcon.attr('src', '/assets/iconkitbuttons/copy.png')
|
||||||
}, 420);
|
}, 420);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -595,12 +606,12 @@ fetch('../api/iconkit').then(res => res.json()).then(iconKitData => {
|
||||||
})
|
})
|
||||||
|
|
||||||
let hoverText = $('#helpText').html()
|
let hoverText = $('#helpText').html()
|
||||||
$(".help").hover(function() {
|
$(".help").hover(function() {
|
||||||
$(this).css('color', 'rgba(200, 255, 255)')
|
$(this).css('color', 'rgba(200, 255, 255)')
|
||||||
$('#helpText').html($(this).attr('help'))
|
$('#helpText').html($(this).attr('help'))
|
||||||
}, function() {
|
}, function() {
|
||||||
$(this).css('color', 'white')
|
$(this).css('color', 'white')
|
||||||
$('#helpText').html(hoverText)
|
$('#helpText').html(hoverText)
|
||||||
})
|
})
|
||||||
|
|
||||||
$(document).on('change', '.iconsetting', function (e) {
|
$(document).on('change', '.iconsetting', function (e) {
|
||||||
|
@ -608,11 +619,11 @@ fetch('../api/iconkit').then(res => res.json()).then(iconKitData => {
|
||||||
$('.iconsetting:checkbox:checked').each((i, x) => { checkedSettings.push(x.id.split('-')[1]) })
|
$('.iconsetting:checkbox:checked').each((i, x) => { checkedSettings.push(x.id.split('-')[1]) })
|
||||||
iconSettings = checkedSettings
|
iconSettings = checkedSettings
|
||||||
switch ($(this).attr('id').slice(4)) {
|
switch ($(this).attr('id').slice(4)) {
|
||||||
case "sort": loadColors(); break;
|
case "sort": loadColors(); break
|
||||||
case "ufo": generateIcon(); break;
|
case "ufo": generateIcon(); break
|
||||||
case "cursed":
|
case "cursed":
|
||||||
$('#animationOptions').hide();
|
c('#animationOptions').hide();
|
||||||
checkAnimation();
|
checkAnimation();
|
||||||
$('#robotAnimation').trigger('change');
|
$('#robotAnimation').trigger('change');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -620,8 +631,8 @@ fetch('../api/iconkit').then(res => res.json()).then(iconKitData => {
|
||||||
})
|
})
|
||||||
|
|
||||||
$('#unlockIcon').click(function() {
|
$('#unlockIcon').click(function() {
|
||||||
if (!achievements.length) {
|
if (!achievements.length) {
|
||||||
fetch('../api/achievements').then(res => { res.json().then(x => {
|
fetch('/api/achievements').then(res => { res.json().then(x => {
|
||||||
achievements = x.achievements
|
achievements = x.achievements
|
||||||
shopIcons = iconStuff.shops
|
shopIcons = iconStuff.shops
|
||||||
unlockMode = true
|
unlockMode = true
|
||||||
|
@ -635,19 +646,19 @@ fetch('../api/iconkit').then(res => res.json()).then(iconKitData => {
|
||||||
else { $('#lock').attr('src', $('#lock').attr('src').replace('_on.png', '.png')); $('#howto').hide() }
|
else { $('#lock').attr('src', $('#lock').attr('src').replace('_on.png', '.png')); $('#howto').hide() }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
$(document).on('mouseover', '.iconButton, .color1, .color2', function () {
|
$(document).on('mouseover', '.iconButton, .color1, .color2', function () {
|
||||||
if (unlockMode && achievements.length) {
|
if (unlockMode && achievements.length) {
|
||||||
$(this).addClass('iconHover')
|
$(this).addClass('iconHover')
|
||||||
let form = $(this).attr('form') || $(this).attr('colType')
|
let form = $(this).attr('form') || $(this).attr('colType')
|
||||||
let iconNumber = $(this).attr('num') || $(this).attr('col')
|
let iconNumber = $(this).attr('num') || $(this).attr('col')
|
||||||
$('#howto').html(getUnlockMethod(iconNumber, form) || `<span style='color: #aaaaaa'>(no info available)</span>`)
|
$('#howto').html(getUnlockMethod(iconNumber, form) || `<span style='color: #aaa'>(no info available)</span>`)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
$(document).on('mouseleave', '.iconButton, .color1, .color2', function () {
|
$(document).on('mouseleave', '.iconButton, .color1, .color2', function () {
|
||||||
$(this).removeClass('iconHover')
|
$(this).removeClass('iconHover')
|
||||||
$('#howto').html("<span style='color: #aaaaaa'>(hover over an icon for info)</span>")
|
$('#howto').html("<span style='color: #aaa'>(hover over an icon for info)</span>")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -657,11 +668,11 @@ fetch('../api/iconkit').then(res => res.json()).then(iconKitData => {
|
||||||
if (!user || !user.length) return $("#steal").hide()
|
if (!user || !user.length) return $("#steal").hide()
|
||||||
|
|
||||||
$(`.iconTabButton[form=${formCopy}]`).trigger('click')
|
$(`.iconTabButton[form=${formCopy}]`).trigger('click')
|
||||||
$('#glow').attr('src', '../assets/iconkitbuttons/streak_off.png')
|
$('#glow').attr('src', '/assets/iconkitbuttons/streak_off.png')
|
||||||
$("#steal").hide()
|
$("#steal").hide()
|
||||||
enableGlow = 0
|
enableGlow = false
|
||||||
|
|
||||||
let info = await fetch('../api/profile/' + user).then(res => res.json()).catch(e => {})
|
let info = await fetch('/api/profile/' + user).then(res => res.json()).catch(e => {})
|
||||||
if (info == "-1") info = {}
|
if (info == "-1") info = {}
|
||||||
|
|
||||||
$(`#${formCopy}-${Math.min(info[formCopy] || 1, $(`.iconButton[form=${formCopy}]`).length)}`).trigger('click')
|
$(`#${formCopy}-${Math.min(info[formCopy] || 1, $(`.iconButton[form=${formCopy}]`).length)}`).trigger('click')
|
||||||
|
@ -724,20 +735,21 @@ $('#animationSpeed').on('input', function() {
|
||||||
})
|
})
|
||||||
|
|
||||||
$('#animationSpeedBox').change(function() {
|
$('#animationSpeedBox').change(function() {
|
||||||
animationMultiplier = Number(Math.abs(Number($(this).val()) || 1).toFixed(2))
|
animationMultiplier = Number( Math.abs( Number( $(this).val() ) || 1 ).toFixed(2) )
|
||||||
if (animationMultiplier > 99) animationMultiplier = 99
|
animationMultiplier = clamp(animationMultiplier, 0, 99)
|
||||||
else if (animationMultiplier <= 0) animationMultiplier = 0.1
|
animationMultiplier ||= 0.1
|
||||||
$('#animationSpeed').val(animationMultiplier)
|
$('#animationSpeed').val(animationMultiplier)
|
||||||
$('#animationSpeedBox').val(animationMultiplier)
|
$('#animationSpeedBox').val(animationMultiplier)
|
||||||
if (icon.complex) icon.animationSpeed = animationMultiplier
|
if (icon.complex) icon.animationSpeed = animationMultiplier
|
||||||
})
|
})
|
||||||
|
|
||||||
$(document).keydown(function(k) {
|
$(document).keydown(function(k) {
|
||||||
if (k.keyCode == 13) { // enter
|
// standard and Numpad support
|
||||||
|
if (k.code.endsWith('Enter')) {
|
||||||
if ($("#steal").is(":visible")) $("#fetchUser").trigger('click')
|
if ($("#steal").is(":visible")) $("#fetchUser").trigger('click')
|
||||||
else if ($(".popup").is(":visible")) return
|
else if ($(".popup").is(":visible")) return
|
||||||
}
|
}
|
||||||
if (k.keyCode == 27) { //esc
|
if (k.code == 'Escape') {
|
||||||
if ($(".popup").is(":visible")) return $('.popup').hide()
|
if ($(".popup").is(":visible")) return $('.popup').hide()
|
||||||
k.preventDefault()
|
k.preventDefault()
|
||||||
$('#backButton').trigger('click')
|
$('#backButton').trigger('click')
|
||||||
|
@ -751,5 +763,4 @@ $(document).on('click', '.brownbox', function (e) {
|
||||||
$(document).on('click', '.popup', function () {
|
$(document).on('click', '.popup', function () {
|
||||||
$('.popup').hide()
|
$('.popup').hide()
|
||||||
})
|
})
|
||||||
|
</script>
|
||||||
</script>
|
|
|
@ -1,9 +1,9 @@
|
||||||
<head>
|
<head>
|
||||||
<title>Leaderboard</title>
|
<title>Leaderboard</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link href="../assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
<link href="/assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
||||||
<link rel="icon" href="../assets/trophy.png">
|
<link rel="icon" href="/assets/trophy.png">
|
||||||
<meta id="meta-title" property="og:title" content="Leaderboards">
|
<meta id="meta-title" property="og:title" content="Leaderboards">
|
||||||
<meta id="meta-desc" property="og:description" content="View Geometry Dash's leaderboards, plus an accurate and updated list of the top players.">
|
<meta id="meta-desc" property="og:description" content="View Geometry Dash's leaderboards, plus an accurate and updated list of the top players.">
|
||||||
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/trophy.png">
|
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/trophy.png">
|
||||||
|
@ -15,74 +15,74 @@
|
||||||
<div id="everything" style="overflow: auto;">
|
<div id="everything" style="overflow: auto;">
|
||||||
|
|
||||||
<div id="scoreTabs">
|
<div id="scoreTabs">
|
||||||
<img src="../assets/tab-top-on.png" class="leaderboardTab" id="topTabOn" style="display: none">
|
<img src="/assets/tab-top-on.png" class="leaderboardTab" id="topTabOn" style="display: none">
|
||||||
<img src="../assets/tab-top-off.png" class="leaderboardTab leaderboardClick" id="topTabOff">
|
<img src="/assets/tab-top-off.png" class="leaderboardTab leaderboardClick" id="topTabOff">
|
||||||
|
|
||||||
<!-- for some GDPS'es -->
|
<!-- for some GDPS'es -->
|
||||||
<img src="../assets/tab-weekly-on.png" class="sideSpaceC leaderboardTab" id="weeklyTabOn" style="display: none">
|
<img src="/assets/tab-weekly-on.png" class="sideSpaceC leaderboardTab" id="weeklyTabOn" style="display: none">
|
||||||
<img src="../assets/tab-weekly-off.png" class="sideSpaceC leaderboardTab leaderboardClick" id="weeklyTabOff" style="display: none">
|
<img src="/assets/tab-weekly-off.png" class="sideSpaceC leaderboardTab leaderboardClick" id="weeklyTabOff" style="display: none">
|
||||||
|
|
||||||
<img src="../assets/tab-accurate-on.png" class="sideSpaceC leaderboardTab" id="accurateTabOn" style="display: none">
|
<img src="/assets/tab-accurate-on.png" class="sideSpaceC leaderboardTab" id="accurateTabOn" style="display: none">
|
||||||
<img src="../assets/tab-accurate-off.png" class="sideSpaceC leaderboardTab leaderboardClick" id="accurateTabOff">
|
<img src="/assets/tab-accurate-off.png" class="sideSpaceC leaderboardTab leaderboardClick" id="accurateTabOff">
|
||||||
|
|
||||||
<img src="../assets/tab-creators-on.png" class="sideSpaceC leaderboardTab" id="creatorTabOn" style="display: none">
|
<img src="/assets/tab-creators-on.png" class="sideSpaceC leaderboardTab" id="creatorTabOn" style="display: none">
|
||||||
<img src="../assets/tab-creators-off.png" class="sideSpaceC leaderboardTab leaderboardClick" id="creatorTabOff">
|
<img src="/assets/tab-creators-off.png" class="sideSpaceC leaderboardTab leaderboardClick" id="creatorTabOff">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="popup" id="infoDiv">
|
<div class="popup" id="infoDiv">
|
||||||
<div class="fancybox bounce center supercenter" style="width: 80vh">
|
<div class="fancybox bounce center supercenter" style="width: 80vh">
|
||||||
<h2 class="smaller center" style="font-size: 5.5vh">Leaderboard Info</h2>
|
<h2 class="smaller center" style="font-size: 5.5vh">Leaderboard Info</h2>
|
||||||
<p class="bigger center" id="infoText" style="line-height: 5vh; margin-top: 1.5vh"></p>
|
<p class="bigger center" id="infoText" style="line-height: 5vh; margin-top: 1.5vh"></p>
|
||||||
<img src="../assets/ok.png" width=20%; class="gdButton center" onclick="$('.popup').hide()">
|
<img src="/assets/ok.png" width=20%; class="gdButton center" onclick="$('.popup').hide()">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 0%; left: 0%; width: 100%">
|
<div style="position:absolute; bottom: 0%; left: 0%; width: 100%">
|
||||||
<img class="cornerPiece noClick" src="../assets/corner.png" width=7%;>
|
<img class="cornerPiece noClick" src="/assets/corner.png" width=7%;>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 0%; right: 0%; width: 100%; text-align: right;">
|
<div style="position:absolute; bottom: 0%; right: 0%; width: 100%; text-align: right;">
|
||||||
<a title="Boomlings Leaderboard?????" href="../boomlings"><img id="boomling" style="position: absolute; width: 6%; top: 2%; right: 1%; display: none"></a>
|
<a title="Boomlings Leaderboard?????" href="../boomlings"><img id="boomling" style="position: absolute; width: 6%; top: 2%; right: 1%; display: none"></a>
|
||||||
<img class="cornerPiece noClick" src="../assets/corner.png" width=7%; style="transform: scaleX(-1)">
|
<img class="cornerPiece noClick" src="/assets/corner.png" width=7%; style="transform: scaleX(-1)">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="searchBox" class="supercenter dragscroll">
|
<div id="searchBox" class="supercenter dragscroll">
|
||||||
<div style="height: 4.5%"></div>
|
<div style="height: 4.5%"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="leaderboardBox supercenter gs" style="width: 120vh; height: 80%; pointer-events: none">
|
<div class="leaderboardBox supercenter gs" style="width: 120vh; height: 80%; pointer-events: none">
|
||||||
<div id="relativeUser" class="sortDiv" style="position: relative; left: 100%; transform: translateX(4.5vh); top: 12%; width: 0.1%">
|
<div id="relativeUser" class="sortDiv" style="position: relative; left: 100%; transform: translateX(4.5vh); top: 12%; width: 0.1%">
|
||||||
<img class="gdButton" id="findRelative" style="margin-bottom: 1vh" title="Global Search" src="../assets/magnify.png" height="11%">
|
<img class="gdButton" id="findRelative" style="margin-bottom: 1vh" title="Global Search" src="/assets/magnify.png" height="11%">
|
||||||
<img class="gdButton" id="clearRelative" style="margin-bottom: 1vh; display: none" title="Clear Global Search" src="../assets/unmagnify.png" height="11%">
|
<img class="gdButton" id="clearRelative" style="margin-bottom: 1vh; display: none" title="Clear Global Search" src="/assets/unmagnify.png" height="11%">
|
||||||
</div>
|
</div>
|
||||||
<div class="sortDiv" style="display: none; position: relative; left: 100%; transform: translateX(4.5vh); top: 12%; width: 0.1%">
|
<div class="sortDiv" style="display: none; position: relative; left: 100%; transform: translateX(4.5vh); top: 12%; width: 0.1%">
|
||||||
<img class="gdButton" id="modSort" style="margin-bottom: 1vh" title="Moderators" src="../assets/sort-mod.png" height="11%">
|
<img class="gdButton" id="modSort" style="margin-bottom: 1vh" title="Moderators" src="/assets/sort-mod.png" height="11%">
|
||||||
<img class="gdButton" id="weeklyStats" style="margin-bottom: 1vh" title="Weekly Stats" src="../assets/sort-week.png" height="11%">
|
<img class="gdButton" id="weeklyStats" style="margin-bottom: 1vh" title="Weekly Stats" src="/assets/sort-week.png" height="11%">
|
||||||
</div>
|
</div>
|
||||||
<div class="sortDiv" style="display: none; position: relative; right: 10.5%; top: 0%; width: 0.1%; transform: translateY(-33.3%)" id="statSort">
|
<div class="sortDiv" style="display: none; position: relative; right: 10.5%; top: 0%; width: 0.1%; transform: translateY(-33.3%)" id="statSort">
|
||||||
<img class="gdButton sortButton" style="margin-bottom: 1vh" sort="stars" title="Most stars" src="../assets/sort-stars-on.png" height="11%" id="starSort">
|
<img class="gdButton sortButton" style="margin-bottom: 1vh" sort="stars" title="Most stars" src="/assets/sort-stars-on.png" height="11%" id="starSort">
|
||||||
<img class="gdButton sortButton" style="margin-bottom: 1vh" sort="diamonds" title="Most diamonds" src="../assets/sort-diamonds.png" height="11%">
|
<img class="gdButton sortButton" style="margin-bottom: 1vh" sort="diamonds" title="Most diamonds" src="/assets/sort-diamonds.png" height="11%">
|
||||||
<img class="gdButton sortButton" style="margin-bottom: 1vh" sort="coins" title="Most coins" src="../assets/sort-coins.png" height="11%">
|
<img class="gdButton sortButton" style="margin-bottom: 1vh" sort="coins" title="Most coins" src="/assets/sort-coins.png" height="11%">
|
||||||
<img class="gdButton sortButton" style="margin-bottom: 1vh" sort="demons" title="Most demons" src="../assets/sort-demons.png" height="11%">
|
<img class="gdButton sortButton" style="margin-bottom: 1vh" sort="demons" title="Most demons" src="/assets/sort-demons.png" height="11%">
|
||||||
<img class="gdButton sortButton" style="margin-bottom: 1vh; display: none" sort="cp" title="Most creator points" src="../assets/sort-cp.png" height="11%" id="cpSort">
|
<img class="gdButton sortButton" style="margin-bottom: 1vh; display: none" sort="cp" title="Most creator points" src="/assets/sort-cp.png" height="11%" id="cpSort">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; top: 2%; left: 1.5%; width: 10%; height: 25%; pointer-events: none">
|
<div style="position:absolute; top: 2%; left: 1.5%; width: 10%; height: 25%; pointer-events: none">
|
||||||
<img class="gdButton yesClick" id="backButton" src="../assets/back.png" height="30%" onclick="backButton()">
|
<img class="gdButton yesClick" id="backButton" src="/assets/back.png" height="30%" onclick="backButton()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; top: 2.5%; right: 2%; width: 10%; text-align: right;">
|
<div style="position:absolute; top: 2.5%; right: 2%; width: 10%; text-align: right;">
|
||||||
<img class="gdButton" src="../assets/smallinfo.png" width="32%" onclick="$('#infoDiv').show()">
|
<img class="gdButton" src="/assets/smallinfo.png" width="32%" onclick="$('#infoDiv').show()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="discordLinks" style="display: none; position:absolute; top: 12%; right: 1.5%; width: 21%; text-align: right;">
|
<div id="discordLinks" style="display: none; position:absolute; top: 12%; right: 1.5%; width: 21%; text-align: right;">
|
||||||
<a id="discord" target="_blank" title="Official leaderboard Discord!" href="https://discord.gg/leaderboard"><img class="gdButton" src="../assets/discord.png" width="20%"></a>
|
<a id="discord" target="_blank" title="Official leaderboard Discord!" href="https://discord.gg/leaderboard"><img class="gdButton" src="/assets/discord.png" width="20%"></a>
|
||||||
<a id="altDiscord" target="_blank" title="Accurate leaderboard Discord!" style="display: none; filter: hue-rotate(300deg)" href="https://discord.gg/Uz7pd4d"><img class="gdButton" src="../assets/discord.png" width="20%"></a>
|
<a id="altDiscord" target="_blank" title="Accurate leaderboard Discord!" style="display: none; filter: hue-rotate(300deg)" href="https://discord.gg/Uz7pd4d"><img class="gdButton" src="/assets/discord.png" width="20%"></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="supercenter" id="loading" style="height: 10%; top: 47%; display: none;">
|
<div class="supercenter" id="loading" style="height: 10%; top: 47%; display: none;">
|
||||||
<img class="spin noSelect" src="../assets/loading.png" height="105%">
|
<img class="spin noSelect" src="/assets/loading.png" height="105%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="popup" id="userSearch">
|
<div class="popup" id="userSearch">
|
||||||
|
@ -90,10 +90,10 @@
|
||||||
<h2 class="smaller center" style="font-size: 5.5vh; margin-top: 1%">User Search</h2>
|
<h2 class="smaller center" style="font-size: 5.5vh; margin-top: 1%">User Search</h2>
|
||||||
<p>Enter the <cy>username</cy> of a player to find their position in the <ca>global leaderboard</ca>.</p>
|
<p>Enter the <cy>username</cy> of a player to find their position in the <ca>global leaderboard</ca>.</p>
|
||||||
<input type="text" id="relativeName" placeholder="Username" style="height: 8vh; width: 90%; text-align: center; margin-top: 0.5%; margin-bottom: 5%"><br>
|
<input type="text" id="relativeName" placeholder="Username" style="height: 8vh; width: 90%; text-align: center; margin-top: 0.5%; margin-bottom: 5%"><br>
|
||||||
<img src="../assets/btn-cancel.png" class="postButton gdButton center" style="width: 32%; margin-right: 1%" onclick="$('#userSearch').hide()">
|
<img src="/assets/btn-cancel.png" class="postButton gdButton center" style="width: 32%; margin-right: 1%" onclick="$('#userSearch').hide()">
|
||||||
<img src="../assets/btn-submit.png" class="postButton gdButton center" style="width: 32%; margin-left: 1%" id="relativeSearch">
|
<img src="/assets/btn-submit.png" class="postButton gdButton center" style="width: 32%; margin-left: 1%" id="relativeSearch">
|
||||||
<p id="relativeStatus" style="display: none"></p>
|
<p id="relativeStatus" style="display: none"></p>
|
||||||
<img class="closeWindow gdButton" src="../assets/close.png" width="13%" style="position: absolute; top: -13.5%; left: -6vh" onclick="$('#userSearch').hide()">
|
<img class="closeWindow gdButton" src="/assets/close.png" width="13%" style="position: absolute; top: -13.5%; left: -6vh" onclick="$('#userSearch').hide()">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -101,35 +101,36 @@
|
||||||
</body>
|
</body>
|
||||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/6.2.2/browser/pixi.js"></script>
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/6.2.2/browser/pixi.js"></script>
|
||||||
<script type="text/javascript" src="../iconkit/icon.js"></script>
|
<script type="text/javascript" src="/iconkit/icon.js"></script>
|
||||||
<script type="text/javascript" src="../global.js?v=1"></script>
|
<script type="text/javascript" src="/misc/global.js?v=1"></script>
|
||||||
<script type="text/javascript" src="../dragscroll.js"></script>
|
<script type="text/javascript" src="/misc/dragscroll.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
"use strict";
|
||||||
|
|
||||||
let type
|
let type
|
||||||
let sort = "stars"
|
let sort = "stars"
|
||||||
let modMode = false
|
let modMode = false
|
||||||
let weekly = false
|
let weekly = false
|
||||||
let showWeek = localStorage.weeklyStats == "1"
|
let showWeek = localStorage.weeklyStats == "1"
|
||||||
let trophies = [1, 3, 10, 25, 50, 75, 100]
|
let trophies = [1, 3, 10, 25, 50, 75, 100] // it seems this can be optimized into a const Uint8Array
|
||||||
let boomColors = ["red", "orange", "yellow", "green", "teal", "blue", "pink"]
|
let boomColors = ["red", "orange", "yellow", "green", "teal", "blue", "pink"]
|
||||||
|
|
||||||
let top250Text =
|
let top250Text =
|
||||||
`The <cg>Stars</cg> leaderboard contains the <cg>top 100 players</cg>, sorted by <cy>star</cy> value. It was formerly <co>inaccurate</co> but should be much more <cb>reliable</cb> now.`
|
`The <cg>Stars</cg> leaderboard contains the <cg>top 100 players</cg>, sorted by <cy>star</cy> value. It was formerly <co>inaccurate</co> but should be much more <cb>reliable</cb> now.`
|
||||||
|
|
||||||
let topGDPSText =
|
let topGDPSText =
|
||||||
`The <cg>Stars</cg> leaderboard contains the <cg>top players</cg>, sorted by <cy>star</cy> value.`
|
`The <cg>Stars</cg> leaderboard contains the <cg>top players</cg>, sorted by <cy>star</cy> value.`
|
||||||
|
|
||||||
let weeklyText =
|
let weeklyText =
|
||||||
`The <cg>Weekly</cg> leaderboard displays the players who have gained the most <cy>stars</cy> in the <cb>past week</cb>. It was officially <co>removed</co> in update 2.0, but lives on in some GDPS'es.`
|
`The <cg>Weekly</cg> leaderboard displays the players who have gained the most <cy>stars</cy> in the <cb>past week</cb>. It was officially <co>removed</co> in update 2.0, but lives on in some GDPS'es.`
|
||||||
|
|
||||||
let accurateText =
|
let accurateText =
|
||||||
`The <cg>Accurate Leaderboard</cg> is an <cy>externally managed</cy> leaderboard which aims to provide <ca>detailed</ca> and hacker-proof stats on top players. It also once provided a way to view an <cg>accurate</cg> list of players with the most <cy>stars</cy> when the official leaderboards were <ca>frozen</ca>. It is managed by <cb>XShadowWizardX, Pepper360, Octeract</cb>, and many many other helpers.`
|
`The <cg>Accurate Leaderboard</cg> is an <cy>externally managed</cy> leaderboard which aims to provide <ca>detailed</ca> and hacker-proof stats on top players. It also once provided a way to view an <cg>accurate</cg> list of players with the most <cy>stars</cy> when the official leaderboards were <ca>frozen</ca>. It is managed by <cb>XShadowWizardX, Pepper360, Octeract</cb>, and many many other helpers.`
|
||||||
|
|
||||||
let creatorText =
|
let creatorText =
|
||||||
`The <cg>Creators Leaderboard</cg> is sorted by <cg>creator points</cg>, rather than stars. A player's <cg>creator points</cg> (CP) is calculated by counting their number of <cy>star rated</cy> levels, plus an extra point for every level that has been <cb>featured</cb>, plus an additional point for <co>epic rated</co> levels.`
|
`The <cg>Creators Leaderboard</cg> is sorted by <cg>creator points</cg>, rather than stars. A player's <cg>creator points</cg> (CP) is calculated by counting their number of <cy>star rated</cy> levels, plus an extra point for every level that has been <cb>featured</cb>, plus an additional point for <co>epic rated</co> levels.`
|
||||||
|
|
||||||
if (showWeek) $('#weeklyStats').attr('src', '../assets/sort-week-on.png')
|
if (showWeek) $('#weeklyStats').attr('src', '/assets/sort-week-on.png')
|
||||||
|
|
||||||
function infoText(text, altDiscord) {
|
function infoText(text, altDiscord) {
|
||||||
$('#infoText').html(text)
|
$('#infoText').html(text)
|
||||||
|
@ -147,7 +148,7 @@ function leaderboard(val, leaderboardParams, scrollTo) {
|
||||||
$('#clearRelative').hide()
|
$('#clearRelative').hide()
|
||||||
$('#loading').show()
|
$('#loading').show()
|
||||||
|
|
||||||
Fetch("../api/leaderboard?" + (leaderboardParams || `count=250&${val}&type=${sort}${modMode ? "&mod=1" : ""}`)).then(res => {
|
Fetch("/api/leaderboard?" + (leaderboardParams || `count=250&${val}&type=${sort}${modMode ? "&mod=1" : ""}`)).then(res => {
|
||||||
|
|
||||||
if (gdps && !didGDPSStuff) {
|
if (gdps && !didGDPSStuff) {
|
||||||
didGDPSStuff = true
|
didGDPSStuff = true
|
||||||
|
@ -155,7 +156,7 @@ function leaderboard(val, leaderboardParams, scrollTo) {
|
||||||
$('#accurateTabOn').remove()
|
$('#accurateTabOn').remove()
|
||||||
$('#accurateTabOff').remove()
|
$('#accurateTabOff').remove()
|
||||||
|
|
||||||
Fetch('../api/gdps?current=1').then(ps => {
|
Fetch('/api/gdps?current=1').then(ps => {
|
||||||
if (weekly) return
|
if (weekly) return
|
||||||
else if (ps.weeklyLeaderboard) { $('#weeklyTabOff').show(); weekly = true }
|
else if (ps.weeklyLeaderboard) { $('#weeklyTabOff').show(); weekly = true }
|
||||||
else $('#scoreTabs').css('margin-left', '-29vh')
|
else $('#scoreTabs').css('margin-left', '-29vh')
|
||||||
|
@ -174,14 +175,14 @@ function leaderboard(val, leaderboardParams, scrollTo) {
|
||||||
$('#searchBox').html(`<div style="height: 4.5%"></div>`)
|
$('#searchBox').html(`<div style="height: 4.5%"></div>`)
|
||||||
$('.ranking').remove()
|
$('.ranking').remove()
|
||||||
|
|
||||||
if (modMode && sort == "cp") res = res.sort(function(a, b){return b.cp - a.cp});
|
if (modMode && sort == "cp") res = res.sort(function(a, b){return b.cp - a.cp})
|
||||||
let wk = type == "weekly"
|
let wk = type == "weekly"
|
||||||
|
|
||||||
if ((leaderboardParams ? true : val == type) && res != -1 && res.length) res.forEach((x, y) => {
|
if ((!!leaderboardParams || val == type) && res != -1 && res.length) res.forEach((x, y) => {
|
||||||
|
|
||||||
let wp = x.weeklyProgress || {}
|
let wp = x.weeklyProgress || {}
|
||||||
let cosmetics = x.cosmetics || {}
|
let cosmetics = x.cosmetics || {}
|
||||||
|
|
||||||
let bgCol = cosmetics.bgColor
|
let bgCol = cosmetics.bgColor
|
||||||
let bgString = bgCol ? ` style="background-color: rgb(${bgCol.join()})"` : ""
|
let bgString = bgCol ? ` style="background-color: rgb(${bgCol.join()})"` : ""
|
||||||
|
|
||||||
|
@ -194,32 +195,32 @@ function leaderboard(val, leaderboardParams, scrollTo) {
|
||||||
$('#searchBox').append(`<div class="searchresult leaderboardSlot"${bgString}>
|
$('#searchBox').append(`<div class="searchresult leaderboardSlot"${bgString}>
|
||||||
|
|
||||||
<div class="center ranking">
|
<div class="center ranking">
|
||||||
${x.icon.icon == -1 && type == "accurate" ? `<img class="spaced" src="./assets/trophies/${trophies.findIndex(z => y+1 <= z) + 1}.png" height="150%" style="margin-bottom: 0%; transform:scale(1.1)">` :
|
${x.icon.icon == -1 && type == "accurate" ? `<img class="spaced" src="./assets/trophies/${trophies.findIndex(z => y+1 <= z) + 1}.png" height="150%" style="margin-bottom: 0%; transform:scale(1.1)">` :
|
||||||
`<gdicon dontload="true" class="leaderboardIcon" iconID=${x.icon.icon} cacheID=${x.playerID} iconForm="${x.icon.form}" col1="${x.icon.col1}" col2="${x.icon.col2}" glow="${x.icon.glow}"></gdicon>`}
|
`<gdicon dontload="true" class="leaderboardIcon" iconID=${x.icon.icon} cacheID=${x.playerID} iconForm="${x.icon.form}" col1="${x.icon.col1}" col2="${x.icon.col2}" glow="${x.icon.glow}"></gdicon>`}
|
||||||
<h2 class="slightlySmaller" style="transform: scale(${1 - (Math.max(0, String(x.rank).length - 1) * 0.1)})">${x.rank}</h2>
|
<h2 class="slightlySmaller" style="transform: scale(${1 - (Math.max(0, String(x.rank).length - 1) * 0.1)})">${x.rank}</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="leaderboardSide">
|
<div class="leaderboardSide">
|
||||||
<div class="leaderboardStars">
|
<div class="leaderboardStars">
|
||||||
${x.moderator ? `<img title="${x.moderator == 2 ? "Elder " : ""}Moderator" src="../assets/mod${x.moderator == 2 ? "-elder" : ""}.png" style="width: 9%; cursor: help; padding-right: 1.6%; transform: translateY(0.7vh)">` : ""}
|
${x.moderator ? `<img title="${x.moderator == 2 ? "Elder " : ""}Moderator" src="/assets/mod${x.moderator == 2 ? "-elder" : ""}.png" style="width: 9%; cursor: help; padding-right: 1.6%; transform: translateY(0.7vh)">` : ""}
|
||||||
<h2 class="leaderboardName small inline gdButton" style="margin-top: 1.5%${nameString || (x.moderator == 2 ? "; color: #FF9977;" : "")}"><a href="${onePointNine ? `../search/${x.playerID}?user` : `../u/${x.accountID}.`}" accountID="${x.accountID}">${x.username}</a></h2>
|
<h2 class="leaderboardName small inline gdButton" style="margin-top: 1.5%${nameString || (x.moderator == 2 ? "; color: #F97;" : "")}"><a href="${onePointNine ? `../search/${x.playerID}?user` : `../u/${x.accountID}.`}" accountID="${x.accountID}">${x.username}</a></h2>
|
||||||
<h3 class="inline${x.stars >= 100000 ? " yellow" : ""}" style="margin-left: 4%; margin-top: 2%; font-size: 4.5vh${type == "weekly" ? "; display: none" : ""};">${x.stars} <img class="help valign" src="../assets/star.png"style="width: 4vh; transform: translate(-25%, -10%);" title="Stars"></h3>
|
<h3 class="inline${x.stars >= 100000 ? " yellow" : ""}" style="margin-left: 4%; margin-top: 2%; font-size: 4.5vh${type == "weekly" ? "; display: none" : ""};">${x.stars} <img class="help valign" src="/assets/star.png"style="width: 4vh; transform: translate(-25%, -10%);" title="Stars"></h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h3 class="lessSpaced leaderboardStats">
|
<h3 class="lessSpaced leaderboardStats">
|
||||||
${type != "weekly" ? "" : `<span${x.stars >= 1000 ? " class='yellow'" : ""}>+${x.stars}</span> <img class="help valign" src="../assets/star.png" title="Star Gain">`}
|
${type != "weekly" ? "" : `<span${x.stars >= 1000 ? " class='yellow'" : ""}>+${x.stars}</span> <img class="help valign" src="/assets/star.png" title="Star Gain">`}
|
||||||
${wk || onePointNine ? "" : `<span${x.diamonds >= 65535 ? ` class='blue'>` : ">"}${x.diamonds}</span> <img class="help valign" src="../assets/diamond.png" title="Diamonds">`}
|
${wk || onePointNine ? "" : `<span${x.diamonds >= 65535 ? ` class='blue'>` : ">"}${x.diamonds}</span> <img class="help valign" src="/assets/diamond.png" title="Diamonds">`}
|
||||||
${wk ? " " : `<span${x.coins >= 149 ? " class='yellow'" : ""}>${x.coins}</span> <img class="help valign" src="../assets/coin.png" title="Secret Coins">`}
|
${wk ? " " : `<span${x.coins >= 149 ? " class='yellow'" : ""}>${x.coins}</span> <img class="help valign" src="/assets/coin.png" title="Secret Coins">`}
|
||||||
${wk || onePointNine ? "" : `<span${x.userCoins >= 10000 ? " class='brightblue'" : ""}>${x.userCoins}</span> <img class="help valign" src="../assets/silvercoin.png" title="User Coins">`}
|
${wk || onePointNine ? "" : `<span${x.userCoins >= 10000 ? " class='brightblue'" : ""}>${x.userCoins}</span> <img class="help valign" src="/assets/silvercoin.png" title="User Coins">`}
|
||||||
${wk ? "" : `<span${x.demons >= 1000 ? " class='brightred'" : ""}>${x.demons}</span> <img class="help valign" src="../assets/demon.png" title="Demons">`}
|
${wk ? "" : `<span${x.demons >= 1000 ? " class='brightred'" : ""}>${x.demons}</span> <img class="help valign" src="/assets/demon.png" title="Demons">`}
|
||||||
${x.cp <= 0 ? "" : `<span${x.cp >= 100 ? " class='yellow'" : ""}>${x.cp}</span> <img class="help valign" src="../assets/cp.png" title="Creator Points">`}
|
${x.cp <= 0 ? "" : `<span${x.cp >= 100 ? " class='yellow'" : ""}>${x.cp}</span> <img class="help valign" src="/assets/cp.png" title="Creator Points">`}
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<h3 class="lessSpaced leaderboardStats weeklyStuff"}>
|
<h3 class="lessSpaced leaderboardStats weeklyStuff"}>
|
||||||
<span${wp.diamonds >= 250 ? " class='blue'" : ""}>${wp.diamonds >= 0 ? "+" : ""}${wp.diamonds}</span> <img class="help valign" src="../assets/diamond.png" title="Diamond Gain">
|
<span${wp.diamonds >= 250 ? " class='blue'" : ""}>${wp.diamonds >= 0 ? "+" : ""}${wp.diamonds}</span> <img class="help valign" src="/assets/diamond.png" title="Diamond Gain">
|
||||||
<span${wp.stars >= 1000 ? " class='yellow'" : ""}>${wp.stars >= 0 ? "+" : ""}${wp.stars}</span> <img class="help valign" src="../assets/star.png" title="Star Gain">
|
<span${wp.stars >= 1000 ? " class='yellow'" : ""}>${wp.stars >= 0 ? "+" : ""}${wp.stars}</span> <img class="help valign" src="/assets/star.png" title="Star Gain">
|
||||||
<span${wp.userCoins >= 250 ? " class='brightblue'" : ""}>${wp.userCoins >= 0 ? "+" : ""}${wp.userCoins}</span> <img class="help valign" src="../assets/silvercoin.png" title="User Coin Gain">
|
<span${wp.userCoins >= 250 ? " class='brightblue'" : ""}>${wp.userCoins >= 0 ? "+" : ""}${wp.userCoins}</span> <img class="help valign" src="/assets/silvercoin.png" title="User Coin Gain">
|
||||||
<span${wp.demons >= 25 ? " class='brightred'" : ""}>${wp.demons >= 0 ? "+" : ""}${wp.demons}</span> <img class="help valign" src="../assets/demon.png" title="Demon Gain">
|
<span${wp.demons >= 25 ? " class='brightred'" : ""}>${wp.demons >= 0 ? "+" : ""}${wp.demons}</span> <img class="help valign" src="/assets/demon.png" title="Demon Gain">
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -249,7 +250,7 @@ function leaderboard(val, leaderboardParams, scrollTo) {
|
||||||
}).catch(e => {console.log(e); $('#loading').hide();})
|
}).catch(e => {console.log(e); $('#loading').hide();})
|
||||||
}
|
}
|
||||||
|
|
||||||
// $('#boomling').attr('src', `../assets/boomlings/${boomColors[Math.floor(Math.random() * boomColors.length)]}.png`)
|
// $('#boomling').attr('src', `../assets/boomlings/${boomColors[randInt(0, boomColors.length)]}.png`)
|
||||||
|
|
||||||
$(document).on('click', '.sortButton', function () {
|
$(document).on('click', '.sortButton', function () {
|
||||||
if ($('#loading').is(":visible")) return
|
if ($('#loading').is(":visible")) return
|
||||||
|
@ -261,7 +262,7 @@ $(document).on('click', '.sortButton', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
$('#topTabOff').click(function() {
|
$('#topTabOff').click(function() {
|
||||||
if (type == "top") return;
|
if (type == "top") return
|
||||||
type = "top"
|
type = "top"
|
||||||
leaderboard(type)
|
leaderboard(type)
|
||||||
$('.leaderboardTab').hide();
|
$('.leaderboardTab').hide();
|
||||||
|
@ -274,7 +275,7 @@ $('#topTabOff').click(function() {
|
||||||
})
|
})
|
||||||
|
|
||||||
$('#accurateTabOff').click(function() {
|
$('#accurateTabOff').click(function() {
|
||||||
if (type == "accurate") return;
|
if (type == "accurate") return
|
||||||
type = "accurate"
|
type = "accurate"
|
||||||
leaderboard(type)
|
leaderboard(type)
|
||||||
$('.leaderboardTab').hide();
|
$('.leaderboardTab').hide();
|
||||||
|
@ -287,7 +288,7 @@ $('#accurateTabOff').click(function() {
|
||||||
})
|
})
|
||||||
|
|
||||||
$('#weeklyTabOff').click(function() {
|
$('#weeklyTabOff').click(function() {
|
||||||
if (type == "weekly" || !gdps) return;
|
if (type == "weekly" || !gdps) return
|
||||||
type = "weekly"
|
type = "weekly"
|
||||||
leaderboard(type)
|
leaderboard(type)
|
||||||
$('.leaderboardTab').hide();
|
$('.leaderboardTab').hide();
|
||||||
|
@ -299,7 +300,7 @@ $('#weeklyTabOff').click(function() {
|
||||||
})
|
})
|
||||||
|
|
||||||
$('#creatorTabOff').click(function() {
|
$('#creatorTabOff').click(function() {
|
||||||
if (type == "creator") return;
|
if (type == "creator") return
|
||||||
type = "creator"
|
type = "creator"
|
||||||
leaderboard(type)
|
leaderboard(type)
|
||||||
$('.leaderboardTab').hide();
|
$('.leaderboardTab').hide();
|
||||||
|
@ -313,7 +314,7 @@ $('#creatorTabOff').click(function() {
|
||||||
$('#modSort').click(function() {
|
$('#modSort').click(function() {
|
||||||
modMode = !modMode
|
modMode = !modMode
|
||||||
$(this).attr('src', `../assets/sort-mod${modMode ? "-on" : ""}.png`)
|
$(this).attr('src', `../assets/sort-mod${modMode ? "-on" : ""}.png`)
|
||||||
if (modMode) {
|
if (modMode) {
|
||||||
$('#cpSort').show();
|
$('#cpSort').show();
|
||||||
$('#statSort').css('transform', 'translateY(-26.7%')
|
$('#statSort').css('transform', 'translateY(-26.7%')
|
||||||
}
|
}
|
||||||
|
@ -348,7 +349,7 @@ $('#relativeSearch').click(function() {
|
||||||
let relativeUsername = $('#relativeName').val()
|
let relativeUsername = $('#relativeName').val()
|
||||||
if (relativeLoading || !relativeUsername) return
|
if (relativeLoading || !relativeUsername) return
|
||||||
relativeLoading = true
|
relativeLoading = true
|
||||||
Fetch("../api/profile/" + relativeUsername).then(foundUser => {
|
Fetch("/api/profile/" + relativeUsername).then(foundUser => {
|
||||||
if (foundUser && foundUser.accountID && foundUser.rank) {
|
if (foundUser && foundUser.accountID && foundUser.rank) {
|
||||||
leaderboard(null, "type=relative&accountID=" + foundUser.accountID, foundUser.accountID)
|
leaderboard(null, "type=relative&accountID=" + foundUser.accountID, foundUser.accountID)
|
||||||
$('#userSearch').hide()
|
$('#userSearch').hide()
|
||||||
|
|
129
html/level.html
|
@ -1,9 +1,9 @@
|
||||||
<head>
|
<head>
|
||||||
<title>[[NAME]] ([[ID]])</title>
|
<title>[[NAME]] ([[ID]])</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link href="../assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
<link href="/assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
||||||
<link rel="icon" href="../assets/difficulties/[[DIFFICULTYFACE]].png">
|
<link rel="icon" href="/assets/difficulties/[[DIFFICULTYFACE]].png">
|
||||||
<meta id="meta-title" property="og:title" content="[[NAME]] by [[AUTHOR]]">
|
<meta id="meta-title" property="og:title" content="[[NAME]] by [[AUTHOR]]">
|
||||||
<meta id="meta-desc" property="og:description" content="ID: [[ID]] | Stars: [[STARS]] | Difficulty: [[DIFFICULTY]] | Downloads: [[DOWNLOADS]] | Likes: [[LIKES]] | Length: [[LENGTH]] | Song: [[SONGNAME]] ([[SONGID]])">
|
<meta id="meta-desc" property="og:description" content="ID: [[ID]] | Stars: [[STARS]] | Difficulty: [[DIFFICULTY]] | Downloads: [[DOWNLOADS]] | Likes: [[LIKES]] | Length: [[LENGTH]] | Song: [[SONGNAME]] ([[SONGID]])">
|
||||||
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/difficulties/[[DIFFICULTYFACE]].png">
|
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/difficulties/[[DIFFICULTYFACE]].png">
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
<br>GD Version: <cy>[[GAMEVERSION]]</cy>
|
<br>GD Version: <cy>[[GAMEVERSION]]</cy>
|
||||||
[[OBJECTINFO]][[REQUESTED]]
|
[[OBJECTINFO]][[REQUESTED]]
|
||||||
</p>
|
</p>
|
||||||
<img src="../assets/ok.png" width=20%; class="gdButton center closeWindow">
|
<img src="/assets/ok.png" width=20%; class="gdButton center closeWindow">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
<p class="bigger center" style="line-height: 5vh; margin-top: 1.5vh;">
|
<p class="bigger center" style="line-height: 5vh; margin-top: 1.5vh;">
|
||||||
<cy class="pre">[[NAME]]</cy> has been added to your <a class="youCanClickThis2" style="color:lime" href="../search/levels?type=saved">saved levels</a> list.
|
<cy class="pre">[[NAME]]</cy> has been added to your <a class="youCanClickThis2" style="color:lime" href="../search/levels?type=saved">saved levels</a> list.
|
||||||
</p>
|
</p>
|
||||||
<img src="../assets/ok.png" width=20%; class="gdButton center" onclick="savedLevel()">
|
<img src="/assets/ok.png" width=20%; class="gdButton center" onclick="savedLevel()">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -44,8 +44,8 @@
|
||||||
<p class="bigger center" style="line-height: 5vh; margin-top: 1.5vh;">
|
<p class="bigger center" style="line-height: 5vh; margin-top: 1.5vh;">
|
||||||
Are you sure you want to <cr>delete</cr> this level from your <a class="youCanClickThis2"style="color:lime" href="../search/levels?type=saved">saved levels </a>list?
|
Are you sure you want to <cr>delete</cr> this level from your <a class="youCanClickThis2"style="color:lime" href="../search/levels?type=saved">saved levels </a>list?
|
||||||
</p>
|
</p>
|
||||||
<img src="../assets/btn-no.png" height=25%; class="gdButton center closeWindow">
|
<img src="/assets/btn-no.png" height=25%; class="gdButton center closeWindow">
|
||||||
<img src="../assets/btn-yes.png" height=25%; class="gdButton center sideSpaceB" onclick="deleteLevel()">
|
<img src="/assets/btn-yes.png" height=25%; class="gdButton center sideSpaceB" onclick="deleteLevel()">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -55,15 +55,15 @@
|
||||||
<p class="bigger center" style="line-height: 5vh; margin-top: 1.5vh;">
|
<p class="bigger center" style="line-height: 5vh; margin-top: 1.5vh;">
|
||||||
<cy>Level analysis</cy> is currently <cr>blocked</cr> by <ca>RobTop</ca>. We don't know when or if it will be re-enabled.<br><a class="youCanClickThis" style="color:aqua" href="./analyze/[[ID]]">(click to try anyways)</a>
|
<cy>Level analysis</cy> is currently <cr>blocked</cr> by <ca>RobTop</ca>. We don't know when or if it will be re-enabled.<br><a class="youCanClickThis" style="color:aqua" href="./analyze/[[ID]]">(click to try anyways)</a>
|
||||||
</p>
|
</p>
|
||||||
<img src="../assets/ok.png" width=20%; class="gdButton center" onclick="$('.popup').hide()">
|
<img src="/assets/ok.png" width=20%; class="gdButton center" onclick="$('.popup').hide()">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- <div class="popup" id="likeDiv">
|
<!-- <div class="popup" id="likeDiv">
|
||||||
<div class="brownbox bounce center supercenter" style="height: 75%; width: 100vh">
|
<div class="brownbox bounce center supercenter" style="height: 75%; width: 100vh">
|
||||||
<h1 class="smaller center" style="font-size: 5.5vh">Vote</h1>
|
<h1 class="smaller center" style="font-size: 5.5vh">Vote</h1>
|
||||||
<img src="../assets/smashLike.png" id="likebtn" class="inline gdButton likeButton">
|
<img src="/assets/smashLike.png" id="likebtn" class="inline gdButton likeButton">
|
||||||
<img src="../assets/smashDislike.png" id="dislikebtn" class="inline gdButton likeButton youAreNotTheOne">
|
<img src="/assets/smashDislike.png" id="dislikebtn" class="inline gdButton likeButton youAreNotTheOne">
|
||||||
<form action="nothing lol">
|
<form action="nothing lol">
|
||||||
<h3 class="center">GD Username</h3>
|
<h3 class="center">GD Username</h3>
|
||||||
<input type="text" name="gdbrowser" id="like-username" maxlength="50" style="height: 8vh; width: 90%; text-align: center; margin-top: 0.5%">
|
<input type="text" name="gdbrowser" id="like-username" maxlength="50" style="height: 8vh; width: 90%; text-align: center; margin-top: 0.5%">
|
||||||
|
@ -73,17 +73,17 @@
|
||||||
<div style="min-height: 18%; max-height: 18%">
|
<div style="min-height: 18%; max-height: 18%">
|
||||||
<p id="message" style="padding: 0% 10%; margin-top: 2.5%"></p>
|
<p id="message" style="padding: 0% 10%; margin-top: 2.5%"></p>
|
||||||
</div>
|
</div>
|
||||||
<img src="../assets/btn-cancel.png" height=10%; class="postButton gdButton center" style="margin-right: 1%" onclick="$('#likeDiv').hide(); $('#likebtn').trigger('click');">
|
<img src="/assets/btn-cancel.png" height=10%; class="postButton gdButton center" style="margin-right: 1%" onclick="$('#likeDiv').hide(); $('#likebtn').trigger('click');">
|
||||||
<img src="../assets/btn-submit.png" type="submit" height=10%; class="postButton gdButton center" style="margin-left: 1%" id="submitVote">
|
<img src="/assets/btn-submit.png" type="submit" height=10%; class="postButton gdButton center" style="margin-left: 1%" id="submitVote">
|
||||||
</div>
|
</div>
|
||||||
</div> -->
|
</div> -->
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 0%; left: 0%; width: 100%">
|
<div style="position:absolute; bottom: 0%; left: 0%; width: 100%">
|
||||||
<img class="cornerPiece" src="../assets/corner.png" width=7%;>
|
<img class="cornerPiece" src="/assets/corner.png" width=7%;>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 0%; right: 0%; width: 100%; text-align: right;">
|
<div style="position:absolute; bottom: 0%; right: 0%; width: 100%; text-align: right;">
|
||||||
<img class="cornerPiece" src="../assets/corner.png" width=7%; style="transform: scaleX(-1)">
|
<img class="cornerPiece" src="/assets/corner.png" width=7%; style="transform: scaleX(-1)">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="center" style="width: 70%; margin: 1% auto">
|
<div class="center" style="width: 70%; margin: 1% auto">
|
||||||
|
@ -93,31 +93,31 @@
|
||||||
<div class="center" style="position:absolute; top: 9%; left: 0%; right: 0%; height: 5%;">
|
<div class="center" style="position:absolute; top: 9%; left: 0%; right: 0%; height: 5%;">
|
||||||
<h2 class="pre inline slightlySmaller normalCursor gdButton" id="authorName"><a class="linkButton" id="authorLink" href="../u/[[ACCOUNTID]].">By [[AUTHOR]]</a></h2>
|
<h2 class="pre inline slightlySmaller normalCursor gdButton" id="authorName"><a class="linkButton" id="authorLink" href="../u/[[ACCOUNTID]].">By [[AUTHOR]]</a></h2>
|
||||||
<h2 class="inline slightlySmaller normalCursor sideSpaceC">
|
<h2 class="inline slightlySmaller normalCursor sideSpaceC">
|
||||||
<img class="inline valign" id="copiedBadge" style="display: none; height: 60%; cursor:help" src="../assets/copied.png" title="Level is a copy or a collaboration">
|
<img class="inline valign" id="copiedBadge" style="display: none; height: 60%; cursor:help" src="/assets/copied.png" title="Level is a copy or a collaboration">
|
||||||
<img class="inline valign" id="largeBadge" style="display: none; height: 60%; margin-left: -7%; cursor:help" src="../assets/large.png" title="Contains more than 40,000 objects">
|
<img class="inline valign" id="largeBadge" style="display: none; height: 60%; margin-left: -7%; cursor:help" src="/assets/large.png" title="Contains more than 40,000 objects">
|
||||||
<img class="inline valign" id="2pBadge" style="display: none; height: 60%; margin-left: -7%; cursor:help" src="../assets/twoPlayer.png" title="Two player level">
|
<img class="inline valign" id="2pBadge" style="display: none; height: 60%; margin-left: -7%; cursor:help" src="/assets/twoPlayer.png" title="Two player level">
|
||||||
</h2><br>
|
</h2><br>
|
||||||
<img class="inline spaced dailyLevel" id="dailyIcon" style="height:90%; display: none; margin-right: 0.5%; margin-top: 0.4%; vertical-align: middle;">
|
<img class="inline spaced dailyLevel" id="dailyIcon" style="height:90%; display: none; margin-right: 0.5%; margin-top: 0.4%; vertical-align: middle;">
|
||||||
<h1 class="inline smallerer spaced dailyLevel" style="display: none; margin: 0 0 0 0">#[[DAILYNUMBER]]<span style="font-size: 2.5vh; vertical-align: middle;" class="h3Size" id="dailyTime"></span></h1>
|
<h1 class="inline smallerer spaced dailyLevel" style="display: none; margin: 0 0 0 0">#[[DAILYNUMBER]]<span style="font-size: 2.5vh; vertical-align: middle;" class="h3Size" id="dailyTime"></span></h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="center valign" style="position:absolute; top: 10.5%; left: 27%; transform:scale(0.8); height: 100%; width: 20%">
|
<div class="center valign" style="position:absolute; top: 10.5%; left: 27%; transform:scale(0.8); height: 100%; width: 20%">
|
||||||
<img class="spaced" src="../assets/difficulties/[[DIFFICULTYFACE]].png" height="15%" style="margin-bottom: 0%">
|
<img class="spaced" src="/assets/difficulties/[[DIFFICULTYFACE]].png" height="15%" style="margin-bottom: 0%">
|
||||||
<h1 class="smaller" id="difficultytext" style="transform:scale(0.9);">[[DIFFICULTY]]</h1>
|
<h1 class="smaller" id="difficultytext" style="transform:scale(0.9);">[[DIFFICULTY]]</h1>
|
||||||
<h1 class="smaller inline stars" style="transform:scale(0.9)">[[STARS]]</h1> <img class="inline stars" src="../assets/star.png" height=4%; style="transform:translateY(-12%)"><br class="stars">
|
<h1 class="smaller inline stars" style="transform:scale(0.9)">[[STARS]]</h1> <img class="inline stars" src="/assets/star.png" height=4%; style="transform:translateY(-12%)"><br class="stars">
|
||||||
<h1 class="smaller inline diamonds" style="transform:scale(0.9)">[[DIAMONDS]]</h1> <img class="inline diamonds" src="../assets/diamond.png" height=4%; style="transform:translateY(-12%)">
|
<h1 class="smaller inline diamonds" style="transform:scale(0.9)">[[DIAMONDS]]</h1> <img class="inline diamonds" src="/assets/diamond.png" height=4%; style="transform:translateY(-12%)">
|
||||||
<h1 class="smaller inline demonList" style="transform:scale(0.9); display: none;">#[[DEMONLIST]]</h1> <img class="inline demonList" src="../assets/demon.png" height=4.5%; style="transform:translateY(-7%); display: none; margin-left: 1.5%">
|
<h1 class="smaller inline demonList" style="transform:scale(0.9); display: none;">#[[DEMONLIST]]</h1> <img class="inline demonList" src="/assets/demon.png" height=4.5%; style="transform:translateY(-7%); display: none; margin-left: 1.5%">
|
||||||
<div id="coins" style="margin-top: 3%"></div>
|
<div id="coins" style="margin-top: 3%"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; top: 20%; right: 0%; height: 38%; width: 40%; line-height: 8.5vh">
|
<div style="position:absolute; top: 20%; right: 0%; height: 38%; width: 40%; line-height: 8.5vh">
|
||||||
<img class="valign inline spaced" src="../assets/download.png" height=15% style="margin-right: 2%">
|
<img class="valign inline spaced" src="/assets/download.png" height=15% style="margin-right: 2%">
|
||||||
<h1 class="valign inline smaller spaced">[[DOWNLOADS]]</h1><br>
|
<h1 class="valign inline smaller spaced">[[DOWNLOADS]]</h1><br>
|
||||||
<img id="likeImg" class="valign inline spaced" src="../assets/like.png" height=15% style="margin-right: 2%">
|
<img id="likeImg" class="valign inline spaced" src="/assets/like.png" height=15% style="margin-right: 2%">
|
||||||
<h1 class="valign inline smaller spaced">[[LIKES]]</h1><br>
|
<h1 class="valign inline smaller spaced">[[LIKES]]</h1><br>
|
||||||
<img class="valign inline spaced" src="../assets/time.png" height=15% style="margin-right: 2%">
|
<img class="valign inline spaced" src="/assets/time.png" height=15% style="margin-right: 2%">
|
||||||
<h1 class="valign inline smaller spaced">[[LENGTH]]</h1><br>
|
<h1 class="valign inline smaller spaced">[[LENGTH]]</h1><br>
|
||||||
<img class="valign inline spaced orbs" src="../assets/orbs.png" height=15% style="margin-right: 2%">
|
<img class="valign inline spaced orbs" src="/assets/orbs.png" height=15% style="margin-right: 2%">
|
||||||
<h1 class="valign inline smaller spaced orbs">[[ORBS]]</h1>
|
<h1 class="valign inline smaller spaced orbs">[[ORBS]]</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -129,16 +129,16 @@
|
||||||
<div style="margin-left: 0.5%">
|
<div style="margin-left: 0.5%">
|
||||||
<h1 class="pre slightlySmaller" id="songname">[[SONGNAME]]</h1>
|
<h1 class="pre slightlySmaller" id="songname">[[SONGNAME]]</h1>
|
||||||
<h2 class="pre smaller">By: [[SONGAUTHOR]]<!--
|
<h2 class="pre smaller">By: [[SONGAUTHOR]]<!--
|
||||||
--><img id="scout" title="Artist is scouted" style="display: none; margin-left: 1.5%; filter: hue-rotate(-55deg);" class="help artistIcon valign" src="../assets/check.png" width="5%"><!--
|
--><img id="scout" title="Artist is scouted" style="display: none; margin-left: 1.5%; filter: hue-rotate(-55deg);" class="help artistIcon valign" src="/assets/check.png" width="5%"><!--
|
||||||
--><img id="whitelist" title="Artist is whitelisted" style="display: none" class="help artistIcon valign" src="../assets/check.png" width="5%"><!--
|
--><img id="whitelist" title="Artist is whitelisted" style="display: none" class="help artistIcon valign" src="/assets/check.png" width="5%"><!--
|
||||||
--> <a class="songLink" href="https://[[SONGAUTHOR]].newgrounds.com" target="_blank"><img id="moreSongs" class="gdButton valign" src="../assets/more.png" width="12%"></a></h2>
|
--> <a class="songLink" href="https://[[SONGAUTHOR]].newgrounds.com" target="_blank"><img id="moreSongs" class="gdButton valign" src="/assets/more.png" width="12%"></a></h2>
|
||||||
<img id="checkSong" style="display: none; margin-top: 1%" title="Check song verification" class="gdButton valign" src="../assets/btn-check.png" width="16%">
|
<img id="checkSong" style="display: none; margin-top: 1%" title="Check song verification" class="gdButton valign" src="/assets/btn-check.png" width="16%">
|
||||||
<h3 id="songLoading" style="display: none; margin-top: 0.5%;">Loading...</h3>
|
<h3 id="songLoading" style="display: none; margin-top: 0.5%;">Loading...</h3>
|
||||||
<h3 id="songAllowed" style="display: none; margin-top: 0.5%; color: lime">Song is allowed for use</h3>
|
<h3 id="songAllowed" style="display: none; margin-top: 0.5%; color: lime">Song is allowed for use</h3>
|
||||||
<h3 id="songNotAllowed" style="display: none; margin-top: 0.5%; color: red">Song is not allowed for use</h3>
|
<h3 id="songNotAllowed" style="display: none; margin-top: 0.5%; color: red">Song is not allowed for use</h3>
|
||||||
<h3 id="artistInfo" style="display: none; margin-top: 0.5%"></h3>
|
<h3 id="artistInfo" style="display: none; margin-top: 0.5%"></h3>
|
||||||
</div>
|
</div>
|
||||||
<a class="songLink" href="https://www.newgrounds.com/audio/listen/[[SONGID]]" target="_blank"><img class="gdButton sideButton" title="Play Song" id="playSong" src="../assets/playsong.png" style="position:absolute; right: 1%; top: 50%; width: 11%; height: auto;"></a>
|
<a class="songLink" href="https://www.newgrounds.com/audio/listen/[[SONGID]]" target="_blank"><img class="gdButton sideButton" title="Play Song" id="playSong" src="/assets/playsong.png" style="position:absolute; right: 1%; top: 50%; width: 11%; height: auto;"></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="center" style="position:absolute; bottom: 5%; left: 0; right: 0">
|
<div class="center" style="position:absolute; bottom: 5%; left: 0; right: 0">
|
||||||
|
@ -146,20 +146,20 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="center noClick" style="position:absolute; top: 24%; right: 0%; min-width: 100%">
|
<div class="center noClick" style="position:absolute; top: 24%; right: 0%; min-width: 100%">
|
||||||
<img class="gdButton yesClick" id="playButton" src="../assets/play.png" width="11%">
|
<img class="gdButton yesClick" id="playButton" src="/assets/play.png" width="11%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="levelButtons" style="position:absolute; top: 46%; right: 3.5%; transform: translateY(-50%); height: 75%;">
|
<div class="levelButtons" style="position:absolute; top: 46%; right: 3.5%; transform: translateY(-50%); height: 75%;">
|
||||||
<img class="gdButton sideButton" title="Save level" id="saveButton" src="../assets/plus.png" onclick="$('#saveDiv').show(); saveLevel()"><br>
|
<img class="gdButton sideButton" title="Save level" id="saveButton" src="/assets/plus.png" onclick="$('#saveDiv').show(); saveLevel()"><br>
|
||||||
<img class="gdButton sideButton" title="Level Info" id="infoButton" src="../assets/info.png" onclick="$('#infoDiv').show()"><br>
|
<img class="gdButton sideButton" title="Level Info" id="infoButton" src="/assets/info.png" onclick="$('#infoDiv').show()"><br>
|
||||||
<!-- <img class="gdButton sideButton" title="Rate Level" id="likeButton" src="../assets/vote.png" onclick="$('#likeDiv').show()"><br> -->
|
<!-- <img class="gdButton sideButton" title="Rate Level" id="likeButton" src="/assets/vote.png" onclick="$('#likeDiv').show()"><br> -->
|
||||||
<a href="./analyze/[[ID]]" id="analyzeLink"><img id="analyzeBtn" title="Analyze Level" class="gdButton sideButton" src="../assets/edit.png"></a><br>
|
<a href="./analyze/[[ID]]" id="analyzeLink"><img id="analyzeBtn" title="Analyze Level" class="gdButton sideButton" src="/assets/edit.png"></a><br>
|
||||||
<a href="./comments/[[ID]]"><img class="gdButton sideButton" title="View Comments" src="../assets/comment.png"></a><br>
|
<a href="./comments/[[ID]]"><img class="gdButton sideButton" title="View Comments" src="/assets/comment.png"></a><br>
|
||||||
<a href="./leaderboard/[[ID]]"><img id="leaderboardbtn" title="View Leaderboard" class="gdButton sideButton" src="../assets/leaderboard.png"></a><br>
|
<a href="./leaderboard/[[ID]]"><img id="leaderboardbtn" title="View Leaderboard" class="gdButton sideButton" src="/assets/leaderboard.png"></a><br>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; top: 2%; left: 1.5%; width: 10%; height: 25%; pointer-events: none">
|
<div style="position:absolute; top: 2%; left: 1.5%; width: 10%; height: 25%; pointer-events: none">
|
||||||
<img class="gdButton yesClick" id="backButton" src="../assets/back.png" height="30%" onclick="backButton()">
|
<img class="gdButton yesClick" id="backButton" src="/assets/back.png" height="30%" onclick="backButton()">
|
||||||
</div>
|
</div>
|
||||||
<div id="copied" style="display: none;">
|
<div id="copied" style="display: none;">
|
||||||
<div class="copied center noClick" style="position:absolute; top: 36%; left: 50%; transform: translate(-50%,-50%); width: 90vh">
|
<div class="copied center noClick" style="position:absolute; top: 36%; left: 50%; transform: translate(-50%,-50%); width: 90vh">
|
||||||
|
@ -171,7 +171,7 @@
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||||
<script type="text/javascript" src="../global.js?v=1"></script>
|
<script type="text/javascript" src="/misc/global.js?v=1"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
let messageText = 'Your <cy>Geometry Dash password</cy> will <cg>not be stored</cg> anywhere on the site, both <ca>locally and server-side.</ca> You can view the code used for liking a level <a class="menuLink" target="_blank" href="https://github.com/GDColon/GDBrowser/blob/master/api/post/like.js">here</a>.'
|
let messageText = 'Your <cy>Geometry Dash password</cy> will <cg>not be stored</cg> anywhere on the site, both <ca>locally and server-side.</ca> You can view the code used for liking a level <a class="menuLink" target="_blank" href="https://github.com/GDColon/GDBrowser/blob/master/api/post/like.js">here</a>.'
|
||||||
|
@ -193,22 +193,22 @@ if (window.location.href.endsWith('?download')) $('#infoDiv').show()
|
||||||
"Get a life", "...", "bruh moment", "Etched into thy's memory!", "h", "I feel physical pain", "Play it in GD!", "[[ID]]", "go away", "Every copy costs 2 cents!", "Un-copied!", "Copied++", "C O P I E D", "help me please", "Open GD to play the level!", "pretend you're playing it", "Anotha one!"]
|
"Get a life", "...", "bruh moment", "Etched into thy's memory!", "h", "I feel physical pain", "Play it in GD!", "[[ID]]", "go away", "Every copy costs 2 cents!", "Un-copied!", "Copied++", "C O P I E D", "help me please", "Open GD to play the level!", "pretend you're playing it", "Anotha one!"]
|
||||||
|
|
||||||
let copies = 0
|
let copies = 0
|
||||||
let animated = false;
|
let animated = false
|
||||||
let freeze = false;
|
let freeze = false
|
||||||
let dailyTime = Number('[[NEXTDAILY]]') || null
|
let dailyTime = Number('[[NEXTDAILY]]') || null
|
||||||
|
|
||||||
$('#playButton').click(function () {
|
$('#playButton').click(function () {
|
||||||
if (!($('#copied').is(':animated')) && !animated) {
|
if (!($('#copied').is(':animated')) && !animated) {
|
||||||
animated = true;
|
animated = true
|
||||||
copies += 1
|
copies += 1
|
||||||
$('#copied').stop().fadeIn(200).delay(500).fadeOut(500, function() {
|
$('#copied').stop().fadeIn(200).delay(500).fadeOut(500, function() {
|
||||||
animated = false
|
animated = false
|
||||||
if (copies > 1) $('#copiedText').text(copyMessages[Math.floor(Math.random()*(copies > 4 ? copyMessages.length : 6))].replace("[C]", copies))
|
if (copies > 1) $('#copiedText').text(copyMessages[randInt(0, copies > 4 ? copyMessages.length : 6)].replace("[C]", copies))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
var temp = $("<input>");
|
var temp = $("<input>");
|
||||||
$("body").append(temp);
|
$("body").append(temp)
|
||||||
temp.val('[[ID]]').select();
|
temp.val('[[ID]]').select()
|
||||||
document.execCommand("copy"); temp.remove()
|
document.execCommand("copy"); temp.remove()
|
||||||
})
|
})
|
||||||
$('.closeWindow').click(function () { if (!freeze) $(".popup").attr('style', 'display: none;') })
|
$('.closeWindow').click(function () { if (!freeze) $(".popup").attr('style', 'display: none;') })
|
||||||
|
@ -238,7 +238,7 @@ else {
|
||||||
.replace('[[TIME1]]', "")
|
.replace('[[TIME1]]', "")
|
||||||
.replace('[[TIME2]]', "")
|
.replace('[[TIME2]]', "")
|
||||||
.replace('[[UPLOAD]]', "")
|
.replace('[[UPLOAD]]', "")
|
||||||
.replace('[[UPDATE]]', "") +
|
.replace('[[UPDATE]]', "") +
|
||||||
`<br><a id="additional" class="youCanClickThis" href="/[[ID]]?download"><ca>Download additional info</ca></a>`
|
`<br><a id="additional" class="youCanClickThis" href="/[[ID]]?download"><ca>Download additional info</ca></a>`
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
@ -251,14 +251,13 @@ if ([[DIAMONDS]] == 0 || !'[[DEMONLIST]]'.startsWith("[")) $('.diamonds').hide()
|
||||||
|
|
||||||
if (!'[[DEMONLIST]]'.startsWith("[")) {
|
if (!'[[DEMONLIST]]'.startsWith("[")) {
|
||||||
$('.demonList').show()
|
$('.demonList').show()
|
||||||
$('#leaderboardbtn').attr('src', '../assets/demonleaderboard.png').parent().attr('href', '../demon/[[DEMONLIST]]')
|
$('#leaderboardbtn').attr('src', '/assets/demonleaderboard.png').parent().attr('href', '../demon/[[DEMONLIST]]')
|
||||||
}
|
}
|
||||||
else $('.demonList').remove()
|
else $('.demonList').remove()
|
||||||
|
|
||||||
if (!'[[DAILYNUMBER]]'.startsWith("[")) {
|
if (!'[[DAILYNUMBER]]'.startsWith("[")) {
|
||||||
$('#dailyIcon').attr('src', `../assets/crown-${'[[WEEKLY]]'.startsWith("[") ? "daily" : "weekly"}.png`)
|
$('#dailyIcon').attr('src', `../assets/crown-${'[[WEEKLY]]'.startsWith("[") ? "daily" : "weekly"}.png`)
|
||||||
$('.dailyLevel').show()
|
$('.dailyLevel').show()
|
||||||
|
|
||||||
if (dailyTime) {
|
if (dailyTime) {
|
||||||
$('#dailyTime').html(` (${colonize(dailyTime, true)})`)
|
$('#dailyTime').html(` (${colonize(dailyTime, true)})`)
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
Potentially unsafe external linkExternal links without noopener/noreferrer are a potential security risk. ## Potentially unsafe external link
External links without noopener/noreferrer are a potential security risk.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/75)
Is this because of using "/" instead of "../"? Is this because of using "/" instead of "../"?
|
|||||||
|
@ -282,10 +281,10 @@ if (!"[[GDPS]]".startsWith("[")) {
|
||||||
}
|
}
|
||||||
$('#leaderboardbtn').hide()
|
$('#leaderboardbtn').hide()
|
||||||
$('#checkSong').remove()
|
$('#checkSong').remove()
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("[[SONGAUTHOR]]" == "Unknown" || "[[INVALIDSONG]]" == "true") $('.songLink').hide()
|
if ("[[SONGAUTHOR]]" == "Unknown" || "[[INVALIDSONG]]" == "true") $('.songLink').hide()
|
||||||
if ("[[DISLIKED]]" == "true") $('#likeImg').attr('src', '../assets/dislike.png').css('transform', 'translateY(20%)')
|
if ("[[DISLIKED]]" == "true") $('#likeImg').attr('src', '/assets/dislike.png').css('transform', 'translateY(20%)')
|
||||||
|
|
||||||
if ($("#additional").hasClass('downloadDisabled')) {
|
if ($("#additional").hasClass('downloadDisabled')) {
|
||||||
$('#analyzeLink').removeAttr('href')
|
$('#analyzeLink').removeAttr('href')
|
||||||
|
@ -295,9 +294,9 @@ if ($("#additional").hasClass('downloadDisabled')) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let coinColor = [[VERIFIEDCOINS]] ? "silvercoin" : "browncoin"
|
let coinColor = [[VERIFIEDCOINS]] ? "silvercoin" : "browncoin"
|
||||||
if ([[COINS]] > 0) $("#coins").append(`<img src="../assets/${coinColor}.png" height="5%">`)
|
if ([[COINS]] > 0) $("#coins").append(`<img src="/assets/${coinColor}.png" height="5%">`)
|
||||||
if ([[COINS]] > 1) $("#coins").append(`<img class="squeeze" src="../assets/${coinColor}.png" height="5%">`)
|
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 ([[COINS]] > 2) $("#coins").append(`<img class="squeeze" src="/assets/${coinColor}.png" height="5%">`)
|
||||||
|
|
||||||
if ("[[GDPS]]".startsWith("1.9/")) $("#authorLink").attr('href', '/search/[[PLAYERID]]?user')
|
if ("[[GDPS]]".startsWith("1.9/")) $("#authorLink").attr('href', '/search/[[PLAYERID]]?user')
|
||||||
|
|
||||||
|
@ -319,43 +318,43 @@ $(window).on('load', function() {
|
||||||
if (overflow > 3) overflow = 3
|
if (overflow > 3) overflow = 3
|
||||||
$('#songname').addClass('smaller').css('font-size', (6 - (overflow)) + 'vh')
|
$('#songname').addClass('smaller').css('font-size', (6 - (overflow)) + 'vh')
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
let savedLevels = JSON.parse(localStorage.getItem('saved') || '[]');
|
let savedLevels = JSON.parse(localStorage.getItem('saved') || '[]')
|
||||||
let deleteMode = false;
|
let deleteMode = false
|
||||||
if (savedLevels.includes('[[ID]]')) $('#saveButton').attr('src', '../assets/delete.png').attr('onclick', '$("#deleteDiv").show()')
|
if (savedLevels.includes('[[ID]]')) $('#saveButton').attr('src', '/assets/delete.png').attr('onclick', '$("#deleteDiv").show()')
|
||||||
|
|
||||||
function saveLevel() {
|
function saveLevel() {
|
||||||
savedLevels.push('[[ID]]');
|
savedLevels.push('[[ID]]')
|
||||||
localStorage.setItem('saved', JSON.stringify(savedLevels));
|
localStorage.setItem('saved', JSON.stringify(savedLevels));
|
||||||
}
|
}
|
||||||
|
|
||||||
function savedLevel() {
|
function savedLevel() {
|
||||||
$('#saveButton').attr('src', '../assets/delete.png').attr('onclick', '$("#deleteDiv").show()')
|
$('#saveButton').attr('src', '/assets/delete.png').attr('onclick', '$("#deleteDiv").show()')
|
||||||
$('.popup').hide()
|
$('.popup').hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteLevel() {
|
function deleteLevel() {
|
||||||
savedLevels = savedLevels.filter(function(el) {return el != '[[ID]]'})
|
savedLevels = savedLevels.filter(function(el) {return el != '[[ID]]'})
|
||||||
localStorage.setItem('saved', JSON.stringify(savedLevels));
|
localStorage.setItem('saved', JSON.stringify(savedLevels));
|
||||||
$('#saveButton').attr('src', '../assets/plus.png').attr('onclick', '$("#saveDiv").show(); saveLevel()')
|
$('#saveButton').attr('src', '/assets/plus.png').attr('onclick', '$("#saveDiv").show(); saveLevel()')
|
||||||
$('.popup').hide()
|
$('.popup').hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#checkSong').click(function() {
|
$('#checkSong').click(function() {
|
||||||
$('#checkSong').hide()
|
$('#checkSong').hide()
|
||||||
$('#songLoading').show()
|
$('#songLoading').show()
|
||||||
fetch(`../api/song/[[SONGID]]`).then(res => res.json()).then(info => {
|
fetch(`/api/song/[[SONGID]]`).then(res => res.json()).then(info => {
|
||||||
$('#songLoading').hide()
|
$('#songLoading').hide()
|
||||||
$(info && info != -1 ? '#songAllowed' : '#songNotAllowed').show().addClass('songStatus')
|
$(info && info != -1 ? '#songAllowed' : '#songNotAllowed').show().addClass('songStatus')
|
||||||
// if (info.error) return
|
// if (info.error) return
|
||||||
// if (!info.artist.scouted) {
|
// if (!info.artist.scouted) {
|
||||||
// $('#scout').attr('src', '../assets/x.png')
|
// $('#scout').attr('src', '/assets/x.png')
|
||||||
// $('#scout').attr('title', $('#scout').attr('title').replace('is ', 'is NOT '))
|
// $('#scout').attr('title', $('#scout').attr('title').replace('is ', 'is NOT '))
|
||||||
// $('#scout').css('filter', 'saturate(0.4)')
|
// $('#scout').css('filter', 'saturate(0.4)')
|
||||||
// }
|
// }
|
||||||
// if (!info.artist.whitelisted) {
|
// if (!info.artist.whitelisted) {
|
||||||
// $('#whitelist').attr('src', '../assets/x.png')
|
// $('#whitelist').attr('src', '/assets/x.png')
|
||||||
// $('#whitelist').attr('title', $('#whitelist').attr('title').replace('is ', 'is NOT '))
|
// $('#whitelist').attr('title', $('#whitelist').attr('title').replace('is ', 'is NOT '))
|
||||||
// }
|
// }
|
||||||
// $('#scout').show(); $('#whitelist').show()
|
// $('#scout').show(); $('#whitelist').show()
|
||||||
|
@ -375,7 +374,7 @@ $('.artistIcon').hover(function() {
|
||||||
|
|
||||||
// let like;
|
// let like;
|
||||||
// let likedLevels = localStorage.likedLevels ? JSON.parse(localStorage.likedLevels) : []
|
// let likedLevels = localStorage.likedLevels ? JSON.parse(localStorage.likedLevels) : []
|
||||||
// if (likedLevels.includes('[[ID]]')) $('#likeButton').attr('src', '../assets/voted.png').removeClass('gdButton').prop("onclick", null)
|
// if (likedLevels.includes('[[ID]]')) $('#likeButton').attr('src', '/assets/voted.png').removeClass('gdButton').prop("onclick", null)
|
||||||
|
|
||||||
// $('#likebtn').click(function() {
|
// $('#likebtn').click(function() {
|
||||||
// $('#likebtn').removeClass('youAreNotTheOne')
|
// $('#likebtn').removeClass('youAreNotTheOne')
|
||||||
|
@ -405,7 +404,7 @@ $('.artistIcon').hover(function() {
|
||||||
// $('.postbutton').hide()
|
// $('.postbutton').hide()
|
||||||
// allowEsc = false
|
// allowEsc = false
|
||||||
|
|
||||||
// fetch(`../api/profile/${username}`).then(res => res.json()).then(res => {
|
// fetch(`/api/profile/${username}`).then(res => res.json()).then(res => {
|
||||||
// if (!res || res == "-1") {$('.postbutton').show(); return $('#message').text("The username you provided doesn't exist!")}
|
// if (!res || res == "-1") {$('.postbutton').show(); return $('#message').text("The username you provided doesn't exist!")}
|
||||||
// else accountID = res.accountID
|
// else accountID = res.accountID
|
||||||
|
|
||||||
|
@ -414,7 +413,7 @@ $('.artistIcon').hover(function() {
|
||||||
// likedLevels.push('[[ID]]')
|
// likedLevels.push('[[ID]]')
|
||||||
// localStorage.setItem('likedLevels', JSON.stringify(likedLevels))
|
// localStorage.setItem('likedLevels', JSON.stringify(likedLevels))
|
||||||
// location.reload()
|
// location.reload()
|
||||||
// })
|
// })
|
||||||
// .fail(e => {$('.postbutton').show();$('#message').text(e.responseText.includes("DOCTYPE") ? "Something went wrong..." : e.responseText)})
|
// .fail(e => {$('.postbutton').show();$('#message').text(e.responseText.includes("DOCTYPE") ? "Something went wrong..." : e.responseText)})
|
||||||
// })
|
// })
|
||||||
// })
|
// })
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<head>
|
<head>
|
||||||
<title>Leaderboard</title>
|
<title>Leaderboard</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link href="../assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
<link href="/assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
||||||
<link rel="icon" href="../assets/trophy.png">
|
<link rel="icon" href="/assets/trophy.png">
|
||||||
<meta id="meta-title" property="og:title" content="Level Leaderboard">
|
<meta id="meta-title" property="og:title" content="Level Leaderboard">
|
||||||
<meta id="meta-desc" property="og:description" content="View the leaderboard of a Geometry Dash level!">
|
<meta id="meta-desc" property="og:description" content="View the leaderboard of a Geometry Dash level!">
|
||||||
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/trophy.png">
|
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/trophy.png">
|
||||||
|
@ -15,17 +15,17 @@
|
||||||
<div id="everything" style="overflow: auto;">
|
<div id="everything" style="overflow: auto;">
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 0%; left: 0%; width: 100%">
|
<div style="position:absolute; bottom: 0%; left: 0%; width: 100%">
|
||||||
<img class="cornerPiece" src="../assets/corner.png" width=7%;>
|
<img class="cornerPiece" src="/assets/corner.png" width=7%;>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 0%; right: 0%; width: 100%; text-align: right;">
|
<div style="position:absolute; bottom: 0%; right: 0%; width: 100%; text-align: right;">
|
||||||
<img class="cornerPiece" src="../assets/corner.png" width=7%; style="transform: scaleX(-1)">
|
<img class="cornerPiece" src="/assets/corner.png" width=7%; style="transform: scaleX(-1)">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="searchBox" class="supercenter dragscroll"; style="width: 124vh">
|
<div id="searchBox" class="supercenter dragscroll"; style="width: 124vh">
|
||||||
<div style="height: 4.5%"></div>
|
<div style="height: 4.5%"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="epicbox supercenter gs" style="width: 126vh; height: 80%; pointer-events: none"></div>
|
<div class="epicbox supercenter gs" style="width: 126vh; height: 80%; pointer-events: none"></div>
|
||||||
|
|
||||||
<div class="center" style="position:absolute; top: 8%; left: 0%; right: 0%">
|
<div class="center" style="position:absolute; top: 8%; left: 0%; right: 0%">
|
||||||
|
@ -33,13 +33,13 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; top: 2%; left: 1.5%; width: 10%; height: 25%; pointer-events: none">
|
<div style="position:absolute; top: 2%; left: 1.5%; width: 10%; height: 25%; pointer-events: none">
|
||||||
<img class="gdButton yesClick" id="backButton" src="../assets/back.png" height="30%" onclick="backButton()">
|
<img class="gdButton yesClick" id="backButton" src="/assets/back.png" height="30%" onclick="backButton()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="supercenter" id="loading" style="height: 10%; top: 47%; display: none;">
|
<div class="supercenter" id="loading" style="height: 10%; top: 47%; display: none;">
|
||||||
<img class="spin noSelect" src="../assets/loading.png" height="105%">
|
<img class="spin noSelect" src="/assets/loading.png" height="105%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="error" class="supercenter" style="height: 20%; top: 47%; display: none;">
|
<div id="error" class="supercenter" style="height: 20%; top: 47%; display: none;">
|
||||||
<h1 class="center">No scores available...</h1>
|
<h1 class="center">No scores available...</h1>
|
||||||
<h3 class="center" style="margin-top: 2%">Either this leaderboard is empty, or the scores weren't able to be obtained from the GD servers.</h3>
|
<h3 class="center" style="margin-top: 2%">Either this leaderboard is empty, or the scores weren't able to be obtained from the GD servers.</h3>
|
||||||
|
@ -47,11 +47,11 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="supercenter" style="left: 87%; top: 24%; height: 10%">
|
<div class="supercenter" style="left: 87%; top: 24%; height: 10%">
|
||||||
<img class="gdButton darken" id="topMode" src="../assets/leaderboard-top.png" height="90%">
|
<img class="gdButton darken" id="topMode" src="/assets/leaderboard-top.png" height="90%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="supercenter" style="left: 87%; top: 35%; height: 10%">
|
<div class="supercenter" style="left: 87%; top: 35%; height: 10%">
|
||||||
<img class="gdButton" id="weekMode" src="../assets/leaderboard-week.png" height="90%">
|
<img class="gdButton" id="weekMode" src="/assets/leaderboard-week.png" height="90%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -59,12 +59,12 @@
|
||||||
</body>
|
</body>
|
||||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/6.2.2/browser/pixi.js"></script>
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/6.2.2/browser/pixi.js"></script>
|
||||||
<script type="text/javascript" src="../iconkit/icon.js"></script>
|
<script type="text/javascript" src="/iconkit/icon.js"></script>
|
||||||
<script type="text/javascript" src="../global.js?v=1"></script>
|
<script type="text/javascript" src="/misc/global.js?v=1"></script>
|
||||||
<script type="text/javascript" src="../dragscroll.js"></script>
|
<script type="text/javascript" src="/misc/dragscroll.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
let loading = false;
|
let loading = false
|
||||||
let lvlID = Math.round(window.location.pathname.split('/')[2])
|
let lvlID = Math.round(window.location.pathname.split('/')[2])
|
||||||
|
|
||||||
if (!lvlID || lvlID > 99999999 || lvlID < -99999999) window.location.href = window.location.href.replace("leaderboard", "search")
|
if (!lvlID || lvlID > 99999999 || lvlID < -99999999) window.location.href = window.location.href.replace("leaderboard", "search")
|
||||||
|
@ -78,7 +78,7 @@ function leaderboard() {
|
||||||
loading = true;
|
loading = true;
|
||||||
$('#loading').show()
|
$('#loading').show()
|
||||||
|
|
||||||
fetch(`../api/level/${lvlID}`).then(lvl => lvl.json()).then(lvl => {
|
fetch(`/api/level/${lvlID}`).then(lvl => lvl.json()).then(lvl => {
|
||||||
if (lvl == "-1") return $('#header').html("Nonexistent level " + lvlID)
|
if (lvl == "-1") return $('#header').html("Nonexistent level " + lvlID)
|
||||||
|
|
||||||
document.title = "Leaderboards for " + lvl.name
|
document.title = "Leaderboards for " + lvl.name
|
||||||
|
@ -86,9 +86,9 @@ function leaderboard() {
|
||||||
$('#meta-title').attr('content', "Leaderboards for " + lvl.name)
|
$('#meta-title').attr('content', "Leaderboards for " + lvl.name)
|
||||||
$('#meta-desc').attr('content', 'View the leaderboard for ' + lvl.name + ' by ' + lvl.author + '!')
|
$('#meta-desc').attr('content', 'View the leaderboard for ' + lvl.name + ' by ' + lvl.author + '!')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
fetch(`../api/leaderboardLevel/${lvlID}?count=200${weekly ? "&week" : ""}`).then(res => res.json()).then(res => {
|
|
||||||
|
fetch(`/api/leaderboardLevel/${lvlID}?count=200${weekly ? "&week" : ""}`).then(res => res.json()).then(res => {
|
||||||
|
|
||||||
if (!res || res.error || res == "-1") {
|
if (!res || res.error || res == "-1") {
|
||||||
loading = false;
|
loading = false;
|
||||||
|
@ -101,12 +101,12 @@ function leaderboard() {
|
||||||
res.forEach((x, y) => {
|
res.forEach((x, y) => {
|
||||||
|
|
||||||
$('#searchBox').append(`<div class="searchresult leaderboardSlot levelboardSlot" style="align-items: center; padding-left: 1vh; height: 15%; width: 100%; position: relative">
|
$('#searchBox').append(`<div class="searchresult leaderboardSlot levelboardSlot" style="align-items: center; padding-left: 1vh; height: 15%; width: 100%; position: relative">
|
||||||
|
|
||||||
<h2 class="center" style="width: 12%; margin: 0% 0% 0% 0.5%; transform: scale(${1 - (Math.max(0, String(x.rank).length - 1) * 0.2)}">${x.rank}</h2>
|
<h2 class="center" style="width: 12%; margin: 0% 0% 0% 0.5%; transform: scale(${1 - (Math.max(0, String(x.rank).length - 1) * 0.2)}">${x.rank}</h2>
|
||||||
<gdicon dontload="true" iconID=${x.icon.icon} cacheID=${x.playerID} iconForm="${x.icon.form}" col1="${x.icon.col1}" col2="${x.icon.col2}" glow="${x.icon.glow}" style="width: 7%; margin-bottom: 1%" imgStyle="width: 100%"></gdicon>
|
<gdicon dontload="true" iconID=${x.icon.icon} cacheID=${x.playerID} iconForm="${x.icon.form}" col1="${x.icon.col1}" col2="${x.icon.col2}" glow="${x.icon.glow}" style="width: 7%; margin-bottom: 1%" imgStyle="width: 100%"></gdicon>
|
||||||
<h2 class="small gdButton" style="font-size: 6.5vh; margin-right: 3%; margin-left: 3%"><a href="../u/${x.accountID}.">${x.username}</a></h2>
|
<h2 class="small gdButton" style="font-size: 6.5vh; margin-right: 3%; margin-left: 3%"><a href="../u/${x.accountID}.">${x.username}</a></h2>
|
||||||
<h3 class="lessSpaced" style="margin-top: 1.3%; margin-right: 2%">${x.percent}%</h3>
|
<h3 class="lessSpaced" style="margin-top: 1.3%; margin-right: 2%">${x.percent}%</h3>
|
||||||
${'<div style="width: 2%"><img class="valign" src="../assets/silvercoin.png" style="height: 33%"></div>'.repeat(x.coins)}
|
${'<div style="width: 2%"><img class="valign" src="/assets/silvercoin.png" style="height: 33%"></div>'.repeat(x.coins)}
|
||||||
|
|
||||||
<div class="center" style="text-align: right; position:absolute; right: 1.25%; height: 10%; width: 12.5%; top: 100%;">
|
<div class="center" style="text-align: right; position:absolute; right: 1.25%; height: 10%; width: 12.5%; top: 100%;">
|
||||||
<p class="commentDate">${x.date}</p>
|
<p class="commentDate">${x.date}</p>
|
||||||
|
@ -117,17 +117,17 @@ function leaderboard() {
|
||||||
|
|
||||||
$('#searchBox').append('<div style="height: 4.5%"></div>')
|
$('#searchBox').append('<div style="height: 4.5%"></div>')
|
||||||
loading = false;
|
loading = false;
|
||||||
$('#loading').hide();
|
$('#loading').hide()
|
||||||
lazyLoadIcons()
|
lazyLoadIcons()
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let weekly = false;
|
let weekly = false
|
||||||
leaderboard()
|
leaderboard()
|
||||||
|
|
||||||
$('#topMode').click(function() {
|
$('#topMode').click(function() {
|
||||||
if (!weekly || loading) return;
|
if (!weekly || loading) return
|
||||||
weekly = false
|
weekly = false
|
||||||
leaderboard()
|
leaderboard()
|
||||||
$('#weekMode').removeClass('darken')
|
$('#weekMode').removeClass('darken')
|
||||||
|
@ -135,12 +135,12 @@ function leaderboard() {
|
||||||
})
|
})
|
||||||
|
|
||||||
$('#weekMode').click(function() {
|
$('#weekMode').click(function() {
|
||||||
if (weekly || loading) return;
|
if (weekly || loading) return
|
||||||
weekly = true
|
weekly = true
|
||||||
leaderboard()
|
leaderboard()
|
||||||
$('#topMode').removeClass('darken')
|
$('#topMode').removeClass('darken')
|
||||||
$('#weekMode').addClass('darken')
|
$('#weekMode').addClass('darken')
|
||||||
});
|
})
|
||||||
|
|
||||||
function lazyLoadIcons() {
|
function lazyLoadIcons() {
|
||||||
let newIconFound = false
|
let newIconFound = false
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<head>
|
<head>
|
||||||
<title>Map Packs</title>
|
<title>Map Packs</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link href="../assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
<link href="/assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
||||||
<link rel="icon" href="../assets/folder.png">
|
<link rel="icon" href="/assets/folder.png">
|
||||||
<meta id="meta-title" property="og:title" content="Map Packs">
|
<meta id="meta-title" property="og:title" content="Map Packs">
|
||||||
<meta id="meta-desc" property="og:description" content="Collections of terrible Geometry Dash levels that people only play because of the absurd number of icons they unlock.">
|
<meta id="meta-desc" property="og:description" content="Collections of terrible Geometry Dash levels that people only play because of the absurd number of icons they unlock.">
|
||||||
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/folder.png">
|
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/folder.png">
|
||||||
|
@ -18,32 +18,32 @@
|
||||||
<h1 style="transform:scale(1.2)">Map Packs</h1>
|
<h1 style="transform:scale(1.2)">Map Packs</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<img id="loading" style="margin-top: 1%" class="spin noSelect" src="../assets/loading.png" height="12%">
|
<img id="loading" style="margin-top: 1%" class="spin noSelect" src="/assets/loading.png" height="12%">
|
||||||
|
|
||||||
<div id="packList">
|
<div id="packList">
|
||||||
<br>
|
<br>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; top: 2%; left: -1.95%; width: 10%; height: 25%; pointer-events: none">
|
<div style="position:absolute; top: 2%; left: -1.95%; width: 10%; height: 25%; pointer-events: none">
|
||||||
<img class="gdButton yesClick" id="backButton" src="../assets/back.png" height="30%" onclick="backButton()">
|
<img class="gdButton yesClick" id="backButton" src="/assets/back.png" height="30%" onclick="backButton()">
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||||
<script type="text/javascript" src="../global.js?v=1"></script>
|
<script type="text/javascript" src="/misc/global.js?v=1"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
fetch('../api/mappacks').then(res => res.json()).then(packs => {
|
fetch('/api/mappacks').then(res => res.json()).then(packs => {
|
||||||
$('#loading').hide()
|
$('#loading').hide()
|
||||||
packs.forEach(x => {
|
packs.forEach(x => {
|
||||||
$('#packList').append(`
|
$('#packList').append(`
|
||||||
<div class="mappack">
|
<div class="mappack">
|
||||||
<a href="../search/${x.levels.join(",")}?list&header=${encodeURIComponent(x.name)}">
|
<a href="../search/${x.levels.join(",")}?list&header=${encodeURIComponent(x.name)}">
|
||||||
<img src="../assets/difficulties/${x.difficulty}.png" width="42%"><br>
|
<img src="/assets/difficulties/${x.difficulty}.png" width="42%"><br>
|
||||||
<h3 class="gauntletText"">${x.name.replace("Pack", "<br>Pack")}<br>
|
<h3 class="gauntletText"">${x.name.replace("Pack", "<br>Pack")}<br>
|
||||||
<span style="color: rgb(${x.textColor})">${x.stars}</span><img class="valign" src="../assets/star.png" style="cursor: help; width: 14%; margin-left: 2%; transform: translateY(-10%);" title="Stars">
|
<span style="color: rgb(${x.textColor})">${x.stars}</span><img class="valign" src="/assets/star.png" style="cursor: help; width: 14%; margin-left: 2%; transform: translateY(-10%);" title="Stars">
|
||||||
<span style="color: rgb(${x.barColor})">${x.coins}</span><img class="valign" src="../assets/coin.png" style="cursor: help; width: 14%; margin-left: 2%; transform: translateY(-10%);" title="Secret Coins">
|
<span style="color: rgb(${x.barColor})">${x.coins}</span><img class="valign" src="/assets/coin.png" style="cursor: help; width: 14%; margin-left: 2%; transform: translateY(-10%);" title="Secret Coins">
|
||||||
</h3></div></a>`)
|
</h3></div></a>`)
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<head>
|
<head>
|
||||||
<title>Messages</title>
|
<title>Messages</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link href="../assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
<link href="/assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script>
|
||||||
<script>window.dataLayer = window.dataLayer || []; function gtag() { dataLayer.push(arguments); } gtag('js', new Date()); gtag('config', 'UA-135255146-3');</script>
|
<script>window.dataLayer = window.dataLayer || []; function gtag() { dataLayer.push(arguments); } gtag('js', new Date()); gtag('config', 'UA-135255146-3');</script>
|
||||||
<link rel="icon" href="../assets/messages.png">
|
<link rel="icon" href="/assets/messages.png">
|
||||||
<meta id="meta-title" property="og:title" content="Messages">
|
<meta id="meta-title" property="og:title" content="Messages">
|
||||||
<meta id="meta-desc" property="og:description" content="Read, write, and manage your Geometry Dash messages!">
|
<meta id="meta-desc" property="og:description" content="Read, write, and manage your Geometry Dash messages!">
|
||||||
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/messages.png">
|
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/messages.png">
|
||||||
|
@ -29,9 +29,9 @@
|
||||||
<div style="margin-bottom: 3%">
|
<div style="margin-bottom: 3%">
|
||||||
<p id="message" style="padding: 0% 10%; margin-top: 1.5%"></p>
|
<p id="message" style="padding: 0% 10%; margin-top: 1.5%"></p>
|
||||||
</div>
|
</div>
|
||||||
<img src="../assets/btn-cancel.png" height=11%; class="gdButton postbutton center"
|
<img src="/assets/btn-cancel.png" height=11%; class="gdButton postbutton center"
|
||||||
style="margin-right: 1%" onclick="backButton()">
|
style="margin-right: 1%" onclick="backButton()">
|
||||||
<img src="../assets/btn-submit.png" type="submit" height=11%; class="gdButton postbutton center"
|
<img src="/assets/btn-submit.png" type="submit" height=11%; class="gdButton postbutton center"
|
||||||
style="margin-left: 1%" id="logIn">
|
style="margin-left: 1%" id="logIn">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
<div class="brownbox center supercenter" style="height: 65%; width: 110vh">
|
<div class="brownbox center supercenter" style="height: 65%; width: 110vh">
|
||||||
<div style="position:absolute; top: 25%; width: 100%">
|
<div style="position:absolute; top: 25%; width: 100%">
|
||||||
<p id="msgCount" style="font-size: 3.5vh; margin-bottom: 5%"></p>
|
<p id="msgCount" style="font-size: 3.5vh; margin-bottom: 5%"></p>
|
||||||
<img class="spin noSelect" id="loadingicon" src="../assets/loading.png" width="10%">
|
<img class="spin noSelect" id="loadingicon" src="/assets/loading.png" width="10%">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -52,25 +52,25 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="text-align: left">
|
<div style="text-align: left">
|
||||||
<img class="gdButton inline" id="purge" src="../assets/trash-square.png" width="7%">
|
<img class="gdButton inline" id="purge" src="/assets/trash-square.png" width="7%">
|
||||||
<div id="selectCount" style="display: none; pointer-events: none;">
|
<div id="selectCount" style="display: none; pointer-events: none;">
|
||||||
<h3 class="center" style="font-size: 3vh; margin-top: 12%"></h3>
|
<h3 class="center" style="font-size: 3vh; margin-top: 12%"></h3>
|
||||||
</div>
|
</div>
|
||||||
<img class="gdButton inline" id="selectAll" src="../assets/select-all.png" width="15%"
|
<img class="gdButton inline" id="selectAll" src="/assets/select-all.png" width="15%"
|
||||||
style="margin: 0% 0% 0.5% 2%">
|
style="margin: 0% 0% 0.5% 2%">
|
||||||
<img class="gdButton inline" id="selectNone" src="../assets/select-none.png" width="15%"
|
<img class="gdButton inline" id="selectNone" src="/assets/select-none.png" width="15%"
|
||||||
style="display: none; margin: 0% 0% 0.5% 2%">
|
style="display: none; margin: 0% 0% 0.5% 2%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<img src="../assets/refresh.png" style="height: 13%;position: absolute;right: 0%;bottom: 0%;" onclick="page = 0; getMessages()" class="gdButton center sideSpaceB">
|
<img src="/assets/refresh.png" style="height: 13%;position: absolute;right: 0%;bottom: 0%;" onclick="page = 0; getMessages()" class="gdButton center sideSpaceB">
|
||||||
|
|
||||||
<div style="position: absolute; left: 0.5%; top: 45%; height: 11%;">
|
<div style="position: absolute; left: 0.5%; top: 45%; height: 11%;">
|
||||||
<img class="gdButton" style="display: none" id="pageDown" src="../assets/arrow-left.png"
|
<img class="gdButton" style="display: none" id="pageDown" src="/assets/arrow-left.png"
|
||||||
height="90%">
|
height="90%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position: absolute; right: 0.5%; top: 45%; height: 11%;">
|
<div style="position: absolute; right: 0.5%; top: 45%; height: 11%;">
|
||||||
<img class="gdButton" style="display: none" id="pageUp" src="../assets/arrow-right.png"
|
<img class="gdButton" style="display: none" id="pageUp" src="/assets/arrow-right.png"
|
||||||
height="90%">
|
height="90%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -84,19 +84,19 @@
|
||||||
<p class="bigger center" style="line-height: 6vh; margin-top: 1.5vh;">
|
<p class="bigger center" style="line-height: 6vh; margin-top: 1.5vh;">
|
||||||
Are you sure you want to <cr>delete</cr> this message?
|
Are you sure you want to <cr>delete</cr> this message?
|
||||||
</p>
|
</p>
|
||||||
<img src="../assets/btn-cancel-green.png" height=29%; class="gdButton center" onclick="$('#confirmDelete').hide()">
|
<img src="/assets/btn-cancel-green.png" height=29%; class="gdButton center" onclick="$('#confirmDelete').hide()">
|
||||||
<img src="../assets/btn-delete.png" height=29%; id="deleteCurrentMessage" class="gdButton center sideSpaceB">
|
<img src="/assets/btn-delete.png" height=29%; id="deleteCurrentMessage" class="gdButton center sideSpaceB">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="deleting" style="display: none">
|
<div id="deleting" style="display: none">
|
||||||
<h2 class="smaller center" style="font-size: 5.5vh">Delete</h2>
|
<h2 class="smaller center" style="font-size: 5.5vh">Delete</h2>
|
||||||
<p class="bigger center" style="line-height: 6vh; margin-top: 1.5vh;">Deleting message...</p>
|
<p class="bigger center" style="line-height: 6vh; margin-top: 1.5vh;">Deleting message...</p>
|
||||||
<img src="../assets/loading.png" class="spin noSelect" style="height: 35%; margin-top: -2%">
|
<img src="/assets/loading.png" class="spin noSelect" style="height: 35%; margin-top: -2%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="delete-error" style="display: none;">
|
<div id="delete-error" style="display: none;">
|
||||||
<img class="gdButton" src="../assets/close.png" style="width: 15%; position: absolute; top: -17.5%; left: -5.5vh" onclick="$('#delete-error').hide(); $('#confirmDelete').hide(); $('#preDelete').show()">
|
<img class="gdButton" src="/assets/close.png" style="width: 15%; position: absolute; top: -17.5%; left: -5.5vh" onclick="$('#delete-error').hide(); $('#confirmDelete').hide(); $('#preDelete').show()">
|
||||||
<img src="../assets/exclamation.png" style="height: 40%">
|
<img src="/assets/exclamation.png" style="height: 40%">
|
||||||
<p class="bigger" style="margin-bottom: 0%; margin-top: 2.5%">Something went wrong!</p>
|
<p class="bigger" style="margin-bottom: 0%; margin-top: 2.5%">Something went wrong!</p>
|
||||||
<p id="delError" style="font-size: 2.4vh; margin-top: 1%"></p>
|
<p id="delError" style="font-size: 2.4vh; margin-top: 1%"></p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -111,9 +111,9 @@
|
||||||
Are you sure you want to <cr>delete</cr> <span class="selectedAmount"
|
Are you sure you want to <cr>delete</cr> <span class="selectedAmount"
|
||||||
style="color: yelow"></span>?
|
style="color: yelow"></span>?
|
||||||
</p>
|
</p>
|
||||||
<img src="../assets/btn-cancel-green.png" height=29%; class="gdButton center"
|
<img src="/assets/btn-cancel-green.png" height=29%; class="gdButton center"
|
||||||
onclick="$('#bulkDelete').hide()">
|
onclick="$('#bulkDelete').hide()">
|
||||||
<img src="../assets/btn-delete.png" height=29%; id="bulkDeleteMessages"
|
<img src="/assets/btn-delete.png" height=29%; id="bulkDeleteMessages"
|
||||||
class="gdButton center sideSpaceB">
|
class="gdButton center sideSpaceB">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -121,12 +121,12 @@
|
||||||
<h2 class="smaller center" style="font-size: 5.5vh">Delete</h2>
|
<h2 class="smaller center" style="font-size: 5.5vh">Delete</h2>
|
||||||
<p class="bigger center" style="line-height: 6vh; margin-top: 1.5vh;">Deleting <span
|
<p class="bigger center" style="line-height: 6vh; margin-top: 1.5vh;">Deleting <span
|
||||||
class="selectedAmount"></span>...</p>
|
class="selectedAmount"></span>...</p>
|
||||||
<img src="../assets/loading.png" class="spin noSelect" style="height: 35%; margin-top: -2%">
|
<img src="/assets/loading.png" class="spin noSelect" style="height: 35%; margin-top: -2%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="bd-error" style="display: none;">
|
<div id="bd-error" style="display: none;">
|
||||||
<img class="gdButton" src="../assets/close.png" style="width: 15%; position: absolute; top: -17.5%; left: -5.5vh" onclick="$('#bd-error').hide(); $('#bulkDelete').hide(); $('#preBulkDelete').show()">
|
<img class="gdButton" src="/assets/close.png" style="width: 15%; position: absolute; top: -17.5%; left: -5.5vh" onclick="$('#bd-error').hide(); $('#bulkDelete').hide(); $('#preBulkDelete').show()">
|
||||||
<img src="../assets/exclamation.png" style="height: 40%">
|
<img src="/assets/exclamation.png" style="height: 40%">
|
||||||
<p class="bigger" style="margin-bottom: 0%; margin-top: 2.5%">Something went wrong!</p>
|
<p class="bigger" style="margin-bottom: 0%; margin-top: 2.5%">Something went wrong!</p>
|
||||||
<p id="bdError" style="font-size: 2.4vh; margin-top: 1%"></p>
|
<p id="bdError" style="font-size: 2.4vh; margin-top: 1%"></p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -136,16 +136,16 @@
|
||||||
<div id="selectedMessage" class="popup">
|
<div id="selectedMessage" class="popup">
|
||||||
<div class="bounce center supercenter" style="height: 70%; width: 115vh">
|
<div class="bounce center supercenter" style="height: 70%; width: 115vh">
|
||||||
<div class="bluebox center supercenter" style="width: 100%; height: 100%">
|
<div class="bluebox center supercenter" style="width: 100%; height: 100%">
|
||||||
<img class="gdButton" src="../assets/close.png" width="9%" style="position: absolute; top: -7.5%; left: -6.5vh" onclick="$('#selectedMessage').hide()">
|
<img class="gdButton" src="/assets/close.png" width="9%" style="position: absolute; top: -7.5%; left: -6.5vh" onclick="$('#selectedMessage').hide()">
|
||||||
<h1 id="messageSubject" class="smaller center" style="font-size: 5.5vh; min-height: 9%; margin-top: 1%"></h1>
|
<h1 id="messageSubject" class="smaller center" style="font-size: 5.5vh; min-height: 9%; margin-top: 1%"></h1>
|
||||||
<h3 id="messageAuthor" class="gold center gauntletText gdButton"></h3>
|
<h3 id="messageAuthor" class="gold center gauntletText gdButton"></h3>
|
||||||
<div class="transparentBox center" id="theMfMessage">
|
<div class="transparentBox center" id="theMfMessage">
|
||||||
<img id="messageLoad" src="../assets/loading.png" class="spin noSelect" style="width: 10%; margin-top: 15%">
|
<img id="messageLoad" src="/assets/loading.png" class="spin noSelect" style="width: 10%; margin-top: 15%">
|
||||||
<p id="messageBody"></p>
|
<p id="messageBody"></p>
|
||||||
</div>
|
</div>
|
||||||
<div id="messageOptions">
|
<div id="messageOptions">
|
||||||
<img class="gdButton" style="width: 8%" title="Reply" src="../assets/reply.png" id="replyButton">
|
<img class="gdButton" style="width: 8%" title="Reply" src="/assets/reply.png" id="replyButton">
|
||||||
<img class="gdButton" style="width: 8%" title="Delete" src="../assets/trash.png" id="deleteButton" onclick="$('#confirmDelete').show()">
|
<img class="gdButton" style="width: 8%" title="Delete" src="/assets/trash.png" id="deleteButton" onclick="$('#confirmDelete').show()">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -163,10 +163,10 @@
|
||||||
placeholder="Message"></textarea>
|
placeholder="Message"></textarea>
|
||||||
</div>
|
</div>
|
||||||
<p id="messageStatus" style="margin: 1% 0% 1.5% 0%; min-height: 5%;"></p>
|
<p id="messageStatus" style="margin: 1% 0% 1.5% 0%; min-height: 5%;"></p>
|
||||||
<img src="../assets/btn-cancel.png" height=10%; class="gdButton center"
|
<img src="/assets/btn-cancel.png" height=10%; class="gdButton center"
|
||||||
onclick="$('textarea').val(''); $('#sendMessage').hide()">
|
onclick="$('textarea').val(''); $('#sendMessage').hide()">
|
||||||
<img src="../assets/btn-submit.png" height=10%; id="postMessage" class="gdButton center sideSpaceB">
|
<img src="/assets/btn-submit.png" height=10%; id="postMessage" class="gdButton center sideSpaceB">
|
||||||
<img src="../assets/trash.png" style="height: 10%; position: absolute; right: 0%"
|
<img src="/assets/trash.png" style="height: 10%; position: absolute; right: 0%"
|
||||||
onclick="$('#postContent').val('');" class="gdButton center sideSpaceB">
|
onclick="$('#postContent').val('');" class="gdButton center sideSpaceB">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -176,19 +176,19 @@
|
||||||
<div class="bluebox bounce center supercenter" style="height: 27%; width: 55vh">
|
<div class="bluebox bounce center supercenter" style="height: 27%; width: 55vh">
|
||||||
|
|
||||||
<div id="reply-loading">
|
<div id="reply-loading">
|
||||||
<img src="../assets/loading.png" class="spin noSelect" style="height: 40%; margin-top: 7.5%">
|
<img src="/assets/loading.png" class="spin noSelect" style="height: 40%; margin-top: 7.5%">
|
||||||
<p class="bigger">Sending...</p>
|
<p class="bigger">Sending...</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="reply-sent" style="display: none;">
|
<div id="reply-sent" style="display: none;">
|
||||||
<img class="gdButton" src="../assets/close.png" style="width: 15%; position: absolute; top: -17.5%; left: -5.5vh" onclick="$('.popup').hide()">
|
<img class="gdButton" src="/assets/close.png" style="width: 15%; position: absolute; top: -17.5%; left: -5.5vh" onclick="$('.popup').hide()">
|
||||||
<img src="../assets/check.png" style="height: 40%; margin-top: 7.5%">
|
<img src="/assets/check.png" style="height: 40%; margin-top: 7.5%">
|
||||||
<p class="bigger">Message sent!</p>
|
<p class="bigger">Message sent!</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="reply-error" style="display: none;">
|
<div id="reply-error" style="display: none;">
|
||||||
<img class="gdButton" src="../assets/close.png" style="width: 15%; position: absolute; top: -17.5%; left: -5.5vh" onclick="$('.popup').hide()">
|
<img class="gdButton" src="/assets/close.png" style="width: 15%; position: absolute; top: -17.5%; left: -5.5vh" onclick="$('.popup').hide()">
|
||||||
<img src="../assets/exclamation.png" style="height: 40%; margin-top: 7.5%">
|
<img src="/assets/exclamation.png" style="height: 40%; margin-top: 7.5%">
|
||||||
<p class="bigger" style="margin-bottom: 0%;">Something went wrong!</p>
|
<p class="bigger" style="margin-bottom: 0%;">Something went wrong!</p>
|
||||||
<p style="font-size: 2.4vh; margin-top: 1%">Does the recipient have messages enabled?</p>
|
<p style="font-size: 2.4vh; margin-top: 1%">Does the recipient have messages enabled?</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -197,15 +197,15 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 0%; left: 0%; width: 100%; pointer-events: none;">
|
<div style="position:absolute; bottom: 0%; left: 0%; width: 100%; pointer-events: none;">
|
||||||
<img class="cornerPiece" src="../assets/corner.png" width=7%;>
|
<img class="cornerPiece" src="/assets/corner.png" width=7%;>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 0%; right: 0%; width: 100%; text-align: right; pointer-events: none;">
|
<div style="position:absolute; bottom: 0%; right: 0%; width: 100%; text-align: right; pointer-events: none;">
|
||||||
<img class="cornerPiece" src="../assets/corner.png" width=7%; style="transform: scaleX(-1)">
|
<img class="cornerPiece" src="/assets/corner.png" width=7%; style="transform: scaleX(-1)">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; top: 2%; left: 1.5%; width: 10%; height: 25%; pointer-events: none">
|
<div style="position:absolute; top: 2%; left: 1.5%; width: 10%; height: 25%; pointer-events: none">
|
||||||
<img class="gdButton yesClick" id="backButton" src="../assets/back.png" height="30%" onclick="backButton()">
|
<img class="gdButton yesClick" id="backButton" src="/assets/back.png" height="30%" onclick="backButton()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -213,18 +213,18 @@
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||||
<script type="text/javascript" src="../global.js?v=1"></script>
|
<script type="text/javascript" src="/misc/global.js?v=1"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
let accountID;
|
let accountID
|
||||||
let password;
|
let password
|
||||||
let page = 0;
|
let page = 0
|
||||||
let messageID = 0;
|
let messageID = 0
|
||||||
let playerID = 0;
|
let playerID = 0
|
||||||
let messages = [];
|
let messages = []
|
||||||
let messageStatus = {};
|
let messageStatus = {}
|
||||||
let cache = {};
|
let cache = {}
|
||||||
let loading = false;
|
let loading = false
|
||||||
|
|
||||||
let messageText = 'Your <cy>Geometry Dash password</cy> will <cg>not be stored</cg> anywhere on the site, both <ca>locally and server-side.</ca> For security, it will be <cy>forgotten</cy> when you exit this page.'
|
let messageText = 'Your <cy>Geometry Dash password</cy> will <cg>not be stored</cg> anywhere on the site, both <ca>locally and server-side.</ca> For security, it will be <cy>forgotten</cy> when you exit this page.'
|
||||||
$('#message').html(messageText)
|
$('#message').html(messageText)
|
||||||
|
@ -254,7 +254,7 @@
|
||||||
<label for="message-${y}" class="gdcheckbox gdButton"></label>
|
<label for="message-${y}" class="gdcheckbox gdButton"></label>
|
||||||
</div>${/*
|
</div>${/*
|
||||||
<div class="xButton hitbox">
|
<div class="xButton hitbox">
|
||||||
<img class="gdButton" style="width: 8%" src="../assets/xbutton.png">
|
<img class="gdButton" style="width: 8%" src="/assets/xbutton.png">
|
||||||
</div>*/""}
|
</div>*/""}
|
||||||
</div>`)
|
</div>`)
|
||||||
})
|
})
|
||||||
|
@ -272,7 +272,7 @@
|
||||||
$('#message').text("Logging in...")
|
$('#message').text("Logging in...")
|
||||||
$('.postbutton').hide()
|
$('.postbutton').hide()
|
||||||
|
|
||||||
fetch(`../api/profile/${username}`).then(res => res.json()).then(res => {
|
fetch(`/api/profile/${username}`).then(res => res.json()).then(res => {
|
||||||
if (!res || res == "-1") { $('.postbutton').show(); return $('#message').text("The username you provided doesn't exist!") }
|
if (!res || res == "-1") { $('.postbutton').show(); return $('#message').text("The username you provided doesn't exist!") }
|
||||||
else accountID = res.accountID
|
else accountID = res.accountID
|
||||||
|
|
||||||
|
@ -292,7 +292,7 @@
|
||||||
let targetUser = window.location.search.match(/(\?|&)sendTo=(.+)/)
|
let targetUser = window.location.search.match(/(\?|&)sendTo=(.+)/)
|
||||||
if (targetUser) {
|
if (targetUser) {
|
||||||
targetUser = decodeURIComponent(targetUser[2])
|
targetUser = decodeURIComponent(targetUser[2])
|
||||||
fetch(`../api/profile/${targetUser}`).then(res => res.json()).then(res => {
|
fetch(`/api/profile/${targetUser}`).then(res => res.json()).then(res => {
|
||||||
if (res == "-1" || !res) return;
|
if (res == "-1" || !res) return;
|
||||||
$('#replyAuthor').html(`<a href="../u/${res.accountID}." target="_blank">To: ${res.username}</a>`)
|
$('#replyAuthor').html(`<a href="../u/${res.accountID}." target="_blank">To: ${res.username}</a>`)
|
||||||
messageStatus[res.accountID] = [res.messages, res.username]
|
messageStatus[res.accountID] = [res.messages, res.username]
|
||||||
|
@ -321,7 +321,7 @@
|
||||||
$('#selectCount').hide()
|
$('#selectCount').hide()
|
||||||
$('#selectAll').show()
|
$('#selectAll').show()
|
||||||
$('#selectNone').hide()
|
$('#selectNone').hide()
|
||||||
$('#msgList').html('<img src="../assets/loading.png" class="spin noSelect" style="margin-top: 20%; height: 20%;">')
|
$('#msgList').html('<img src="/assets/loading.png" class="spin noSelect" style="margin-top: 20%; height: 20%;">')
|
||||||
$.post("../messages", { password, accountID, page })
|
$.post("../messages", { password, accountID, page })
|
||||||
.done(msgs => {
|
.done(msgs => {
|
||||||
messages = msgs
|
messages = msgs
|
||||||
|
@ -384,7 +384,7 @@
|
||||||
$('#deleteButton').show()
|
$('#deleteButton').show()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!messageStatus[msg.accountID]) fetch(`../api/profile/${msg.author}`).then(res => res.json()).then(res => {
|
if (!messageStatus[msg.accountID]) fetch(`/api/profile/${msg.author}`).then(res => res.json()).then(res => {
|
||||||
messageStatus[msg.accountID] = [res.messages, msg.author]
|
messageStatus[msg.accountID] = [res.messages, msg.author]
|
||||||
loadMsg()
|
loadMsg()
|
||||||
})
|
})
|
||||||
|
@ -392,10 +392,10 @@
|
||||||
loadMsg()
|
loadMsg()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.fail(e => {
|
.fail(e => {
|
||||||
$('#messageAuthor').html(' ')
|
$('#messageAuthor').html(' ')
|
||||||
$('#messageSubject').html(' ')
|
$('#messageSubject').html(' ')
|
||||||
$('#messageLoad').hide()
|
$('#messageLoad').hide()
|
||||||
$('#messageBody').html(e.responseText).show()
|
$('#messageBody').html(e.responseText).show()
|
||||||
$('#theMfMessage').attr('style', 'background-color: rgba(0, 0, 0, 0)')
|
$('#theMfMessage').attr('style', 'background-color: rgba(0, 0, 0, 0)')
|
||||||
})
|
})
|
||||||
|
@ -416,7 +416,7 @@
|
||||||
$('#preDelete').show()
|
$('#preDelete').show()
|
||||||
$('#deleting').hide()
|
$('#deleting').hide()
|
||||||
})
|
})
|
||||||
.fail(e => {
|
.fail(e => {
|
||||||
$('#deleting').hide()
|
$('#deleting').hide()
|
||||||
$('#delete-error').show()
|
$('#delete-error').show()
|
||||||
$('#delError').html(e.responseText)
|
$('#delError').html(e.responseText)
|
||||||
|
@ -450,7 +450,7 @@
|
||||||
$('#bulkDeleting').hide()
|
$('#bulkDeleting').hide()
|
||||||
$('#preBulkDelete').show()
|
$('#preBulkDelete').show()
|
||||||
})
|
})
|
||||||
.fail(e => {
|
.fail(e => {
|
||||||
$('#bulkDeleting').hide()
|
$('#bulkDeleting').hide()
|
||||||
$('#bd-error').show()
|
$('#bd-error').show()
|
||||||
$('#bdError').html(e.responseText)
|
$('#bdError').html(e.responseText)
|
||||||
|
@ -458,7 +458,7 @@
|
||||||
})
|
})
|
||||||
|
|
||||||
$('#replyButton').click(function() {
|
$('#replyButton').click(function() {
|
||||||
if (!messageStatus[playerID]) return;
|
if (!messageStatus[playerID]) return
|
||||||
let status = messageStatus[playerID][0]
|
let status = messageStatus[playerID][0]
|
||||||
let name = messageStatus[playerID][1]
|
let name = messageStatus[playerID][1]
|
||||||
$('#postMessage').removeClass('grayscale')
|
$('#postMessage').removeClass('grayscale')
|
||||||
|
@ -475,7 +475,7 @@
|
||||||
$('#postMessage').click(function () {
|
$('#postMessage').click(function () {
|
||||||
let subject = $('#postSubject').val()
|
let subject = $('#postSubject').val()
|
||||||
let message = $('#postContent').val()
|
let message = $('#postContent').val()
|
||||||
if (!subject || !message || !messageStatus[playerID] || messageStatus[playerID][0] == "off") return;
|
if (!subject || !message || !messageStatus[playerID] || messageStatus[playerID][0] == "off") return
|
||||||
allowEsc = false
|
allowEsc = false
|
||||||
$('#reply-loading').show()
|
$('#reply-loading').show()
|
||||||
$('#reply-sent').hide()
|
$('#reply-sent').hide()
|
||||||
|
@ -488,7 +488,7 @@
|
||||||
$('#reply-sent').show()
|
$('#reply-sent').show()
|
||||||
allowEsc = true
|
allowEsc = true
|
||||||
})
|
})
|
||||||
.fail(e => {
|
.fail(e => {
|
||||||
$('#reply-loading').hide()
|
$('#reply-loading').hide()
|
||||||
$('#reply-error').show()
|
$('#reply-error').show()
|
||||||
allowEsc = true
|
allowEsc = true
|
||||||
|
@ -518,10 +518,10 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).keydown(function (k) {
|
$(document).keydown(function (k) {
|
||||||
if (loading) return;
|
if (loading) return
|
||||||
|
|
||||||
if ($('#access').is(':visible')) {
|
if ($('#access').is(':visible')) {
|
||||||
if (k.which == 13) $('#logIn').trigger('click') //enter
|
if (k.which == 13) $('#logIn').trigger('click') //enter
|
||||||
else return;
|
else return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<head>
|
<head>
|
||||||
<title>Geometry Dash Browser!</title>
|
<title>Geometry Dash Browser!</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link href="../assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
<link href="/assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
||||||
<link rel="icon" href="../assets/keymaster-head.png">
|
<link rel="icon" href="/assets/keymaster-head.png">
|
||||||
<meta id="meta-title" property="og:title" content="Geometry Dash Browser!">
|
<meta id="meta-title" property="og:title" content="Geometry Dash Browser!">
|
||||||
<meta id="meta-desc" property="og:description" content="Browse all of Geometry Dash's online features, right from this handy little website! Levels, profiles, leaderboards, comments, and more!">
|
<meta id="meta-desc" property="og:description" content="Browse all of Geometry Dash's online features, right from this handy little website! Levels, profiles, leaderboards, comments, and more!">
|
||||||
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/coin.png">
|
<meta id="meta-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/coin.png">
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
<div id="everything" class="center" style="overflow: hidden">
|
<div id="everything" class="center" style="overflow: hidden">
|
||||||
<h2 style="margin-top: 2%; margin-bottom: 2.2%">RobTop's Purgatory</h2>
|
<h2 style="margin-top: 2%; margin-bottom: 2.2%">RobTop's Purgatory</h2>
|
||||||
<h1 id="msg" class="smaller" style="margin-bottom: 1.2%; white-space: normal;"> </h1>
|
<h1 id="msg" class="smaller" style="margin-bottom: 1.2%; white-space: normal;"> </h1>
|
||||||
<img id="glubfub" src="../assets/keymaster.png" height="25%" class="gdButton">
|
<img id="glubfub" src="/assets/keymaster.png" height="25%" class="gdButton">
|
||||||
|
|
||||||
|
|
||||||
<div id="footer" style="position: absolute; left: 1%; bottom: 0%; text-align: left">
|
<div id="footer" style="position: absolute; left: 1%; bottom: 0%; text-align: left">
|
||||||
|
@ -27,33 +27,33 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; top: 2.8%; left: 0.5%; width: 4.5%; text-align: right;">
|
<div style="position:absolute; top: 2.8%; left: 0.5%; width: 4.5%; text-align: right;">
|
||||||
<a href="../?home"><img class="gdButton" src="../assets/arrow-left.png" width=80%;"></a>
|
<a href="../?home"><img class="gdButton" src="/assets/arrow-left.png" width=80%;"></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 3%; right: 3%; width: 10%; text-align: right;">
|
<div style="position:absolute; bottom: 3%; right: 3%; width: 10%; text-align: right;">
|
||||||
<a href="../gdps"><img class="gdButton" src="../assets/basement.png" width=85%;"></a>
|
<a href="../gdps"><img class="gdButton" src="/assets/basement.png" width=85%;"></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 22%; right: 7%; width: 10%; text-align: right; pointer-events: none">
|
<div style="position:absolute; bottom: 22%; right: 7%; width: 10%; text-align: right; pointer-events: none">
|
||||||
<img src="../assets/privateservers.png" width=85%;">
|
<img src="/assets/privateservers.png" width=85%;">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; top: 15.5%; right: 7.5%; width: 10%; text-align: right; pointer-events: none">
|
<div style="position:absolute; top: 15.5%; right: 7.5%; width: 10%; text-align: right; pointer-events: none">
|
||||||
<img src="../assets/leaderboardarrow.png" width=85%;">
|
<img src="/assets/leaderboardarrow.png" width=85%;">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; top: 2.2%; right: 2.5%; text-align: right; width: 11%;">
|
<div style="position:absolute; top: 2.2%; right: 2.5%; text-align: right; width: 11%;">
|
||||||
<a href="../leaderboard"><img class="gdButton" src="../assets/leaderboard.png" width="55%"></a>
|
<a href="../leaderboard"><img class="gdButton" src="/assets/leaderboard.png" width="55%"></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; top: -1.5%; right: 11%; text-align: right; width: 10%;">
|
<div style="position:absolute; top: -1.5%; right: 11%; text-align: right; width: 10%;">
|
||||||
<a href="../iconkit"><img class="iconRope" src="../assets/iconrope.png" width="40%"></a>
|
<a href="../iconkit"><img class="iconRope" src="/assets/iconrope.png" width="40%"></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||||
<script type="text/javascript" src="../global.js?v=1"></script>
|
<script type="text/javascript" src="/misc/global.js?v=1"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
let line = 0
|
let line = 0
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<head>
|
<head>
|
||||||
<title>[[USERNAME]]'s Profile</title>
|
<title>[[USERNAME]]'s Profile</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link href="../assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
<link href="/assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
||||||
<link rel="icon" href="">
|
<link rel="icon" href="">
|
||||||
<meta id="meta-title" property="og:title" content="[[USERNAME]]'s profile">
|
<meta id="meta-title" property="og:title" content="[[USERNAME]]'s profile">
|
||||||
|
@ -26,16 +26,16 @@
|
||||||
<div style="min-height: 20%; max-height: 20%">
|
<div style="min-height: 20%; max-height: 20%">
|
||||||
<p id="message" style="padding: 0% 10%; margin-top: 2%"></p>
|
<p id="message" style="padding: 0% 10%; margin-top: 2%"></p>
|
||||||
</div>
|
</div>
|
||||||
<img src="../assets/btn-cancel.png" height=11%; class="postButton gdButton center" style="margin-right: 1%" onclick="$('#leavePost').hide(); $('textarea').val('')">
|
<img src="/assets/btn-cancel.png" height=11%; class="postButton gdButton center" style="margin-right: 1%" onclick="$('#leavePost').hide(); $('textarea').val('')">
|
||||||
<img src="../assets/btn-submit.png" type="submit" height=11%; class="postButton gdButton center" style="margin-left: 1%" id="submitComment">
|
<img src="/assets/btn-submit.png" type="submit" height=11%; class="postButton gdButton center" style="margin-left: 1%" id="submitComment">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="popup" id="likeComment">
|
<div class="popup" id="likeComment">
|
||||||
<div class="brownbox bounce center supercenter" style="height: 75%; width: 100vh">
|
<div class="brownbox bounce center supercenter" style="height: 75%; width: 100vh">
|
||||||
<h1 class="smaller center" style="font-size: 5.5vh">Vote</h1>
|
<h1 class="smaller center" style="font-size: 5.5vh">Vote</h1>
|
||||||
<img src="../assets/smashLike.png" id="likebtn" class="inline gdButton likeButton"><!--
|
<img src="/assets/smashLike.png" id="likebtn" class="inline gdButton likeButton"><!--
|
||||||
--><img src="../assets/smashDislike.png" id="dislikebtn" class="inline gdButton likeButton youAreNotTheOne">
|
--><img src="/assets/smashDislike.png" id="dislikebtn" class="inline gdButton likeButton youAreNotTheOne">
|
||||||
<form action="nothing lol">
|
<form action="nothing lol">
|
||||||
<h3 class="center">GD Username</h3>
|
<h3 class="center">GD Username</h3>
|
||||||
<input type="text" name="gdbrowser" id="like-username" maxlength="50" style="height: 8vh; width: 90%; text-align: center; margin-top: 0.5%">
|
<input type="text" name="gdbrowser" id="like-username" maxlength="50" style="height: 8vh; width: 90%; text-align: center; margin-top: 0.5%">
|
||||||
|
@ -45,11 +45,11 @@
|
||||||
<div style="min-height: 18%; max-height: 18%">
|
<div style="min-height: 18%; max-height: 18%">
|
||||||
<p id="likeMessage" style="padding: 0% 10%; margin-top: 2.5%"></p>
|
<p id="likeMessage" style="padding: 0% 10%; margin-top: 2.5%"></p>
|
||||||
</div>
|
</div>
|
||||||
<img src="../assets/btn-cancel.png" height=10%; class="postButton gdButton center" style="margin-right: 1%" onclick="$('#likeComment').hide(); $('#likebtn').trigger('click');">
|
<img src="/assets/btn-cancel.png" height=10%; class="postButton gdButton center" style="margin-right: 1%" onclick="$('#likeComment').hide(); $('#likebtn').trigger('click');">
|
||||||
<img src="../assets/btn-submit.png" type="submit" height=10%; class="postButton gdButton center" style="margin-left: 1%" id="submitVote">
|
<img src="/assets/btn-submit.png" type="submit" height=10%; class="postButton gdButton center" style="margin-left: 1%" id="submitVote">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="popup" id="settingsDiv">
|
<div class="popup" id="settingsDiv">
|
||||||
<div class="fancybox bounce center supercenter">
|
<div class="fancybox bounce center supercenter">
|
||||||
<h2 class="smaller center" style="font-size: 5.5vh">User Info</h2>
|
<h2 class="smaller center" style="font-size: 5.5vh">User Info</h2>
|
||||||
|
@ -58,43 +58,43 @@
|
||||||
Private Messages: [[DMS]]<br>
|
Private Messages: [[DMS]]<br>
|
||||||
Comment History: [[COMMENTS]]<br>
|
Comment History: [[COMMENTS]]<br>
|
||||||
</p>
|
</p>
|
||||||
<img src="../assets/ok.png" width=20%; class="gdButton center" onclick="$('#settingsDiv').hide()">
|
<img src="/assets/ok.png" width=20%; class="gdButton center" onclick="$('#settingsDiv').hide()">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 0%; left: 0%; width: 100%">
|
<div style="position:absolute; bottom: 0%; left: 0%; width: 100%">
|
||||||
<img class="cornerPiece" src="../assets/corner.png" width=7%;>
|
<img class="cornerPiece" src="/assets/corner.png" width=7%;>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 0%; right: 0%; width: 100%; text-align: right;">
|
<div style="position:absolute; bottom: 0%; right: 0%; width: 100%; text-align: right;">
|
||||||
<img class="cornerPiece" src="../assets/corner.png" width=7%; style="transform: scaleX(-1)">
|
<img class="cornerPiece" src="/assets/corner.png" width=7%; style="transform: scaleX(-1)">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; top: 2%; left: 1.5%; width: 10%; height: 25%; pointer-events: none">
|
<div style="position:absolute; top: 2%; left: 1.5%; width: 10%; height: 25%; pointer-events: none">
|
||||||
<img class="gdButton yesClick" id="backButton" src="../assets/back.png" height="30%" onclick="backButton()">
|
<img class="gdButton yesClick" id="backButton" src="/assets/back.png" height="30%" onclick="backButton()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="brownBox center supercenter" style="width: 135vh; height: 82%; margin-top: -0.7%">
|
<div class="brownBox center supercenter" style="width: 135vh; height: 82%; margin-top: -0.7%">
|
||||||
|
|
||||||
<div id="globalrank0" style="position: absolute; left: 0.3%; top: 1.5%; width: 18%; text-align: left">
|
<div id="globalrank0" style="position: absolute; left: 0.3%; top: 1.5%; width: 18%; text-align: left">
|
||||||
<p style="margin: 0;"><img src="../assets/trophy.png" class="inline valign help profileTrophy" width="22%" title="Global Rank"> [[RANK]]</p>
|
<p style="margin: 0;"><img src="/assets/trophy.png" class="inline valign help profileTrophy" width="22%" title="Global Rank"> [[RANK]]</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h1 class="veryBig inline" style="width: inherit">
|
<h1 class="veryBig inline" style="width: inherit">
|
||||||
<img class="inline valign" id="modBadge1" style="display: none; height: 7%; cursor:help" src="../assets/mod.png" title="[[USERNAME]] is a moderator!"><!--
|
<img class="inline valign" id="modBadge1" style="display: none; height: 7%; cursor:help" src="/assets/mod.png" title="[[USERNAME]] is a moderator!"><!--
|
||||||
--><img class="inline valign" id="modBadge2" style="display: none; height: 7%; cursor:help" src="../assets/mod-elder.png" title="[[USERNAME]] is an elder moderator!"><!--
|
--><img class="inline valign" id="modBadge2" style="display: none; height: 7%; cursor:help" src="/assets/mod-elder.png" title="[[USERNAME]] is an elder moderator!"><!--
|
||||||
--><img class="inline valign" id="modBadge3" style="display: none; height: 7%; cursor:help" src="../assets/mod-extra.png" title="[[USERNAME]] is a custom moderator! (tier [[MODERATOR]])"><!--
|
--><img class="inline valign" id="modBadge3" style="display: none; height: 7%; cursor:help" src="/assets/mod-extra.png" title="[[USERNAME]] is a custom moderator! (tier [[MODERATOR]])"><!--
|
||||||
--><span style="margin-left: 1%">[[USERNAME]]</span>
|
--><span style="margin-left: 1%">[[USERNAME]]</span>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<hr style="margin-bottom: 2%" class="profilePostHide">
|
<hr style="margin-bottom: 2%" class="profilePostHide">
|
||||||
<h3 id="collectibles" class="profilePostHide">
|
<h3 id="collectibles" class="profilePostHide">
|
||||||
<span id="stars">[[STARS]]</span> <img class="help valign" src="../assets/star.png" title="Stars">
|
<span id="stars">[[STARS]]</span> <img class="help valign" src="/assets/star.png" title="Stars">
|
||||||
<span id="diamonds">[[DIAMONDS]]</span> <img class="help valign" src="../assets/diamond.png" title="Diamonds">
|
<span id="diamonds">[[DIAMONDS]]</span> <img class="help valign" src="/assets/diamond.png" title="Diamonds">
|
||||||
<span id="coins">[[COINS]]</span> <img class="help valign" src="../assets/coin.png" title="Secret Coins">
|
<span id="coins">[[COINS]]</span> <img class="help valign" src="/assets/coin.png" title="Secret Coins">
|
||||||
<span id="usercoins">[[USERCOINS]]</span> <img class="help valign"src="../assets/silvercoin.png" title="User Coins">
|
<span id="usercoins">[[USERCOINS]]</span> <img class="help valign"src="/assets/silvercoin.png" title="User Coins">
|
||||||
<span id="demons">[[DEMONS]]</span> <img class="help valign"src="../assets/demon.png" title="Demons">
|
<span id="demons">[[DEMONS]]</span> <img class="help valign"src="/assets/demon.png" title="Demons">
|
||||||
<span id="creatorpoints" style="display: none"><span id="cp">[[CP]]</span> <img class="help valign" src="../assets/cp.png" title="Creator Points"></span>
|
<span id="creatorpoints" style="display: none"><span id="cp">[[CP]]</span> <img class="help valign" src="/assets/cp.png" title="Creator Points"></span>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div class="lightBox center profilePostHide" id="iconsDiv" style="margin: 2% auto; width: 105vh">
|
<div class="lightBox center profilePostHide" id="iconsDiv" style="margin: 2% auto; width: 105vh">
|
||||||
|
@ -105,45 +105,45 @@
|
||||||
<gdicon iconID=[[WAVE]] iconForm="wave" col1="[[COL1]]" col2="[[COL2]]" glow="[[GLOW]]" imgStyle="height: 7%"></gdicon>
|
<gdicon iconID=[[WAVE]] iconForm="wave" col1="[[COL1]]" col2="[[COL2]]" glow="[[GLOW]]" imgStyle="height: 7%"></gdicon>
|
||||||
<gdicon iconID=[[ROBOT]] iconForm="robot" col1="[[COL1]]" col2="[[COL2]]" glow="[[GLOW]]"></gdicon>
|
<gdicon iconID=[[ROBOT]] iconForm="robot" col1="[[COL1]]" col2="[[COL2]]" glow="[[GLOW]]"></gdicon>
|
||||||
<gdicon iconID=[[SPIDER]] iconForm="spider" col1="[[COL1]]" col2="[[COL2]]" glow="[[GLOW]]"></gdicon>
|
<gdicon iconID=[[SPIDER]] iconForm="spider" col1="[[COL1]]" col2="[[COL2]]" glow="[[GLOW]]"></gdicon>
|
||||||
<img src="../assets/deatheffects/[[DEATHEFFECT]].png" title="Death Effect [[DEATHEFFECT]]" id="deatheffect">
|
<img src="/assets/deatheffects/[[DEATHEFFECT]].png" title="Death Effect [[DEATHEFFECT]]" id="deatheffect">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="lightBox center dragscroll" id="statusDiv" normalHeight="36vh" compactHeight="69vh" style="margin: 2% auto; width: 105vh; height: 36vh; background-color: #BE6F3F">
|
<div class="lightBox center dragscroll" id="statusDiv" normalHeight="36vh" compactHeight="69vh" style="margin: 2% auto; width: 105vh; height: 36vh; background-color: #BE6F3F">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="center profilePostHide" style="margin: 1.5% auto 2.5% auto;">
|
<div class="center profilePostHide" style="margin: 1.5% auto 2.5% auto;">
|
||||||
<a id="msgA" target="_blank"><img src="../assets/messages.png" height="10%" id="msgButton" class="sideSpace gdButton" onclick="$('#settingsDiv').show()"></a>
|
<a id="msgA" target="_blank"><img src="/assets/messages.png" height="10%" id="msgButton" class="sideSpace gdButton" onclick="$('#settingsDiv').show()"></a>
|
||||||
<img src="../assets/friends.png" height="10%" id="friendButton" class="sideSpace gdButton" onclick="$('#settingsDiv').show()">
|
<img src="/assets/friends.png" height="10%" id="friendButton" class="sideSpace gdButton" onclick="$('#settingsDiv').show()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position: absolute; bottom: 0%; left: 12%;" class="profilePostHide">
|
<div style="position: absolute; bottom: 0%; left: 12%;" class="profilePostHide">
|
||||||
<p style="text-align: left; font-size: 2.2vh; color: rgba(0, 0, 0, 0.5)">Account ID: [[ACCOUNTID]]<br>Player ID: [[PLAYERID]]</p>
|
<p style="text-align: left; font-size: 2.2vh; color: rgba(0, 0, 0, 0.5)">Account ID: [[ACCOUNTID]]<br>Player ID: [[PLAYERID]]</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<img src="../assets/follow-off.png" id="followOff" class="gdButton profilePostHide" style="position: absolute; left: 4.5%; bottom: 1%; width: 6%">
|
<img src="/assets/follow-off.png" id="followOff" class="gdButton profilePostHide" style="position: absolute; left: 4.5%; bottom: 1%; width: 6%">
|
||||||
<img src="../assets/follow-on.png" id="followOn" class="gdButton profilePostHide" style="position: absolute; left: 4.5%; bottom: 1%; width: 6%; display: none">
|
<img src="/assets/follow-on.png" id="followOn" class="gdButton profilePostHide" style="position: absolute; left: 4.5%; bottom: 1%; width: 6%; display: none">
|
||||||
|
|
||||||
<a id="commentA"><img src="../assets/comments.png" class="gdButton" id="commentButton" style="position: absolute; right: 0.5%; bottom: 50%; width: 6%" onclick="$('#settingsDiv').show()"></a>
|
|
||||||
<img src="../assets/expanded-off.png" class="gdButton" id="compactMode" style="position: absolute; left: 2%; bottom: 45%; width: 6%">
|
|
||||||
|
|
||||||
<a href="../search/[[USERNAME]]?user"><img src="../assets/levels.png" class="gdButton" style="position: absolute; right: 0.5%; bottom: 1%; width: 6%"></a>
|
<a id="commentA"><img src="/assets/comments.png" class="gdButton" id="commentButton" style="position: absolute; right: 0.5%; bottom: 50%; width: 6%" onclick="$('#settingsDiv').show()"></a>
|
||||||
|
<img src="/assets/expanded-off.png" class="gdButton" id="compactMode" style="position: absolute; left: 2%; bottom: 45%; width: 6%">
|
||||||
|
|
||||||
|
<a href="../search/[[USERNAME]]?user"><img src="/assets/levels.png" class="gdButton" style="position: absolute; right: 0.5%; bottom: 1%; width: 6%"></a>
|
||||||
|
|
||||||
<div style="position: absolute; right: 0.5%; top: 0%; width: 6%">
|
<div style="position: absolute; right: 0.5%; top: 0%; width: 6%">
|
||||||
<a id="youtube" style="display: none" target="_blank" href="https://youtube.com/channel/[[YOUTUBE]]"><img src="../assets/youtube.png" class="gdButton socialButton"></a>
|
<a id="youtube" style="display: none" target="_blank" href="https://youtube.com/channel/[[YOUTUBE]]"><img src="/assets/youtube.png" class="gdButton socialButton"></a>
|
||||||
<a id="twitter" style="display: none" target="_blank" href="https://twitter.com/[[TWITTER]]"><img src="../assets/twitter.png" class="gdButton socialButton"></a>
|
<a id="twitter" style="display: none" target="_blank" href="https://twitter.com/[[TWITTER]]"><img src="/assets/twitter.png" class="gdButton socialButton"></a>
|
||||||
<a id="twitch" style="display: none" target="_blank" href="https://twitch.tv/[[TWITCH]]"><img src="../assets/twitch.png" class="gdButton socialButton"></a>
|
<a id="twitch" style="display: none" target="_blank" href="https://twitch.tv/[[TWITCH]]"><img src="/assets/twitch.png" class="gdButton socialButton"></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="supercenter" style="left: 5%; top: 65%; height: 10%">
|
<div class="supercenter" style="left: 5%; top: 65%; height: 10%">
|
||||||
<img class="gdButton" id="pageDown" style="display: none" src="../assets/arrow-left.png" height="95%" onclick="page -= 1; appendComments()">
|
<img class="gdButton" id="pageDown" style="display: none" src="/assets/arrow-left.png" height="95%" onclick="page -= 1; appendComments()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="supercenter" style="left: 95%; top: 65%; height: 10%;">
|
<div class="supercenter" style="left: 95%; top: 65%; height: 10%;">
|
||||||
<img class="gdButton" id="pageUp" src="../assets/arrow-right.png" height="95%" onclick="page += 1; appendComments()">
|
<img class="gdButton" id="pageUp" src="/assets/arrow-right.png" height="95%" onclick="page += 1; appendComments()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="postButton" style="position:absolute; bottom: 0%; left: 0%; width: 14%; text-align: left; transform: translate(-35%, 40%);">
|
<div id="postButton" style="position:absolute; bottom: 0%; left: 0%; width: 14%; text-align: left; transform: translate(-35%, 40%);">
|
||||||
<img class="gdButton" src="../assets/comment.png" width="60%" onclick="$('#content').trigger('input'); $('#leavePost').show();">
|
<img class="gdButton" src="/assets/comment.png" width="60%" onclick="$('#content').trigger('input'); $('#leavePost').show();">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -153,9 +153,9 @@
|
||||||
</body>
|
</body>
|
||||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/6.2.2/browser/pixi.js"></script>
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/6.2.2/browser/pixi.js"></script>
|
||||||
<script type="text/javascript" src="../iconkit/icon.js"></script>
|
<script type="text/javascript" src="/iconkit/icon.js"></script>
|
||||||
<script type="text/javascript" src="../global.js?v=1"></script>
|
<script type="text/javascript" src="/misc/global.js?v=1"></script>
|
||||||
<script type="text/javascript" src="../dragscroll.js"></script>
|
<script type="text/javascript" src="/misc/dragscroll.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ renderIcons()
|
||||||
// set favicon
|
// set favicon
|
||||||
$('#mainIcon').on('DOMNodeInserted', 'img', function () {
|
$('#mainIcon').on('DOMNodeInserted', 'img', function () {
|
||||||
$("link[rel='icon']").attr("href", $(this).attr("src"));
|
$("link[rel='icon']").attr("href", $(this).attr("src"));
|
||||||
});
|
})
|
||||||
|
|
||||||
let messageText = 'Your <cy>Geometry Dash password</cy> will <cg>not be stored</cg> anywhere on the site, both <ca>locally and server-side.</ca> You can view the code used for profile posts <a class="menuLink" target="_blank" href="https://github.com/GDColon/GDBrowser/blob/master/api/post/postProfileComment.js">here</a>.'
|
let messageText = 'Your <cy>Geometry Dash password</cy> will <cg>not be stored</cg> anywhere on the site, both <ca>locally and server-side.</ca> You can view the code used for profile posts <a class="menuLink" target="_blank" href="https://github.com/GDColon/GDBrowser/blob/master/api/post/postProfileComment.js">here</a>.'
|
||||||
$('#message').html(messageText)
|
$('#message').html(messageText)
|
||||||
|
@ -211,14 +211,14 @@ if (`[[TWITTER]]` != "null") $('#twitter').show()
|
||||||
if (`[[TWITCH]]` != "null") $('#twitch').show()
|
if (`[[TWITCH]]` != "null") $('#twitch').show()
|
||||||
|
|
||||||
let numRank = parseInt("[[RANK]]")
|
let numRank = parseInt("[[RANK]]")
|
||||||
if (numRank < 2) $(".profileTrophy").attr("src","../assets/trophies/1.png")
|
if (numRank < 2) $(".profileTrophy").attr("src","/assets/trophies/1.png")
|
||||||
else if (numRank <= 10) $(".profileTrophy").attr("src","../assets/trophies/2.png")
|
else if (numRank <= 10) $(".profileTrophy").attr("src","/assets/trophies/2.png")
|
||||||
else if (numRank <= 50 ) $(".profileTrophy").attr("src","../assets/trophies/3.png")
|
else if (numRank <= 50 ) $(".profileTrophy").attr("src","/assets/trophies/3.png")
|
||||||
else if (numRank <= 100) $(".profileTrophy").attr("src","../assets/trophies/4.png")
|
else if (numRank <= 100) $(".profileTrophy").attr("src","/assets/trophies/4.png")
|
||||||
else if (numRank <= 200) $(".profileTrophy").attr("src","../assets/trophies/5.png")
|
else if (numRank <= 200) $(".profileTrophy").attr("src","/assets/trophies/5.png")
|
||||||
else if (numRank <= 500) $(".profileTrophy").attr("src","../assets/trophies/6.png")
|
else if (numRank <= 500) $(".profileTrophy").attr("src","/assets/trophies/6.png")
|
||||||
else if (numRank <= 1000) $(".profileTrophy").attr("src","../assets/trophies/7.png")
|
else if (numRank <= 1000) $(".profileTrophy").attr("src","/assets/trophies/7.png")
|
||||||
else $(".profileTrophy").attr("src","../assets/trophies/0.png")
|
else $(".profileTrophy").attr("src","/assets/trophies/0.png")
|
||||||
|
|
||||||
let messages = "[[MESSAGES]]"
|
let messages = "[[MESSAGES]]"
|
||||||
let commenthistory = "[[COMMENTHISTORY]]"
|
let commenthistory = "[[COMMENTHISTORY]]"
|
||||||
|
@ -227,10 +227,10 @@ let reqMode = [[FRIENDREQUESTS]] ? "<cg>Enabled</cg>" : "<cr>Disabled</cr>"
|
||||||
let dmMode = messages == "all" ? "<cg>Public</cg>" : messages == "friends" ? "<cy>Friends Only</cy>" : "<cr>Disabled</cr>"
|
let dmMode = messages == "all" ? "<cg>Public</cg>" : messages == "friends" ? "<cy>Friends Only</cy>" : "<cr>Disabled</cr>"
|
||||||
let commentMode = commenthistory == "all" ? "<cg>Public</cg>" : commenthistory == "friends" ? "<cy>Friends Only</cy>" : "<cr>Disabled</cr>"
|
let commentMode = commenthistory == "all" ? "<cg>Public</cg>" : commenthistory == "friends" ? "<cy>Friends Only</cy>" : "<cr>Disabled</cr>"
|
||||||
|
|
||||||
if (commenthistory == "friends") $('#commentButton').attr('src', '../assets/comments-yellow.png')
|
if (commenthistory == "friends") $('#commentButton').attr('src', '/assets/comments-yellow.png')
|
||||||
else if (commenthistory == "off") $('#commentButton').attr('src', '../assets/comments-grey.png')
|
else if (commenthistory == "off") $('#commentButton').attr('src', '/assets/comments-grey.png')
|
||||||
else {
|
else {
|
||||||
$('#commentButton').attr('src', '../assets/comments.png').attr('onclick', '')
|
$('#commentButton').attr('src', '/assets/comments.png').attr('onclick', '')
|
||||||
$('#commentA').attr('href', '../comments/[[USERNAME]]')
|
$('#commentA').attr('href', '../comments/[[USERNAME]]')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,10 +239,10 @@ if (messages == "all") {
|
||||||
$('#msgA').attr('href', '../messages?sendTo=[[USERNAME]]')
|
$('#msgA').attr('href', '../messages?sendTo=[[USERNAME]]')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (messages == "friends") $('#msgButton').attr('src', '../assets/messages-yellow.png')
|
if (messages == "friends") $('#msgButton').attr('src', '/assets/messages-yellow.png')
|
||||||
else if (messages == "off") $('#msgButton').attr('src', '../assets/messages-grey.png')
|
else if (messages == "off") $('#msgButton').attr('src', '/assets/messages-grey.png')
|
||||||
|
|
||||||
if (![[FRIENDREQUESTS]]) $('#friendButton').attr('src', '../assets/friends-grey.png')
|
if (![[FRIENDREQUESTS]]) $('#friendButton').attr('src', '/assets/friends-grey.png')
|
||||||
|
|
||||||
$('#userInfo').html($('#userInfo').html()
|
$('#userInfo').html($('#userInfo').html()
|
||||||
.replace("[[REQS]]", reqMode)
|
.replace("[[REQS]]", reqMode)
|
||||||
|
@ -250,15 +250,15 @@ $('#userInfo').html($('#userInfo').html()
|
||||||
.replace("[[COMMENTS]]", commentMode) + (messages == "friends" ? "<br style='line-height: 69%'><a target='_blank' style='color: lime' class='youCanClickThis2' href='../messages?sendTo=[[USERNAME]]'>Send message</a><br>(if friended)" : ""))
|
.replace("[[COMMENTS]]", commentMode) + (messages == "friends" ? "<br style='line-height: 69%'><a target='_blank' style='color: lime' class='youCanClickThis2' href='../messages?sendTo=[[USERNAME]]'>Send message</a><br>(if friended)" : ""))
|
||||||
|
|
||||||
function appendComments() {
|
function appendComments() {
|
||||||
if (loadingComments) return;
|
if (loadingComments) return
|
||||||
else loadingComments = true;
|
else loadingComments = true;
|
||||||
|
|
||||||
$('#statusDiv').html(`<div class="supercenter" id="loading" style="height: 12%; top: 62%;"><img class="spin noSelect" src="../assets/loading.png" height="105%"></div>`)
|
$('#statusDiv').html(`<div class="supercenter" id="loading" style="height: 12%; top: 62%;"><img class="spin noSelect" src="/assets/loading.png" height="105%"></div>`)
|
||||||
|
|
||||||
if (page == 0) $('#pageDown').hide()
|
if (page == 0) $('#pageDown').hide()
|
||||||
else $('#pageDown').show()
|
else $('#pageDown').show()
|
||||||
|
|
||||||
Fetch(`../api/comments/[[ACCOUNTID]]?type=profile&page=${page}`).then(res => {
|
Fetch(`/api/comments/[[ACCOUNTID]]?type=profile&page=${page}`).then(res => {
|
||||||
|
|
||||||
if (res.length != 10) $('#pageUp').hide()
|
if (res.length != 10) $('#pageUp').hide()
|
||||||
else $('#pageUp').show()
|
else $('#pageUp').show()
|
||||||
|
@ -277,7 +277,7 @@ function appendComments() {
|
||||||
</div>
|
</div>
|
||||||
<p class="commentDate">${x.date}</p>
|
<p class="commentDate">${x.date}</p>
|
||||||
<div class="commentLikes">
|
<div class="commentLikes">
|
||||||
<img id="likeImg" class="likeComment gdButton inline" commentID="${x.ID}" ${x.likes < 0 ? "style='transform: translateY(25%)'" : ""} src="../assets/${x.likes < 0 ? "dis" : ""}like.png" height=20% style="margin-right: 0.4%">
|
<img id="likeImg" class="likeComment gdButton inline" commentID="${x.ID}" ${x.likes < 0 ? "style='transform: translateY(25%)'" : ""} src="/assets/${x.likes < 0 ? "dis" : ""}like.png" height=20% style="margin-right: 0.4%">
|
||||||
<h3 class="inline">${x.likes}</h3><br>
|
<h3 class="inline">${x.likes}</h3><br>
|
||||||
</div>
|
</div>
|
||||||
</div>`)
|
</div>`)
|
||||||
|
@ -325,9 +325,9 @@ $('#submitComment').click(function () {
|
||||||
.fail(e => { allowEsc = true; $('.postbutton').show(); $('#message').text(e.responseText.includes("DOCTYPE") ? "Something went wrong..." : e.responseText) })
|
.fail(e => { allowEsc = true; $('.postbutton').show(); $('#message').text(e.responseText.includes("DOCTYPE") ? "Something went wrong..." : e.responseText) })
|
||||||
})
|
})
|
||||||
|
|
||||||
let commentID = 0;
|
let commentID = 0
|
||||||
let likeCount, likeImg;
|
let likeCount, likeImg
|
||||||
let likedComments;
|
let likedComments
|
||||||
let like = true;
|
let like = true;
|
||||||
|
|
||||||
$('#likebtn').click(function() {
|
$('#likebtn').click(function() {
|
||||||
|
@ -346,7 +346,7 @@ $(document).on('click', '.likeComment', function(cmnt) {
|
||||||
commentID = $(this).attr('commentID')
|
commentID = $(this).attr('commentID')
|
||||||
|
|
||||||
likedComments = localStorage.likedComments ? JSON.parse(localStorage.likedComments) : []
|
likedComments = localStorage.likedComments ? JSON.parse(localStorage.likedComments) : []
|
||||||
if (likedComments.includes(commentID)) return;
|
if (likedComments.includes(commentID)) return
|
||||||
|
|
||||||
lvID = $(this).attr('levelID') || 0
|
lvID = $(this).attr('levelID') || 0
|
||||||
likeImg = $(this).find('img')
|
likeImg = $(this).find('img')
|
||||||
|
@ -356,7 +356,7 @@ $(document).on('click', '.likeComment', function(cmnt) {
|
||||||
|
|
||||||
$('#submitVote').click(function() {
|
$('#submitVote').click(function() {
|
||||||
|
|
||||||
if (likedComments.includes(commentID)) return $('#likeMessage').text("You've already liked/disliked this comment!");
|
if (likedComments.includes(commentID)) return $('#likeMessage').text("You've already liked/disliked this comment!")
|
||||||
|
|
||||||
let ID = commentID
|
let ID = commentID
|
||||||
let username = $('#like-username').val()
|
let username = $('#like-username').val()
|
||||||
|
@ -364,14 +364,14 @@ $('#submitVote').click(function() {
|
||||||
let extraID = lvID || window.location.pathname.split('/')[2]
|
let extraID = lvID || window.location.pathname.split('/')[2]
|
||||||
let accountID = 0
|
let accountID = 0
|
||||||
let likeType = like ? "1" : "0"
|
let likeType = like ? "1" : "0"
|
||||||
|
|
||||||
if (!ID || !username || !password || loadingComments) return $('#postComment').hide()
|
if (!ID || !username || !password || loadingComments) return $('#postComment').hide()
|
||||||
|
|
||||||
$('#likeMessage').text(like ? "Liking..." : "Disliking... :(")
|
$('#likeMessage').text(like ? "Liking..." : "Disliking... :(")
|
||||||
$('.postbutton').hide()
|
$('.postbutton').hide()
|
||||||
allowEsc = false
|
allowEsc = false
|
||||||
|
|
||||||
Fetch(`../api/profile/${username}`).then(res => {
|
Fetch(`/api/profile/${username}`).then(res => {
|
||||||
if (!res || res == "-1") {allowEsc = true; $('.postbutton').show(); return $('#likeMessage').text("The username you provided doesn't exist!")}
|
if (!res || res == "-1") {allowEsc = true; $('.postbutton').show(); return $('#likeMessage').text("The username you provided doesn't exist!")}
|
||||||
else accountID = res.accountID
|
else accountID = res.accountID
|
||||||
|
|
||||||
|
@ -379,8 +379,8 @@ $('#submitVote').click(function() {
|
||||||
.done(x => {
|
.done(x => {
|
||||||
let newCount = parseInt(likeCount.text()) + (like ? 1 : -1)
|
let newCount = parseInt(likeCount.text()) + (like ? 1 : -1)
|
||||||
likeCount.text(newCount)
|
likeCount.text(newCount)
|
||||||
if (newCount < 0) likeImg.attr('src', '../assets/dislike.png').css('transform', compact ? 'translateY(15%)' : 'translateY(25%)')
|
if (newCount < 0) likeImg.attr('src', '/assets/dislike.png').css('transform', compact ? 'translateY(15%)' : 'translateY(25%)')
|
||||||
else likeImg.attr('src', '../assets/like.png').removeAttr('style')
|
else likeImg.attr('src', '/assets/like.png').removeAttr('style')
|
||||||
$('#likeComment').hide()
|
$('#likeComment').hide()
|
||||||
$('#likebtn').trigger('click')
|
$('#likebtn').trigger('click')
|
||||||
$('.postbutton').show()
|
$('.postbutton').show()
|
||||||
|
@ -388,7 +388,7 @@ $('#submitVote').click(function() {
|
||||||
allowEsc = true
|
allowEsc = true
|
||||||
likedComments.push(commentID)
|
likedComments.push(commentID)
|
||||||
localStorage.setItem('likedComments', JSON.stringify(likedComments))
|
localStorage.setItem('likedComments', JSON.stringify(likedComments))
|
||||||
})
|
})
|
||||||
.fail(e => {allowEsc = true; $('.postbutton').show();$('#likeMessage').text(e.responseText.includes("DOCTYPE") ? "Something went wrong..." : e.responseText)})
|
.fail(e => {allowEsc = true; $('.postbutton').show();$('#likeMessage').text(e.responseText.includes("DOCTYPE") ? "Something went wrong..." : e.responseText)})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -400,14 +400,14 @@ $('#compactMode').click(function() {
|
||||||
$('.profilePostHide').hide()
|
$('.profilePostHide').hide()
|
||||||
$('.statusIcon').show()
|
$('.statusIcon').show()
|
||||||
$('#statusDiv').css('height', $('#statusDiv').attr('compactHeight'))
|
$('#statusDiv').css('height', $('#statusDiv').attr('compactHeight'))
|
||||||
$(this).attr('src', "../assets/expanded-on.png")
|
$(this).attr('src', "/assets/expanded-on.png")
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
$('.profilePostHide').show()
|
$('.profilePostHide').show()
|
||||||
$('.statusIcon').hide()
|
$('.statusIcon').hide()
|
||||||
$('#statusDiv').css('height', $('#statusDiv').attr('normalHeight'))
|
$('#statusDiv').css('height', $('#statusDiv').attr('normalHeight'))
|
||||||
$(this).attr('src', "../assets/expanded-off.png")
|
$(this).attr('src', "/assets/expanded-off.png")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -416,12 +416,12 @@ $('#leavePost').on("change keyup keydown paste click", "textarea", function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
$(document).keydown(function(k) {
|
$(document).keydown(function(k) {
|
||||||
|
|
||||||
if ($('#content').is(':visible')) {
|
if ($('#content').is(':visible')) {
|
||||||
if (k.which == 13) k.preventDefault() //enter
|
if (k.which == 13) k.preventDefault() //enter
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loadingComments || $('.popup').is(":visible")) return;
|
if (loadingComments || $('.popup').is(":visible")) return
|
||||||
|
|
||||||
if (k.which == 37 && $('#pageDown').is(":visible")) { //left
|
if (k.which == 37 && $('#pageDown').is(":visible")) { //left
|
||||||
$('#pageDown').trigger('click')
|
$('#pageDown').trigger('click')
|
||||||
|
@ -431,7 +431,7 @@ $(document).keydown(function(k) {
|
||||||
$('#pageUp').trigger('click')
|
$('#pageUp').trigger('click')
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
132
html/search.html
|
@ -1,9 +1,9 @@
|
||||||
<head>
|
<head>
|
||||||
<title id="tabTitle">Level Search</title>
|
<title id="tabTitle">Level Search</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link href="../assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
<link href="/assets/css/browser.css?v=1" type="text/css" rel="stylesheet">
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135255146-3"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', 'UA-135255146-3');</script>
|
||||||
<link rel="icon" href="../assets/coin.png">
|
<link rel="icon" href="/assets/coin.png">
|
||||||
<meta id="meta-title" property="og:title" content="Level Search">
|
<meta id="meta-title" property="og:title" content="Level Search">
|
||||||
<meta id="meta-desc" property="og:description" content="Search for Geometry Dash levels, and filter by length, difficulty, song + more!">
|
<meta id="meta-desc" property="og:description" content="Search for Geometry Dash levels, and filter by length, difficulty, song + more!">
|
||||||
<meta id="meta-image" name="og:image" itemprop="image" content="../coin.png">
|
<meta id="meta-image" name="og:image" itemprop="image" content="../coin.png">
|
||||||
|
@ -18,15 +18,15 @@
|
||||||
<div class="brownbox bounce center supercenter" style="width: 60vh; height: 34%">
|
<div class="brownbox bounce center supercenter" style="width: 60vh; height: 34%">
|
||||||
<h2 class="smaller center" style="font-size: 5.5vh; margin-top: 1%">Jump to Page</h2>
|
<h2 class="smaller center" style="font-size: 5.5vh; margin-top: 1%">Jump to Page</h2>
|
||||||
<input type="number" id="pageSelect" placeholder="1"><br>
|
<input type="number" id="pageSelect" placeholder="1"><br>
|
||||||
<img src="../assets/ok.png" height=20%; id="pageJump" class="gdButton center closeWindow">
|
<img src="/assets/ok.png" height=20%; id="pageJump" class="gdButton center closeWindow">
|
||||||
<img class="closeWindow gdButton" src="../assets/close.png" height="25%" style="position: absolute; top: -13.5%; left: -6vh">
|
<img class="closeWindow gdButton" src="/assets/close.png" height="25%" style="position: absolute; top: -13.5%; left: -6vh">
|
||||||
|
|
||||||
<div class="supercenter" style="left: 25%; top: 43%; height: 10%;">
|
<div class="supercenter" style="left: 25%; top: 43%; height: 10%;">
|
||||||
<img class="gdButton" src="../assets/whitearrow-left.png" height="160%" onclick="$('#pageSelect').val(parseInt($('#pageSelect').val() || 0) - 1); $('#pageSelect').trigger('input');">
|
<img class="gdButton" src="/assets/whitearrow-left.png" height="160%" onclick="$('#pageSelect').val(parseInt($('#pageSelect').val() || 0) - 1); $('#pageSelect').trigger('input');">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="supercenter" style="left: 75%; top: 43%; height: 10%;">
|
<div class="supercenter" style="left: 75%; top: 43%; height: 10%;">
|
||||||
<img class="gdButton" src="../assets/whitearrow-right.png" height="160%" onclick="$('#pageSelect').val(parseInt($('#pageSelect').val() || 0) + 1); $('#pageSelect').trigger('input');">
|
<img class="gdButton" src="/assets/whitearrow-right.png" height="160%" onclick="$('#pageSelect').val(parseInt($('#pageSelect').val() || 0) + 1); $('#pageSelect').trigger('input');">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -37,8 +37,8 @@
|
||||||
<p class="bigger center" style="line-height: 5vh; margin-top: 1.5vh;">
|
<p class="bigger center" style="line-height: 5vh; margin-top: 1.5vh;">
|
||||||
Delete all saved online levels?<br><cy>Levels will be cleared from your browser.</cy>
|
Delete all saved online levels?<br><cy>Levels will be cleared from your browser.</cy>
|
||||||
</p>
|
</p>
|
||||||
<img src="../assets/btn-cancel-green.png" height=25%; class="gdButton center closeWindow">
|
<img src="/assets/btn-cancel-green.png" height=25%; class="gdButton center closeWindow">
|
||||||
<img src="../assets/btn-delete.png" height=25%; id="purgeSaved" class="gdButton center sideSpaceB">
|
<img src="/assets/btn-delete.png" height=25%; id="purgeSaved" class="gdButton center sideSpaceB">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -49,22 +49,22 @@
|
||||||
A random level cannot be picked with your current <cy>search filters!</cy>
|
A random level cannot be picked with your current <cy>search filters!</cy>
|
||||||
This is because there is no way to tell how many results were found, due to the GD servers inaccurately saying there's <cg>9999</cg>.
|
This is because there is no way to tell how many results were found, due to the GD servers inaccurately saying there's <cg>9999</cg>.
|
||||||
</p>
|
</p>
|
||||||
<img src="../assets/ok.png" width=20%; class="gdButton center closeWindow">
|
<img src="/assets/ok.png" width=20%; class="gdButton center closeWindow">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 0%; left: 0%; width: 100%">
|
<div style="position:absolute; bottom: 0%; left: 0%; width: 100%">
|
||||||
<img class="cornerPiece" src="../assets/corner.png" width=7%;>
|
<img class="cornerPiece" src="/assets/corner.png" width=7%;>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 0%; right: 0%; width: 100%; text-align: right;">
|
<div style="position:absolute; bottom: 0%; right: 0%; width: 100%; text-align: right;">
|
||||||
<img class="cornerPiece" src="../assets/corner.png" width=7%; style="transform: scaleX(-1)">
|
<img class="cornerPiece" src="/assets/corner.png" width=7%; style="transform: scaleX(-1)">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="searchBox" class="supercenter dragscroll">
|
<div id="searchBox" class="supercenter dragscroll">
|
||||||
<div style="height: 4.5%"></div>
|
<div style="height: 4.5%"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="epicbox supercenter gs" style="width: 120vh; height: 80%; pointer-events: none;"></div>
|
<div class="epicbox supercenter gs" style="width: 120vh; height: 80%; pointer-events: none;"></div>
|
||||||
|
|
||||||
<div class="center" style="position:absolute; top: 8%; left: 0%; right: 0%">
|
<div class="center" style="position:absolute; top: 8%; left: 0%; right: 0%">
|
||||||
|
@ -76,61 +76,62 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div title="Jump to page" style="text-align: right; position:absolute; top: 7.5%; right: 2%; height: 12%;">
|
<div title="Jump to page" style="text-align: right; position:absolute; top: 7.5%; right: 2%; height: 12%;">
|
||||||
<img src="../assets/magnify.png" height="60%" class="gdButton" style="margin-top: 5%" onclick="$('#pageDiv').show(); $('#pageSelect').focus().select()">
|
<img src="/assets/magnify.png" height="60%" class="gdButton" style="margin-top: 5%" onclick="$('#pageDiv').show(); $('#pageSelect').focus().select()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="shuffle" title="Random level" style="display: none; text-align: right; position:absolute; top: 7.5%; right: 6.5%; height: 12%;">
|
<div id="shuffle" title="Random level" style="display: none; text-align: right; position:absolute; top: 7.5%; right: 6.5%; height: 12%;">
|
||||||
<img src="../assets/random.png" height="60%" class="gdButton" style="margin-top: 5%">
|
<img src="/assets/random.png" height="60%" class="gdButton" style="margin-top: 5%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="lastPage" title="Last page" style="display: none; text-align: right; position:absolute; top: 7.5%; right: 11%; height: 11%;">
|
<div id="lastPage" title="Last page" style="display: none; text-align: right; position:absolute; top: 7.5%; right: 11%; height: 11%;">
|
||||||
<img src="../assets/double-arrow.png" height="60%" class="gdButton" style="margin-top: 5%">
|
<img src="/assets/double-arrow.png" height="60%" class="gdButton" style="margin-top: 5%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; top: 2%; left: 1.5%; width: 10%; height: 25%; pointer-events: none">
|
<div style="position:absolute; top: 2%; left: 1.5%; width: 10%; height: 25%; pointer-events: none">
|
||||||
<img class="gdButton yesClick" id="backButton" src="../assets/back.png" height="30%" onclick="backButton()">
|
<img class="gdButton yesClick" id="backButton" src="/assets/back.png" height="30%" onclick="backButton()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="purge" style="position:absolute; bottom: 1%; right: -3%; width: 10%; display:none;">
|
<div id="purge" style="position:absolute; bottom: 1%; right: -3%; width: 10%; display:none;">
|
||||||
<img class="gdButton" src="../assets/delete.png" width="60%" onclick="$('#purgeDiv').show()">
|
<img class="gdButton" src="/assets/delete.png" width="60%" onclick="$('#purgeDiv').show()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 2%; right: 1%; text-align: right; width: 15%;">
|
<div style="position:absolute; bottom: 2%; right: 1%; text-align: right; width: 15%;">
|
||||||
<img class="gdButton" src="../assets/refresh.png" width="40%" id="refreshPage"></a>
|
<img class="gdButton" src="/assets/refresh.png" width="40%" id="refreshPage"></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 2%; right: 8.5%; text-align: right; width: 15%; display: none" id="gdWorld">
|
<div style="position:absolute; bottom: 2%; right: 8.5%; text-align: right; width: 15%; display: none" id="gdWorld">
|
||||||
<a title="Geometry Dash World" href="/search/*?type=gdw"><img class="gdButton" src="../assets/gdw_circle.png" width="40%"></a>
|
<a title="Geometry Dash World" href="/search/*?type=gdw"><img class="gdButton" src="/assets/gdw_circle.png" width="40%"></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position:absolute; bottom: 2%; right: 8.5%; text-align: right; width: 15%; display: none" id="normalGD">
|
<div style="position:absolute; bottom: 2%; right: 8.5%; text-align: right; width: 15%; display: none" id="normalGD">
|
||||||
<a title="Back to Geometry Dash" href="/search/*?type=featured"><img class="gdButton" src="../assets/gd_circle.png" width="40%"></a>
|
<a title="Back to Geometry Dash" href="/search/*?type=featured"><img class="gdButton" src="/assets/gd_circle.png" width="40%"></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position: absolute; left: 7%; top: 45%; height: 10%;">
|
<div style="position: absolute; left: 7%; top: 45%; height: 10%;">
|
||||||
<img class="gdButton" id="pageDown" style="display: none"; src="../assets/arrow-left.png" height="90%">
|
<img class="gdButton" id="pageDown" style="display: none"; src="/assets/arrow-left.png" height="90%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="position: absolute; right: 7%; top: 45%; height: 10%;">
|
<div style="position: absolute; right: 7%; top: 45%; height: 10%;">
|
||||||
<img class="gdButton" id="pageUp" style="display: none"; src="../assets/arrow-right.png" height="90%">
|
<img class="gdButton" id="pageUp" style="display: none"; src="/assets/arrow-right.png" height="90%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="supercenter" id="loading" style="height: 10%; top: 47%; display: none;">
|
<div class="supercenter" id="loading" style="height: 10%; top: 47%; display: none;">
|
||||||
<img class="spin noSelect" src="../assets/loading.png" height="105%">
|
<img class="spin noSelect" src="/assets/loading.png" height="105%">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||||
<script type="text/javascript" src="../global.js?v=1"></script>
|
<script type="text/javascript" src="./global.js?v=1"></script>
|
||||||
<script type="text/javascript" src="../dragscroll.js"></script>
|
<script type="text/javascript" src="../dragscroll.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
"use strict";
|
||||||
|
|
||||||
$('#pageDown').hide()
|
$('#pageDown').hide()
|
||||||
$('#pageUp').hide()
|
$('#pageUp').hide()
|
||||||
|
|
||||||
let accID;
|
let accID
|
||||||
let path = location.pathname.replace('/search/', "")
|
let path = location.pathname.replace('/search/', "")
|
||||||
let url = new URL(window.location.href)
|
let url = new URL(window.location.href)
|
||||||
let gauntlet = url.searchParams.get('gauntlet')
|
let gauntlet = url.searchParams.get('gauntlet')
|
||||||
|
@ -140,7 +141,7 @@ let list = url.searchParams.get('list')
|
||||||
let count = url.searchParams.get('count')
|
let count = url.searchParams.get('count')
|
||||||
let header = url.searchParams.get('header')
|
let header = url.searchParams.get('header')
|
||||||
let demonList = ["demonList", "demonlist"].some(x => typeof url.searchParams.get(x) == "string" || type == x)
|
let demonList = ["demonList", "demonlist"].some(x => typeof url.searchParams.get(x) == "string" || type == x)
|
||||||
let loading = false;
|
let loading = false
|
||||||
let gauntlets = ["Fire", "Ice", "Poison", "Shadow", "Lava", "Bonus", "Chaos", "Demon", "Time", "Crystal", "Magic", "Spike", "Monster", "Doom", "Death"]
|
let gauntlets = ["Fire", "Ice", "Poison", "Shadow", "Lava", "Bonus", "Chaos", "Demon", "Time", "Crystal", "Magic", "Spike", "Monster", "Doom", "Death"]
|
||||||
|
|
||||||
let page = Math.max(1, url.searchParams.get('page')) - 1
|
let page = Math.max(1, url.searchParams.get('page')) - 1
|
||||||
|
@ -152,24 +153,26 @@ let superSearch = ['*', '*?type=mostliked', '*?type=mostdownloaded', '*?type=rec
|
||||||
let pageCache = {}
|
let pageCache = {}
|
||||||
|
|
||||||
let demonListLink = "https://pointercrate.com/"
|
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")}`
|
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")}`
|
||||||
|
|
||||||
function clean(text) {return (text || "").toString().replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/=/g, "=").replace(/"/g, """).replace(/'/g, "'")}
|
let clean = text => (text || '').toString().replace(/./gs, c => (
|
||||||
|
{'&': '&', '<': '<', '>': '>', '=': '=', '"': '"', "'": '''}[c] || c
|
||||||
|
))
|
||||||
|
|
||||||
if (type == "followed") {
|
if (type == "followed") {
|
||||||
let followed = localStorage.followed ? JSON.parse(localStorage.followed) : []
|
let followed = localStorage.followed ? JSON.parse(localStorage.followed) : []
|
||||||
searchFilters += ("&creators=" + followed.join())
|
searchFilters += ("&creators=" + followed.join())
|
||||||
}
|
}
|
||||||
|
|
||||||
let hostMatch = window.location.host.match(/\./g)
|
let hostMatch = window.location.host.match(/\./g)
|
||||||
if (hostMatch && hostMatch.length > 1) { // gdps check
|
if (hostMatch?.length > 1) { // gdps check
|
||||||
$('#gdWorld').remove()
|
$('#gdWorld').remove()
|
||||||
$('#normalGD').remove()
|
$('#normalGD').remove()
|
||||||
}
|
}
|
||||||
|
|
||||||
function Append(firstLoad, noCache) {
|
function Append(firstLoad, noCache) {
|
||||||
|
|
||||||
loading = true;
|
loading = true
|
||||||
if (!firstLoad) $('#pagenum').text(`Page ${(page + 1)}${pages ? ` of ${pages}` : ""}`)
|
if (!firstLoad) $('#pagenum').text(`Page ${(page + 1)}${pages ? ` of ${pages}` : ""}`)
|
||||||
$('#searchBox').html('<div style="height: 4.5%"></div>')
|
$('#searchBox').html('<div style="height: 4.5%"></div>')
|
||||||
$('#pageSelect').val(page + 1)
|
$('#pageSelect').val(page + 1)
|
||||||
|
@ -207,7 +210,7 @@ function Append(firstLoad, noCache) {
|
||||||
|
|
||||||
if (demonList) {
|
if (demonList) {
|
||||||
demonListLink = res[0].demonList
|
demonListLink = res[0].demonList
|
||||||
res = res.sort(function(a, b){return a.demonPosition - b.demonPosition});
|
res = res.sort((a, b) => a.demonPosition - b.demonPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
res.forEach((x, y) => {
|
res.forEach((x, y) => {
|
||||||
|
@ -229,35 +232,35 @@ function Append(firstLoad, noCache) {
|
||||||
<h2 class="pre smaller inline gdButton help ${hasAuthor ? "" : "green unregistered"}" title="Account ID: ${x.accountID}\nPlayer ID: ${x.playerID}"><!--
|
<h2 class="pre smaller inline gdButton help ${hasAuthor ? "" : "green unregistered"}" title="Account ID: ${x.accountID}\nPlayer ID: ${x.playerID}"><!--
|
||||||
-->${hasAuthor && !onePointNine ? `<a style="margin-right: 0.66vh" href="../u/${x.accountID}.">By ${x.author || "-"}</a>` : `<a ${userSearch ? "" : `href="../search/${x.playerID}?user"`}>By ${x.author || "-"}</a>`}</h2><!--
|
-->${hasAuthor && !onePointNine ? `<a style="margin-right: 0.66vh" href="../u/${x.accountID}.">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' ? "" : `<a target="_blank" href="../${x.copiedID}"><!--
|
--><h2 class="inline" style="margin-left: 1.5%; transform:translateY(30%)"> ${x.copiedID == '0' ? "" : `<a target="_blank" href="../${x.copiedID}"><!--
|
||||||
--><img class="gdButton valign sideSpaceD" title="Original: ${x.copiedID}" src="../assets/copied.png" height="12%"></a>`}<!--
|
--><img class="gdButton valign sideSpaceD" title="Original: ${x.copiedID}" src="/assets/copied.png" height="12%"></a>`}<!--
|
||||||
-->${x.large ? `<img class="help valign sideSpaceD" title="${x.objects}${x.objects == 65535 ? "+" : ""} objects" src="../assets/large.png" height="12%">` : ''}<!--
|
-->${x.large ? `<img class="help valign sideSpaceD" title="${x.objects}${x.objects == 65535 ? "+" : ""} objects" src="/assets/large.png" height="12%">` : ''}<!--
|
||||||
-->${x.twoPlayer ? `<img class="help valign sideSpaceD" title="Two player level" src="../assets/twoPlayer.png" height="12%">` : ''}
|
-->${x.twoPlayer ? `<img class="help valign sideSpaceD" title="Two player level" src="/assets/twoPlayer.png" height="12%">` : ''}
|
||||||
</h2>
|
</h2>
|
||||||
<h3 class="lessSpaced help ${noLink ? "" : 'gdButton '}pre ${songColor}" title="${filteredSong} by ${x.songAuthor} (${x.songID})" style="overflow: hidden; max-height: 19%; width: fit-content; padding: 1% 1% 0% 0%">${noLink ? filteredSong : `<a target="_blank" style="width: fit-content" href="https://www.newgrounds.com/audio/listen/${x.songID}">${filteredSong}</a>`}</h3>
|
<h3 class="lessSpaced help ${noLink ? "" : 'gdButton '}pre ${songColor}" title="${filteredSong} by ${x.songAuthor} (${x.songID})" style="overflow: hidden; max-height: 19%; width: fit-content; padding: 1% 1% 0% 0%">${noLink ? filteredSong : `<a target="_blank" style="width: fit-content" href="https://www.newgrounds.com/audio/listen/${x.songID}">${filteredSong}</a>`}</h3>
|
||||||
<h3 class="lessSpaced" style="width: fit-content" title="">
|
<h3 class="lessSpaced" style="width: fit-content" title="">
|
||||||
<img class="help valign rightSpace" title="Length" src="../assets/time.png" height="14%">${x.length}
|
<img class="help valign rightSpace" title="Length" src="/assets/time.png" height="14%">${x.length}
|
||||||
<img class="help valign rightSpace" title="Downloads" src="../assets/download.png" height="14%">${x.downloads}
|
<img class="help valign rightSpace" title="Downloads" src="/assets/download.png" height="14%">${x.downloads}
|
||||||
<img class="help valign rightSpace" title="Likes" src="../assets/${x.disliked ? 'dis' : ''}like.png" height="14%">${x.likes}
|
<img class="help valign rightSpace" title="Likes" src="/assets/${x.disliked ? 'dis' : ''}like.png" height="14%">${x.likes}
|
||||||
${x.orbs != 0 ? `<img class="help valign rightSpace" title="Mana Orbs" src="../assets/orbs.png" height="14%">${x.orbs}` : ""}
|
${x.orbs != 0 ? `<img class="help valign rightSpace" title="Mana Orbs" src="/assets/orbs.png" height="14%">${x.orbs}` : ""}
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div class="center" style="position:absolute; top: ${6.5 + (y * 33.5) + (x.coins == 0 ? 2.5 : 0)}%; left: 4.4%; transform:scale(0.82); height: 10%; width: 12.5%;">
|
<div class="center" style="position:absolute; top: ${6.5 + (y * 33.5) + (x.coins == 0 ? 2.5 : 0)}%; left: 4.4%; transform:scale(0.82); height: 10%; width: 12.5%;">
|
||||||
<img class="help spaced" id="dFace" title="${x.difficulty}${x.epic ? " (Epic)" : x.featured ? " (Featured)" : ""}" src="../assets/difficulties/${x.difficultyFace}.png" height="150%" style="margin-bottom: 0%; ${x.epic ? 'transform:scale(1.2)' : x.featured ? 'transform:scale(1.1)' : ''}">
|
<img class="help spaced" id="dFace" title="${x.difficulty}${x.epic ? " (Epic)" : x.featured ? " (Featured)" : ""}" src="/assets/difficulties/${x.difficultyFace}.png" height="150%" style="margin-bottom: 0%; ${x.epic ? 'transform:scale(1.2)' : x.featured ? 'transform:scale(1.1)' : ''}">
|
||||||
<h3 title="">${x.difficulty.includes('Demon') ? "Demon" : x.difficulty}</h3>
|
<h3 title="">${x.difficulty.includes('Demon') ? "Demon" : x.difficulty}</h3>
|
||||||
${x.stars != 0 && !demonList ? `<h3 class="help" title="${x.stars} star${x.stars == 1 ? "" : "s"}${x.starsRequested ? ` (${x.starsRequested} requested)` : ""}">${x.stars}<img class="valign sideSpaceB" src="../assets/star.png" height="35%" style="transform:translateY(-8%)"></h3>` : ""}
|
${x.stars != 0 && !demonList ? `<h3 class="help" title="${x.stars} star${x.stars == 1 ? "" : "s"}${x.starsRequested ? ` (${x.starsRequested} requested)` : ""}">${x.stars}<img class="valign sideSpaceB" src="/assets/star.png" height="35%" style="transform:translateY(-8%)"></h3>` : ""}
|
||||||
|
|
||||||
${demonList ? `<h3 class="help yellow" title="Ranked #${x.demonPosition} on the Demon List">#${x.demonPosition}</h3>` : ""}
|
${demonList ? `<h3 class="help yellow" title="Ranked #${x.demonPosition} on the Demon List">#${x.demonPosition}</h3>` : ""}
|
||||||
|
|
||||||
<div id="coins" style="margin-top: 3%" title="${x.coins} user coin${x.coins == 1 ? "" : "s"} (${x.verifiedCoins ? "" : "un"}verified)">
|
<div id="coins" style="margin-top: 3%" title="${x.coins} user coin${x.coins == 1 ? "" : "s"} (${x.verifiedCoins ? "" : "un"}verified)">
|
||||||
${x.coins > 0 ? `<img src="../assets/${x.verifiedCoins ? 'silver' : 'brown'}coin.png" height="50%" class="help">` : ""}
|
${x.coins > 0 ? `<img src="/assets/${x.verifiedCoins ? 'silver' : 'brown'}coin.png" height="50%" class="help">` : ""}
|
||||||
${x.coins > 1 ? `<img src="../assets/${x.verifiedCoins ? 'silver' : 'brown'}coin.png" height="50%" class="help squeezeB">` : ""}
|
${x.coins > 1 ? `<img src="/assets/${x.verifiedCoins ? 'silver' : 'brown'}coin.png" height="50%" class="help squeezeB">` : ""}
|
||||||
${x.coins > 2 ? `<img src="../assets/${x.verifiedCoins ? 'silver' : 'brown'}coin.png" height="50%" class="help squeezeB">` : ""}
|
${x.coins > 2 ? `<img src="/assets/${x.verifiedCoins ? 'silver' : 'brown'}coin.png" height="50%" class="help squeezeB">` : ""}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="center" style="position:absolute; right: 7%; transform:translateY(-${demonList ? 19.5 : 16.25}vh); height: 10%">
|
<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>
|
<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.demonPosition}""><img class="valign gdButton" src="../assets/trophyButton.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>` : "" }
|
<a title="View on Pointercrate" href="${demonListLink}demonlist/${x.demonPosition}" target=_blank><img class="valign gdButton" src="/assets/demonButton.png" height="110%"></a>` : "" }
|
||||||
<p title="Level ID" style="text-align: right; color: rgba(0, 0, 0, 0.4); font-size: 2.2vh; transform: translate(2.8vh, ${demonList ? -1.8 : 2.5}vh)">#${x.id}</p>
|
<p title="Level ID" style="text-align: right; color: rgba(0, 0, 0, 0.4); font-size: 2.2vh; transform: translate(2.8vh, ${demonList ? -1.8 : 2.5}vh)">#${x.id}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>`)
|
</div>`)
|
||||||
|
@ -336,31 +339,26 @@ if (!$('#header').text() && typeof userMode != "string") {
|
||||||
$('.closeWindow').click(function() {$(".popup").attr('style', 'display: none;')})
|
$('.closeWindow').click(function() {$(".popup").attr('style', 'display: none;')})
|
||||||
|
|
||||||
$('#purgeSaved').click(function() {
|
$('#purgeSaved').click(function() {
|
||||||
localStorage.removeItem('saved');
|
localStorage.removeItem('saved')
|
||||||
location.reload()
|
location.reload()
|
||||||
})
|
})
|
||||||
|
|
||||||
var max = 9999
|
function onPageSel(that) {
|
||||||
var min = 1
|
let x = $(that).val()
|
||||||
|
if (x != "") $(that).val(clamp(Math.floor(x), 1, 9999))
|
||||||
|
}
|
||||||
|
|
||||||
$('#pageSelect').on('input', function () {
|
$('#pageSelect').on('input', function() {onPageSel(this)})
|
||||||
var x = $(this).val();
|
$('#pageSelect').on('blur', function() {onPageSel(this)})
|
||||||
if ($(this).val() != "") $(this).val(Math.max(Math.min(Math.floor(x), max), min));
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#pageSelect').on('blur', function () {
|
|
||||||
var x = $(this).val();
|
|
||||||
if ($(this).val() != "") $(this).val(Math.max(Math.min(Math.floor(x), max), min));
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#shuffle').click(function() {
|
$('#shuffle').click(function() {
|
||||||
if (superSearch) {
|
if (superSearch) {
|
||||||
$('#searchBox').html('<div style="height: 4.5%"></div>')
|
$('#searchBox').html('<div style="height: 4.5%"></div>')
|
||||||
$('#loading').show()
|
$('#loading').show()
|
||||||
fetch("../api/search/*?page=0&type=recent").then(res => res.json()).then(recent => {
|
fetch("/api/search/*?page=0&type=recent").then(res => res.json()).then(recent => {
|
||||||
let mostRecent = recent[0].id
|
let mostRecent = recent[0].id
|
||||||
function fetchRandom() {
|
function fetchRandom() {
|
||||||
fetch(`../api/level/${Math.floor(Math.random() * (mostRecent)) + 1}`).then(res => res.json()).then(res => {
|
fetch(`/api/level/${randInt(0, mostRecent) + 1}`).then(res => res.json()).then(res => {
|
||||||
if (res == "-1" || !res.id) return fetchRandom()
|
if (res == "-1" || !res.id) return fetchRandom()
|
||||||
else window.location.href = "../" + res.id
|
else window.location.href = "../" + res.id
|
||||||
})
|
})
|
||||||
|
@ -371,7 +369,7 @@ $('#shuffle').click(function() {
|
||||||
else if (pages) {
|
else if (pages) {
|
||||||
let random = {}
|
let random = {}
|
||||||
let pageCount = +count || 10
|
let pageCount = +count || 10
|
||||||
randomResult = Math.floor(Math.random() * (results)) + 1
|
randomResult = randInt(0, results) + 1
|
||||||
randomPage = Math.ceil(randomResult / pageCount)
|
randomPage = Math.ceil(randomResult / pageCount)
|
||||||
randomIndex = randomResult % pageCount
|
randomIndex = randomResult % pageCount
|
||||||
if (randomIndex == 0) randomIndex = pageCount
|
if (randomIndex == 0) randomIndex = pageCount
|
||||||
|
@ -385,11 +383,11 @@ $('#shuffle').click(function() {
|
||||||
})
|
})
|
||||||
|
|
||||||
$(document).keydown(function(k) {
|
$(document).keydown(function(k) {
|
||||||
if (loading) return;
|
if (loading) return
|
||||||
|
|
||||||
if ($('#pageDiv').is(':visible')) {
|
if ($('#pageDiv').is(':visible')) {
|
||||||
if (k.which == 13) $('#pageJump').trigger('click') //enter
|
if (k.which == 13) $('#pageJump').trigger('click') //enter
|
||||||
else return;
|
else return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (k.which == 37 && $('#pageDown').is(":visible")) $('#pageDown').trigger('click') // left
|
if (k.which == 37 && $('#pageDown').is(":visible")) $('#pageDown').trigger('click') // left
|
||||||
|
|
|
@ -51,4 +51,4 @@
|
||||||
{ "form": "spider", "id": 7, "type": "treasureRoom", "keys": 1 },
|
{ "form": "spider", "id": 7, "type": "treasureRoom", "keys": 1 },
|
||||||
{ "form": "spider", "id": 10, "type": "gauntlet", "gauntlet": "Demon" },
|
{ "form": "spider", "id": 10, "type": "gauntlet", "gauntlet": "Demon" },
|
||||||
{ "form": "spider", "id": 17, "type": "treasureRoom", "keys": 5 }
|
{ "form": "spider", "id": 17, "type": "treasureRoom", "keys": 5 }
|
||||||
]
|
]
|
||||||
|
|
221
iconkit/icon.js
|
@ -1,3 +1,4 @@
|
||||||
|
"use strict";
|
||||||
const WHITE = 0xffffff
|
const WHITE = 0xffffff
|
||||||
const colorNames = { "1": "Color 1", "2": "Color 2", "g": "Glow", "w": "White", "u": "UFO Dome" }
|
const colorNames = { "1": "Color 1", "2": "Color 2", "g": "Glow", "w": "White", "u": "UFO Dome" }
|
||||||
const formNames = { "player": "icon", "player_ball": "ball", "bird": "ufo", "dart": "wave" }
|
const formNames = { "player": "icon", "player_ball": "ball", "bird": "ufo", "dart": "wave" }
|
||||||
|
@ -5,10 +6,19 @@ const loader = PIXI.Loader.shared
|
||||||
|
|
||||||
const loadedNewIcons = {}
|
const loadedNewIcons = {}
|
||||||
|
|
||||||
let positionMultiplier = 4
|
const TAU = Math.PI * 2
|
||||||
|
// by default, converts degrees to rads
|
||||||
|
const toRadians = (angle, scale = 360) => TAU / scale * angle
|
||||||
|
// default rad to deg
|
||||||
|
const fromRadians = (rad, scale = 360) => rad / (TAU / scale)
|
||||||
|
// `scale` is the num of subdivisions in a turn. More info: https://en.wikipedia.org/wiki/Turn_(angle)
|
||||||
|
// `scale = 400` corresponds to gradians, `256` to byte radians, and `100` to percentage of a turn
|
||||||
|
|
||||||
|
const positionMultiplier = 4
|
||||||
function positionPart(part, partIndex, layer, formName, isNew, isGlow) {
|
function positionPart(part, partIndex, layer, formName, isNew, isGlow) {
|
||||||
layer.position.x += (part.pos[0] * positionMultiplier * (isNew ? 0.5 : 1))
|
let truePosMultiplier = positionMultiplier / (isNew ? 2 : 1)
|
||||||
layer.position.y -= (part.pos[1] * positionMultiplier * (isNew ? 0.5 : 1))
|
layer.position.x += (part.pos[0] * truePosMultiplier)
|
||||||
|
layer.position.y -= (part.pos[1] * truePosMultiplier)
|
||||||
layer.scale.x = part.scale[0]
|
layer.scale.x = part.scale[0]
|
||||||
layer.scale.y = part.scale[1]
|
layer.scale.y = part.scale[1]
|
||||||
if (part.flipped[0]) layer.scale.x *= -1
|
if (part.flipped[0]) layer.scale.x *= -1
|
||||||
|
@ -20,17 +30,18 @@ function positionPart(part, partIndex, layer, formName, isNew, isGlow) {
|
||||||
let tintInfo = iconData.robotAnimations.info[formName].tints
|
let tintInfo = iconData.robotAnimations.info[formName].tints
|
||||||
let foundTint = tintInfo[partIndex]
|
let foundTint = tintInfo[partIndex]
|
||||||
if (foundTint > 0) {
|
if (foundTint > 0) {
|
||||||
let darkenFilter = new PIXI.filters.ColorMatrixFilter();
|
let darkenFilter = new PIXI.filters.ColorMatrixFilter()
|
||||||
darkenFilter.brightness(0)
|
darkenFilter.brightness(0)
|
||||||
darkenFilter.alpha = (255 - foundTint) / 255
|
darkenFilter.alpha = 1 - foundTint / 255
|
||||||
layer.filters = [darkenFilter]
|
layer.filters = [darkenFilter]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function validNum(val, defaultVal) {
|
function sanitizeNum(val, defaultVal) {
|
||||||
let colVal = +val
|
let colVal = +val
|
||||||
return isNaN(colVal) ? defaultVal : colVal
|
// yes, it also checks for NaN
|
||||||
|
return isFinite(colVal) ? colVal : defaultVal
|
||||||
}
|
}
|
||||||
|
|
||||||
function getGlowColor(colors) {
|
function getGlowColor(colors) {
|
||||||
|
@ -39,17 +50,17 @@ function getGlowColor(colors) {
|
||||||
return glowCol
|
return glowCol
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateIconID(id, form) {
|
function sanitizeIconID(id, form) {
|
||||||
let realID = Math.min(iconData.newIconCounts[form], Math.abs(validNum(id, 1)))
|
let realID = Math.min(iconData.newIconCounts[form], Math.abs(sanitizeNum(id, 1)))
|
||||||
if (realID == 0 && !["player", "player_ball"].includes(form)) realID = 1
|
if (realID == 0 && !["player", "player_ball"].includes(form)) realID = 1
|
||||||
return realID
|
return realID
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseIconColor(col) {
|
function parseIconColor(col) {
|
||||||
if (!col) return WHITE
|
if (!col) return WHITE
|
||||||
else if (typeof col == "string" && col.length >= 6) return parseInt(col, 16)
|
if (typeof col == "string" && col.length >= 6) return parseInt(col, 16)
|
||||||
let rgb = iconData.colors[col]
|
let rgb = iconData.colors[col]
|
||||||
return rgb ? rgbToDecimal(rgb) : WHITE;
|
return rgb ? rgb2Pac(rgb) : WHITE
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseIconForm(form) {
|
function parseIconForm(form) {
|
||||||
|
@ -58,7 +69,7 @@ function parseIconForm(form) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadIconLayers(form, id, cb) {
|
function loadIconLayers(form, id, cb) {
|
||||||
let iconStr = `${form}_${padZero(validateIconID(id, form))}`
|
let iconStr = `${form}_${padZero(sanitizeIconID(id, form))}`
|
||||||
let texturesToLoad = Object.keys(iconData.gameSheet).filter(x => x.startsWith(iconStr + "_"))
|
let texturesToLoad = Object.keys(iconData.gameSheet).filter(x => x.startsWith(iconStr + "_"))
|
||||||
|
|
||||||
if (loadedNewIcons[texturesToLoad[0]]) return cb(loader, loader.resources, true)
|
if (loadedNewIcons[texturesToLoad[0]]) return cb(loader, loader.resources, true)
|
||||||
|
@ -67,7 +78,10 @@ function loadIconLayers(form, id, cb) {
|
||||||
if (iconData.newIcons.includes(iconStr)) return loadNewIcon(iconStr, cb)
|
if (iconData.newIcons.includes(iconStr)) return loadNewIcon(iconStr, cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
loader.add(texturesToLoad.filter(x => !loader.resources[x]).map(x => ({ name: x, url: `/iconkit/icons/${x}` })))
|
loader.add(texturesToLoad
|
||||||
|
.filter(x => !loader.resources[x])
|
||||||
|
.map(x => ({ name: x, url: `/iconkit/icons/${x}` }))
|
||||||
|
)
|
||||||
loader.load(cb) // no params
|
loader.load(cb) // no params
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,11 +94,11 @@ function loadNewIcon(iconStr, cb) {
|
||||||
loader.add({ name: sheetName, url: `/iconkit/newicons/${iconStr}-hd.png` })
|
loader.add({ name: sheetName, url: `/iconkit/newicons/${iconStr}-hd.png` })
|
||||||
loader.load((l, resources) => {
|
loader.load((l, resources) => {
|
||||||
let texture = resources[sheetName].texture
|
let texture = resources[sheetName].texture
|
||||||
Object.keys(data).forEach(x => {
|
Object.keys(data).forEach(k => {
|
||||||
let bounds = data[x]
|
let bounds = data[k]
|
||||||
let textureRect = new PIXI.Rectangle(bounds.pos[0], bounds.pos[1], bounds.size[0], bounds.size[1])
|
let textureRect = new PIXI.Rectangle(bounds.pos[0], bounds.pos[1], bounds.size[0], bounds.size[1])
|
||||||
let partTexture = new PIXI.Texture(texture, textureRect)
|
let partTexture = new PIXI.Texture(texture, textureRect)
|
||||||
loadedNewIcons[x] = partTexture
|
loadedNewIcons[k] = partTexture
|
||||||
})
|
})
|
||||||
cb(l, resources, true)
|
cb(l, resources, true)
|
||||||
})
|
})
|
||||||
|
@ -104,23 +118,23 @@ function parseNewPlist(data) {
|
||||||
iconData.gameSheet[frameName] = {}
|
iconData.gameSheet[frameName] = {}
|
||||||
positionData[frameName] = {}
|
positionData[frameName] = {}
|
||||||
|
|
||||||
for (let n=0; n < frameData.length; n += 2) {
|
for (let n = 0; n < frameData.length; n += 2) {
|
||||||
let keyName = frameData[n].innerHTML
|
let keyName = frameData[n].innerHTML
|
||||||
let keyData = frameData[n + 1].innerHTML
|
let keyData = frameData[n + 1].innerHTML
|
||||||
if (["spriteOffset", "spriteSize", "spriteSourceSize"].includes(keyName)) {
|
switch (keyName) {
|
||||||
iconData.gameSheet[frameName][keyName] = parseWeirdArray(keyData)
|
case "spriteOffset": case "spriteSize": case "spriteSourceSize":
|
||||||
|
iconData.gameSheet[frameName][keyName] = parseWeirdArray(keyData)
|
||||||
|
break
|
||||||
|
case "textureRotated":
|
||||||
|
isRotated = frameData[n + 1].outerHTML.includes("true")
|
||||||
|
iconData.gameSheet[frameName][keyName] = isRotated
|
||||||
|
break
|
||||||
|
case "textureRect":
|
||||||
|
let textureArr = keyData.slice(1, -1).split("},{").map(parseWeirdArray)
|
||||||
|
positionData[frameName].pos = textureArr[0]
|
||||||
|
positionData[frameName].size = textureArr[1]
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (keyName == "textureRotated") {
|
|
||||||
isRotated = frameData[n + 1].outerHTML.includes("true")
|
|
||||||
iconData.gameSheet[frameName][keyName] = isRotated
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (keyName == "textureRect") {
|
|
||||||
let textureArr = keyData.slice(1, -1).split("},{").map(x => parseWeirdArray(x))
|
|
||||||
positionData[frameName].pos = textureArr[0]
|
|
||||||
positionData[frameName].size = textureArr[1]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isRotated) positionData[frameName].size.reverse()
|
if (isRotated) positionData[frameName].size.reverse()
|
||||||
|
@ -129,35 +143,37 @@ function parseNewPlist(data) {
|
||||||
return positionData
|
return positionData
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseWeirdArray(data) {
|
let parseWeirdArray = data => data.replace(/[^\d,-]/g, "").split(",").map(x => +x)
|
||||||
return data.replace(/[^0-9,-]/g, "").split(",").map(x => +x)
|
|
||||||
}
|
|
||||||
|
|
||||||
function padZero(num) {
|
let padZero = num => num.toString().padStart(2, "0")
|
||||||
let numStr = num.toString()
|
|
||||||
if (num < 10) numStr = "0" + numStr
|
|
||||||
return numStr
|
|
||||||
}
|
|
||||||
|
|
||||||
function rgbToDecimal(rgb) {
|
/*
|
||||||
return (rgb.r << 16) + (rgb.g << 8) + rgb.b;
|
name explanation:
|
||||||
}
|
`Number`s are not decimals, because they are not `String`s, and the internal representation is binary.
|
||||||
|
This means "rgbToDecimal" is a misleading name.
|
||||||
|
Converting independent color components into one number is called "color packing".
|
||||||
|
So I thougth it would be funny to rename `rgbToPacked` into `rgb2Pac`.
|
||||||
|
Alternative names could be `rgbPacker` or `packRGB`, IDK
|
||||||
|
- said by @Rudxain
|
||||||
|
*/
|
||||||
|
let rgb2Pac = rgb => (rgb.r << 16) | (rgb.g << 8) | rgb.b
|
||||||
|
|
||||||
class Icon {
|
class Icon {
|
||||||
constructor(data={}, cb) {
|
constructor(data={}, cb) {
|
||||||
this.app = data.app
|
this.app = data.app
|
||||||
this.sprite = new PIXI.Container();
|
this.sprite = new PIXI.Container()
|
||||||
this.form = data.form || "player"
|
this.form = data.form || "player"
|
||||||
this.id = validateIconID(data.id, this.form)
|
this.id = sanitizeIconID(data.id, this.form)
|
||||||
this.new = !!data.new
|
this.new = !!data.new
|
||||||
|
|
||||||
this.colors = {
|
this.colors = {
|
||||||
"1": validNum(data.col1, 0xafafaf), // primary
|
"1": sanitizeNum(data.col1, 0xafafaf), // primary
|
||||||
"2": validNum(data.col2, WHITE), // secondary
|
"2": sanitizeNum(data.col2, WHITE), // secondary
|
||||||
"g": validNum(data.colG, validNum(+data.colg, null)), // glow
|
"g": sanitizeNum(data.colG, sanitizeNum(data.colg, null)), // glow
|
||||||
"w": validNum(data.colW, validNum(+data.colw, WHITE)), // white
|
"w": sanitizeNum(data.colW, sanitizeNum(data.colw, WHITE)), // white
|
||||||
"u": validNum(data.colU, validNum(+data.colu, WHITE)), // ufo
|
"u": sanitizeNum(data.colU, sanitizeNum(data.colu, WHITE)), // ufo
|
||||||
}
|
}
|
||||||
|
|
||||||
this.glow = !!data.glow
|
this.glow = !!data.glow
|
||||||
this.layers = []
|
this.layers = []
|
||||||
this.glowLayers = []
|
this.glowLayers = []
|
||||||
|
@ -178,22 +194,24 @@ class Icon {
|
||||||
let idlePosition = this.getAnimation(data.animation, data.animationForm).frames[0]
|
let idlePosition = this.getAnimation(data.animation, data.animationForm).frames[0]
|
||||||
idlePosition.forEach((x, y) => {
|
idlePosition.forEach((x, y) => {
|
||||||
x.name = iconData.robotAnimations.info[this.form].names[y]
|
x.name = iconData.robotAnimations.info[this.form].names[y]
|
||||||
|
|
||||||
let part = new IconPart(this.form, this.id, this.colors, false, { part: x, skipGlow: true, new: this.new })
|
let part = new IconPart(this.form, this.id, this.colors, false, { part: x, skipGlow: true, new: this.new })
|
||||||
positionPart(x, y, part.sprite, this.form, this.new)
|
positionPart(x, y, part.sprite, this.form, this.new)
|
||||||
|
|
||||||
let glowPart = new IconPart(this.form, this.id, this.colors, true, { part: x, onlyGlow: true, new: this.new })
|
let glowPart = new IconPart(this.form, this.id, this.colors, true, { part: x, onlyGlow: true, new: this.new })
|
||||||
positionPart(x, y, glowPart.sprite, this.form, this.new, true)
|
positionPart(x, y, glowPart.sprite, this.form, this.new, true)
|
||||||
|
|
||||||
glowPart.sprite.visible = this.glow
|
glowPart.sprite.visible = this.glow
|
||||||
this.glowLayers.push(glowPart)
|
this.glowLayers.push(glowPart)
|
||||||
|
|
||||||
this.layers.push(part)
|
this.layers.push(part)
|
||||||
this.sprite.addChild(part.sprite)
|
this.sprite.addChild(part.sprite)
|
||||||
})
|
})
|
||||||
|
|
||||||
let fullGlow = new PIXI.Container();
|
let fullGlow = new PIXI.Container()
|
||||||
this.glowLayers.forEach(x => fullGlow.addChild(x.sprite))
|
this.glowLayers.forEach(x => fullGlow.addChild(x.sprite))
|
||||||
this.sprite.addChildAt(fullGlow, 0)
|
this.sprite.addChildAt(fullGlow, 0)
|
||||||
if (typeof Ease !== "undefined") this.ease = new Ease.Ease()
|
if (typeof Ease != "undefined") this.ease = new Ease.Ease()
|
||||||
this.animationSpeed = Math.abs(Number(data.animationSpeed) || 1)
|
this.animationSpeed = Math.abs(Number(data.animationSpeed) || 1)
|
||||||
if (data.animation) this.setAnimation(data.animation, data.animationForm)
|
if (data.animation) this.setAnimation(data.animation, data.animationForm)
|
||||||
}
|
}
|
||||||
|
@ -209,14 +227,16 @@ class Icon {
|
||||||
|
|
||||||
getAllLayers() {
|
getAllLayers() {
|
||||||
let allLayers = [];
|
let allLayers = [];
|
||||||
(this.complex ? this.glowLayers : []).concat(this.layers).forEach(x => x.sections.forEach(s => allLayers.push(s)))
|
(this.complex ? this.glowLayers : [])
|
||||||
|
.concat(this.layers)
|
||||||
|
.forEach(x => x.sections.forEach(s => allLayers.push(s)))
|
||||||
return allLayers
|
return allLayers
|
||||||
}
|
}
|
||||||
|
|
||||||
setColor(colorType, newColor, extra={}) {
|
setColor(colorType, newColor, extra={}) {
|
||||||
let colorStr = String(colorType).toLowerCase()
|
let colorStr = String(colorType).toLowerCase()
|
||||||
if (!colorType || !Object.keys(this.colors).includes(colorStr)) return
|
if (!colorType || !this.colors.hasOwnProperty(colorStr)) return
|
||||||
else this.colors[colorStr] = newColor
|
this.colors[colorStr] = newColor
|
||||||
let newGlow = getGlowColor(this.colors)
|
let newGlow = getGlowColor(this.colors)
|
||||||
this.getAllLayers().forEach(x => {
|
this.getAllLayers().forEach(x => {
|
||||||
if (colorType != "g" && x.colorType == colorStr) x.setColor(newColor)
|
if (colorType != "g" && x.colorType == colorStr) x.setColor(newColor)
|
||||||
|
@ -228,13 +248,9 @@ class Icon {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
formName() {
|
formName() { return formNames[this.form] || this.form }
|
||||||
return formNames[this.form] || this.form
|
|
||||||
}
|
|
||||||
|
|
||||||
isGlowing() {
|
isGlowing() { return this.glowLayers[0].sprite.visible }
|
||||||
return this.glowLayers[0].sprite.visible
|
|
||||||
}
|
|
||||||
|
|
||||||
setGlow(toggle) {
|
setGlow(toggle) {
|
||||||
this.glow = !!toggle
|
this.glow = !!toggle
|
||||||
|
@ -258,7 +274,7 @@ class Icon {
|
||||||
animData.frames[this.animationFrame].forEach((newPart, index) => {
|
animData.frames[this.animationFrame].forEach((newPart, index) => {
|
||||||
let section = this.layers[index]
|
let section = this.layers[index]
|
||||||
let glowSection = this.glowLayers[index]
|
let glowSection = this.glowLayers[index]
|
||||||
let truePosMultiplier = this.new ? positionMultiplier * 0.5 : positionMultiplier
|
let truePosMultiplier = positionMultiplier / (this.new ? 2 : 1)
|
||||||
if (!section) return
|
if (!section) return
|
||||||
|
|
||||||
// gd is weird with negative rotations
|
// gd is weird with negative rotations
|
||||||
|
@ -270,16 +286,16 @@ class Icon {
|
||||||
y: newPart.pos[1] * truePosMultiplier * -1,
|
y: newPart.pos[1] * truePosMultiplier * -1,
|
||||||
scaleX: newPart.scale[0],
|
scaleX: newPart.scale[0],
|
||||||
scaleY: newPart.scale[1],
|
scaleY: newPart.scale[1],
|
||||||
rotation: realRot * (Math.PI / 180) // radians
|
rotation: toRadians(realRot)
|
||||||
}
|
}
|
||||||
if (newPart.flipped[0]) movementData.scaleX *= -1
|
if (newPart.flipped[0]) movementData.scaleX *= -1
|
||||||
if (newPart.flipped[1]) movementData.scaleY *= -1
|
if (newPart.flipped[1]) movementData.scaleY *= -1
|
||||||
|
|
||||||
let bothSections = [section, glowSection]
|
let bothSections = [section, glowSection]
|
||||||
bothSections.forEach((x, y) => {
|
bothSections.forEach((x, y) => {
|
||||||
let easing = this.ease.add(x.sprite, movementData, { duration: duration || 1, ease: 'linear' })
|
let easing = this.ease.add(x.sprite, movementData, { duration: duration || 1, ease: "linear" })
|
||||||
let continueAfterEase = animData.frames.length > 1 && y == 0 && index == 0 && animName == this.animationName
|
let continueAfterEase = animData.frames.length > 1 && y == 0 && index == 0 && animName == this.animationName
|
||||||
if (continueAfterEase) easing.on('complete', () => {
|
if (continueAfterEase) easing.on("complete", () => {
|
||||||
this.animationFrame++
|
this.animationFrame++
|
||||||
if (this.animationFrame >= animData.frames.length) {
|
if (this.animationFrame >= animData.frames.length) {
|
||||||
if (animData.info.loop) this.animationFrame = 0
|
if (animData.info.loop) this.animationFrame = 0
|
||||||
|
@ -294,7 +310,7 @@ class Icon {
|
||||||
// find actual icon size by reading pixel data (otherwise there's whitespace and shit)
|
// find actual icon size by reading pixel data (otherwise there's whitespace and shit)
|
||||||
if (this.new) this.sprite.scale.set(1)
|
if (this.new) this.sprite.scale.set(1)
|
||||||
let spriteSize = [Math.round(this.sprite.width), Math.round(this.sprite.height)]
|
let spriteSize = [Math.round(this.sprite.width), Math.round(this.sprite.height)]
|
||||||
let pixels = this.app.renderer.plugins.extract.pixels(this.sprite);
|
let pixels = this.app.renderer.plugins.extract.pixels(this.sprite)
|
||||||
let xRange = [spriteSize[0], 0]
|
let xRange = [spriteSize[0], 0]
|
||||||
let yRange = [spriteSize[1], 0]
|
let yRange = [spriteSize[1], 0]
|
||||||
|
|
||||||
|
@ -316,7 +332,7 @@ class Icon {
|
||||||
// this took hours to figure out. i fucking hate my life
|
// this took hours to figure out. i fucking hate my life
|
||||||
xRange[1]++
|
xRange[1]++
|
||||||
yRange[1]++
|
yRange[1]++
|
||||||
|
|
||||||
let realWidth = xRange[1] - xRange[0]
|
let realWidth = xRange[1] - xRange[0]
|
||||||
let realHeight = yRange[1] - yRange[0]
|
let realHeight = yRange[1] - yRange[0]
|
||||||
|
|
||||||
|
@ -336,35 +352,35 @@ class Icon {
|
||||||
|
|
||||||
toDataURL(dataType="image/png") {
|
toDataURL(dataType="image/png") {
|
||||||
this.autocrop()
|
this.autocrop()
|
||||||
this.app.renderer.render(this.app.stage);
|
this.app.renderer.render(this.app.stage)
|
||||||
let b64data = this.app.view.toDataURL(dataType);
|
let b64data = this.app.view.toDataURL(dataType)
|
||||||
this.revertCrop()
|
this.revertCrop()
|
||||||
return b64data
|
return b64data
|
||||||
}
|
}
|
||||||
|
|
||||||
pngExport() {
|
pngExport() {
|
||||||
let b64data = this.toDataURL()
|
let b64data = this.toDataURL()
|
||||||
let downloader = document.createElement('a');
|
let downloader = document.createElement("a")
|
||||||
downloader.href = b64data
|
downloader.href = b64data
|
||||||
downloader.setAttribute("download", `${this.formName()}_${this.id}.png`);
|
downloader.setAttribute("download", `${this.formName()}_${this.id}.png`)
|
||||||
document.body.appendChild(downloader);
|
document.body.appendChild(downloader)
|
||||||
downloader.click();
|
downloader.click()
|
||||||
document.body.removeChild(downloader);
|
document.body.removeChild(downloader)
|
||||||
}
|
}
|
||||||
|
|
||||||
copyToClipboard() {
|
copyToClipboard() {
|
||||||
this.autocrop()
|
this.autocrop()
|
||||||
this.app.renderer.render(app.stage);
|
this.app.renderer.render(app.stage)
|
||||||
this.app.view.toBlob(blob => {
|
this.app.view.toBlob(blob => {
|
||||||
let item = new ClipboardItem({ "image/png": blob });
|
let item = new ClipboardItem({ "image/png": blob })
|
||||||
navigator.clipboard.write([item]);
|
navigator.clipboard.write([item])
|
||||||
});
|
})
|
||||||
this.revertCrop()
|
this.revertCrop()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
psdExport() {
|
psdExport() {
|
||||||
if (typeof agPsd === "undefined") throw new Error("ag-psd not imported!")
|
if (typeof agPsd == "undefined") throw new Error("ag-psd not imported!")
|
||||||
let glowing = this.isGlowing()
|
let glowing = this.isGlowing()
|
||||||
this.setGlow(true)
|
this.setGlow(true)
|
||||||
|
|
||||||
|
@ -376,10 +392,10 @@ class Icon {
|
||||||
function addPSDLayer(layer, parent, sprite) {
|
function addPSDLayer(layer, parent, sprite) {
|
||||||
allLayers.forEach(x => x.sprite.alpha = 0)
|
allLayers.forEach(x => x.sprite.alpha = 0)
|
||||||
layer.sprite.alpha = 255
|
layer.sprite.alpha = 255
|
||||||
|
|
||||||
let layerChild = { name: layer.colorName, canvas: renderer.plugins.extract.canvas(sprite) }
|
let layerChild = { name: layer.colorName, canvas: renderer.plugins.extract.canvas(sprite) }
|
||||||
if (layer.colorType == "g") {
|
if (layer.colorType == "g") {
|
||||||
if (parent.part) layerChild.name = parent.part.name + " glow"
|
if (parent.part) layerChild.name = `${parent.part.name} glow`
|
||||||
else layerChild.blendMode = "linear dodge"
|
else layerChild.blendMode = "linear dodge"
|
||||||
if (!complex && !glowing) layerChild.hidden = true
|
if (!complex && !glowing) layerChild.hidden = true
|
||||||
}
|
}
|
||||||
|
@ -404,13 +420,13 @@ class Icon {
|
||||||
|
|
||||||
allLayers.forEach(x => x.sprite.alpha = 255)
|
allLayers.forEach(x => x.sprite.alpha = 255)
|
||||||
let output = agPsd.writePsd(psd)
|
let output = agPsd.writePsd(psd)
|
||||||
let blob = new Blob([output]);
|
let blob = new Blob([output])
|
||||||
let downloader = document.createElement('a');
|
let downloader = document.createElement("a")
|
||||||
downloader.href = URL.createObjectURL(blob);
|
downloader.href = URL.createObjectURL(blob)
|
||||||
downloader.setAttribute("download", `${this.formName()}_${this.id}.psd`);
|
downloader.setAttribute("download", `${this.formName()}_${this.id}.psd`)
|
||||||
document.body.appendChild(downloader);
|
document.body.appendChild(downloader)
|
||||||
downloader.click();
|
downloader.click()
|
||||||
document.body.removeChild(downloader);
|
document.body.removeChild(downloader)
|
||||||
this.setGlow(glowing)
|
this.setGlow(glowing)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -421,11 +437,11 @@ class IconPart {
|
||||||
if (colors[1] == 0 && !misc.skipGlow) glow = true // add glow if p1 is black
|
if (colors[1] == 0 && !misc.skipGlow) glow = true // add glow if p1 is black
|
||||||
|
|
||||||
let iconPath = `${form}_${padZero(id)}`
|
let iconPath = `${form}_${padZero(id)}`
|
||||||
let partString = misc.part ? "_" + padZero(misc.part.part) : ""
|
let partString = misc.part ? `_${padZero(misc.part.part)}` : ""
|
||||||
let sections = {}
|
let sections = {}
|
||||||
if (misc.part) this.part = misc.part
|
if (misc.part) this.part = misc.part
|
||||||
|
|
||||||
this.sprite = new PIXI.Container();
|
this.sprite = new PIXI.Container()
|
||||||
this.sections = []
|
this.sections = []
|
||||||
|
|
||||||
if (!misc.skipGlow) {
|
if (!misc.skipGlow) {
|
||||||
|
@ -448,11 +464,22 @@ class IconPart {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let layerOrder = ["glow", "ufo", "col2", "col1", "white"].map(x => sections[x]).filter(x => x)
|
let layerOrder = ["glow", "ufo", "col2", "col1", "white"]
|
||||||
layerOrder.forEach(x => {
|
for (let x of layerOrder) {
|
||||||
|
x = sections[x]
|
||||||
|
if (!x) continue
|
||||||
this.sections.push(x)
|
this.sections.push(x)
|
||||||
this.sprite.addChild(x.sprite)
|
this.sprite.addChild(x.sprite)
|
||||||
})
|
}
|
||||||
|
/* alternative:
|
||||||
|
|
||||||
|
layerOrder.map(x => sections[x])
|
||||||
|
.filter(x => x)
|
||||||
|
.forEach(x => {
|
||||||
|
this.sections.push(x)
|
||||||
|
this.sprite.addChild(x.sprite)
|
||||||
|
})
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,7 +506,7 @@ class IconLayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
setColor(color) {
|
setColor(color) {
|
||||||
this.color = validNum(color, WHITE)
|
this.color = sanitizeNum(color, WHITE)
|
||||||
this.sprite.tint = this.color
|
this.sprite.tint = this.color
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.agPsd = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
(function(f){if(typeof exports=="object"&&typeof module!="undefined"){module.exports=f()}else if(typeof define=="function"&&define.amd){define([],f)}else{var g;if(typeof window!="undefined"){g=window}else if(typeof global!="undefined"){g=global}else if(typeof self!="undefined"){g=self}else{g=this}g.agPsd = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.readAbr = void 0;
|
exports.readAbr = void 0;
|
||||||
|
@ -1189,7 +1189,7 @@ addHandler('Anno', function (target) { return target.annotations !== undefined;
|
||||||
var sound = annotation.type === 'sound';
|
var sound = annotation.type === 'sound';
|
||||||
if (sound && !(annotation.data instanceof Uint8Array))
|
if (sound && !(annotation.data instanceof Uint8Array))
|
||||||
throw new Error('Sound annotation data should be Uint8Array');
|
throw new Error('Sound annotation data should be Uint8Array');
|
||||||
if (!sound && typeof annotation.data !== 'string')
|
if (!sound && typeof annotation.data != 'string')
|
||||||
throw new Error('Text annotation data should be string');
|
throw new Error('Text annotation data should be string');
|
||||||
var lengthOffset = writer.offset;
|
var lengthOffset = writer.offset;
|
||||||
psdWriter_1.writeUint32(writer, 0); // length
|
psdWriter_1.writeUint32(writer, 0); // length
|
||||||
|
@ -3049,16 +3049,16 @@ function getTypeByKey(key, value, root) {
|
||||||
return ('Wdth' in value) ? 'Objc' : (('units' in value) ? 'UntF' : 'doub');
|
return ('Wdth' in value) ? 'Objc' : (('units' in value) ? 'UntF' : 'doub');
|
||||||
}
|
}
|
||||||
else if (key === 'Type') {
|
else if (key === 'Type') {
|
||||||
return typeof value === 'string' ? 'enum' : 'long';
|
return typeof value == 'string' ? 'enum' : 'long';
|
||||||
}
|
}
|
||||||
else if (key === 'AntA') {
|
else if (key === 'AntA') {
|
||||||
return typeof value === 'string' ? 'enum' : 'bool';
|
return typeof value == 'string' ? 'enum' : 'bool';
|
||||||
}
|
}
|
||||||
else if (key === 'Hrzn' || key === 'Vrtc' || key === 'Top ' || key === 'Left' || key === 'Btom' || key === 'Rght') {
|
else if (key === 'Hrzn' || key === 'Vrtc' || key === 'Top ' || key === 'Left' || key === 'Btom' || key === 'Rght') {
|
||||||
return typeof value === 'number' ? 'doub' : 'UntF';
|
return typeof value == 'number' ? 'doub' : 'UntF';
|
||||||
}
|
}
|
||||||
else if (key === 'Vrsn') {
|
else if (key === 'Vrsn') {
|
||||||
return typeof value === 'number' ? 'long' : 'Objc';
|
return typeof value == 'number' ? 'long' : 'Objc';
|
||||||
}
|
}
|
||||||
else if (key === 'Rd ' || key === 'Grn ' || key === 'Bl ') {
|
else if (key === 'Rd ' || key === 'Grn ' || key === 'Bl ') {
|
||||||
return root === 'artd' ? 'long' : 'doub';
|
return root === 'artd' ? 'long' : 'doub';
|
||||||
|
@ -3390,7 +3390,7 @@ function writeReferenceStructure(writer, _key, items) {
|
||||||
for (var i = 0; i < items.length; i++) {
|
for (var i = 0; i < items.length; i++) {
|
||||||
var value = items[i];
|
var value = items[i];
|
||||||
var type = 'unknown';
|
var type = 'unknown';
|
||||||
if (typeof value === 'string') {
|
if (typeof value == 'string') {
|
||||||
if (/^[a-z]+\.[a-z]+$/i.test(value)) {
|
if (/^[a-z]+\.[a-z]+$/i.test(value)) {
|
||||||
type = 'Enmr';
|
type = 'Enmr';
|
||||||
}
|
}
|
||||||
|
@ -3485,7 +3485,7 @@ function parseUnits(_a) {
|
||||||
exports.parseUnits = parseUnits;
|
exports.parseUnits = parseUnits;
|
||||||
function parseUnitsOrNumber(value, units) {
|
function parseUnitsOrNumber(value, units) {
|
||||||
if (units === void 0) { units = 'Pixels'; }
|
if (units === void 0) { units = 'Pixels'; }
|
||||||
if (typeof value === 'number')
|
if (typeof value == 'number')
|
||||||
return { value: value, units: units };
|
return { value: value, units: units };
|
||||||
return parseUnits(value);
|
return parseUnits(value);
|
||||||
}
|
}
|
||||||
|
@ -3508,10 +3508,10 @@ exports.unitsPercent = unitsPercent;
|
||||||
function unitsValue(x, key) {
|
function unitsValue(x, key) {
|
||||||
if (x == null)
|
if (x == null)
|
||||||
return { units: 'Pixels', value: 0 };
|
return { units: 'Pixels', value: 0 };
|
||||||
if (typeof x !== 'object')
|
if (typeof x != 'object')
|
||||||
throw new Error("Invalid value: " + JSON.stringify(x) + " (key: " + key + ") (should have value and units)");
|
throw new Error("Invalid value: " + JSON.stringify(x) + " (key: " + key + ") (should have value and units)");
|
||||||
var units = x.units, value = x.value;
|
var units = x.units, value = x.value;
|
||||||
if (typeof value !== 'number')
|
if (typeof value != 'number')
|
||||||
throw new Error("Invalid value in " + JSON.stringify(x) + " (key: " + key + ")");
|
throw new Error("Invalid value in " + JSON.stringify(x) + " (key: " + key + ")");
|
||||||
if (units !== 'Pixels' && units !== 'Millimeters' && units !== 'Points' && units !== 'None' &&
|
if (units !== 'Pixels' && units !== 'Millimeters' && units !== 'Points' && units !== 'None' &&
|
||||||
units !== 'Picas' && units !== 'Inches' && units !== 'Centimeters' && units !== 'Density') {
|
units !== 'Picas' && units !== 'Inches' && units !== 'Centimeters' && units !== 'Density') {
|
||||||
|
@ -4009,7 +4009,7 @@ function parseEngineData(data) {
|
||||||
if (!stack.length)
|
if (!stack.length)
|
||||||
throw new Error('Invalid data');
|
throw new Error('Invalid data');
|
||||||
var top = stack[stack.length - 1];
|
var top = stack[stack.length - 1];
|
||||||
if (typeof top === 'string') {
|
if (typeof top == 'string') {
|
||||||
stack[stack.length - 2][top] = value;
|
stack[stack.length - 2][top] = value;
|
||||||
pop();
|
pop();
|
||||||
}
|
}
|
||||||
|
@ -4024,7 +4024,7 @@ function parseEngineData(data) {
|
||||||
if (!stack.length)
|
if (!stack.length)
|
||||||
pushContainer({});
|
pushContainer({});
|
||||||
var top = stack[stack.length - 1];
|
var top = stack[stack.length - 1];
|
||||||
if (top && typeof top === 'string') {
|
if (top && typeof top == 'string') {
|
||||||
if (name === 'nil') {
|
if (name === 'nil') {
|
||||||
pushValue(null);
|
pushValue(null);
|
||||||
}
|
}
|
||||||
|
@ -4032,7 +4032,7 @@ function parseEngineData(data) {
|
||||||
pushValue("/" + name);
|
pushValue("/" + name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (top && typeof top === 'object') {
|
else if (top && typeof top == 'object') {
|
||||||
stack.push(name);
|
stack.push(name);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -4196,15 +4196,15 @@ function serializeEngineData(data, condensed) {
|
||||||
writePrefix();
|
writePrefix();
|
||||||
writeString(condensed ? '/nil' : 'null');
|
writeString(condensed ? '/nil' : 'null');
|
||||||
}
|
}
|
||||||
else if (typeof value === 'number') {
|
else if (typeof value == 'number') {
|
||||||
writePrefix();
|
writePrefix();
|
||||||
writeString(serializeNumber(value, key));
|
writeString(serializeNumber(value, key));
|
||||||
}
|
}
|
||||||
else if (typeof value === 'boolean') {
|
else if (typeof value == 'boolean') {
|
||||||
writePrefix();
|
writePrefix();
|
||||||
writeString(value ? 'true' : 'false');
|
writeString(value ? 'true' : 'false');
|
||||||
}
|
}
|
||||||
else if (typeof value === 'string') {
|
else if (typeof value == 'string') {
|
||||||
writePrefix();
|
writePrefix();
|
||||||
if ((key === '99' || key === '98') && value.charAt(0) === '/') {
|
if ((key === '99' || key === '98') && value.charAt(0) === '/') {
|
||||||
writeString(value);
|
writeString(value);
|
||||||
|
@ -4223,7 +4223,7 @@ function serializeEngineData(data, condensed) {
|
||||||
}
|
}
|
||||||
else if (Array.isArray(value)) {
|
else if (Array.isArray(value)) {
|
||||||
writePrefix();
|
writePrefix();
|
||||||
if (value.every(function (x) { return typeof x === 'number'; })) {
|
if (value.every(function (x) { return typeof x == 'number'; })) {
|
||||||
writeString('[');
|
writeString('[');
|
||||||
var intArray = intArrays.indexOf(key) !== -1;
|
var intArray = intArrays.indexOf(key) !== -1;
|
||||||
for (var _i = 0, value_1 = value; _i < value_1.length; _i++) {
|
for (var _i = 0, value_1 = value; _i < value_1.length; _i++) {
|
||||||
|
@ -4247,7 +4247,7 @@ function serializeEngineData(data, condensed) {
|
||||||
writeString(']');
|
writeString(']');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (typeof value === 'object') {
|
else if (typeof value == 'object') {
|
||||||
if (inProperty && !condensed)
|
if (inProperty && !condensed)
|
||||||
writeString('\n');
|
writeString('\n');
|
||||||
writeIndent();
|
writeIndent();
|
||||||
|
@ -4266,7 +4266,7 @@ function serializeEngineData(data, condensed) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
if (condensed) {
|
if (condensed) {
|
||||||
if (typeof data === 'object') {
|
if (typeof data == 'object') {
|
||||||
for (var _i = 0, _a = getKeys(data); _i < _a.length; _i++) {
|
for (var _i = 0, _a = getKeys(data); _i < _a.length; _i++) {
|
||||||
var key = _a[_i];
|
var key = _a[_i];
|
||||||
writeProperty(key, data[key]);
|
writeProperty(key, data[key]);
|
||||||
|
@ -4560,7 +4560,7 @@ var createImageData = function (width, height) {
|
||||||
return tempCanvas.getContext('2d').createImageData(width, height);
|
return tempCanvas.getContext('2d').createImageData(width, height);
|
||||||
};
|
};
|
||||||
exports.createImageData = createImageData;
|
exports.createImageData = createImageData;
|
||||||
if (typeof document !== 'undefined') {
|
if (typeof document != 'undefined') {
|
||||||
exports.createCanvas = function (width, height) {
|
exports.createCanvas = function (width, height) {
|
||||||
var canvas = document.createElement('canvas');
|
var canvas = document.createElement('canvas');
|
||||||
canvas.width = width;
|
canvas.width = width;
|
||||||
|
@ -5225,7 +5225,7 @@ function writePsdUint8Array(psd, options) {
|
||||||
}
|
}
|
||||||
exports.writePsdUint8Array = writePsdUint8Array;
|
exports.writePsdUint8Array = writePsdUint8Array;
|
||||||
function writePsdBuffer(psd, options) {
|
function writePsdBuffer(psd, options) {
|
||||||
if (typeof Buffer === 'undefined') {
|
if (typeof Buffer == 'undefined') {
|
||||||
throw new Error('Buffer not supported on this platform');
|
throw new Error('Buffer not supported on this platform');
|
||||||
}
|
}
|
||||||
return Buffer.from(writePsdUint8Array(psd, options));
|
return Buffer.from(writePsdUint8Array(psd, options));
|
||||||
|
@ -7050,7 +7050,7 @@ function deduplicateValues(base, runs, keys) {
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
identical = runs.every(function (r) { return arraysEqual(r.style[key], value); });
|
identical = runs.every(function (r) { return arraysEqual(r.style[key], value); });
|
||||||
}
|
}
|
||||||
else if (typeof value === 'object') {
|
else if (typeof value == 'object') {
|
||||||
identical = runs.every(function (r) { return objectsEqual(r.style[key], value); });
|
identical = runs.every(function (r) { return objectsEqual(r.style[key], value); });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -7068,7 +7068,7 @@ function deduplicateValues(base, runs, keys) {
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
same = arraysEqual(r.style[key], value);
|
same = arraysEqual(r.style[key], value);
|
||||||
}
|
}
|
||||||
else if (typeof value === 'object') {
|
else if (typeof value == 'object') {
|
||||||
same = objectsEqual(r.style[key], value);
|
same = objectsEqual(r.style[key], value);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -7514,7 +7514,7 @@ function decodeString(value) {
|
||||||
throw Error("Lone surrogate U+" + code.toString(16).toUpperCase() + " is not a scalar value");
|
throw Error("Lone surrogate U+" + code.toString(16).toUpperCase() + " is not a scalar value");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((byte1 & 0xf8) === 0xf0) {
|
else if ((byte1 & 0xf8) == 0xf0) {
|
||||||
var byte2 = continuationByte(value, i++);
|
var byte2 = continuationByte(value, i++);
|
||||||
var byte3 = continuationByte(value, i++);
|
var byte3 = continuationByte(value, i++);
|
||||||
var byte4 = continuationByte(value, i++);
|
var byte4 = continuationByte(value, i++);
|
||||||
|
@ -7539,7 +7539,7 @@ exports.decodeString = decodeString;
|
||||||
|
|
||||||
|
|
||||||
},{}],15:[function(require,module,exports){
|
},{}],15:[function(require,module,exports){
|
||||||
'use strict'
|
"use strict";
|
||||||
|
|
||||||
exports.byteLength = byteLength
|
exports.byteLength = byteLength
|
||||||
exports.toByteArray = toByteArray
|
exports.toByteArray = toByteArray
|
||||||
|
@ -7547,7 +7547,7 @@ exports.fromByteArray = fromByteArray
|
||||||
|
|
||||||
var lookup = []
|
var lookup = []
|
||||||
var revLookup = []
|
var revLookup = []
|
||||||
var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
|
var Arr = typeof Uint8Array != 'undefined' ? Uint8Array : Array
|
||||||
|
|
||||||
var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||||
for (var i = 0, len = code.length; i < len; ++i) {
|
for (var i = 0, len = code.length; i < len; ++i) {
|
||||||
|
@ -7700,7 +7700,7 @@ function fromByteArray (uint8) {
|
||||||
*/
|
*/
|
||||||
/* eslint-disable no-proto */
|
/* eslint-disable no-proto */
|
||||||
|
|
||||||
'use strict'
|
"use strict";
|
||||||
|
|
||||||
var base64 = require('base64-js')
|
var base64 = require('base64-js')
|
||||||
var ieee754 = require('ieee754')
|
var ieee754 = require('ieee754')
|
||||||
|
@ -7728,8 +7728,8 @@ exports.kMaxLength = K_MAX_LENGTH
|
||||||
*/
|
*/
|
||||||
Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport()
|
Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport()
|
||||||
|
|
||||||
if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' &&
|
if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console != 'undefined' &&
|
||||||
typeof console.error === 'function') {
|
typeof console.error == 'function') {
|
||||||
console.error(
|
console.error(
|
||||||
'This browser lacks typed array (Uint8Array) support which is required by ' +
|
'This browser lacks typed array (Uint8Array) support which is required by ' +
|
||||||
'`buffer` v5.x. Use `buffer` v4.x if you require old browser support.'
|
'`buffer` v5.x. Use `buffer` v4.x if you require old browser support.'
|
||||||
|
@ -7785,8 +7785,8 @@ function createBuffer (length) {
|
||||||
|
|
||||||
function Buffer (arg, encodingOrOffset, length) {
|
function Buffer (arg, encodingOrOffset, length) {
|
||||||
// Common case.
|
// Common case.
|
||||||
if (typeof arg === 'number') {
|
if (typeof arg == 'number') {
|
||||||
if (typeof encodingOrOffset === 'string') {
|
if (typeof encodingOrOffset == 'string') {
|
||||||
throw new TypeError(
|
throw new TypeError(
|
||||||
'The "string" argument must be of type string. Received type number'
|
'The "string" argument must be of type string. Received type number'
|
||||||
)
|
)
|
||||||
|
@ -7797,7 +7797,7 @@ function Buffer (arg, encodingOrOffset, length) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
|
// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
|
||||||
if (typeof Symbol !== 'undefined' && Symbol.species != null &&
|
if (typeof Symbol != 'undefined' && Symbol.species != null &&
|
||||||
Buffer[Symbol.species] === Buffer) {
|
Buffer[Symbol.species] === Buffer) {
|
||||||
Object.defineProperty(Buffer, Symbol.species, {
|
Object.defineProperty(Buffer, Symbol.species, {
|
||||||
value: null,
|
value: null,
|
||||||
|
@ -7810,7 +7810,7 @@ if (typeof Symbol !== 'undefined' && Symbol.species != null &&
|
||||||
Buffer.poolSize = 8192 // not used by this implementation
|
Buffer.poolSize = 8192 // not used by this implementation
|
||||||
|
|
||||||
function from (value, encodingOrOffset, length) {
|
function from (value, encodingOrOffset, length) {
|
||||||
if (typeof value === 'string') {
|
if (typeof value == 'string') {
|
||||||
return fromString(value, encodingOrOffset)
|
return fromString(value, encodingOrOffset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7830,7 +7830,7 @@ function from (value, encodingOrOffset, length) {
|
||||||
return fromArrayBuffer(value, encodingOrOffset, length)
|
return fromArrayBuffer(value, encodingOrOffset, length)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof value === 'number') {
|
if (typeof value == 'number') {
|
||||||
throw new TypeError(
|
throw new TypeError(
|
||||||
'The "value" argument must not be of type number. Received type number'
|
'The "value" argument must not be of type number. Received type number'
|
||||||
)
|
)
|
||||||
|
@ -7844,8 +7844,8 @@ function from (value, encodingOrOffset, length) {
|
||||||
var b = fromObject(value)
|
var b = fromObject(value)
|
||||||
if (b) return b
|
if (b) return b
|
||||||
|
|
||||||
if (typeof Symbol !== 'undefined' && Symbol.toPrimitive != null &&
|
if (typeof Symbol != 'undefined' && Symbol.toPrimitive != null &&
|
||||||
typeof value[Symbol.toPrimitive] === 'function') {
|
typeof value[Symbol.toPrimitive] == 'function') {
|
||||||
return Buffer.from(
|
return Buffer.from(
|
||||||
value[Symbol.toPrimitive]('string'), encodingOrOffset, length
|
value[Symbol.toPrimitive]('string'), encodingOrOffset, length
|
||||||
)
|
)
|
||||||
|
@ -7875,7 +7875,7 @@ Buffer.prototype.__proto__ = Uint8Array.prototype
|
||||||
Buffer.__proto__ = Uint8Array
|
Buffer.__proto__ = Uint8Array
|
||||||
|
|
||||||
function assertSize (size) {
|
function assertSize (size) {
|
||||||
if (typeof size !== 'number') {
|
if (typeof size != 'number') {
|
||||||
throw new TypeError('"size" argument must be of type number')
|
throw new TypeError('"size" argument must be of type number')
|
||||||
} else if (size < 0) {
|
} else if (size < 0) {
|
||||||
throw new RangeError('The value "' + size + '" is invalid for option "size"')
|
throw new RangeError('The value "' + size + '" is invalid for option "size"')
|
||||||
|
@ -7884,18 +7884,14 @@ function assertSize (size) {
|
||||||
|
|
||||||
function alloc (size, fill, encoding) {
|
function alloc (size, fill, encoding) {
|
||||||
assertSize(size)
|
assertSize(size)
|
||||||
if (size <= 0) {
|
return (size <= 0 || fill === undefined
|
||||||
return createBuffer(size)
|
? createBuffer(size)
|
||||||
}
|
:
|
||||||
if (fill !== undefined) {
|
|
||||||
// Only pay attention to encoding if it's a string. This
|
// Only pay attention to encoding if it's a string. This
|
||||||
// prevents accidentally sending in a number that would
|
// prevents accidentally sending in a number that would
|
||||||
// be interpretted as a start offset.
|
// be interpretted as a start offset.
|
||||||
return typeof encoding === 'string'
|
createBuffer(size).fill(fill, typeof encoding == 'string' ? encoding : undefined)
|
||||||
? createBuffer(size).fill(fill, encoding)
|
)
|
||||||
: createBuffer(size).fill(fill)
|
|
||||||
}
|
|
||||||
return createBuffer(size)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7925,7 +7921,7 @@ Buffer.allocUnsafeSlow = function (size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function fromString (string, encoding) {
|
function fromString (string, encoding) {
|
||||||
if (typeof encoding !== 'string' || encoding === '') {
|
if (typeof encoding != 'string' || encoding === '') {
|
||||||
encoding = 'utf8'
|
encoding = 'utf8'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7994,7 +7990,7 @@ function fromObject (obj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj.length !== undefined) {
|
if (obj.length !== undefined) {
|
||||||
if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) {
|
if (typeof obj.length != 'number' || numberIsNaN(obj.length)) {
|
||||||
return createBuffer(0)
|
return createBuffer(0)
|
||||||
}
|
}
|
||||||
return fromArrayLike(obj)
|
return fromArrayLike(obj)
|
||||||
|
@ -8113,7 +8109,7 @@ function byteLength (string, encoding) {
|
||||||
if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) {
|
if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) {
|
||||||
return string.byteLength
|
return string.byteLength
|
||||||
}
|
}
|
||||||
if (typeof string !== 'string') {
|
if (typeof string != 'string') {
|
||||||
throw new TypeError(
|
throw new TypeError(
|
||||||
'The "string" argument must be one of type string, Buffer, or ArrayBuffer. ' +
|
'The "string" argument must be one of type string, Buffer, or ArrayBuffer. ' +
|
||||||
'Received type ' + typeof string
|
'Received type ' + typeof string
|
||||||
|
@ -8378,7 +8374,7 @@ function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
|
||||||
if (buffer.length === 0) return -1
|
if (buffer.length === 0) return -1
|
||||||
|
|
||||||
// Normalize byteOffset
|
// Normalize byteOffset
|
||||||
if (typeof byteOffset === 'string') {
|
if (typeof byteOffset == 'string') {
|
||||||
encoding = byteOffset
|
encoding = byteOffset
|
||||||
byteOffset = 0
|
byteOffset = 0
|
||||||
} else if (byteOffset > 0x7fffffff) {
|
} else if (byteOffset > 0x7fffffff) {
|
||||||
|
@ -8403,7 +8399,7 @@ function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalize val
|
// Normalize val
|
||||||
if (typeof val === 'string') {
|
if (typeof val == 'string') {
|
||||||
val = Buffer.from(val, encoding)
|
val = Buffer.from(val, encoding)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8414,9 +8410,9 @@ function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
|
return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
|
||||||
} else if (typeof val === 'number') {
|
} else if (typeof val == 'number') {
|
||||||
val = val & 0xFF // Search for a byte value [0-255]
|
val = val & 0xFF // Search for a byte value [0-255]
|
||||||
if (typeof Uint8Array.prototype.indexOf === 'function') {
|
if (typeof Uint8Array.prototype.indexOf == 'function') {
|
||||||
if (dir) {
|
if (dir) {
|
||||||
return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
|
return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
|
||||||
} else {
|
} else {
|
||||||
|
@ -8549,7 +8545,7 @@ Buffer.prototype.write = function write (string, offset, length, encoding) {
|
||||||
length = this.length
|
length = this.length
|
||||||
offset = 0
|
offset = 0
|
||||||
// Buffer#write(string, encoding)
|
// Buffer#write(string, encoding)
|
||||||
} else if (length === undefined && typeof offset === 'string') {
|
} else if (length === undefined && typeof offset == 'string') {
|
||||||
encoding = offset
|
encoding = offset
|
||||||
length = this.length
|
length = this.length
|
||||||
offset = 0
|
offset = 0
|
||||||
|
@ -9228,7 +9224,7 @@ Buffer.prototype.copy = function copy (target, targetStart, start, end) {
|
||||||
|
|
||||||
var len = end - start
|
var len = end - start
|
||||||
|
|
||||||
if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') {
|
if (this === target && typeof Uint8Array.prototype.copyWithin == 'function') {
|
||||||
// Use built-in when available, missing from IE11
|
// Use built-in when available, missing from IE11
|
||||||
this.copyWithin(targetStart, start, end)
|
this.copyWithin(targetStart, start, end)
|
||||||
} else if (this === target && start < targetStart && targetStart < end) {
|
} else if (this === target && start < targetStart && targetStart < end) {
|
||||||
|
@ -9253,19 +9249,19 @@ Buffer.prototype.copy = function copy (target, targetStart, start, end) {
|
||||||
// buffer.fill(string[, offset[, end]][, encoding])
|
// buffer.fill(string[, offset[, end]][, encoding])
|
||||||
Buffer.prototype.fill = function fill (val, start, end, encoding) {
|
Buffer.prototype.fill = function fill (val, start, end, encoding) {
|
||||||
// Handle string cases:
|
// Handle string cases:
|
||||||
if (typeof val === 'string') {
|
if (typeof val == 'string') {
|
||||||
if (typeof start === 'string') {
|
if (typeof start == 'string') {
|
||||||
encoding = start
|
encoding = start
|
||||||
start = 0
|
start = 0
|
||||||
end = this.length
|
end = this.length
|
||||||
} else if (typeof end === 'string') {
|
} else if (typeof end == 'string') {
|
||||||
encoding = end
|
encoding = end
|
||||||
end = this.length
|
end = this.length
|
||||||
}
|
}
|
||||||
if (encoding !== undefined && typeof encoding !== 'string') {
|
if (encoding !== undefined && typeof encoding != 'string') {
|
||||||
throw new TypeError('encoding must be a string')
|
throw new TypeError('encoding must be a string')
|
||||||
}
|
}
|
||||||
if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
|
if (typeof encoding == 'string' && !Buffer.isEncoding(encoding)) {
|
||||||
throw new TypeError('Unknown encoding: ' + encoding)
|
throw new TypeError('Unknown encoding: ' + encoding)
|
||||||
}
|
}
|
||||||
if (val.length === 1) {
|
if (val.length === 1) {
|
||||||
|
@ -9276,7 +9272,7 @@ Buffer.prototype.fill = function fill (val, start, end, encoding) {
|
||||||
val = code
|
val = code
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (typeof val === 'number') {
|
} else if (typeof val == 'number') {
|
||||||
val = val & 255
|
val = val & 255
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9295,7 +9291,7 @@ Buffer.prototype.fill = function fill (val, start, end, encoding) {
|
||||||
if (!val) val = 0
|
if (!val) val = 0
|
||||||
|
|
||||||
var i
|
var i
|
||||||
if (typeof val === 'number') {
|
if (typeof val == 'number') {
|
||||||
for (i = start; i < end; ++i) {
|
for (i = start; i < end; ++i) {
|
||||||
this[i] = val
|
this[i] = val
|
||||||
}
|
}
|
||||||
|
@ -9319,25 +9315,22 @@ Buffer.prototype.fill = function fill (val, start, end, encoding) {
|
||||||
// HELPER FUNCTIONS
|
// HELPER FUNCTIONS
|
||||||
// ================
|
// ================
|
||||||
|
|
||||||
var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g
|
var INVALID_BASE64_RE = /[^+/\dA-Z-_]/gi
|
||||||
|
|
||||||
function base64clean (str) {
|
function base64clean (str) {
|
||||||
// Node takes equal signs as end of the Base64 encoding
|
// Node takes equal signs as end of the Base64 encoding
|
||||||
str = str.split('=')[0]
|
str = str.split('=', 1)[0]
|
||||||
// Node strips out invalid characters like \n and \t from the string, base64-js does not
|
// Node strips out invalid characters like \n and \t from the string, base64-js does not
|
||||||
str = str.trim().replace(INVALID_BASE64_RE, '')
|
str = str.trim().replace(INVALID_BASE64_RE, '')
|
||||||
// Node converts strings with length < 2 to ''
|
// Node converts strings with length < 2 to ''
|
||||||
if (str.length < 2) return ''
|
if (str.length < 2) return ''
|
||||||
// Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
|
// Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
|
||||||
while (str.length % 4 !== 0) {
|
while (str.length % 4 !== 0) str += '='
|
||||||
str = str + '='
|
|
||||||
}
|
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
function toHex (n) {
|
function toHex (n) {
|
||||||
if (n < 16) return '0' + n.toString(16)
|
return (n < 16 ? '0' : '') + n.toString(16)
|
||||||
return n.toString(16)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function utf8ToBytes (string, units) {
|
function utf8ToBytes (string, units) {
|
||||||
|
|
340
index.js
|
@ -1,30 +1,33 @@
|
||||||
const express = require('express');
|
"use strict";
|
||||||
const request = require('request');
|
const express = require('express')
|
||||||
const compression = require('compression');
|
const request = require('request')
|
||||||
const timeout = require('connect-timeout');
|
const compression = require('compression')
|
||||||
const rateLimit = require("express-rate-limit");
|
const timeout = require('connect-timeout')
|
||||||
const fs = require("fs");
|
const rateLimit = require("express-rate-limit")
|
||||||
const app = express();
|
const fs = require("fs")
|
||||||
|
const app = express()
|
||||||
|
|
||||||
let serverList = require('./servers.json')
|
const serverList = require('./servers.json')
|
||||||
let pinnedServers = serverList.filter(x => x.pinned)
|
const pinnedServers = []
|
||||||
let notPinnedServers = serverList.filter(x => !x.pinned).sort((a, b) => a.name.localeCompare(b.name))
|
const notPinnedServers = []
|
||||||
|
serverList.forEach(x => (x.pinned ? pinnedServers : notPinnedServers).push(x))
|
||||||
|
notPinnedServers.sort((a, b) => a.name.localeCompare(b.name))
|
||||||
|
|
||||||
app.servers = pinnedServers.concat(notPinnedServers)
|
app.servers = pinnedServers.concat(notPinnedServers)
|
||||||
app.safeServers = JSON.parse(JSON.stringify(app.servers)) // clone
|
app.safeServers = JSON.parse(JSON.stringify(app.servers)) // deep clone
|
||||||
app.safeServers.forEach(x => { delete x.endpoint; delete x.substitutions; delete x.overrides; delete x.disabled })
|
app.safeServers.forEach(x => ['endpoint', 'substitutions', 'overrides', 'disabled'].forEach(k => delete x[k]))
|
||||||
app.config = require('./settings.js')
|
app.config = require('./settings.js')
|
||||||
|
|
||||||
let rlMessage = "Rate limited ¯\\_(ツ)_/¯<br><br>Please do not spam my servers with a crazy amount of requests. It slows things down on my end and stresses RobTop's servers just as much." +
|
const rlMessage = "Rate limited ¯\\_(ツ)_/¯<br><br>Please do not spam my servers with a crazy amount of requests. It slows things down on my end and stresses RobTop's servers just as much. "+
|
||||||
" If you really want to send a zillion requests for whatever reason, please download the GDBrowser repository locally - or even just send the request directly to the GD servers.<br><br>" +
|
"If you really want to send a zillion requests for whatever reason, please download the GDBrowser repository locally - or even just send the request directly to the GD servers.<br><br>"+
|
||||||
"This kind of spam usually leads to GDBrowser getting IP banned by RobTop, and every time that happens I have to start making the rate limit even stricter. Please don't be the reason for that.<br><br>"
|
"This kind of spam usually leads to GDBrowser getting IP banned by RobTop, and every time that happens I have to start making the rate limit even stricter. Please don't be the reason for that.<br><br>"
|
||||||
|
|
||||||
const RL = rateLimit({
|
const RL = rateLimit({
|
||||||
windowMs: app.config.rateLimiting ? 5 * 60 * 1000 : 0,
|
windowMs: app.config.rateLimiting ? 5 * 60 * 1000 : 0,
|
||||||
max: app.config.rateLimiting ? 100 : 0, // max requests per 5 minutes
|
max: app.config.rateLimiting ? 100 : 0, // max requests per 5 minutes
|
||||||
message: rlMessage,
|
message: rlMessage,
|
||||||
keyGenerator: function(req) { return req.headers['x-real-ip'] || req.headers['x-forwarded-for'] },
|
keyGenerator: req => req.headers['x-real-ip'] || req.headers['x-forwarded-for'],
|
||||||
skip: function(req) { return ((req.url.includes("api/level") && !req.query.hasOwnProperty("download")) ? true : false) }
|
skip: req => req.url.includes("api/level") && !req.query.hasOwnProperty("download")
|
||||||
})
|
})
|
||||||
|
|
||||||
const RL2 = rateLimit({
|
const RL2 = rateLimit({
|
||||||
|
@ -34,8 +37,8 @@ const RL2 = rateLimit({
|
||||||
keyGenerator: function(req) { return req.headers['x-real-ip'] || req.headers['x-forwarded-for'] }
|
keyGenerator: function(req) { return req.headers['x-real-ip'] || req.headers['x-forwarded-for'] }
|
||||||
})
|
})
|
||||||
|
|
||||||
let XOR = require('./classes/XOR.js');
|
const XOR = require('./classes/XOR.js')
|
||||||
let achievements = require('./misc/achievements.json')
|
const achievements = require('./misc/achievements.json')
|
||||||
let achievementTypes = require('./misc/achievementTypes.json')
|
let achievementTypes = require('./misc/achievementTypes.json')
|
||||||
let music = require('./misc/music.json')
|
let music = require('./misc/music.json')
|
||||||
let assetPage = fs.readFileSync('./html/assets.html', 'utf8')
|
let assetPage = fs.readFileSync('./html/assets.html', 'utf8')
|
||||||
|
@ -45,25 +48,27 @@ app.lastSuccess = {}
|
||||||
app.actuallyWorked = {}
|
app.actuallyWorked = {}
|
||||||
|
|
||||||
app.servers.forEach(x => {
|
app.servers.forEach(x => {
|
||||||
app.accountCache[x.id || "gd"] = {}
|
x = x.id || "gd"
|
||||||
app.lastSuccess[x.id || "gd"] = Date.now()
|
app.accountCache[x] = {}
|
||||||
|
app.lastSuccess[x] = Date.now()
|
||||||
})
|
})
|
||||||
app.mainEndpoint = app.servers.find(x => !x.id).endpoint // boomlings.com unless changed in fork
|
app.mainEndpoint = app.servers.find(x => !x.id).endpoint // boomlings.com unless changed in fork
|
||||||
|
|
||||||
app.set('json spaces', 2)
|
app.set('json spaces', 2)
|
||||||
app.use(compression());
|
app.use(compression())
|
||||||
app.use(express.json());
|
app.use(express.json())
|
||||||
app.use(express.urlencoded({extended: true}));
|
app.use(express.urlencoded({extended: true}))
|
||||||
app.use(timeout('20s'));
|
app.use(timeout('20s'))
|
||||||
|
|
||||||
app.use(async function(req, res, next) {
|
app.use(async function(req, res, next) {
|
||||||
|
|
||||||
let subdomains = req.subdomains.map(x => x.toLowerCase())
|
let subdomains = req.subdomains.map(x => x.toLowerCase())
|
||||||
if (!subdomains.length) subdomains = [""]
|
if (!subdomains.length) subdomains = [""]
|
||||||
req.server = app.servers.find(x => subdomains.includes(x.id.toLowerCase()))
|
req.server = app.servers.find(x => subdomains.includes(x.id.toLowerCase()))
|
||||||
if (subdomains.length > 1 || !req.server) return res.redirect("http://" + req.get('host').split(".").slice(subdomains.length).join(".") + req.originalUrl)
|
if (subdomains.length > 1 || !req.server)
|
||||||
|
return res.redirect("http://" + req.get('host').split(".").slice(subdomains.length).join(".") + req.originalUrl)
|
||||||
|
|
||||||
// will expand this in the future :wink:
|
// will expand this in the future :wink: 😉
|
||||||
res.sendError = function(errorCode=500) {
|
res.sendError = function(errorCode=500) {
|
||||||
res.status(errorCode).send("-1")
|
res.status(errorCode).send("-1")
|
||||||
}
|
}
|
||||||
|
@ -80,14 +85,17 @@ app.use(async function(req, res, next) {
|
||||||
if (req.query.online > 0) req.offline = false
|
if (req.query.online > 0) req.offline = false
|
||||||
|
|
||||||
req.gdParams = function(obj={}, substitute=true) {
|
req.gdParams = function(obj={}, substitute=true) {
|
||||||
Object.keys(app.config.params).forEach(x => { if (!obj[x]) obj[x] = app.config.params[x] })
|
Object.keys(app.config.params).forEach(k => obj[k] ||= app.config.params[k])
|
||||||
Object.keys(req.server.extraParams || {}).forEach(x => { if (!obj[x]) obj[x] = req.server.extraParams[x] })
|
Object.keys(req.server.extraParams || {}).forEach(k => obj[k] ||= req.server.extraParams[k])
|
||||||
let ip = req.headers['x-real-ip'] || req.headers['x-forwarded-for']
|
let ip = req.headers['x-real-ip'] || req.headers['x-forwarded-for']
|
||||||
let params = {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} : {}}
|
||||||
|
|
||||||
if (substitute) { // GDPS substitutions in settings.js
|
if (substitute) { // GDPS substitutions in settings.js
|
||||||
for (let ss in req.server.substitutions) {
|
for (let ss in req.server.substitutions) {
|
||||||
if (params.form[ss]) { params.form[req.server.substitutions[ss]] = params.form[ss]; delete params.form[ss] }
|
if (params.form[ss]) {
|
||||||
|
params.form[req.server.substitutions[ss]] = params.form[ss]
|
||||||
|
delete params.form[ss]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return params
|
return params
|
||||||
|
@ -95,16 +103,16 @@ app.use(async function(req, res, next) {
|
||||||
|
|
||||||
req.gdRequest = function(target, params={}, cb=function(){}) {
|
req.gdRequest = function(target, params={}, cb=function(){}) {
|
||||||
if (!target) return cb(true)
|
if (!target) return cb(true)
|
||||||
target = req.server.overrides ? (req.server.overrides[target] || target) : target
|
target = (req.server.overrides && req.server.overrides[target]) || target
|
||||||
let parameters = params.headers ? params : req.gdParams(params)
|
let parameters = params.headers ? params : req.gdParams(params)
|
||||||
let endpoint = req.endpoint
|
let {endpoint} = req
|
||||||
if (params.forceGD || (params.form && params.form.forceGD)) endpoint = "http://www.boomlings.com/database/"
|
if (params.forceGD || (params.form?.forceGD))
|
||||||
|
endpoint = "http://www.boomlings.com/database/"
|
||||||
request.post(endpoint + target + '.php', parameters, function(err, res, body) {
|
request.post(endpoint + target + '.php', parameters, function(err, res, body) {
|
||||||
let error = err
|
if (!err && (!body || /(^-\d$)|^error|^</.test(body)))
|
||||||
if (!error && (err || !body || body.match(/^-\d$/) || body.startsWith("error") || body.startsWith("<"))) {
|
err = {serverError: true, response: body}
|
||||||
error = {serverError: true, response: body}
|
|
||||||
}
|
return cb(err, res, body)
|
||||||
return cb(error, res, body)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,20 +124,25 @@ fs.readdirSync('./api').filter(x => !x.includes(".")).forEach(x => directories.p
|
||||||
|
|
||||||
app.trackSuccess = function(id) {
|
app.trackSuccess = function(id) {
|
||||||
app.lastSuccess[id] = Date.now()
|
app.lastSuccess[id] = Date.now()
|
||||||
if (!app.actuallyWorked[id]) app.actuallyWorked[id] = true
|
app.actuallyWorked[id] ||= true
|
||||||
}
|
}
|
||||||
|
|
||||||
app.timeSince = function(id, time) {
|
app.timeSince = function(id, time) {
|
||||||
if (!time) time = app.lastSuccess[id]
|
if (!time) time = app.lastSuccess[id]
|
||||||
let secsPassed = Math.floor((Date.now() - time) / 1000)
|
let secsPassed = Math.floor((Date.now() - time) / 1000)
|
||||||
let minsPassed = Math.floor(secsPassed / 60)
|
let minsPassed = Math.floor(secsPassed / 60)
|
||||||
secsPassed -= 60 * minsPassed;
|
secsPassed -= 60 * minsPassed
|
||||||
return `${app.actuallyWorked[id] ? "" : "~"}${minsPassed}m ${secsPassed}s`
|
return `${app.actuallyWorked[id] ? "" : "~"}${minsPassed}m ${secsPassed}s`
|
||||||
}
|
}
|
||||||
|
|
||||||
app.userCache = function(id, accountID, playerID, name) {
|
app.userCache = function(id, accountID, playerID, name) {
|
||||||
|
|
||||||
if (!accountID || accountID == "0" || (name && name.toLowerCase() == "robtop" && accountID != "71") || !app.config.cacheAccountIDs) return
|
if ( // "IDK how to format this nicely" @Rudxain
|
||||||
|
!accountID || accountID == "0" ||
|
||||||
|
(name?.toLowerCase() == "robtop" && accountID != "71") ||
|
||||||
|
!app.config.cacheAccountIDs
|
||||||
|
)
|
||||||
|
return
|
||||||
if (!playerID) return app.accountCache[id][accountID.toLowerCase()]
|
if (!playerID) return app.accountCache[id][accountID.toLowerCase()]
|
||||||
let cacheStuff = [accountID, playerID, name]
|
let cacheStuff = [accountID, playerID, name]
|
||||||
app.accountCache[id][name.toLowerCase()] = cacheStuff
|
app.accountCache[id][name.toLowerCase()] = cacheStuff
|
||||||
|
@ -138,7 +151,10 @@ app.userCache = function(id, accountID, playerID, name) {
|
||||||
|
|
||||||
app.run = {}
|
app.run = {}
|
||||||
directories.forEach(d => {
|
directories.forEach(d => {
|
||||||
fs.readdirSync('./api/' + d).forEach(x => {if (x.includes('.')) app.run[x.split('.')[0]] = require('./api/' + d + "/" + x) })
|
fs.readdirSync('./api/' + d)
|
||||||
|
.forEach(x => {
|
||||||
|
if (x.includes('.')) app.run[x.split('.', 1)[0]] = require(`./api/${d}/${x}`)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
app.xor = new XOR()
|
app.xor = new XOR()
|
||||||
|
@ -162,26 +178,29 @@ catch(e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
app.parseResponse = function (responseBody, splitter=":") {
|
app.parseResponse = function (responseBody, splitter=":") {
|
||||||
if (!responseBody || responseBody == "-1") return {};
|
if (!responseBody || responseBody == "-1") return {}
|
||||||
if (responseBody.startsWith("\nWarning:")) responseBody = responseBody.split("\n").slice(2).join("\n").trim() // GDPS'es are wild
|
if (responseBody.startsWith("\nWarning:")) responseBody = responseBody.split("\n").slice(2).join("\n").trim() // GDPS'es are wild
|
||||||
if (responseBody.startsWith("<br />")) responseBody = responseBody.split("<br />").slice(2).join("<br />").trim() // Seriously screw this
|
if (responseBody.startsWith("<br />")) responseBody = responseBody.split("<br />").slice(2).join("<br />").trim() // Seriously screw this
|
||||||
let response = responseBody.split('#')[0].split(splitter);
|
let response = responseBody.split('#', 1)[0].split(splitter)
|
||||||
let res = {};
|
let res = {}
|
||||||
for (let i = 0; i < response.length; i += 2) {
|
for (let i = 0; i < response.length; i += 2)
|
||||||
res[response[i]] = response[i + 1]}
|
res[response[i]] = response[i + 1]
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
//xss bad
|
//xss bad
|
||||||
app.clean = function(text) {if (!text || typeof text != "string") return text; else return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/=/g, "=").replace(/"/g, """).replace(/'/g, "'")}
|
app.clean = text => {
|
||||||
|
const escChar = c => ({"&": "&", "<": "<", ">": ">", "=": "=", '"': """, "'": "'"}[c] || c)
|
||||||
|
return !text || typeof text != "string" ? text : text.replace(/./gs, escChar)
|
||||||
|
}
|
||||||
|
|
||||||
// ASSETS
|
// ASSETS
|
||||||
|
|
||||||
app.use('/assets', express.static(__dirname + '/assets', {maxAge: "7d"}));
|
app.use('/assets', express.static(__dirname + '/assets', {maxAge: "7d"}))
|
||||||
app.use('/assets/css', express.static(__dirname + '/assets/css'));
|
app.use('/assets/css', express.static(__dirname + '/assets/css'))
|
||||||
|
|
||||||
app.use('/iconkit', express.static(__dirname + '/iconkit'));
|
app.use('/iconkit', express.static(__dirname + '/iconkit'))
|
||||||
app.get("/global.js", function(req, res) { res.status(200).sendFile(__dirname + "/misc/global.js") })
|
app.get("/misc/global.js", function(req, res) { res.status(200).sendFile(__dirname + "/misc/global.js") })
|
||||||
app.get("/dragscroll.js", function(req, res) { res.status(200).sendFile(__dirname + "/misc/dragscroll.js") })
|
app.get("/dragscroll.js", function(req, res) { res.status(200).sendFile(__dirname + "/misc/dragscroll.js") })
|
||||||
|
|
||||||
app.get("/assets/:dir*?", function(req, res) {
|
app.get("/assets/:dir*?", function(req, res) {
|
||||||
|
@ -208,116 +227,151 @@ app.get("/assets/:dir*?", function(req, res) {
|
||||||
|
|
||||||
// POST REQUESTS
|
// POST REQUESTS
|
||||||
|
|
||||||
app.post("/like", RL, function(req, res) { app.run.like(app, req, res) })
|
function doPOST(name, key, noRL, wtf) {
|
||||||
app.post("/postComment", RL, function(req, res) { app.run.postComment(app, req, res) })
|
const args = ["/" + name]
|
||||||
app.post("/postProfileComment", RL, function(req, res) { app.run.postProfileComment(app, req, res) })
|
if (!noRL) args.push(RL)
|
||||||
|
app.post(...args, function(req, res) { app.run[ key || name ](app, req, res, wtf ? true : undefined) })
|
||||||
|
}
|
||||||
|
doPOST("like")
|
||||||
|
doPOST("postComment")
|
||||||
|
doPOST("postProfileComment")
|
||||||
|
doPOST("messages", "getMessages")
|
||||||
|
doPOST("messages/:id", "fetchMessage")
|
||||||
|
doPOST("deleteMessage")
|
||||||
|
doPOST("sendMessage")
|
||||||
|
doPOST("accurateLeaderboard", "accurate", true, true)
|
||||||
|
doPOST("analyzeLevel", "analyze", true)
|
||||||
|
|
||||||
app.post("/messages", RL, function(req, res) { app.run.getMessages(app, req, res) })
|
|
||||||
app.post("/messages/:id", RL, function(req, res) { app.run.fetchMessage(app, req, res) })
|
|
||||||
app.post("/deleteMessage", RL, function(req, res) { app.run.deleteMessage(app, req, res) })
|
|
||||||
app.post("/sendMessage", RL, function(req, res) { app.run.sendMessage(app, req, res) })
|
|
||||||
|
|
||||||
app.post("/accurateLeaderboard", function(req, res) { app.run.accurate(app, req, res, true) })
|
|
||||||
app.post("/analyzeLevel", function(req, res) { app.run.analyze(app, req, res) })
|
|
||||||
|
|
||||||
// HTML
|
// HTML
|
||||||
|
|
||||||
let onePointNineDisabled = ['daily', 'weekly', 'gauntlets', 'messages']
|
|
||||||
let downloadDisabled = ['daily', 'weekly']
|
let downloadDisabled = ['daily', 'weekly']
|
||||||
|
let onePointNineDisabled = ['daily', 'weekly', 'gauntlets', 'messages'] // using `concat` won't shorten this
|
||||||
let gdpsHide = ['achievements', 'messages']
|
let gdpsHide = ['achievements', 'messages']
|
||||||
|
|
||||||
app.get("/", function(req, res) {
|
app.get("/", function(req, res) {
|
||||||
if (req.query.hasOwnProperty("offline") || (req.offline && !req.query.hasOwnProperty("home"))) res.status(200).sendFile(__dirname + "/html/offline.html")
|
if (req.query.hasOwnProperty("offline") || (req.offline && !req.query.hasOwnProperty("home")))
|
||||||
|
res.status(200).sendFile(__dirname + "/html/offline.html")
|
||||||
else {
|
else {
|
||||||
fs.readFile('./html/home.html', 'utf8', function (err, data) {
|
fs.readFile('./html/home.html', 'utf8', function (err, data) {
|
||||||
let html = data;
|
let html = data
|
||||||
if (req.isGDPS) {
|
if (req.isGDPS) {
|
||||||
html = html.replace('"levelBG"', '"levelBG purpleBG"')
|
html = html
|
||||||
.replace(/Geometry Dash Browser!/g, req.server.name + " Browser!")
|
.replace('"levelBG"', '"levelBG purpleBG"')
|
||||||
.replace("/assets/gdlogo", `/assets/gdps/${req.id}_logo`)
|
.replace(/Geometry Dash Browser!/g, req.server.name + " Browser!")
|
||||||
.replace("coin.png\" itemprop", `gdps/${req.id}_icon.png" itemprop`)
|
.replace("/assets/gdlogo", `/assets/gdps/${req.id}_logo`)
|
||||||
.replace(/coin\.png/g, `${req.server.onePointNine ? "blue" : "silver"}coin.png`)
|
.replace("coin.png\" itemprop", `gdps/${req.id}_icon.png" itemprop`)
|
||||||
|
.replace(/coin\.png/g, `${req.server.onePointNine ? "blue" : "silver"}coin.png`)
|
||||||
|
|
||||||
gdpsHide.forEach(x => { html = html.replace(`menu-${x}`, 'changeDaWorld') })
|
gdpsHide.forEach(x => { html = html.replace(`menu-${x}`, 'changeDaWorld') })
|
||||||
}
|
}
|
||||||
if (req.onePointNine) onePointNineDisabled.forEach(x => { html = html.replace(`menu-${x}`, 'menuDisabled') })
|
const htmlReplacer = x => { html = html.replace(`menu-${x}`, 'menuDisabled') }
|
||||||
if (req.server.disabled) req.server.disabled.forEach(x => { html = html.replace(`menu-${x}`, 'menuDisabled') })
|
if (req.onePointNine) onePointNineDisabled.forEach(htmlReplacer)
|
||||||
|
if (req.server.disabled) req.server.disabled.forEach(htmlReplacer)
|
||||||
if (req.server.downloadsDisabled && process.platform == "linux") {
|
if (req.server.downloadsDisabled && process.platform == "linux") {
|
||||||
downloadDisabled.forEach(x => { html = html.replace(`menu-${x}`, 'menuDisabled') })
|
downloadDisabled.forEach(htmlReplacer)
|
||||||
html = html.replace('id="dl" style="display: none', 'style="display: block')
|
html = html
|
||||||
.replace('No active <span id="noLevel">daily</span> level!', '[Blocked by RobTop]')
|
.replace('id="dl" style="display: none', 'style="display: block')
|
||||||
|
.replace('No active <span id="noLevel">daily</span> level!', '[Blocked by RobTop]')
|
||||||
}
|
}
|
||||||
if (html.includes('menuDisabled" src="../assets/category-weekly')) { // if weekly disabled, replace with featured
|
if (html.includes('menuDisabled" src="/assets/category-weekly')) { // if weekly disabled, replace with featured
|
||||||
html = html.replace('block" id="menu_weekly', 'none" id="menu_weekly')
|
html = html
|
||||||
.replace('none" id="menu_featured', 'block" id="menu_featured')
|
.replace('block" id="menu_weekly', 'none" id="menu_weekly')
|
||||||
|
.replace('none" id="menu_featured', 'block" id="menu_featured')
|
||||||
}
|
}
|
||||||
return res.status(200).send(html)
|
return res.status(200).send(html)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function sendHTML(dir, name) {
|
||||||
|
app.get("/" + dir, function(req, res) { res.status(200).sendFile(`${__dirname}/html/${name || dir}.html`) })
|
||||||
|
}
|
||||||
|
sendHTML("achievements")
|
||||||
|
sendHTML("analyze/:id", "analyze")
|
||||||
|
sendHTML("api")
|
||||||
|
sendHTML("boomlings")
|
||||||
|
sendHTML("comments/:id", "comments")
|
||||||
|
sendHTML("demon/:id", "demon")
|
||||||
|
sendHTML("gauntlets")
|
||||||
|
sendHTML("gdps")
|
||||||
|
sendHTML("iconkit")
|
||||||
|
sendHTML("leaderboard")
|
||||||
|
sendHTML("leaderboard/:text", "levelboard")
|
||||||
|
sendHTML("mappacks")
|
||||||
|
sendHTML("messages")
|
||||||
|
sendHTML("search", "filters")
|
||||||
|
sendHTML("search/:text", "search")
|
||||||
|
|
||||||
app.get("/achievements", function(req, res) { res.status(200).sendFile(__dirname + "/html/achievements.html") })
|
|
||||||
app.get("/analyze/:id", function(req, res) { res.status(200).sendFile(__dirname + "/html/analyze.html") })
|
|
||||||
app.get("/api", function(req, res) { res.status(200).sendFile(__dirname + "/html/api.html") })
|
|
||||||
app.get("/boomlings", function(req, res) { res.status(200).sendFile(__dirname + "/html/boomlings.html") })
|
|
||||||
app.get("/comments/:id", function(req, res) { res.status(200).sendFile(__dirname + "/html/comments.html") })
|
|
||||||
app.get("/demon/:id", function(req, res) { res.status(200).sendFile(__dirname + "/html/demon.html") })
|
|
||||||
app.get("/gauntlets", function(req, res) { res.status(200).sendFile(__dirname + "/html/gauntlets.html") })
|
|
||||||
app.get("/gdps", function(req, res) { res.status(200).sendFile(__dirname + "/html/gdps.html") })
|
|
||||||
app.get("/iconkit", function(req, res) { res.status(200).sendFile(__dirname + "/html/iconkit.html") })
|
|
||||||
app.get("/leaderboard", function(req, res) { res.status(200).sendFile(__dirname + "/html/leaderboard.html") })
|
|
||||||
app.get("/leaderboard/:text", function(req, res) { res.status(200).sendFile(__dirname + "/html/levelboard.html") })
|
|
||||||
app.get("/mappacks", function(req, res) { res.status(200).sendFile(__dirname + "/html/mappacks.html") })
|
|
||||||
app.get("/messages", function(req, res) { res.status(200).sendFile(__dirname + "/html/messages.html") })
|
|
||||||
app.get("/search", function(req, res) { res.status(200).sendFile(__dirname + "/html/filters.html") })
|
|
||||||
app.get("/search/:text", function(req, res) { res.status(200).sendFile(__dirname + "/html/search.html") })
|
|
||||||
|
|
||||||
// API
|
// API
|
||||||
|
|
||||||
app.get("/api/analyze/:id", RL, function(req, res) { app.run.level(app, req, res, true, true) })
|
|
||||||
app.get("/api/boomlings", function(req, res) { app.run.boomlings(app, req, res) })
|
function doGET(name, key, RL, wtf1, wtf2) {
|
||||||
app.get("/api/comments/:id", RL2, function(req, res) { app.run.comments(app, req, res) })
|
const args = ["/api/" + name]
|
||||||
|
if (RL !== null && RL !== undefined) args.push(RL)
|
||||||
|
app.post(...args, function(req, res) { app.run[ key || name ](app, req, res, wtf1 ? true : undefined, wtf2 ? true : undefined) })
|
||||||
|
}
|
||||||
|
|
||||||
|
doGET("analyze/:id", "level", RL, true, true)
|
||||||
|
doGET("boomlings", "", null)
|
||||||
|
doGET("comments/:id", "comments", RL2)
|
||||||
|
|
||||||
app.get("/api/credits", function(req, res) { res.status(200).send(require('./misc/credits.json')) })
|
app.get("/api/credits", function(req, res) { res.status(200).send(require('./misc/credits.json')) })
|
||||||
app.get("/api/gauntlets", function(req, res) { app.run.gauntlets(app, req, res) })
|
|
||||||
|
doGET("gauntlets")
|
||||||
app.get("/api/leaderboard", function(req, res) { app.run[req.query.hasOwnProperty("accurate") ? "accurate" : "scores"](app, req, res) })
|
app.get("/api/leaderboard", function(req, res) { app.run[req.query.hasOwnProperty("accurate") ? "accurate" : "scores"](app, req, res) })
|
||||||
app.get("/api/leaderboardLevel/:id", RL2, function(req, res) { app.run.leaderboardLevel(app, req, res) })
|
doGET("leaderboardLevel/:id", "leaderboardLevel", RL2)
|
||||||
app.get("/api/level/:id", RL, function(req, res) { app.run.level(app, req, res, true) })
|
doGET("level/:id", "level", RL, true)
|
||||||
app.get("/api/mappacks", function(req, res) { app.run.mappacks(app, req, res) })
|
doGET("mappacks")
|
||||||
app.get("/api/profile/:id", RL2, function(req, res) { app.run.profile(app, req, res, true) })
|
doGET("profile/:id", "profile", RL2, true)
|
||||||
app.get("/api/search/:text", RL2, function(req, res) { app.run.search(app, req, res) })
|
doGET("search/:text", "search", RL2)
|
||||||
app.get("/api/song/:song", function(req, res){ app.run.song(app, req, res) })
|
doGET("song/:song", "song")
|
||||||
|
|
||||||
|
|
||||||
// REDIRECTS
|
// REDIRECTS
|
||||||
|
|
||||||
app.get("/icon", function(req, res) { res.redirect('/iconkit') })
|
function doRedir(name, dir, key = 'id') {
|
||||||
app.get("/obj/:text", function(req, res) { res.redirect('/obj/' + req.params.text) })
|
app.get('/' + name, function(req, res) { res.redirect('/' + dir + (key && '/' + req.params[key]) ) })
|
||||||
app.get("/leaderboards/:id", function(req, res) { res.redirect('/leaderboard/' + req.params.id) })
|
}
|
||||||
app.get("/profile/:id", function(req, res) { res.redirect('/u/' + req.params.id) })
|
doRedir('icon', 'iconkit', '')
|
||||||
app.get("/p/:id", function(req, res) { res.redirect('/u/' + req.params.id) })
|
doRedir('obj/:text', 'obj', 'text')
|
||||||
app.get("/l/:id", function(req, res) { res.redirect('/leaderboard/' + req.params.id) })
|
doRedir('leaderboards/:id', 'leaderboard')
|
||||||
app.get("/a/:id", function(req, res) { res.redirect('/analyze/' + req.params.id) })
|
doRedir('profile/:id', 'u')
|
||||||
app.get("/c/:id", function(req, res) { res.redirect('/comments/' + req.params.id) })
|
doRedir('p/:id', 'u')
|
||||||
app.get("/d/:id", function(req, res) { res.redirect('/demon/' + req.params.id) })
|
doRedir('l/:id', 'leaderboard')
|
||||||
|
doRedir('a/:id', 'analyze')
|
||||||
|
doRedir('c/:id', 'comments')
|
||||||
|
doRedir('d/:id', 'demon')
|
||||||
|
|
||||||
|
|
||||||
// API AND HTML
|
// API AND HTML
|
||||||
|
|
||||||
app.get("/u/:id", function(req, res) { app.run.profile(app, req, res) })
|
|
||||||
app.get("/:id", function(req, res) { app.run.level(app, req, res) })
|
|
||||||
|
|
||||||
|
doPOST("u/:id", "profile", true)
|
||||||
|
doPOST(":id", "level", true)
|
||||||
|
|
||||||
// MISC
|
// MISC
|
||||||
|
|
||||||
app.get("/api/userCache", function(req, res) { res.status(200).send(app.accountCache) })
|
app.get("/api/userCache", function(req, res) { res.status(200).send(app.accountCache) })
|
||||||
app.get("/api/achievements", function(req, res) { res.status(200).send({achievements, types: achievementTypes, shopIcons: sacredTexts.shops, colors: sacredTexts.colors }) })
|
app.get("/api/achievements", function(req, res) {
|
||||||
|
res.status(200).send(
|
||||||
|
{achievements, types: achievementTypes, shopIcons: sacredTexts.shops, colors: sacredTexts.colors}
|
||||||
|
)
|
||||||
|
})
|
||||||
app.get("/api/music", function(req, res) { res.status(200).send(music) })
|
app.get("/api/music", function(req, res) { res.status(200).send(music) })
|
||||||
app.get("/api/gdps", function(req, res) {res.status(200).send(req.query.hasOwnProperty("current") ? app.safeServers.find(x => req.server.id == x.id) : app.safeServers) })
|
app.get("/api/gdps", function(req, res) {
|
||||||
|
res.status(200).send(
|
||||||
|
req.query.hasOwnProperty("current")
|
||||||
|
? app.safeServers.find(x => req.server.id == x.id)
|
||||||
|
: app.safeServers
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
// important icon stuff
|
// important icon stuff
|
||||||
let sacredTexts = {}
|
let sacredTexts = {}
|
||||||
|
|
||||||
fs.readdirSync('./iconkit/sacredtexts').forEach(x => {
|
fs.readdirSync('./iconkit/sacredtexts').forEach(x => {
|
||||||
sacredTexts[x.split(".")[0]] = require("./iconkit/sacredtexts/" + x)
|
sacredTexts[x.split(".", 1)[0]] = require("./iconkit/sacredtexts/" + x)
|
||||||
})
|
})
|
||||||
|
|
||||||
let previewIcons = fs.readdirSync('./iconkit/premade')
|
let previewIcons = fs.readdirSync('./iconkit/premade')
|
||||||
|
@ -326,7 +380,7 @@ let newPreviewIcons = fs.readdirSync('./iconkit/newpremade')
|
||||||
let previewCounts = {}
|
let previewCounts = {}
|
||||||
previewIcons.forEach(x => {
|
previewIcons.forEach(x => {
|
||||||
if (x.endsWith("_0.png")) return
|
if (x.endsWith("_0.png")) return
|
||||||
let iconType = sacredTexts.forms[x.split("_")[0]].form
|
let iconType = sacredTexts.forms[x.split("_", 1)[0]].form
|
||||||
if (!previewCounts[iconType]) previewCounts[iconType] = 1
|
if (!previewCounts[iconType]) previewCounts[iconType] = 1
|
||||||
else previewCounts[iconType]++
|
else previewCounts[iconType]++
|
||||||
})
|
})
|
||||||
|
@ -337,15 +391,15 @@ sacredTexts.newIcons = []
|
||||||
let newIconCounts = {}
|
let newIconCounts = {}
|
||||||
newIcons.forEach(x => {
|
newIcons.forEach(x => {
|
||||||
if (x.endsWith(".plist")) {
|
if (x.endsWith(".plist")) {
|
||||||
sacredTexts.newIcons.push(x.split("-")[0])
|
sacredTexts.newIcons.push(x.split("-", 1)[0])
|
||||||
let formName = x.split(/_\d/g)[0]
|
let formName = x.split(/_\d/g, 1)[0]
|
||||||
if (!newIconCounts[formName]) newIconCounts[formName] = 1
|
if (!newIconCounts[formName]) newIconCounts[formName] = 1
|
||||||
else newIconCounts[formName]++
|
else newIconCounts[formName]++
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
sacredTexts.newIconCounts = newIconCounts
|
sacredTexts.newIconCounts = newIconCounts
|
||||||
Missing rate limitingThis route handler performs a file system access, but is not rate-limited. ## Missing rate limiting
This route handler performs [a file system access](1), but is not rate-limited.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/71)
|
|||||||
|
|
||||||
app.get('/api/icons', function(req, res) {
|
app.get('/api/icons', function(req, res) {
|
||||||
res.status(200).send(sacredTexts);
|
res.status(200).send(sacredTexts);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -353,37 +407,37 @@ app.get('/api/icons', function(req, res) {
|
||||||
let iconKitFiles = {}
|
let iconKitFiles = {}
|
||||||
let sampleIcons = require('./misc/sampleIcons.json')
|
let sampleIcons = require('./misc/sampleIcons.json')
|
||||||
fs.readdirSync('./iconkit/extradata').forEach(x => {
|
fs.readdirSync('./iconkit/extradata').forEach(x => {
|
||||||
iconKitFiles[x.split(".")[0]] = require("./iconkit/extradata/" + x)
|
iconKitFiles[x.split(".", 1)[0]] = require("./iconkit/extradata/" + x)
|
||||||
})
|
})
|
||||||
|
|
||||||
iconKitFiles.previewIcons = previewIcons
|
Object.assign(iconKitFiles, {previewIcons, newPreviewIcons})
|
||||||
iconKitFiles.newPreviewIcons = newPreviewIcons
|
|
||||||
|
|
||||||
app.get('/api/iconkit', function(req, res) {
|
app.get('/api/iconkit', function(req, res) {
|
||||||
let sample = [JSON.stringify(sampleIcons[Math.floor(Math.random() * sampleIcons.length)].slice(1))]
|
let sample = [JSON.stringify(sampleIcons[Math.random() * sampleIcons.length >>>0].slice(1))]
|
||||||
let iconserver = req.isGDPS ? req.server.name : undefined
|
let iconserver = req.isGDPS ? req.server.name : undefined
|
||||||
res.status(200).send(Object.assign(iconKitFiles, {sample, server: iconserver, noCopy: req.onePointNine || req.offline}));
|
res.status(200).send(Object.assign(iconKitFiles, {sample, server: iconserver, noCopy: req.onePointNine || req.offline}));
|
||||||
});
|
})
|
||||||
|
|
||||||
app.get('/icon/:text', function(req, res) {
|
app.get('/icon/:text', function(req, res) {
|
||||||
let iconID = Number(req.query.icon || 1)
|
let iconID = Number(req.query.icon || 1)
|
||||||
let iconForm = sacredTexts.forms[req.query.form] ? req.query.form : "icon"
|
let iconForm = sacredTexts.forms[req.query.form] ? req.query.form : "icon"
|
||||||
let iconPath = `${iconForm}_${iconID}.png`
|
let iconPath = `${iconForm}_${iconID}.png`
|
||||||
let fileExists = iconKitFiles.previewIcons.includes(iconPath)
|
let fileExists = iconKitFiles.previewIcons.includes(iconPath)
|
||||||
if (fileExists) return res.status(200).sendFile(`./iconkit/premade/${iconPath}`, {root: __dirname })
|
return res.status(200).sendFile(`./iconkit/premade/${fileExists ? iconPath : iconForm + '_01.png'}`, {root: __dirname})
|
||||||
else return res.status(200).sendFile(`./iconkit/premade/${iconForm}_01.png`, {root: __dirname})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
app.get('*', function(req, res) {
|
app.get('*', function(req, res) {
|
||||||
if (req.path.startsWith('/api') || req.path.startsWith("/iconkit")) res.status(404).send('-1')
|
if (/^\/(api|iconkit)/.test(req.path))
|
||||||
else res.redirect('/search/404%20')
|
res.status(404).send('-1')
|
||||||
});
|
else
|
||||||
|
res.redirect('/search/404%20')
|
||||||
app.use(function (err, req, res, next) {
|
|
||||||
if (err && err.message == "Response timeout") res.status(504).send('Internal server error! (Timed out)')
|
|
||||||
})
|
})
|
||||||
|
|
||||||
process.on('uncaughtException', (e) => { console.log(e) });
|
app.use(function (err, req, res) {
|
||||||
process.on('unhandledRejection', (e, p) => { console.log(e) });
|
if (err?.message == "Response timeout") res.status(504).send('Internal server error! (Timed out)')
|
||||||
|
})
|
||||||
|
|
||||||
app.listen(app.config.port, () => console.log(`Site online! (port ${app.config.port})`))
|
process.on('uncaughtException', e => console.log(e))
|
||||||
|
process.on('unhandledRejection', e => console.log(e))
|
||||||
|
|
||||||
|
app.listen(app.config.port, () => console.log(`Site online! (port ${app.config.port})`))
|
||||||
|
|
|
@ -1,30 +1,33 @@
|
||||||
|
"use strict";
|
||||||
function somethingSelected() {
|
function somethingSelected() {
|
||||||
return typeof window.getSelection == 'function' && window.getSelection().toString() != "";
|
return typeof window.getSelection == 'function' && window.getSelection().toString() != "";
|
||||||
}
|
}
|
||||||
const remover = / |\n|\t/g;
|
const remover = /[ \n\t]/g; //should it be /\s/g ?
|
||||||
$('.dragscroll').each(function(_, el) {
|
$('.dragscroll').each(function(_, el) {
|
||||||
let previouslyMouseDown = false;
|
let previouslyMouseDown = false
|
||||||
el.addEventListener('mousemove', function(e) {
|
el.addEventListener('mousemove', function(e) {
|
||||||
if (e.buttons != 1) {
|
if (e.buttons != 1) {
|
||||||
if (previouslyMouseDown) {
|
if (previouslyMouseDown) {
|
||||||
el.style.removeProperty('user-select');
|
el.style.removeProperty('user-select')
|
||||||
el.style.removeProperty('-webkit-user-select');
|
el.style.removeProperty('-webkit-user-select')
|
||||||
previouslyMouseDown = false;
|
previouslyMouseDown = false;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (somethingSelected())
|
if (somethingSelected()) return
|
||||||
return;
|
|
||||||
if (!previouslyMouseDown) {
|
if (!previouslyMouseDown) {
|
||||||
for (let el of e.target.childNodes) {
|
if ([...e.target.childNodes].some(
|
||||||
if (el.nodeType === Node.TEXT_NODE && el.textContent.replace(remover, '').length)
|
el => el.nodeType === Node.TEXT_NODE
|
||||||
return;
|
&&
|
||||||
}
|
el.textContent.replace(remover, '').length
|
||||||
el.style['user-select'] = 'none';
|
)
|
||||||
el.style['-webkit-user-select'] = 'none';
|
) return
|
||||||
|
|
||||||
|
el.style['user-select'] = 'none'
|
||||||
|
el.style['-webkit-user-select'] = 'none'
|
||||||
previouslyMouseDown = true;
|
previouslyMouseDown = true;
|
||||||
}
|
}
|
||||||
//el.scrollLeft -= e.movementX;
|
//el.scrollLeft -= e.movementX
|
||||||
el.scrollTop -= e.movementY;
|
el.scrollTop -= e.movementY;
|
||||||
}, {passive: true});
|
}, {passive: true});
|
||||||
});
|
});
|
111
misc/global.js
|
@ -1,3 +1,4 @@
|
||||||
|
"use strict";
|
||||||
$('body').append(`
|
$('body').append(`
|
||||||
<div data-nosnippet id="tooSmall" class="brownbox center supercenter" style="display: none; width: 80%">
|
<div data-nosnippet id="tooSmall" class="brownbox center supercenter" style="display: none; width: 80%">
|
||||||
<h1>Yikes!</h1>
|
<h1>Yikes!</h1>
|
||||||
|
@ -9,28 +10,36 @@ $('body').append(`
|
||||||
`)
|
`)
|
||||||
|
|
||||||
|
|
||||||
$(window).resize(function () {
|
$(window).resize(function() {
|
||||||
if (window.innerHeight > window.innerWidth - 75) {
|
// these alternatives may be helpful: https://stackoverflow.com/a/4917796
|
||||||
$('#everything').hide();
|
let isPortrait = window.innerHeight > window.innerWidth - 75
|
||||||
$('#tooSmall').show();
|
$('#everything')[isPortrait ? 'hide' : 'show']()
|
||||||
}
|
$('#tooSmall')[isPortrait ? 'show' : 'hide']()
|
||||||
|
})
|
||||||
|
|
||||||
else {
|
// supports Numbers, BigInts, and Strings!
|
||||||
$('#everything').show();
|
const clamp = (x, min, max) => x < min ? min : (x > max ? max : x) // interval [min, max]
|
||||||
$('#tooSmall').hide()
|
|
||||||
}
|
const randRange = (min, max) => Math.random() * (max - min) + +min // prevent string concat
|
||||||
});
|
// interval [min, max)
|
||||||
|
const randInt = (min, max) => Math.floor(randRange(min, max))
|
||||||
|
|
||||||
|
//fn, to always get an updated answer
|
||||||
|
let isDownloadURL = () => window.location.href.endsWith('?download')
|
||||||
|
|
||||||
function saveUrl() {
|
function saveUrl() {
|
||||||
if (window.location.href.endsWith('?download')) return;
|
if ( !isDownloadURL() ) sessionStorage.setItem('prevUrl', window.location.href)
|
||||||
sessionStorage.setItem('prevUrl', window.location.href);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function backButton() {
|
function backButton() {
|
||||||
if (window.history.length > 1 && document.referrer.startsWith(window.location.origin)){
|
if (window.history.length > 1 && document.referrer.startsWith(window.location.origin)) {
|
||||||
if (window.location.href.endsWith('?download') && sessionStorage.getItem('prevUrl') === window.location.href.replace('?download', '')) window.history.go(-2);
|
let steps = (
|
||||||
else window.history.back()
|
isDownloadURL() &&
|
||||||
}
|
sessionStorage.getItem('prevUrl') === window.location.href.replace('?download', '')
|
||||||
|
? -2 : -1
|
||||||
|
)
|
||||||
|
window.history.go(steps)
|
||||||
|
}
|
||||||
else window.location.href = "../../../../../"
|
else window.location.href = "../../../../../"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,23 +51,23 @@ function Fetch(link) {
|
||||||
fetch(link).then(resp => {
|
fetch(link).then(resp => {
|
||||||
if (!resp.ok) return rej(resp)
|
if (!resp.ok) return rej(resp)
|
||||||
gdps = resp.headers.get('gdps')
|
gdps = resp.headers.get('gdps')
|
||||||
if (gdps && gdps.startsWith('1.9/')) { onePointNine = true; gdps = gdps.slice(4) }
|
if (gdps?.startsWith('1.9/')) { onePointNine = true; gdps = gdps.slice(4) }
|
||||||
resp.json().then(res)
|
resp.json().then(res)
|
||||||
}).catch(rej)
|
}).catch(rej)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let allowEsc = true;
|
let allowEsc = true
|
||||||
let popupEsc = true;
|
let popupEsc = true
|
||||||
|
|
||||||
$(document).keydown(function(k) {
|
$(document).keydown(function(k) {
|
||||||
if (k.keyCode == 27) { //esc
|
if (k.code != 'Escape' || !allowEsc) return
|
||||||
if (!allowEsc) return
|
k.preventDefault()
|
||||||
k.preventDefault()
|
if (popupEsc && $('.popup').is(":visible"))
|
||||||
if (popupEsc && $('.popup').is(":visible")) $('.popup').hide();
|
$('.popup').hide()
|
||||||
else $('#backButton').trigger('click')
|
else
|
||||||
}
|
$('#backButton').trigger('click')
|
||||||
});
|
})
|
||||||
|
|
||||||
let iconData = null
|
let iconData = null
|
||||||
let iconCanvas = null
|
let iconCanvas = null
|
||||||
|
@ -72,9 +81,9 @@ async function renderIcons() {
|
||||||
if (overrideLoader) return
|
if (overrideLoader) return
|
||||||
let iconsToRender = $('gdicon:not([rendered], [dontload])')
|
let iconsToRender = $('gdicon:not([rendered], [dontload])')
|
||||||
if (iconsToRender.length < 1) return
|
if (iconsToRender.length < 1) return
|
||||||
if (!iconData) iconData = await Fetch("../api/icons")
|
iconData ||= await Fetch("/api/icons")
|
||||||
if (!iconCanvas) iconCanvas = document.createElement('canvas')
|
iconCanvas ||= document.createElement('canvas')
|
||||||
if (!iconRenderer) iconRenderer = new PIXI.Application({ view: iconCanvas, width: 300, height: 300, backgroundAlpha: 0});
|
iconRenderer ||= new PIXI.Application({ view: iconCanvas, width: 300, height: 300, backgroundAlpha: 0})
|
||||||
if (loader.loading) return overrideLoader = true
|
if (loader.loading) return overrideLoader = true
|
||||||
buildIcon(iconsToRender, 0)
|
buildIcon(iconsToRender, 0)
|
||||||
}
|
}
|
||||||
|
@ -121,37 +130,37 @@ function finishIcon(currentIcon, name, data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset scroll
|
// reset scroll
|
||||||
while ($(this).scrollTop() != 0) {
|
while ($(this).scrollTop() != 0)
|
||||||
$(this).scrollTop(0);
|
$(this).scrollTop(0);
|
||||||
}
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$(window).trigger('resize');
|
$(window).trigger('resize')
|
||||||
});
|
|
||||||
|
|
||||||
// Adds all necessary elements into the tab index (all buttons and links that aren't natively focusable)
|
|
||||||
const inaccessibleLinkSelector = "*:not(a) > img.gdButton, .leaderboardTab, .gdcheckbox, .diffDiv, .lengthDiv";
|
|
||||||
|
|
||||||
document.querySelectorAll(inaccessibleLinkSelector).forEach(elem => {
|
|
||||||
elem.setAttribute('tabindex', 0);
|
|
||||||
})
|
})
|
||||||
|
|
||||||
document.getElementById('backButton')?.setAttribute('tabindex', 1); // Prioritize back button, first element to be focused
|
// Adds all necessary elements into the tab index (all buttons and links that aren't natively focusable)
|
||||||
|
const inaccessibleLinkSelector = "*:not(a) > img.gdButton, .leaderboardTab, .gdcheckbox, .diffDiv, .lengthDiv"
|
||||||
|
|
||||||
|
document.querySelectorAll(inaccessibleLinkSelector)
|
||||||
|
.forEach(elem => { elem.setAttribute('tabindex', 0) })
|
||||||
|
|
||||||
|
document.getElementById('backButton')?.setAttribute('tabindex', 1) // Prioritize back button, first element to be focused
|
||||||
|
|
||||||
// Event listener to run a .click() function if
|
// Event listener to run a .click() function if
|
||||||
window.addEventListener("keydown", e => {
|
window.addEventListener("keydown", k => {
|
||||||
if(e.key !== 'Enter') return;
|
// standard and Numpad support
|
||||||
|
if ( !k.code.endsWith('Enter') ) return
|
||||||
|
|
||||||
const active = document.activeElement;
|
const active = document.activeElement
|
||||||
const isUnsupportedLink = active.hasAttribute('tabindex'); // Only click on links that aren't already natively supported to prevent double clicking
|
const isUnsupportedLink = active.hasAttribute('tabindex') // Only click on links that aren't already natively supported to prevent double clicking
|
||||||
if(isUnsupportedLink) active.click();
|
if(isUnsupportedLink) active.click()
|
||||||
})
|
})
|
||||||
|
|
||||||
// stolen from stackoverflow
|
// stolen from stackoverflow
|
||||||
$.fn.isInViewport = function () {
|
$.fn.isInViewport = function () {
|
||||||
let elementTop = $(this).offset().top;
|
let elementTop = $(this).offset().top
|
||||||
let elementBottom = elementTop + $(this).outerHeight();
|
let elementBottom = elementTop + $(this).outerHeight()
|
||||||
let viewportTop = $(window).scrollTop();
|
let viewportTop = $(window).scrollTop()
|
||||||
let viewportBottom = viewportTop + $(window).height();
|
let viewportBottom = viewportTop + $(window).height()
|
||||||
return elementBottom > viewportTop && elementTop < viewportBottom;
|
return elementBottom > viewportTop && elementTop < viewportBottom
|
||||||
};
|
}
|
||||||
|
|
|
@ -1,25 +1,26 @@
|
||||||
|
"use strict";
|
||||||
let path = "../extra/"
|
let path = "../extra/"
|
||||||
|
|
||||||
let files = ["AchievementsDesc", "AchievementsDescMD", null, "AchievementsDescSZ"]
|
const files = ["", "MD", null, "SZ"]
|
||||||
let gameNames = ["gd", "meltdown", "world", "subzero"]
|
const gameNames = ["gd", "meltdown", "world", "subzero"]
|
||||||
let achString = "geometry.ach."
|
const achString = "geometry.ach."
|
||||||
let rewardTypes = { color: "color1", icon: "cube", bird: "ufo", dart: "wave", special: "trail", death: "deathEffect" }
|
let rewardTypes = { color: "color1", icon: "cube", bird: "ufo", dart: "wave", special: "trail", death: "deathEffect" }
|
||||||
let games = { "md": "meltdown", "world.": "world", "subzero.": "subzero" }
|
let games = { "md": "meltdown", "world.": "world", "subzero.": "subzero" }
|
||||||
|
|
||||||
const plist = require('plist');
|
const plist = require('plist')
|
||||||
const fs = require('fs');
|
const fs = require('fs')
|
||||||
|
|
||||||
let achArray = []
|
let achArray = []
|
||||||
|
|
||||||
files.forEach((file, fileNum) => {
|
files.forEach((file, fileNum) => {
|
||||||
if (!file) return
|
if (file === null) return
|
||||||
let data = plist.parse(fs.readFileSync(path + file + '.plist', 'utf8'));
|
file = "AchievementsDesc" + file
|
||||||
|
f
|
||||||
console.log(`Converting ${file}.plist...`)
|
console.log(`Converting ${file}.plist...`)
|
||||||
|
|
||||||
for (let key in data) {
|
for (let key in data) {
|
||||||
if (!achArray.find(x => x.trueID == key)) {
|
if (!achArray.find(x => x.trueID == key)) {
|
||||||
let fileData = data[key];
|
let fileData = data[key]
|
||||||
let reward = fileData.icon ? fileData.icon.split("_") : []
|
let reward = fileData.icon ? fileData.icon.split("_") : []
|
||||||
let achObj = {
|
let achObj = {
|
||||||
id: key.slice(achString.length),
|
id: key.slice(achString.length),
|
||||||
|
|
|
@ -1,16 +1,19 @@
|
||||||
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
|
|||||||
let gdPath = 'C:\\Program Files (x86)\\Steam\\steamapps\\common\\Geometry Dash\\Resources\\'
|
"use strict";
|
||||||
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
|
|||||||
|
const gdPath = 'C:\\Program Files (x86)\\Steam\\steamapps\\common\\Geometry Dash\\Resources\\'
|
||||||
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
|
|||||||
|
|
||||||
const plist = require('plist');
|
const plist = require('plist')
|
||||||
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
|
|||||||
const fs = require('fs');
|
const fs = require('fs')
|
||||||
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
|
|||||||
const forms = require('./forms.json')
|
const forms = require('./forms.json')
|
||||||
const data = plist.parse(fs.readFileSync(gdPath + 'GJ_GameSheet02-uhd.plist', 'utf8'));
|
const data = plist.parse(fs.readFileSync(gdPath + 'GJ_GameSheet02-uhd.plist', 'utf8'))
|
||||||
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
|
|||||||
const glowSheet = plist.parse(fs.readFileSync(gdPath + 'GJ_GameSheetGlow-uhd.plist', 'utf8'));
|
const glowSheet = plist.parse(fs.readFileSync(gdPath + 'GJ_GameSheetGlow-uhd.plist', 'utf8'))
|
||||||
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
|
|||||||
let formList = Object.values(forms).map(x => x.form)
|
let formList = Object.values(forms).map(x => x.form)
|
||||||
|
|
||||||
let frames = {}
|
let frames = {}
|
||||||
|
|
||||||
function addIcons(data) {
|
function addIcons(data) {
|
||||||
Object.keys(data).filter(x => formList.includes(x.split("_")[0])).forEach(x => frames[x] = data[x])
|
Object.keys(data)
|
||||||
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
|
|||||||
|
.filter(k => formList.includes(k.split("_", 1)[0]))
|
||||||
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
|
|||||||
|
.forEach(k => frames[k] = data[k])
|
||||||
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
|
|||||||
}
|
}
|
||||||
|
|
||||||
addIcons(data.frames)
|
addIcons(data.frames)
|
||||||
|
@ -18,13 +21,13 @@ addIcons(glowSheet.frames)
|
||||||
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
|
|||||||
|
|
||||||
for (let key in frames) {
|
for (let key in frames) {
|
||||||
if (key.startsWith(".")) delete frames[key]
|
if (key.startsWith(".")) delete frames[key]
|
||||||
else { let fileData = frames[key];
|
else {
|
||||||
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
|
|||||||
for (let innerKey in fileData) {
|
let fileData = frames[key]
|
||||||
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
|
|||||||
if (typeof fileData[innerKey]) {
|
for (let innerKey in fileData) {
|
||||||
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
|
|||||||
if (!["spriteSize", "spriteOffset"].includes(innerKey)) delete fileData[innerKey] // remove useless stuff
|
if (!["spriteSize", "spriteOffset"].includes(innerKey)) delete fileData[innerKey] // remove useless stuff
|
||||||
else fileData[innerKey] = JSON.parse(fileData[innerKey].replace(/{/g, '[').replace(/}/g, ']'));
|
else fileData[innerKey] = JSON.parse(fileData[innerKey].replaceAll('{', '[').replaceAll('}', ']'))
|
||||||
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}
|
}
|
||||||
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
|
|||||||
fs.writeFileSync('./parsed/gameSheet.json', JSON.stringify(frames, null, 2).replace(/\[\n.+?(-?\d+),\n.+?(-?\d+)\n.+]/g, "[$1, $2]")); // regex to make it easier to read
|
fs.writeFileSync('./parsed/gameSheet.json', JSON.stringify(frames, null, 2).replace(/\[\n.+?(-?\d+),\n.+?(-?\d+)\n.+]/g, "[$1, $2]")); // regex to make it easier to read
|
||||||
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
|
|||||||
console.log("Successfully parsed!")
|
console.log("Successfully parsed!")
|
||||||
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
|
|||||||
|
|
||||||
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
Incomplete string escaping or encodingThis replaces only the first occurrence of '}}'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '}}'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/69)
Incomplete string escaping or encodingThis replaces only the first occurrence of '{{'. ## Incomplete string escaping or encoding
This replaces only the first occurrence of '{{'.
[Show more details](https://github.com/GDColon/GDBrowser/security/code-scanning/70)
I realized I realized `replaceAll` is better there
|
|
@ -1,5 +1,6 @@
|
||||||
const plist = require('plist');
|
"use strict";
|
||||||
const fs = require('fs');
|
const plist = require('plist')
|
||||||
|
const fs = require('fs')
|
||||||
const gdPath = 'C:\\Program Files (x86)\\Steam\\steamapps\\common\\Geometry Dash\\Resources\\'
|
const gdPath = 'C:\\Program Files (x86)\\Steam\\steamapps\\common\\Geometry Dash\\Resources\\'
|
||||||
const animationPlists = ["Robot_AnimDesc.plist", "Spider_AnimDesc.plist"]
|
const animationPlists = ["Robot_AnimDesc.plist", "Spider_AnimDesc.plist"]
|
||||||
const objectDefinitions = "objectDefinitions.plist"
|
const objectDefinitions = "objectDefinitions.plist"
|
||||||
|
@ -29,16 +30,16 @@ plistData.forEach(x => {
|
||||||
Object.keys(x.animationContainer).forEach(a => fullAnimationData[a] = x.animationContainer[a])
|
Object.keys(x.animationContainer).forEach(a => fullAnimationData[a] = x.animationContainer[a])
|
||||||
})
|
})
|
||||||
|
|
||||||
let animations = { "robot": {}, "spider": {} }
|
let animations = { robot: {}, spider: {} }
|
||||||
|
|
||||||
for (let animation in fullAnimationData) {
|
for (let animation in fullAnimationData) {
|
||||||
let animationName = animation.split(".")[0].split("_")
|
let animationName = animation.split(".", 1)[0].split("_")
|
||||||
let animationForm = animationName.shift()
|
let animationForm = animationName.shift()
|
||||||
let animationIndex = Number(animationName.pop()) - 1
|
let animationIndex = Number(animationName.pop()) - 1
|
||||||
animationName = animationName.join("_")
|
animationName = animationName.join("_")
|
||||||
|
|
||||||
let animationList = Object.values(fullAnimationData[animation])
|
let animationList = Object.values(fullAnimationData[animation])
|
||||||
let formName = animation.split("_")[0].toLowerCase()
|
let formName = animation.split("_", 1)[0].toLowerCase()
|
||||||
let animationData = animationList.map(anim => {
|
let animationData = animationList.map(anim => {
|
||||||
let textureInfo = anim.texture.split("_")
|
let textureInfo = anim.texture.split("_")
|
||||||
let flips = parseSet(anim.flipped)
|
let flips = parseSet(anim.flipped)
|
||||||
|
@ -55,17 +56,19 @@ for (let animation in fullAnimationData) {
|
||||||
if (!animations[formName][animationName]) {
|
if (!animations[formName][animationName]) {
|
||||||
let timingDefs = timings[animationForm].animations[animationName] || {}
|
let timingDefs = timings[animationForm].animations[animationName] || {}
|
||||||
let animationInfo = { duration: cleanFloat(Number(timingDefs.delay || 0.05) * 1000) }
|
let animationInfo = { duration: cleanFloat(Number(timingDefs.delay || 0.05) * 1000) }
|
||||||
if (timingDefs.looped == '1' || (!timingDefs.looped && animationName.includes("loop"))) animationInfo.loop = true
|
if (timingDefs.looped == '1' || (!timingDefs.looped && animationName.includes("loop")))
|
||||||
if (timingDefs.singleFrame) animationInfo.single = true
|
animationInfo.loop = true
|
||||||
|
if (timingDefs.singleFrame)
|
||||||
|
animationInfo.single = true
|
||||||
animations[formName][animationName] = { info: animationInfo, frames: [] }
|
animations[formName][animationName] = { info: animationInfo, frames: [] }
|
||||||
}
|
}
|
||||||
animations[formName][animationName].frames[animationIndex] = animationData
|
animations[formName][animationName].frames[animationIndex] = animationData
|
||||||
}
|
}
|
||||||
|
|
||||||
let cleanJSON = JSON.stringify({info, animations}, null, 2)
|
let cleanJSON = JSON.stringify({info, animations}, null, 2)
|
||||||
.replace(/: \[\n\s+([0-9a-z.-]+),\n\s+([0-9a-z.-]+)\n\s+],/g, ": [$1, $2],") // keep sets on one line
|
.replace(/: \[\n\s+([\da-z.-]+),\n\s+([\da-z.-]+)\n\s+],/g, ": [$1, $2],") // keep sets on one line
|
||||||
.replace(/],\n(\s+)"(.+?)": \[\n/g, '],\n\n$1"$2": [\n') // blank line between animations
|
.replace(/],\n(\s+)"(.+?)": \[\n/g, '],\n\n$1"$2": [\n') // blank line between animations
|
||||||
.replace(' "animations"', '\n "animations"') // blank line before animation list
|
.replace(' "animations"', '\n "animations"') // blank line before animation list
|
||||||
|
|
||||||
fs.writeFileSync('./parsed/robotAnimations.json', cleanJSON); // regex to make it easier to read
|
fs.writeFileSync('./parsed/robotAnimations.json', cleanJSON); // regex to make it easier to read
|
||||||
console.log("Successfully parsed!")
|
console.log("Successfully parsed!")
|
|
@ -17,7 +17,6 @@
|
||||||
[ "Cool", 37, 20, 17, 1 ],
|
[ "Cool", 37, 20, 17, 1 ],
|
||||||
[ "Cyclic", 30, 3, 12, 0 ],
|
[ "Cyclic", 30, 3, 12, 0 ],
|
||||||
[ "DanZmeN", 104, 34, 12, 1 ],
|
[ "DanZmeN", 104, 34, 12, 1 ],
|
||||||
[ "DanZmeN", 104, 34, 12, 1 ],
|
|
||||||
[ "envylol", 73, 20, 1, 1],
|
[ "envylol", 73, 20, 1, 1],
|
||||||
DanZmeN was duped lol DanZmeN was duped lol
|
|||||||
[ "EVW", 28, 12, 9, 0 ],
|
[ "EVW", 28, 12, 9, 0 ],
|
||||||
[ "Flub", 25, 3, 12, 1 ],
|
[ "Flub", 25, 3, 12, 1 ],
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
// Feel free to enable/disable stuff here for smoother local use, free of rate limits
|
// Feel free to enable/disable stuff here for smoother local use, free of rate limits
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
||||||
port: 2000, // Port to host website on
|
port: 2000, // Port to host website on
|
||||||
|
|
||||||
params: { // Always send this stuff to the servers
|
params: { // Always send this stuff to the servers
|
||||||
secret: 'Wmfd2893gb7',
|
secret: 'Wmfd2893gb7',
|
||||||
gameVersion: '21',
|
gameVersion: '21',
|
||||||
binaryVersion: '35',
|
binaryVersion: '35',
|
||||||
|
|
Use of a broken or weak cryptographic algorithm
Sensitive data from an access to username is used in a broken or weak cryptographic algorithm.
Sensitive data from an access to userName is used in a broken or weak cryptographic algorithm.
Show more details