mirror of
				https://github.com/keanuplayz/TravBot-v3.git
				synced 2024-08-15 02:33:12 +00:00 
			
		
		
		
	Various small changes/fixes
This commit is contained in:
		
							parent
							
								
									53705e76c5
								
							
						
					
					
						commit
						139630ce9f
					
				
					 11 changed files with 57 additions and 74 deletions
				
			
		|  | @ -2,6 +2,8 @@ import Command from "../core/command"; | |||
| import {CommonLibrary, logs} from "../core/lib"; | ||||
| import {Config, Storage} from "../core/structures"; | ||||
| import {PermissionNames, getPermissionLevel} from "../core/permissions"; | ||||
| import {botHasPermission} from "../index"; | ||||
| import {Permissions} from "discord.js"; | ||||
| 
 | ||||
| function getLogBuffer(type: string) | ||||
| { | ||||
|  | @ -11,12 +13,7 @@ function getLogBuffer(type: string) | |||
| 	}]}; | ||||
| } | ||||
| 
 | ||||
| const activities: { [type: string]: string } = { | ||||
| 	playing: "", | ||||
| 	listening: "", | ||||
| 	streaming: "", | ||||
| 	watching: "" | ||||
| }; | ||||
| const activities = ["playing", "listening", "streaming", "watching"]; | ||||
| 
 | ||||
