249 lines
8.3 KiB
JavaScript
249 lines
8.3 KiB
JavaScript
const express = require("express")
|
|
const router = express.Router()
|
|
const rcctalk = require('./../../thumbnailrcctalk')
|
|
const rcctalk2018 = require('./../../rcctalk2018')
|
|
const fs = require('fs')
|
|
const assetrenderscript = fs.readFileSync('assetthumbnailrenderer.lua','utf-8')
|
|
var path = require("path");
|
|
const User = require('./../../model/user.js')
|
|
const item = require('./../../model/item.js')
|
|
var rgx = /^[0-9]*\.?[0-9]*$/;
|
|
router.use(express.json({limit: '200mb'}));
|
|
const { requireAuth } = require('./../../middleware/authmiddleware.js')
|
|
const { grabAuth } = require('./../../middleware/grabauth.js')
|
|
const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));
|
|
require('dotenv').config()
|
|
const RCC_HOST = process.env.RCC_HOST
|
|
const rateLimit = require('express-rate-limit')
|
|
const limiter = rateLimit({
|
|
windowMs: 2 * 1000, // 5 seconds
|
|
max: 1, // Limit each IP to 1 requests per `window`
|
|
standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers
|
|
legacyHeaders: false, // Disable the `X-RateLimit-*` headers
|
|
handler: (request, response, next, options) =>{
|
|
return response.sendFile(path.resolve("./assets/default.png"))
|
|
}
|
|
})
|
|
|
|
router.get("/",grabAuth,async (req, res) => {
|
|
if (!req.query.id && !req.query.userId) {
|
|
return res.status(400)
|
|
}
|
|
let headshot = false
|
|
if (req.query.type === "headshot"){
|
|
headshot = true
|
|
}
|
|
let id = req.query.id??req.query.userId
|
|
|
|
var sanitizedid = id.match(rgx)
|
|
|
|
const user = await User.findOne({userid: sanitizedid}).lean()
|
|
if (!user) {
|
|
return res.json({status: 'error', error: 'User does not exist'})
|
|
}
|
|
|
|
|
|
// lets get our file path with sanitized id
|
|
let path2=path.resolve(__dirname, "../../assets/userthumbnails/"+sanitizedid+".png")
|
|
if (headshot === true){
|
|
path2=path.resolve(__dirname, "../../assets/userthumbnailsheadshots/"+sanitizedid+".png")
|
|
}
|
|
|
|
fs.access(path2, fs.F_OK,async (err) => {
|
|
if (err) {
|
|
|
|
|
|
let newrender = await rcctalk2018.OpenRender(sanitizedid,headshot)
|
|
if (newrender.error){
|
|
return res.sendFile(path.resolve("./assets/default.png"))
|
|
}
|
|
newrender = newrender['SOAP-ENV:Envelope']['SOAP-ENV:Body']['ns1:OpenJobResponse']['ns1:OpenJobResult'][0]['ns1:value']._text
|
|
|
|
res.writeHead(200, {'Content-Type': 'image/png'})
|
|
|
|
fs.writeFile(path2,newrender,'base64',function(err){
|
|
if (err) {
|
|
console.log("error")
|
|
}
|
|
|
|
})
|
|
return res.end(Buffer.from(newrender, 'base64'))
|
|
|
|
// if this timeouts and rcc doesn't return the image feor some reason then send the default fallback
|
|
//return res.sendFile(path.resolve("./assets/default.png"))
|
|
}
|
|
|
|
//file exists
|
|
if (req.query.method && req.userdocument && req.userdocument.userid == sanitizedid){ // don't allow unauthenticated users to regenerate avatars and don't allow authenticated users to regenerate other peoples avatars
|
|
if (req.query.method === "regenerate"){
|
|
fs.unlink(path2,async function (err) {
|
|
if (err){
|
|
console.log(err)
|
|
}
|
|
|
|
|
|
let newrender = await rcctalk2018.OpenRender(sanitizedid,headshot)
|
|
if (newrender.error){
|
|
return res.sendFile(path.resolve("./assets/default.png"))
|
|
}
|
|
newrender = newrender['SOAP-ENV:Envelope']['SOAP-ENV:Body']['ns1:OpenJobResponse']['ns1:OpenJobResult'][0]['ns1:value']._text
|
|
|
|
res.writeHead(200, {'Content-Type': 'image/png'})
|
|
|
|
fs.writeFile(path2,newrender,'base64',function(err){
|
|
if (err) {
|
|
console.log("error")
|
|
}
|
|
|
|
})
|
|
return res.end(Buffer.from(newrender, 'base64'))
|
|
|
|
|
|
|
|
});
|
|
}
|
|
}else{
|
|
res.sendFile(path.resolve(path2))
|
|
return
|
|
}
|
|
|
|
|
|
})
|
|
|
|
})
|
|
|
|
router.post("/rcc", (req, res) => {
|
|
var ip = req.headers['cf-connecting-ip'] || req.socket.remoteAddress
|
|
if (ip == RCC_HOST || ip == "::ffff:"+RCC_HOST) {
|
|
const {player, thumbnail} = req.body
|
|
let path2=path.resolve(__dirname, "../../assets/userthumbnails/"+player+".png")
|
|
fs.writeFile(path2,thumbnail,'base64',function(err){
|
|
if (err) {
|
|
console.log("error")
|
|
// if writing fails we can still fallback
|
|
return res.sendFile(path.resolve("./../../assets/default.png"))
|
|
}
|
|
// if it succeeds then we can send the userthumbnail
|
|
// close the job after
|
|
rcctalk.CloseJob("Thumbnailfor"+player)
|
|
})
|
|
}
|
|
})
|
|
|
|
|
|
|
|
|
|
router.get(["/asset","/asset.ashx"],grabAuth,async (req, res) => {
|
|
if (!req.query.id && !req.query.assetid) {
|
|
return res.status(400)
|
|
}
|
|
let id = req.query.id??req.query.assetid
|
|
|
|
var sanitizedid = id.match(rgx)
|
|
|
|
const user = await item.findOne({ItemId: sanitizedid}).lean()
|
|
if (!user) {
|
|
return res.json({status: 'error', error: 'Item does not exist'})
|
|
}
|
|
if (user.Type === "Audio"){
|
|
return res.sendFile(path.resolve("./assets/images/audio.png"))
|
|
}
|
|
if (user.Hidden === true){
|
|
// if item isn't supposed to have a thumbnail
|
|
return res.sendFile(path.resolve("./assets/moderated.png"))
|
|
}
|
|
if (user.approved === false && !req.query.nonapproved){
|
|
return res.sendFile(path.resolve("./assets/approval.png"))
|
|
}
|
|
if (req.query.nonapproved && req?.userdocument?.admin === false){ // we only want admins to be able to see non approved assets anyways
|
|
return res.sendFile(path.resolve("./assets/approval.png"))
|
|
}
|
|
if (req.query.nonapproved && (user.Type === "Pants" || user.Type === "Shirts")){
|
|
sanitizedid -= 1
|
|
return res.sendFile(path.resolve(__dirname, "../../assets/ugc/itemfile-"+sanitizedid+".rbxm"))
|
|
}
|
|
if (req.query.nonapproved && user.Type === "Video"){
|
|
return res.sendFile(path.resolve(__dirname, "../../assets/ugc/itemfile-"+sanitizedid+".rbxm"))
|
|
}
|
|
if (user.Type === "Video"){
|
|
return res.sendFile(path.resolve("./assets/video.png"))
|
|
}
|
|
if (user.Type === "User Ad" || user.Type === "Gamepass"){
|
|
try{
|
|
await fs.promises.access(path.resolve(__dirname, "../../assets/ugc/itemfile-"+sanitizedid+".rbxm"), fs.constants.W_OK)
|
|
return res.sendFile(path.resolve(__dirname, "../../assets/ugc/itemfile-"+sanitizedid+".rbxm"))
|
|
}catch{
|
|
return res.sendFile(path.resolve("./assets/images/defaultadsky.png"))
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// lets get our file path with sanitized id
|
|
let path2=path.resolve(__dirname, "../../assets/ugc/asset-"+sanitizedid+".png")
|
|
|
|
fs.access(path2, fs.F_OK,async (err) => {
|
|
if (err) {
|
|
|
|
|
|
// get our renderscript with the new character app
|
|
var newrenderscript = assetrenderscript.replace('local asset = 0','local asset = "'+sanitizedid+'"')
|
|
//open a new job for our thumbnail render request
|
|
var response = await rcctalk.OpenJob("Thumbnailfor"+sanitizedid,newrenderscript,"120")
|
|
if (response['SOAP-ENV:Envelope']['SOAP-ENV:Body']['SOAP-ENV:Fault']){
|
|
// if failed then print out error close job then send a fallback image
|
|
//console.dir(response,{ depth: null })
|
|
rcctalk.CloseJob("Thumbnailfor"+sanitizedid)
|
|
return res.sendFile(path.resolve("./assets/default.png"))
|
|
}else{
|
|
// send image to user
|
|
// wait for image to be uploaded by rcc
|
|
function check() {
|
|
setTimeout(() => {
|
|
fs.access(path2, fs.constants.F_OK, error => {
|
|
if (error) {
|
|
check()
|
|
} else {
|
|
return res.sendFile(path2)
|
|
}
|
|
});
|
|
},3000)
|
|
}
|
|
}
|
|
check()
|
|
|
|
// if this timeouts and rcc doesn't return the image feor some reason then send the default fallback
|
|
return res.sendFile(path.resolve("./assets/default.png"))
|
|
}
|
|
|
|
res.sendFile(path.resolve(path2))
|
|
return
|
|
|
|
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
router.post("/rccasset", (req, res) => {
|
|
var ip = req.headers['cf-connecting-ip'] || req.socket.remoteAddress
|
|
if (ip == RCC_HOST || ip == "::ffff:"+RCC_HOST) {
|
|
const {asset, thumbnail} = req.body
|
|
console.log(asset)
|
|
let path2=path.resolve(__dirname, "../../assets/ugc/asset-"+asset+".png")
|
|
fs.writeFile(path2,thumbnail,'base64',function(err){
|
|
if (err) {
|
|
console.log("error")
|
|
// if writing fails we can still fallback
|
|
return res.sendFile(path.resolve("./../../assets/default.png"))
|
|
}
|
|
// if it succeeds then we can send the userthumbnail
|
|
// close the job after
|
|
rcctalk.CloseJob("Thumbnailforasset"+asset)
|
|
})
|
|
}
|
|
})
|
|
|
|
module.exports = router |