nice new update

This commit is contained in:
404invalid-user 2025-01-18 01:27:58 +00:00
parent e136522421
commit 666638c956
136 changed files with 4483 additions and 9190 deletions

9
.env.example Normal file
View file

@ -0,0 +1,9 @@
CLIENT_ID=
CLIENT_SECRET=
BOT_TOKEN=
DB_URI=mariadb://knightrider:<password>@localhost:3306/knightrider
WEBSITE_PORT=3000

24
.eslintrc.json Normal file
View file

@ -0,0 +1,24 @@
{
"env": {
"node": true,
"es2021": true
},
"extends": [
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"plugins": [
"@typescript-eslint"
],
"overrides": [],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"rules": {
"no-console": "warn"
}
}

5
.gitignore vendored
View file

@ -1 +1,6 @@
node_modules node_modules
.env
/dist
/logs
/TODO
/OLD_src

View file

@ -1,44 +1,36 @@
# knightrider
mfking discord bot with all that shit
### file structure
this is the guide on what is where
```
| - src - | - applications - \ - bot.js
| | / - webserver.js
| |
| | - bot - | - addons
| | | - commands
| | | - events
| | | - handlers
| |
| | - conf - \ conf.json
| | / tokens.js
| |
| | - express
| |
| | - funcs
| |
| | - models
```
# knightrider # knightrider
the all-purpose open source discord bot for CWH11's Hangout Crew. the all-purpose open source discord bot for CWH11's Hangout Crew.
### set up ### set up
- go to discord.com/developers and make a bot token - go to discord.com/developers and make a bot token
- bot token goes in src/conf/tokens.js under { bot: {token: "here"} } - take note of the client id, client secret, snd then bot token
- make a mongo db with the schemas "servers" "users" - make a mysql server with a db
- put the mongo db connect uri in src/conf/tokens.js under { db: {URI: "here"} }
- edit neccery information and details in src/conf/conf.json - copy the .env.example file to .env fill in the client id, client secret bot token and database uri
- npm install
- npm start - from the folder run `npm install --save-dev` then `npm run build` finally `npm run start`
yeah it will be more detailed with the next update. ## Features
[ ] - reaction roles
[ ] - message macros
[ ] - custom reaction role embeds
[ ] - reaction ban
[ ] - reaction kick
[ ] - user info/strike system
[ ] - CAPS spam
~~[ ] - word filter~~ (use built in auto mod)
[ ] - simple web dashboard
~~[ ] - mc server status command~~ (use McStatus https://mcstauts.net/bot)

20
TODO
View file

@ -1,5 +1,15 @@
better nav bar implement /reactionrole add /reactionrole remove commands--done
better main page implement add remove message macro cmd
batter server page
better error checking for fivem cmd
fix discord tag not showing up in fivem commands
implement event to listen for reactions and then role them
add onto rr event listner and add this
add reaction remove listnere
implement /kickrole enable and /kickrole disable
implement /banrole enable and /banrole disable

5
nodemon.json Normal file
View file

@ -0,0 +1,5 @@
{
"watch": ["src"],
"ext": "ts",
"exec": "ts-node --files --project tsconfig.json src/index.ts"
}

6789
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -2,11 +2,11 @@
"name": "knightrider", "name": "knightrider",
"version": "4.8.434", "version": "4.8.434",
"description": "a bot for a private discord server", "description": "a bot for a private discord server",
"updatenote": "small update (untested): fixed non staff from accessing dashboard by doing to domain/server/:server-id", "main": "./dist/index.js",
"main": "./src/knightrider.js",
"scripts": { "scripts": {
"start": "node ./src/knightrider.js", "build": "tsc",
"help": "if you need help with this bot please look at http://knightrider.invalidlag.com/help/" "start": "node ./dist/index.js",
"dev": "nodemon"
}, },
"author": "404invalid-user", "author": "404invalid-user",
"repository": { "repository": {
@ -15,22 +15,19 @@
}, },
"license": "Apache license 2.0", "license": "Apache license 2.0",
"dependencies": { "dependencies": {
"@discordjs/opus": "*",
"body-parser": "*", "body-parser": "*",
"discord-bitfield-calculator": "^1.0.0", "discord-bitfield-calculator": "^1.0.0",
"discord.js": "^12.5.3", "discord.js": "^14.16.3",
"ejs": "*", "dotenv": "^16.4.5",
"express": "*", "express": "^4.21.1",
"express-rate-limit": "*", "mariadb": "^3.4.0",
"ffmpeg-static": "*", "mcstatusbot-logger": "^1.0.5",
"minecraft-server-util": "*", "mysql2": "^3.12.0",
"mongoose": "*", "sequelize": "^6.37.5"
"node-fetch": "*", },
"randomstring": "*", "devDependencies": {
"request": "*", "@types/express": "^5.0.0",
"url": "^*", "nodemon": "^3.1.9",
"util": "*", "ts-node": "^10.9.2"
"yt-search": "*",
"ytdl-core": "*"
} }
} }

View file

@ -1,22 +0,0 @@
/*
* licence https://github.com/404invalid-user/knightrider/blob/main/LICENCE
*/
const chalk = require('chalk')
const { readdirSync } = require('fs')
const Discord = require('discord.js')
module.exports = (client, webServer) => {
client.commands = new Discord.Collection();
client.addons = [];
const handlers = readdirSync(__dirname + '/../bot/handlers/').filter((file) => file.endsWith(".js"));
for (let handler of handlers) {
require(`../bot/handlers/${handler}`)(client);
}
try {
client.login(require('../conf/tokens').bot.token);
} catch (error) {
console.log(chalk.blue('[bot]: ') + chalk.red('(error): ') + "cant login error: " + error);
}
}

View file

@ -1,48 +0,0 @@
/*
* licence https://github.com/404invalid-user/knightrider/blob/main/LICENCE
*/
const chalk = require('chalk')
const bodyParser = require('body-parser');
const rateLimit = require("express-rate-limit");
const express = require('express')
const fs = require('fs')
const conf = require('../conf/conf.json')
module.exports = (client, webServer) => {
webServer.use(bodyParser.json());
webServer.use(bodyParser.urlencoded({ extended: true }));
webServer.use(express.static(__dirname + '/../express/www/static'));
webServer.set('view engine', 'ejs');
webServer.set('views', __dirname + '/../express/www/views');
webServer.use((req, res, next) => {
const { headers: { cookie } } = req;
if (cookie) {
const values = cookie.split(';').reduce((res, item) => {
const data = item.trim().split('=');
return {...res, [data[0]]: data[1] };
}, {});
res.locals.cookie = values;
} else res.locals.cookie = {};
next();
});
//rate limit the api so we dont have spam
const apiLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 400
});
webServer.use("/api/", apiLimiter);
['get', 'post'].forEach(handler => {
require(`../express/handlers/${handler}`)(client, webServer)
})
try {
webServer.listen(conf.port, () => {
console.log(chalk.cyan('[webServer]: ') + 'running at ' + conf.domain + ' (port:' + conf.port + ')')
});
} catch (error) {
console.log(chalk.cyan('[webServer]: ') + chalk.cyan('(error): ') + 'could not start the web server error: ' + error)
}
}

View file

@ -1,17 +0,0 @@
const Server = require('../../models/server');
const conf = require('../../conf/conf.json')
module.exports = async(message, server, user, client) => {
if (server.addons.caps == true) {
if (!message.member.roles.cache.find(r => server.staffRoles.includes(r.name))) {
const textRegex = new RegExp(/[^a-zA-Z0-9]/, 'g');
const capsRegex = new RegExp(/[A-Z]/, 'g');
const capsText = message.content.replace(textRegex, '');
const capsPerc = 1 - (capsText.replace(capsRegex, '').length / capsText.length);
if (capsText.length > 6 && capsPerc > 0.7) {
message.channel.send("too many caps")
}
}
}
}

View file

@ -1,42 +0,0 @@
const conf = require('../../conf/conf.json')
module.exports = (message, server, user, client) => {
//filter banned words at different levels
try {
if (server.addons.filter == true) {
if (!message.member.roles.cache.find(r => server.staffRoles.includes(r.name))) {
if (server.filter.level == 'safe') {
server.filter.safe.forEach(async(word) => {
let msgContent = message.content.toLowerCase();
if (msgContent.includes(word)) {
await message.delete().catch(error => {});
addstrike(user);
if (parseInt(server.channels.modLogs) !== 'NaW') {
client.guilds.cache.get(server.id).channels.cache.get(server.channels.modLogs).send({ embed: { color: conf.colour.ok, title: 'filter has been triggered', url: conf.domain + '/server/' + user.guildID + '/user/' + user.id, author: { name: conf.bot.name, icon_url: conf.bot.logo, url: conf.bot.url, }, thumbnail: { url: message.author.displayAvatarURL() }, fields: [{ name: '__**Member**__', value: message.author.tag + '<@!' + message.author.id + '> (' + message.author.id + ')', inline: true, }, { name: '__**Channel**__', value: '<#' + message.channel.id + '>', inline: true }, { name: '__**Filter level**__', value: '`safe`' }, { name: '__**Mesage Content**__', value: '`"' + message.content + '"`', }, { name: '__**Filtered Word**__', value: '`"' + word + '"`' }], timestamp: new Date(), footer: { text: 'moderation log', } } });
};
message.reply(`please dont swear.\nwas this a miss trigger? fill in ${conf.domain}/server/${server.id}/er`).then(m => m.delete({ timeout: 30000 }));
return;
};
});
//filter normal mode
} else if (server.filter.level == 'normal') {
server.filter.normal.forEach(async(word) => {
let msgContent = message.content.toLowerCase();
if (msgContent.includes(word)) {
await message.delete().catch(error => {});
functions.addstrike(message);
if (parseInt(server.channels.modLogs) !== 'NaW') {
client.guilds.cache.get(conf.server.id).channels.cache.get(conf.server.channels.modLogs).send({ embed: { color: conf.colour.ok, title: 'filter has been triggered', url: conf.domain + '/server/' + user.guildID + '/user/' + user.id, author: { name: conf.bot.name, icon_url: conf.bot.logo, url: conf.bot.url, }, thumbnail: { url: message.author.displayAvatarURL() }, fields: [{ name: '__**Member**__', value: message.author.tag + '<@!' + message.author.id + '> (' + message.author.id + ')', inline: true, }, { name: '__**Channel**__', value: '<#' + message.channel.id + '>', inline: true }, { name: '__**Filter level**__', value: '`normal`' }, { name: '__**Mesage Content**__', value: '`"' + message.content + '"`', }, { name: '__**Filtered Word**__', value: '`"' + word + '"`' }], timestamp: new Date(), footer: { text: 'moderation log', } } });
};
message.reply(`please dont swear.\nwas this a miss trigger? fill in ${conf.domain}/server/${server.id}/er`).then(m => m.delete({ timeout: 30000 }));
return;
};
});
};
};
};
} catch (error) {
console.log(error)
}
}

View file

@ -1,125 +0,0 @@
const http = require('http');
const conf = require('../../../conf/conf.json')
module.exports = {
name: 'fivem',
description: "`.fivem` gets information for the fivem server. do `.fivem players` to see who is online",
async execute(message, args, Discord, currentServer, messageUser, client) {
const url = "http://lxn4gvp-aries1.linuxnodes.net:3000"
if (!args[1]) {
let serverEmbed = new Discord.MessageEmbed()
.setAuthor("fiveM info")
.setColor(conf.colour.ok)
.setDescription("some info about the server")
try {
await http.get(`${currentServer.configs.fivem.url}/dynamic.json`, (result) => {
let body = ''
result.on('data', (chunk) => {
body += chunk
})
result.on('end', () => {
let dynamicResponse = JSON.parse(body)
serverEmbed.addField(`__**players:**__`, `${dynamicResponse.clients}/${dynamicResponse.sv_maxclients}`, true)
}).on('error', function (error) {
console.log('error: ' + error)
})
})
await http.get(`${currentServer.configs.fivem.url}/info.json`, (result) => {
let body = ''
result.on('data', (chunk) => {
body += chunk
})
result.on('end', () => {
let infoResponse = JSON.parse(body)
serverEmbed.addField(`__**server:**__`, `${infoResponse.server}`, true)
let oneEyncEnabled;
let enhancedHostSupport;
let scriptHookAllowed;
if (infoResponse.vars.onesync_enabled == 'true') {
oneEyncEnabled = ":white_check_mark:"
} else {
oneEyncEnabled = ":x:"
}
if (infoResponse.vars.sv_enhancedHostSupport == 'true') {
enhancedHostSupport = ":white_check_mark:"
} else {
enhancedHostSupport = ":x:"
}
if (infoResponse.vars.sv_scriptHookAllowed == 'true') {
scriptHookAllowed = ":white_check_mark:"
} else {
scriptHookAllowed = ":x:"
}
serverEmbed.addField(`__**server Info:**__`, ` __onesync:__ ${infoResponse.vars.onesync} \n __onesync Enabled:__ ${oneEyncEnabled} \n __Enhanced Host Support:__ ${enhancedHostSupport} \n __Script Hook Allowed:__ ${scriptHookAllowed}`)
serverEmbed.addField(`__**resources:**__`, `${infoResponse.resources}`)
message.channel.send(serverEmbed)
})
})
} catch (error) {
message.reply("__**there has been an error**__\nserver is down maybe.")
console.log('error: ' + error)
}
} else if (args[1] == 'ip') {
let fivemIpEmbed = new Discord.MessageEmbed()
.setAuthor("fiveM ip")
.setColor(conf.colour.ok)
.setDescription("the fiveM server ip is: `" + currentServer.configs.fivem.ip + "`")
message.channel.send(fivemIpEmbed)
} else if (args[1] == 'players') {
let playersEmbed = new Discord.MessageEmbed()
.setAuthor("fiveM players")
.setColor(conf.colour.ok)
try {
http.get(`${currentServer.configs.fivem.url}/players.json`, (result) => {
let body = ''
result.on('data', (chunk) => {
body += chunk
})
result.on('end', async () => {
var response = JSON.parse(body)
if (response.length == 0 || response.length < 0) {
playersEmbed.addField("__info__", `no one is on the server`)
}
let i;
for (i = 0; i < response.length; i++) {
let discordID = '';
await response[i].identifiers.forEach(id => {
if (id.includes('discord:')) {
discordID = id.replace('discord:', '');
}
});
playersEmbed.addField(`player ${i}:`, `__**name:**__ ${response[i].name} \n __**discord:**__ <@!${discordID}> \n __**fiveM id:**__ ${response[i].id} \n __**ping:**__ ${response[i].ping} \n`)
}
if (i == response.length) {
try {
message.channel.send(playersEmbed)
} catch (error) {
message.channel.send("i couldnt sent that maybe there are too many players online and i cant add them all to the embed.")
console.log('error: ' + error)
}
}
}).on('error', function (error) {
console.log('error: ' + error)
})
})
} catch (error) {
message.reply("__**there has been an error**__\nserver is down maybe.")
console.log('error: ' + error)
}
}
}
}

View file

@ -1,35 +0,0 @@
const Discord = require('discord.js');
const util = require('minecraft-server-util');
module.exports = {
name: 'mcstatus',
description: "mcstat",
execute(message, args, Discord, currentServer, messageUser, client) {
util.status('cwh11.mc.sparks.codes' || currentServer.conf.mc)
.then((response) => {
let minecraftEmbed = new Discord.MessageEmbed()
.setColor(conf.colour.ok)
.setAuthor(conf.bot.name, conf.bot.logo)
.setTitle('Minecraft server status')
.setURL('http://cwh11.mc.sparks.codes')
.setThumbnail(`${message.guild.iconURL() || `${conf.domain}/logo.png`}`)
.setDescription('its online!')
.addField('Server IP:', `${response.host}`)
.addField('Version:', `${response.version}`)
.addField('MOTD:', `${response.description.descriptionText}`)
.addFields({ name: 'Online Players', value: `${response.onlinePlayers}`, inline: true }, { name: 'Max Players', value: `${response.maxPlayers}`, inline: true }, )
.setTimestamp()
.setFooter(`Requested by ${message.member.displayName}`, `${message.author.displayAvatarURL()}`);
message.channel.send(minecraftEmbed).catch(error => console.log('error: ' + error));
})
.catch((error) => {
console.log('error: ' + error);
message.channel.send('**there has been a error**\n this is probably because the server is down');
});
}
}

View file

@ -1,55 +0,0 @@
const https = require('https');
const conf = require('../../../conf/conf.json')
module.exports = {
name: 'memes',
description: " shrekbot meme command http://shrekbot.tk/github",
execute(message, args, Discord, currentServer, messageUser, client) {
try {
const url = `https://www.reddit.com/${currentServer.configs.memes || 'r/memes'}/.json?limit=200`
https.get(url, (result) => {
var body = ''
result.on('data', (chunk) => {
body += chunk
})
result.on('end', () => {
var response = JSON.parse(body)
var index = response.data.children[Math.floor(Math.random() * 129) + 1].data
if (index.post_hint !== 'image') {
message.channel.send('there has been a shrekup retrying...')
}
if (!index.preview) return message.channel.send('a big shrekup has hapened do that command agian');
var image = index.preview.images[0].source.url.replace('&amp;', '&')
var title = index.title
var link = 'https://reddit.com' + index.permalink
var subRedditName = index.subreddit_name_prefixed
if (index.post_hint !== 'image') {
console.log("error no image")
}
console.log(image);
const imageembed = new Discord.MessageEmbed()
.setTitle('a meme provided by reddit')
.setImage(image)
.setColor(`${conf.colour.ok}`)
.setDescription(`[${title}](${link})`)
//.setURL(`https://reddit.com/${subRedditName}`)
.setFooter('powered by ' + `${subRedditName}`)
message.channel.send(imageembed).catch(error => console.log('error: ' + error))
}).on('error', function(error) {
console.log('Got an error: ' + error);
})
})
} catch (error) {
console.log('error: ' + error);
}
}
}

View file