| export default new Command({ | ||||
| 	description: "An all-in-one command to do admin stuff. You need to be either an admin of the server or one of the bot's mechanics to use this command.", | ||||
|  | @ -63,7 +60,7 @@ export default new Command({ | |||
| 				$.channel.send(getLogBuffer("info")); | ||||
| 			}, | ||||
| 			any: new Command({ | ||||
| 				description: `Select a verbosity to listen to. Available levels: \`[${Object.keys(logs)}]\``, | ||||
| 				description: `Select a verbosity to listen to. Available levels: \`[${Object.keys(logs).join(", ")}]\``, | ||||
| 				async run($: CommonLibrary): Promise<any> | ||||
| 				{ | ||||
| 					const type = $.args[0]; | ||||
|  | @ -71,7 +68,7 @@ export default new Command({ | |||
| 					if(type in logs) | ||||
| 						$.channel.send(getLogBuffer(type)); | ||||
| 					else | ||||
| 						$.channel.send(`Couldn't find a verbosity level named \`${type}\`! The available types are \`[${Object.keys(logs)}]\`.`); | ||||
| 						$.channel.send(`Couldn't find a verbosity level named \`${type}\`! The available types are \`[${Object.keys(logs).join(", ")}]\`.`); | ||||
| 				} | ||||
| 			}) | ||||
| 		}), | ||||
|  | @ -118,16 +115,13 @@ export default new Command({ | |||
| 			permission: Command.PERMISSIONS.BOT_SUPPORT, | ||||
| 			async run($: CommonLibrary): Promise<any> | ||||
| 			{ | ||||
| 				try { | ||||
| 				const nickName = $.args.join(" "); | ||||
| 				const trav = $.guild?.members.cache.find(member => member.id === $.client.user?.id); | ||||
| 				await trav?.setNickname(nickName); | ||||
| 					$.message.delete({timeout: 5000}); | ||||
| 				if(botHasPermission($.guild, Permissions.FLAGS.MANAGE_MESSAGES)) | ||||
| 					$.message.delete({timeout: 5000}).catch($.handler.bind($)); | ||||
| 				$.channel.send(`Nickname set to \`${nickName}\``) | ||||
| 					.then(m => m.delete({timeout: 5000})); | ||||
| 				} catch (e) { | ||||
| 					console.log(e); | ||||
| 				} | ||||
| 			} | ||||
| 		}), | ||||
| 		guilds: new Command({ | ||||
|  | @ -152,17 +146,17 @@ export default new Command({ | |||
| 				$.channel.send("Activity set to default.") | ||||
| 			}, | ||||
| 			any: new Command({ | ||||
| 				description: `Select an activity type to set. Available levels: \`[${Object.keys(activities)}]\``, | ||||
| 				description: `Select an activity type to set. Available levels: \`[${activities.join(", ")}]\``, | ||||
| 				async run($: CommonLibrary): Promise<any> | ||||
| 				{ | ||||
| 					const type = $.args[0]; | ||||
| 					 | ||||
| 					if(type in activities) { | ||||
| 					if(activities.includes(type)) { | ||||
| 						$.client.user?.setActivity($.args.slice(1).join(" "), {type: $.args[0].toUpperCase()}) | ||||
| 						$.channel.send(`Set activity to \`${$.args[0].toUpperCase()}\` \`${$.args.slice(1).join(" ")}\`.`) | ||||
| 					} | ||||
| 					else | ||||
| 						$.channel.send(`Couldn't find an activity type named \`${type}\`! The available types are \`[${Object.keys(activities)}]\`.`); | ||||
| 						$.channel.send(`Couldn't find an activity type named \`${type}\`! The available types are \`[${activities.join(", ")}]\`.`); | ||||
| 				} | ||||
| 			}) | ||||
| 		}) | ||||
|  |  | |||
|  | @ -41,7 +41,7 @@ export default new Command({ | |||
| 				async run($: CommonLibrary): Promise<any> | ||||
| 				{ | ||||
| 					const sender = $.message.author; | ||||
| 					$.channel.send(responses[Math.floor(Math.random() * responses.length)] + ` <@${sender.id}>`); | ||||
| 					$.channel.send($(responses).random() + ` <@${sender.id}>`); | ||||
| 				} | ||||
| 			}) | ||||
| 		}), | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ import { verificationLevels, filterLevels, regions, flags } from "../defs/info"; | |||
| 
 | ||||
| export default new Command({ | ||||
| 	description: "Command to provide all sorts of info about the current server, a user, etc.", | ||||
| 	run: "Please provide an argument.\nFor help, run `.help info`.", | ||||
| 	run: "Please provide an argument.\nFor help, run `%prefix%help info`.", | ||||
| 	subcommands: | ||||
| 	{ | ||||
| 		avatar: new Command({ | ||||
|  |  | |||
|  | @ -1,34 +1,31 @@ | |||
| import {Client} from "discord.js"; | ||||
| import {Client, ClientEvents, Constants} from "discord.js"; | ||||
| import Storage from "./storage"; | ||||
| import $ from "./lib"; | ||||
| 
 | ||||
| // Last Updated: Discord.js v12.2.0
 | ||||
| const EVENTS = ["channelCreate", "channelDelete", "channelPinsUpdate", "channelUpdate", "debug", "warn", "disconnect", "emojiCreate", "emojiDelete", "emojiUpdate", "error", "guildBanAdd", "guildBanRemove", "guildCreate", "guildDelete", "guildUnavailable", "guildIntegrationsUpdate", "guildMemberAdd", "guildMemberAvailable", "guildMemberRemove", "guildMembersChunk", "guildMemberSpeaking", "guildMemberUpdate", "guildUpdate", "inviteCreate", "inviteDelete", "message", "messageDelete", "messageReactionRemoveAll", "messageReactionRemoveEmoji", "messageDeleteBulk", "messageReactionAdd", "messageReactionRemove", "messageUpdate", "presenceUpdate", "rateLimit", "ready", "invalidated", "roleCreate", "roleDelete", "roleUpdate", "typingStart", "userUpdate", "voiceStateUpdate", "webhookUpdate", "shardDisconnect", "shardError", "shardReady", "shardReconnecting", "shardResume"]; | ||||
| 
 | ||||
| interface EventOptions | ||||
| interface EventOptions<K extends keyof ClientEvents> | ||||
| { | ||||
| 	readonly on?: Function; | ||||
| 	readonly once?: Function; | ||||
| 	readonly on?: (...args: ClientEvents[K]) => void; | ||||
| 	readonly once?: (...args: ClientEvents[K]) => void; | ||||
| } | ||||
| 
 | ||||
| export default class Event | ||||
| export default class Event<K extends keyof ClientEvents> | ||||
| { | ||||
| 	private readonly on: Function|null; | ||||
| 	private readonly once: Function|null; | ||||
| 	private readonly on?: (...args: ClientEvents[K]) => void; | ||||
| 	private readonly once?: (...args: ClientEvents[K]) => void; | ||||
| 	 | ||||
| 	constructor(options: EventOptions) | ||||
| 	constructor(options: EventOptions<K>) | ||||
| 	{ | ||||
| 		this.on = options.on || null; | ||||
| 		this.once = options.once || null; | ||||
| 		this.on = options.on; | ||||
| 		this.once = options.once; | ||||
| 	} | ||||
| 	 | ||||
| 	// For this function, I'm going to assume that the event is used with the correct arguments and that the event tag is checked in "storage.ts".
 | ||||
| 	public attach(client: Client, event: string) | ||||
| 	public attach(client: Client, event: K) | ||||
| 	{ | ||||
| 		if(this.on) | ||||
| 			client.on(event as any, this.on as any); | ||||
| 			client.on(event, this.on); | ||||
| 		if(this.once) | ||||
| 			client.once(event as any, this.once as any); | ||||
| 			client.once(event, this.once); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -39,7 +36,7 @@ export async function loadEvents(client: Client) | |||
| 		const header = file.substring(0, file.indexOf(".js")); | ||||
| 		const event = (await import(`../events/${header}`)).default; | ||||
| 		 | ||||
| 		if(EVENTS.includes(header)) | ||||
| 		if((Object.values(Constants.Events) as string[]).includes(header)) | ||||
| 		{ | ||||
| 			event.attach(client, header); | ||||
| 			$.log(`Loading Event: ${header}`); | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ import {Client, Message, TextChannel, DMChannel, NewsChannel, Guild, User, Guild | |||
| import chalk from "chalk"; | ||||
| import FileManager from "./storage"; | ||||
| import {eventListeners} from "../events/messageReactionRemove"; | ||||
| import {client} from "../index"; | ||||
| import {botHasPermission} from "../index"; | ||||
| 
 | ||||
| /** A type that describes what the library module does. */ | ||||
| export interface CommonLibrary | ||||
|  | @ -170,10 +170,10 @@ $.paginate = async(message: Message, senderID: string, total: number, callback: | |||
| 	await message.awaitReactions((reaction, user) => { | ||||
| 		// The reason this is inside the call is because it's possible to switch a user's permissions halfway and suddenly throw an error.
 | ||||
| 		// This will dynamically adjust for that, switching modes depending on whether it currently has the "Manage Messages" permission.
 | ||||
| 		const canDeleteEmotes = !!(client.user && message.guild?.members.resolve(client.user)?.hasPermission(Permissions.FLAGS.MANAGE_MESSAGES)); | ||||
| 		const canDeleteEmotes = botHasPermission(message.guild, Permissions.FLAGS.MANAGE_MESSAGES); | ||||
| 		handle(reaction.emoji.name, user.id); | ||||
| 		 | ||||
| 		if(canDeleteEmotes && user.id !== client.user?.id) | ||||
| 		if(canDeleteEmotes) | ||||
| 			reaction.users.remove(user); | ||||
| 		 | ||||
| 		return false; | ||||
|  | @ -258,7 +258,7 @@ export function parseArgs(line: string): string[] | |||
|  * - `%%` = `%` | ||||
|  * - If the invalid token is null/undefined, nothing is changed. | ||||
|  */ | ||||
| export function parseVars(line: string, definitions: {[key: string]: string}, invalid: string|null|undefined = ""): string | ||||
| export function parseVars(line: string, definitions: {[key: string]: string}, invalid: string|null = ""): string | ||||
| { | ||||
| 	let result = ""; | ||||
| 	let inVariable = false; | ||||
|  | @ -276,7 +276,7 @@ export function parseVars(line: string, definitions: {[key: string]: string}, in | |||
| 				{ | ||||
| 					if(token in definitions) | ||||
| 						result += definitions[token]; | ||||
| 					else if(invalid === undefined || invalid === null) | ||||
| 					else if(invalid === null) | ||||
| 						result += `%${token}%`; | ||||
| 					else | ||||
| 						result += invalid; | ||||
|  | @ -352,7 +352,7 @@ export interface GenericJSON | |||
| 
 | ||||
| export abstract class GenericStructure | ||||
| { | ||||
| 	protected __meta__ = "generic"; | ||||
| 	private __meta__ = "generic"; | ||||
| 	 | ||||
| 	constructor(tag?: string) | ||||
| 	{ | ||||
|  |  | |||
|  | @ -38,30 +38,17 @@ const length = Object.keys(PERMISSIONS).length / 2; | |||
| 
 | ||||
| export function hasPermission(member: GuildMember, permission: PERMISSIONS): boolean | ||||
| { | ||||
| 	if(permission === PERMISSIONS.NONE) | ||||
| 		return true; | ||||
| 	 | ||||
| 	for(let i = length-1; i >= permission; i--) | ||||
| 	{ | ||||
| 		const condition = PermissionChecker[i](member); | ||||
| 		 | ||||
| 		if(condition) | ||||
| 		if(PermissionChecker[i](member)) | ||||
| 			return true; | ||||
| 	} | ||||
| 	 | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| export function getPermissionLevel(member: GuildMember): number | ||||
| { | ||||
| 	for(let i = length-1; i >= 0; i--) | ||||
| 	{ | ||||
| 		const condition = PermissionChecker[i](member); | ||||
| 		 | ||||
| 		if(condition) | ||||
| 		if(PermissionChecker[i](member)) | ||||
| 			return i; | ||||
| 	} | ||||
| 	 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,15 +1,15 @@ | |||
| import Event from "../core/event"; | ||||
| import Command, {loadCommands} from "../core/command"; | ||||
| import {hasPermission, getPermissionLevel, PermissionNames} from "../core/permissions"; | ||||
| import $ from "../core/lib"; | ||||
| import {Message, Permissions, Collection} from "discord.js"; | ||||
| import {Permissions, Collection} from "discord.js"; | ||||
| import {getPrefix} from "../core/structures"; | ||||
| import $ from "../core/lib"; | ||||
| 
 | ||||
| // It's a rather hacky solution, but since there's no top-level await, I just have to make the loading conditional.
 | ||||
| let commands: Collection<string, Command>|null = null; | ||||
| 
 | ||||
| export default new Event({ | ||||
| 	async on(message: Message) | ||||
| export default new Event<"message">({ | ||||
| 	async on(message) | ||||
| 	{ | ||||
| 		// Load commands if it hasn't already done so. Luckily, it's called once at most.
 | ||||
| 		if(!commands) | ||||
|  |  | |||
|  | @ -1,15 +1,15 @@ | |||
| import Event from "../core/event"; | ||||
| import {MessageReaction, User, PartialUser, Permissions} from "discord.js"; | ||||
| import {client} from "../index"; | ||||
| import {Permissions} from "discord.js"; | ||||
| import {botHasPermission} from "../index"; | ||||
| 
 | ||||
| // A list of message ID and callback pairs. You get the emote name and ID of the user reacting.
 | ||||
| export const eventListeners: Map<string, (emote: string, id: string) => void> = new Map(); | ||||
| 
 | ||||
| // Attached to the client, there can be one event listener attached to a message ID which is executed if present.
 | ||||
| export default new Event({ | ||||
| 	on(reaction: MessageReaction, user: User|PartialUser) | ||||
| export default new Event<"messageReactionRemove">({ | ||||
| 	on(reaction, user) | ||||
| 	{ | ||||
| 		const canDeleteEmotes = !!(client.user && reaction.message.guild?.members.resolve(client.user)?.hasPermission(Permissions.FLAGS.MANAGE_MESSAGES)); | ||||
| 		const canDeleteEmotes = botHasPermission(reaction.message.guild, Permissions.FLAGS.MANAGE_MESSAGES); | ||||
| 		 | ||||
| 		if(!canDeleteEmotes) | ||||
| 		{ | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ import {client} from "../index"; | |||
| import $ from "../core/lib"; | ||||
| import {Config} from "../core/structures"; | ||||
| 
 | ||||
| export default new Event({ | ||||
| export default new Event<"ready">({ | ||||
| 	once() | ||||
| 	{ | ||||
| 		if(client.user) | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| import {Client} from "discord.js"; | ||||
| import {Client, Guild} from "discord.js"; | ||||
| import setup from "./setup"; | ||||
| import {Config} from "./core/structures"; | ||||
| import {loadCommands} from "./core/command"; | ||||
|  | @ -14,3 +14,8 @@ setup.init().then(() => { | |||
| 	loadEvents(client); | ||||
| 	client.login(Config.token).catch(setup.again); | ||||
| }); | ||||
| 
 | ||||
| export function botHasPermission(guild: Guild|null, permission: number): boolean | ||||
| { | ||||
| 	return !!(client.user && guild?.members.resolve(client.user)?.hasPermission(permission)) | ||||
| } | ||||
|  | @ -44,7 +44,7 @@ export default { | |||
| 			Config.admins = admins !== "" ? admins.split(" ") : []; | ||||
| 			const support = (answers.support as string); | ||||
| 			Config.support = support !== "" ? support.split(" ") : []; | ||||
| 			Config.save(); | ||||
| 			Config.save(false); | ||||
| 		} | ||||
| 	}, | ||||
| 	/** Prompt the user to set their token again. */ | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue