import Module from "node:module" const require = Module.createRequire(import.meta.url) import path from "path" import { fileURLToPath } from "url" import { requireAuth } from "./middleware/authmiddleware.js" const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) var express = require("express") const app = require("express")() var cookieParser = require("cookie-parser") var session = require("express-session") const helmet = require("helmet") const mongoose = require("mongoose") import configNew from "./model/configNew.mjs" import ipWhitelist from "./model/ipWhitelist.mjs" const user = require("./model/user.js") const model = require("./model/user.js") const jwt = require("jsonwebtoken") const rcctalk = require("./rcctalk") const { grabAuth } = require("./middleware/grabauth.js") const games = require("./model/games.js") require("dotenv").config() const https = require("https") const PROD = process.env.PROD const client = require("prom-client") const { handler } = await import("../Front/build/handler.js") app.use((req, res, next) => { const allowedOrigins = [ "m.mete0r.xyz", "mete0r.xyz", "assetgame.mete0r.xyz", "www.mete0r.xyz", "api.mete0r.xyz", "dinnerbone.mete0r.xyz" /* funny */, "assetgame.mete0r.xyz", "clientsettingscdn.mete0r.xyz", "http://127.0.0.1:5173", ] const origin = req.get("host") if (allowedOrigins.includes(origin)) { res.setHeader( "Access-Control-Allow-Origin", req.headers["x-forwarded-proto"] ?? "http" + "://" + origin, ) } if (origin === "mete0r.xyz") { res.setHeader("Access-Control-Allow-Origin", "*") } //res.header('Access-Control-Allow-Origin', 'http://127.0.0.1:8020'); res.header("Access-Control-Allow-Methods", "POST, GET, OPTIONS") res.header("Access-Control-Allow-Headers", "Content-Type, Authorization") res.header("Access-Control-Allow-Credentials", true) return next() }) import { createClient } from "redis" let redis // on prod we can just use a locally hosted redisStack I'm too lazy to use docker on windows to host one for local dev if (PROD === "true") { redis = createClient() } else { const localRedisConnection = process.env.LOCALREDISCONNECTION redis = createClient({ url: localRedisConnection }) } redis.on("error", err => console.log("Redis Client Error", err)) await redis.connect() import { Repository } from "redis-om" const configRepository = new Repository(configNew, redis) const ipWhiteListRepository = new Repository(ipWhitelist, redis) const collectDefaultMetrics = client.collectDefaultMetrics collectDefaultMetrics({ timeout: 5000 }) const counter = new client.Counter({ name: "node_request_operations_total", help: "The total number of processed requests", }) const playercounter = new client.Gauge({ name: "node_players", help: "Amount of players every minute", async collect() { // Invoked when the registry collects its metrics' values. const currentValue = await games.aggregate([ { $group: { _id: null, numberofplayers: { $sum: { $convert: { input: "$numberofplayers", to: "int" }, }, }, }, }, ]) this.set(currentValue[0].numberofplayers) }, }) const histogram = new client.Histogram({ name: "node_request_duration_seconds", help: "Histogram for the duration in seconds", buckets: [1, 2, 5, 6, 10], }) const getDurationInMilliseconds = start => { const NS_PER_SEC = 1e9 const NS_TO_MS = 1e6 const diff = process.hrtime(start) return (diff[0] * NS_PER_SEC + diff[1]) / NS_TO_MS } app.use((req, res, next) => { const start = process.hrtime() counter.inc() res.on("finish", () => { const durationInMilliseconds = getDurationInMilliseconds(start) histogram.observe(durationInMilliseconds) }) next() }) const JWT_SECRET = process.env.JWT_SECRET const RCC_HOST = process.env.RCC_HOST const DB_PASSWORD = process.env.DB_PASSWORD console.log(RCC_HOST) const { logExecutionTime } = require("mongoose-execution-time") //mongoose.plugin(logExecutionTime); if (PROD === "true") { mongoose.connect("mongodb://127.0.0.1:27017/meteoritedb", { useNewUrlParser: true, useUnifiedTopology: true, authSource: "admin", user: "server", pass: DB_PASSWORD, }) } else { mongoose.connect("mongodb://127.0.0.1:27017/meteoritedb", { useNewUrlParser: true, useUnifiedTopology: true, }) } app.disable("x-powered-by") // we don't wanna tell potential attackers our exact framework yet lol // automatically create a default document in redisdb for our config // if the redis document doesn't exist auto create one these are also the default settings your site will start with async function createconfig() { try { var resp = await redis.exists("config:ONE") if (resp === 0) { // doesn't exist await configRepository.save("ONE", { RegistrationEnabled: true, MaintenanceEnabled: false, GamesEnabled: true, KeysEnabled: false, bannermessage: "", }) } } catch (err) { throw err } } createconfig() app.use(cookieParser()) // maintenance mode middleware app.use(async function (req, res, next) { if (req.url === "/assets/audio/wof.mp3") { return next() } res.header("Cache-Control", "no-store,no-cache,must-revalidate") var resp = await configRepository.fetch("ONE") req.config = resp req.configRepository = configRepository //console.log(req.headers['x-forwarded-proto']) if (!req.headers["x-forwarded-proto"]) { if (req.secure === true) { req.headers["x-forwarded-proto"] = "https" } else { req.headers["x-forwarded-proto"] = "http" } } /*if (!req.headers['cf-connecting-ip']){ //localhost res.header("Access-Control-Allow-Origin", "*"); }*/ if ( req.headers["x-forwarded-host"] === "www.mete0r.xyz" && req.headers["x-forwarded-host"] && req.headers?.["user-agent"] != "RobloxStudio/WinInet" && req.headers?.["user-agent"] != "Roblox/WinInet" ) { if ( req.method === "GET" && req.url.startsWith("/game/") === false && req.url.startsWith("/login/") === false ) { return res.redirect( 302, req.headers["x-forwarded-proto"] + "://mete0r.xyz" + req.url, ) } } //console.log(req.headers['x-forwarded-host']) //req.headers['x-forwarded-host'] = "mete0r.xyz" //console.log(req.headers?.['cf-connecting-ip']) //console.log(req.socket.remoteAddress) console.log(req.url) if (req.url === "/assets/2020.zip") { return res.redirect("https://www.youtube.com/watch?v=dQw4w9WgXcQ") } //return res.sendFile(path.join(__dirname, '/under_maintenance.html')); if ( resp.MaintenanceEnabled === true && req.headers?.["cf-connecting-ip"] != RCC_HOST && req.headers?.["cf-connecting-ip"] ) { if (!req.cookies) { return res.sendFile(path.join(__dirname, "/under_maintenance.html")) } if ( req?.cookies?.real === "2fKMlOumsNSnbuVJkLonCOYZXYZbWrGrdDeRTIeWAbXeOiFGyAY" ) { return next() } return res.sendFile(path.join(__dirname, "/under_maintenance.html")) } if ( req.headers?.["cf-connecting-ip"] != RCC_HOST && req.headers?.["cf-connecting-ip"] && req.url != "/initialize" && req.headers?.["user-agent"] != "Roblox/WinInet" && req.headers?.["user-agent"] != "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/605.1.15 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/605.1.15" ) { var ip = req.headers["cf-connecting-ip"] || req.socket.remoteAddress var resp = await redis.exists("ipWhiteListSchema:" + ip.toString()) if (resp === 0) { return res .status(401) .send("Not allowed visit the discord. discord.gg/5r6ZjG57kU") } } next() }) app.use(express.urlencoded({ extended: true })) async function lol() { try { const res = await rcctalk.GetAllJobs() //console.dir(res,{ depth: null }) } catch (error) { throw "RCC Test run failed please have rcc soap running on port 64989" } } //lol() app.set("trust proxy", true) // routes lol const assetRouter = require("./routes/assets.js") app.use(["/asset", "/v1/asset"], assetRouter) const gameRouter = require("./routes/game.js") app.use(["/game", "//game"], gameRouter) const persistenceRouter = require("./routes/persistence.js") app.use("/persistence", persistenceRouter) const clientSettingsRouter = require("./routes/clientsettings.js") app.use("/", clientSettingsRouter) const registerRouter = require("./routes/register.js") app.use("/register", registerRouter) const loginRouter = require("./routes/login.js") app.use(["/login", "/v2/login", "/v2/twostepverification/verify"], loginRouter) const logoutRouter = require("./routes/logout.js") app.use("/logout", logoutRouter) const gamesRouter = require("./routes/games.js") app.use("/games", gamesRouter) const adminRouter = require("./routes/admin.js") app.use("/admin", adminRouter) app.get("/users/account-info", (req, res) => { return res.json({ AgeBracket: 0, Email: { IsVerified: 1, Value: "kmulherin@roblox.com", }, HasPasswordSet: 1, Username: "iMightBeLying", RobuxBalance: 9999999, }) }) const usersRouter = require("./routes/users.js") app.use("/", usersRouter) const avatarRouter = require("./routes/avatar.js") app.use("/api/avatar", avatarRouter) const settingsRouter = require("./routes/settings.js") app.use("/settings", settingsRouter) const developRouter = require("./routes/develop.js") app.use("/develop", developRouter) const thumbnailRenderRouter = require("./routes/api/renderthumbnail.js") app.use( [ "/api/thumbnailrender", "/thumbs" /*2016 asset thumbs*/, "/avatar-thumbnail/image", ], thumbnailRenderRouter, ) const purchaseRouter = require("./routes/api/purchase.js") app.use("/api/purchase", purchaseRouter) const moderateRouter = require("./routes/api/moderate.js") app.use("/api/moderate", moderateRouter) const verifyRouter = require("./routes/api/verify.js") app.use("/api/verify", verifyRouter) const itemactionRouter = require("./routes/api/itemaction.js") app.use("/api/itemaction", itemactionRouter) const bodycolorupdateRouter = require("./routes/api/bodycolorupdate.js") app.use("/api/bodycolorupdate", bodycolorupdateRouter) const changepasswordRouter = require("./routes/api/changepassword.js") app.use("/api/changepassword", changepasswordRouter) const generatekeyRouter = require("./routes/api/generatekey.js") app.use("/api/generatekey", generatekeyRouter) const authRouter = require("./routes/api/auth.js") app.use("/api/auth", authRouter) const catalogRouter = require("./routes/catalog.js") app.use("/api/catalog", catalogRouter) const updategameinfoRouter = require("./routes/api/updategameinfo.js") app.use("/", updategameinfoRouter) const userinfoRouter = require("./routes/api/userinfo.js") app.use("/api/userinfo", userinfoRouter) const updateusermembershipRouter = require("./routes/api/updateusermembership.js") app.use("/api/updateusermembership", updateusermembershipRouter) const marketplaceRouter = require("./routes/marketplace.js") app.use("/", marketplaceRouter) const versioncompatibilityRouter = require("./routes/versioncompatibility.js") app.use("/", versioncompatibilityRouter) const t8gameRouter = require("./routes/2018/game.js") app.use("/game/", t8gameRouter.router) const t20gameRouter = require("./routes/2020/game.js") app.use(["/game/", "/v1"], t20gameRouter.router) const mobileApiRouter = require("./routes/mobileapi.js") app.use("/mobileapi", mobileApiRouter) const friendsApiRouter = require("./routes/api/friends.js") app.use("/api/friends", friendsApiRouter) const advertiseApiRouter = require("./routes/api/advertise.js") app.use("/api/advertise", advertiseApiRouter) const requestAdRouter = require("./routes/api/requestad.js") app.use("/api/requestad", requestAdRouter) /*const bankRouter = require('./routes/api/bank.js'); app.use('/api/bank',bankRouter)*/ const groupRouter = require("./routes/api/groups.js") app.use("/api/groups", groupRouter) const feedRouter = require("./routes/api/feed.js") app.use("/api/feed", feedRouter) const commentRouter = require("./routes/api/comment.js") app.use("/api/comments", commentRouter) const ideRouter = require("./routes/ide.js") app.use(["/ide", "//ide"], ideRouter) /* app.get("/My/Places", (req, res) => { res.send("No editing sorry") })*/ app.get("/studio/e.png", (req, res) => { res.send() }) app.get("/tags/c/36/studio.json", (req, res) => { res.json({ users: [ { id: 306443, username: "Hajimalago", avatar_template: "/user_avatar/devforum.roblox.com/hajimalago/{size}/724795_2.png", }, { id: 36263, username: "rickje139", avatar_template: "/user_avatar/devforum.roblox.com/rickje139/{size}/1459648_2.png", }, { id: 120450, username: "GodSysAdmin", avatar_template: "/user_avatar/devforum.roblox.com/godsysadmin/{size}/1540208_2.png", }, { id: 472489, username: "ItsMeFelixAccept", avatar_template: "/user_avatar/devforum.roblox.com/itsmefelixaccept/{size}/1551006_2.png", }, { id: 44883, username: "iSyriux", avatar_template: "/user_avatar/devforum.roblox.com/isyriux/{size}/1464807_2.png", }, { id: 351893, username: "JoshSedai", avatar_template: "/user_avatar/devforum.roblox.com/joshsedai/{size}/842420_2.png", }, { id: 376200, username: "Logimite", avatar_template: "/user_avatar/devforum.roblox.com/logimite/{size}/1573532_2.png", }, { id: 598293, username: "jmkd3v", avatar_template: "/user_avatar/devforum.roblox.com/jmkd3v/{size}/1572236_2.png", }, { id: 249742, username: "zachary108181", avatar_template: "/user_avatar/devforum.roblox.com/zachary108181/{size}/1376998_2.png", }, { id: 557246, username: "Miles_1king", avatar_template: "/user_avatar/devforum.roblox.com/miles_1king/{size}/1558993_2.png", }, { id: 341046, username: "tnavarts", avatar_template: "/user_avatar/devforum.roblox.com/tnavarts/{size}/797168_2.png", }, { id: 164536, username: "LucasTutoriaisSaimo", avatar_template: "/user_avatar/devforum.roblox.com/lucastutoriaissaimo/{size}/1572474_2.png", }, { id: 300, username: "Tomarty", avatar_template: "/user_avatar/devforum.roblox.com/tomarty/{size}/1557837_2.png", }, { id: 27022, username: "nooneisback", avatar_template: "/user_avatar/devforum.roblox.com/nooneisback/{size}/1488960_2.png", }, { id: 11348, username: "Hexcede", avatar_template: "/user_avatar/devforum.roblox.com/hexcede/{size}/1152765_2.png", }, { id: 350909, username: "crypto_mancer", avatar_template: "/user_avatar/devforum.roblox.com/crypto_mancer/{size}/822643_2.png", }, { id: 200305, username: "Kyxino", avatar_template: "/user_avatar/devforum.roblox.com/kyxino/{size}/1526293_2.png", }, { id: 176552, username: "7z99", avatar_template: "/user_avatar/devforum.roblox.com/7z99/{size}/1375229_2.png", }, { id: 17304, username: "FilteredStudio", avatar_template: "/user_avatar/devforum.roblox.com/filteredstudio/{size}/1555102_2.png", }, { id: 461567, username: "Optiplex3020SFF", avatar_template: "/user_avatar/devforum.roblox.com/optiplex3020sff/{size}/1498767_2.png", }, { id: 260389, username: "WallsAreForClimbing", avatar_template: "/user_avatar/devforum.roblox.com/wallsareforclimbing/{size}/1041671_2.png", }, { id: 163116, username: "SillyMeTimbers", avatar_template: "/user_avatar/devforum.roblox.com/sillymetimbers/{size}/1395188_2.png", }, { id: 396736, username: "HugeCoolboy2007", avatar_template: "/user_avatar/devforum.roblox.com/hugecoolboy2007/{size}/1533064_2.png", }, { id: 105134, username: "Fire540Games", avatar_template: "/user_avatar/devforum.roblox.com/fire540games/{size}/1539762_2.png", }, { id: 17941, username: "RBLXImagineer", avatar_template: "/user_avatar/devforum.roblox.com/rblximagineer/{size}/1417349_2.png", }, { id: 395244, username: "IdontPlayz343", avatar_template: "/user_avatar/devforum.roblox.com/idontplayz343/{size}/1379043_2.png", }, { id: 351579, username: "SimonEnderB", avatar_template: "/user_avatar/devforum.roblox.com/simonenderb/{size}/1533230_2.png", }, { id: 194130, username: "cunpliy", avatar_template: "/user_avatar/devforum.roblox.com/cunpliy/{size}/1426008_2.png", }, { id: 7289, username: "ittrgrey", avatar_template: "/user_avatar/devforum.roblox.com/ittrgrey/{size}/1570588_2.png", }, { id: 451394, username: "parker02311", avatar_template: "/user_avatar/devforum.roblox.com/parker02311/{size}/1103926_2.png", }, { id: 312723, username: "ihavoc101", avatar_template: "/user_avatar/devforum.roblox.com/ihavoc101/{size}/1574065_2.png", }, { id: 51619, username: "G2_funny", avatar_template: "/user_avatar/devforum.roblox.com/g2_funny/{size}/1528742_2.png", }, { id: 285060, username: "RainingSwordFire", avatar_template: "/user_avatar/devforum.roblox.com/rainingswordfire/{size}/1311775_2.png", }, { id: 417018, username: "SoaringKeyy", avatar_template: "/user_avatar/devforum.roblox.com/soaringkeyy/{size}/1551178_2.png", }, { id: 32451, username: "Clueless_Brick", avatar_template: "/user_avatar/devforum.roblox.com/clueless_brick/{size}/1556141_2.png", }, { id: 45822, username: "Vulkarin", avatar_template: "/user_avatar/devforum.roblox.com/vulkarin/{size}/1533760_2.png", }, { id: 100697, username: "ItzDaSniper_ALT", avatar_template: "/user_avatar/devforum.roblox.com/itzdasniper_alt/{size}/1111052_2.png", }, { id: 192817, username: "GeneralRelish", avatar_template: "/user_avatar/devforum.roblox.com/generalrelish/{size}/882303_2.png", }, { id: 3657, username: "Maxx_J", avatar_template: "/user_avatar/devforum.roblox.com/maxx_j/{size}/1257582_2.png", }, { id: 778, username: "gillern", avatar_template: "/user_avatar/devforum.roblox.com/gillern/{size}/1063851_2.png", }, { id: 5316, username: "unmiss", avatar_template: "/user_avatar/devforum.roblox.com/unmiss/{size}/1275904_2.png", }, { id: 230186, username: "overflowed", avatar_template: "/user_avatar/devforum.roblox.com/overflowed/{size}/1518666_2.png", }, { id: 119859, username: "kleptonaut", avatar_template: "/user_avatar/devforum.roblox.com/kleptonaut/{size}/1534225_2.png", }, { id: 222257, username: "ko_ch4", avatar_template: "/user_avatar/devforum.roblox.com/ko_ch4/{size}/1277003_2.png", }, { id: 96898, username: "Phoninian", avatar_template: "/user_avatar/devforum.roblox.com/phoninian/{size}/1505728_2.png", }, { id: 130, username: "zeuxcg", avatar_template: "/user_avatar/devforum.roblox.com/zeuxcg/{size}/759527_2.png", }, { id: 346894, username: "XOLT1268", avatar_template: "/user_avatar/devforum.roblox.com/xolt1268/{size}/1081693_2.png", }, { id: 223, username: "Dekkonot", avatar_template: "/user_avatar/devforum.roblox.com/dekkonot/{size}/1268788_2.png", }, { id: 431, username: "DataBrain", avatar_template: "/user_avatar/devforum.roblox.com/databrain/{size}/1346532_2.png", }, { id: 87089, username: "ForgotenR4", avatar_template: "/user_avatar/devforum.roblox.com/forgotenr4/{size}/993976_2.png", }, { id: 134567, username: "RoxyBloxyy", avatar_template: "/user_avatar/devforum.roblox.com/roxybloxyy/{size}/1063572_2.png", }, { id: 214043, username: "DavidNet22", avatar_template: "/user_avatar/devforum.roblox.com/davidnet22/{size}/1561725_2.png", }, { id: 393053, username: "jumbopushpop112", avatar_template: "/user_avatar/devforum.roblox.com/jumbopushpop112/{size}/1448545_2.png", }, { id: 9518, username: "jacklollz2", avatar_template: "/user_avatar/devforum.roblox.com/jacklollz2/{size}/1453855_2.png", }, { id: 34253, username: "incapaz", avatar_template: "/user_avatar/devforum.roblox.com/incapaz/{size}/1097885_2.png", }, { id: 32226, username: "Optikk", avatar_template: "/user_avatar/devforum.roblox.com/optikk/{size}/1515061_2.png", }, { id: 317122, username: "DoctorNO2106", avatar_template: "/user_avatar/devforum.roblox.com/doctorno2106/{size}/1439049_2.png", }, { id: 33762, username: "RuizuKun_Dev", avatar_template: "/user_avatar/devforum.roblox.com/ruizukun_dev/{size}/1587315_2.png", }, { id: 237547, username: "darkmodeonn", avatar_template: "/user_avatar/devforum.roblox.com/darkmodeonn/{size}/975957_2.png", }, { id: 1045, username: "WingItMan", avatar_template: "/user_avatar/devforum.roblox.com/wingitman/{size}/1288630_2.png", }, { id: 27530, username: "swmaniac", avatar_template: "/user_avatar/devforum.roblox.com/swmaniac/{size}/1054812_2.png", }, { id: 47029, username: "PH_OENlX", avatar_template: "/user_avatar/devforum.roblox.com/ph_oenlx/{size}/1462687_2.png", }, { id: 231587, username: "KrYn0MoRe", avatar_template: "/user_avatar/devforum.roblox.com/kryn0more/{size}/1347965_2.png", }, { id: 347486, username: "CanadianCrepe", avatar_template: "/user_avatar/devforum.roblox.com/canadiancrepe/{size}/1544739_2.png", }, { id: 416893, username: "FirewolfYT_751Adult", avatar_template: "/user_avatar/devforum.roblox.com/firewolfyt_751adult/{size}/1002940_2.png", }, { id: 33422, username: "nsgriff", avatar_template: "/user_avatar/devforum.roblox.com/nsgriff/{size}/648586_2.png", }, { id: -1, username: "system", avatar_template: "/user_avatar/devforum.roblox.com/system/{size}/278369_2.png", }, { id: 112950, username: "coefficients", avatar_template: "/user_avatar/devforum.roblox.com/coefficients/{size}/1344844_2.png", }, { id: 419793, username: "ORLANDOMAGIC00", avatar_template: "/user_avatar/devforum.roblox.com/orlandomagic00/{size}/1583711_2.png", }, { id: 57718, username: "rogchamp", avatar_template: "/user_avatar/devforum.roblox.com/rogchamp/{size}/1359144_2.png", }, { id: 3052, username: "ziplocBag", avatar_template: "/user_avatar/devforum.roblox.com/ziplocbag/{size}/909305_2.png", }, { id: 26244, username: "mxdanger", avatar_template: "/user_avatar/devforum.roblox.com/mxdanger/{size}/1457829_2.png", }, { id: 2791, username: "Dogutsune", avatar_template: "/user_avatar/devforum.roblox.com/dogutsune/{size}/1053710_2.png", }, { id: 431740, username: "TheSenorDuck", avatar_template: "/user_avatar/devforum.roblox.com/thesenorduck/{size}/933266_2.png", }, { id: 155602, username: "RobieTheCat", avatar_template: "/user_avatar/devforum.roblox.com/robiethecat/{size}/1572265_2.png", }, { id: 6350, username: "The_Aliens", avatar_template: "/user_avatar/devforum.roblox.com/the_aliens/{size}/1369228_2.png", }, { id: 8849, username: "lateregistration", avatar_template: "/user_avatar/devforum.roblox.com/lateregistration/{size}/964581_2.png", }, { id: 241899, username: "CringeEngineer", avatar_template: "/user_avatar/devforum.roblox.com/cringeengineer/{size}/1141949_2.png", }, { id: 789, username: "mothmage", avatar_template: "/user_avatar/devforum.roblox.com/mothmage/{size}/1387000_2.png", }, { id: 273497, username: "Voxelinator", avatar_template: "/user_avatar/devforum.roblox.com/voxelinator/{size}/1083723_2.png", }, { id: 120247, username: "MeaxisDev", avatar_template: "/user_avatar/devforum.roblox.com/meaxisdev/{size}/1454273_2.png", }, { id: 38549, username: "NickoSCP", avatar_template: "/user_avatar/devforum.roblox.com/nickoscp/{size}/1128258_2.png", }, { id: 139902, username: "LuukOriginal", avatar_template: "/user_avatar/devforum.roblox.com/luukoriginal/{size}/1314121_2.png", }, { id: 38606, username: "Homeomorph", avatar_template: "/user_avatar/devforum.roblox.com/homeomorph/{size}/1521085_2.png", }, { id: 31496, username: "Sentross", avatar_template: "/user_avatar/devforum.roblox.com/sentross/{size}/1485711_2.png", }, { id: 326221, username: "so1ehee", avatar_template: "/user_avatar/devforum.roblox.com/so1ehee/{size}/1494050_2.png", }, { id: 304229, username: "RawEggTheGreatIX", avatar_template: "/user_avatar/devforum.roblox.com/raweggthegreatix/{size}/1534316_2.png", }, { id: 357, username: "Plutonem", avatar_template: "/user_avatar/devforum.roblox.com/plutonem/{size}/1214626_2.png", }, { id: 281177, username: "meshadapt", avatar_template: "/user_avatar/devforum.roblox.com/meshadapt/{size}/1024879_2.png", }, { id: 1227, username: "Rocky28447", avatar_template: "/user_avatar/devforum.roblox.com/rocky28447/{size}/1025963_2.png", }, { id: 439104, username: "meblec", avatar_template: "/user_avatar/devforum.roblox.com/meblec/{size}/1582125_2.png", }, { id: 224996, username: "TheCrypticRunner", avatar_template: "/user_avatar/devforum.roblox.com/thecrypticrunner/{size}/1457066_2.png", }, { id: 92183, username: "Vasilakious", avatar_template: "/user_avatar/devforum.roblox.com/vasilakious/{size}/1117302_2.png", }, { id: 9593, username: "BanTech", avatar_template: "/user_avatar/devforum.roblox.com/bantech/{size}/1534999_2.png", }, { id: 7351, username: "Sublivion", avatar_template: "/user_avatar/devforum.roblox.com/sublivion/{size}/629555_2.png", }, { id: 643, username: "buildthomas", avatar_template: "/user_avatar/devforum.roblox.com/buildthomas/{size}/1146835_2.png", }, { id: 153142, username: "Blokhampster34", avatar_template: "/user_avatar/devforum.roblox.com/blokhampster34/{size}/1170235_2.png", }, { id: 86089, username: "Vmena", avatar_template: "/user_avatar/devforum.roblox.com/vmena/{size}/1155786_2.png", }, { id: 220864, username: "rogeriodec_games", avatar_template: "/user_avatar/devforum.roblox.com/rogeriodec_games/{size}/957129_2.png", }, { id: 186756, username: "Dummy_Tested", avatar_template: "/user_avatar/devforum.roblox.com/dummy_tested/{size}/399575_2.png", }, { id: 23710, username: "DarthChadius", avatar_template: "/user_avatar/devforum.roblox.com/darthchadius/{size}/734631_2.png", }, { id: 77150, username: "CAP7A1N", avatar_template: "/user_avatar/devforum.roblox.com/cap7a1n/{size}/1428937_2.png", }, { id: 306008, username: "Stelth155_Dev", avatar_template: "/user_avatar/devforum.roblox.com/stelth155_dev/{size}/1127802_2.png", }, { id: 103015, username: "Cruizer_Snowman", avatar_template: "/user_avatar/devforum.roblox.com/cruizer_snowman/{size}/1441731_2.png", }, { id: 210201, username: "vrtblox", avatar_template: "/user_avatar/devforum.roblox.com/vrtblox/{size}/580542_2.png", }, { id: 12817, username: "anon66957764", avatar_template: "https://www.roblox.com/headshot-thumbnail/image?userId=463253&width=150&height=150", }, { id: 380713, username: "Vargogram", avatar_template: "/user_avatar/devforum.roblox.com/vargogram/{size}/1475193_2.png", }, { id: 289807, username: "Crazedbrick1", avatar_template: "/user_avatar/devforum.roblox.com/crazedbrick1/{size}/1571206_2.png", }, { id: 10734, username: "CycloneUprising", avatar_template: "/user_avatar/devforum.roblox.com/cycloneuprising/{size}/1327682_2.png", }, { id: 363802, username: "Kairomatic", avatar_template: "/user_avatar/devforum.roblox.com/kairomatic/{size}/1482469_2.png", }, { id: 224243, username: "Eternalove_fan32", avatar_template: "/user_avatar/devforum.roblox.com/eternalove_fan32/{size}/1426044_2.png", }, { id: 84276, username: "Phlegethon5778", avatar_template: "/user_avatar/devforum.roblox.com/phlegethon5778/{size}/1232567_2.png", }, { id: 317063, username: "umpireboy", avatar_template: "/user_avatar/devforum.roblox.com/umpireboy/{size}/1418322_2.png", }, { id: 14154, username: "Hadiisepic", avatar_template: "/user_avatar/devforum.roblox.com/hadiisepic/{size}/1472103_2.png", }, { id: 202896, username: "vrs2210", avatar_template: "/user_avatar/devforum.roblox.com/vrs2210/{size}/1570268_2.png", }, { id: 201, username: "Khanovich", avatar_template: "/user_avatar/devforum.roblox.com/khanovich/{size}/540780_2.png", }, { id: 85229, username: "Oficcer_F", avatar_template: "/user_avatar/devforum.roblox.com/oficcer_f/{size}/1545789_2.png", }, { id: 186768, username: "Cald_fan", avatar_template: "/user_avatar/devforum.roblox.com/cald_fan/{size}/1561054_2.png", }, { id: 286481, username: "TheGreat_Scott", avatar_template: "/user_avatar/devforum.roblox.com/thegreat_scott/{size}/1350329_2.png", }, ], primary_groups: [ { id: 41, name: "Roblox_Staff", flair_url: "/uploads/default/original/4X/9/e/7/9e76ae2dd3aa25dc7a42e6443ec4cc57dd999ffe.png", flair_bg_color: "", flair_color: "", }, { id: 50, name: "DevRelationsTeam", flair_url: "/uploads/default/original/4X/9/e/7/9e76ae2dd3aa25dc7a42e6443ec4cc57dd999ffe.png", flair_bg_color: "", flair_color: "", }, ], topic_list: { can_create_topic: true, more_topics_url: "/tags/c/updates/announcements/36/studio?match_all_tags=true&page=1&tags%5B%5D=studio", draft: null, draft_key: "new_topic", draft_sequence: 1681, per_page: 30, top_tags: [ "studio", "physics", "scripting", "maintenance", "avatar", "beta", "accelerator", "building", "welds", "gui", "modeling", "wiki", "animation", "humanoid", "luau", "terrain", "api", "events", "intern", "internship", "motor6d", "r15", "smoothterrain", "accessories", "analytics", "animation-editor", "animations", "incubator", "rdc", "rendering", ], tags: [{ id: 68, name: "studio", topic_count: 7872, staff: false }], topics: [ { id: 1038853, title: "New Physics Stepping Method: Adaptive Timestepping", fancy_title: "New Physics Stepping Method: Adaptive Timestepping", slug: "new-physics-stepping-method-adaptive-timestepping", posts_count: 65, reply_count: 33, highest_post_number: 68, image_url: null, created_at: "2021-02-10T22:51:55.427Z", last_posted_at: "2021-02-16T20:18:25.918Z", bumped: true, bumped_at: "2021-02-18T03:52:19.710Z", archetype: "regular", unseen: false, last_read_post_number: 12, unread: 34, new_posts: 22, pinned: false, unpinned: null, visible: true, closed: false, archived: false, notification_level: 3, bookmarked: false, liked: false, tags: ["studio", "beta"], views: 15049, like_count: 663, has_summary: true, last_poster_username: "iSyriux", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 306443, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 36263, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 120450, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 472489, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: 44883, primary_group_id: null, }, ], }, { id: 1025033, title: "Heightmaps Go to New Altitudes!", fancy_title: "Heightmaps Go to New Altitudes!", slug: "heightmaps-go-to-new-altitudes", posts_count: 108, reply_count: 69, highest_post_number: 141, image_url: "https://doy2mn9upadnk.cloudfront.net/uploads/default/optimized/4X/0/c/c/0cca114c25efbe61d257c9580c3cd7413278b84d_2_1024x779.jpeg", created_at: "2021-02-04T18:31:29.269Z", last_posted_at: "2021-02-17T09:20:13.946Z", bumped: true, bumped_at: "2021-02-17T09:20:13.946Z", archetype: "regular", unseen: false, pinned: false, unpinned: null, visible: true, closed: false, archived: false, bookmarked: null, liked: null, tags: ["studio", "beta"], views: 16743, like_count: 1093, has_summary: true, last_poster_username: "Miles_1king", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 351893, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 376200, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 598293, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 249742, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: 557246, primary_group_id: null, }, ], }, { id: 1007452, title: 'Upcoming Potential Property Name Conflict: "Pivot"', fancy_title: "Upcoming Potential Property Name Conflict: “Pivot”", slug: "upcoming-potential-property-name-conflict-pivot", posts_count: 74, reply_count: 51, highest_post_number: 76, image_url: null, created_at: "2021-01-26T17:37:55.868Z", last_posted_at: "2021-02-11T19:12:41.189Z", bumped: true, bumped_at: "2021-02-11T19:12:41.189Z", archetype: "regular", unseen: false, last_read_post_number: 5, unread: 6, new_posts: 65, pinned: false, unpinned: null, visible: true, closed: false, archived: false, notification_level: 3, bookmarked: false, liked: false, tags: ["studio"], views: 16748, like_count: 490, has_summary: true, last_poster_username: "tnavarts", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: "latest", description: "Автор, Последний автор", user_id: 341046, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 164536, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 300, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 27022, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 11348, primary_group_id: null, }, ], }, { id: 993767, title: "Changing the Mac Studio Command Keycode: Control vs Meta", fancy_title: "Changing the Mac Studio Command Keycode: Control vs Meta", slug: "changing-the-mac-studio-command-keycode-control-vs-meta", posts_count: 16, reply_count: 5, highest_post_number: 17, image_url: null, created_at: "2021-01-19T22:05:17.218Z", last_posted_at: "2021-01-22T01:22:09.206Z", bumped: true, bumped_at: "2021-01-22T01:22:09.206Z", archetype: "regular", unseen: false, pinned: false, unpinned: null, visible: true, closed: false, archived: false, bookmarked: null, liked: null, tags: ["studio"], views: 14308, like_count: 166, has_summary: false, last_poster_username: "Optiplex3020SFF", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 350909, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 200305, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 176552, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 17304, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: 461567, primary_group_id: null, }, ], }, { id: 984141, title: "New Studio Beta: Attributes!", fancy_title: "New Studio Beta: Attributes!", slug: "new-studio-beta-attributes", posts_count: 353, reply_count: 140, highest_post_number: 372, image_url: "https://doy2mn9upadnk.cloudfront.net/uploads/default/original/4X/f/0/4/f04ea572324df16f6eb86f657ab0765c3b7c4779.png", created_at: "2021-01-14T23:57:24.805Z", last_posted_at: "2021-02-17T21:39:05.229Z", bumped: true, bumped_at: "2021-02-17T21:39:05.229Z", archetype: "regular", unseen: false, last_read_post_number: 30, unread: 314, new_posts: 28, pinned: false, unpinned: null, visible: true, closed: false, archived: false, notification_level: 3, bookmarked: false, liked: false, tags: ["studio", "beta"], views: 36468, like_count: 1942, has_summary: true, last_poster_username: "Fire540Games", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 260389, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 11348, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 163116, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 396736, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: 105134, primary_group_id: null, }, ], }, { id: 932576, title: "New Terrain, and Parts, and Built-In Materials, Oh my!", fancy_title: "New Terrain, and Parts, and Built-In Materials, Oh my!", slug: "new-terrain-and-parts-and-built-in-materials-oh-my", posts_count: 1155, reply_count: 358, highest_post_number: 1341, image_url: "https://doy2mn9upadnk.cloudfront.net/uploads/default/optimized/4X/5/2/2/52240686713d0ec0b1b9ab802268030a8cb15627_2_1024x420.jpeg", created_at: "2020-12-19T00:22:20.801Z", last_posted_at: "2021-02-17T22:45:44.156Z", bumped: true, bumped_at: "2021-02-17T22:45:44.156Z", archetype: "regular", unseen: false, last_read_post_number: 20, unread: 849, new_posts: 472, pinned: false, unpinned: null, visible: true, closed: false, archived: false, notification_level: 3, bookmarked: false, liked: false, tags: ["studio", "beta"], views: 100027, like_count: 7467, has_summary: true, last_poster_username: "ittrgrey", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 17941, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 395244, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 351579, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 194130, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: 7289, primary_group_id: null, }, ], }, { id: 919991, title: "Proximity Prompt Release", fancy_title: "Proximity Prompt Release", slug: "proximity-prompt-release", posts_count: 161, reply_count: 96, highest_post_number: 228, image_url: "https://doy2mn9upadnk.cloudfront.net/uploads/default/original/4X/5/a/8/5a8617595bc32d070053437b78e722f12f01e78a.gif", created_at: "2020-12-12T02:06:19.525Z", last_posted_at: "2021-02-16T02:45:15.238Z", bumped: true, bumped_at: "2021-02-16T02:45:15.238Z", archetype: "regular", unseen: false, last_read_post_number: 205, unread: 22, new_posts: 1, pinned: false, unpinned: null, visible: true, closed: false, archived: false, notification_level: 3, bookmarked: false, liked: false, tags: ["studio"], views: 33224, like_count: 941, has_summary: true, last_poster_username: "Miles_1king", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 350909, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 451394, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 312723, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 51619, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: 557246, primary_group_id: null, }, ], }, { id: 904022, title: "Asset Manager Phased Rollout", fancy_title: "Asset Manager Phased Rollout", slug: "asset-manager-phased-rollout", posts_count: 75, reply_count: 42, highest_post_number: 82, image_url: null, created_at: "2020-12-03T19:15:44.962Z", last_posted_at: "2021-02-13T04:08:21.822Z", bumped: true, bumped_at: "2021-02-13T04:08:21.822Z", archetype: "regular", unseen: false, last_read_post_number: 17, unread: 0, new_posts: 65, pinned: false, unpinned: null, visible: true, closed: false, archived: false, notification_level: 3, bookmarked: false, liked: false, tags: ["studio", "beta"], views: 20262, like_count: 339, has_summary: true, last_poster_username: "ItzDaSniper_ALT", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 285060, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 417018, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 32451, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 45822, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: 100697, primary_group_id: null, }, ], }, { id: 898436, title: "Expressive Output Window - Phased Rollout", fancy_title: "Expressive Output Window - Phased Rollout", slug: "expressive-output-window-phased-rollout", posts_count: 35, reply_count: 9, highest_post_number: 38, image_url: null, created_at: "2020-11-30T21:14:57.519Z", last_posted_at: "2021-02-09T02:19:01.395Z", bumped: true, bumped_at: "2021-02-09T02:19:01.395Z", archetype: "regular", unseen: false, last_read_post_number: 1, unread: 0, new_posts: 37, pinned: false, unpinned: null, visible: true, closed: false, archived: false, notification_level: 3, bookmarked: false, liked: false, tags: ["studio", "beta", "output-window", "output"], views: 11811, like_count: 255, has_summary: false, last_poster_username: "overflowed", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 192817, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 3657, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 778, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 5316, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: 230186, primary_group_id: null, }, ], }, { id: 897999, title: "[Activated!] New Part Physics API", fancy_title: "[Activated!] New Part Physics API", slug: "activated-new-part-physics-api", posts_count: 80, reply_count: 43, highest_post_number: 83, image_url: null, created_at: "2020-11-30T18:30:16.161Z", last_posted_at: "2021-02-08T20:31:36.781Z", bumped: true, bumped_at: "2021-02-08T20:31:36.781Z", archetype: "regular", unseen: false, last_read_post_number: 33, unread: 0, new_posts: 50, pinned: false, unpinned: null, visible: true, closed: false, archived: false, notification_level: 3, bookmarked: false, liked: false, tags: ["studio", "physics"], views: 15373, like_count: 456, has_summary: true, last_poster_username: "Phoninian", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: true, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 119859, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 341046, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 222257, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 36263, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: 96898, primary_group_id: null, }, ], }, { id: 878947, title: "Luau Type Checking Release", fancy_title: "Luau Type Checking Release", slug: "luau-type-checking-release", posts_count: 130, reply_count: 51, highest_post_number: 135, image_url: "https://doy2mn9upadnk.cloudfront.net/uploads/default/original/4X/1/0/b/10b42bc7cc1bef0f79f6a79415c8a87435edf0c1.png", created_at: "2020-11-19T18:21:13.701Z", last_posted_at: "2021-02-09T20:39:33.667Z", bumped: true, bumped_at: "2021-02-09T20:39:33.667Z", archetype: "regular", unseen: false, pinned: false, unpinned: null, visible: true, closed: false, archived: false, bookmarked: null, liked: null, tags: ["scripting", "studio", "luau"], views: 15216, like_count: 507, has_summary: true, last_poster_username: "zeuxcg", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: "latest", description: "Автор, Последний автор", user_id: 130, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 346894, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 223, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 431, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 87089, primary_group_id: null, }, ], }, { id: 877873, title: "Introducing Bulk Audio Importing in Studio!", fancy_title: "Introducing Bulk Audio Importing in Studio!", slug: "introducing-bulk-audio-importing-in-studio", posts_count: 55, reply_count: 19, highest_post_number: 60, image_url: "https://doy2mn9upadnk.cloudfront.net/uploads/default/original/4X/e/f/b/efbc663dd66369ccc18459d2ec642cc45cff3414.png", created_at: "2020-11-19T00:00:47.997Z", last_posted_at: "2021-02-07T00:36:38.741Z", bumped: true, bumped_at: "2021-02-07T00:36:38.741Z", archetype: "regular", unseen: false, pinned: false, unpinned: null, visible: true, closed: false, archived: false, bookmarked: null, liked: null, tags: ["studio"], views: 13730, like_count: 562, has_summary: true, last_poster_username: "jacklollz2", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 134567, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 214043, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 451394, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 393053, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: 9518, primary_group_id: null, }, ], }, { id: 877312, title: "Introducing Plugin Script Modification Permissions", fancy_title: "Introducing Plugin Script Modification Permissions", slug: "introducing-plugin-script-modification-permissions", posts_count: 76, reply_count: 28, highest_post_number: 86, image_url: "https://doy2mn9upadnk.cloudfront.net/uploads/default/optimized/4X/5/a/6/5a645ea86f19c66297c1b763bf4e77541d5ed8ca_2_1024x401.png", created_at: "2020-11-18T18:26:04.109Z", last_posted_at: "2021-01-15T23:17:58.252Z", bumped: true, bumped_at: "2021-01-15T23:17:58.252Z", archetype: "regular", unseen: false, pinned: false, unpinned: null, visible: true, closed: false, archived: false, bookmarked: null, liked: null, tags: ["studio"], views: 11452, like_count: 422, has_summary: true, last_poster_username: "RuizuKun_Dev", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 134567, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 34253, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 32226, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 317122, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: 33762, primary_group_id: null, }, ], }, { id: 874260, title: "Script Editor - Semantic Highlighting and Temporary Tabs are now in Beta!", fancy_title: "Script Editor - Semantic Highlighting and Temporary Tabs are now in Beta!", slug: "script-editor-semantic-highlighting-and-temporary-tabs-are-now-in-beta", posts_count: 201, reply_count: 99, highest_post_number: 205, image_url: "https://doy2mn9upadnk.cloudfront.net/uploads/default/optimized/4X/5/d/c/5dce483b91353355e69c03ffd023388cfbbbeca2_2_1024x526.jpeg", created_at: "2020-11-16T21:18:47.223Z", last_posted_at: "2021-02-07T08:17:42.638Z", bumped: true, bumped_at: "2021-02-07T08:17:42.638Z", archetype: "regular", unseen: false, pinned: false, unpinned: null, visible: true, closed: false, archived: false, bookmarked: null, liked: null, tags: ["studio", "beta"], views: 13036, like_count: 1056, has_summary: true, last_poster_username: "KrYn0MoRe", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 237547, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 1045, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 27530, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 47029, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: 231587, primary_group_id: null, }, ], }, { id: 744534, title: "Studio is Ending Support for Mac OS X 10.10 (Yosemite)", fancy_title: "Studio is Ending Support for Mac OS X 10.10 (Yosemite)", slug: "studio-is-ending-support-for-mac-os-x-10-10-yosemite", posts_count: 66, reply_count: 31, highest_post_number: 76, image_url: null, created_at: "2020-08-31T17:34:00.000Z", last_posted_at: "2021-01-26T22:14:45.165Z", bumped: true, bumped_at: "2020-09-28T22:14:43.451Z", archetype: "regular", unseen: false, pinned: false, unpinned: null, visible: true, closed: true, archived: false, bookmarked: null, liked: null, tags: ["studio"], views: 50641, like_count: 451, has_summary: true, last_poster_username: "system", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 285060, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 347486, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 416893, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 33422, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: -1, primary_group_id: null, }, ], }, { id: 746146, title: "Display All Permissions for Group Games", fancy_title: "Display All Permissions for Group Games", slug: "display-all-permissions-for-group-games", posts_count: 12, reply_count: 8, highest_post_number: 20, image_url: null, created_at: "2020-08-28T17:31:49.301Z", last_posted_at: "2021-01-22T17:15:00.609Z", bumped: true, bumped_at: "2020-09-24T17:15:00.254Z", archetype: "regular", unseen: false, last_read_post_number: 20, unread: 0, new_posts: 0, pinned: false, unpinned: null, visible: true, closed: true, archived: false, notification_level: 3, bookmarked: false, liked: false, tags: ["studio"], views: 43683, like_count: 251, has_summary: false, last_poster_username: "coefficients", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: "latest", description: "Автор, Последний автор", user_id: 112950, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 419793, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 57718, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 3052, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 26244, primary_group_id: null, }, ], }, { id: 722215, title: "Finale of Part Surface Changes: No More Hinges", fancy_title: "Finale of Part Surface Changes: No More Hinges", slug: "finale-of-part-surface-changes-no-more-hinges", posts_count: 133, reply_count: 67, highest_post_number: 143, image_url: "https://doy2mn9upadnk.cloudfront.net/uploads/default/original/4X/d/9/b/d9bdfde1668446e0037867a9dcbd49dcc685b7eb.gif", created_at: "2020-08-13T18:09:27.690Z", last_posted_at: "2020-12-08T19:04:09.193Z", bumped: true, bumped_at: "2020-12-08T19:04:09.193Z", archetype: "regular", unseen: false, pinned: false, unpinned: null, visible: true, closed: false, archived: false, bookmarked: null, liked: null, tags: ["building", "studio", "physics"], views: 25124, like_count: 885, has_summary: true, last_poster_username: "TheSenorDuck", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 119859, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 2791, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 11348, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 341046, primary_group_id: 41, }, { extras: "latest", description: "Последний автор", user_id: 431740, primary_group_id: null, }, ], }, { id: 705528, title: "Skinned MeshPart Studio Beta", fancy_title: "Skinned MeshPart Studio Beta", slug: "skinned-meshpart-studio-beta", posts_count: 345, reply_count: 207, highest_post_number: 358, image_url: "https://doy2mn9upadnk.cloudfront.net/uploads/default/original/4X/a/8/7/a8786999b226cbb244060442b7e3fc04154267ae.png", created_at: "2020-08-03T22:59:46.002Z", last_posted_at: "2020-12-02T00:04:48.733Z", bumped: true, bumped_at: "2020-12-01T21:30:40.306Z", archetype: "regular", unseen: false, pinned: false, unpinned: null, visible: true, closed: true, archived: false, bookmarked: null, liked: null, tags: ["studio", "modeling", "rendering"], views: 49892, like_count: 2218, has_summary: true, last_poster_username: "mothmage", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 155602, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 6350, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 8849, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 241899, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: 789, primary_group_id: null, }, ], }, { id: 674209, title: "Introducing Two Game Security Settings: Third Party Sales & Cross Game Teleports", fancy_title: "Introducing Two Game Security Settings: Third Party Sales & Cross Game Teleports", slug: "introducing-two-game-security-settings-third-party-sales-cross-game-teleports", posts_count: 100, reply_count: 28, highest_post_number: 120, image_url: "https://doy2mn9upadnk.cloudfront.net/uploads/default/original/4X/0/c/7/0c776e4648a634d0c17287869c13fbdb790f7f36.png", created_at: "2020-07-16T00:43:28.114Z", last_posted_at: "2020-11-11T21:06:01.454Z", bumped: true, bumped_at: "2021-01-22T16:14:45.381Z", archetype: "regular", unseen: false, pinned: false, unpinned: null, visible: true, closed: false, archived: false, bookmarked: null, liked: null, tags: ["studio"], views: 33642, like_count: 735, has_summary: true, last_poster_username: "LuukOriginal", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 134567, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 273497, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 120247, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 38549, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: 139902, primary_group_id: null, }, ], }, { id: 663449, title: "SurfaceAppearance Studio Beta", fancy_title: "SurfaceAppearance Studio Beta", slug: "surfaceappearance-studio-beta", posts_count: 415, reply_count: 186, highest_post_number: 437, image_url: "https://doy2mn9upadnk.cloudfront.net/uploads/default/original/4X/5/f/c/5fca97d93e86876dbb3ee5bd2adfa3b5f699bcfd.png", created_at: "2020-07-09T18:58:00.000Z", last_posted_at: "2021-02-15T21:51:59.958Z", bumped: true, bumped_at: "2021-02-15T21:51:59.958Z", archetype: "regular", unseen: false, last_read_post_number: 43, unread: 55, new_posts: 339, pinned: false, unpinned: null, visible: true, closed: false, archived: false, notification_level: 3, bookmarked: false, liked: false, tags: ["studio"], views: 68064, like_count: 4562, has_summary: true, last_poster_username: "Plutonem", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 38606, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 31496, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 326221, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 304229, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: 357, primary_group_id: null, }, ], }, { id: 662464, title: "New Beta Feature: LevelOfDetail Property for Models (Enabled Globally)", fancy_title: "New Beta Feature: LevelOfDetail Property for Models (Enabled Globally)", slug: "new-beta-feature-levelofdetail-property-for-models-enabled-globally", posts_count: 51, reply_count: 18, highest_post_number: 52, image_url: "https://doy2mn9upadnk.cloudfront.net/uploads/default/original/4X/d/e/b/deb938a882c680f766fa49d5a3b8a16f2e56b39f.png", created_at: "2020-07-08T05:12:01.996Z", last_posted_at: "2021-01-06T09:49:20.839Z", bumped: true, bumped_at: "2021-01-06T09:49:20.839Z", archetype: "regular", unseen: false, pinned: false, unpinned: null, visible: true, closed: false, archived: false, bookmarked: null, liked: null, tags: ["studio", "modeling", "rendering", "networking"], views: 11907, like_count: 502, has_summary: true, last_poster_username: "Vasilakious", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 281177, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 1227, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 439104, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 224996, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: 92183, primary_group_id: null, }, ], }, { id: 644467, title: "New RaycastParams Property, Deprecating Old Raycast Functions", fancy_title: "New RaycastParams Property, Deprecating Old Raycast Functions", slug: "new-raycastparams-property-deprecating-old-raycast-functions", posts_count: 91, reply_count: 53, highest_post_number: 95, image_url: "https://doy2mn9upadnk.cloudfront.net/uploads/default/original/4X/d/3/2/d32b1ab64c2f0a4da24ffbe7450e8c6b251010f6.png", created_at: "2020-06-26T00:21:46.173Z", last_posted_at: "2021-01-01T22:29:39.110Z", bumped: true, bumped_at: "2021-01-01T21:59:42.756Z", archetype: "regular", unseen: false, pinned: false, unpinned: null, visible: true, closed: true, archived: false, bookmarked: null, liked: null, tags: ["studio", "physics"], views: 13036, like_count: 396, has_summary: true, last_poster_username: "buildthomas", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 119859, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 431, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 9593, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 7351, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: 643, primary_group_id: null, }, ], }, { id: 642684, title: "Expressive Output Window - Beta", fancy_title: "Expressive Output Window - Beta", slug: "expressive-output-window-beta", posts_count: 153, reply_count: 44, highest_post_number: 170, image_url: null, created_at: "2020-06-25T19:30:00.000Z", last_posted_at: "2020-12-05T18:24:48.359Z", bumped: true, bumped_at: "2020-12-05T18:32:03.488Z", archetype: "regular", unseen: false, last_read_post_number: 107, unread: 0, new_posts: 63, pinned: false, unpinned: null, visible: true, closed: false, archived: false, notification_level: 3, bookmarked: false, liked: false, tags: ["studio", "output-window"], views: 23650, like_count: 1181, has_summary: true, last_poster_username: "Dummy_Tested", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 192817, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 153142, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 86089, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 220864, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: 186756, primary_group_id: null, }, ], }, { id: 643907, title: "Universal Breakpoints Beta - One Breakpoint to Rule Them All", fancy_title: "Universal Breakpoints Beta - One Breakpoint to Rule Them All", slug: "universal-breakpoints-beta-one-breakpoint-to-rule-them-all", posts_count: 18, reply_count: 3, highest_post_number: 21, image_url: null, created_at: "2020-06-25T18:28:25.069Z", last_posted_at: "2020-11-26T15:43:44.683Z", bumped: true, bumped_at: "2020-07-29T15:43:43.770Z", archetype: "regular", unseen: false, pinned: false, unpinned: null, visible: true, closed: true, archived: false, bookmarked: null, liked: null, tags: ["studio", "debugger"], views: 11147, like_count: 140, has_summary: false, last_poster_username: "system", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 192817, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 112950, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 120247, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 23710, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: -1, primary_group_id: null, }, ], }, { id: 642282, title: "Additional Game Management in Roblox Studio", fancy_title: "Additional Game Management in Roblox Studio", slug: "additional-game-management-in-roblox-studio", posts_count: 88, reply_count: 21, highest_post_number: 92, image_url: "https://doy2mn9upadnk.cloudfront.net/uploads/default/optimized/4X/e/2/4/e24da11e138f564733aabacad3558b95a720830c_2_1023x638.png", created_at: "2020-06-24T23:21:00.000Z", last_posted_at: "2020-12-22T12:36:54.093Z", bumped: true, bumped_at: "2020-08-24T12:36:47.186Z", archetype: "regular", unseen: false, last_read_post_number: 82, unread: 2, new_posts: 8, pinned: false, unpinned: null, visible: true, closed: true, archived: false, notification_level: 3, bookmarked: false, liked: false, tags: ["studio"], views: 12540, like_count: 421, has_summary: true, last_poster_username: "system", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: true, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 33422, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 77150, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 306008, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 103015, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: -1, primary_group_id: null, }, ], }, { id: 639903, title: "Future Is Bright: Phase 3 - Studio Beta", fancy_title: "Future Is Bright: Phase 3 - Studio Beta", slug: "future-is-bright-phase-3-studio-beta", posts_count: 1160, reply_count: 657, highest_post_number: 1233, image_url: "https://doy2mn9upadnk.cloudfront.net/uploads/default/original/4X/e/6/4/e643cf506a8ac153c7720bab4af414a88eaf0a9a.png", created_at: "2020-06-23T09:13:23.197Z", last_posted_at: "2021-02-04T17:43:41.911Z", bumped: true, bumped_at: "2021-02-04T17:43:41.911Z", archetype: "regular", unseen: false, pinned: false, unpinned: null, visible: true, closed: false, archived: false, bookmarked: null, liked: null, tags: ["building", "studio"], views: 97604, like_count: 12547, has_summary: true, last_poster_username: "DoctorNO2106", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 210201, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 12817, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 380713, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 289807, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: 317122, primary_group_id: null, }, ], }, { id: 623350, title: "Plugin Debugging: New Beta Feature!", fancy_title: "Plugin Debugging: New Beta Feature!", slug: "plugin-debugging-new-beta-feature", posts_count: 42, reply_count: 13, highest_post_number: 42, image_url: null, created_at: "2020-06-12T22:29:13.391Z", last_posted_at: "2020-12-18T17:38:25.942Z", bumped: true, bumped_at: "2021-02-13T17:57:38.712Z", archetype: "regular", unseen: false, last_read_post_number: 6, unread: 36, new_posts: 0, pinned: false, unpinned: null, visible: true, closed: false, archived: false, notification_level: 3, bookmarked: false, liked: false, tags: ["studio"], views: 12535, like_count: 287, has_summary: false, last_poster_username: "Eternalove_fan32", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 10734, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 363802, primary_group_id: 50, }, { extras: null, description: "Частый автор", user_id: 341046, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 223, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: 224243, primary_group_id: null, }, ], }, { id: 582921, title: "Script Editor - New Foundation and First Features", fancy_title: "Script Editor - New Foundation and First Features", slug: "script-editor-new-foundation-and-first-features", posts_count: 104, reply_count: 42, highest_post_number: 106, image_url: "https://doy2mn9upadnk.cloudfront.net/uploads/default/original/4X/1/9/1/191215aedf29cd0902640dcd2faffcdcfe1faeda.jpeg", created_at: "2020-06-11T18:09:00.000Z", last_posted_at: "2020-11-18T13:40:56.854Z", bumped: true, bumped_at: "2020-07-21T13:40:56.784Z", archetype: "regular", unseen: false, last_read_post_number: 6, unread: 94, new_posts: 6, pinned: false, unpinned: null, visible: true, closed: true, archived: false, notification_level: 3, bookmarked: false, liked: false, tags: ["studio", "script-editor"], views: 23750, like_count: 602, has_summary: true, last_poster_username: "system", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 192817, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 778, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 12817, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 84276, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: -1, primary_group_id: null, }, ], }, { id: 552810, title: "Introducing SmoothingAngle property for PartOperation (Enabled Globally)", fancy_title: "Introducing SmoothingAngle property for PartOperation (Enabled Globally)", slug: "introducing-smoothingangle-property-for-partoperation-enabled-globally", posts_count: 103, reply_count: 33, highest_post_number: 106, image_url: "https://doy2mn9upadnk.cloudfront.net/uploads/default/original/4X/0/7/c/07c3ad00b386afbf9cc8924d69c86bceecfe003c.png", created_at: "2020-05-06T21:42:00.000Z", last_posted_at: "2020-09-09T11:12:18.309Z", bumped: true, bumped_at: "2020-08-04T18:46:27.868Z", archetype: "regular", unseen: false, pinned: false, unpinned: null, visible: true, closed: true, archived: false, bookmarked: null, liked: null, tags: ["studio", "csg", "csgv2"], views: 36298, like_count: 855, has_summary: true, last_poster_username: "system", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 281177, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 317063, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 14154, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 202896, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: -1, primary_group_id: null, }, ], }, { id: 529077, title: "New Studio Feature - CollisionFidelity.PreciseConvexDecomposition (Enabled Globally)", fancy_title: "New Studio Feature - CollisionFidelity.PreciseConvexDecomposition (Enabled Globally)", slug: "new-studio-feature-collisionfidelity-preciseconvexdecomposition-enabled-globally", posts_count: 140, reply_count: 59, highest_post_number: 146, image_url: "https://doy2mn9upadnk.cloudfront.net/uploads/default/original/4X/1/f/d/1fd823f35f415e8e12eee67d842f70f638f38c5a.png", created_at: "2020-04-17T14:59:53.209Z", last_posted_at: "2021-01-03T23:10:39.815Z", bumped: true, bumped_at: "2021-01-03T23:14:21.658Z", archetype: "regular", unseen: false, last_read_post_number: 2, unread: 136, new_posts: 8, pinned: false, unpinned: null, visible: true, closed: false, archived: false, notification_level: 3, bookmarked: false, liked: false, tags: ["studio"], views: 50555, like_count: 862, has_summary: true, last_poster_username: "TheGreat_Scott", category_id: 36, pinned_globally: false, featured_link: null, has_accepted_answer: false, vote_count: 0, can_vote: false, user_voted: false, posters: [ { extras: null, description: "Автор", user_id: 201, primary_group_id: 41, }, { extras: null, description: "Частый автор", user_id: 300, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 85229, primary_group_id: null, }, { extras: null, description: "Частый автор", user_id: 186768, primary_group_id: null, }, { extras: "latest", description: "Последний автор", user_id: 286481, primary_group_id: null, }, ], }, ], }, }) }) app.get("/my/settings/json", (req, res) => { res.json({ PreviousUserNames: "", UserId: 1, Name: "df", UseSuperSafePrivacyMode: false, IsSuperSafeModeEnabledForPrivacySetting: false, UseSuperSafeChat: false, IsAppChatSettingEnabled: true, IsGameChatSettingEnabled: true, IsAccountPrivacySettingsV2Enabled: true, IsSetPasswordNotificationEnabled: false, ChangePasswordRequiresTwoStepVerification: false, ChangeEmailRequiresTwoStepVerification: false, UserEmail: "", IsEmailOnFile: false, UserEmailMasked: true, IsEmailVerified: false, UserEmailVerified: false, CanHideInventory: false, CanTrade: false, MissingParentEmail: false, IsUpdateEmailSectionShown: false, IsUnder13UpdateEmailMessageSectionShown: false, IsUserConnectedToFacebook: false, IsTwoStepToggleEnabled: false, AgeBracket: 0, UserAbove13: true, ClientIpAddress: "123.123.123.123", AccountAgeInDays: 0, IsOBC: false, IsTBC: false, IsAnyBC: false, IsPremium: false, IsBcRenewalMembership: false, BcExpireDate: "/Date(-0)/", BcRenewalPeriod: null, BcLevel: null, HasCurrencyOperationError: false, CurrencyOperationErrorMessage: null, BlockedUsersModel: { BlockedUserIds: [], BlockedUsers: [], MaxBlockedUsers: 50, Total: 1, Page: 1, }, Tab: null, ChangePassword: false, IsAccountPinEnabled: false, IsAccountRestrictionsFeatureEnabled: true, IsAccountRestrictionsSettingEnabled: false, IsAccountSettingsSocialNetworksV2Enabled: false, IsUiBootstrapModalV2Enabled: true, IsI18nBirthdayPickerInAccountSettingsEnabled: true, InApp: false, MyAccountSecurityModel: { IsEmailSet: false, IsEmailVerified: false, IsTwoStepEnabled: false, ShowSignOutFromAllSessions: true, TwoStepVerificationViewModel: { UserId: 1, IsEnabled: true, CodeLength: 0, ValidCodeCharacters: null, }, }, ApiProxyDomain: "https://www.mete0r.xyz", AccountSettingsApiDomain: "https://www.mete0r.xyz", AuthDomain: "https://www.mete0r.xyz", IsDisconnectFbSocialSignOnEnabled: true, IsDisconnectXboxEnabled: true, NotificationSettingsDomain: "https://www.mete0r.xyz", AllowedNotificationSourceTypes: [ "Test", "FriendRequestReceived", "FriendRequestAccepted", "PartyInviteReceived", "PartyMemberJoined", "ChatNewMessage", "PrivateMessageReceived", "UserAddedToPrivateServerWhiteList", "ConversationUniverseChanged", "TeamCreateInvite", "GameUpdate", "DeveloperMetricsAvailable", ], AllowedReceiverDestinationTypes: ["DesktopPush", "NotificationStream"], BlacklistedNotificationSourceTypesForMobilePush: [], MinimumChromeVersionForPushNotifications: 50, PushNotificationsEnabledOnFirefox: true, LocaleApiDomain: "https://www.mete0r.xyz", HasValidPasswordSet: true, IsUpdateEmailApiEndpointEnabled: true, FastTrackMember: null, IsFastTrackAccessible: false, HasFreeNameChange: false, IsAgeDownEnabled: true, IsSendVerifyEmailApiEndpointEnabled: true, IsPromotionChannelsEndpointEnabled: true, ReceiveNewsletter: false, SocialNetworksVisibilityPrivacy: 6, SocialNetworksVisibilityPrivacyValue: "AllUsers", Facebook: null, Twitter: null, YouTube: null, Twitch: null, }) }) const userinfoClient = require("./routes/userinfoclient.js") app.use("/", userinfoClient) app.get("/metrics", async (req, res) => { res.set("Content-Type", client.register.contentType) res.end(await client.register.metrics()) }) app.disable("etag") app.get("/currency/balance", requireAuth, (req, res) => { return res.json({ robux: req.userdocument.coins, tickets: 0, }) }) app.post("/device/initialize", (req, res) => { return res.json({ browserTrackerId: 1, appDeviceIdentifier: null }) }) app.post("/login/v1/", (req, res) => { return res.json({ userId: "12345", }) }) app.get("/my/account/json", (req, res) => { return res.json({ AgeBracket: 0, Email: { IsVerified: 1, Value: "kmulherin@roblox.com", }, HasPasswordSet: 1, Username: "iMightBeLying", }) }) app.get("/ab/v1/enroll", (req, res) => { return res.json({ baller: "baller" }) }) app.get("/GetAllowedMD5Hashes", (req, res) => { return res.json({ data: [ "7ede9e9841e46b0538c3b684d979f759", "268b4bb9ffcc0586cc13fbbb3e4de16f", ], }) }) app.get("/GetAllowedSecurityVersions", (req, res) => { return res.json({ data: ["0.347.0pcplayer"] }) }) app.get("/asset-thumbnail/json", (req, res) => { return res.json({ Url: "https://mete0r.xyz/assets/images/lol.png", Final: true, SubstitutionType: 0, }) }) app.get("/avatar-thumbnail/json", (req, res) => { return res.json({ Url: "https://mete0r.xyz/api/thumbnailrender/?id=" + req.query.userId, Final: true, SubstitutionType: 0, }) }) app.get("/v1.1/avatar-fetch", async (req, res) => { // 2018 charapp //console.log(req.headers) const userid = req.query?.userId const placeId = req.query?.placeId ?? 0 const doc = await user.findOne({ userid: userid }) const placedoc = await games.findOne({ idofgame: placeId }) if (!doc) { return res.json({ status: "error", error: "User not found." }) } if (!placedoc) { return res.json({ status: "error", error: "Place not found." }) } //console.log(doc.colors) let json = { resolvedAvatarType: doc.avatartype ?? "R6", accessoryVersionIds: [], equippedGearVersionIds: [], backpackGearVersionIds: [], bodyColors: { HeadColor: parseFloat( doc.colors.find(x => x.name === "Head").value, ), LeftArmColor: parseFloat( doc.colors.find(x => x.name === "Left Arm").value, ), LeftLegColor: parseFloat( doc.colors.find(x => x.name === "Left Leg").value, ), RightArmColor: parseFloat( doc.colors.find(x => x.name === "Right Arm").value, ), RightLegColor: parseFloat( doc.colors.find(x => x.name === "Right Leg").value, ), TorsoColor: parseFloat( doc.colors.find(x => x.name === "Torso").value, ), }, animations: {}, scales: { Width: 1.0, Height: 1.0, Head: 1.0, Depth: 1.0, Proportion: 0.0, BodyType: 0.0, }, } if (!doc.inventory) { return res.json(json) } for (var key of doc.inventory) { if (key.Equipped === true) { if (placedoc.gearallowed ?? false === true) { json.accessoryVersionIds.push(parseFloat(key.ItemId)) } else { if (key.Type != "Gears") { json.accessoryVersionIds.push(parseFloat(key.ItemId)) } } } } //console.log(json.accessoryVersionIds) return res.json(json) }) app.get("/v1/avatar-fetch", async (req, res) => { // 2020 charapp //console.log(req.headers) const userid = req.query?.userId const placeId = req.query?.placeId ?? 0 const doc = await user.findOne({ userid: userid }) const placedoc = await games.findOne({ idofgame: placeId }) if (!doc) { return res.json({ status: "error", error: "User not found." }) } if (!placedoc) { return res.json({ status: "error", error: "Place not found." }) } if (req.headers?.["roblox-game-id"] === "render") { // 2020 render needs v1.1 colors let json = { resolvedAvatarType: doc.avatartype ?? "R6", accessoryVersionIds: [], equippedGearVersionIds: [], backpackGearVersionIds: [], bodyColors: { HeadColor: parseFloat( doc.colors.find(x => x.name === "Head").value, ), LeftArmColor: parseFloat( doc.colors.find(x => x.name === "Left Arm").value, ), LeftLegColor: parseFloat( doc.colors.find(x => x.name === "Left Leg").value, ), RightArmColor: parseFloat( doc.colors.find(x => x.name === "Right Arm").value, ), RightLegColor: parseFloat( doc.colors.find(x => x.name === "Right Leg").value, ), TorsoColor: parseFloat( doc.colors.find(x => x.name === "Torso").value, ), }, animations: {}, scales: { Width: 1.0, Height: 1.0, Head: 1.0, Depth: 1.0, Proportion: 0.0, BodyType: 0.0, }, } if (!doc.inventory) { return res.json(json) } for (var key of doc.inventory) { if (key.Equipped === true) { json.accessoryVersionIds.push(parseFloat(key.ItemId)) } } //console.log(json.accessoryVersionIds) return res.json(json) } //console.log(doc.colors) let json = { resolvedAvatarType: doc.avatartype ?? "R6", assetAndAssetTypeIds: [], equippedGearVersionIds: [], backpackGearVersionIds: [], bodyColors: { headColorId: parseFloat( doc.colors.find(x => x.name === "Head").value, ), leftArmColorId: parseFloat( doc.colors.find(x => x.name === "Left Arm").value, ), leftLegColorId: parseFloat( doc.colors.find(x => x.name === "Left Leg").value, ), rightArmColorId: parseFloat( doc.colors.find(x => x.name === "Right Arm").value, ), rightLegColorId: parseFloat( doc.colors.find(x => x.name === "Right Leg").value, ), torsoColorId: parseFloat( doc.colors.find(x => x.name === "Torso").value, ), }, animations: {}, scales: { Width: 1.0, Height: 1.0, Head: 1.0, Depth: 1.0, Proportion: 0.0, BodyType: 0.0, }, emotes: [], } if (!doc.inventory) { return res.json(json) } let currentEmotePosition = 1 for (var key of doc.inventory) { if (key.Equipped === true) { if (key.Type === "Emotes" && currentEmotePosition <= 8) { json.emotes.push({ assetId: parseFloat(key.ItemId), assetName: key.ItemName, position: currentEmotePosition, }) currentEmotePosition += 1 } let gearallowed = placedoc.gearallowed ?? false if (gearallowed === true && key.Type != "Emotes") { json.assetAndAssetTypeIds.push({ assetId: parseFloat(key.ItemId), assetTypeId: 8, }) } else if (gearallowed === false && key.Type != "Emotes") { if (key.Type != "Gears") { json.assetAndAssetTypeIds.push({ assetId: parseFloat(key.ItemId), assetTypeId: 8, }) } } } } //console.log(json.accessoryVersionIds) return res.json(json) }) app.get("/v2/users/:id/groups/roles", async (req, res) => { // 2020 admin badge const userid = req.params?.id const doc = await user.findOne({ userid: userid }) if (!doc) { return res.json({ status: "error", error: "User not found." }) } if (doc.admin === true) { return res.json({ data: [ { group: { id: 1200769, name: "Official Group of Roblox", memberCount: 1976, hasVerifiedBadge: false, }, role: { id: 41221804, name: "Team Member", rank: 20, }, }, ], }) } return res.json({ data: [], }) }) app.all("/v1.1/game-start-info/", async (req, res) => { // 2020 game settings const placeid = req.query.universeId ?? 0 const doc = await games.findOne({ idofgame: placeid }) if (!doc) { return res.json({ status: "error", error: "Game not found." }) } const json = { gameAvatarType: "PlayerChoice", allowCustomAnimations: "True", universeAvatarCollisionType: "OuterBox", universeAvatarBodyType: "Standard", jointPositioningType: "ArtistIntent", message: "", universeAvatarMinScales: { height: 0.9, width: 0.7, head: 0.95, depth: 0.0, proportion: 0.0, bodyType: 0.0, }, universeAvatarMaxScales: { height: 1.05, width: 1.0, head: 1.0, depth: 0.0, proportion: 0.0, bodyType: 0.0, }, universeAvatarAssetOverrides: [], moderationStatus: null, } json.gameAvatarType = doc.avatartype ?? "PlayerChoice" if (doc.avatartype) { json.gameAvatarType = "MorphTo" + json.gameAvatarType } return res.json(json) }) app.all( ["//moderation/v2/filtertext", "/moderation/v2/filtertext"], (req, res) => { const filtered = ["faggot", "nigger", "nigga", "sex"] let filteredtext = req.body?.text if ( filtered.includes(filteredtext) === true || filtered.some(substr => filteredtext.toLowerCase().startsWith(substr.toLowerCase()), ) === true ) { //filteredtext = '#'.repeat(req.body?.text?.length) //filteredtext = filteredtext.replaceAll(filtered,"#") let regex for (var i = 0; i < filtered.length; i++) { regex = new RegExp(filtered[i], "g") filteredtext = filteredtext.replace( regex, "#".repeat(filtered[i].length), ) } } //console.log(req.body) return res.json({ data: { AgeUnder13: filteredtext, Age13OrOver: filteredtext, }, success: true, }) }, ) app.post("/v2/login", (req, res) => { //console.log(req.body) return res.json({ user: { id: 1, name: "bruh", }, isBanned: false, }) }) app.all("/v1/login", (req, res) => { //console.log(req.body) res.cookie( ".ROBLOSECURITY", "_|WARNING:-DO-NOT-SHARE-THIS.--Sharing-this-will-allow-someone-to-log-in-as-you-and-to-steal-your-ROBUX-and-items.|_DGJJD464646464dfgdgdgdCUdgjneth4iht4ih64uh4uihy4y4yuhi4yhuiyhui4yhui4uihy4huiyhu4iyhuihu4hhdghdgihdigdhuigdhuigidhugihugdgidojgijodijogdijogdjoigdjoidijogijodgijdgiojdgijodgijoF", ) res.cookie( ".RBXID", "_|WARNING:-DO-NOT-SHARE-THIS.--Sharing-this-will-allow-someone-to-log-in-as-you-and-to-steal-your-ROBUX-and-items.|_eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI2NDA3MGQyNC0zYWR4LTQ5NzMtODAxYy0yOWNhNzUyNTA5NjIiLCJzdWfdijogdoijdijogijodcB6YExhM", ) return res.json({ user: { id: 1, name: "Shit", displayName: "Shitter" } }) }) app.get("/initialize", async (req, res) => { var ip = req.headers["cf-connecting-ip"] || req.socket.remoteAddress ip = ip.toString() await ipWhiteListRepository.save(ip, { ip: ip, }) //await ipWhiteListRepository.expire(ip, 24 * 60 * 60 * 7 * 4) return res.redirect("/") }) app.get("/Usapi/:id", async (req, res) => { const userid = req.params?.id const doc = await user.findOne({ userid: userid }) if (!doc) { return res.json({ status: "error", error: "User not found." }) } return res.json({ Id: doc.userid, Username: doc.username, AvatarUri: null, AvatarFinal: false, IsOnline: false, }) }) // TODO remove this app.get("/assets/ugc/*", async (req, res) => { return res.status(404).end() }) // protect this route app.use("/assets", express.static("assets")) app.use(handler) console.log("here") if (PROD === "true") { app.listen(9000, "localhost") } else { app.listen(80) // don't forget to change to 9000 for production const localPrivateKeyPath = process.env.PRIVATEKEYLOCAL const localCertificatePath = process.env.LOCALCERTIFICATEPATH var privateKey = require("fs").readFileSync(localPrivateKeyPath) var certificate = require("fs").readFileSync(localCertificatePath) https .createServer( { key: privateKey, cert: certificate, }, app, ) .listen(443) // remove this for prod } const f = { Mode: "Thumbnail", Settings: { Type: "Avatar_R15_Action", PlaceId: 1818, UserId: 0, BaseUrl: "mete0r.xyz", MatchmakingContextId: 1, Arguments: [ "https://www.mete0r.xyz", "https://api.mete0r.xyz/v1.1/avatar-fetch?userId=0", "PNG", 420, 420, ], }, Arguments: { PrefferedPort: 53640, MachineAddress: "localhost", }, }