// Other requires const fs = require("fs"); const path = require('path'); const { execSync } = require('child_process'); const flags = require("./flags.js") const log = require("./log"); // Legal stuff log.info(`UBS Server (${execSync("git rev-parse --short HEAD").toString().trim()}) on ${execSync("git rev-parse --abbrev-ref HEAD").toString().trim()}`) log.info(`\u00A9 ${new Date().getFullYear()} RTECH Consortium.`) log.info("This software is licensed under the GNU General Public License v3.0") log.info("This software is provided as-is with no warranty or guarantee of support.") log.info("This software is not affiliated with Roblox Corporation.") // dotenv require("dotenv").config(); const noblox = require("noblox.js") noblox.setCookie(process.env.ROBLOSECURITY) // Express const express = require("express"); const app = new express(); const port = process.env.SERVER_PORT || 3000; app.use(express.json()); app.use((req, res, next) => { if (!process.env.LOGFILE) return next(); var requestIp = req.ip; if (process.env.TRUST_PROXY && (req.ip == `::ffff:${process.env.PROXY_IP}` || req.ip == process.env.PROXY_IP)) { requestIp = req.headers["x-forwarded-for"]; } fs.appendFileSync(process.env.LOGFILE, `${requestIp} - ${req.method} ${req.protocol}://${req.get('host')}${req.originalUrl} - ${req.headers["user-agent"]}\n`) next() }); // Flags const reasonFlagTypes = [ "OTHER", "LEAKER", "TOXIC", "SCAM", "CHILD_SAFETY" ] const reasonFlags = flags.defineFlags(reasonFlagTypes) process.env.REASON_FLAGS = JSON.stringify(reasonFlags) // Discord stuff const Discord = require("discord.js"); const client = new Discord.Client({intents: ["Guilds", "GuildBans", "GuildMembers"]}) client.on("ready", async () => { log.info(`Logged into Discord as ${client.user.displayName}`); const commands = require("./commands") // Command registration await (async () => { try { const rest = new Discord.REST().setToken(client.token); //Global await rest.put(Discord.Routes.applicationGuildCommands(client.user.id, process.env.ADMIN_GUILD), { body: [] }) log.info(`Registering global commands`); await rest.put(Discord.Routes.applicationCommands(client.user.id), { body: commands.global }) //Admin log.info(`Registering admin commands`); await rest.put(Discord.Routes.applicationGuildCommands(client.user.id, process.env.ADMIN_GUILD), { body: commands.admin }) } catch (error) { console.error(error); } })(); }); client.on("interactionCreate", async (interaction) => { // Switch by type (either slash command or modal) switch(interaction.type) { // Slash Command Handler case Discord.InteractionType.ApplicationCommand: if (!interaction.isCommand()) return; const command = interaction.commandName; const args = interaction.options; switch(command) { // Report Command case "report": const robloxId = args.getNumber("roblox_id"); const reason = args.getString("reason"); // TODO: Report Command break; }; break; // Modal Handler case Discord.InteractionType.ModalSubmit: break; } }); // Startup log.info("Starting up...") require("./migrations")().then(() => { // Load all route modules from the 'routes' folder const routesPath = path.join(__dirname, 'routes'); fs.readdirSync(routesPath).forEach((file) => { const route = require(path.join(routesPath, file)); const routeName = `/${file.replace('.js', '')}`; // Use filename as route base app.use(routeName, route); log.info(`Using ${routeName}`) }); app.listen(port, () => { log.info(`Listening on ${port}`) }) client.login(process.env.DISCORD_TOKEN); });