2022-06-16 20:35:50 -04:00
"use strict" ;
const express = require ( 'express' )
const request = require ( 'request' )
const compression = require ( 'compression' )
const timeout = require ( 'connect-timeout' )
const rateLimit = require ( "express-rate-limit" )
const fs = require ( "fs" )
const app = express ( )
2020-11-07 19:20:44 -05:00
2022-07-03 13:41:05 -04:00
const serverList = require ( './servers.json' )
const pinnedServers = [ ]
const notPinnedServers = [ ]
serverList . forEach ( x => ( x . pinned ? pinnedServers : notPinnedServers ) . push ( x ) )
notPinnedServers . sort ( ( a , b ) => a . name . localeCompare ( b . name ) )
2021-08-01 19:22:35 -04:00
app . servers = pinnedServers . concat ( notPinnedServers )
2022-07-03 13:41:05 -04:00
app . safeServers = JSON . parse ( JSON . stringify ( app . servers ) ) // deep clone
app . safeServers . forEach ( x => [ 'endpoint' , 'substitutions' , 'overrides' , 'disabled' ] . forEach ( k => delete x [ k ] ) )
2021-01-18 21:54:18 -05:00
app . config = require ( './settings.js' )
2020-11-07 19:20:44 -05:00
2022-07-03 13:41:05 -04:00
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>" +
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 09:02:40 -04:00
const RL = rateLimit ( {
2020-11-01 15:29:32 -05:00
windowMs : app . config . rateLimiting ? 5 * 60 * 1000 : 0 ,
max : app . config . rateLimiting ? 100 : 0 , // max requests per 5 minutes
2020-11-07 19:20:44 -05:00
message : rlMessage ,
2022-07-03 13:41:05 -04:00
keyGenerator : req => req . headers [ 'x-real-ip' ] || req . headers [ 'x-forwarded-for' ] ,
skip : req => req . url . includes ( "api/level" ) && ! req . query . hasOwnProperty ( "download" )
2020-09-10 09:02:40 -04:00
} )
2019-11-06 23:07:31 -05:00
2020-11-07 19:20:44 -05: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' ] }
} )
2022-07-03 13:41:05 -04:00
const XOR = require ( './classes/XOR.js' )
const achievements = require ( './misc/achievements.json' )
2021-01-11 16:00:21 -05:00
let achievementTypes = require ( './misc/achievementTypes.json' )
2021-02-01 14:30:40 -05:00
let music = require ( './misc/music.json' )
2021-01-04 10:21:58 -05:00
let assetPage = fs . readFileSync ( './html/assets.html' , 'utf8' )
2020-09-24 22:07:53 -04:00
2021-01-18 21:54:18 -05:00
app . accountCache = { }
app . lastSuccess = { }
app . actuallyWorked = { }
app . servers . forEach ( x => {
2022-07-03 13:41:05 -04:00
x = x . id || "gd"
app . accountCache [ x ] = { }
app . lastSuccess [ x ] = Date . now ( )
2021-01-18 21:54:18 -05:00
} )
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 21:54:18 -05:00
app . set ( 'json spaces' , 2 )
2022-06-16 20:35:50 -04:00
app . use ( compression ( ) )
app . use ( express . json ( ) )
app . use ( express . urlencoded ( { extended : true } ) )
app . use ( timeout ( '20s' ) )
2019-10-15 22:42:47 -04:00
2021-01-18 21:54:18 -05: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 ( ) ) )
2022-07-03 13:41:05 -04:00
if ( subdomains . length > 1 || ! req . server )
return res . redirect ( "http://" + req . get ( 'host' ) . split ( "." ) . slice ( subdomains . length ) . join ( "." ) + req . originalUrl )
2021-01-18 21:54:18 -05:00
2022-07-03 13:41:05 -04:00
// will expand this in the future :wink: 😉
2021-12-07 14:14:56 -05:00
res . sendError = function ( errorCode = 500 ) {
res . status ( errorCode ) . send ( "-1" )
}
2021-01-18 21:54:18 -05:00
// literally just for convenience
req . offline = req . server . offline
req . endpoint = req . server . endpoint
req . onePointNine = req . server . onePointNine
2021-01-19 00:56:21 -05:00
req . timestampSuffix = req . server . timestampSuffix || ""
2021-01-18 21:54:18 -05: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 21:54:18 -05:00
if ( req . isGDPS ) res . set ( "gdps" , ( req . onePointNine ? "1.9/" : "" ) + req . id )
2021-02-01 14:30:40 -05:00
if ( req . query . online > 0 ) req . offline = false
2021-01-18 21:54:18 -05:00
2021-01-17 00:05:06 -05:00
req . gdParams = function ( obj = { } , substitute = true ) {
2022-07-03 13:41:05 -04:00
Object . keys ( app . config . params ) . forEach ( k => obj [ k ] || = app . config . params [ k ] )
Object . keys ( req . server . extraParams || { } ) . forEach ( k => obj [ k ] || = req . server . extraParams [ k ] )
2020-11-01 15:29:32 -05:00
let ip = req . headers [ 'x-real-ip' ] || req . headers [ 'x-forwarded-for' ]
2021-01-14 18:18:19 -05:00
let params = { form : obj , headers : app . config . ipForwarding && ip ? { 'x-forwarded-for' : ip , 'x-real-ip' : ip } : { } }
2021-01-17 00:05:06 -05:00
if ( substitute ) { // GDPS substitutions in settings.js
2021-01-18 21:54:18 -05:00
for ( let ss in req . server . substitutions ) {
2022-07-03 13:41:05 -04:00
if ( params . form [ ss ] ) {
params . form [ req . server . substitutions [ ss ] ] = params . form [ ss ]
delete params . form [ ss ]
}
2021-01-17 00:05:06 -05:00
}
2021-01-14 18:18:19 -05:00
}
return params
2020-11-01 15:29:32 -05:00
}
2021-01-18 21:54:18 -05:00
req . gdRequest = function ( target , params = { } , cb = function ( ) { } ) {
if ( ! target ) return cb ( true )
2022-07-03 13:41:05 -04:00
target = ( req . server . overrides && req . server . overrides [ target ] ) || target
2021-01-18 21:54:18 -05:00
let parameters = params . headers ? params : req . gdParams ( params )
2022-07-03 13:41:05 -04:00
let { endpoint } = req
if ( params . forceGD || ( params . form ? . forceGD ) )
endpoint = "http://www.boomlings.com/database/"
2021-01-18 21:54:18 -05:00
request . post ( endpoint + target + '.php' , parameters , function ( err , res , body ) {
2022-07-03 13:41:05 -04:00
if ( ! err && ( ! body || /(^-\d$)|^error|^</ . test ( body ) ) )
err = { serverError : true , response : body }
return cb ( err , res , body )
2021-01-18 21:54:18 -05:00
} )
}
2020-11-01 15:29:32 -05:00
next ( )
} )
2020-10-28 21:25:13 -04:00
let directories = [ "" ]
fs . readdirSync ( './api' ) . filter ( x => ! x . includes ( "." ) ) . forEach ( x => directories . push ( x ) )
2019-12-25 16:20:32 -05:00
2021-01-18 21:54:18 -05:00
app . trackSuccess = function ( id ) {
app . lastSuccess [ id ] = Date . now ( )
2022-07-03 13:41:05 -04:00
app . actuallyWorked [ id ] || = true
2021-01-11 16:00:21 -05:00
}
2021-01-18 21:54:18 -05:00
app . timeSince = function ( id , time ) {
if ( ! time ) time = app . lastSuccess [ id ]
2021-01-11 16:00:21 -05:00
let secsPassed = Math . floor ( ( Date . now ( ) - time ) / 1000 )
let minsPassed = Math . floor ( secsPassed / 60 )
2022-06-16 20:35:50 -04:00
secsPassed -= 60 * minsPassed
2021-01-18 21:54:18 -05:00
return ` ${ app . actuallyWorked [ id ] ? "" : "~" } ${ minsPassed } m ${ secsPassed } s `
2021-01-11 16:00:21 -05:00
}
2021-01-21 17:15:31 -05:00
app . userCache = function ( id , accountID , playerID , name ) {
2022-06-16 20:35:50 -04:00
2022-07-03 13:41:05 -04:00
if ( // "IDK how to format this nicely" @Rudxain
! accountID || accountID == "0" ||
( name ? . toLowerCase ( ) == "robtop" && accountID != "71" ) ||
! app . config . cacheAccountIDs
)
return
2021-01-21 17:15:31 -05: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 16:20:32 -05:00
app . run = { }
directories . forEach ( d => {
2022-07-03 13:41:05 -04:00
fs . readdirSync ( './api/' + d )
. forEach ( x => {
if ( x . includes ( '.' ) ) app . run [ x . split ( '.' , 1 ) [ 0 ] ] = require ( ` ./api/ ${ d } / ${ x } ` )
} )
2019-10-16 18:47:53 -04:00
} )
2019-10-15 22:42:47 -04:00
2021-08-03 11:51:09 -04:00
app . xor = new XOR ( )
let hasSecretStuff = false
2021-05-27 19:30:56 +07:00
2019-12-21 22:52:09 -05:00
try {
const secrets = require ( "./misc/secretStuff.json" )
2021-08-03 11:51:09 -04:00
hasSecretStuff = true
2019-12-21 22:52:09 -05: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-21 22:52:09 -05:00
}
2019-10-15 22:42:47 -04:00
2019-12-25 16:20:32 -05:00
catch ( e ) {
2019-12-21 22:52:09 -05: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 22:42:47 -04:00
}
2021-08-18 20:10:35 -04:00
app . parseResponse = function ( responseBody , splitter = ":" ) {
2022-06-16 20:35:50 -04:00
if ( ! responseBody || responseBody == "-1" ) return { }
2021-01-15 10:29:46 -05: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
2022-07-03 13:41:05 -04:00
let response = responseBody . split ( '#' , 1 ) [ 0 ] . split ( splitter )
2022-06-16 20:35:50 -04:00
let res = { }
2022-07-03 13:41:05 -04:00
for ( let i = 0 ; i < response . length ; i += 2 )
res [ response [ i ] ] = response [ i + 1 ]
2022-06-16 20:35:50 -04:00
return res
2021-01-15 10:29:46 -05:00
}
2019-10-15 22:42:47 -04:00
2019-10-16 18:47:53 -04:00
//xss bad
2022-07-03 13:41:05 -04:00
app . clean = text => {
const escChar = c => ( { "&" : "&" , "<" : "<" , ">" : ">" , "=" : "=" , '"' : """ , "'" : "'" } [ c ] || c )
return ! text || typeof text != "string" ? text : text . replace ( / . / g s , e s c C h a r )
}
2019-10-15 22:42:47 -04:00
2019-12-16 08:48:05 -05:00
// ASSETS
2022-06-16 20:35:50 -04:00
app . use ( '/assets' , express . static ( _ _dirname + '/assets' , { maxAge : "7d" } ) )
app . use ( '/assets/css' , express . static ( _ _dirname + '/assets/css' ) )
2021-01-04 10:21:58 -05:00
2022-06-16 20:35:50 -04:00
app . use ( '/iconkit' , express . static ( _ _dirname + '/iconkit' ) )
2022-07-03 13:41:05 -04:00
app . get ( "/misc/global.js" , function ( req , res ) { res . status ( 200 ) . sendFile ( _ _dirname + "/misc/global.js" ) } )
2021-12-07 11:06:33 -08:00
app . get ( "/dragscroll.js" , function ( req , res ) { res . status ( 200 ) . sendFile ( _ _dirname + "/misc/dragscroll.js" ) } )
2021-01-04 10:21:58 -05: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 11:06:33 -08: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 10:21:58 -05: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 11:06:33 -08:00
res . status ( 200 ) . send ( assetPage . replace ( '{NAME}' , dir || "assets" ) . replace ( '{DATA}' , assetData ) )
2021-01-04 10:21:58 -05:00
} )
2019-10-15 22:42:47 -04:00
2019-12-16 08:48:05 -05:00
// POST REQUESTS
2019-10-15 22:42:47 -04:00
2022-07-03 13:41:05 -04:00
function doPOST ( name , key , noRL , wtf ) {
const args = [ "/" + name ]
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 )
2019-10-15 22:42:47 -04:00
2020-10-02 14:33:24 -04:00
2019-12-16 08:48:05 -05:00
// HTML
2019-10-15 22:42:47 -04:00
2021-01-18 21:54:18 -05:00
let downloadDisabled = [ 'daily' , 'weekly' ]
2022-07-03 13:41:05 -04:00
let onePointNineDisabled = [ 'daily' , 'weekly' , 'gauntlets' , 'messages' ] // using `concat` won't shorten this
2021-01-18 21:54:18 -05:00
let gdpsHide = [ 'achievements' , 'messages' ]
2022-06-16 20:35:50 -04:00
app . get ( "/" , function ( req , res ) {
2022-07-03 13:41:05 -04:00
if ( req . query . hasOwnProperty ( "offline" ) || ( req . offline && ! req . query . hasOwnProperty ( "home" ) ) )
res . status ( 200 ) . sendFile ( _ _dirname + "/html/offline.html" )
2021-01-18 21:54:18 -05:00
else {
fs . readFile ( './html/home.html' , 'utf8' , function ( err , data ) {
2022-06-16 20:35:50 -04:00
let html = data
2021-01-18 21:54:18 -05:00
if ( req . isGDPS ) {
2022-07-03 13:41:05 -04:00
html = html
. replace ( '"levelBG"' , '"levelBG purpleBG"' )
. replace ( /Geometry Dash Browser!/g , req . server . name + " Browser!" )
. replace ( "/assets/gdlogo" , ` /assets/gdps/ ${ req . id } _logo ` )
. replace ( "coin.png\" itemprop" , ` gdps/ ${ req . id } _icon.png" itemprop ` )
. replace ( /coin\.png/g , ` ${ req . server . onePointNine ? "blue" : "silver" } coin.png ` )
2021-01-18 21:54:18 -05:00
gdpsHide . forEach ( x => { html = html . replace ( ` menu- ${ x } ` , 'changeDaWorld' ) } )
}
2022-07-03 13:41:05 -04:00
const htmlReplacer = x => { html = html . replace ( ` menu- ${ x } ` , 'menuDisabled' ) }
if ( req . onePointNine ) onePointNineDisabled . forEach ( htmlReplacer )
if ( req . server . disabled ) req . server . disabled . forEach ( htmlReplacer )
2021-08-01 21:37:22 -04:00
if ( req . server . downloadsDisabled && process . platform == "linux" ) {
2022-07-03 13:41:05 -04:00
downloadDisabled . forEach ( htmlReplacer )
html = html
. replace ( 'id="dl" style="display: none' , 'style="display: block' )
. replace ( 'No active <span id="noLevel">daily</span> level!' , '[Blocked by RobTop]' )
2021-12-07 14:22:17 -05:00
}
2022-07-03 13:41:05 -04: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 21:54:18 -05:00
}
2021-12-07 11:06:33 -08:00
return res . status ( 200 ) . send ( html )
2021-01-18 21:54:18 -05:00
} )
}
2022-06-16 20:35:50 -04:00
} )
2020-09-10 09:02:40 -04:00
2022-07-03 13:41:05 -04:00
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" )
2019-10-15 22:42:47 -04:00
2019-12-16 08:48:05 -05:00
// API
2019-10-20 23:33:01 -04:00
2022-07-03 13:41:05 -04:00
function doGET ( name , key , RL , wtf1 , wtf2 ) {
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 )
2021-12-07 11:06:33 -08:00
app . get ( "/api/credits" , function ( req , res ) { res . status ( 200 ) . send ( require ( './misc/credits.json' ) ) } )
2022-07-03 13:41:05 -04:00
doGET ( "gauntlets" )
2020-10-28 21:25:13 -04:00
app . get ( "/api/leaderboard" , function ( req , res ) { app . run [ req . query . hasOwnProperty ( "accurate" ) ? "accurate" : "scores" ] ( app , req , res ) } )
2022-07-03 13:41:05 -04:00
doGET ( "leaderboardLevel/:id" , "leaderboardLevel" , RL2 )
doGET ( "level/:id" , "level" , RL , true )
doGET ( "mappacks" )
doGET ( "profile/:id" , "profile" , RL2 , true )
doGET ( "search/:text" , "search" , RL2 )
doGET ( "song/:song" , "song" )
2022-06-16 20:35:50 -04:00
2019-10-15 22:42:47 -04:00
2019-12-16 08:48:05 -05:00
// REDIRECTS
2019-10-15 22:42:47 -04:00
2022-07-03 13:41:05 -04:00
function doRedir ( name , dir , key = 'id' ) {
app . get ( '/' + name , function ( req , res ) { res . redirect ( '/' + dir + ( key && '/' + req . params [ key ] ) ) } )
}
doRedir ( 'icon' , 'iconkit' , '' )
doRedir ( 'obj/:text' , 'obj' , 'text' )
doRedir ( 'leaderboards/:id' , 'leaderboard' )
doRedir ( 'profile/:id' , 'u' )
doRedir ( 'p/:id' , 'u' )
doRedir ( 'l/:id' , 'leaderboard' )
doRedir ( 'a/:id' , 'analyze' )
doRedir ( 'c/:id' , 'comments' )
doRedir ( 'd/:id' , 'demon' )
2019-10-15 22:42:47 -04:00
2020-09-24 22:07:53 -04:00
// API AND HTML
2022-06-16 20:35:50 -04:00
2022-07-03 13:41:05 -04:00
doPOST ( "u/:id" , "profile" , true )
doPOST ( ":id" , "level" , true )
2020-09-24 22:07:53 -04:00
2019-12-16 08:48:05 -05:00
// MISC
2019-10-15 22:42:47 -04:00
2021-12-07 11:06:33 -08:00
app . get ( "/api/userCache" , function ( req , res ) { res . status ( 200 ) . send ( app . accountCache ) } )
2022-07-03 13:41:05 -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 11:06:33 -08:00
app . get ( "/api/music" , function ( req , res ) { res . status ( 200 ) . send ( music ) } )
2022-07-03 13:41:05 -04:00
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 => {
2022-07-03 13:41:05 -04:00
sacredTexts [ x . split ( "." , 1 ) [ 0 ] ] = require ( "./iconkit/sacredtexts/" + x )
2022-05-19 22:30:54 -04:00
} )
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
2022-07-03 13:41:05 -04:00
let iconType = sacredTexts . forms [ x . split ( "_" , 1 ) [ 0 ] ] . form
2022-05-19 22:30:54 -04:00
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" ) ) {
2022-07-03 13:41:05 -04:00
sacredTexts . newIcons . push ( x . split ( "-" , 1 ) [ 0 ] )
let formName = x . split ( /_\d/g , 1 ) [ 0 ]
2022-05-29 13:18:14 -04:00
if ( ! newIconCounts [ formName ] ) newIconCounts [ formName ] = 1
else newIconCounts [ formName ] ++
}
} )
sacredTexts . newIconCounts = newIconCounts
2022-05-19 22:30:54 -04:00
2022-06-16 20:35:50 -04: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 => {
2022-07-03 13:41:05 -04:00
iconKitFiles [ x . split ( "." , 1 ) [ 0 ] ] = require ( "./iconkit/extradata/" + x )
2022-05-19 22:30:54 -04:00
} )
2022-07-03 13:41:05 -04:00
Object . assign ( iconKitFiles , { previewIcons , newPreviewIcons } )
2022-05-19 22:30:54 -04:00
2022-06-16 20:35:50 -04:00
app . get ( '/api/iconkit' , function ( req , res ) {
2022-07-03 13:41:05 -04:00
let sample = [ JSON . stringify ( sampleIcons [ Math . random ( ) * sampleIcons . length >>> 0 ] . slice ( 1 ) ) ]
2021-01-18 21:54:18 -05: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 } ) ) ;
2022-06-16 20:35:50 -04:00
} )
2019-10-15 22:42:47 -04: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 )
2022-07-03 13:41:05 -04:00
return res . status ( 200 ) . sendFile ( ` ./iconkit/premade/ ${ fileExists ? iconPath : iconForm + '_01.png' } ` , { root : _ _dirname } )
2022-05-19 22:30:54 -04:00
} )
2019-10-15 22:42:47 -04:00
app . get ( '*' , function ( req , res ) {
2022-07-03 13:41:05 -04:00
if ( /^\/(api|iconkit)/ . test ( req . path ) )
res . status ( 404 ) . send ( '-1' )
else
res . redirect ( '/search/404%20' )
2022-06-16 20:35:50 -04:00
} )
2019-10-15 22:42:47 -04:00
2022-07-03 13:41:05 -04:00
app . use ( function ( err , req , res ) {
if ( err ? . message == "Response timeout" ) res . status ( 504 ) . send ( 'Internal server error! (Timed out)' )
2020-11-01 15:29:32 -05:00
} )
2022-07-03 13:41:05 -04:00
process . on ( 'uncaughtException' , e => console . log ( e ) )
process . on ( 'unhandledRejection' , e => console . log ( e ) )
2021-08-18 20:10:35 -04:00
2022-05-28 22:46:33 -04:00
app . listen ( app . config . port , ( ) => console . log ( ` Site online! (port ${ app . config . port } ) ` ) )