@ -1,203 +0,0 @@
const ytdl = require('ytdl-core');
const ytSearch = require('yt-search');
const Discord = require('discord.js')
const conf = require('../../../conf/conf.json')
const queue = new Map();
module.exports = {
name: 'play',
description: "the moosk command",
aliases: ["p", "q", "skip", "stop", "remove", "queue"],
async execute(message, args, Discord, currentServer, messageUser, client) {
/*TODO
*make these embeds better and objects
*/
const noContentErrorEmbed = new Discord.MessageEmbed()
.setAuthor('Music', `${conf.bot.logo}`)
.setTitle('Error')
.setURL(conf.domain)
.setColor(conf.colour.okError)
.setDescription("well what do you want to listen to?\ni know i am an amazing bot but i cant read minds ~~yet~~")
.addField("possible fixes:", `You have two spaces between ${currentServer.prefix}play and the url/song name remove one of them`)
.setTimestamp()
.setFooter(`Requested by ${message.member.displayName}`, `${message.author.displayAvatarURL()}`);
const notVoiceErrorEmbed = new Discord.MessageEmbed()
.setAuthor('Music', `${conf.bot.logo}`)
.setTitle('Error')
.setURL(conf.domain)
.setColor(conf.colour.okError)
.setTitle("you need to be in a voice channel to execute this command im not exactly going to send you the cd")
.setTimestamp()
.setFooter(`Requested by ${message.member.displayName}`, `${message.author.displayAvatarURL()}`);
const noSongsErrorEmbed = new Discord.MessageEmbed()
.setAuthor('Music', `${conf.bot.logo}`)
.setTitle('Error')
.setURL(conf.domain)
.setColor(conf.colour.okError)
.setTitle("oof there are no songs left in queue")
.setTimestamp()
.setFooter(`Requested by ${message.member.displayName}`, `${message.author.displayAvatarURL()}`);
const errorEmbed = new Discord.MessageEmbed()
.setAuthor('Music', `${conf.bot.logo}`)
.setTitle('Error')
.setURL(conf.domain)
.setColor(conf.colour.okError)
.setTitle("There was some error ~~like there always is~~")
.setTimestamp()
.setFooter(`Requested by ${message.member.displayName}`, `${message.author.displayAvatarURL()}`);
const videoErrorEmbed = new Discord.MessageEmbed()
.setAuthor('Music', `${conf.bot.logo}`)
.setTitle('Error')
.setURL(conf.domain)
.setColor(conf.colour.okError)
.setTitle("I cant seem to find that video")
.setDescription("try adding more key words or just use the song's url")
.setTimestamp()
.setFooter(`Requested by ${message.member.displayName}`, `${message.author.displayAvatarURL()}`);
const voiceChannel = message.member.voice.channel;
if (!voiceChannel) return message.channel.send(notVoiceErrorEmbed);
const permissions = voiceChannel.permissionsFor(message.client.user);
if (!permissions.has('connect')) return message.channel.send('i cant connect to this voice channel ask someone that can help me');
if (!permissions.has('speak')) return message.channel.send('i cant talk in this voice channel aks someone that can help me');
const serverQueue = queue.get(message.guild.id);
if (args[0] === 'play' || args[0] === 'p') {
if (!args[1]) return message.channel.send(noContentErrorEmbed).catch(e => console.log(e))
let song = {};
const videoFinder = async(query) => {
const videoResult = await ytSearch(query).catch(e => console.log(e));
try {
return (videoResult.videos.length > 1) ? videoResult.videos[0] : null;
} catch (err) {
console.log(err)
}
}
let songQuery = args.slice(1).join(' ').replace('http://', '').replace('https://', '').replace('www.', '').replace('youtube.com/', '').replace('/watch?v=', '').replace('&feature=share', '').replace('youtu.be', '')
const video = await videoFinder(songQuery);
if (video) {
song = { title: video.title, url: video.url }
} else {
message.channel.send(videoErrorEmbed).catch(e => console.log(e))
}
if (!serverQueue) {
const queueConstructor = {
voiceChannel: voiceChannel,
textChannel: message.channel,
connection: null,
songs: []
}
queue.set(message.guild.id, queueConstructor);
queueConstructor.songs.push(song);
try {
const connection = await voiceChannel.join();
queueConstructor.connection = connection;
videoPlayer(message.guild, queueConstructor.songs[0], message);
} catch (error) {
queue.delete(message.guild.id);
message.channel.send(errorEmbed).catch(e => console.log(e))
console.log('error: ' + error)
}
} else {
serverQueue.songs.push(song);
let addSongEmbed = new Discord.MessageEmbed()
.setAuthor('Music', `${conf.bot.logo}`)
.setColor(conf.colour.ok)
.setTitle(`**${song.title}** added to the queue`)
.setURL(`${song.url}`)
.setTimestamp()
.setFooter(`Requested by ${message.member.displayName}`, `${message.author.displayAvatarURL()}`);
return message.channel.send(addSongEmbed).catch(e => console.log(e))
}
} else if (args[0] === 'queue' || args[0] === 'q') serverQueueGet(message, serverQueue, args);
else if (args[0] === 'skip') skipSong(message, serverQueue);
else if (args[0] === 'stop') stopSong(message, serverQueue);
else if (args[0] === 'remove') removeSong(message, serverQueue, args);
}
}
const videoPlayer = async(guild, song, message) => {
const songQueue = queue.get(guild.id);
if (!song) {
songQueue.voiceChannel.leave();
queue.delete(guild.id);
return;
}
const stream = ytdl(song.url, { filter: 'audioonly' });
try {
songQueue.connection.play(stream, { seek: 0, volume: 0.5 })
.on('finish', () => {
songQueue.songs.shift();
videoPlayer(guild, songQueue.songs[0], message);
})
} catch (err) {
message.channel.send("i cant connect to the voice channel within the time frame i have high ping or some other error")
}
if (song.url) {
let embedUrl = song.url
if (!embedUrl.includes('http')) {
embedUrl = conf.domain
}
let addSongEmbed = new Discord.MessageEmbed()
.setAuthor('Music', `${conf.bot.logo}`)
.setColor(conf.colour.ok)
.setTitle(`Now playing **${song.title}**`)
.setURL(`${embedUrl}`)
.setTimestamp()
.setFooter(`Requested by ${message.member.displayName}`, `${message.author.displayAvatarURL()}`);
await songQueue.textChannel.send(addSongEmbed)
}
}
const serverQueueGet = async(message, serverQueue, args) => {
if (!message.member.voice.channel) return message.channel.send(notVoiceErrorEmbed);
let serverQueueEmbed = new Discord.MessageEmbed()
.setAuthor('Music Queue', `${conf.bot.logo}`)
.setColor(conf.colour.ok)
.setTitle(`the server queue`)
.setURL(`${conf.domain}`)
.setTimestamp()
.setFooter(`Requested by ${message.member.displayName}`, `${message.author.displayAvatarURL()}`)
await serverQueue.songs.forEach(theSong => {
serverQueueEmbed.addField(`${serverQueue.songs.indexOf(theSong)}`, `__title:__ ${theSong.title}\n__url:__ ${theSong.url}`)
})
await message.channel.send(serverQueueEmbed)
}
const skipSong = (message, serverQueue) => {
if (!message.member.voice.channel) return message.channel.send(notVoiceErrorEmbed);
if (!serverQueue) {
return message.channel.send(noSongsErrorEmbed);
}
serverQueue.connection.dispatcher.end();
}
const stopSong = (message, serverQueue) => {
if (!message.member.voice.channel) return message.channel.send(notVoiceErrorEmbed);
serverQueue.songs = [];
serverQueue.connection.dispatcher.end();
}
const removeSong = (message, serverQueue) => {
serverQueue.songs.forEach(theSong => {
if (args[1] == serverQueue.songs.indexOf(theSong)) {
try {
serverQueue.songs.indexOf(theSong) > -1 ? serverQueue.songs.splice(serverQueue.songs.indexOf(theSong), 1) : false
} catch (err) {
message.channel.send("there was an error removing that song")
}
} else {
message.channel.send("That song isn't in the queue you can use the url insted.\nYou can find the url by clicking on the blue text in the embed i sent when you requested to play that song.")
}
})
}

View file

@ -1,38 +0,0 @@
const { version } = require('../../../../package.json');
const conf = require('../../../conf/conf.json')
module.exports = {
name: 'about',
description: "about bot",
async execute(message, args, Discord, currentServer, messageUser, client) {
message.channel.send(conf.domain + '/img/loading.gif').then(m => {
let totalSeconds = (client.uptime / 1000);
let days = Math.floor(totalSeconds / 86400);
totalSeconds %= 86400;
let hours = Math.floor(totalSeconds / 3600);
totalSeconds %= 3600;
let minutes = Math.floor(totalSeconds / 60);
let seconds = Math.floor(totalSeconds % 60);
let aboutEmbed = new Discord.MessageEmbed()
.setAuthor(conf.bot.name, `${conf.bot.logo}`, `${conf.domain}`)
.setDescription('everything you need to know.')
.setColor(conf.colour.ok)
.setTitle('about')
.setThumbnail(`${message.guild.iconURL() || `${conf.domain}/logo.png`}`)
.addField('Website:', `${conf.domain}`)
.addField('Coolness level', `epic bot for ${message.guild.name} server`)
.addField('Developer(s)', '<@!522534458071449620>')
.addField('Version', `${version}`)
.addField('Libary', `discord.js v12`)
.addField("commands sent:", `${currentServer.commandCount} commands`)
.addField('Bot version:', `${version}`)
.addField('Up Time', `${days} d, ${hours} h, ${minutes} m, ${seconds} s`)
.addField("Memory usage:", `${(process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2)} MB / 1GB`)
.addField('Ping', `ping: ${m.createdTimestamp - message.createdTimestamp} api ping: ${Math.round(client.ws.ping)}`)
.setFooter(`Requested by ${message.member.displayName}`, `${message.author.displayAvatarURL()}`);
m.edit(aboutEmbed).catch(error => console.log('error: ' + error));
}).catch(error => console.log('error: ' + error))
}
}

View file

@ -1,49 +0,0 @@
const conf = require('../../../conf/conf.json')
module.exports = {
name: 'help',
description: "help command",
execute(message, args, Discord, currentServer, messageUser, client) {
if (args[1] == 'embed') {
let helpSomethingEmbed = new Discord.MessageEmbed()
.setAuthor(conf.bot.name, conf.bot.logo)
.setColor('#10FF00')
.setTitle('Help embed')
.setDescription('**For mods and admins only**\nLets mods and admin make a custom embed.')
.addField('Command structure', `${currentServer.prefix}embed [title] [description] [colour]`)
.addField('Command example', `${currentServer.prefix}embed [bruv is awesome] [just joking you are] [#FF0000]`)
.addField('Extra info', `To get the # colour code(s) [click here](https://htmlcolorcodes.com/)`)
.setThumbnail(`${message.guild.iconURL() || `${conf.domain}/logo.png`}`)
.setTimestamp()
.setFooter(`Requested by ${message.member.displayName}`, `${message.author.displayAvatarURL()}`);
message.channel.send(helpSomethingEmbed).catch(error => console.log('error: ' + error));
} else if (args[1] == 'embed-img') {
let helpSomethingEmbed = new Discord.MessageEmbed()
.setAuthor(conf.bot.name, conf.bot.logo)
.setColor('#10FF00')
.setTitle('Help embed-img')
.setDescription('**For mods and admins only**\nLets mods and admin make a custom embed.')
.addField('Command structure', `${currentServer.prefix}}embed [title] [description] [colour] [img-url]`)
.addField('Command example', `${currentServer.prefix}embed [bruv is awesome] [just joking you are] [#FF0000] [http://imgsite.com/knightrider.png]`)
.addField('Extra info', `To get the # colour code(s) [click here](https://htmlcolorcodes.com/)`)
.setThumbnail(`${message.guild.iconURL() || `${conf.domain}/logo.png`}`)
.setTimestamp()
.setFooter(`Requested by ${message.member.displayName}`, `${message.author.displayAvatarURL()}`);
message.channel.send(helpSomethingEmbed).catch(error => console.log('error: ' + error));
} else {
let helpEmbed = new Discord.MessageEmbed()
.setColor(conf.colour.ok)
.setTitle('Help!')
.setURL(`${conf.domain}`)
.setAuthor(conf.bot.name, conf.bot.logo)
.addField("util commands:", `${currentServer.prefix}ping - shows ping\n${currentServer.prefix}about - gives general information about the bot`)
.addField("general commands:", `${currentServer.prefix}mcstatus - shows minecraft server status\n${currentServer.prefix}memes - shows a random meme from redid mus be done in memes channel\n${currentServer.prefix}fivem - shows fiveM server status\n${currentServer.prefix}fivem players - shows online players on fiveM\n${currentServer.prefix}fivem ip - gives you the fiveM server ip\n${currentServer.prefix}play (song name) or (youtube-url) - plays selected music in a voice channel\n${currentServer.prefix}skip - skips the current song to the next one on the queue\n${currentServer.prefix}stop - bot stops playing music\n`)
.addField("moderator commands:", `${currentServer.prefix}say #channel message - bot sends message in channel of choice\n${currentServer.prefix}filter <safe/normal/off> - sets the word filter level\n${currentServer.prefix}userinfo <@user> - gives how many strikes a user has and other basic info on the user like nots and join dates.\n${currentServer.prefix}noteset <@user> - sets a note for a user\n${currentServer.prefix}note <@user> - see a moderator note for a user\n${currentServer.prefix}embed [title] [description] [colour] - sends a embed\n${currentServer.prefix}embed-img [title] [description] [colour] [img-url]\n${currentServer.prefix}OTR11 - for <@!276156203770314755> announcment`)
.setThumbnail(`${message.guild.iconURL() || `${conf.domain}/logo.png`}`)
.setTimestamp()
.setFooter(`Requested by ${message.member.displayName}`, `${message.author.displayAvatarURL()}`);
message.channel.send(helpEmbed).catch(error => console.log('error: ' + error))
}
}
}

View file

@ -1,11 +0,0 @@
module.exports = {
name: 'ping',
description: "about bot",
execute(message, args, Discord, currentServer, messageUser, client) {
message.channel.send("Pinging...").then(m => {
var ping = m.createdTimestamp - message.createdTimestamp;
var apiPing = Math.round(client.ws.ping)
m.edit(`ping: ${ping}\napi ping: ${apiPing}`).catch(error => console.log('error: ' + error))
});
}
}

View file

@ -0,0 +1,79 @@
import { Client, ChatInputCommandInteraction, PermissionFlagsBits, SlashCommandBuilder } from "discord.js";
//@ts-expect-error
import YALAS from 'mcstatusbot-logger';
import * as AddMessageMacro from './messagemacro/add';
import * as ListMessageMacros from './messagemacro/list';
import { GuildInstance } from "../../database/schemas/Guild";
import { UserInstance } from "../../database/schemas/User";
const data = {
serverOnly: false,
guildId: null,
allowSuspendedUserAccess: true,
command: new SlashCommandBuilder()
.setName('messagemacro')
.setDefaultMemberPermissions(PermissionFlagsBits.ManageGuild)
.setDescription("setup message macros for the server")
.addSubcommand(subcommand =>
subcommand
.setName('add')
.setDescription("Add a message macro")
.addStringOption(option =>
option.setName('macro')
.setDescription('The macro you send (without prefix)')
.setRequired(true)
.setMinLength(1)
.setMaxLength(5)
)
.addStringOption(option =>
option.setName('message')
.setDescription('The content of the message the bot will send')
.setRequired(true)
.setMinLength(3)
.setMaxLength(2000)
)
.addMentionableOption(option =>
option.setName('trigger-role')
.setDescription('The role that grants people permission to use this')
.setRequired(true)
)
.addBooleanOption(o =>
o.setName('deletecmd')
.setDescription("should your macro message be deleted after you send it?")
.setRequired(true)
)
.addBooleanOption(o =>
o.setName('impersonate')
.setDescription("setting to true will use your name and photo")
.setRequired(true)
)
.addChannelOption(option =>
option.setName('channel')
.setDescription('The channel in which you want to it to be sent in (leave blank to send in same channel as command)')
.setRequired(false)
)
)
.addSubcommand(subcommand =>
subcommand
.setName('list')
.setDescription("Lists all your message macros and allows you to edit/remove them")
)
}
export { data };
export async function chatInputCommand(client: Client, interaction: ChatInputCommandInteraction, guild: GuildInstance, user: UserInstance) {
switch (interaction.options.getSubcommand()) {
case 'add':
AddMessageMacro.chatInputCommand(client, interaction, guild, user)
break;
case 'list':
ListMessageMacros.chatInputCommand(client, interaction, guild, user)
break;
}
}

View file

@ -0,0 +1,140 @@
import { Client, ChatInputCommandInteraction, Role, GuildChannelResolvable, PermissionsBitField, ChannelType } from "discord.js";
import { schemas } from "../../../database";
//@ts-expect-error
import YALAS from 'mcstatusbot-logger';
import { GuildInstance } from "../../../database/schemas/Guild";
import { UserInstance } from "../../../database/schemas/User";
export async function chatInputCommand(client: Client, interaction: ChatInputCommandInteraction, guild: GuildInstance, user: UserInstance) {
if (!interaction.guild) return interaction.reply("must be done in discord server");
const botMember = interaction.guild.members.me;
if (!botMember) {
YALAS.error("messagemacro add: bot in guild null");
return;
}
//get macro
let macroContent = interaction.options.getString('macro');
if (!macroContent) return;
macroContent = macroContent.replace(/\s+/g, '');
//get and validate message content
const messageContent = interaction.options.getString('message');
if (messageContent === null) return;
if (messageContent.length < 3 || messageContent.length > 2000) {
return interaction.reply({
embeds: [{
title: "Invalid Message",
description: "The set message must be between 3 and 2000 in length."
}]
});
}
//get and validate role
const role = interaction.options.getMentionable('trigger-role');
if (!(role instanceof Role)) {
return interaction.reply({
embeds: [{
title: "Invalid Role",
description: "The selected role is not a valid role"
}]
});
}
const deleteMsg = interaction.options.getBoolean('deletecmd') ?? false;
const impersonate = interaction.options.getBoolean('impersonate') ?? false;
//get and validate channel
let channel = interaction.options.getChannel('channel');
console.log("balkkd cjrA")
console.log(channel
)
if (channel === undefined) channel = null;
if (channel !== null) {
if (channel.type !== ChannelType.GuildText && channel.type !== ChannelType.GuildAnnouncement) {
return interaction.reply({
embeds: [{
title: "That Will Not Work",
description: "The selected channel is not a text channel please select a text channel."
}]
});
}
const botPermSM = botMember.permissionsIn((channel as GuildChannelResolvable)).toArray();
if (botPermSM && !botPermSM.includes('SendMessages')) {
return interaction.reply({
embeds: [{
title: "Missing permission",
description: "you need to give me the send message permission in the selected channel."
}]
});
}
}
await interaction.deferReply();
//check msgMacro does net exist for reaction in channel
try {
const msgMacro = await schemas['MessageMacro'].findOne({
where: {
guild: guild.id,
shortCode: macroContent,
}
});
if (msgMacro !== null) {
return interaction.editReply({
embeds: [{
title: "Message Macro Exists",
description: "The message macro `" + msgMacro.dataValues.shortCode + "` already exists please edit or remove it"
}]
});
}
} catch (err: any) {
YALAS.error(err)
YALAS.error(err.stack || err);
return interaction.editReply("error when checking for existing message macro in database.");
}
try {
await schemas['MessageMacro'].create({
guild: guild.id,
channel: channel ? channel.id : null,
shortCode: macroContent,
message: messageContent,
role: role.id,
impersonate: impersonate,
deleteShortCode: deleteMsg
});
} catch (err: any) {
YALAS.error(err.stack || err);
return interaction.editReply("error when saving reaction role to database.");
}
let prefixNote = '';
if (macroContent.toLocaleLowerCase().startsWith(guild.prefix)) {
prefixNote = "\nNote: it looks like your macro contains the prefix so to activate it you will need to type `" + guild.prefix + macroContent + "`";
}
try {
return interaction.editReply({
embeds: [{
title: "Success",
description: "The message Macro has been created."+macroContent
}]
});
} catch (err: any) {
YALAS.error(err.stack || err);
}
}

View file

