Progress is being made

This commit is contained in:
Christopher Cookman 2024-12-06 09:13:01 -07:00
parent 65c6991a6a
commit 8d6aa4cbe7
11 changed files with 1177 additions and 20 deletions

24
commands.js Normal file
View file

@ -0,0 +1,24 @@
// Command definitions
const Discord = require("discord.js")
module.exports = {
global: [
// Use SlashCommandBuilder for command creation
new Discord.SlashCommandBuilder()
.setName("report")
.setDescription("Report a user.")
.addNumberOption(option => option.setName("roblox_id").setDescription("The Roblox ID of the user you're reporting.").setRequired(true))
.addStringOption(option => option.setName("reason").setDescription("The reason for the report. (Please be as descriptive as possible)").setRequired(true)),
],
admin: [
new Discord.SlashCommandBuilder()
.setName("ban")
.setDescription("Ban a user.")
.setDefaultMemberPermissions(0),
new Discord.SlashCommandBuilder()
.setName("unban")
.setDescription("Unban a user.")
.addNumberOption(option => option.setName("roblox_id").setDescription("The Roblox ID of the user you're unbanning.").setRequired(true))
.setDefaultMemberPermissions(0),
]
}

View file

@ -70,6 +70,18 @@ function defineFlags(flagNames) {
}, {});
}
/**
* Retrieves the names of the flags that are set.
* @param {number} flags - The current set of flags.
* @param {Object} flagDefinitions - An object where keys are flag names and values are powers of 2.
* @returns {string[]} - An array of flag names that are set.
*/
function getSetFlags(flags, flagDefinitions) {
return Object.keys(flagDefinitions).filter(flagName =>
(flags & flagDefinitions[flagName]) !== 0
);
}
module.exports = {
addFlag,
@ -78,5 +90,6 @@ module.exports = {
toggleFlag,
hasAllFlags,
hasAnyFlag,
defineFlags
defineFlags,
getSetFlags
}

View file

@ -1,18 +1,25 @@
// Other stuff
const colors = require("colors");
// 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.")
// Color logs
const log = {
info(msg) {
console.log(`${colors.cyan.bold("[INFO]")} ${msg}`);
}
}
// dotenv
require("dotenv").config();
const noblox = require("noblox.js")
noblox.setCookie(process.env.ROBLOSECURITY)
// Express
const express = require("express");
const app = new express();
@ -27,11 +34,76 @@ app.use((req, res, next) => {
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`)
console.log(req.headers)
next()
});
// Run migrations
// 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');
@ -45,4 +117,5 @@ require("./migrations")().then(() => {
app.listen(port, () => {
log.info(`Listening on ${port}`)
})
client.login(process.env.DISCORD_TOKEN);
});

9
log.js Normal file
View file

@ -0,0 +1,9 @@
const colors = require("colors");
module.exports = {
info(msg) {
console.log(`${colors.cyan.bold("[INFO]")} ${msg}`);
},
error(msg) {
console.log(`${colors.red.bold("[ERROR]")} ${msg}`);
}
}

View file

@ -3,6 +3,8 @@ const fs = require('fs');
const path = require('path');
const util = require("util")
require("dotenv").config()
const log = require("./log");
// Create a MariaDB connection pool
const pool = mariadb.createPool({
@ -45,7 +47,7 @@ function runMigrations() {
[migrationName]
).then(([rows]) => {
if (Object.keys(rows || {}).length > 0) {
console.log(`Skipping already applied migration: ${migrationName}`);
//log.info(`Skipping already applied migration: ${migrationName}`);
return; // Skip this migration
}
@ -58,7 +60,7 @@ function runMigrations() {
'INSERT INTO migrations (name) VALUES (?)',
[migrationName]
).then(() => {
console.log(`Applied migration: ${migrationName}`);
log.info(`Applied migration: ${migrationName}`);
});
});
});
@ -66,11 +68,11 @@ function runMigrations() {
}, Promise.resolve());
})
.then(() => {
console.log('All migrations applied successfully!');
log.info('All migrations applied successfully!');
resolve();
})
.catch(err => {
console.error('Error running migrations:', err);
log.error('Error running migrations:', err);
reject(err);
})
.finally(() => {

View file

@ -1,7 +1,7 @@
CREATE TABLE bans (
id INT AUTO_INCREMENT PRIMARY KEY,
robloxId INT,
discordId INT,
id CHAR(36) DEFAULT (UUID()) PRIMARY KEY,
robloxId VARCHAR(16),
discordId VARCHAR(24),
robloxUsername VARCHAR(255),
discordUsername VARCHAR(255),
reasonShort VARCHAR(255),

View file

@ -0,0 +1,12 @@
CREATE TABLE guilds (
id VARCHAR(24) NOT NULL PRIMARY KEY,
robloxId VARCHAR(16),
discordId VARCHAR(24),
robloxUsername VARCHAR(255),
discordUsername VARCHAR(255),
reasonShort VARCHAR(255),
reasonLong VARCHAR(2048),
reasonsFlag INT,
banTimestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
expiresTimestamp TIMESTAMP DEFAULT NULL
);

View file

@ -0,0 +1 @@
INSERT INTO ubs.bans (robloxId,discordId,robloxUsername,discordUsername,reasonShort,reasonLong,reasonsFlag) VALUES (999999999,123456789,'testuser','testuser', "Example Short", "Example Long", 20);

990
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -14,6 +14,7 @@
"discord.js": "^14.16.3",
"dotenv": "^16.4.7",
"express": "^4.21.1",
"mariadb": "^3.4.0"
"mariadb": "^3.4.0",
"noblox.js": "^6.0.2"
}
}

View file

@ -1,6 +1,9 @@
const express = require('express');
const router = express.Router();
const mariadb = require('mariadb');
const reasonFlags = JSON.parse(process.env.REASON_FLAGS)
const { execSync } = require('child_process');
// Create a MariaDB connection pool
const pool = mariadb.createPool({
@ -60,4 +63,35 @@ router.get("/v1/ban/roblox/:uid", async (req, res) => {
}
})
router.get("/v1/ban/discord/:uid", async (req, res) => {
if (!req.params.uid) return res.status(400).json({error: "Specify user ID!"});
try {
// Get a connection from the pool
const connection = await pool.getConnection();
try {
// Execute the query to fetch all rows from the `bans` table
const rows = await connection.query('SELECT * FROM bans WHERE discordId = ?', [req.params.uid]);
// Send the results as a JSON response
res.json(rows);
} finally {
// Release the connection back to the pool
connection.release();
}
} catch (err) {
console.error('Error fetching bans:', err);
// Respond with a 500 Internal Server Error status if something goes wrong
res.status(500).json({ error: 'An error occurred while fetching the bans.' });
}
})
router.get("/v1/info", (req,res) => {
res.json({
commit_hash: execSync('git rev-parse HEAD').toString().trim(),
reasonFlags
})
})
module.exports = router;