2023-03-05 14:46:25 +07:00
import {
Guild ,
Client ,
GuildMember ,
IntentsBitField ,
Interaction ,
Message ,
TextChannel ,
BaseGuildTextChannel ,
TextBasedChannelMixin ,
ChannelType ,
BaseGuildVoiceChannel ,
InteractionType
} from 'discord.js' ;
2021-09-14 09:56:11 -07:00
2022-06-06 14:59:53 +07:00
import Logger from '../libs/Logger' ;
import Environment from './Environment' ;
2021-09-14 09:56:11 -07:00
2022-06-06 14:59:53 +07:00
import Discord_Core from '../discord/Core' ;
import Discord_Settings from '../discord/Settings' ;
import Discord_Ping from '../discord/Ping' ;
import Discord_Help from '../discord/Help' ;
import Discord_Invite from '../discord/Invite' ;
import Discord_Say from '../discord/Say' ;
import Discord_InteractionManager from '../discord/InteractionManager' ;
import Discord_MembershipScreening from '../discord/MembershipScreening' ;
import Discord_osu from '../discord/osu' ;
2023-04-23 13:13:20 +07:00
import Discord_VRChat from '../discord/VRChat' ;
2023-04-23 17:51:25 +07:00
import Discord_VRChatLogin from '../discord/Developer/VRChatLogin' ;
2022-06-06 14:59:53 +07:00
import Discord_UserInfo from '../discord/UserInfo' ;
import Discord_Stats from '../discord/Stats' ;
2022-06-29 19:59:53 +07:00
import Discord_Support from '../discord/Support' ;
2022-02-05 00:46:35 +07:00
2022-06-06 14:59:53 +07:00
import Discord_MusicPlayer_Play from '../discord/MusicPlayer/Play' ;
2022-07-05 14:54:08 +07:00
import Discord_MusicPlayer_PlayMy from '../discord/MusicPlayer/PlayMy' ;
2022-06-06 14:59:53 +07:00
import Discord_MusicPlayer_Skip from '../discord/MusicPlayer/Skip' ;
import Discord_MusicPlayer_Join from '../discord/MusicPlayer/Join' ;
import Discord_MusicPlayer_Leave from '../discord/MusicPlayer/Leave' ;
import Discord_MusicPlayer_Queue from '../discord/MusicPlayer/Queue' ;
import Discord_MusicPlayer_Search from '../discord/MusicPlayer/Search' ;
import Discord_MusicPlayer_NowPlaying from '../discord/MusicPlayer/NowPlaying' ;
import Discord_MusicPlayer_Loop from '../discord/MusicPlayer/Loop' ;
import Discord_MusicPlayer_Pause from '../discord/MusicPlayer/Pause' ;
import Discord_MusicPlayer_Resume from '../discord/MusicPlayer/Resume' ;
2022-01-30 20:10:17 +07:00
2022-06-07 14:11:52 +07:00
import Discord_Developer_ServiceAnnouncement from '../discord/Developer/ServiceAnnouncement' ;
import Discord_Developer_Debug from '../discord/Developer/Debug' ;
2021-09-19 08:40:09 -07:00
2022-06-06 14:59:53 +07:00
import Cache from './Cache' ;
import DiscordModule from '../utils/DiscordModule' ;
2021-09-14 09:56:11 -07:00
2023-04-23 18:54:32 +07:00
const LOGGING_TAG = '[DiscordProvider]' ;
2021-09-14 09:56:11 -07:00
class Discord {
public client : Client ;
2022-03-03 20:56:49 +07:00
private loaded_module = new Map < string , DiscordModule >();
2021-09-14 09:56:11 -07:00
2022-06-06 14:59:53 +07:00
constructor () {
this . client = new Client ({
intents : [
2022-06-29 15:27:42 +07:00
IntentsBitField . Flags . MessageContent ,
IntentsBitField . Flags . Guilds ,
IntentsBitField . Flags . GuildMessages ,
IntentsBitField . Flags . GuildMembers ,
IntentsBitField . Flags . GuildPresences ,
IntentsBitField . Flags . GuildVoiceStates
2022-06-06 14:59:53 +07:00
]
2021-09-14 09:56:11 -07:00
});
}
public init () : void {
Logger . info ( 'Logging in to discord' );
this . client . login ( Environment . get (). DISCORD_TOKEN );
2022-06-06 14:59:53 +07:00
2022-03-03 20:56:49 +07:00
const modules : DiscordModule [] = [
new Discord_Core (),
new Discord_Help (),
new Discord_Invite (),
new Discord_Ping (),
new Discord_Stats (),
new Discord_UserInfo (),
new Discord_Say (),
new Discord_InteractionManager (),
new Discord_osu (),
2023-04-23 13:13:20 +07:00
new Discord_VRChat (),
2023-04-23 17:51:25 +07:00
new Discord_VRChatLogin (),
2022-03-03 20:56:49 +07:00
new Discord_Settings (),
2022-06-29 19:59:53 +07:00
new Discord_Support (),
2021-09-15 04:10:50 -07:00
2022-03-03 20:56:49 +07:00
new Discord_MusicPlayer_Play (),
2022-07-05 14:54:08 +07:00
new Discord_MusicPlayer_PlayMy (),
2022-03-03 20:56:49 +07:00
new Discord_MusicPlayer_NowPlaying (),
new Discord_MusicPlayer_Skip (),
new Discord_MusicPlayer_Join (),
new Discord_MusicPlayer_Leave (),
new Discord_MusicPlayer_Queue (),
new Discord_MusicPlayer_Search (),
2022-03-03 23:57:30 +07:00
new Discord_MusicPlayer_Loop (),
2022-06-06 02:18:41 +07:00
new Discord_MusicPlayer_Pause (),
new Discord_MusicPlayer_Resume (),
2021-09-19 08:40:09 -07:00
2022-03-03 20:56:49 +07:00
new Discord_MembershipScreening (),
2022-01-30 20:10:17 +07:00
2022-03-03 20:56:49 +07:00
new Discord_Developer_ServiceAnnouncement (),
2022-03-03 22:18:34 +07:00
new Discord_Developer_Debug ()
2022-03-03 20:56:49 +07:00
];
2021-09-14 09:56:11 -07:00
2022-06-06 14:59:53 +07:00
for ( const _module of modules ) {
if ( _module . id ) {
if ( this . loaded_module . has ( _module . id ))
Logger . error (
2022-06-07 14:11:52 +07:00
`Module ${ _module . constructor . name } is trying to assign a conflicting module id ${
_module . id
} . ${ this . loaded_module . get ( _module . id ) ! . constructor . name } is already assigned to this id.`
2022-06-06 14:59:53 +07:00
);
2023-04-23 18:54:32 +07:00
else {
Logger . verbose ( LOGGING_TAG , `Loaded module ${ _module . constructor . name } ` );
this . loaded_module . set ( _module . id , _module );
}
2022-06-07 14:11:52 +07:00
} else Logger . error ( `Invalid module ${ _module . constructor . name } . The module does not have an id.` );
2022-03-03 20:56:49 +07:00
}
2022-01-27 17:59:59 +07:00
2022-03-03 20:56:49 +07:00
Logger . info ( `Loaded ${ this . loaded_module . size } Discord Modules` );
2022-06-06 14:59:53 +07:00
for ( const module of this . loaded_module ) {
2022-03-03 20:56:49 +07:00
let thisModule : DiscordModule = module [ 1 ];
2023-04-23 18:54:32 +07:00
Logger . verbose ( LOGGING_TAG , `Initializing module ${ thisModule . constructor . name } ` );
2022-03-03 20:56:49 +07:00
thisModule . Init ();
2021-09-14 09:56:11 -07:00
}
2021-09-18 05:19:53 -07:00
// On bot logged in
2022-06-06 14:59:53 +07:00
this . client . on ( 'ready' , () => {
for ( const module of this . loaded_module ) {
2022-03-03 20:56:49 +07:00
let thisModule : DiscordModule = module [ 1 ];
2023-04-23 18:54:32 +07:00
Logger . verbose ( LOGGING_TAG , `Triggering 'ready' event for module ${ thisModule . constructor . name } ` );
2022-03-03 20:56:49 +07:00
thisModule . Ready ();
2021-09-14 09:56:11 -07:00
}
});
2021-09-18 05:19:53 -07:00
// Member join guild event to modules
2022-06-06 14:59:53 +07:00
this . client . on ( 'guildMemberAdd' , ( member : GuildMember ) => {
for ( const module of this . loaded_module ) {
2022-03-03 20:56:49 +07:00
let thisModule : DiscordModule = module [ 1 ];
2023-04-23 18:54:32 +07:00
Logger . verbose (
LOGGING_TAG ,
`Triggering 'guildMemberAdd' event for module ${ thisModule . constructor . name } `
);
2022-03-03 20:56:49 +07:00
thisModule . GuildMemberAdd ( member );
2021-09-15 04:10:50 -07:00
}
});
2021-09-18 05:19:53 -07:00
// Interaction create event to modules
2022-06-06 20:11:07 +07:00
this . client . on ( 'interactionCreate' , async ( interaction : Interaction ) => {
2022-06-07 14:11:52 +07:00
if ( ! Cache . isUserCached ( interaction . user . id )) await Cache . updateUserCache ( interaction . user . id );
2022-06-06 20:11:07 +07:00
2022-06-06 14:59:53 +07:00
for ( const module of this . loaded_module ) {
2022-03-03 20:56:49 +07:00
let thisModule : DiscordModule = module [ 1 ];
2022-06-06 14:59:53 +07:00
if ( interaction . guild ) {
2022-03-03 20:56:49 +07:00
thisModule . GuildInteractionCreate ( interaction );
2023-03-05 14:46:25 +07:00
if (
interaction . type === InteractionType . ApplicationCommand &&
interaction . commandName &&
thisModule . commandInteractionName
) {
2022-03-03 20:56:49 +07:00
thisModule . GuildCommandInteractionCreate ( interaction );
2023-04-23 18:54:32 +07:00
if ( interaction . commandName . toLowerCase () === thisModule . commandInteractionName ) {
Logger . verbose (
LOGGING_TAG ,
`Triggering 'GuildModuleCommandInteractionCreate' event for module ${ thisModule . constructor . name } `
);
2022-03-03 20:56:49 +07:00
thisModule . GuildModuleCommandInteractionCreate ( interaction );
2023-04-23 18:54:32 +07:00
}
2022-06-06 14:59:53 +07:00
} else if ( interaction . isButton ()) {
2023-04-23 18:54:32 +07:00
Logger . verbose (
LOGGING_TAG ,
`Triggering 'GuildButtonInteractionCreate' event for module ${ thisModule . constructor . name } `
);
2022-03-03 20:56:49 +07:00
thisModule . GuildButtonInteractionCreate ( interaction );
2022-06-06 14:59:53 +07:00
} else if ( interaction . isSelectMenu ()) {
2023-04-23 18:54:32 +07:00
Logger . verbose (
LOGGING_TAG ,
`Triggering 'GuildSelectMenuInteractionCreate' event for module ${ thisModule . constructor . name } `
);
2022-03-03 20:56:49 +07:00
thisModule . GuildSelectMenuInteractionCreate ( interaction );
}
}
2022-06-06 14:59:53 +07:00
2022-03-03 20:56:49 +07:00
//thisModule.InteractionCreate(interaction);
2021-09-15 04:10:50 -07:00
}
});
2021-09-18 05:19:53 -07:00
// Message create event to modules
2022-06-06 14:59:53 +07:00
this . client . on ( 'messageCreate' , ( message : Message ) => {
for ( const module of this . loaded_module ) {
2022-03-03 20:56:49 +07:00
let thisModule : DiscordModule = module [ 1 ];
2023-04-23 18:54:32 +07:00
// This spamms too much logs
//Logger.verbose(
// LOGGING_TAG,
// `Triggering 'messageCreate' event for module ${thisModule.constructor.name}`
//);
2022-03-03 20:56:49 +07:00
thisModule . GuildMessageCreate ( message );
2021-09-14 09:56:11 -07:00
}
});
2021-09-18 05:19:53 -07:00
// Joined guild event to modules
2022-06-06 14:59:53 +07:00
this . client . on ( 'guildCreate' , ( guild : Guild ) => {
for ( const module of this . loaded_module ) {
2022-03-03 20:56:49 +07:00
let thisModule : DiscordModule = module [ 1 ];
2023-04-23 18:54:32 +07:00
Logger . verbose ( LOGGING_TAG , `Triggering 'guildCreate' event for module ${ thisModule . constructor . name } ` );
2022-03-03 20:56:49 +07:00
thisModule . GuildCreate ( guild );
2021-09-18 05:19:53 -07:00
}
});
2022-03-03 20:56:49 +07:00
// Handling guild commands
2022-06-06 14:59:53 +07:00
this . client . on ( 'messageCreate' , async ( message : Message ) => {
2023-03-05 14:46:25 +07:00
if ( ! ( message . channel instanceof BaseGuildTextChannel || message . channel instanceof BaseGuildVoiceChannel ))
return ;
2022-06-06 14:59:53 +07:00
if ( message . author . bot ) return ;
if ( typeof message . guild ? . id === 'undefined' ) return ;
2021-09-14 09:56:11 -07:00
2022-06-06 20:11:07 +07:00
let GuildCache = await Cache . getCachedGuild ( message . guild . id );
2022-06-07 14:11:52 +07:00
if ( typeof GuildCache === 'undefined' || typeof GuildCache . prefix === 'undefined' ) return ;
2021-09-14 09:56:11 -07:00
2022-06-06 14:59:53 +07:00
if ( ! message . content . startsWith ( GuildCache . prefix )) return ;
2021-09-14 09:56:11 -07:00
2021-09-19 01:33:45 -07:00
let noPrefixMessage = message . content . replace ( GuildCache . prefix , '' );
let symbols = [
2022-06-06 14:59:53 +07:00
'!' ,
'@' ,
'#' ,
'$' ,
'%' ,
'^' ,
'&' ,
'*' ,
'(' ,
')' ,
'-' ,
'=' ,
'_' ,
'+' ,
'\\' ,
'/' ,
'<' ,
'>' ,
'[' ,
']' ,
'{' ,
'}' ,
'`' ,
'"' ,
"'" ,
',' ,
'.' ,
'~' ,
'|' ,
';' ,
':' ,
'?' ,
'、' ,
'。'
2021-09-19 01:33:45 -07:00
];
2021-09-18 11:15:22 -07:00
2021-09-19 03:36:55 -07:00
const isTag = ( prefix : string ) => {
2022-06-06 14:59:53 +07:00
return (
( prefix . startsWith ( '<@!' ) && prefix . endsWith ( '>' )) ||
( prefix . startsWith ( '<:' ) && prefix . endsWith ( '>' )) ||
( prefix . startsWith ( '<a:' ) && prefix . endsWith ( '>' )) ||
( prefix . startsWith ( '<#' ) && prefix . endsWith ( '>' ))
);
};
2021-09-19 03:36:55 -07:00
2022-06-06 14:59:53 +07:00
if ( GuildCache . prefix . indexOf ( ' ' ) >= 0 ) {
if ( noPrefixMessage . charAt ( 0 ) !== ' ' ) return ;
} else {
if ( symbols . includes ( GuildCache . prefix . charAt ( GuildCache . prefix . length - 1 ))) {
if ( noPrefixMessage . charAt ( 0 ) === ' ' ) {
2021-09-19 03:36:55 -07:00
//Handle for "@Bot <command>"
2022-06-06 14:59:53 +07:00
if ( isTag ( GuildCache . prefix )) {
} else return ;
} else {
2021-09-19 03:36:55 -07:00
//Handle for "@Bot<command>"
2022-06-06 14:59:53 +07:00
if ( isTag ( GuildCache . prefix )) return ;
2021-09-19 03:36:55 -07:00
}
2022-06-06 14:59:53 +07:00
} else {
if ( noPrefixMessage . charAt ( 0 ) !== ' ' ) return ;
2021-09-19 01:33:45 -07:00
}
2021-09-18 11:15:22 -07:00
}
2022-06-06 14:59:53 +07:00
if ( noPrefixMessage === '' ) return ;
if ( noPrefixMessage . charAt ( 0 ) === ' ' ) {
2021-09-19 01:33:45 -07:00
noPrefixMessage = noPrefixMessage . substring ( 1 );
2021-09-18 11:15:22 -07:00
}
2022-06-06 14:59:53 +07:00
let args = noPrefixMessage . split ( ' ' );
args = args . filter (( e ) => e !== '' );
2021-09-14 09:56:11 -07:00
2021-09-19 01:33:45 -07:00
let command = args [ 0 ];
args . shift ();
2022-06-06 14:59:53 +07:00
if ( args . length === 0 ) args = [];
2021-09-14 09:56:11 -07:00
2022-06-07 14:11:52 +07:00
if ( ! Cache . isUserCached ( message . author . id )) await Cache . updateUserCache ( message . author . id );
2022-06-06 20:11:07 +07:00
2023-04-23 18:54:32 +07:00
Logger . verbose (
LOGGING_TAG ,
`Triggering 'GuildOnCommand (Message)' event to loaded modules for command ${ command } by ${ message . author . username } ( ${ message . author . id } ) in ${ message . guild . name } ( ${ message . guild . id } )`
);
2022-06-06 14:59:53 +07:00
for ( const module of this . loaded_module ) {
2022-03-03 20:56:49 +07:00
let thisModule : DiscordModule = module [ 1 ];
thisModule . GuildOnCommand ( command , args , message );
2022-06-06 14:59:53 +07:00
if ( thisModule . commands && thisModule . commands . includes ( command ))
2022-03-03 20:56:49 +07:00
thisModule . GuildOnModuleCommand ( args , message );
2021-09-14 09:56:11 -07:00
}
});
2021-09-18 03:51:14 -07:00
// Handling mentions
2022-06-06 14:59:53 +07:00
this . client . on ( 'messageCreate' , async ( message : Message ) => {
2021-09-18 03:51:14 -07:00
// TODO: Handle DMs commands soon
2023-03-05 14:46:25 +07:00
if ( ! ( message . channel instanceof BaseGuildTextChannel || message . channel instanceof BaseGuildVoiceChannel ))
return ;
2022-06-06 14:59:53 +07:00
if ( message . author . bot ) return ;
2021-09-18 03:51:14 -07:00
2022-06-06 14:59:53 +07:00
if ( typeof message . guild ? . id === 'undefined' ) return ;
if ( ! message . mentions . users ) return ;
2021-09-18 03:51:14 -07:00
2022-06-06 14:59:53 +07:00
if ( message . mentions . users . first () ? . id !== this . client . user ? . id ) return ;
2022-06-07 14:11:52 +07:00
if (
! message . content . startsWith ( `<@! ${ this . client . user ? . id } >` ) &&
! message . content . startsWith ( `<@ ${ this . client . user ? . id } >` )
)
return ;
2021-09-18 03:51:14 -07:00
2022-06-06 14:59:53 +07:00
let args = message . content . split ( ' ' );
2021-09-18 03:51:14 -07:00
let command = args [ 1 ];
args . shift ();
args . shift ();
2022-06-06 14:59:53 +07:00
args = args . filter (( e ) => e !== '' );
2021-09-18 03:51:14 -07:00
2022-06-06 14:59:53 +07:00
if ( args . length === 0 ) args = [];
2021-09-18 03:51:14 -07:00
2022-06-07 14:11:52 +07:00
if ( ! Cache . isUserCached ( message . author . id )) await Cache . updateUserCache ( message . author . id );
2022-06-06 20:11:07 +07:00
2022-06-06 14:59:53 +07:00
for ( const module of this . loaded_module ) {
2022-03-04 20:21:07 +07:00
let thisModule : DiscordModule = module [ 1 ];
2023-04-23 18:54:32 +07:00
Logger . verbose (
LOGGING_TAG ,
`Triggering 'GuildOnCommand (Mention)' event for module ${ thisModule . constructor . name } `
);
2022-03-03 20:56:49 +07:00
thisModule . GuildOnCommand ( command , args , message );
2022-06-06 14:59:53 +07:00
if ( thisModule . commands && thisModule . commands . includes ( command ))
2022-03-04 20:21:07 +07:00
thisModule . GuildOnModuleCommand ( args , message );
2021-09-18 03:51:14 -07:00
}
});
2021-09-14 09:56:11 -07:00
}
}
export default new Discord ();