musicbot.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. const Discord = require ( 'discord.js' );
  2. const Client = new Discord.Client ( );
  3. const logger = require ( './logger.js' );
  4. const Config = require ( './config.json' );
  5. const fs = require ( 'fs' );
  6. let isVoiceChannel = false;
  7. let dispatcher = undefined;
  8. let voteSkips = 0;
  9. let voteSkipped = { };
  10. let globalVoiceChannel = null;
  11. let songs = [];
  12. let songQueue = [];
  13. function shuffleArray ( array )
  14. {
  15. let newArray = Array.from ( array );
  16. let remaining = newArray.length, index, temp;
  17. while ( remaining > 0 )
  18. {
  19. index = Math.floor ( ( Math.random ( ) * remaining ) );
  20. remaining = remaining - 1;
  21. temp = newArray [remaining];
  22. newArray [remaining] = newArray [index];
  23. newArray [index] = temp;
  24. }
  25. return newArray;
  26. }
  27. function musicQueueRandomize ( )
  28. {
  29. logger.log ( '[Info/automusic] a new song queue will now be randomized!' );
  30. songQueue = shuffleArray ( songs );
  31. }
  32. function musicQueueInsert ( song )
  33. {
  34. logger.log ( '[Info/automusic] added song to queue: ' + song );
  35. songQueue.push ( song );
  36. }
  37. function musicQueuePop ( )
  38. {
  39. return songQueue.pop ( );
  40. }
  41. function getNextSong ( )
  42. {
  43. if ( songQueue.length > 0 ) return musicQueuePop ( );
  44. else
  45. {
  46. generateSongList ( );
  47. musicQueueRandomize ( );
  48. return musicQueuePop ( );
  49. }
  50. }
  51. function generateSongList ( )
  52. {
  53. songs = [ ];
  54. fs.readdirSync ( './playlist' ).forEach ( function ( file )
  55. {
  56. songs.push ( file );
  57. } );
  58. }
  59. function musicQueueGet ( )
  60. {
  61. return Array.from ( songQueue );
  62. }
  63. function playMusic ( )
  64. {
  65. let song = getNextSong ( );
  66. logger.log ( '[Sound/automusic] now playing: ' + song );
  67. let voiceChannel = Client.channels.get ( Config.channel_id );
  68. globalVoiceChannel = voiceChannel;
  69. if ( voiceChannel instanceof Discord.VoiceChannel )
  70. {
  71. voiceChannel.join ( ).then ( ( connection ) =>
  72. {
  73. connection.on ( 'disconnect', function ( )
  74. {
  75. logger.log ( '[Info/automusic] disconnected from channel, will reconnect soon' );
  76. setTimeout ( function ( )
  77. {
  78. logger.log ( '[Info/automusic] reconnecting' );
  79. playMusic ( );
  80. }, 3000 );
  81. } );
  82. globalConnection = connection;
  83. dispatcher = connection.play ( './playlist/' + song, { passes: 3 } );
  84. dispatcher.on ( 'error', function ( m ) { logger.error ( m ); } );
  85. dispatcher.on ( 'end', ( ) =>
  86. {
  87. setTimeout ( function ( )
  88. {
  89. let announcer = connection.play ( './announcer.mp3', { passes: 3 } );
  90. announcer.on ( 'error', function ( m ) { logger.error ( m ); } );
  91. logger.log ( '[Info/automusic] playing announcer' );
  92. announcer.on ( 'end', ( ) =>
  93. {
  94. voteSkips = 0;
  95. voteSkipped = { };
  96. logger.log ( '[Info/automusic] song concluded, playing another random song' );
  97. setTimeout ( function ( ) { playMusic ( ); }, 500 );
  98. } );
  99. }, 1000 );
  100. } );
  101. } )
  102. .catch ( ( error ) => {
  103. logger.log ( '[Error/automusic] cannot join voice channel' );
  104. logger.log ( error );
  105. } );
  106. }
  107. else
  108. {
  109. logger.log ( '[Info/automusic] WARNING! ' + Config.channel_id + ' is not a valid voice channel id!' );
  110. }
  111. }
  112. Client.on ( 'ready', ( ) =>
  113. {
  114. // client is ready
  115. logger.log ( '[Info/automusic] logged in!' );
  116. Client.user.setActivity ( 'weeb shit', { type: 'LISTENING' } );
  117. playMusic ( );
  118. } );
  119. Client.on ( 'warning', function ( m ) { logger.warn ( m ); } )
  120. .on ( 'error', function ( m ) { logger.error ( m ); } )
  121. .on ( 'disconnect', ( ) => {
  122. logger.warn ( '[Info/automusic] disconnected!' );
  123. } );
  124. function formatResponse ( text )
  125. {
  126. if ( typeof text === 'string' )
  127. return text.replace( /`/g, "`" + String.fromCharCode ( 8203 ) ).replace ( /@/g, "@" + String.fromCharCode ( 8203 ) );
  128. else
  129. return text;
  130. }
  131. Client.on ( 'message', ( message ) =>
  132. {
  133. // maintenance
  134. if ( message.content.startsWith ( '$voteskip' ) )
  135. {
  136. let userid = message.author.id;
  137. let onlineusers = globalVoiceChannel.members.size;
  138. let required = Math.floor ( ( onlineusers - 1 ) / 2 );
  139. if ( !voteSkipped [userid] )
  140. {
  141. voteSkips++;
  142. message.channel.send ( "Zarejestrowano twój glos **" + voteSkips + "/" + ( required + 1 ) + "**" );
  143. voteSkipped [userid] = true;
  144. if ( voteSkips > Math.floor ( ( onlineusers - 1 ) / 2 ) )
  145. {
  146. message.channel.send ( "Głosem większości dostępnych piosenka została pominięta." );
  147. dispatcher.end ( );
  148. }
  149. }
  150. else
  151. {
  152. message.channel.send ( "Twój głos był już zarejestrowany." );
  153. }
  154. }
  155. else if ( message.content.startsWith ( '$cancelvote' ) )
  156. {
  157. let userid = message.author.id;
  158. let onlineusers = globalVoiceChannel.members.size;
  159. let required = Math.floor ( ( onlineusers - 1 ) / 2 );
  160. if ( voteSkipped [userid] )
  161. {
  162. voteSkips--;
  163. message.channel.send ( "Wycofano twój głos **" + voteSkips + "/" + ( required + 1 ) + "**" );
  164. voteSkipped [userid] = false;
  165. }
  166. else
  167. {
  168. message.channel.send ( "Nie głosowałeś za pominięciem tej piosenki." );
  169. }
  170. }
  171. else if ( message.content.startsWith ( '$lock' ) )
  172. {
  173. message.channel.send ( "Nie będę wyłączał tej chujowej piosenki z demokratycznego głosowania." );
  174. }
  175. else if ( message.content.startsWith ( '$skip' ) && message.member.hasPermission( 'KICK_MEMBERS' ) )
  176. {
  177. dispatcher.end ( );
  178. return;
  179. }
  180. else if ( message.content.startsWith ( '$eval ' ) && message.author.id === '276791868141076480' )
  181. {
  182. try
  183. {
  184. let payload = message.content.substring ( 6, message.content.length );
  185. let output = true;
  186. let result = eval ( payload );
  187. if ( output )
  188. message.channel.send ( formatResponse ( result ), { code: 'xl' } );
  189. }
  190. catch ( error )
  191. {
  192. message.channel.send ( '```' + formatResponse ( error ) + '```' );
  193. }
  194. return;
  195. }
  196. } );
  197. Client.on ( 'disconnect', function ( )
  198. {
  199. logger.error ( '[Error/musicbot] disconnected. bot will try to reconnect soon (10 seconds)' );
  200. setTimeout ( function ( )
  201. {
  202. logger.log ( '[Info/musicbot] reconnecting' );
  203. Client.login ( Config.token );
  204. }, 10000 );
  205. } );
  206. module.exports.run = function ( )
  207. {
  208. logger.log ( '[Info/musicbot] initializing bot account' );
  209. Client.login ( Config.token );
  210. }
  211. module.exports.musicQueueInsert = musicQueueInsert;
  212. module.exports.musicQueuePop = musicQueuePop;
  213. module.exports.musicQueueRandomize = musicQueueRandomize;
  214. module.exports.musicQueueGet = musicQueueGet;