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
.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
the all-purpose open source discord bot for CWH11's Hangout Crew.
### set up
- 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"
- put the mongo db connect uri in src/conf/tokens.js under { db: {URI: "here"} }
- make a mysql server with a db
- 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
better main page
batter server page
better error checking for fivem cmd
fix discord tag not showing up in fivem commands
implement /reactionrole add /reactionrole remove commands--done
implement add remove message macro cmd
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",
"version": "4.8.434",
"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": "./src/knightrider.js",
"main": "./dist/index.js",
"scripts": {
"start": "node ./src/knightrider.js",
"help": "if you need help with this bot please look at http://knightrider.invalidlag.com/help/"
"build": "tsc",
"start": "node ./dist/index.js",
"dev": "nodemon"
},
"author": "404invalid-user",
"repository": {
@ -15,22 +15,19 @@
},
"license": "Apache license 2.0",
"dependencies": {
"@discordjs/opus": "*",
"body-parser": "*",
"discord-bitfield-calculator": "^1.0.0",
"discord.js": "^12.5.3",
"ejs": "*",
"express": "*",
"express-rate-limit": "*",
"ffmpeg-static": "*",
"minecraft-server-util": "*",
"mongoose": "*",
"node-fetch": "*",
"randomstring": "*",
"request": "*",
"url": "^*",
"util": "*",
"yt-search": "*",
"ytdl-core": "*"
"discord.js": "^14.16.3",
"dotenv": "^16.4.5",
"express": "^4.21.1",
"mariadb": "^3.4.0",
"mcstatusbot-logger": "^1.0.5",
"mysql2": "^3.12.0",
"sequelize": "^6.37.5"
},
"devDependencies": {
"@types/express": "^5.0.0",
"nodemon": "^3.1.9",
"ts-node": "^10.9.2"
}
}
}

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