Added IP forwarded for my boy Rob

This commit is contained in:
GDColon 2020-11-01 15:29:32 -05:00
parent 16a1b4d491
commit 2e6f104501
25 changed files with 85 additions and 125 deletions

View file

@ -7,7 +7,7 @@ module.exports = async (app, req, res) => {
let count = +req.query.count || 10
if (count > 1000) count = 1000
let params = app.gdParams({
let params = req.gdParams({
userID : req.params.id,
accountID : req.params.id,
levelID: req.params.id,
@ -20,8 +20,7 @@ module.exports = async (app, req, res) => {
if (req.query.type == "commentHistory") path = "getGJCommentHistory"
else if (req.query.type == "profile") path = "getGJAccountComments20"
request.post(`${app.endpoint}${path}.php`, {
form : params}, async function(err, resp, body) {
request.post(`${app.endpoint}${path}.php`, params, async function(err, resp, body) {
if (err || body == '-1' || !body) return res.send("-1")

View file

@ -14,9 +14,7 @@ module.exports = async (app, req, res, api, ID, analyze) => {
else if (levelID == "weekly") levelID = -2
else levelID = levelID.replace(/[^0-9]/g, "")
request.post(app.endpoint + 'downloadGJLevel22.php', {
form: app.gdParams({ levelID })
}, async function (err, resp, body) {
request.post(app.endpoint + 'downloadGJLevel22.php', req.gdParams({ levelID }), async function (err, resp, body) {
if (err || !body || body == '-1' || body.startsWith("<!")) {
if (!api && levelID < 0) return res.redirect('/')
@ -27,13 +25,9 @@ module.exports = async (app, req, res, api, ID, analyze) => {
let levelInfo = app.parseResponse(body)
let level = new Level(levelInfo)
request.post(app.endpoint + 'getGJUsers20.php', {
form: app.gdParams({ str: level.authorID })
}, function (err1, res1, b1) {
request.post(app.endpoint + 'getGJUsers20.php', req.gdParams({ str: level.authorID }), function (err1, res1, b1) {
let gdSearchResult = app.parseResponse(b1)
request.post(app.endpoint + 'getGJUserInfo20.php', {
form: app.gdParams({ targetAccountID: gdSearchResult[16] })
}, function (err2, res2, b2) {
request.post(app.endpoint + 'getGJUserInfo20.php', req.gdParams({ targetAccountID: gdSearchResult[16] }), function (err2, res2, b2) {
if (b2 != '-1') {
let account = app.parseResponse(b2)
level.author = account[1]
@ -45,9 +39,7 @@ module.exports = async (app, req, res, api, ID, analyze) => {
level.accountID = "0"
}
request.post(app.endpoint + 'getGJSongInfo.php', {
form: app.gdParams({ songID: level.customSong })
}, async function (err, resp, songRes) {
request.post(app.endpoint + 'getGJSongInfo.php', req.gdParams({ songID: level.customSong }), async function (err, resp, songRes) {
if (songRes != '-1') {
let songData = app.parseResponse(songRes, '~|~')

View file

@ -360,15 +360,11 @@ module.exports = async (app, req, res) => {
if (app.offline || req.query.hasOwnProperty("noUser") || req.query.hasOwnProperty("nouser") || username == "icon") return buildIcon()
res.contentType('image/png');
request.post(app.endpoint + 'getGJUsers20.php', {
form: app.gdParams({ str: username })
}, function (err1, res1, body1) {
request.post(app.endpoint + 'getGJUsers20.php', req.gdParams({ str: username }), function (err1, res1, body1) {
if (err1 || !body1 || body1 == "-1") return buildIcon()
else result = app.parseResponse(body1);
request.post(app.endpoint + 'getGJUserInfo20.php', {
form: app.gdParams({ targetAccountID: result[16] })
}, function (err2, res2, body2) {
request.post(app.endpoint + 'getGJUserInfo20.php', req.gdParams({ targetAccountID: result[16] }), function (err2, res2, body2) {
if (!err2 && body2 && body2 != '-1') return buildIcon(app.parseResponse(body2));
else return buildIcon()

View file

@ -29,9 +29,7 @@ module.exports = async (app, req, res, post) => {
idArray.forEach((x, y) => {
request.post(app.endpoint + 'getGJUserInfo20.php', {
form: app.gdParams({targetAccountID: x})
}, function (err, resp, body) {
request.post(app.endpoint + 'getGJUserInfo20.php', req.gdParams({targetAccountID: x}), function (err, resp, body) {
if (err || !body || body == '-1') return res.send([])
let account = app.parseResponse(body)

View file

@ -11,15 +11,14 @@ module.exports = async (app, req, res) => {
else amount = count;
}
let params = app.gdParams({
let params = req.gdParams({
levelID: req.params.id,
accountID: app.id,
gjp: app.gjp,
type: req.query.hasOwnProperty("week") ? "2" : "1",
})
request.post(app.endpoint + 'getGJLevelScores211.php', {
form : params, headers: {'x-forwarded-for': req.headers['x-real-ip']}}, async function(err, resp, body) {
request.post(app.endpoint + 'getGJLevelScores211.php', params, async function(err, resp, body) {
if (err || body == '-1' || !body) return res.send("-1")
scores = body.split('|').map(x => app.parseResponse(x))

View file

@ -11,13 +11,12 @@ module.exports = async (app, req, res) => {
else amount = count;
}
let params = app.gdParams({
let params = req.gdParams({
count: amount,
type: (req.query.hasOwnProperty("creator") || req.query.hasOwnProperty("creators")) ? "creators" : "top",
})
request.post(app.endpoint + 'getGJScores20.php', {
form : params}, async function(err, resp, body) {
request.post(app.endpoint + 'getGJScores20.php', params, async function(err, resp, body) {
if (err || body == '-1' || !body) return res.send("-1")
scores = body.split('|').map(x => app.parseResponse(x)).filter(x => x[1])

View file

@ -22,12 +22,7 @@ module.exports = async (app, req, res, api, analyze) => {
if (analyze || req.query.hasOwnProperty("download")) return app.run.download(app, req, res, api, levelID, analyze)
request.post(app.endpoint + 'getGJLevels21.php', {
form: app.gdParams({
str: levelID,
type: 0
})
}, async function (err, resp, body) {
request.post(app.endpoint + 'getGJLevels21.php', req.gdParams({ str: levelID, type: 0 }), async function (err, resp, body) {
if (err || !body || body == '-1' || body.startsWith("<!")) {
if (!api) return res.redirect('search/' + req.params.id)

View file

@ -7,16 +7,13 @@ module.exports = async (app, req, res) => {
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!")
let params = app.gdParams({
let params = req.gdParams({
accountID: req.body.accountID,
targetAccountID: req.body.accountID,
gjp: xor.encrypt(req.body.password, 37526),
})
request.post(app.endpoint + 'getGJUserInfo20.php', {
form: params,
headers: {'x-forwarded-for': req.headers['x-real-ip']}
}, async function (err, resp, body) {
request.post(app.endpoint + 'getGJUserInfo20.php', params, async function (err, resp, body) {
if (err || body == '-1' || body == '-2' || !body) return res.status(400).send("Error fetching profile! Make sure your username and password are entered correctly. (this is not an issue with gdbrowser)")
let count = app.parseResponse(body)[38]

View file

@ -8,18 +8,15 @@ module.exports = async (app, req, res, api) => {
if (!req.body.password) return res.status(400).send("No password provided!")
if (!req.body.id) return res.status(400).send("No message ID(s) provided!")
let params = app.gdParams({
let params = {
accountID: req.body.accountID,
gjp: xor.encrypt(req.body.password, 37526),
messages: Array.isArray(req.body.id) ? req.body.id.map(x => x.trim()).join(",") : req.body.id,
})
}
let deleted = params.messages.split(",").length
request.post(app.endpoint + 'deleteGJMessages20.php', {
form: params,
headers: {'x-forwarded-for': req.headers['x-real-ip']}
}, async function (err, resp, body) {
request.post(app.endpoint + 'deleteGJMessages20.php', req.gdParams(params), async function (err, resp, body) {
if (body != 1) return res.status(400).send("The Geometry Dash servers refused to delete the message! Make sure your username and password are entered correctly.")
else res.status(200).send(`${deleted == 1 ? "1 message" : `${deleted} messages`} deleted!`)

View file

@ -7,16 +7,13 @@ module.exports = async (app, req, res, api) => {
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!")
let params = app.gdParams({
let params = req.gdParams({
accountID: req.body.accountID,
gjp: xor.encrypt(req.body.password, 37526),
messageID: req.params.id,
})
request.post(app.endpoint + 'downloadGJMessage20.php', {
form: params,
headers: {'x-forwarded-for': req.headers['x-real-ip']}
}, async function (err, resp, body) {
request.post(app.endpoint + 'downloadGJMessage20.php', params, async function (err, resp, body) {
if (err || body == '-1' || !body) return res.status(400).send("Error fetching message!")

View file

@ -8,17 +8,14 @@ module.exports = async (app, req, res, api) => {
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!")
let params = app.gdParams({
let params = req.gdParams({
accountID: req.body.accountID,
gjp: xor.encrypt(req.body.password, 37526),
page: req.body.page || 0,
getSent: req.query.sent ? 1 : 0
})
request.post(app.endpoint + 'getGJMessages20.php', {
form: params,
headers: {'x-forwarded-for': req.headers['x-real-ip']}
}, async function (err, resp, body) {
request.post(app.endpoint + 'getGJMessages20.php', params, async function (err, resp, body) {
if (err || body == '-1' || body == '-2' || !body) return res.status(400).send("Error fetching messages!")

View file

@ -12,17 +12,14 @@ module.exports = async (app, req, res, api) => {
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 body = xor.encrypt(req.body.message.slice(0, 300), 14251)
let params = app.gdParams({
let params = req.gdParams({
accountID: req.body.accountID,
gjp: xor.encrypt(req.body.password, 37526),
toAccountID: req.body.targetID,
subject, body,
})
request.post(app.endpoint + 'uploadGJMessage20.php', {
form: params,
headers: {'x-forwarded-for': req.headers['x-real-ip']}
}, async function (err, resp, body) {
request.post(app.endpoint + 'uploadGJMessage20.php', params, async function (err, resp, body) {
if (body != 1) return res.status(400).send("The Geometry Dash servers refused to send the message! Make sure your username and password are entered correctly.")
else res.status(200).send('Message sent!')

View file

@ -13,11 +13,11 @@ module.exports = async (app, req, res) => {
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 = app.gdParams({
let params = {
udid: '0',
uuid: '0',
rs: '8f0l0ClAN1'
})
}
params.itemID = req.body.ID.toString()
params.gjp = xor.encrypt(req.body.password, 37526)
@ -32,10 +32,7 @@ module.exports = async (app, req, res) => {
params.chk = chk
request.post(app.endpoint + 'likeGJItem211.php', {
form: params,
headers: {'x-forwarded-for': req.headers['x-real-ip']}
}, function (err, resp, body) {
request.post(app.endpoint + 'likeGJItem211.php', req.gdParams(params), function (err, resp, body) {
if (err) return res.status(400).send("The Geometry Dash servers returned an error! Perhaps they're down for maintenance")
if (!body || body == "-1") return res.status(400).send("The Geometry Dash servers rejected your vote! Make sure your username and password are entered correctly.")
res.status(200).send((params.like == 1 ? 'Successfully liked!' : 'Successfully disliked!') + " (this will only take effect if this is your first time doing so)")

View file

@ -24,9 +24,7 @@ module.exports = async (app, req, res) => {
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 = app.gdParams({
percent: 0
})
let params = { percent: 0 }
params.comment = Buffer.from(req.body.comment + (req.body.color ? "☆" : "")).toString('base64').replace(/\//g, '_').replace(/\+/g, "-")
params.gjp = xor.encrypt(req.body.password, 37526)
@ -42,10 +40,7 @@ module.exports = async (app, req, res) => {
chk = xor.encrypt(chk, 29481)
params.chk = chk
request.post(app.endpoint + 'uploadGJComment21.php', {
form: params,
headers: {'x-forwarded-for': req.headers['x-real-ip']} // prevent pesky ip bans
}, function (err, resp, body) {
request.post(app.endpoint + 'uploadGJComment21.php', req.gdParams(params), function (err, resp, body) {
if (err) return res.status(400).send("The Geometry Dash servers returned an error! Perhaps they're down for maintenance")
if (!body || body == "-1") 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.")
if (body.startsWith("temp")) {

View file

@ -13,9 +13,7 @@ module.exports = async (app, req, res) => {
if (req.body.comment.includes('\n')) return res.status(400).send("Profile posts cannot contain line breaks!")
let params = app.gdParams({
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.gjp = xor.encrypt(req.body.password, 37526)
@ -27,10 +25,7 @@ module.exports = async (app, req, res) => {
chk = xor.encrypt(chk, 29481)
params.chk = chk
request.post(app.endpoint + 'uploadGJAccComment20.php', {
form: params,
headers: {'x-forwarded-for': req.headers['x-real-ip']}
}, function (err, resp, body) {
request.post(app.endpoint + 'uploadGJAccComment20.php', req.gdParams(params), function (err, resp, body) {
if (err) return res.status(400).send("The Geometry Dash servers returned an error! Perhaps they're down for maintenance")
if (!body || body == "-1") 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.")
res.status(200).send(`Comment posted to ${params.userName} with ID ${body}`)

View file

@ -5,15 +5,11 @@ module.exports = async (app, req, res, api, getLevels) => {
if (app.offline) return res.send("-1")
request.post(app.endpoint + 'getGJUsers20.php', {
form: app.gdParams({ str: getLevels || req.params.id })
}, function (err1, res1, b1) {
request.post(app.endpoint + 'getGJUsers20.php', req.gdParams({ str: getLevels || req.params.id }), function (err1, res1, b1) {
let searchResult = (req.query.hasOwnProperty("account") || err1 || b1 == '-1' || b1.startsWith("<!") || !b1) ? req.params.id : app.parseResponse(b1)[16]
let searchResult = ((!req.query.hasOwnProperty("player") && Number(req.params.id)) || err1 || b1 == '-1' || b1.startsWith("<!") || !b1) ? req.params.id : app.parseResponse(b1)[16]
request.post(app.endpoint + 'getGJUserInfo20.php', {
form: app.gdParams({ targetAccountID: searchResult })
}, function (err2, res2, body) {
request.post(app.endpoint + 'getGJUserInfo20.php', req.gdParams({ targetAccountID: searchResult }), function (err2, res2, body) {
if (err2 || body == '-1' || !body) {
if (!api) return res.redirect('/search/' + req.params.id)

View file

@ -14,7 +14,7 @@ module.exports = async (app, req, res) => {
else amount = count;
}
let filters = app.gdParams({
let filters = {
str: req.params.text,
diff: req.query.diff,
@ -35,7 +35,7 @@ module.exports = async (app, req, res) => {
customSong: req.query.hasOwnProperty("customSong") ? 1 : 0,
type: req.query.type || 0,
})
}
let foundPack = mapPacks[req.params.text.toLowerCase()]
if (foundPack) filters.str = `${foundPack[0]},${foundPack[1]},${foundPack[2]}`;
@ -66,10 +66,8 @@ module.exports = async (app, req, res) => {
if (req.query.hasOwnProperty("creators")) filters.type = 12
if (req.params.text == "*") delete filters.str
request.post(app.endpoint + 'getGJLevels21.php', {
form : filters}, async function(err, resp, body) {
request.post(app.endpoint + 'getGJLevels21.php', req.gdParams(filters), async function(err, resp, body) {
if (err || !body || body == '-1' || body.startsWith("<!")) return res.send("-1")
let splitBody = body.split('#')

View file

@ -291,7 +291,7 @@ input:focus, select:focus, textarea:focus, button:focus {
}
.iconSelected {
border-image: url('https://gdcolon.com/assets/gj_select.png') 10 stretch !important;
border-image: url('./../assets/select.png') 10 stretch !important;
}
.iconTabButton, .glowToggle, .copyForm {

BIN
assets/select.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -12,6 +12,8 @@ module.exports = {
binaryVersion: '35',
},
rateLimiting: true, // Enables rate limiting to avoid api spam, feel free to disable for private use
ipForwarding: true, // Forwards 'x-real-ip' to the servers (requested by robtop)
base64descriptions: true, // Are level descriptions encoded in Base64?
xorPasswords: true, // Are level passwords XOR encrypted?
timestampSuffix: " ago", // Suffix to add after timestamps, if any.

View file

@ -188,7 +188,7 @@
<br>
<p class="reveal" onclick="$('#params-profile').slideToggle(100)"><b>Parameters (1)</b></p>
<div class="subdiv" id="params-profile">
<p>account: Forces the account ID to be used for fetching (normally Player ID is tried first)</p>
<p>player: Forces the player ID to be used for fetching (normally Account ID is tried first)</p>
</div>
<br>

View file

@ -45,6 +45,14 @@
<h1 id="header"></h1>
</div>
<div style="position: absolute; left: 7%; top: 45%; height: 10%;">
<a id="pageDown"><img class="gdButton" src="../assets/arrow-left.png" height="90%"></a>
</div>
<div style="position: absolute; right: 7%; top: 45%; height: 10%;">
<a id="pageUp"><img class="gdButton" src="../assets/arrow-right.png" height="90%"></a>
</div>
<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()">
</div>
@ -69,9 +77,14 @@
<script>
let demonID = Math.round(window.location.pathname.split('/')[2])
if (!demonID || demonID > 250 || demonID < 1) window.location.href = "../../../"
if (demonID > 1) $('#pageDown').attr('href', `./${demonID - 1}`)
else $('#pageDown').hide()
if (demonID < 250) $('#pageUp').attr('href', `./${demonID + 1}`)
else $('#pageUp').hide()
fetch(`https://pointercrate.com/api/v1/demons/${demonID}/`).then(res => res.json()).then(demonRes => {
let demon = demonRes.data
if (!demon.id) window.location.href = "../../../"
@ -112,4 +125,9 @@ fetch(`https://pointercrate.com/api/v1/demons/${demonID}/`).then(res => res.json
$('.lazyLoad').Lazy({ appendScroll: '#searchBox' });
})
$(document).keydown(function(k) {
if (k.which == 37) window.location.href = $('#pageDown').attr('href') // left
if (k.which == 39) window.location.href = $('#pageUp').attr('href') // right
});
</script>

View file

@ -39,10 +39,10 @@
let line = 0
let dialogue = [
"Hey, hey", "Wondering what happened to GDBrowser?", "Me too, kid",
"Well the truth is, we got IP banned", "By RubRub himself", "Fear not, though.",
"Ah frick, here we go again.", "Happy to see me?", "Aw, that's a shame", "Wondering what happened to GDBrowser?",
"Well, we got IP banned", "By RubRub himself", "...again", "Not entirely sure why this time", "Fear not, though.",
"Things will be worked out ASAP", "And if I obey RubRub's orders...",
"We'll be back in no time", "But in the meantime", "Yeah nothing is gonna work",
"We'll be back in no time", "Plus you get to hang out with me!", "But in the meantime", "Yeah nothing is gonna work",
"API is down as well", "But keep in mind we're on GitHub", "So you can use GDBrowser locally",
"Gotta be big brain for that though...", "At least the icon kit is okay", "Well, mostly", "Anywhooo",
"Enjoy your time here in the Vault", "I'm sure you'll find something to do", "Just stay six feet from me",

View file

@ -306,13 +306,9 @@ $(document).keydown(function(k) {
else return;
}
if (k.which == 37 && $('#pageDown').is(":visible")) { //left
$('#pageDown').trigger('click')
}
if (k.which == 39 && $('#pageUp').is(":visible")) { //right
$('#pageUp').trigger('click')
}
if (k.which == 37 && $('#pageDown').is(":visible")) $('#pageDown').trigger('click') // left
if (k.which == 39 && $('#pageUp').is(":visible")) $('#pageUp').trigger('click') // right
});
</script>

View file

@ -4,24 +4,16 @@ const compression = require('compression');
const timeout = require('connect-timeout')
const rateLimit = require("express-rate-limit");
// set to false if you're using gdbrowser locally, for obvious reasons
let useRateLimiting = true
const app = express();
app.offline = false // set to true to go into "offline" mode (in case of ip ban from rob)
app.secret = "Wmfd2893gb7" // lol
app.config = require('./gdpsConfig') // tweak settings in this file if you're using a GDPS
app.endpoint = app.config.endpoint // boomlings.com/database/
app.gdParams = function(obj={}) {
Object.keys(app.config.params).forEach(x => { if (!obj[x]) obj[x] = app.config.params[x] })
return obj
}
app.endpoint = app.config.endpoint // default is boomlings.com/database/
const RL = rateLimit({
windowMs: useRateLimiting ? 5 * 60 * 1000 : 0,
max: useRateLimiting ? 100 : 0, // max requests per 5 minutes
windowMs: app.config.rateLimiting ? 5 * 60 * 1000 : 0,
max: app.config.rateLimiting ? 100 : 0, // max requests per 5 minutes
message: "Rate limited ¯\\_(ツ)_/¯",
keyGenerator: function(req) { return req.headers['x-real-ip'] },
skip: function(req) { return ((req.url.includes("api/level") && !req.query.hasOwnProperty("download")) ? true : false) }
@ -34,10 +26,18 @@ let sampleIcons = require('./misc/sampleIcons.json')
app.use(compression());
app.use(express.json());
app.use(express.urlencoded({extended: true}));
app.use(timeout('30s'));
app.use(haltOnTimedout)
app.use(timeout('20s'));
app.set('json spaces', 2)
app.use(function(req, res, next) {
req.gdParams = function(obj={}) {
Object.keys(app.config.params).forEach(x => { if (!obj[x]) obj[x] = app.config.params[x] })
let ip = req.headers['x-real-ip'] || req.headers['x-forwarded-for']
return {form: obj, headers: app.config.ipForwarding && ip ? {'x-forwarded-for': ip, 'x-real-ip': ip} : {}}
}
next()
})
let directories = [""]
fs.readdirSync('./api').filter(x => !x.includes(".")).forEach(x => directories.push(x))
@ -46,10 +46,6 @@ directories.forEach(d => {
fs.readdirSync('./api/' + d).forEach(x => {if (x.includes('.')) app.run[x.split('.')[0]] = require('./api/' + d + "/" + x) })
})
function haltOnTimedout (req, res, next) {
if (!req.timedout) next()
}
try {
const secrets = require("./misc/secretStuff.json")
app.id = secrets.id
@ -176,4 +172,8 @@ app.get('*', function(req, res) {
else res.redirect('/search/404%20')
});
app.use(function (err, req, res, next) {
if (err && err.message == "Response timeout") res.status(500).send('Internal server error! (Timed out)')
})
app.listen(2000, () => console.log("Site online!"))