syntax.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import { Util } from 'discord.js';
  2. import { got } from '../../util/functions.js';
  3. import Wiki from '../../util/wiki.js';
  4. import { createRequire } from 'module';
  5. const require = createRequire(import.meta.url);
  6. const commands = require('./commands.json');
  7. /**
  8. * Sends a Minecraft command.
  9. * @param {import('../../util/i18n.js').default} lang - The user language.
  10. * @param {import('discord.js').Message} msg - The Discord message.
  11. * @param {import('../../util/wiki.js').default} wiki - The wiki.
  12. * @param {String} mccmd - The Minecraft command argument.
  13. * @param {String[]} args - The command arguments.
  14. * @param {String} title - The page title.
  15. * @param {String} cmd - The command at this point.
  16. * @param {import('discord.js').MessageReaction} reaction - The reaction on the message.
  17. * @param {String} spoiler - If the response is in a spoiler.
  18. * @param {Boolean} noEmbed - If the response should be without an embed.
  19. */
  20. function minecraft_syntax(lang, msg, wiki, mccmd, args, title, cmd, reaction, spoiler, noEmbed) {
  21. mccmd = mccmd.toLowerCase();
  22. var aliasCmd = ( commands.aliases[mccmd] || mccmd );
  23. var cmdpage = commands.wikis[wiki.href];
  24. if ( commands.list.hasOwnProperty(aliasCmd) ) {
  25. var cmdSyntaxMap = commands.list[aliasCmd].map( command => {
  26. var cmdargs = command.split(' ');
  27. if ( cmdargs[0].startsWith( '/' ) ) cmdargs = cmdargs.slice(1);
  28. var argmatches = cmdargs.map( (arg, i) => {
  29. if ( arg === args[i] ) return true;
  30. } );
  31. var matchCount = 0;
  32. argmatches.forEach( match => {
  33. if ( match ) matchCount++;
  34. } );
  35. return [argmatches.lastIndexOf(true),matchCount];
  36. } );
  37. var lastIndex = Math.max(...cmdSyntaxMap.map( command => command[0] ));
  38. var matchCount = Math.max(...cmdSyntaxMap.filter( command => command[0] === lastIndex ).map( command => command[1] ));
  39. var regex = new RegExp('/' + aliasCmd, 'g');
  40. var cmdSyntax = commands.list[aliasCmd].filter( (command, i) => ( lastIndex === -1 || cmdSyntaxMap[i][0] === lastIndex ) && cmdSyntaxMap[i][1] === matchCount ).join('\n').replaceSave( regex, '/' + mccmd );
  41. got.get( wiki + ( cmdpage.endsWith( '/' ) ? 'api.php?action=query&redirects=true&converttitles=true&titles=%1F' + encodeURIComponent( cmdpage + aliasCmd ) : 'api.php?action=parse&redirects=true&prop=sections&page=' + encodeURIComponent( cmdpage ) ) + '&format=json' ).then( response => {
  42. var body = response.body;
  43. if ( body && body.warnings ) log_warning(body.warnings);
  44. if ( response.statusCode !== 200 || !( body?.query?.pages || body?.parse?.sections?.length ) ) {
  45. console.log( '- ' + response.statusCode + ': Error while getting the command page: ' + ( body && body.error && body.error.info ) );
  46. }
  47. else if ( cmdpage.endsWith( '/' ) ) {
  48. if ( body.query.pages['-1'] ) {
  49. wiki = new Wiki('https://minecraft.fandom.com/');
  50. cmdpage = 'Commands/';
  51. }
  52. else {
  53. cmdpage = Object.values(body.query.pages)[0].title;
  54. aliasCmd = ( body.query.redirects?.[0]?.tofragment || '' );
  55. }
  56. }
  57. else {
  58. cmdpage = body.parse.title;
  59. if ( !body.parse.sections.some( section => section.anchor === aliasCmd ) ) {
  60. if ( body.parse.sections.some( section => section.anchor === mccmd ) ) {
  61. aliasCmd = mccmd;
  62. }
  63. else {
  64. wiki = new Wiki('https://minecraft.fandom.com/');
  65. cmdpage = 'Commands/';
  66. }
  67. }
  68. }
  69. }, error => {
  70. console.log( '- Error while getting the command page: ' + error );
  71. } ).finally( () => {
  72. Util.splitMessage( spoiler + '```md\n' + cmdSyntax + '```<' + wiki.toLink(( cmdpage.endsWith( '/' ) ? cmdpage + aliasCmd : cmdpage ), '', ( cmdpage.endsWith( '/' ) ? '' : aliasCmd )) + '>' + spoiler, {maxLength: 2000, prepend: spoiler + '```md\n', append: '```' + spoiler} ).forEach( textpart => msg.sendChannel( textpart ) );
  73. if ( reaction ) reaction.removeEmoji();
  74. } );
  75. }
  76. else {
  77. msg.notMinecraft = true;
  78. this.WIKI.general(lang, msg, title, wiki, cmd, reaction, spoiler, noEmbed);
  79. }
  80. }
  81. export default {
  82. name: 'SYNTAX',
  83. run: minecraft_syntax
  84. };