haha we got ip banned
- added rate limiting - added panic mode
This commit is contained in:
parent
3bc525233a
commit
eaca3a393b
18 changed files with 139 additions and 28 deletions
|
@ -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"
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
BIN
assets/door.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
BIN
assets/keymaster-head.png
Normal file
BIN
assets/keymaster-head.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 45 KiB |
BIN
assets/keymaster.png
Normal file
BIN
assets/keymaster.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 56 KiB |
|
@ -59,7 +59,7 @@
|
|||
|
||||
<a class="menuLink" href="https://github.com/GDColon/GDBrowser">GitHub</a>
|
||||
|
||||
<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%">
|
||||
|
|
|
@ -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
63
html/offline.html
Normal 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>
|
53
index.js
53
index.js
|
@ -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) })
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in a new issue