haha we got ip banned

- added rate limiting
- added panic mode
This commit is contained in:
Colon 2020-09-10 09:02:40 -04:00
parent 3bc525233a
commit eaca3a393b
18 changed files with 139 additions and 28 deletions

View file

@ -4,7 +4,7 @@ const sheet = new GoogleSpreadsheet('1ADIJvAkL0XHGBDhO7PP9aQOuK3mPIKB2cVPbshuBBH
module.exports = async (app, req, res) => {
if (!app.sheetsKey || app.endpoint != "http://boomlings.com/database/") return res.send([])
if (app.offline || !app.sheetsKey || app.endpoint != "http://boomlings.com/database/") return res.send([])
let type = req.query.type ? req.query.type.toLowerCase() : ''
if (type == "usercoins") type = "coins"

View file

@ -2,6 +2,8 @@ const request = require('request')
module.exports = async (app, req, res) => {
if (app.offline) return res.send("-1")
let params = {
userID : req.params.id,
accountID : req.params.id,

View file

@ -3,6 +3,12 @@ const fs = require('fs')
const Level = require('../classes/Level.js')
module.exports = async (app, req, res, api, ID, analyze) => {
if (app.offline) {
if (!api && levelID < 0) return res.redirect('/')
if (!api) return res.redirect('search/' + req.params.id)
else return res.send("-1")
}
let levelID = ID || req.params.id
if (levelID == "daily") levelID = -1
else if (levelID == "weekly") levelID = -2

View file

@ -350,7 +350,7 @@ module.exports = async (app, req, res) => {
let username = req.params.text
let result = []
if (req.query.hasOwnProperty("noUser") || req.query.hasOwnProperty("nouser") || username == "icon") return buildIcon()
if (app.offline || req.query.hasOwnProperty("noUser") || req.query.hasOwnProperty("nouser") || username == "icon") return buildIcon()
request.post(app.endpoint + 'getGJUsers20.php', {
form: {

View file

@ -2,6 +2,8 @@ const request = require('request')
module.exports = async (app, req, res) => {
if (app.offline) return res.send("-1")
let amount = 100;
let count = req.query.count ? parseInt(req.query.count) : null
if (count && count > 0) {

View file

@ -2,6 +2,8 @@ const request = require('request')
module.exports = async (app, req, res) => {
if (app.offline) return res.send("-1")
let amount = 100;
let count = req.query.count ? parseInt(req.query.count) : null
if (count && count > 0) {

View file

@ -4,6 +4,11 @@ const Level = require('../classes/Level.js')
module.exports = async (app, req, res, api, analyze) => {
if (app.offline) {
if (!api) return res.redirect('search/' + req.params.id)
else return res.send("-1")
}
let levelID = req.params.id
if (levelID == "daily") return app.run.download(app, req, res, api, 'daily', analyze)
else if (levelID == "weekly") return app.run.download(app, req, res, api, 'weekly', analyze)

View file

@ -3,6 +3,8 @@ const fs = require('fs')
module.exports = async (app, req, res, api, getLevels) => {
if (app.offline) return res.send("-1")
request.post(app.endpoint + 'getGJUsers20.php', {
form: {
str: getLevels || req.params.id,

View file

@ -1,13 +1,12 @@
const request = require('request')
const orbs = [0, 0, 50, 75, 125, 175, 225, 275, 350, 425, 500]
const difficulty = {0: 'Unrated', 10: 'Easy', 20: 'Normal', 30: 'Hard', 40: 'Harder', 50: 'Insane'}
const length = ['Tiny', 'Short', 'Medium', 'Long', 'XL']
const mapPacks = require('../misc/mapPacks.json')
const levels = require('../misc/level.json').music
const Level = require('../classes/Level.js')
module.exports = async (app, req, res) => {
if (app.offline) return res.send("-1")
let amount = 10;
let count = req.query.count ? parseInt(req.query.count) : null
if (count && count > 0) {

View file

@ -20,6 +20,10 @@ body {
background-image: linear-gradient(#323232, #171717) !important;
}
.vaultBG {
background-image: linear-gradient(#4B0062, #22002D) !important;
}
img, .noSelect {
user-select: none;
}
@ -478,6 +482,16 @@ input::-webkit-inner-spin-button {
cursor: pointer;
}
.vaultLink {
color: aqua;
cursor: pointer;
filter: opacity(40%);
}
.vaultLink:hover {
filter: opacity(100%);
}
.youCanClickThis:hover {
border-bottom: 2px solid aqua
}

BIN
assets/door.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
assets/keymaster-head.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
assets/keymaster.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View file

@ -59,7 +59,7 @@
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
<a class="menuLink" href="https://github.com/GDColon/GDBrowser">GitHub</a>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
<a class="menuLink" href="https://store.steampowered.com/app/322170/Geometry_Dash/">Buy Geometry Dash!</a>
<a class="menuLink" href="https://store.steampowered.com/app/322170/Geometry_Dash/">Buy Geometry Dash!</a></p>
</div>
<div class="center" width="100%" style="margin-top: 2%">

View file

@ -105,16 +105,14 @@ function leaderboard(val) {
fetch(`../api/leaderboard?count=250&${val}&type=${sort}`).then(res => res.json()).then(res => {
if (val != type) return;
$('#searchBox').html(`<div style="height: 4.5%"></div>`)
$('.ranking').remove()
res.forEach((x, y) => {
if (val == type && res != -1) res.forEach((x, y) => {
$('#searchBox').append(`<div class="searchresult leaderboardSlot">
<h2 class="small inline gdButton" style="margin-top: 1.5%"><a href="../profile/${x.username}">${x.username}</a></h2>
<h3 class="inline sideSpace${x.stars > 100000 ? " yellow" : ""}" style="font-size: 4.5vh">${x.stars} <img class="valign" src="../assets/star.png"
<h3 class="inline sideSpace${x.stars >= 100000 ? " yellow" : ""}" style="font-size: 4.5vh">${x.stars} <img class="valign" src="../assets/star.png"
style="cursor: help; height: 19%; transform: translate(-25%, -10%);" title="Stars"></h3>
<h3 class="lessSpaced leaderboardStats">

63
html/offline.html Normal file
View file

@ -0,0 +1,63 @@
<head>
<title>#GDBrowserIsOverParty</title>
<meta charset="utf-8">
<link href="../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>
<link rel="icon" href="../assets/keymaster-head.png">
<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-image" name="og:image" itemprop="image" content="https://gdbrowser.com/assets/coin.png">
</head>
<body class="levelBG vaultBG" style="overflow-y:auto;" onbeforeunload="saveUrl()">
<div id="everything" class="center" style="overflow: hidden">
<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;">Hey, hey</h1>
<img id="glubfub" src="../assets/keymaster.png" height="25%" class="gdButton">
<div id="footer" style="position: absolute; left: 1%; bottom: 0%; text-align: left">
<p style="line-height: 150%"><a class="vaultLink" href="https://gdcolon.com/tools">• GD Tools</a><br>
<a class="vaultLink" href="./api">• API</a><br>
<a class="vaultLink" href="https://github.com/GDColon/GDBrowser">• GitHub</a><br>
<a class="vaultLink" href="https://store.steampowered.com/app/322170/Geometry_Dash/">• Buy Geometry Dash!</a></p>
</div>
<div style="position:absolute; bottom: 3%; right: 3%; width: 10%; text-align: right;">
<a href="../?home"><img class="gdButton" src="../assets/door.png" width=85%;"></a>
</div>
<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>
</div>
</div>
</body>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script async type="text/javascript" src="../assets/sizecheck.js"></script>
<script>
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.",
"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",
"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",
"...", ".....", "Yeah that's all I have to say", "You can stop clicking now",
"I'm just gonna repeat myself", "Like my iPod stuck on replay", "*ahem*"
]
$("#glubfub").click(function() {
let msg = dialogue[line]
$("#msg").text(msg)
line++
if (line == dialogue.length) line = 0
})
$("#glubfub").trigger("click")
</script>

View file

@ -2,10 +2,29 @@ const express = require('express');
const fs = require("fs")
const timeout = require('connect-timeout')
const compression = require('compression');
const rateLimit = require("express-rate-limit");
// set to false if you're using gdbrowser locally, for obvious reasons
let useRateLimiting = false
const app = express();
app.offline = false // set to true to go into "offline" mode (in case of ip ban from rob)
app.secret = 'Wmfd2893gb7'
app.gameVersion = '21'
app.binaryVersion = '35'
app.endpoint = 'http://boomlings.com/database/'
app.config = require('./misc/gdpsConfig') // tweak settings in this file if you're using a GDPS
const RL = rateLimit({
windowMs: useRateLimiting ? 5 * 60 * 1000 : 0,
max: useRateLimiting ? 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) }
})
let api = true;
let gdicons = fs.readdirSync('./icons/iconkit')
const app = express();
app.use(compression());
app.use(express.json());
app.use(express.urlencoded({extended: true}));
@ -24,12 +43,6 @@ function haltOnTimedout (req, res, next) {
if (!req.timedout) next()
}
app.secret = 'Wmfd2893gb7'
app.gameVersion = '21'
app.binaryVersion = '35'
app.endpoint = 'http://boomlings.com/database/'
app.config = require('./misc/gdpsConfig') // tweak settings in this file if you're using a GDPS
try {
const secrets = require("./misc/secretStuff.json")
app.id = secrets.id
@ -74,19 +87,23 @@ app.use('/objects', express.static(__dirname + '/assets/objects', {maxAge: "7d"}
// POST REQUESTS
app.post("/like", function(req, res) { app.run.like(app, req, res) })
app.post("/postComment", function(req, res) { app.run.postComment(app, req, res) })
app.post("/postProfileComment", function(req, res) { app.run.postProfileComment(app, req, res) })
app.post("/like", RL, function(req, res) { app.run.like(app, req, res) })
app.post("/postComment", RL, function(req, res) { app.run.postComment(app, req, res) })
app.post("/postProfileComment", RL, function(req, res) { app.run.postProfileComment(app, req, res) })
app.post("/messages", async function(req, res) { app.run.getMessages(app, req, res) })
app.post("/messages/:id", async function(req, res) { app.run.fetchMessage(app, req, res) })
app.post("/deleteMessage", function(req, res) { app.run.deleteMessage(app, req, res) })
app.post("/sendMessage", function(req, res) { app.run.sendMessage(app, req, res) })
app.post("/messages", RL, async function(req, res) { app.run.getMessages(app, req, res) })
app.post("/messages/:id", RL, async 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) })
// HTML
app.get("/", function(req, res) { res.sendFile(__dirname + "/html/home.html") })
app.get("/", function(req, res) {
if (app.offline && !req.query.hasOwnProperty("home")) res.sendFile(__dirname + "/html/offline.html")
else res.sendFile(__dirname + "/html/home.html")
})
app.get("/analyze/:id", async function(req, res) { res.sendFile(__dirname + "/html/analyze.html") })
app.get("/api", function(req, res) { res.sendFile(__dirname + "/html/api.html") })
app.get("/comments/:id", function(req, res) { res.sendFile(__dirname + "/html/comments.html") })
@ -102,12 +119,12 @@ app.get("/search/:text", function(req, res) { res.sendFile(__dirname + "/html/se
// API
app.get("/api/analyze/:id", async function(req, res) { app.run.level(app, req, res, api, true) })
app.get("/api/analyze/:id", RL, async function(req, res) { app.run.level(app, req, res, api, true) })
app.get("/api/comments/:id", function(req, res) { app.run.comments(app, req, res, api) })
app.get("/api/credits", function(req, res) { res.send(require('./misc/credits.json')) })
app.get("/api/leaderboard", function(req, res, api) { app.run[req.query.hasOwnProperty("accurate") ? "accurateLeaderboard" : "leaderboard"](app, req, res) })
app.get("/api/leaderboardLevel/:id", function(req, res) { app.run.leaderboardLevel(app, req, res, api) })
app.get("/api/level/:id", async function(req, res) { app.run.level(app, req, res, api) })
app.get("/api/leaderboardLevel/:id", RL, function(req, res) { app.run.leaderboardLevel(app, req, res, api) })
app.get("/api/level/:id", RL, async function(req, res) { app.run.level(app, req, res, api) })
app.get("/api/mappacks", async function(req, res) { res.send(require('./misc/mapPacks.json')) })
app.get("/api/profile/:id", function(req, res) { app.run.profile(app, req, res, api) })
app.get("/api/search/:text", function(req, res) { app.run.search(app, req, res, api) })

View file

@ -9,6 +9,7 @@
"compression": "^1.7.4",
"connect-timeout": "^1.9.0",
"express": "^4.17.1",
"express-rate-limit": "^5.1.3",
"google-spreadsheet": "^3.0.11",
"jimp": "^0.8.5",
"plist": "^3.0.1",