@ -0,0 +1,183 @@
import {
Client,
ChatInputCommandInteraction,
EmbedBuilder,
ButtonBuilder,
ActionRowBuilder,
ButtonStyle,
} from "discord.js";
import { schemas } from "../../../database";
//@ts-expect-error
import YALAS from "mcstatusbot-logger";
import { GuildInstance } from "../../../database/schemas/Guild";
import { UserInstance } from "../../../database/schemas/User";
import { MessageMacroAttributes } from "../../../database/schemas/MessageMacro";
export async function chatInputCommand(client: Client, interaction: ChatInputCommandInteraction, guild: GuildInstance, user: UserInstance) {
if (!interaction.guild) return interaction.reply("Must be done in a Discord server.");
const botMember = interaction.guild.members.me;
if (!botMember) {
YALAS.error("MessageMacro Add: Bot in guild is null");
return;
}
await interaction.deferReply();
let msgMacros = [];
try {
const msgMacroDocs = await schemas["MessageMacro"].findAll({
where: {
guild: guild.id,
},
});
console.log("nuts")
msgMacros = msgMacroDocs.map((item: any) => item.dataValues);
} catch (err: any) {
YALAS.error(err);
YALAS.error(err.stack || err);
return interaction.editReply("Error when checking for message macros in the database.");
}
if (msgMacros.length === 0) {
return interaction.editReply("No message macros found.");
}
console.log("balks")
const updateEmbed = (index: number) => {
const currentMacro: MessageMacroAttributes = msgMacros[index];
const embed = new EmbedBuilder()
.setAuthor({name: "Message Macro"})
.setTitle(currentMacro.shortCode)
.setDescription(currentMacro.message + `\n\n-# --\n-# Prefix: ${guild.prefix}\n-# role: <@&${currentMacro.role}>\n-# Channel: ${currentMacro.channel == null ? '' : '<#' + currentMacro.channel + '>'}`)
const buttons = new ActionRowBuilder<ButtonBuilder>()
.addComponents(
new ButtonBuilder()
.setCustomId("prev")
.setLabel("<")
.setStyle(ButtonStyle.Primary)
.setDisabled(index === 0),
new ButtonBuilder()
.setCustomId("index")
.setLabel(`${index + 1}/${msgMacros.length}`)
.setStyle(ButtonStyle.Secondary)
.setDisabled(true),
new ButtonBuilder()
.setCustomId("next")
.setLabel(">")
.setStyle(ButtonStyle.Primary)
.setDisabled(index === msgMacros.length - 1)
);
const actionButtons = new ActionRowBuilder<ButtonBuilder>()
.addComponents(
new ButtonBuilder()
.setCustomId("delete")
.setLabel("Delete")
.setStyle(ButtonStyle.Danger),
new ButtonBuilder()
.setCustomId("edit")
.setLabel("Edit")
.setStyle(ButtonStyle.Success)
);
return { embed, buttons, actionButtons };
};
// Pagination variables
let currentIndex = 0;
const { embed, buttons, actionButtons } = updateEmbed(currentIndex);
const message = await interaction.editReply({
embeds: [embed],
components: [buttons, actionButtons]
});
const collector = message.createMessageComponentCollector({
time: 60000, // 1 minute timeout
});
collector.on("collect", async (i) => {
if (i.user.id !== interaction.user.id) {
return i.reply({ content: "This interaction isn't for you.", ephemeral: true });
}
switch (i.customId) {
case "prev":
currentIndex = Math.max(0, currentIndex - 1);
break;
case "next":
currentIndex = Math.min(msgMacros.length - 1, currentIndex + 1);
break;
case "delete":
await schemas["MessageMacro"].destroy({
where: { id: msgMacros[currentIndex].id },
});
msgMacros.splice(currentIndex, 1);
currentIndex = Math.max(0, currentIndex - 1);
break;
case "edit":
// Handle edit logic here
await i.reply({
content: "Edit functionality is not implemented yet.",
ephemeral: true,
});
return;
}
if (msgMacros.length === 0) {
collector.stop();
return interaction.editReply({
content: "All message macros have been deleted.",
embeds: [],
components: [],
});
}
const { embed, buttons, actionButtons } = updateEmbed(currentIndex);
await i.update({ embeds: [embed], components: [buttons, actionButtons] });
});
collector.on("end", () => {
const buttons = new ActionRowBuilder<ButtonBuilder>()
.addComponents(
new ButtonBuilder()
.setCustomId("prev")
.setLabel("<")
.setStyle(ButtonStyle.Primary)
.setDisabled(true),
new ButtonBuilder()
.setCustomId("index")
.setLabel(`${currentIndex + 1}/${msgMacros.length}`)
.setStyle(ButtonStyle.Secondary)
.setDisabled(true),
new ButtonBuilder()
.setCustomId("next")
.setLabel(">")
.setStyle(ButtonStyle.Primary)
.setDisabled(true)
);
const actionButtons = new ActionRowBuilder<ButtonBuilder>()
.addComponents(
new ButtonBuilder()
.setCustomId("delete")
.setLabel("Delete")
.setStyle(ButtonStyle.Danger)
.setDisabled(true),
new ButtonBuilder()
.setCustomId("edit")
.setLabel("Edit")
.setStyle(ButtonStyle.Success)
.setDisabled(true)
);
interaction.editReply({
components: [buttons, actionButtons],
});
});
}

View file

@ -1,45 +0,0 @@
const fs = require('fs')
const conf = require('../../../conf/conf.json')
module.exports = {
name: 'editfilter',
description: "edit the filter array",
execute(message, args, Discord, currentServer, messageUser, client) {
if (currentServer.staff.includes(message.author.id) || message.member.roles.cache.find(r => server.staffRoles.includes(r.name))) {
if (!args[1]) {
message.channel.send("please specify an operation <add/remove/dash>");
return;
};
if (!args[2]) {
message.channel.send("please specify something to add to the filter");
return;
};
if (message.content.toLowerCase().substring(currentServer.prefix.length).split(" ").slice(2).join(" ").includes('@everyone') || message.content.toLowerCase().substring(currentServer.prefix.length).split(" ").slice(2).join(" ").includes('@here')) {
message.channel.send("please dont try and exploit me, if you would like to add that to the filter for a genuing reason please use the admin dashboard");
return;
};
if (args[1] == 'add') {
currentServer.filter[currentServer.filter.level].push(message.content.toLowerCase().substring(currentServer.prefix.length).split(" ").slice(2).join(" "));
currentServer.save();
message.channel.send(message.content.toLowerCase().substring(currentServer.prefix.length).split(" ").slice(2).join(" ") + " has been added to the `" + currentServer.filter.level + "` filter");
} else if (args[1] == 'remove') {
const index = currentServer.filter[currentServer.filter.level].indexOf(message.content.toLowerCase().substring(currentServer.prefix.length).split(" ").slice(2).join(" "));
if (index > -1) {
currentServer.filter[currentServer.filter.level].splice(index, 1);
message.channel.send("`" + message.content.toLowerCase().substring(currentServer.prefix.length).split(" ").slice(2).join(" ") + "` has been removed from the `" + currentServer.filter.level + "` filter");
} else {
message.channel.send("you cant remove that as it dosnt exist in the `" + currentServer.filter.level + "` filter");
};
} else if (args[1] == 'dash' || args[1] == 'dashboard') {
message.channel.send(conf.domain + "/dashboard");
};
} else {
return message.reply("you cant do that only staff can").catch(e => console.log(e));
};
}
}

View file

@ -1,32 +0,0 @@
module.exports = {
name: 'embed-img',
description: "embed with image command for mods and admins",
execute(message, args, Discord, currentServer, messageUser, client) {
if (currentServer.staff.includes(message.author.id) || message.member.roles.cache.find(r => server.staffRoles.includes(r.name))) {
if (!args[1]) return message.reply(`you at leas need to supply a title if you stuck do ${currentServer.prefix}help embed`);
if (!message.content.includes('[')) return message.reply(`something is wrong with that if youre stuck do ${currentServer.prefix}help embed`);
let mcontent = message.content;
let titleStart = mcontent.indexOf('[');
let titleEnd = mcontent.indexOf(']');
let title = mcontent.substr(titleStart + 1, titleEnd - titleStart - 1);
let descStart = mcontent.indexOf('[', titleStart + 1);
let descEnd = mcontent.indexOf(']', titleEnd + 1);
let description = mcontent.substr(descStart + 1, descEnd - descStart - 1);
let colorstart = mcontent.indexOf('[', descStart + 1);
let colorend = mcontent.indexOf(']', descEnd + 1);
let color = mcontent.substr(colorstart + 1, colorend - colorstart - 1);
let imgstart = mcontent.indexOf('[', colorstart + 1);
let imgend = mcontent.indexOf(']', colorend + 1);
let img = mcontent.substr(imgstart + 1, imgend - imgstart - 1);
let custome_embed = new Discord.MessageEmbed().setAuthor(`${message.member.displayName}`, `${message.author.displayAvatarURL()}`).setTitle(title).setDescription(description).setColor(color).setImage(`${img}`);
message.channel.send(custome_embed);
} else {
return message.reply("you cant do that only staff can").catch(e => console.log(e));
};
}
}

View file

@ -1,30 +0,0 @@
module.exports = {
name: 'embed',
description: "embed command for mods and admins",
execute(message, args, Discord, currentServer, messageUser, client) {
if (currentServer.staff.includes(message.author.id) || message.member.roles.cache.find(r => server.staffRoles.includes(r.name))) {
if (!args[1]) return message.reply(`you at leas need to supply a title if you stuck do ${currentServer.prefix}help embed`);
if (!message.content.includes('[')) return message.reply(`something is wrong with that if youre stuck do ${currentServer.prefix}help embed`);
let mcontent = message.content;
let titleStart = mcontent.indexOf('[');
let titleEnd = mcontent.indexOf(']');
let title = mcontent.substr(titleStart + 1, titleEnd - titleStart - 1);
let descStart = mcontent.indexOf('[', titleStart + 1);
let descEnd = mcontent.indexOf(']', titleEnd + 1);
let description = mcontent.substr(descStart + 1, descEnd - descStart - 1);
let colorstart = mcontent.indexOf('[', descStart + 1);
let colorend = mcontent.indexOf(']', descEnd + 1);
let color = mcontent.substr(colorstart + 1, colorend - colorstart - 1);
let custome_embed = new Discord.MessageEmbed().setAuthor(`${message.member.displayName}`, `${message.author.displayAvatarURL()}`).setTitle(title).setDescription(description).setColor(color);
message.channel.send(custome_embed);
} else {
return message.reply("you cant do that only staff can").catch(e => console.log(e));
};
}
}

View file

@ -1,26 +0,0 @@
module.exports = {
name: 'filter',
description: "sets filter",
async execute(message, args, Discord, currentServer, messageUser, client) {
if (currentServer.staff.includes(message.author.id) || message.member.roles.cache.find(r => server.staffRoles.includes(r.name))) {
if (args[1] == 'off') {
currentServer.filter.level = 'off';
currentServer.save();
message.channel.send("filter has been set to " + currentServer.filter.level);
} else if (args[1] == 'normal') {
currentServer.filter.level = 'normal';
currentServer.save();
message.channel.send("filter has been set to " + currentServer.filter.level);
} else if (args[1] == 'safe') {
currentServer.filter.level = 'safe';
currentServer.save();
message.channel.send("filter has been set to " + currentServer.filter.level);
} else {
message.channel.send("that is not a valid filter setting you can chose from: 'normal' 'safe' and 'off'.");
};
} else {
return message.reply("you cant do that only staff can").catch(e => console.log(e));
};
}
}

View file

@ -1,28 +0,0 @@
const conf = require('../../../conf/conf.json');
module.exports = {
name: 'rulesrolesljoughuihoutfd8es5tryj/i.uliutygrjyhgjlkukbjhcfjklhgfhjouhbgrvycghujyiljknhbgvfhtgfhiuoihkjbnhbvgfgyuo',
description: "say command for mods and admins",
async execute(message, args, Discord, currentServer, messageUser, client) {
if (currentServer.staff.includes(message.author.id) || message.member.roles.cache.find(r => server.staffRoles.includes(r.name))) {
const exampleEmbed = new Discord.MessageEmbed()
.setColor(conf.colour.ok)
.setAuthor("Game Reaction Roles")
.setTitle("react to get your roles")
.setThumbnail('https://cdn.discordapp.com/icons/584484766997282836/94b16e813edb9a2f1df4a5bd16f98ad1.png')
.setURL("http://knightRider.rf.gd/reaction-role-error.php")
.setDescription("🚚 - <@&595087305212035084>\n🚜 - <@&595086913430355973>\n⛏ - <@&595087098604683277>\n🗺 - <@&604424840807710721>\n🚓 - <@&691635977889906849>\n🚗 - <@&752217267600621578>\n🏎 - <@&752217137728192543>\n🔧 - <@&595767995998011392>\n⚙ - <@&860942666195927050>")
.setFooter('something wrong? go to http://knightRider.rf.gd/er.html');
let msg = await message.channel.send(exampleEmbed);
msg.react("🚚")
msg.react("🚜")
msg.react("⛏")
msg.react("🗺")
msg.react("🚓")
msg.react("🚗")
msg.react("🏎")
msg.react("🔧")
msg.react("⚙")
}
}
}

View file

@ -1,7 +0,0 @@
module.exports = {
name: 'note',
description: "shows a users note",
async execute(message, args, Discord, currentServer, messageUser, client) {
message.reply("* depricated *: do " + currentServer.prefix + "userinfo @someone")
}
}

View file

@ -1,16 +0,0 @@
module.exports = {
name: 'say',
description: "say command for mods and admins",
execute(message, args, Discord, currentServer, messageUser, client) {
if (currentServer.staff.includes(message.author.id) || message.member.roles.cache.find(r => server.staffRoles.includes(r.name))) {
message.delete();
let sayArgs = message.content.substring(prefix.length).split(" ");
if (message.content.toLowerCase().includes('@everyone')) return message.reply(`Holup you can't @ every one`);
if (message.content.toLowerCase().includes('@here')) return message.reply(`Holup you can't @ here`);
message.channel.send(`${sayArgs.slice(2).join(" ")}`);
} else {
return message.reply("you cant do that only staff can").catch(e => console.log(e));
};
}
}

View file

@ -1,45 +0,0 @@
const conf = require('../../../conf/conf.json')
module.exports = {
name: 'townhall',
description: "say command for mods and admins",
async execute(message, args, Discord, currentServer, messageUser, client) {
if (currentServer.staff.includes(message.author.id) || message.member.roles.cache.find(r => server.staffRoles.includes(r.name))) {
if (args[1] == 'end') {
if (args[2] == 'confirm') {
require('../../events/voicestateupdate').members[message.guild.id] = [];
message.channel.send("townHall meeting members have been removed.")
} else {
message.channel.send("are you sure you want to end the townhall meeting? this will remove all members even ones that may still be currently in the voice channel.\nto confirm please do `" + currentServer.prefix + "townhall end confirm`.")
}
} else {
let members = require('../../events/voicestateupdate').members[message.guild.id];
let mpos = 0;
let mEmbed = new Discord.MessageEmbed()
.setColor(conf.colour.ok)
.setTitle('Members that have Joined Townhall Vc')
.setURL(conf.domain + '/server/' + message.guild.id + '/townhall')
.setAuthor(conf.bot.name, conf.bot.logo, conf.bot.url)
.setDescription('when the townhall meeting ends remember to do `' + currentServer.prefix + 'townhall end` otherwise users from the previous meeting will show up.')
.setThumbnail(message.guild.iconURL() || conf.domain + '/logo.png')
.setTimestamp()
.setFooter('TownHall Meeting');
await members.forEach(async(member) => {
let isStaff;
if (client.guilds.cache.get(currentServer.id).members.cache.get(member).roles.cache.find(r => currentServer.staffRoles.includes(r.name))) {
isStaff = 'yes';
} else {
isStaff = 'no';
};
mpos++;
await mEmbed.addField(`__${client.users.cache.get(member).tag}:__`, `__**id:**__ ${member}\n__**@:**__ <@!${member}>\n__**isStaff:**__ ${isStaff}\n__**Join Position:**__ ${mpos}`);
})
message.channel.send({ embed: mEmbed });
};
} else {
return message.reply("you cant do that only staff can").catch(e => console.log(e));
};
}
}

View file

@ -1,48 +0,0 @@
const conf = require('../../../conf/conf.json');
const User = require('../../../models/user');
module.exports = {
name: 'userinfo',
description: "get information about someone on the server",
async execute(message, args, Discord, currentServer, messageUser, client) {
try {
if (currentServer.staff.includes(message.author.id) || message.member.roles.cache.find(r => server.staffRoles.includes(r.name))) {
let theUser;
if (message.mentions.users.first()) {
theUser = message.mentions.users.first();
} else {
theUser = message.author;
};
let currentUser = await User.findOne({ userid: theUser, guildid: message.guild.id });
if (currentUser == null) return message.channel.send("that user inst in the database");
const userInfoEmbed = new Discord.MessageEmbed()
.setAuthor(`${conf.bot.name}`, `${conf.bot.logo}`)
.setTitle('user info')
.setURL(conf.domain)
.setColor(conf.colour.ok)
.setThumbnail(theUser.avatarURL())
.addField("__**user:**__", "<@!" + currentUser.id + "> (" + currentUser.id + ")")
.addField("__**strikes:**__", "`" + currentUser.strike.toString() + "`")
.addField("__**note:**__", "`" + currentUser.note + "`")
.setTimestamp()
.setFooter(`Requested by ${message.member.displayName} | react with a ❌ to delete`, `${message.author.displayAvatarURL()}`);
message.channel.send(userInfoEmbed).then(async sentMsg => {
await sentMsg.react('❌');
sentMsg.awaitReactions(async(reaction, user) => {
if (reaction.emoji.name === '❌') await sentMsg.delete();
});
/*
await sentMsg.react('❌');
const filter = (reaction, user) => ['❌'].includes(reaction.emoji.name) && user.id === message.author.id;
const [reaction] = await sentMsg.awaitReactions(filter, { maxMatches: 1 });
if (reaction.emoji.name === '❌') await sentMsg.delete();
*/
});
} else {
return message.reply("you cant do that only staff can").catch(e => console.log(e));
};
} catch (err) {
message.channel.send("an error happened. are they in the \"database\"?")
}
}
}

View file

@ -0,0 +1,86 @@
import { Client, ChatInputCommandInteraction, PermissionFlagsBits, SlashCommandBuilder } from "discord.js";
//@ts-expect-error
import YALAS from 'mcstatusbot-logger';
import * as AddReactionRole from './reactionrole/add';
import * as RemoveReactionRole from './reactionrole/remove';
import { GuildInstance } from "../../database/schemas/Guild";
import { UserInstance } from "../../database/schemas/User";
const data = {
serverOnly: false,
guildId: null,
allowSuspendedUserAccess: true,
command: new SlashCommandBuilder()
.setName('reactionrole')
.setDefaultMemberPermissions(PermissionFlagsBits.ManageRoles)
.setDescription("setup reaction roles for your server")
.addSubcommand(subcommand =>
subcommand
.setName('add')
.setDescription("Add a reaction role to your channel")
.addChannelOption(option =>
option.setName('channel')
.setDescription('The channel in which you want to add a reaction')
.setRequired(true)
)
.addStringOption(option =>
option.setName('emoji')
.setDescription('The reaction emoji')
.setRequired(true)
)
.addMentionableOption(option =>
option.setName('role')
.setDescription('The @ mention of the role you want to add')
.setRequired(true)
)
.addBooleanOption(o =>
o.setName('reaction-remove')
.setDescription("allow users to remove the role by unreacting")
.setRequired(true)
)
)
.addSubcommand(subcommand =>
subcommand
.setName('remove')
.setDescription("remove a reaction role")
.addChannelOption(option =>
option.setName('channel')
.setDescription('The channel in which you want to remove a reaction')
.setRequired(true)
)
.addStringOption(o =>
o
.setName('emoji')
.setDescription("the reaction emoji")
.setRequired(true)
)
)
.addSubcommand(subcommand =>
subcommand
.setName('edit-embed')
.setDescription("Edit the message embed sent with the list of reaction roles")
.addChannelOption(option =>
option.setName('channel')
.setDescription('The channel in which you want to edit the embed for')
.setRequired(true)
)
)
}
export { data };
export async function chatInputCommand(client: Client, interaction: ChatInputCommandInteraction, guild: GuildInstance, user: UserInstance) {
switch (interaction.options.getSubcommand()) {
case 'add':
AddReactionRole.chatInputCommand(client, interaction, guild, user)
break;
case 'remove':
RemoveReactionRole.chatInputCommand(client, interaction, guild, user)
break;
}
}

