mirror of
				https://github.com/keanuplayz/TravBot-v3.git
				synced 2024-08-15 02:33:12 +00:00 
			
		
		
		
	Merge pull request #19 from keanuplayz/testing
Attempting to fix the emote name resolution
This commit is contained in:
		
						commit
						f84cc726be
					
				
					 4 changed files with 53 additions and 29 deletions
				
			
		|  | @ -10,5 +10,5 @@ module.exports = { | ||||||
|     bracketSpacing: false, |     bracketSpacing: false, | ||||||
|     jsxBracketSameLine: false, |     jsxBracketSameLine: false, | ||||||
|     arrowParens: "always", |     arrowParens: "always", | ||||||
|     endOfLine: "lf" |     endOfLine: "auto" // Apparently, the GitHub repository still uses CRLF. I don't know how to force it to use LF, and until someone figures that out, I'm changing this to auto because I don't want more than one line ending commit.
 | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -1,19 +1,19 @@ | ||||||
| import {MessageEmbed} from "discord.js"; |  | ||||||
| import Command from "../../core/command"; | import Command from "../../core/command"; | ||||||
| import {CommonLibrary} from "../../core/lib"; | import {queryClosestEmoteByName} from "./subcommands/emote-utils"; | ||||||
|  | import {botHasPermission} from "../../core/lib"; | ||||||
|  | import {Permissions} from "discord.js"; | ||||||
| 
 | 
 | ||||||
| export default new Command({ | export default new Command({ | ||||||
|     description: "Send the specified emote.", |     description: "Send the specified emote.", | ||||||
|     run: "Please provide a command name.", |     run: "Please provide a command name.", | ||||||
|     any: new Command({ |     any: new Command({ | ||||||
|         description: "The emote to send.", |         description: "The emote(s) to send.", | ||||||
|         usage: "<emote>", |         usage: "<emotes...>", | ||||||
|         async run($: CommonLibrary): Promise<any> { |         async run({guild, channel, message, args}) { | ||||||
|             const search = $.args[0].toLowerCase(); |             let output = ""; | ||||||
|             const emote = $.client.emojis.cache.find((emote) => emote.name.toLowerCase().includes(search)); |             for (const query of args) output += queryClosestEmoteByName(query).toString(); | ||||||
|             if (!emote) return $.channel.send("That's not a valid emote name!"); |             if (botHasPermission(guild, Permissions.FLAGS.MANAGE_MESSAGES)) message.delete(); | ||||||
|             $.message.delete(); |             channel.send(output); | ||||||
|             $.channel.send(`${emote}`); |  | ||||||
|         } |         } | ||||||
|     }) |     }) | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| import Command from "../../core/command"; | import Command from "../../core/command"; | ||||||
| import {CommonLibrary} from "../../core/lib"; | import {CommonLibrary} from "../../core/lib"; | ||||||
| import {Message, Channel, TextChannel} from "discord.js"; | import {Message, Channel, TextChannel} from "discord.js"; | ||||||
|  | import {queryClosestEmoteByName} from "./subcommands/emote-utils"; | ||||||
| 
 | 
 | ||||||
| export default new Command({ | export default new Command({ | ||||||
|     description: |     description: | ||||||
|  | @ -94,26 +95,16 @@ export default new Command({ | ||||||
|             ).last(); |             ).last(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         let anyEmoteIsValid = false; |  | ||||||
| 
 |  | ||||||
|         for (const search of $.args) { |         for (const search of $.args) { | ||||||
|             const emoji = $.client.emojis.cache.find((emoji) => emoji.name === search); |             // Even though the bot will always grab *some* emote, the user can choose not to keep that emote there if it isn't what they want
 | ||||||
| 
 |             const emote = queryClosestEmoteByName(search); | ||||||
|             if (emoji) { |             const reaction = await target!.react(emote); | ||||||
|                 // Call the delete function only once to avoid unnecessary errors.
 |  | ||||||
|                 if (!anyEmoteIsValid && distance !== 0) $.message.delete(); |  | ||||||
|                 anyEmoteIsValid = true; |  | ||||||
|                 const reaction = await target?.react(emoji); |  | ||||||
| 
 | 
 | ||||||
|             // This part is called with a promise because you don't want to wait 5 seconds between each reaction.
 |             // This part is called with a promise because you don't want to wait 5 seconds between each reaction.
 | ||||||
| 
 |  | ||||||
|             setTimeout(() => { |             setTimeout(() => { | ||||||
|                     /// @ts-ignore
 |                 // This reason for this null assertion is that by the time you use this command, the client is going to be loaded.
 | ||||||
|                     reaction.users.remove($.client.user); |                 reaction.users.remove($.client.user!); | ||||||
|             }, 5000); |             }, 5000); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|         if (!anyEmoteIsValid && !$.message.deleted) $.message.react("❓"); |  | ||||||
|     } |  | ||||||
| }); | }); | ||||||
|  |  | ||||||
							
								
								
									
										33
									
								
								src/commands/utilities/subcommands/emote-utils.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/commands/utilities/subcommands/emote-utils.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,33 @@ | ||||||
|  | import {client} from "../../../index"; | ||||||
|  | 
 | ||||||
|  | // Calculate and match the list of emotes against the queried emote, then sort the IDs based on calculated priority.
 | ||||||
|  | export function queryClosestEmoteByName(query: string) { | ||||||
|  |     const priorityTable: {[id: string]: number} = {}; | ||||||
|  | 
 | ||||||
|  |     for (const emote of client.emojis.cache.values()) priorityTable[emote.id] = compareEmoteNames(emote.name, query); | ||||||
|  | 
 | ||||||
|  |     const resultingIDs = Object.keys(priorityTable).sort((a, b) => priorityTable[b] - priorityTable[a]); | ||||||
|  |     return client.emojis.cache.get(resultingIDs[0])!; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Compare an emote's name against a query to see how alike the two are. The higher the number, the closer they are. Takes into account length and capitalization.
 | ||||||
|  | function compareEmoteNames(emote: string, query: string) { | ||||||
|  |     let likeness = -Math.abs(emote.length - query.length); | ||||||
|  |     const isQueryLonger = query.length > emote.length; | ||||||
|  | 
 | ||||||
|  |     // Loop through all indexes that the two strings share then compare each letter.
 | ||||||
|  |     for (let i = 0; i < (isQueryLonger ? emote.length : query.length); i++) { | ||||||
|  |         const c = emote[i]; | ||||||
|  |         const q = query[i]; | ||||||
|  | 
 | ||||||
|  |         // If they're the exact same character
 | ||||||
|  |         if (c === q) likeness += 1.5; | ||||||
|  |         // If the emote is uppercase but the query is lowercase
 | ||||||
|  |         else if (c === q.toUpperCase()) likeness += 1; | ||||||
|  |         // If the emote is lowercase but the query is uppercase
 | ||||||
|  |         else if (c === q.toLowerCase()) likeness += 0.5; | ||||||
|  |         // Otherwise, if they're different characters, don't add anything (this isn't a spellchecker)
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return likeness; | ||||||
|  | } | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue