2019-10-15 23:42:47 -03:00
const express = require ( 'express' ) ;
2021-01-18 23:54:18 -03:00
const request = require ( 'request' ) ;
2019-11-07 01:07:31 -03:00
const compression = require ( 'compression' ) ;
2021-01-18 23:54:18 -03:00
const timeout = require ( 'connect-timeout' ) ;
2020-09-10 10:02:40 -03:00
const rateLimit = require ( "express-rate-limit" ) ;
2021-01-18 23:54:18 -03:00
const fs = require ( "fs" ) ;
2020-09-10 10:02:40 -03:00
const app = express ( ) ;
2020-11-07 21:20:44 -03:00
2021-08-01 19:22:35 -04:00
let serverList = require ( './servers.json' )
let pinnedServers = serverList . filter ( x => x . pinned )
let notPinnedServers = serverList . filter ( x => ! x . pinned ) . sort ( ( a , b ) => a . name . localeCompare ( b . name ) )
app . servers = pinnedServers . concat ( notPinnedServers )
2021-08-03 11:51:09 -04:00
app . safeServers = JSON . parse ( JSON . stringify ( app . servers ) ) // clone
app . safeServers . forEach ( x => { delete x . endpoint ; delete x . substitutions ; delete x . overrides ; delete x . disabled } )
2021-01-18 23:54:18 -03:00
app . config = require ( './settings.js' )
2020-11-07 21:20:44 -03:00
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." +
" 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>" +
2022-05-19 22:30:54 -04:00
"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>"
2020-09-10 10:02:40 -03:00
const RL = rateLimit ( {
2020-11-01 17:29:32 -03:00
windowMs : app . config . rateLimiting ? 5 * 60 * 1000 : 0 ,
max : app . config . rateLimiting ? 100 : 0 , // max requests per 5 minutes
2020-11-07 21:20:44 -03:00
message : rlMessage ,
keyGenerator : function ( req ) { return req . headers [ 'x-real-ip' ] || req . headers [ 'x-forwarded-for' ] } ,
2020-09-10 10:02:40 -03:00
skip : function ( req ) { return ( ( req . url . includes ( "api/level" ) && ! req . query . hasOwnProperty ( "download" ) ) ? true : false ) }
} )
2019-11-07 01:07:31 -03:00
2020-11-07 21:20:44 -03:00
const RL2 = rateLimit ( {
windowMs : app . config . rateLimiting ? 2 * 60 * 1000 : 0 ,
max : app . config . rateLimiting ? 200 : 0 , // max requests per 1 minute
message : rlMessage ,
keyGenerator : function ( req ) { return req . headers [ 'x-real-ip' ] || req . headers [ 'x-forwarded-for' ] }
} )
2021-01-18 23:54:18 -03:00
let XOR = require ( './classes/XOR.js' ) ;
2021-01-11 18:00:21 -03:00
let achievements = require ( './misc/achievements.json' )
let achievementTypes = require ( './misc/achievementTypes.json' )
2021-02-01 16:30:40 -03:00
let music = require ( './misc/music.json' )
2021-01-04 12:21:58 -03:00
let assetPage = fs . readFileSync ( './html/assets.html' , 'utf8' )
2020-09-24 23:07:53 -03:00
2021-01-18 23:54:18 -03:00
app . accountCache = { }
app . lastSuccess = { }
app . actuallyWorked = { }
app . servers . forEach ( x => {
app . accountCache [ x . id || "gd" ] = { }
app . lastSuccess [ x . id || "gd" ] = Date . now ( )
} )
2021-07-07 10:25:35 -04:00
app . mainEndpoint = app . servers . find ( x => ! x . id ) . endpoint // boomlings.com unless changed in fork
2021-01-18 23:54:18 -03:00
app . set ( 'json spaces' , 2 )
2019-10-21 12:20:25 -03:00
app . use ( compression ( ) ) ;
2019-10-15 23:42:47 -03:00
app . use ( express . json ( ) ) ;
app . use ( express . urlencoded ( { extended : true } ) ) ;
2020-11-01 17:29:32 -03:00
app . use ( timeout ( '20s' ) ) ;
2019-10-15 23:42:47 -03:00
2021-01-18 23:54:18 -03:00
app . use ( async function ( req , res , next ) {
let subdomains = req . subdomains . map ( x => x . toLowerCase ( ) )
if ( ! subdomains . length ) subdomains = [ "" ]
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 )
2021-12-07 16:14:56 -03:00
// will expand this in the future :wink:
res . sendError = function ( errorCode = 500 ) {
res . status ( errorCode ) . send ( "-1" )
}
2021-01-18 23:54:18 -03:00
// literally just for convenience
req . offline = req . server . offline
req . endpoint = req . server . endpoint
req . onePointNine = req . server . onePointNine
2021-01-19 02:56:21 -03:00
req . timestampSuffix = req . server . timestampSuffix || ""
2021-01-18 23:54:18 -03:00
req . id = req . server . id || "gd"
2021-07-07 10:25:35 -04:00
req . isGDPS = req . server . endpoint != app . mainEndpoint
2021-01-18 23:54:18 -03:00
if ( req . isGDPS ) res . set ( "gdps" , ( req . onePointNine ? "1.9/" : "" ) + req . id )
2021-02-01 16:30:40 -03:00
if ( req . query . online > 0 ) req . offline = false
2021-01-18 23:54:18 -03:00
2021-01-17 02:05:06 -03:00
req . gdParams = function ( obj = { } , substitute = true ) {
2020-11-01 17:29:32 -03:00
Object . keys ( app . config . params ) . forEach ( x => { if ( ! obj [ x ] ) obj [ x ] = app . config . params [ x ] } )
2021-01-18 23:54:18 -03:00
Object . keys ( req . server . extraParams || { } ) . forEach ( x => { if ( ! obj [ x ] ) obj [ x ] = req . server . extraParams [ x ] } )
2020-11-01 17:29:32 -03:00
let ip = req . headers [ 'x-real-ip' ] || req . headers [ 'x-forwarded-for' ]
2021-01-14 20:18:19 -03:00
let params = { form : obj , headers : app . config . ipForwarding && ip ? { 'x-forwarded-for' : ip , 'x-real-ip' : ip } : { } }
2021-01-17 02:05:06 -03:00
if ( substitute ) { // GDPS substitutions in settings.js
2021-01-18 23:54:18 -03:00
for ( let ss in req . server . substitutions ) {
if ( params . form [ ss ] ) { params . form [ req . server . substitutions [ ss ] ] = params . form [ ss ] ; delete params . form [ ss ] }
2021-01-17 02:05:06 -03:00
}
2021-01-14 20:18:19 -03:00
}
return params
2020-11-01 17:29:32 -03:00
}
2021-01-18 23:54:18 -03:00
req . gdRequest = function ( target , params = { } , cb = function ( ) { } ) {
if ( ! target ) return cb ( true )
target = req . server . overrides ? ( req . server . overrides [ target ] || target ) : target
let parameters = params . headers ? params : req . gdParams ( params )
let endpoint = req . endpoint
2021-09-02 19:07:31 -04:00
if ( params . forceGD || ( params . form && params . form . forceGD ) ) endpoint = "http://www.boomlings.com/database/"
2021-01-18 23:54:18 -03:00
request . post ( endpoint + target + '.php' , parameters , function ( err , res , body ) {
2021-08-18 20:10:35 -04:00
let error = err
if ( ! error && ( err || ! body || body . match ( /^-\d$/ ) || body . startsWith ( "error" ) || body . startsWith ( "<" ) ) ) {
error = { serverError : true , response : body }
}
return cb ( error , res , body )
2021-01-18 23:54:18 -03:00
} )
}
2020-11-01 17:29:32 -03:00
next ( )
} )
2020-10-28 22:25:13 -03:00
let directories = [ "" ]
fs . readdirSync ( './api' ) . filter ( x => ! x . includes ( "." ) ) . forEach ( x => directories . push ( x ) )
2019-12-25 18:20:32 -03:00
2021-01-18 23:54:18 -03:00
app . trackSuccess = function ( id ) {
app . lastSuccess [ id ] = Date . now ( )
if ( ! app . actuallyWorked [ id ] ) app . actuallyWorked [ id ] = true
2021-01-11 18:00:21 -03:00
}
2021-01-18 23:54:18 -03:00
app . timeSince = function ( id , time ) {
if ( ! time ) time = app . lastSuccess [ id ]
2021-01-11 18:00:21 -03:00
let secsPassed = Math . floor ( ( Date . now ( ) - time ) / 1000 )
let minsPassed = Math . floor ( secsPassed / 60 )
secsPassed -= 60 * minsPassed ;
2021-01-18 23:54:18 -03:00
return ` ${ app . actuallyWorked [ id ] ? "" : "~" } ${ minsPassed } m ${ secsPassed } s `
2021-01-11 18:00:21 -03:00
}
2021-01-21 19:15:31 -03:00
app . userCache = function ( id , accountID , playerID , name ) {
2022-05-19 23:01:13 -04:00
2022-05-29 13:18:14 -04:00
if ( ! accountID || accountID == "0" || ( name && name . toLowerCase ( ) == "robtop" && accountID != "71" ) || ! app . config . cacheAccountIDs ) return
2021-01-21 19:15:31 -03:00
if ( ! playerID ) return app . accountCache [ id ] [ accountID . toLowerCase ( ) ]
let cacheStuff = [ accountID , playerID , name ]
app . accountCache [ id ] [ name . toLowerCase ( ) ] = cacheStuff
return cacheStuff
}
2019-12-25 18:20:32 -03:00
app . run = { }
directories . forEach ( d => {
fs . readdirSync ( './api/' + d ) . forEach ( x => { if ( x . includes ( '.' ) ) app . run [ x . split ( '.' ) [ 0 ] ] = require ( './api/' + d + "/" + x ) } )
2019-10-16 19:47:53 -03:00
} )
2019-10-15 23:42:47 -03:00
2021-08-03 11:51:09 -04:00
app . xor = new XOR ( )
let hasSecretStuff = false
2021-05-27 08:30:56 -04:00
2019-12-22 00:52:09 -03:00
try {
const secrets = require ( "./misc/secretStuff.json" )
2021-08-03 11:51:09 -04:00
hasSecretStuff = true
2019-12-22 00:52:09 -03:00
app . id = secrets . id
2021-08-03 11:51:09 -04:00
app . gjp = secrets . gjp || app . xor . encrypt ( secrets . password )
2020-04-24 15:26:29 -04:00
app . sheetsKey = secrets . sheetsKey
2021-08-18 20:10:35 -04:00
if ( ! Number ( app . id ) || ( ! secrets . password && ! secrets . gjp ) || ( secrets . password || secrets . gjp ) . includes ( "delete this line" ) ) console . warn ( "Warning: No account ID and/or password has been provided in secretStuff.json! These are required for level leaderboards to work." )
2021-08-03 11:51:09 -04:00
if ( app . sheetsKey . includes ( "google sheets api key" ) ) app . sheetsKey = undefined
2019-12-22 00:52:09 -03:00
}
2019-10-15 23:42:47 -03:00
2019-12-25 18:20:32 -03:00
catch ( e ) {
2019-12-22 00:52:09 -03:00
app . id = 0
app . gjp = 0
2021-08-03 11:51:09 -04:00
if ( ! hasSecretStuff ) console . warn ( "Warning: secretStuff.json has not been created! This file is required for level leaderboards to work." )
else { console . warn ( "There was an error parsing your secretStuff.json file!" ) ; console . error ( e ) }
2019-10-15 23:42:47 -03:00
}
2021-08-18 20:10:35 -04:00
app . parseResponse = function ( responseBody , splitter = ":" ) {
2019-10-23 18:48:01 -03:00
if ( ! responseBody || responseBody == "-1" ) return { } ;
2021-01-15 12:29:46 -03:00
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
2021-08-18 20:10:35 -04:00
let response = responseBody . split ( '#' ) [ 0 ] . split ( splitter ) ;
2019-10-15 23:42:47 -03:00
let res = { } ;
for ( let i = 0 ; i < response . length ; i += 2 ) {
res [ response [ i ] ] = response [ i + 1 ] }
2021-01-15 12:29:46 -03:00
return res
}
2019-10-15 23:42:47 -03:00
2019-10-16 19:47:53 -03:00
//xss bad
2019-10-25 18:22:29 -03:00
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 , "'" ) }
2019-10-15 23:42:47 -03:00
2019-12-16 10:48:05 -03:00
// ASSETS
app . use ( '/assets' , express . static ( _ _dirname + '/assets' , { maxAge : "7d" } ) ) ;
2022-05-19 22:30:54 -04:00
app . use ( '/assets/css' , express . static ( _ _dirname + '/assets/css' ) ) ;
2021-01-04 12:21:58 -03:00
2022-05-19 22:30:54 -04:00
app . use ( '/iconkit' , express . static ( _ _dirname + '/iconkit' ) ) ;
app . get ( "/global.js" , function ( req , res ) { res . status ( 200 ) . sendFile ( _ _dirname + "/misc/global.js" ) } )
2021-12-07 16:06:33 -03:00
app . get ( "/dragscroll.js" , function ( req , res ) { res . status ( 200 ) . sendFile ( _ _dirname + "/misc/dragscroll.js" ) } )
2021-01-04 12:21:58 -03:00
app . get ( "/assets/:dir*?" , function ( req , res ) {
let main = ( req . params . dir || "" ) . toLowerCase ( )
let dir = main + ( req . params [ 0 ] || "" ) . toLowerCase ( )
if ( dir . includes ( '.' ) || ! req . path . endsWith ( "/" ) ) {
if ( ! req . params [ 0 ] ) main = ""
2021-12-07 16:06:33 -03:00
if ( req . params . dir == "deatheffects" || req . params . dir == "trails" ) return res . status ( 200 ) . sendFile ( _ _dirname + "/assets/deatheffects/0.png" )
else if ( req . params . dir == "gdps" && req . params [ 0 ] . endsWith ( "_icon.png" ) ) return res . status ( 200 ) . sendFile ( _ _dirname + "/assets/gdps/unknown_icon.png" )
else if ( req . params . dir == "gdps" && req . params [ 0 ] . endsWith ( "_logo.png" ) ) return res . status ( 200 ) . sendFile ( _ _dirname + "/assets/gdps/unknown_logo.png" )
return res . status ( 404 ) . send ( ` <p style="font-size: 20px; font-family: aller, helvetica, arial">Looks like this file doesn't exist ¯ \\ _(ツ)_/¯<br><a href='/assets/ ${ main } '>View directory listing for <b>/assets/ ${ main } </b></a></p> ` )
2021-01-04 12:21:58 -03:00
}
let path = ` ./assets/ ${ dir } `
let files = [ ]
if ( fs . existsSync ( path ) ) { files = fs . readdirSync ( path ) }
assetPage = fs . readFileSync ( './html/assets.html' , 'utf8' )
let assetData = JSON . stringify ( { files : files . filter ( x => x . includes ( '.' ) ) , directories : files . filter ( x => ! x . includes ( '.' ) ) } )
2021-12-07 16:06:33 -03:00
res . status ( 200 ) . send ( assetPage . replace ( '{NAME}' , dir || "assets" ) . replace ( '{DATA}' , assetData ) )
2021-01-04 12:21:58 -03:00
} )
2019-10-15 23:42:47 -03:00
2019-12-16 10:48:05 -03:00
// POST REQUESTS
2019-10-15 23:42:47 -03:00
2020-09-10 10:02:40 -03:00
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 ) } )
2019-12-25 18:20:32 -03:00
2021-01-18 23:54:18 -03:00
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 ) } )
2020-09-10 10:02:40 -03:00
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 ) } )
2019-10-15 23:42:47 -03:00
2020-10-28 22:25:13 -03:00
app . post ( "/accurateLeaderboard" , function ( req , res ) { app . run . accurate ( app , req , res , true ) } )
2021-12-03 18:30:58 -03:00
app . post ( "/analyzeLevel" , function ( req , res ) { app . run . analyze ( app , req , res ) } )
2020-10-02 15:33:24 -03:00
2019-12-16 10:48:05 -03:00
// HTML
2019-10-15 23:42:47 -03:00
2021-01-18 23:54:18 -03:00
let onePointNineDisabled = [ 'daily' , 'weekly' , 'gauntlets' , 'messages' ]
let downloadDisabled = [ 'daily' , 'weekly' ]
let gdpsHide = [ 'achievements' , 'messages' ]
2020-09-10 10:02:40 -03:00
app . get ( "/" , function ( req , res ) {
2021-12-07 16:06:33 -03:00
if ( req . query . hasOwnProperty ( "offline" ) || ( req . offline && ! req . query . hasOwnProperty ( "home" ) ) ) res . status ( 200 ) . sendFile ( _ _dirname + "/html/offline.html" )
2021-01-18 23:54:18 -03:00
else {
fs . readFile ( './html/home.html' , 'utf8' , function ( err , data ) {
let html = data ;
if ( req . isGDPS ) {
html = html . replace ( '"levelBG"' , '"levelBG purpleBG"' )
. replace ( /Geometry Dash Browser!/g , req . server . name + " Browser!" )
. replace ( "/assets/gdlogo" , ` /assets/gdps/ ${ req . id } _logo ` )
2021-04-22 18:23:31 -04:00
. replace ( "coin.png\" itemprop" , ` gdps/ ${ req . id } _icon.png" itemprop ` )
2021-08-08 22:06:38 -04:00
. replace ( /coin\.png/g , ` ${ req . server . onePointNine ? "blue" : "silver" } coin.png ` )
2021-01-18 23:54:18 -03:00
gdpsHide . forEach ( x => { html = html . replace ( ` menu- ${ x } ` , 'changeDaWorld' ) } )
}
if ( req . onePointNine ) onePointNineDisabled . forEach ( x => { html = html . replace ( ` menu- ${ x } ` , 'menuDisabled' ) } )
2021-08-01 19:22:35 -04:00
if ( req . server . disabled ) req . server . disabled . forEach ( x => { html = html . replace ( ` menu- ${ x } ` , 'menuDisabled' ) } )
2021-08-01 21:37:22 -04:00
if ( req . server . downloadsDisabled && process . platform == "linux" ) {
2021-01-18 23:54:18 -03:00
downloadDisabled . forEach ( x => { html = html . replace ( ` menu- ${ x } ` , 'menuDisabled' ) } )
html = html . replace ( 'id="dl" style="display: none' , 'style="display: block' )
2021-12-29 14:02:34 -03:00
. replace ( 'No active <span id="noLevel">daily</span> level!' , '[Blocked by RobTop]' )
2021-12-07 16:22:17 -03:00
}
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' )
. replace ( 'none" id="menu_featured' , 'block" id="menu_featured' )
2021-01-18 23:54:18 -03:00
}
2021-12-07 16:06:33 -03:00
return res . status ( 200 ) . send ( html )
2021-01-18 23:54:18 -03:00
} )
}
2020-09-10 10:02:40 -03:00
} )
2021-12-07 16:06:33 -03:00
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" ) } )
2019-10-15 23:42:47 -03:00
2019-12-16 10:48:05 -03:00
// API
2019-10-21 00:33:01 -03:00
2021-01-18 23:54:18 -03:00
app . get ( "/api/analyze/:id" , RL , function ( req , res ) { app . run . level ( app , req , res , true , true ) } )
2020-11-16 21:28:24 -03:00
app . get ( "/api/boomlings" , function ( req , res ) { app . run . boomlings ( app , req , res ) } )
2020-11-07 21:20:44 -03:00
app . get ( "/api/comments/:id" , RL2 , function ( req , res ) { app . run . comments ( app , req , res ) } )
2021-12-07 16:06:33 -03:00
app . get ( "/api/credits" , function ( req , res ) { res . status ( 200 ) . send ( require ( './misc/credits.json' ) ) } )
2021-01-18 23:54:18 -03:00
app . get ( "/api/gauntlets" , function ( req , res ) { app . run . gauntlets ( app , req , res ) } )
2020-10-28 22:25:13 -03:00
app . get ( "/api/leaderboard" , function ( req , res ) { app . run [ req . query . hasOwnProperty ( "accurate" ) ? "accurate" : "scores" ] ( app , req , res ) } )
2020-11-07 21:20:44 -03:00
app . get ( "/api/leaderboardLevel/:id" , RL2 , function ( req , res ) { app . run . leaderboardLevel ( app , req , res ) } )
2021-01-18 23:54:18 -03:00
app . get ( "/api/level/:id" , RL , function ( req , res ) { app . run . level ( app , req , res , true ) } )
app . get ( "/api/mappacks" , function ( req , res ) { app . run . mappacks ( app , req , res ) } )
app . get ( "/api/profile/:id" , RL2 , function ( req , res ) { app . run . profile ( app , req , res , true ) } )
2020-11-07 21:20:44 -03:00
app . get ( "/api/search/:text" , RL2 , function ( req , res ) { app . run . search ( app , req , res ) } )
2021-01-05 13:03:04 -03:00
app . get ( "/api/song/:song" , function ( req , res ) { app . run . song ( app , req , res ) } )
2019-12-16 10:48:05 -03:00
2019-10-15 23:42:47 -03:00
2019-12-16 10:48:05 -03:00
// REDIRECTS
2019-10-15 23:42:47 -03:00
2019-12-16 10:48:05 -03:00
app . get ( "/icon" , function ( req , res ) { res . redirect ( '/iconkit' ) } )
2020-10-13 11:25:07 -03:00
app . get ( "/obj/:text" , function ( req , res ) { res . redirect ( '/obj/' + req . params . text ) } )
2019-12-16 10:48:05 -03:00
app . get ( "/leaderboards/:id" , function ( req , res ) { res . redirect ( '/leaderboard/' + req . params . id ) } )
2020-09-29 22:42:18 -03:00
app . get ( "/profile/:id" , function ( req , res ) { res . redirect ( '/u/' + req . params . id ) } )
app . get ( "/p/:id" , function ( req , res ) { res . redirect ( '/u/' + req . params . id ) } )
2019-12-16 10:48:05 -03:00
app . get ( "/l/:id" , function ( req , res ) { res . redirect ( '/leaderboard/' + req . params . id ) } )
app . get ( "/a/:id" , function ( req , res ) { res . redirect ( '/analyze/' + req . params . id ) } )
app . get ( "/c/:id" , function ( req , res ) { res . redirect ( '/comments/' + req . params . id ) } )
2020-10-28 22:25:13 -03:00
app . get ( "/d/:id" , function ( req , res ) { res . redirect ( '/demon/' + req . params . id ) } )
2019-10-15 23:42:47 -03:00
2020-09-24 23:07:53 -03:00
// API AND HTML
2020-09-29 22:42:18 -03:00
app . get ( "/u/:id" , function ( req , res ) { app . run . profile ( app , req , res ) } )
2020-09-24 23:07:53 -03:00
app . get ( "/:id" , function ( req , res ) { app . run . level ( app , req , res ) } )
2019-12-16 10:48:05 -03:00
// MISC
2019-10-15 23:42:47 -03:00
2021-12-07 16:06:33 -03:00
app . get ( "/api/userCache" , function ( req , res ) { res . status ( 200 ) . send ( app . accountCache ) } )
2022-05-19 22:30:54 -04:00
app . get ( "/api/achievements" , function ( req , res ) { res . status ( 200 ) . send ( { achievements , types : achievementTypes , shopIcons : sacredTexts . shops , colors : sacredTexts . colors } ) } )
2021-12-07 16:06:33 -03:00
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 ) } )
2022-05-19 22:30:54 -04:00
// important icon stuff
let sacredTexts = { }
fs . readdirSync ( './iconkit/sacredtexts' ) . forEach ( x => {
sacredTexts [ x . split ( "." ) [ 0 ] ] = require ( "./iconkit/sacredtexts/" + x )
} )
let previewIcons = fs . readdirSync ( './iconkit/premade' )
2022-05-29 13:18:14 -04:00
let newPreviewIcons = fs . readdirSync ( './iconkit/newpremade' )
2022-05-19 22:30:54 -04:00
let previewCounts = { }
previewIcons . forEach ( x => {
if ( x . endsWith ( "_0.png" ) ) return
let iconType = sacredTexts . forms [ x . split ( "_" ) [ 0 ] ] . form
if ( ! previewCounts [ iconType ] ) previewCounts [ iconType ] = 1
else previewCounts [ iconType ] ++
} )
sacredTexts . iconCounts = previewCounts
2022-05-29 13:18:14 -04:00
let newIcons = fs . readdirSync ( './iconkit/newicons' )
sacredTexts . newIcons = [ ]
let newIconCounts = { }
newIcons . forEach ( x => {
if ( x . endsWith ( ".plist" ) ) {
sacredTexts . newIcons . push ( x . split ( "-" ) [ 0 ] )
let formName = x . split ( /_\d/g ) [ 0 ]
if ( ! newIconCounts [ formName ] ) newIconCounts [ formName ] = 1
else newIconCounts [ formName ] ++
}
} )
sacredTexts . newIconCounts = newIconCounts
2022-05-19 22:30:54 -04:00
2020-09-24 23:07:53 -03:00
app . get ( '/api/icons' , function ( req , res ) {
2022-05-19 22:30:54 -04:00
res . status ( 200 ) . send ( sacredTexts ) ;
} ) ;
// important icon kit stuff
let iconKitFiles = { }
let sampleIcons = require ( './misc/sampleIcons.json' )
fs . readdirSync ( './iconkit/extradata' ) . forEach ( x => {
iconKitFiles [ x . split ( "." ) [ 0 ] ] = require ( "./iconkit/extradata/" + x )
} )
iconKitFiles . previewIcons = previewIcons
2022-05-29 13:18:14 -04:00
iconKitFiles . newPreviewIcons = newPreviewIcons
2022-05-19 22:30:54 -04:00
app . get ( '/api/iconkit' , function ( req , res ) {
2020-09-24 23:07:53 -03:00
let sample = [ JSON . stringify ( sampleIcons [ Math . floor ( Math . random ( ) * sampleIcons . length ) ] . slice ( 1 ) ) ]
2021-01-18 23:54:18 -03:00
let iconserver = req . isGDPS ? req . server . name : undefined
2022-05-19 22:30:54 -04:00
res . status ( 200 ) . send ( Object . assign ( iconKitFiles , { sample , server : iconserver , noCopy : req . onePointNine || req . offline } ) ) ;
2020-09-24 23:07:53 -03:00
} ) ;
2019-10-15 23:42:47 -03:00
2022-05-19 22:30:54 -04:00
app . get ( '/icon/:text' , function ( req , res ) {
let iconID = Number ( req . query . icon || 1 )
let iconForm = sacredTexts . forms [ req . query . form ] ? req . query . form : "icon"
let iconPath = ` ${ iconForm } _ ${ iconID } .png `
let fileExists = iconKitFiles . previewIcons . includes ( iconPath )
if ( fileExists ) return res . status ( 200 ) . sendFile ( ` ./iconkit/premade/ ${ iconPath } ` , { root : _ _dirname } )
else return res . status ( 200 ) . sendFile ( ` ./iconkit/premade/ ${ iconForm } _01.png ` , { root : _ _dirname } )
} )
2019-10-15 23:42:47 -03:00
app . get ( '*' , function ( req , res ) {
2022-05-29 13:18:14 -04:00
if ( req . path . startsWith ( '/api' ) || req . path . startsWith ( "/iconkit" ) ) res . status ( 404 ) . send ( '-1' )
2019-12-15 21:11:35 -03:00
else res . redirect ( '/search/404%20' )
2019-10-15 23:42:47 -03:00
} ) ;
2020-11-01 17:29:32 -03:00
app . use ( function ( err , req , res , next ) {
2021-12-07 16:06:33 -03:00
if ( err && err . message == "Response timeout" ) res . status ( 504 ) . send ( 'Internal server error! (Timed out)' )
2020-11-01 17:29:32 -03:00
} )
2021-08-18 20:10:35 -04:00
process . on ( 'uncaughtException' , ( e ) => { console . log ( e ) } ) ;
process . on ( 'unhandledRejection' , ( e , p ) => { console . log ( e ) } ) ;
2021-01-04 12:21:58 -03:00
app . listen ( app . config . port , ( ) => console . log ( ` Site online! (port ${ app . config . port } ) ` ) )