View file

@ -0,0 +1,161 @@
import { Client, ChatInputCommandInteraction, Role, GuildChannelResolvable, PermissionsBitField } from "discord.js";
import parseEmoji from "../../functions/parseEmoji";
import { schemas } from "../../../database";
//@ts-expect-error
import YALAS from 'mcstatusbot-logger';
import SendReactionRoleEmbed from "../../functions/SendReactionRoleEmbed";
import { GuildInstance } from "../../../database/schemas/Guild";
import { UserInstance } from "../../../database/schemas/User";
export async function chatInputCommand(client: Client, interaction: ChatInputCommandInteraction, guild: GuildInstance, user: UserInstance) {
if (!interaction.guild) return interaction.reply("must be done in discord server");
const botMember = interaction.guild.members.me;
if (!botMember) {
YALAS.error("reactionrole add: bot in guild null");
return;
}
//get and validate channel
const channel = interaction.options.getChannel('channel');
if (channel == undefined) {
return interaction.reply({
embeds: [{
title: "Channel Not Found",
description: "The selected channel could not be found please try again."
}]
});
}
if (channel.type !== 0) {
return interaction.reply({
embeds: [{
title: "That Will Not Work",
description: "The selected channel is not a text channel please select a text channel."
}]
});
}
const botPermSM = botMember.permissionsIn((channel as GuildChannelResolvable)).toArray();
if (botPermSM && !botPermSM.includes('SendMessages')) {
return interaction.reply({
embeds: [{
title: "Missing permission",
description: "you need to give me the send message permission in the selected channel."
}]
});
}
//check bot has manage roles perm
const botPermMR = botMember.permissions.has(PermissionsBitField.Flags.ManageRoles);
if (!botPermMR) {
return interaction.reply({
embeds: [{
title: "Missing permission",
description: "you need to give me the Manage Roles permission in this server."
}]
});
}
//get and validate emoji
const emoji = interaction.options.getString('emoji');
let cleanEmoji = parseEmoji(emoji);
if (cleanEmoji == null) {
return interaction.reply({
embeds: [{
title: "Invalid Emoji",
description: "The selected emoji is invalid please doublecheck it."
}]
});
}
//get and validate role
const role = interaction.options.getMentionable('role');
if (!(role instanceof Role)) {
return interaction.reply({
embeds: [{
title: "Invalid Role",
description: "The selected role is not a valid role"
}]
});
}
//check bot can assign role
const botHighestRole = botMember.roles.highest;
if (role.position >= botHighestRole.position) {
return interaction.reply({
embeds: [{
title: "Missing permission",
description: `The role <@&${role.id}> is higher than my role so I can't assign it to users.`
}]
});
}
await interaction.deferReply();
//check emoji does net exist for reaction in channel
try {
const reactionRole = await schemas['ReactionRole'].findOne({
where: {
guild: guild.id,
channel: channel.id,
role: role.id,
reaction: cleanEmoji,
}
});
if (reactionRole !== null) {
return interaction.editReply({
embeds: [{
title: "Reaction Role Exists",
description: "This emoji is already setup to give selected role in selected channel."
}]
});
}
} catch (err: any) {
YALAS.error(err)
YALAS.error(err.stack || err);
return interaction.editReply("error when checking for existing reaction role in database.");
}
const allowReactionRemove: boolean = interaction.options.getBoolean('reaction-remove') || false;
try {
await schemas['ReactionRole'].create({
guild: guild.id,
channel: channel.id,
role: role.id,
reaction: cleanEmoji,
reactionRemove: allowReactionRemove
});
} catch (err: any) {
YALAS.error(err.stack || err);
return interaction.editReply("error when saving reaction role to database.");
}
try {
const textChannel = interaction.guild?.channels.cache.get(channel.id);
if (textChannel === undefined || textChannel.type !== 0) return;
const embed = await SendReactionRoleEmbed(textChannel, guild.id, channel.id);
return interaction.editReply({
embeds: [{
title: "Success",
description: "The reaction role has been created and a new embed sent.\n-# Note you will need to delete the old embed"
}]
});
} catch (err: any) {
YALAS.error(err.stack || err);
return interaction.editReply("error when making reaction role embed.");
}
}

View file

@ -0,0 +1,113 @@
import { GuildInstance } from "../../../database/schemas/Guild";
import { UserInstance } from "../../../database/schemas/User";
import { Client, ChatInputCommandInteraction, Role, GuildChannelResolvable, TextChannel } from "discord.js";
import parseEmoji from "../../functions/parseEmoji";
import { schemas } from "../../../database";
//@ts-expect-error
import YALAS from 'mcstatusbot-logger';
import SendReactionRoleEmbed from "../../functions/SendReactionRoleEmbed";
export async function chatInputCommand(client: Client, interaction: ChatInputCommandInteraction, guild: GuildInstance, user: UserInstance) {
if (!interaction.guild) return interaction.reply("must be done in discord server");
//get and validate channel
const channel = interaction.options.getChannel('channel');
if (channel == undefined) {
return interaction.reply({
embeds: [{
title: "Channel Not Found",
description: "The selected channel could not be found please try again."
}]
});
}
if (channel.type !== 0) {
return interaction.reply({
embeds: [{
title: "That Will Not Work",
description: "The selected channel is not a text channel please select a text channel."
}]
});
}
const botPermissionsIn = interaction.guild.members.me?.permissionsIn((channel as GuildChannelResolvable)).toArray();
if (botPermissionsIn && !botPermissionsIn.includes('SendMessages')) {
return interaction.reply({
embeds: [{
title: "Missing permission",
description: "you need to give me the send message permission in the selected channel."
}]
});
}
//get and validate emoji
const emoji = interaction.options.getString('emoji');
let cleanEmoji = parseEmoji(emoji);
if (cleanEmoji == null) {
return interaction.reply({
embeds: [{
title: "Invalid Emoji",
description: "The selected emoji is invalid please doublecheck it."
}]
});
}
await interaction.deferReply();
try {
const reactionRoles = await schemas['ReactionRole'].findAll({
where: {
guild: guild.id,
channel: channel.id,
reaction: cleanEmoji,
},
raw: true
});
if (reactionRoles.length <= 0) {
return interaction.editReply({
embeds: [{
title: "Reaction Role(s) Doesn't Exists",
description: "This reaction could not be found in the selected channel."
}]
});
}
for (const rr of reactionRoles) {
try {
await schemas['ReactionRole'].destroy({ where: { id: rr.id } });
} catch (err: any) {
YALAS.error(err.stack || err);
continue;
}
}
} catch (err: any) {
YALAS.error(err)
YALAS.error(err.stack || err);
return interaction.editReply("error when getting and deleting reaction role in database.");
}
try {
const textChannel = interaction.guild?.channels.cache.get(channel.id);
if (textChannel === undefined || textChannel.type !== 0) return;
const embed = await SendReactionRoleEmbed(textChannel, guild.id, channel.id);
return interaction.editReply({
embeds: [{
title: "Success",
description: "The reaction role(s) have been removed and a new embed sent.\n-# Note you will need to delete the old embed"
}]
});
} catch (err: any) {
YALAS.error(err.stack || err);
return interaction.editReply("error when making reaction role embed.");
}
}

View file

@ -0,0 +1,48 @@
import { Client, ChatInputCommandInteraction, PermissionFlagsBits, SlashCommandBuilder } from "discord.js";
import { schemas } from "../../database/index";
//@ts-expect-error
import YALAS from 'mcstatusbot-logger';
import { GuildInstance } from "../../database/schemas/Guild";
import { UserInstance } from "../../database/schemas/User";
const data = {
serverOnly: false,
guildId: null,
allowSuspendedUserAccess: true,
command: new SlashCommandBuilder()
.setName('setprefix')
.setDescription("sets the message prefix for your server")
.setDefaultMemberPermissions(PermissionFlagsBits.ManageGuild)
.addStringOption(o =>
o.setName('prefix')
.setDescription("the prefix eg . or !")
.setRequired(true)
)
}
export { data };
export async function chatInputCommand(client: Client, interaction: ChatInputCommandInteraction, guild: GuildInstance, user: UserInstance) {
const prefix = interaction.options.getString('prefix');
if (prefix == undefined) return;
const prefixLower = prefix.toLowerCase();
if (prefix.length > 3) return interaction.reply("the is to long, limit is 3");
if (guild.prefix === prefixLower) return interaction.reply("the prefix `" + guild.prefix + "` has been set");
try {
await schemas['Guild'].update({
prefix: prefixLower
}, {
where: { id: guild.id }
});
return interaction.reply("the prefix `" + prefixLower + "` has been set");
} catch (err: any) {
YALAS.error(err.stack || err);
return interaction.reply("failed to update prefix.");
}
}

View file

@ -1,8 +0,0 @@
const conf = require('../../conf/conf.json')
module.exports = {
name: 'error',
async exe(client, Discord, error) {
//one day i will saves these to a file or something
console.log(error)
}
}

View file

@ -1,55 +0,0 @@
const conf = require('../../conf/conf.json')
module.exports = {
name: 'guildMemberAdd',
async exe(client, Discord, member) {
try {
member.guild.fetchInvites().then(guildInvites => {
const inviteGuild = invites;
const invite = guildInvites.find(i => inviteGuild.get(i.code).uses < i.uses);
const inviter = client.users.cache.get(invite.inviter.id);
const inviteLogEmbed = {
color: `${conf.colour.ok}`,
title: 'invite',
url: `${conf.domain}`,
author: {
name: conf.bot.name
},
thumbnail: {
url: `${conf.server.logo}`,
},
description: `${member.user.discriminator} (${member.user.id}) joined using invite code ${invite.code} from ${inviter.tag} (${inviter.id}). Invite was used ${invite.uses} times since its creation.`,
fields: [{
name: 'Member joined:',
value: `${member.user.discriminator} (${member.user.id})`,
},
{
name: 'Inviter:',
value: `${inviter.tag} (${inviter.id})`,
},
{
name: 'Invite Code:',
value: `[https://discord.gg/${invite.code}](https://discord.gg/${invite.code})`,
},
{
name: 'Invite Uses:',
value: `${invite.uses}`,
},
{
name: 'Time of Invite:',
value: `${new Date()}`,
}
],
timestamp: new Date(),
footer: {
text: 'moderation logs'
},
};
member.guild.channels.cache.get(conf.server.channels.modLogs).send({ embed: inviteLogEmbed });
invites = guildInvites;
});
} catch (error) {
require('../conf/functions.js').reportError(client, conf, "guildMemberAdd", error, { name: null, id: null })
}
}
}

View file

@ -1,74 +0,0 @@
const conf = require('../../conf/conf.json')
const getGuild = require('../../funcs/getserver');
const getUser = require('../../funcs/getuser');
function addCmd(message) {
}
module.exports = {
name: 'message',
async exe(client, Discord, message) {
if (message.author.bot || !message.guild) return;
let currentServer = await getGuild(message);
let messageUser = await getUser(message);
if (currentServer == null) return;
['caps', 'swearfilter'].forEach(addon => {
require(`../addons/${addon}`)(message, currentServer, messageUser, client);
})
//eval command
if (message.content.toLowerCase().startsWith("--eval")) {
const evalargs = message.content.split(" ").slice(1);
function clean(text) {
if (typeof(text) === "string") {
return text.replace(/`/g, "`" + String.fromCharCode(8203)).replace(/@/g, "@" + String.fromCharCode(8203));
} else {
return text;
}
}
if (message.author.id !== conf.owner) return message.channel.send("no you cant do that, only <@!522534458071449620> can.");
if (message.author.id == conf.owner) {
try {
const code = evalargs.join(" ");
let evaled = eval(code);
if (typeof evaled !== "string") {
evaled = require("util").inspect(evaled);
}
message.channel.send(clean(evaled), { code: "xl" });
} catch (err) {
message.channel.send(`\`ERROR\` \`\`\`xl\n${clean(err)}\n\`\`\``);
}
}
}
let args = message.content.toLowerCase().substring(currentServer.prefix.length).split(" ");
if (!message.content.startsWith(currentServer.prefix)) return;
//otr commands
if (message.author.id == conf.cwh11) {
require('../../funcs/otr').otrCommand(message, args, Discord, currentServer, messageUser, client);
};
//dynamic get command name or prefix
if (client.commands.has(args[0])) {
try {
client.commands.get(args[0]).execute(message, args, Discord, currentServer, messageUser, client);
addCmd(message);
} catch (error) {
message.reply('there was an error with that command!');
};
} else if (client.commands.find(command => command.aliases && command.aliases.includes(args[0]))) {
try {
client.commands.find(command => command.aliases && command.aliases.includes(args[0])).execute(message, args, Discord, currentServer, messageUser, client);
addCmd(message);
} catch (error) {
message.reply('there was an error with that command!');
};
};
}
}

View file

@ -1,26 +0,0 @@
const Server = require('../../models/server');
module.exports = {
name: 'messageReactionAdd',
async exe(client, Discord, reaction, user) {
let currentServer = await Server.findOne({ id: reaction.message.guild.id });
if (currentServer == null) return;
if (!reaction.message.guild || user.bot) return;
if (reaction.message.partial) await reaction.message.fetch();
if (reaction.partial) await reaction.fetch();
let member = await reaction.message.guild.members.fetch(user.id);
try {
currentServer.reactionRoles.forEach(role => {
if (reaction.message.channel.id == role.channelID) {
if (reaction.emoji.name == role.emoji) {
let rr = client.guilds.cache.get(reaction.message.guild.id).roles.cache.get(role.roleID);
member.roles.add(rr).catch(e => console.log(e));
};
};
});
} catch (error) {
return console.log(error)
};
}
}

View file

@ -1,29 +0,0 @@
const Server = require('../../models/server');
const conf = require('../../conf/conf.json')
module.exports = {
name: 'messageReactionRemove',
async exe(client, Discord, reaction, user) {
let currentServer = await Server.findOne({ id: reaction.message.guild.id });
if (currentServer == null) return;
if (!reaction.message.guild || user.bot) return;
if (reaction.message.partial) await reaction.message.fetch();
if (reaction.partial) await reaction.fetch();
let member = await reaction.message.guild.members.fetch(user.id);
try {
currentServer.reactionRoles.forEach(role => {
if (reaction.message.channel.id == role.channelID) {
if (reaction.emoji.name == role.emoji) {
let rr = client.guilds.cache.get(reaction.message.guild.id).roles.cache.get(role.roleID);
member.roles.remove(rr).catch(e => console.log(e));
};
};
});
} catch (error) {
return console.log(error)
};
}
}

View file

@ -1,9 +0,0 @@
const { green } = require('chalk');
const conf = require('../../conf/conf.json');
module.exports = {
name: 'ready',
async exe(client) {
console.log(green('[bot]: ') + `${client.user.tag}` + " is online");
console.log("Ready!");
}
}

View file

@ -1,71 +0,0 @@
const Server = require("../../models/server");
const conf = require('../../conf/conf.json')
var members = [];
module.exports = {
members: members,
name: 'voiceStateUpdate',
async exe(client, Discord, oldMember, newMember) {
try {
let newUserChannel = newMember.channelID;
let oldUserChannel = oldMember.channelID;
const currentServer = await Server.findOne({ id: newMember.guild.id });
if (currentServer == null) return;
if (currentServer.channels.townhall == ' ' || currentServer.channels.townhallLogs == ' ') return;
if (newUserChannel == currentServer.channels.townhall) {
let isStaff;
if (client.guilds.cache.get(currentServer.id).members.cache.get(newMember.id).roles.cache.find(r => currentServer.staffRoles.includes(r.name))) {
isStaff = 'yes';
} else {
isStaff = 'no';
};
if (!members[newMember.guild.id]) {
members[newMember.guild.id] = [];
};
if (!members[newMember.guild.id].includes(newMember.id)) {
members[newMember.guild.id].push(newMember.id)
};
const e6 = {
color: conf.colour.ok,
title: 'User joinded Town hall vc',
author: {
name: client.users.cache.get(newMember.id).tag,
icon_url: client.users.cache.get(newMember.id).avatarURL()
},
description: "a new member has joined the town hall VC.\nto get all members that have joined during this session do `" + currentServer.prefix + "townhall`.",
fields: [{
name: '**__name:**__',
value: client.users.cache.get(newMember.id).tag,
},
{
name: '__**id:**__',
value: newMember.id,
},
{
name: '__**@ mention**__',
value: '<@!' + newMember.id + '>'
},
{
name: '__**is staff**__',
value: isStaff
},
{
name: '__**join position:**__',
value: members.length
},
],
timestamp: new Date(),
footer: {
text: 'TownHall Meeting Log'
},
};
client.guilds.cache.get(currentServer.id).channels.cache.get(currentServer.channels.townhallLogs).send({ embed: e6 });
};
} catch (error) {
console.log(error)
}
}
}

View file

@ -0,0 +1,59 @@
import { Client, MessageReaction, PartialMessageReaction, User, PartialUser, Guild, Role, GuildMember } from "discord.js";
import { schemas } from "../../database";
//@ts-expect-error
import * as YALAS from 'mcstatusbot-logger';
export default async function ReactionRoleAddHandler(reaction: MessageReaction | PartialMessageReaction, user: User | PartialUser) {
const emoji: string | null = reaction.emoji.id ?? reaction.emoji.name;
const guild: Guild | null = reaction.message.guild;
const channelId: string = reaction.message.channelId;
if (guild === null || emoji === null) return YALAS.error("failed to find guild");
async function getRole(roleId: string) {
if (!guild) return null;
let role: Role | null | undefined = guild.roles.cache.get(roleId);
if (role) return role
try {
role = await guild.roles.fetch(roleId);
} catch (error) {
YALAS.error('Error fetching role:');
YALAS.error(error);
return null;
}
if (role) return role
return null;
}
const reactionRoles = await schemas['ReactionRole'].findAll({
where: {
guild: guild.id,
channel: channelId,
reaction: emoji,
},
raw: true
});
for (const rRole of reactionRoles) {
let role = await getRole(rRole.role);
if (role == null) return YALAS.error("failed to find role '" + rRole.role + "' in guild '" + guild.id + "' ")
// Fetch role if not cached
// Get the member from the user
const member: GuildMember | null = guild.members.cache.get(user.id) || (await guild.members.fetch(user.id).catch(() => null));
if (!member) return YALAS.error("Member not found in the guild '" + guild.id + "'");
// Add the role to the member
try {
await member.roles.add(role);
if (process.env.DEBUG === 'true') YALAS.info(`Added role "${role.name}" to user "${user.tag}".`);
} catch (error) {
YALAS.error("Error adding role '" + role.id + "' to user '" + user.id + "' for guild '" + guild.id + "'");
YALAS.error(error);
}
}
}

View file

@ -0,0 +1,29 @@
import { schemas } from "../../database";
//@ts-expect-error
import * as YALAS from 'mcstatusbot-logger';
import { GuildAttributes } from "../../database/schemas/Guild";
import { Guild } from "discord.js";
export default async function LookupGuild(guild: Guild | null): Promise<GuildAttributes | null> {
if (guild == null) return null;
try {
let guildDoc = await schemas['Guild'].findOne({ where: { id: guild.id } });
if (guildDoc !== null && guildDoc !== undefined) return guildDoc.dataValues;
//TODO: implement a check to update guild name owner etc
//TODO: make a webhook for defualt guild channel so can then be used and changed when needed for macro cmds
guildDoc = await schemas['Guild'].create({
id: guild.id,
name: guild.name,
icon: guild.iconURL(),
owner: guild.ownerId
});
return guildDoc.dataValues;
} catch (err: any) {
YALAS.error(err);
YALAS.error(err.stack || err);
return null;
}
}

View file

@ -0,0 +1,25 @@
import { User } from "discord.js";
import { schemas } from "../../database";
//@ts-expect-error
import * as YALAS from 'mcstatusbot-logger';
import { UserAttributes } from '../../database/schemas/User';
export default async function LookupUser(user: User | null): Promise<UserAttributes | null> {
if (user === null) return null
let userDoc;
try {
userDoc = await schemas['User'].findOne({ where: { id: user.id } });
if (userDoc !== null) return userDoc.dataValues;
//TODO: implement check to update username avatar etc
userDoc = await schemas['User'].create({
id: user.id,
username: user.username,
avatar: user.avatar,
admin: false,
});
return userDoc.dataValues;
} catch (err: any) {
YALAS.error(err);
YALAS.error(err.stack || err);
return null;
}
}

View file

@ -0,0 +1,33 @@
export default class PrefixCache {
private cache = new Map<string, string>();
// Add a value to the cache
set(key: string, value: string): void {
this.cache.set(key, value);
}
// Retrieve a value from the cache
get(key: string): string | null {
return this.cache.get(key)??null;
}
// Check if a key exists in the cache
has(key: string): boolean {
return this.cache.has(key);
}
// Remove a key from the cache
delete(key: string): void {
this.cache.delete(key);
}
// Clear the entire cache
clear(): void {
this.cache.clear();
}
// Get the current size of the cache
size(): number {
return this.cache.size;
}
}

View file

@ -0,0 +1,66 @@
import { Client, MessageReaction, PartialMessageReaction, User, PartialUser, Guild, Role, GuildMember, TextChannel } from "discord.js";
import { schemas } from "../../database";
//@ts-expect-error
import * as YALAS from 'mcstatusbot-logger';
export default async function ReactionRoleAddHandler(reaction: MessageReaction | PartialMessageReaction, user: User | PartialUser) {
if (reaction.message.guild === undefined) return;
const emoji: string | null = reaction.emoji.id ?? reaction.emoji.name;
const guild: Guild | null = reaction.message.guild;
const channel = reaction.message.channel;
if (guild === null || emoji === null) return YALAS.error("failed to find guild");
async function getRole(roleId: string) {
if (!guild) return null;
let role: Role | null | undefined = guild.roles.cache.get(roleId);
if (role) return role
try {
role = await guild.roles.fetch(roleId);
} catch (error) {
YALAS.error('Error fetching role:');
YALAS.error(error);
return null;
}
if (role) return role
return null;
}
// Get the member from the user
const member: GuildMember | null = guild.members.cache.get(user.id) || (await guild.members.fetch(user.id).catch(() => null));
if (!member) return YALAS.error("Member not found in the guild '" + guild.id + "'");
const reactionRoles = await schemas['ReactionRole'].findAll({
where: {
guild: guild.id,
channel: channel.id,
reaction: emoji,
},
raw: true
});
for (const rRole of reactionRoles) {
let role = await getRole(rRole.role);
if (role == null) return YALAS.error("failed to find role '" + rRole.role + "' in guild '" + guild.id + "' ")
//TODO: mod channel logs ad role error etc
// Add the role to the member
try {
await member.roles.add(role);
if (process.env.DEBUG === 'true') YALAS.info(`Added role "${role.name}" to user "${user.tag}".`);
} catch (error) {
//TODO: implement ignore reaction reomve when using this
//reaction.users.remove(user.id);
//@ts-expect-error
const errUsrMsg = await channel.send(`Sorry <@!${user.id}>, that did not work please try again later or ask a moderator.`);
setTimeout(() => {
errUsrMsg.delete().catch((e: any) => null);
}, 3500);
YALAS.error("Error adding role '" + role.id + "' to user '" + user.id + "' for guild '" + guild.id + "'");
YALAS.error(error);
}
}
}

View file

@ -0,0 +1,66 @@
import { Client, MessageReaction, PartialMessageReaction, User, PartialUser, Guild, Role, GuildMember, TextChannel, flatten } from "discord.js";
import { schemas } from "../../database";
//@ts-expect-error
import * as YALAS from 'mcstatusbot-logger';
export default async function ReactionRoleRemoveHandler(reaction: MessageReaction | PartialMessageReaction, user: User | PartialUser) {
if (reaction.message.guild === undefined) return;
const emoji: string | null = reaction.emoji.id ?? reaction.emoji.name;
const guild: Guild | null = reaction.message.guild;
const channel = reaction.message.channel;
if (guild === null || emoji === null) return YALAS.error("failed to find guild");
async function getRole(roleId: string) {
if (!guild) return null;
let role: Role | null | undefined = guild.roles.cache.get(roleId);
if (role) return role
try {
role = await guild.roles.fetch(roleId);
} catch (error) {
YALAS.error('Error fetching role:');
YALAS.error(error);
return null;
}
if (role) return role
return null;
}
// Get the member from the user
const member: GuildMember | null = guild.members.cache.get(user.id) || (await guild.members.fetch(user.id).catch(() => null));
if (!member) return YALAS.error("Member not found in the guild '" + guild.id + "'");
const reactionRoles = await schemas['ReactionRole'].findAll({
where: {
guild: guild.id,
channel: channel.id,
reaction: emoji,
},
});
for (let rRole of reactionRoles) {
let role = await getRole(rRole.dataValues.role);
if (role == null) return YALAS.error("failed to find role '" + rRole.role + "' in guild '" + guild.id + "' ")
if (rRole.dataValues.reactionRemove === false) continue;
// Add the role to the member
try {
await member.roles.remove(role);
if (process.env.DEBUG === 'true') YALAS.info(`Added role "${role.name}" to user "${user.tag}".`);
} catch (error) {
reaction.users.remove(user.id);
//@ts-expect-error
const errUsrMsg = await channel.send(`Sorry <@!${user.id}>, that did not work please try again later or ask a moderator.`);
setTimeout(() => {
errUsrMsg.delete().catch((e: any) => null);
}, 3500);
YALAS.error("Error removingW role '" + role.id + "' to user '" + user.id + "' for guild '" + guild.id + "'");
YALAS.error(error);
}
}
//TODO: log roles added to user/errors
}

View file

@ -0,0 +1,71 @@
import { EmbedBuilder, ColorResolvable, TextChannel } from 'discord.js';
import { schemas } from '../../database';
import { ReactionRoleInstance } from '../../database/schemas/ReactionRole';
function isOnlyNumbers(str: string): boolean {
return /^\d+$/.test(str);
}
interface GroupedReactionRole {
reaction: string;
roles: string[]
}
function groupReactionRoles(reactionRoles: ReactionRoleInstance[]): GroupedReactionRole[] {
return reactionRoles.reduce((acc, item) => {
const { reaction, role } = item;
// Find if the reaction already exists in the accumulator
let existing = acc.find(group => group.reaction === reaction);
if (existing) {
existing.roles.push(role);
} else {
// Otherwise, create a new group for this reaction
acc.push({
reaction,
roles: [role],
});
}
return acc;
}, [] as GroupedReactionRole[]);
}
export default async function SendReactionRoleEmbed(roleChannel: TextChannel, guildId: string, channelId: string) {
let config = { where: { guild: guildId, channel: channelId }, raw: true };
let reactionRoleEmbedConfig = await schemas['ReactionRoleEmbed'].findOne(config);
if (reactionRoleEmbedConfig == null) {
reactionRoleEmbedConfig = await schemas['ReactionRoleEmbed'].create({ guild: guildId, channel: channelId }, { raw: true });
}
if (reactionRoleEmbedConfig === null) return { title: "error" };
let reactionRoles = await schemas['ReactionRole'].findAll(config);
let groupedReactionRoles = groupReactionRoles(reactionRoles);
//[[icon]] [[role]]
let description: string = "";
for (const rr of groupedReactionRoles) {
let roleRow = reactionRoleEmbedConfig.listItemTemplate.replace('[[icon]]', isOnlyNumbers(rr.reaction) ? `<:emoji:${rr.reaction}>` : rr.reaction).replace('[[roles]]', rr.roles.map(r => `<@&${r}>`).join(reactionRoleEmbedConfig.roleSeparator));
description += roleRow + '\n';
}
// inside a command, event listener, etc.
const embed = new EmbedBuilder()
.setColor((reactionRoleEmbedConfig.color as ColorResolvable))
.setTitle(reactionRoleEmbedConfig.title)
.setURL(reactionRoleEmbedConfig.icon)
//.setAuthor({ name: 'Some name', iconURL: 'https://i.imgur.com/AfFp7pu.png', url: 'https://discord.js.org' })
.setDescription(description.substring(0, 4096))
//.setFooter({ text: 'Some footer text here', iconURL: 'https://i.imgur.com/AfFp7pu.png' });
const reactionRoleEmbedMsg = await roleChannel.send({ embeds: [embed] });
for (const reactionRole of reactionRoles) {
await reactionRoleEmbedMsg.react(reactionRole.reaction);
}
return reactionRoleEmbedMsg;
}

View file

@ -0,0 +1,11 @@
export default function parseEmoji(input: string | null): string | null {
if (input === null || input == ' ' || input === ' ') return null;
const customEmojiMatch = input.match(/^<:.*:(\d+)>$/);
if (customEmojiMatch) return customEmojiMatch[1];
const unicodeEmojiRegex = /^[\p{Emoji_Presentation}\p{Emoji}\uFE0F]+$/u;
if (unicodeEmojiRegex.test(input)) return input;
return null;
}

View file

@ -0,0 +1,60 @@
import { Client, Interaction, ChatInputCommandInteraction, User } from "discord.js";
import { schemas } from '../../database/index';
//@ts-expect-error
import YALAS from 'mcstatusbot-logger';
import LookupUser from "../functions/LookupUser";
import LookupGuild from "../functions/LookupGuild";
async function chatInputCommand(client: Client, interaction: ChatInputCommandInteraction) {
if (!client.commands.has(interaction.commandName)) return YALAS.warn("no command found for interaction: " + interaction.commandName);
if (interaction.guild===null) return interaction.reply("only works in discord servers sorry.");
//get user from db
const user = await LookupUser(interaction.user)
if (user == null) return interaction.reply({
embeds: [{ title: "could not get your user info", description: "we could not get or create your user info to the bots database." }]
});
//get discord guild from db
const guild = await LookupGuild(interaction.guild);
if (guild == null) return interaction.reply({
embeds: [{ title: "could not get discord server", description: "we could not get or create your discord server to the bots database." }]
})
const command = client.commands.get(interaction.commandName);
if (command.data.allowSuspendedUserAccess == false && user.suspended == true) {
return interaction.reply({
embeds: [{
title: "You Are Suspended",
description: "Your account has been suspended/blocked from using this bot."
}]
});
}
try {
await command.chatInputCommand(client, interaction, guild, user);
} catch (err: any) {
YALAS.error("could not run command");
YALAS.error(err.stack || err)
}
}
export default async function InteractionCreate(client: Client, interaction: Interaction) {
if (interaction.member && interaction.member.user.bot) return;
//slash command
if (interaction.isChatInputCommand()) return chatInputCommand(client, interaction);
//modal/form
//if (interaction.isModalSubmit()) return modalSubmit(client, interaction, guild, user);
}

View file

@ -0,0 +1,74 @@
import { Client, Guild, Message } from "discord.js";
import MessageMacro from "../messageHandler/plugins/MesageMacro";
import { schemas } from "../../database";
import LookupUser from "../functions/LookupUser";
//@ts-expect-error
import * as YALAS from 'mcstatusbot-logger';
import { UserAttributes } from "../../database/schemas/User";
import { GuildAttributes } from "../../database/schemas/Guild";
import LookupGuild from "../functions/LookupGuild";
import { MessageCreateOptions } from "../../../types/MessageCreate";
import PrefixCache from "../functions/PrefixCache";
function splitAndRemovePrefix(prefix: string, content: string): string[] {
if (content.startsWith(prefix)) {
content = content.slice(prefix.length).trim();
}
return content.split(/\s+/);
}
const guildPrefixs = new PrefixCache();
async function getGuildPrefix(guild: Guild) {
let p = guildPrefixs.get(guild.id);
console.log("p: "+p)
if (p !== null) return p;
let guildDoc: GuildAttributes | null = await schemas['Guild'].findOne({
where: { id: guild.id },
attributes: ['prefix'],
raw: true,
});
if (guildDoc === null) {
guildDoc = await LookupGuild(guild);
if (guildDoc === null) {
YALAS.error("MessageCreate: guild '" + guild.id + "' will not add to db");
return null;
}
}
guildPrefixs.set(guild.id, guildDoc.prefix);
p = guildDoc.prefix;
return p;
}
async function GuildMsg(client: Client, msg: Message) {
if (msg.guild === null) return;
const prefix: string | null = await getGuildPrefix(msg.guild);
//r
if (prefix===null) return;
if (!msg.content.toLowerCase().startsWith(prefix)) return;
const msgCmds: string[] = splitAndRemovePrefix(prefix, msg.content);
try {
await MessageMacro(client, msg, msgCmds);
} catch (err: any) {
YALAS.error("MessageCreate: failed to run message macro plugin");
YALAS.error(err.stack || err);
}
return;
}
export default async function MessageCreate(client: Client, msg: Message) {
await GuildMsg(client, msg);
return;
}

View file

@ -0,0 +1,36 @@
import { Client, MessageReaction, PartialMessageReaction, User, PartialUser } from "discord.js";
import ReactionRoleAddHandler from "../functions/ReactionRoleAddHandler";
//@ts-expect-error
import * as YALAS from 'mcstatusbot-logger';
export default async function MessageReactionAdd(client: Client, reaction: MessageReaction | PartialMessageReaction, user: User | PartialUser) {
if (reaction.partial) {
console.log("reaction partial")
try {
await reaction.fetch();
} catch (error) {
YALAS.error('Something went wrong when fetching the message:', error);
return;
}
}
if (!reaction.message.guild) return;
if (user.partial) {
console.log("user partial")
try {
await user.fetch();
} catch (error) {
YALAS.error('Something went wrong when fetching the user:', error);
return;
}
}
if (user.id===client.user?.id) return;
await ReactionRoleAddHandler(reaction, user);
//TODO: ban role hndler
//TODO: kick role handler
return;
}

View file

@ -0,0 +1,31 @@
import { Client, MessageReaction, PartialMessageReaction, User, PartialUser } from "discord.js";
import ReactionRoleRemoveHandler from "../functions/ReactionRoleRemoveHandler";
//@ts-expect-error
import * as YALAS from 'mcstatusbot-logger';
export default async function MessageReactionRemove(client: Client, reaction: MessageReaction | PartialMessageReaction, user: User | PartialUser) {
if (!reaction.message.guild) return;
// When a reaction is received, check if the structure is partial
if (reaction.partial) {
console.log("reaction partial")
try {
await reaction.fetch();
} catch (error) {
YALAS.error('Something went wrong when fetching the message:', error);
// Return as `reaction.message.author` may be undefined/null
return;
}
}
if (user.partial) {
console.log("user partial")
try {
await user.fetch();
} catch (error) {
YALAS.error('Something went wrong when fetching the user:', error);
return;
}
}
if (user.id === client.user?.id) return;
await ReactionRoleRemoveHandler(reaction, user);
return;
}

19
src/bot/handlers/Ready.ts Normal file
View file

@ -0,0 +1,19 @@
import { Client, ActivityType } from 'discord.js';
//@ts-expect-error
import YALAS from 'mcstatusbot-logger';
export default function Ready(client: Client) {
console.log("Ready!");
YALAS.success("The bot is up and running!");
YALAS.info(`logged in as ${client.user?.username}#${client.user?.tag}`);
//TODO: have list of messages in const folder and cycle them allow super admins (ids list in env file) to add from web ui
// Update activity every hour so that it doesn't expire
if (client.user) client.user.setActivity("you", { type: ActivityType.Watching });
setInterval(() => {
if (client.user) client.user.setActivity("you", { type: ActivityType.Watching });
}, 3600000);
}

View file

@ -1,13 +0,0 @@
const { readdirSync } = require("fs");
const chalk = require('chalk');
module.exports = (client) => {
const addons = readdirSync(__dirname + '/../addons/').filter((file) => file.endsWith(".js"));
for (let addonFile of addons) {
try {
console.log(chalk.green('[addon handler]: ') + " found '" + addonFile + "'");
} catch (error) {
console.log(chalk.green('[addon handler]: ') + chalk.red('(error): ') + "unhandled error: " + error);
continue;
}
}
};

View file

@ -1,37 +0,0 @@
const { readdirSync } = require("fs");
const chalk = require('chalk');
let chalkColour;
module.exports = (client) => {
readdirSync(__dirname + "/../commands/").forEach((dir) => {
const commands = readdirSync(__dirname + `/../commands/${dir}/`).filter((file) => file.endsWith(".js"));
for (let file of commands) {
let cmd = require(__dirname + `/../commands/${dir}/${file}`);
if (cmd.name && cmd.description) {
switch (dir) {
case 'fun':
chalkColour = 'green'
break;
case 'moderaton':
chalkColour = 'blue'
break;
case 'info':
chalkColour = 'cyan'
break;
default:
chalkColour = 'green'
}
try {
client.commands.set(cmd.name, cmd);
console.log(chalk.yellow('[command handler]: ') + chalk[chalkColour]('(' + dir + '): ') + "name: " + cmd.name + " path: " + `./commands/${dir}/${file}`);
} catch (error) {
console.log(chalk.yellow('[command handler]: ') + chalk.red('(command error): ') + "adding command. path: " + `./commands/${dir}/${file}`);
console.log("eeer: " + error)
continue;
}
} else {
console.log(chalk.yellow('[command handler]: ') + chalk.red('(command error): ') + "command dosnt contain a name or description. path: " + `./commands/${dir}/${file}`);
continue;
}
}
});
};

View file

@ -1,10 +0,0 @@
const chalk = require('chalk');
const { readdirSync } = require("fs");
const Discord = require('discord.js');
module.exports = (client) => {
const eventFiles = readdirSync(__dirname + '/../events/').filter(file => file.endsWith('.js'));
for (const file of eventFiles) {
const event = require(__dirname + `/../events/${file}`);
client.on(event.name, async(...args) => event.exe(client, Discord, ...args));
};
}

44
src/bot/index.ts Normal file
View file

@ -0,0 +1,44 @@
import { readdirSync } from 'fs';
import { Client, Collection, GatewayIntentBits, Interaction, Events, Partials } from 'discord.js';
import Ready from './handlers/Ready';
import InteractionCreate from './handlers/InteractionCreate';
import MessageCreate from './handlers/MessageCreate';
import MessageReactionAdd from './handlers/MessageReactionAdd';
import MessageReactionRemove from './handlers/MessageReactionRemove';
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.GuildMessageReactions,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildPresences
],
partials: [Partials.Message, Partials.Channel, Partials.Reaction],
});
//load in slash commands
client.commands = new Collection();
const commands: string[] = readdirSync(__dirname + '/commands').filter((file: string) => file.endsWith('.js') || file.endsWith('.ts'));
for (const c of commands) {
const command = require(__dirname + '/commands/' + c);
if (!command.data.command) continue;
if (!command.data.command.name) continue;
client.commands.set(command.data.command.name, command);
}
client.once(Events.ClientReady, () => Ready(client));
client.on(Events.InteractionCreate, (interaction: Interaction) => InteractionCreate(client, interaction));
client.on(Events.MessageCreate, (msg) => MessageCreate(client, msg))
client.on(Events.MessageReactionAdd, (reaction, user) => MessageReactionAdd(client, reaction, user))
client.on(Events.MessageReactionRemove, (reaction, user) => MessageReactionRemove(client, reaction, user))
export async function login(): Promise<boolean> {
await client.login(process.env.BOT_TOKEN);
return true;
}

View file

@ -0,0 +1,37 @@
import { CategoryChannel, Client, DMChannel, GuildBasedChannel, Message, NewsChannel, TextChannel, ThreadChannel } from "discord.js";
import { UserAttributes } from "../../../database/schemas/User";
import { GuildAttributes, GuildInstance } from "../../../database/schemas/Guild";
import { MessageCreateOptions } from "../../../../types/MessageCreate";
import { schemas } from "../../../database";
import LookupGuild from "../../functions/LookupGuild";
//@ts-expect-error
import * as YALAS from 'mcstatusbot-logger';
export default async function MessageMacro(client: Client, msg: Message, msgCmds: string[]) {
if (msg.guild === null) return;
if (msg.member === null) return;
const guild: GuildAttributes | null = await LookupGuild(msg.guild);
if (guild == null) return YALAS.error("MessageCreate guild null")
const msgMacroDoc = await schemas['MessageMacro'].findOne({
where: {
guild: guild.id,
shortCode: msgCmds[0]
}
});
if (msgMacroDoc === null) return;
const msgMacro = msgMacroDoc.dataValues;
if (!msg.member.roles.cache.has(msgMacro.role)) return;
if (msgMacro.deleteShortCode === true) msg.deletable ?? msg.delete().catch((err: any) => null);
let channel = msgMacro.channel === null ? msg.channel : await msg.guild.channels.fetch(msgMacro.channel);
if (channel === null || channel === undefined) return;
if (!(channel instanceof TextChannel || channel instanceof DMChannel || channel instanceof NewsChannel || channel instanceof ThreadChannel)) return;
await channel.send(msgMacro.message);
return;
}

View file

@ -1,24 +0,0 @@
{
"prefix": ".",
"owner": "522534458071449620",
"domain": "http://localhost:4758",
"port": "4758",
"cwh11": "276156203770314755",
"colour": {
"ok": "#ff0000",
"error": "#ff5733"
},
"mainServer": {
"invite": "https://discord.gg/52AugmVzjt",
"id": "here"
},
"bot": {
"name": "knightrider",
"logo": "https://cdn.discordapp.com/icons/584484766997282836/337d9f62b88bc8d343be2bb3bc90292f.png",
"url": "http://knightrider.invalidlag.com/me"
},
"webServer": {
"port": 4758,
"oauthURI": "here"
}
}

View file

@ -1,105 +0,0 @@
/*
* licence https://github.com/404invalid-user/knightrider/blob/main/LICENCE
*/
const { User } = require('discord.js');
const User = require('../models/user');
const Server = require('../models/server');
const getServer = require('../funcs/getserver');
module.exports = {
reportError: function(client, conf, task, error, user) {
const errorEmbed = {
color: `${conf.colour.okError}`,
title: 'Error',
url: `${conf.domain}`,
author: {
name: conf.bot.name
},
thumbnail: {
url: `${conf.server.logo}`,
},
description: `there has been an error executing somthing this will be somthing from a automated script or a member using the bot\nthe infromation below can be sensative **do not share** this with anyone unless you know what to hide:`,
fields: [{
name: '__**task:**__',
value: `\`${task}\``,
},
{
name: '__**Error**__',
value: `\`${error}\``,
},
{
name: '__**user who triggered it**__',
value: `__name:__ \`${currentUser.userName}\`\n__id:__ \`${user.id}\``,
}
],
timestamp: new Date(),
footer: {
text: 'Owner Error Log'
},
};
client.users.cache.get(conf.owner).send({ embed: errorEmbed });
},
addCmd: async function(message) {
let currentServer = await Server.findOne({ id: message.guild.id });
currentServer.commandCount++;
currentServer.save();
},
addstrike: async function(message) {
let currentUser = await User.findOne({ id: message.author.id })
if (currentUser == null) {
await User.create({
id: message.author.id,
avatar: message.author.avatarURL()
})
currentUser = await User.findOne({ id: message.author.id })
}
currentUser.strike++;
currentUser.save()
},
otrCommand: async function(message, args, Discord, client) {
if (message.author.id == conf.cwh11) {
let server = getServer(message);
if (server == null) return message.channel.send("this server isnt in the db");
const annoncmentsChannel = client.channels.cache.get(server.channels.annoncments);
switch (args[0]) {
case 'ito':
await message.delete().catch(e => message.channel.send("i cant auto delete the messag you sent have i got permission to send messages in <#" + message.channel.id + ">?"));
annoncmentsChannel.send("@here Hey guys! Charlie is in the office. Join him in voice if you want.").catch(e => message.channel.send("i cant do that have i got permission to send messages in <#" + channels.annoncments + ">?"));
break;
case 'otrf':
await message.delete().catch(e => message.channel.send("i cant auto delete the messag you sent have i got permission to send messages in <#" + message.channel.id + ">?"));
annoncmentsChannel.send("@here Hey guys! Charlie is on the road in the Ford. Join him in voice if you want.").catch(e => message.channel.send("i cant do that have i got permission to send messages in <#" + channels.annoncments + ">?"));
break;
case 'otrs':
await message.delete().catch(e => message.channel.send("i cant auto delete the messag you sent have i got permission to send messages in <#" + message.channel.id + ">?"));
annoncmentsChannel.send("@here Hey guys! Charlie is on the road in the Subaru. Join him in voice if you want.").catch(e => message.channel.send("i cant do that have i got permission to send messages in <#" + channels.annoncments + ">?"));
break;
case 'otr11':
await message.delete().catch(e => message.channel.send("i cant auto delete the messag you sent have i got permission to send messages in <#" + message.channel.id + ">?"));
annoncmentsChannel.send("@here Hey guys! Charlie is on the road in his car. Join him in voice if you want.").catch(e => message.channel.send("i cant do that have i got permission to send messages in <#" + channels.annoncments + ">?"));
break;
case 'otr':
await message.delete().catch(e => message.channel.send("i cant auto delete the messag you sent have i got permission to send messages in <#" + message.channel.id + ">?"));
annoncmentsChannel.send("@here Hey guys! Charlie is on the road. Join him in voice if you want.").catch(e => message.channel.send("i cant do that have i got permission to send messages in <#" + channels.annoncments + ">?"));
break;
case 'olb':
await message.delete().catch(e => message.channel.send("i cant auto delete the messag you sent have i got permission to send messages in <#" + message.channel.id + ">?"));
annoncmentsChannel.send("@here Hey guys! Charlie is on the road. Join him in voice if you want.").catch(e => message.channel.send("i cant do that have i got permission to send messages in <#" + channels.annoncments + ">?"));
break;
case 'yts':
await message.delete().catch(e => message.channel.send("i cant auto delete the messag you sent have i got permission to send messages in <#" + message.channel.id + ">?"));
annoncmentsChannel.send("@here Hey guys! Charlie is streaming on YouTube: https://www.youtube.com/channel/UC7uWWizg0tmQ2R1kBkuDJHg").catch(e => message.channel.send("i cant do that have i got permission to send messages in <#" + channels.annoncments + ">?"));
break;
case 'ts':
await message.delete().catch(e => message.channel.send("i cant auto delete the messag you sent have i got permission to send messages in <#" + message.channel.id + ">?"));
annoncmentsChannel.send("@here Hey guys! Charlie is streaming on Twitch: https://www.twitch.tv/therealcwh11").catch(e => message.channel.send("i cant do that have i got permission to send messages in <#" + channels.annoncments + ">?"));
break;
default:
return;
};
}
}
};

View file

@ -1,34 +0,0 @@
{
"584494185453977622": {
"roles": {
"✅": "584487354194984981"
}
},
"790737726332600360": {
"roles": {
"📑": "783031927753801770",
"💻": "791376525475315742",
"🎧": "791376529233674310",
"🖥": "791376533057962095",
"📱": "791376535138467900",
"🎮": "791376535474536458",
"🔌": "791376537211371560"
}
},
"791381305111347231": {
"roles": {
"🚚": "595087305212035084",
"🚜": "595086913430355973",
"⛏️": "595087098604683277",
"🗺️": "604424840807710721",
"🚓": "691635977889906849",
"🚗": "752217267600621578",
"🏎️": "752217137728192543",
"🔧": "595767995998011392",
"⚙️": "860942666195927050"
}
}
}

View file

@ -1,15 +0,0 @@
module.exports = {
bot: {
token: "here"
},
oauth: {
clientId: "here",
clientSecret: "here",
redirectUri: "http://localhost:4758/dashboard",
scope: "identify email guilds"
},
db: {
URI: "here"
}
}

48
src/database/index.ts Normal file
View file

@ -0,0 +1,48 @@
import { Sequelize, DataTypes } from 'sequelize';
//@ts-ignore
import YALAS from 'mcstatusbot-logger';
import BanReaction from './schemas/BanReaction';
import Guild from './schemas/Guild';
import KickReaction from './schemas/KickReaction';
import MessageMacro from './schemas/MessageMacro';
import ReactionRole from './schemas/ReactionRole';
import ReactionRoleEmbed from './schemas/ReactionRoleEmbed';
import User from './schemas/User';
if (!process.env.DB_URI) {
YALAS.crash("A database uri must be provided.");
process.exit(1);
}
const sequelize = new Sequelize(process.env.DB_URI);
const schemas = {
BanRole: BanReaction(sequelize),
Guild: Guild(sequelize),
KickRole: KickReaction(sequelize),
MessageMacro: MessageMacro(sequelize),
ReactionRole: ReactionRole(sequelize),
ReactionRoleEmbed: ReactionRoleEmbed(sequelize),
User: User(sequelize)
};
export async function connect() {
YALAS.info("attempting to connect to db");
try {
await sequelize.authenticate();
YALAS.success("Connection has been established successfully.");
} catch (error: any) {
YALAS.crash(error.stack || error);
YALAS.crash("Unable to connect to the database");
process.exit(1);
}
return true;
}
export { schemas };

View file

@ -0,0 +1,42 @@
import { DataTypes, Sequelize, Model, Optional } from 'sequelize';
export interface BanReactionAttributes {
id: number;
guild: string;
channel: string;
reaction: string;
}
export interface BanReactionCreationAttributes extends Optional<BanReactionAttributes, 'id'> { }
export interface BanReactionInstance
extends Model<BanReactionAttributes, BanReactionCreationAttributes>,
BanReactionAttributes { }
export default function BanRole(sequelize: Sequelize) {
const BanReaction = sequelize.define<BanReactionInstance>('BanReaction', {
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
},
guild: {
type: DataTypes.STRING,
allowNull: false,
},
channel: {
type: DataTypes.STRING,
allowNull: false,
},
reaction: {
type: DataTypes.STRING,
allowNull: false,
},
});
// Sync the model with the database
BanReaction.sync({ alter: true });
return BanReaction;
}

View file

@ -0,0 +1,74 @@
import { DataTypes, Sequelize, Model, Optional } from 'sequelize';
export interface GuildAttributes {
id: string;
name: string;
icon: string | null;
owner: string;
prefix: string;
modAddOnEnableCaps: boolean;
modAddOnEnableFilter: boolean;
modAddOnEnableEmojiSpam: boolean;
logChannel: boolean | null;
webhookURI: string
}
export interface GuildCreationAttributes extends Optional<GuildAttributes, 'id' | 'icon' | 'prefix' | 'modAddOnEnableCaps' | 'modAddOnEnableFilter' | 'modAddOnEnableEmojiSpam' | 'logChannel' | 'webhookURI'> { }
export interface GuildInstance
extends Model<GuildAttributes, GuildCreationAttributes>,
GuildAttributes { }
export default function Guild(sequelize: Sequelize) {
const Guild = sequelize.define<GuildInstance>('Guild', {
id: {
type: DataTypes.STRING,
primaryKey: true,
},
name: {
type: DataTypes.STRING,
allowNull: false,
},
icon: {
type: DataTypes.STRING,
allowNull: true,
},
owner: {
type: DataTypes.STRING,
allowNull: false,
},
prefix: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: '.',
},
modAddOnEnableCaps: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false,
},
modAddOnEnableFilter: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false,
},
modAddOnEnableEmojiSpam: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false,
},
logChannel: {
type: DataTypes.STRING,
allowNull: true,
},
webhookURI: {
type: DataTypes.STRING,
allowNull: true,
}
});
// Sync the model with the database
Guild.sync({ alter: true });
return Guild;
}

View file

@ -0,0 +1,41 @@
import { DataTypes, Sequelize, Model, Optional } from 'sequelize';
export interface KickReactionAttributes {
id: number;
guild: string;
channel: string;
reaction: string;
}
export interface KickReactionCreationAttributes extends Optional<KickReactionAttributes, 'id'> { }
export interface KickReactionInstance
extends Model<KickReactionAttributes, KickReactionCreationAttributes>,
KickReactionAttributes { }
export default function KickRole(sequelize: Sequelize) {
const KickReaction = sequelize.define<KickReactionInstance>('KickReaction', {
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
},
guild: {
type: DataTypes.STRING,
allowNull: false,
},
channel: {
type: DataTypes.STRING,
allowNull: false,
},
reaction: {
type: DataTypes.STRING,
allowNull: false,
},
});
// Sync the model with the database
KickReaction.sync({ alter: true });
return KickReaction;
}

View file

@ -0,0 +1,63 @@
import { DataTypes, Sequelize, Model, Optional } from 'sequelize';
export interface MessageMacroAttributes {
id: number;
guild: string;
channel: string | null;
shortCode: string;
message: string;
role: string;
impersonate: boolean;
deleteShortCode: boolean;
}
export interface MessageMacroCreationAttributes extends Optional<MessageMacroAttributes, 'id'> { }
export interface MessageMacroInstance
extends Model<MessageMacroAttributes, MessageMacroCreationAttributes>,
MessageMacroAttributes { }
export default function MessageMacro(sequelize: Sequelize) {
const MessageMacro = sequelize.define<MessageMacroInstance>('MessageMacro', {
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
},
guild: {
type: DataTypes.STRING,
allowNull: false,
},
channel: {
type: DataTypes.STRING,
allowNull: true,
},
shortCode: {
type: DataTypes.STRING(5),
allowNull: false,
},
message: {
type: DataTypes.STRING(2000),
allowNull: false,
},
role: {
type: DataTypes.STRING,
allowNull: true,
},
impersonate: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false,
},
deleteShortCode: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false,
}
});
// Sync the model with the database
MessageMacro.sync({ alter: true });
return MessageMacro;
}

View file

@ -0,0 +1,52 @@
import { DataTypes, Sequelize, Model, Optional } from 'sequelize';
export interface ReactionRoleAttributes {
id: number;
guild: string;
channel: string;
role: string;
reaction: string;
reactionRemove: boolean;
}
export interface ReactionRoleCreationAttributes extends Optional<ReactionRoleAttributes, 'id' | 'reactionRemove'> { }
export interface ReactionRoleInstance
extends Model<ReactionRoleAttributes, ReactionRoleCreationAttributes>,
ReactionRoleAttributes { }
export default function ReactionRole(sequelize: Sequelize) {
const ReactionRole = sequelize.define<ReactionRoleInstance>('ReactionRole', {
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
},
guild: {
type: DataTypes.STRING,
allowNull: false,
},
channel: {
type: DataTypes.STRING,
allowNull: false,
},
role: {
type: DataTypes.STRING,
allowNull: false,
},
reaction: {
type: DataTypes.STRING,
allowNull: false,
},
reactionRemove: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: true,
},
});
// Sync the model with the database
ReactionRole.sync({ alter: true });
return ReactionRole;
}

View file

@ -0,0 +1,66 @@
import { flatten } from 'discord.js';
import { DataTypes, Sequelize, Model, Optional } from 'sequelize';
export interface ReactionRoleEmbedAttributes {
id: number;
guild: string;
channel: string;
title: string;
icon: string | null;
color: string;
roleSeparator: string;
listItemTemplate: string;
}
export interface ReactionRoleEmbedCreationAttributes extends Optional<ReactionRoleEmbedAttributes, 'id' | 'title' | 'icon' | 'color' | 'roleSeparator' | 'listItemTemplate'> { }
export interface ReactionRoleEmbedInstance
extends Model<ReactionRoleEmbedAttributes, ReactionRoleEmbedCreationAttributes>,
ReactionRoleEmbedAttributes { }
export default function ReactionRoleEmbed(sequelize: Sequelize) {
const ReactionRoleEmbed = sequelize.define<ReactionRoleEmbedInstance>('ReactionRoleEmbed', {
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
},
guild: {
type: DataTypes.STRING,
allowNull: false,
},
channel: {
type: DataTypes.STRING,
allowNull: false,
},
title: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: "Reaction Roles",
},
icon: {
type: DataTypes.STRING,
allowNull: true,
},
color: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: "#ff0000",
},
roleSeparator: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: ', '
},
listItemTemplate: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: "[[icon]] - [[roles]]",
},
});
// Synchronize the model with the database
ReactionRoleEmbed.sync({ alter: true });
return ReactionRoleEmbed;
}

View file

@ -0,0 +1,45 @@
import { DataTypes, Sequelize, Model, Optional } from 'sequelize';
export interface UserAttributes {
id: string;
username: string;
avatar: string | null;
admin: boolean;
suspended: boolean;
}
export interface UserCreationAttributes extends Optional<UserAttributes, 'id' | 'avatar' | 'suspended'> { }
export interface UserInstance extends Model<UserAttributes, UserCreationAttributes>, UserAttributes { }
export default function defineUser(sequelize: Sequelize) {
const User = sequelize.define<UserInstance>('User', {
id: {
type: DataTypes.STRING,
primaryKey: true,
},
username: {
type: DataTypes.STRING,
allowNull: false,
},
avatar: {
type: DataTypes.STRING,
allowNull: true,
},
admin: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false,
},
suspended: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false,
},
});
// Sync the model with the database (optional in production)
User.sync({ alter: true });
return User;
}

View file

@ -1,14 +0,0 @@
const { version, repository: { url } } = require('../../../../package.json');
const { domain, prefix, mainServer: { invite } } = require('../../../conf/conf.json');
module.exports = {
name: '/api',
dynamic: false,
async exe(client, req, res) {
try {
res.status(200).json({ defaultPrefix: prefix, doamin: domain, version: version, mainGuild: invite, github: url.replace('.git', '') });
} catch (error) {
console.log(error);
res.status(500).json({ error: "500 - some error", message: "report it if it happens again" });
}
}
}

View file

@ -1,159 +0,0 @@
/*
* licence https://github.com/404invalid-user/knightrider/blob/main/LICENCE
*/
const fetch = require('node-fetch');
const config = require('../../../conf/conf.json')
const User = require('../../../models/userdashboard');
const dbc = require('discord-bitfield-calculator')
const token = require('../../../conf/tokens');
const Server = require('../../../models/server');
const randomString = require("randomstring").generate({
length: 33,
charset: 'alphabetic'
});
module.exports = {
name: '/dashboard',
dynamic: false,
async exe(client, req, res) {
// try {
if (req.query.code) {
let oath;
let userInfo;
let userGuilds = [];
let guilds = [];
let theAccessCode = randomString;
//access discord oauth2 and get nececry data
await fetch('https://discord.com/api/oauth2/token', {
method: 'POST',
body: new URLSearchParams({
client_id: token.oauth.clientId,
client_secret: token.oauth.clientSecret,
grant_type: 'authorization_code',
redirect_uri: token.oauth.redirectUri,
code: req.query.code,
scope: token.oauth.scope,
}),
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
}).then(discordRes => discordRes.json()).then(info => oath = info);
//fetch user info from OAuth2 token
await fetch('https://discord.com/api/users/@me', {
headers: {
authorization: `${oath.token_type} ${oath.access_token}`,
},
}).then(async userRes => {
userInfo = await userRes.json();
});
//fetch guilds from OAuth2 token
await fetch('https://discord.com/api/users/@me/guilds', {
headers: {
authorization: `${oath.token_type} ${oath.access_token}`,
},
})
.then(async guildRes => {
userGuilds = await guildRes.json()
});
//if the access code was used/expired (from browser refresh) redirect without code and try use cookeis
if (userInfo.message == '401: Unauthorized') return res.redirect('/dashboard');
if (userGuilds.message == '401: Unauthorized') return res.redirect('/dashboard');
let botGuilds = await client.guilds.cache.map(guild => guild.id)
//loop though oauth2 guilds and push guild info for matching guilds to 'guilds' array
await userGuilds.forEach(async(userGuild) => {
let currentServer = await Server.findOne({ id: userGuild.id })
//handle servers only the user is in
if (currentServer == null) {
if (userGuild.owner == true) {
guilds.push({ id: userGuild.id, name: userGuild.name, icon: `https://cdn.discordapp.com/icons/${userGuild.id}/${userGuild.icon}.webp`, mutual: false, userPermission: 'owner' });
} else {
if (dbc.permissions(userGuild.permissions_new).includes('MANAGE_GUILD')) {
guilds.push({ id: userGuild.id, name: userGuild.name, icon: `https://cdn.discordapp.com/icons/${userGuild.id}/${userGuild.icon}.webp`, mutual: false, userPermission: 'MANAGE_GUILD' });
};
};
//handle servers the bot and user are in
} else {
if (userGuild.owner == true) {
guilds.push({ id: userGuild.id, name: userGuild.name, icon: `https://cdn.discordapp.com/icons/${userGuild.id}/${userGuild.icon}.webp`, mutual: true, userPermission: 'owner' });
} else {
if (client.guilds.cache.get(currentServer.id).members.cache.get(userInfo.id).roles.cache.find(r => currentServer.staffRoles.includes(r.name))) {
guilds.push({ id: userGuild.id, name: userGuild.name, icon: `https://cdn.discordapp.com/icons/${userGuild.id}/${userGuild.icon}.webp`, mutual: true, userPermission: 'staffrole' });
} else {
currentServer.staff.forEach(userid => {
if (userInfo.id == userid) {
guilds.push({ id: userGuild.id, name: userGuild.name, icon: `https://cdn.discordapp.com/icons/${userGuild.id}/${userGuild.icon}.webp`, mutual: true, userPermission: 'staffid' });
} else if (dbc.permissions(userGuild.permissions_new).includes('MANAGE_GUILD')) {
guilds.push({ id: userGuild.id, name: userGuild.name, icon: `https://cdn.discordapp.com/icons/${userGuild.id}/${userGuild.icon}.webp`, mutual: true, userPermission: 'MANAGE_GUILD' });
};
});
};
};
};
});
delete botGuilds;
let currentUser = await User.findOne({ userId: userInfo.id });
if (currentUser == null) {
await User.create({
userId: userInfo.id,
userName: userInfo.username,
discriminator: userInfo.discriminator || '0000',
avatar: `https://cdn.discordapp.com/avatars/${userInfo.id}/${userInfo.avatar}.png`,
accessCodes: [{ browser: req.headers['user-agent'], code: randomString }],
guilds: guilds
});
currentUser = await User.findOne({ userId: userInfo.id });
} else {
let gotCorrectAccessCode = false;
if (res.locals.cookie.accesscode) {
await currentUser.accessCodes.forEach(async(accessCode) => {
if (res.locals.cookie.accesscode == accessCode.code) {
gotCorrectAccessCode = await true;
theAccessCode = res.locals.cookie.accesscode;
}
});
};
if (gotCorrectAccessCode == false) {
currentUser.accessCodes.push({ browser: req.headers['user-agent'], code: randomString });
theAccessCode = randomString;
};
currentUser.userName = userInfo.username;
currentUser.avatar = `https://cdn.discordapp.com/avatars/${userInfo.id}/${userInfo.avatar}.png`;
currentUser.guilds = guilds;
currentUser.save();
};
res.cookie('id', currentUser.userId, { expires: new Date(253402300000000), httpOnly: true }).cookie('accesscode', theAccessCode, { expires: new Date(253402300000000), httpOnly: true }).status(200).render('dashboard/index.ejs', { currentUser: currentUser, guilds: currentUser.guilds });
} else if (req.query.error) {
console.log("req query error: " + req.query.error)
await res.status(500).render('500.ejs');
} else if (res.locals.cookie.id && res.locals.cookie.accesscode) {
const currentUser = await User.findOne({ userId: res.locals.cookie.id });
if (currentUser == null) return res.redirect('/login?nouser');
let hasAccess = false;
await currentUser.accessCodes.forEach(async(userCode) => {
if (res.locals.cookie.accesscode == userCode.code) {
hasAccess = true;
return res.cookie('id', currentUser.userId, { expires: new Date(253402300000000), httpOnly: true }).cookie('accesscode', res.locals.cookie.accesscode, { expires: new Date(253402300000000), httpOnly: true }).render('dashboard/index.ejs', { user: { name: currentUser.userName, tag: currentUser.discriminator, avatar: currentUser.avatar }, currentUser: currentUser, guilds: currentUser.guilds });
};
});
if (hasAccess == false) return res.redirect('/login?ninvalidcode');
} else if (!res.locals.cookie.id || !res.locals.cookie.accesscode) return res.redirect('/login?nocookies');
/*
} catch (error) {
console.log(chalk.red('[express get]: ') + "there was an error with dashboard.js\nerror: " + error);
return res.status(500).render('500.ejs');
};
*/
}
}

View file

@ -1,45 +0,0 @@
/*
* licence https://github.com/404invalid-user/knightrider/blob/main/LICENCE
*/
const Server = require('../../../models/server')
const Userdashboard = require('../../../models/userdashboard')
const conf = require('../../../conf/conf.json')
module.exports = {
name: '/server/:serverid/filter',
dynamic: true,
async exe(client, req, res) {
try {
if (!res.locals.cookie.id || !res.locals.cookie.accesscode) {
return res.redirect(conf.domain + "/login")
}
let currentUser = await Userdashboard.findOne({ userId: res.locals.cookie.id })
let currentServer = await Server.findOne({ id: req.params.serverid })
if (currentServer == null) return res.render('404.ejs')
let gAccess = false;
await currentUser.guilds.forEach(async (guild) => {
if (guild.id == currentServer.id) {
gAccess = true;
if (guild.userPermission == 'owner' || guild.userPermission == 'MANAGE_GUILD' || currentServer.staff.includes(currentUser.userId)) {
let hasAccess = false;
await currentUser.accessCodes.forEach(async(userCode) => {
if (res.locals.cookie.accesscode == userCode.code) {
hasAccess = true;
return res.cookie('id', currentUser.userId, { expires: new Date(253402300000000), httpOnly: true }).cookie('accesscode', res.locals.cookie.accesscode, { expires: new Date(253402300000000), httpOnly: true }).render('dashboard/filter.ejs', { domain: conf.domain, user: { id: currentUser.userId, accesscode: res.locals.cookie.accesscode }, currentUser: currentUser, currentServer: currentServer });
};
});
if (hasAccess == false) return res.redirect('/login?ninvalidcode');
};
};
});
if (gAccess == false) {
return res.status(401).render('error.ejs', { errorMessage: null, error: "you do not have access to the admin dashboard if you are a member of staff tell the bot owner" })
}
} catch (error) {
console.log(error)
// require('../../../conf/functions.js').reportError(client, conf, "/api/reaction-error", error, { name: null, id: req.body.userid })
res.status(500).render('error.ejs', { errorMessage: error, error: "there has been an issue with your request please try again, if this continuous report it at http://knightrider.rf.gd/er/admin.php" })
}
}
}

View file

@ -1,29 +0,0 @@
/*
* licence https://github.com/404invalid-user/knightrider/blob/main/LICENCE
*/
module.exports = {
name: '/dash/message',
async exe(client, req, res) {
try {
let usersDB = JSON.parse(fs.readFileSync('./././database/users.json', 'utf8'));
if (!req.query.tmpPassWord) {
res.redirect("http://idiotlanparty.com/oauth")
}
if (usersDB[req.query.userid].admin == true) {
if (req.query.tmpPassWord == usersDB[req.query.userid].tmpPassWord) {
res.render('admin-message.ejs', { userInfo: { id: req.query.userid, username: req.query.username, avatar: req.query.userAvatar }, tmpPassWord: req.query.tmpPassWord })
} else {
await res.status(401).render('error.ejs', { errorMessage: null, error: "you do not have access please login again to regenrate your temporary local oath key", userInfo: { id: req.query.userid, username: req.query.username, avatar: req.query.userAvatar } })
}
} else if (usersDB[userInfo.id].admin == false) {
await res.status(401).render('error.ejs', { errorMessage: null, error: "you do not have access to the admin dashboard if you are a member of staff fill out http://knightrider.rf.gd/er/admin.php", userInfo: { id: req.query.userid, username: req.query.userame, avatar: req.query.userAvatar } })
}
} catch (error) {
console.log(error)
require('../../../conf/functions.js').reportError(client, conf, "/api/reaction-error", error, { name: null, id: req.body.userid })
res.status(500).render('error.ejs', { errorMessage: error, error: "there has been an issue with your request please try again, if this continuous report it at http://knightrider.rf.gd/er/admin.php" })
}
}
}

View file

@ -1,54 +0,0 @@
/*
* licence https://github.com/404invalid-user/knightrider/blob/main/LICENCE
*/
const Server = require('../../../models/server');
const Userdashboard = require('../../../models/userdashboard');
const conf = require('../../../conf/conf.json');
module.exports = {
name: '/server/:serverid/reactionroles',
dynamic: true,
async exe(client, req, res) {
try {
if (!res.locals.cookie.id || !res.locals.cookie.accesscode) {
return res.redirect(conf.domain + "/login")
}
let currentUser = await Userdashboard.findOne({ userId: res.locals.cookie.id })
if (currentUser == null) return res.render('404.ejs')
let currentServer = await Server.findOne({ id: req.params.serverid })
if (currentServer == null) return res.render('404.ejs')
let gAccess = false;
await currentUser.guilds.forEach(async (guild) => {
if (guild.id == currentServer.id) {
gAccess = true;
if (guild.userPermission == 'owner' || guild.userPermission == 'MANAGE_GUILD' || currentServer.staff.includes(currentUser.userId)) {
let hasAccess = false;
let listedRoles = [];
let listedChannels = [];
let server = await client.guilds.cache.get(currentServer.id);
let user = await server.members.fetch(currentUser.userId);
//push server roles to array
server.roles.cache.map((role) => listedRoles.push({ id: role.id, name: role.name }));
//push only channels user can see to array
server.channels.cache.filter(c => c.type == 'text').forEach(channel => {
if (server.channels.cache.get(channel.id).permissionsFor(user).has(['SEND_MESSAGES', 'VIEW_CHANNEL'])) listedChannels.push({ name: channel.name, id: channel.id });
});
await currentUser.accessCodes.forEach(async(userCode) => {
if (res.locals.cookie.accesscode == userCode.code) {
hasAccess = true;
return res.cookie('id', currentUser.userId, { expires: new Date(253402300000000), httpOnly: true }).cookie('accesscode', res.locals.cookie.accesscode, { expires: new Date(253402300000000), httpOnly: true }).render('dashboard/reactionroles.ejs', { domain: conf.domain, server: { channels: listedChannels, roles: listedRoles }, user: { id: currentUser.userId, accesscode: res.locals.cookie.accesscode }, currentUser: currentUser, currentServer: currentServer });
};
});
if (hasAccess == false) return res.redirect('/login?ninvalidcode');
};
};
});
if (gAccess == false) {
return res.status(401).render('error.ejs', { errorMessage: null, error: "you do not have access to the admin dashboard if you are a member of staff tell the bot owner" })
}
} catch (error) {
console.log(error)
res.status(500).render('error.ejs', { errorMessage: error, error: "there has been an issue with your request please try again, if this continuous report it at http://knightrider.rf.gd/er/admin.php" })
}
}
}

View file

@ -1,48 +0,0 @@
/*
* licence https://github.com/404invalid-user/knightrider/blob/main/LICENCE
*/
const Server = require('../../../models/server')
const Userdashboard = require('../../../models/userdashboard')
const conf = require('../../../conf/conf.json')
module.exports = {
name: '/server/:serverid/filter',
dynamic: true,
async exe(client, req, res) {
try {
if (!res.locals.cookie.id || !res.locals.cookie.accesscode) {
return res.redirect(conf.domain + "/login")
}
let currentUser = await Userdashboard.findOne({ userId: res.locals.cookie.id })
if (currentUser == null) return res.redirect('/login');
let currentServer = await Server.findOne({ id: req.params.serverid })
if (currentServer == null) return res.render('404.ejs');
let gAccess = false;
let hasAccess = false;
await currentUser.guilds.forEach(async (guild) => {
if (guild.id == currentServer.id) {
gAccess = true;
if (guild.userPermission == 'owner' || guild.userPermission == 'MANAGE_GUILD' || currentServer.staff.includes(currentUser.userId)) {
await currentUser.accessCodes.forEach(async(userCode) => {
if (res.locals.cookie.accesscode == userCode.code) {
hasAccess = true;
const memberCount = await client.guilds.cache.get(currentServer.id).memberCount;
return res.cookie('id', currentUser.userId, { expires: new Date(253402300000000), httpOnly: true }).cookie('accesscode', res.locals.cookie.accesscode, { expires: new Date(253402300000000), httpOnly: true }).render('dashboard/server.ejs', { domain: conf.domain, user: { id: currentUser.userId, accesscode: res.locals.cookie.accesscode }, currentUser: currentUser, currentServer: currentServer, memberCount: memberCount });
};
});
if (hasAccess == false) return res.redirect('/login?ninvalidcode');
}
};
});
if (gAccess == false) {
return res.status(401).render('error.ejs', { errorMessage: null, error: "you do not have access to the admin dashboard if you are a member of staff tell the bot owner" })
}
} catch (error) {
console.log(error)
res.status(500).render('error.ejs', { errorMessage: error, error: "there has been an issue with your request please try again, if this continuous report it at http://knightrider.rf.gd/er/admin.php" })
}
}
}

View file

@ -1,6 +0,0 @@
module.exports = {
name: '/er',
exe(client, conf, req, res) {
res.render('er/er.ejs')
}
}

View file

@ -1,8 +0,0 @@
const { webServer: { oauthURI } } = require('../../../conf/conf.json')
module.exports = {
name: '/login',
dynamic: false,
exe(client, req, res) {
res.redirect(oauthURI)
}
}

View file

@ -1,11 +0,0 @@
/*
* licence https://github.com/404invalid-user/knightrider/blob/main/LICENCE
*/
const conf = require('../../../conf/conf.json')
module.exports = {
name: '/',
dynamic: false,
exe(client, req, res) {
res.render('index.ejs', { bot: { name: conf.bot.name }, servers: client.guilds.cache.size, users: client.guilds.cache.reduce((acc, guild) => acc + guild.memberCount, 0) });
}
}

View file

@ -1,38 +0,0 @@
/*
* licence https://github.com/404invalid-user/knightrider/blob/main/LICENCE
*/
const chalk = require('chalk');
const { readdirSync } = require("fs");
module.exports = (client, webServer) => {
readdirSync(__dirname + '/../get/').forEach((dir) => {
const getReqFiles = readdirSync(__dirname + `/../get/${dir}/`).filter((file) => file.endsWith(".js"));
for (let file of getReqFiles) {
let getReqFile = require(__dirname + `/../get/${dir}/${file}`);
if (getReqFile.name) {
try {
if (getReqFile.dynamic == false) {
webServer.get(getReqFile.name, async(...args) => getReqFile.exe(client, ...args));
};
} catch (error) {
console.log(chalk.cyan('[webserver get handler]: ') + chalk.red('(error): ') + "executing. path: " + `./get/${dir}/${file}`);
continue;
};
} else {
console.log(chalk.cyan('[webserver get handler]: ') + chalk.red('(error): ') + "get file dosnt contain a name or description. path: " + `./get/${dir}/${file}`);
continue;
};
};
});
webServer.get('/server/:serverid', async(...args) => require('../get/dashboard/server').exe(client, ...args));
webServer.get('/server/:serverid/filter', async(...args) => require('../get/dashboard/filter').exe(client, ...args));
webServer.get('/server/:serverid/reactionroles', async(...args) => require('../get/dashboard/reactionroles').exe(client, ...args));
webServer.get('*', (req, res) => {
res.status(404).render('404.ejs');
});
console.log(chalk.cyan('[webserver]: ') + "loaded get request handler");
}

View file

@ -1,29 +0,0 @@
/*
* licence https://github.com/404invalid-user/knightrider/blob/main/LICENCE
*/
const chalk = require('chalk');
const { readdirSync } = require("fs");
const conf = require('../../conf/conf.json');
module.exports = (client, webServer) => {
readdirSync(__dirname + '/../post/').forEach((dir) => {
const postReqFiles = readdirSync(__dirname + `/../post/${dir}/`).filter((file) => file.endsWith(".js"));
for (let file of postReqFiles) {
let postReqFile = require(__dirname + `/../post/${dir}/${file}`);
if (postReqFile.name) {
try {
webServer.post(postReqFile.name, async(...args) => postReqFile.exe(client, conf, ...args));
} catch (error) {
console.log(chalk.cyan('[webserver post handler]: ') + chalk.red('(error): ') + "executing. path: " + `./get/${dir}/${file}`);
continue;
}
} else {
console.log(chalk.cyan('[webserver post handler]: ') + chalk.red('(error): ') + "post file dosnt contain a name or description. path: " + `./get/${dir}/${file}`);
continue;
};
};
});
console.log(chalk.cyan('[webserver]: ') + "loaded post request handler");
}

View file

@ -1,16 +0,0 @@
/*
* licence https://github.com/404invalid-user/knightrider/blob/main/LICENCE
*/
const { version, repository: { url } } = require('../../../../package.json');
const { domain, prefix, mainServer: { invite } } = require('../../../conf/conf.json');
module.exports = {
name: '/api',
async exe(client, req, res) {
try {
res.status(200).json({ defaultPrefix: prefix, doamin: domain, version: version, mainGuild: invite, github: url.replace('.git', '') });
} catch (error) {
console.log(error);
res.status(500).json({ error: "500 - some error", message: "report it if it happens again" });
}
}
}

View file

@ -1,44 +0,0 @@
/*
* licence https://github.com/404invalid-user/knightrider/blob/main/LICENCE
*/
const Server = require('../../../models/server');
const { domain } = require('../../../conf/conf.json');
const Userdashboard = require('../../../models/userdashboard');
module.exports = {
name: '/api/updatefilter',
async exe(client, conf, req, res) {
try {
if (!req.body.user || !req.body.server || !req.body.server.id || !req.body.normalFilter || !req.body.safeFilter) return res.status(401).JSON({ error: "000 - missing information", info: "please include all neccery information for this api endpoint for help on how to use this api more info in the docs " + conf.domain + '/docs' });
let currentUser = await Userdashboard.findOne({ userId: req.body.user.id });
if (currentUser == null) return res.status(404).json({ error: "404 - cant find you in the db" });
let currentServer = await Server.findOne({ id: req.body.server.id });
if (currentServer == null) return res.status(404).json({ error: "404 - cant find that server in the db" });
let gAccess = false;
await currentUser.guilds.forEach(async (guild) => {
if (guild.id == currentServer.id) {
gAccess = true;
if (guild.userPermission == 'owner' || guild.userPermission == 'MANAGE_GUILD' || currentServer.staff.includes(currentUser.userId)) {
let hasAccess = false;
await currentUser.accessCodes.forEach(async(userCode) => {
if (req.body.user.accesscode == userCode.code) {
hasAccess = true;
currentServer.filter.normal = await req.body.normalFilter;
currentServer.filter.safe = await req.body.safeFilter;
currentServer.save();
return res.status(200).json({ error: "no", message: "filters have been updates" });
};
});
}
}
});
if (hasAccess == false) return res.status(401).json({ error: "401 - unauthorised", info: "please include your accesscode and user id to use this api more info in the docs " + conf.domain + '/docs' });
if (gAccess == false) {
return res.status(401).render('error.ejs', { errorMessage: null, error: "you do not have access to the admin dashboard if you are a member of staff tell the bot owner" })
}
} catch (error) {
console.log(error);
res.status(500).json({ error: "some error happened", info: "report this if it happenes again." + domain + '/er' });
}
}
}

View file

@ -1,51 +0,0 @@
/*
* licence https://github.com/404invalid-user/knightrider/blob/main/LICENCE
*/
const Userdashboard = require('../../../models/userdashboard');
const Server = require('../../../models/server');
const { prefix, domain } = require('../../../conf/conf.json');
module.exports = {
name: '/api/updateoverview',
async exe(client, conf, req, res) {
try {
if (!req.body.user || !req.body.server || !req.body.server.id || !req.body.staffRoles || !req.body.staffids) return res.status(403).json({ error: "000 - missing information", message: "please include all neccery information for this api endpoint for help on how to use this api more info in the docs " + conf.domain + '/docs' })
let currentUser = await Userdashboard.findOne({ userId: req.body.user.id })
if (currentUser == null) return res.status(404).json({ error: "404 - cant find you in the db", message: "that user id cant be found" });
let currentServer = await Server.findOne({ id: req.body.server.id });
if (currentServer == null) return res.status(404).json({ error: "404 - cant find that server in the db", message: "that server id cant be found" });
let gAccess = false;
await currentUser.guilds.forEach(async (guild) => {
if (guild.id == currentServer.id) {
gAccess = true;
if (guild.userPermission == 'owner' || guild.userPermission == 'MANAGE_GUILD' || currentServer.staff.includes(currentUser.userId)) {
let hasAccess = false;
await currentUser.accessCodes.forEach(async(userCode) => {
if (req.body.user.accesscode == userCode.code) {
hasAccess = true;
//apply all data from the req to the db (probabbly a better way to do this)
currentServer.prefix = req.body.prefix || prefix;
currentServer.staff = req.body.staffids || [];
currentServer.staffRoles = req.body.staffRoles || [];
currentServer.channels.modLogs = req.body.channels.modlogs || ' ';
currentServer.channels.announcments = req.body.channels.announcments || ' ';
currentServer.channels.townhall = req.body.channels.townhall || ' ';
currentServer.channels.townhallLogs = req.body.channels.townhallLogs || ' ';
currentServer.save();
return res.status(200);
};
});
}
}
});
if (hasAccess == false) return res.status(401).json({ error: "401 - unauthorised", info: "please include your accesscode and user id to use this api more info in the docs " + conf.domain + '/docs' });
if (gAccess == false) {
return res.status(401).render('error.ejs', { errorMessage: null, error: "you do not have access to the admin dashboard if you are a member of staff tell the bot owner" })
}
} catch (error) {
console.log(error);
res.status(500).JSON({ error: "some error happened", info: "report this if it happenes again. " + domain + '/er' });
}
}
}

View file

@ -1,87 +0,0 @@
/*
* licence https://github.com/404invalid-user/knightrider/blob/main/LICENCE
*/
const Server = require('../../../models/server');
const Userdashboard = require('../../../models/userdashboard');
module.exports = {
name: '/api/updatereactionroles',
async exe(client, conf, req, res) {
try {
if (!req.body.user || !req.body.server || !req.body.server.id || !req.body.reactionRoles) return res.status(404).json({ error: "000 - missing information", info: "please include all neccery information for this api endpoint for help on how to use this api more info in the docs " + conf.domain + '/docs' });
let currentUser = await Userdashboard.findOne({ userId: req.body.user.id });
if (currentUser == null) return res.status(404).json({ error: "404 - cant find you in the db" });
let currentServer = await Server.findOne({ id: req.body.server.id });
if (currentServer == null) return res.status(404).json({ error: "404 - cant find that server in the db" });
let gAccess = false;
await currentUser.guilds.forEach(async (guild) => {
if (guild.id == currentServer.id) {
gAccess = true;
if (guild.userPermission == 'owner' || guild.userPermission == 'MANAGE_GUILD' || currentServer.staff.includes(currentUser.userId)) {
let hasAccess = false;
await currentUser.accessCodes.forEach(async(userCode) => {
if (req.body.user.accesscode == userCode.code) {
hasAccess = true;
currentServer.reactionRoles = await req.body.reactionRoles;
currentServer.save();
let eachChannelRoles = {};
await currentServer.reactionRoles.forEach(role => {
if (!eachChannelRoles[role.channelID]) {
eachChannelRoles[role.channelID] = [{
roleID: role.roleID,
emoji: role.emoji
}];
} else {
eachChannelRoles[role.channelID].push({
roleID: role.roleID,
emoji: role.emoji
});
};
});
for (let i in eachChannelRoles) {
let rolesEmbed = {
color: conf.colour.ok,
title: 'ReactionRoles',
url: conf.domain,
author: {
name: conf.bot.name,
icon_url: conf.bot.logo,
url: conf.bot.url,
},
description: 'react with the appropriate emoji to get your role',
fields: [],
timestamp: new Date(),
footer: {
text: currentServer.name,
},
};
await eachChannelRoles[i].forEach(role => {
rolesEmbed.fields.push({
name: '\u200B',
value: '<@&' + role.roleID + '> - ' + role.emoji,
});
});
const channel = client.guilds.cache.get(currentServer.id).channels.cache.get(i)
if (channel !== undefined) {
const msg = await channel.send({ embed: rolesEmbed });
eachChannelRoles[i].forEach(role => {
msg.react(role.emoji);
});
};
};
return res.status(200).json({ error: "no", message: "reactionroles have been updates" });
};
});
}
}
});
if (hasAccess == false) return res.status(401).json({ error: "401 - unauthorised", info: "please include your accesscode and user id to use this api more info in the docs " + conf.domain + '/docs' });
if (gAccess == false) {
return res.status(401).render('error.ejs', { errorMessage: null, error: "you do not have access to the admin dashboard if you are a member of staff tell the bot owner" })
}
} catch (error) {
console.log(error);
res.status(500).json({ error: "some error happened", info: "report this if it happenes again." + conf.domain + '/er' });
}
}
}

View file

@ -1,24 +0,0 @@
/*
* licence https://github.com/404invalid-user/knightrider/blob/main/LICENCE
*/
module.exports = {
name: '/api/userinfo/update',
async exe(client, conf, req, res) {
try {
if (req.body.tmpPassWord == usersDB[req.body.userInfo.id].tmpPassWord) {
if (!usersDB[req.body.memberId]) {
res.status(404).json({ error: "user id isnt in the database", info: "user id could be wrong or that user hasnt sent a message in the discord server since the bot has been setup" })
} else {
res.status(200).json({ userStrikes: usersDB[req.body.memberId].strike, userNote: usersDB[req.body.memberId].note, userAdmin: usersDB[req.body.memberId].admin })
}
} else {
res.status(401).json({ error: "401 - unauthorised", info: "please include your tmp password and user id to use this api more info in the docs http://knightrider.rf.gd/docs/" })
}
} catch (error) {
console.log(error)
res.status(500).JSON({ error: "some error happened", info: "report this if it happenes again." })
require('./././conf/functions.js').reportError(client, conf, "/api/reaction-error", error, { name: null, id: req.body.userid })
}
}
}

View file

@ -1,14 +0,0 @@
/*
* licence https://github.com/404invalid-user/knightrider/blob/main/LICENCE
*/
module.exports = {
name: '/api/userinfo',
async exe(client, conf, req, res) {
try {
} catch (error) {
console.log(error)
res.status(500).JSON({ error: "some error happened", info: "report this if it happenes again." })
}
}
}

View file

@ -1,17 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="/favicon.ico">
<link rel="shortcut icon" href="/logo.png">
<title>404</title>
</head>
<body>
<h2>404 - that page cant be found</h2>
</body>
</html>

View file

@ -1,18 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="/favicon.ico">
<link rel="shortcut icon" href="/logo.png">
<title>Document</title>
</head>
<body>
<h2>500 - web server error </h2>
<p>the owner has been informed of this error.</p>
</body>
</html>

View file

@ -1,192 +0,0 @@
@import url('https://fonts.googleapis.com/css2?family=Open+Sans&display=swap');
html,
body {
margin: 0;
padding: 0;
min-width: 100%;
min-height: 100%;
background-color: #2C2F33;
color: rgb(255, 255, 255);
font-family: 'Open Sans', sans-serif;
background-image: url('/assets/topggbackground.png');
background-repeat: no-repeat;
background-attachment: fixed;
background-size: cover;
}
.user-information {
display: flex;
}
.useravatar {
padding: auto;
}
.username {
padding: auto;
}
.container {
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.servers-lists {
width: 90%;
padding: 15px 0 10px;
background: #15528f69;
border-radius: 15px;
}
/* if screen big big make button marging right more so dosnt look weirds 3% and maybe makde button text 2em and width/height bigger*/
.server-list {
position: relative;
display: flex;
flex-direction: column;
row-gap: 40px;
align-items: center;
margin-bottom: 50px;
}
.server-container {
display: flex;
justify-content: space-between;
flex-direction: row;
min-height: 10px;
width: 90%;
margin: auto;
flex-wrap: wrap;
background-color: #000000;
border-radius: 35px;
}
.server {
display: flex;
min-width: 50%;
flex-direction: row;
min-height: 10px;
flex-wrap: wrap;
}
.button-container {
margin: 0 0.5% 0 0;
display: flex;
justify-content: center;
align-items: center;
}
.server-info {
display: flex;
align-items: center;
flex-direction: row;
margin: 0.9% 0.6%;
color: rgb(255, 255, 255);
}
.server-icon {
margin-top: 0.4%;
margin-left: 0.4%;
}
.server-icon-img {
width: 70px;
height: 70px;
border-radius: 50%;
}
.server-name {
font-size: 1em;
margin: 5px;
}
.server-dash-btn {
display: flex;
align-items: center;
flex-direction: column;
flex-wrap: wrap;
}
.button {
display: flex;
justify-content: center;
align-items: center;
border: rgb(240, 236, 236) 1px solid;
color: rgb(255, 255, 255);
width: 105px;
height: 35px;
border-radius: 100px;
cursor: pointer;
transition: all .2s ease;
font-size: 1em;
text-decoration: none !important;
}
@media (max-width: 858px) {
.container {
width: 100% !important;
}
.servers-lists {
width: 100% !important;
margin: 0 !important;
padding: 5px !important;
}
.server-container {
flex-direction: column !important;
padding: 0 !important;
padding-bottom: 0 !important;
max-width: 40% !important;
min-height: 150px;
border-radius: 15% !important;
overflow: hidden !important;
}
.button-container {
margin: 0 !important;
width: 100%;
min-height: 33px !important;
background-color: aliceblue;
color: black !important;
}
.server-info {
margin-top: 8px !important;
margin-bottom: 9px !important;
margin-left: 4px !important;
}
.server-icon {
display: flex !important;
align-items: center !important;
align-content: center !important;
width: 100%;
height: 90%;
flex-direction: column !important;
margin: auto !important;
}
.server-icon-img {
width: 100% !important;
height: 90% !important;
border-radius: 0 !important;
}
.button {
display: flex;
justify-content: center;
align-items: center;
border: 0 !important;
color: rgb(0, 0, 0) !important;
width: 100% !important;
height: 35px;
cursor: pointer;
transition: all .2s ease;
font-size: 1em;
text-decoration: none !important;
border-radius: 0px;
}
}
.manage {}
.invite {
background-color: rgb(123, 255, 0);
}

View file

@ -1,65 +0,0 @@
* {
box-sizing: border-box;
}
body {
font-family: Arial, Helvetica, sans-serif;
margin: 0;
font-size: 120%;
}
.header {
padding: 90px;
padding-top: 169px;
text-align: center;
background: red;
color: white;
}
.header h1 {
font-size: 40px;
}
.content {
display: -ms-flexbox;
/* IE10 */
display: flex;
-ms-flex-wrap: wrap;
/* IE10 */
flex-wrap: wrap;
}
.main {
-ms-flex: 70%;
/* IE10 */
flex: 70%;
background-color: white;
padding: 20px;
}
#connection {
vertical-align: middle;
}
.dot {
height: 20px;
width: 20px;
background-color: red;
border-radius: 50%;
display: inline-block;
vertical-align: middle;
text-align: center;
}
.stat {
background-color: rgb(233, 223, 223);
padding: 5px;
padding-right: 7px;
border-radius: 6px;
}
.footer {
padding: 20px;
text-align: center;
background: #ddd;
}

View file

@ -1,132 +0,0 @@
/* mobile navbar navbar */
.mobnav {
top: 0;
right: 0;
width: 0;
z-index: 1;
height: 100%;
position: fixed;
transition: 0.5s;
padding-top: 60px;
overflow-x: hidden;
background-color: #25282a;
}
.mobnav a {
display: block;
font-size: 25px;
color: #ffffff;
transition: 0.3s;
text-decoration: none;
padding: 7px 8px 7px 32px;
}
.mobnav a:hover {
color: #888B8D;
}
.mobnav .closebtn {
top: 0;
right: 25px;
font-size: 36px;
margin-left: 50px;
position: absolute;
}
/* responsive */
@media screen and (max-height: 450px) {
.mobnav {
padding-top: 15px;
}
.mobnav a {
font-size: 18px;
}
}
@media screen and (min-width: 1024px) {
.mobilenavbtn {
display: none !important;
}
}
/* desktop navbar */
.navbar {
margin-top: 0;
padding-top: 5px;
background-color: #25282a;
display: block;
overflow: hidden;
}
.desktop-nav {
left: 0;
margin-top: 0;
display: block;
margin-bottom: 0;
padding-top: 3px;
margin-left: 5.5%;
padding-bottom: 3px;
transition: 143.9ms;
}
.desktop-nav li {
float: left;
margin-left: 2px;
margin-right: 2px;
transition: 0.5ms;
list-style-type: none;
}
.desktop-nav li a {
display: block;
color: #ffffff;
cursor: pointer;
margin-top: 6px;
padding-top: 8px;
margin-bottom: 6px;
padding-left: 14px;
text-align: center;
padding-bottom: 8px;
padding-right: 14px;
border-radius: 13px;
text-decoration: none;
font-family: "Zegoe UI Semi Bold - U";
font-size: 150%;
}
.desktop-nav a:hover:not(.active) {
color: #888B8D;
}
.active a {
color: #8C8B89;
}
/* responstive */
@media screen and (max-width: 1024px) {
.desktop-nav {
display: none !important;
}
}
div.user {
vertical-align: top;
display: inline-block;
text-align: center;
float: left;
margin: 5px;
margin-right: 45%;
}
.userimg {
width: 50;
height: 50;
border-radius: 45%;
background-color: grey;
}
.usercaption {
display: block;
color: #ffffff;
}

View file

@ -1,232 +0,0 @@
body {
font-family: Arial, Helvetica, sans-serif;
background-color: #2C2F33;
color: #ffffff;
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
.headding {
margin-left: 3.4%;
}
input[type=text],
select,
textarea {
width: 30%;
padding: 12px;
border: 1px solid #2C2F33;
border-radius: 4px;
box-sizing: border-box;
margin-top: 6px;
margin-bottom: 16px;
resize: vertical;
background-color: #4c4e55;
color: #ffffff;
}
.buttont {
display: flex;
background-color: #5865F2;
justify-content: center;
align-items: center;
border: rgb(240, 236, 236) 1px solid;
width: 105px;
height: 35px;
color: white;
padding: 12px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
transition: all .2s ease;
}
.buttonttt {
display: flex;
justify-content: center;
align-items: center;
border: rgb(240, 236, 236) 1px solid;
color: rgb(255, 255, 255);
min-width: 105px;
min-height: 35px;
max-width: 50%;
border-radius: 100px;
cursor: pointer;
transition: all .2s ease;
font-size: 1em;
text-decoration: none !important;
}
.button:hover {
background-color: #5460e7;
}
.button#submit:hover {
background-color: #EB459E;
}
.container {
border-radius: 5px;
background-color: #40444B;
padding: 20px;
margin: 12px;
}
.filterul {
margin: 0;
}
.filterul li {
list-style-type: none;
float: left;
padding: 5px;
margin: 3px;
border-radius: 5%;
background-color: #33363a;
}
.filters {
margin-bottom: 10px;
display: flex;
}
.flex-containor {
display: flex;
flex-direction: row;
}
@media (max-width: 858px) {
.flex-containor {
flex-direction: column;
}
.server-name-text {
margin-left: 1% !important;
}
.serverinfo {
max-width: 45% !important;
}
.dropdown-content {
width: 45% !important;
}
}
.menu {
min-width: 15%;
display: flex;
flex-direction: column;
row-gap: 0px;
}
.menu div .button {
display: flex;
justify-content: center;
align-items: center;
color: rgb(255, 255, 255);
border-radius: 25px 25px 0 0;
height: 50px;
cursor: pointer;
transition: all .2s ease;
font-size: 1em;
text-decoration: none !important;
}
.menu div .button:hover {
background-color: #363a3f;
}
.view {
min-width: 70%;
}
.view-btn-active {
background-color: #404449;
border-radius: 0 !important;
}
.serverinfo {
margin: 5px;
margin-bottom: 0;
padding: 5px;
max-width: 80%;
background-color: #575a5e;
border-radius: 8px;
}
.server-main-items {
display: flex;
flex-direction: row;
align-items: center;
align-content: center;
font-size: 1.5em;
row-gap: 1.3%;
}
.server-main-img,
.dropdown-server-main-img {
border-radius: 50%;
width: 50px;
vertical-align: middle
}
.server-name-text {
margin-left: 5.6%;
}
.server-sub-items {
margin-top: 6px;
font-size: 0.5em;
}
.dropbtn {
border: none;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #6A6D70;
width: 80%;
margin: 5px;
margin-top: 0;
padding: 5px;
font-size: 0.5em;
box-shadow: 0px 8px 16px 0px rgb(0 0 0 / 20%);
z-index: 1;
border-radius: 0 0 8px 8px;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown-content a:hover {
background-color: #52565c;
}
.dropdown:hover .dropdown-content {
display: flex;
flex-direction: column;
max-width: 80%;
}
.dropdown:hover .serverinfo {
background-color: #6a6d70;
border-radius: 8px 8px 0 0;
}
/* buttons */
.buttons {
margin-top: 5px;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -1,11 +0,0 @@
//for mobile navbar
function openNav() {
document.getElementById("mobilenavbar").style.width = "250px";
}
function closeNav() {
document.getElementById("mobilenavbar").style.width = "0";
}
if (window.innerWidth <= 280) {
alert("please open your fold phone to use this page")
}

Some files were not shown because too many files have changed in this diff Show more