2023-04-25 20:06:08 +00:00
// @ts-check
2023-04-30 12:57:30 +00:00
// Discord library internals type beat
2023-05-04 20:25:00 +00:00
const DiscordTypes = require ( "discord-api-types/v10" )
2023-03-05 16:05:35 +00:00
const passthrough = require ( "../passthrough" )
const { sync } = passthrough
const utils = {
/ * *
2023-04-25 20:06:08 +00:00
* @ param { import ( "./discord-client" ) } client
2023-03-05 16:05:35 +00:00
* @ param { import ( "cloudstorm" ) . IGatewayMessage } message
2023-09-03 13:38:30 +00:00
* @ param { string } listen "full" , "half" , "no" - whether to set up the event listeners for OOYE to operate
2023-03-05 16:05:35 +00:00
* /
2023-09-03 13:38:30 +00:00
async onPacket ( client , message , listen ) {
2023-05-09 03:29:46 +00:00
// requiring this later so that the client is already constructed by the time event-dispatcher is loaded
/** @type {typeof import("./event-dispatcher")} */
const eventDispatcher = sync . require ( "./event-dispatcher" )
2023-08-17 13:22:14 +00:00
// Client internals, keep track of the state we need
2023-03-05 16:05:35 +00:00
if ( message . t === "READY" ) {
if ( client . ready ) return
client . ready = true
client . user = message . d . user
client . application = message . d . application
console . log ( ` Discord logged in as ${ client . user . username } # ${ client . user . discriminator } ( ${ client . user . id } ) ` )
} else if ( message . t === "GUILD_CREATE" ) {
client . guilds . set ( message . d . id , message . d )
const arr = [ ]
client . guildChannelMap . set ( message . d . id , arr )
for ( const channel of message . d . channels || [ ] ) {
2023-05-04 20:25:00 +00:00
// @ts-ignore
channel . guild _id = message . d . id
2023-03-05 16:05:35 +00:00
arr . push ( channel . id )
client . channels . set ( channel . id , channel )
}
2023-08-19 06:39:23 +00:00
for ( const thread of message . d . threads || [ ] ) {
// @ts-ignore
thread . guild _id = message . d . id
arr . push ( thread . id )
client . channels . set ( thread . id , thread )
}
2023-09-03 13:38:30 +00:00
if ( listen === "full" ) {
eventDispatcher . checkMissedMessages ( client , message . d )
}
2023-03-05 16:05:35 +00:00
2023-09-03 13:36:35 +00:00
} else if ( message . t === "GUILD_UPDATE" ) {
const guild = client . guilds . get ( message . d . id )
if ( guild ) {
for ( const prop of Object . keys ( message . d ) ) {
if ( ! [ "channels" , "threads" ] . includes ( prop ) ) {
guild [ prop ] = message . d [ prop ]
}
}
}
2023-03-05 16:05:35 +00:00
2023-09-18 13:45:40 +00:00
} else if ( message . t === "GUILD_EMOJIS_UPDATE" ) {
const guild = client . guilds . get ( message . d . guild _id )
if ( guild ) {
guild . emojis = message . d . emojis
}
} else if ( message . t === "GUILD_STICKERS_UPDATE" ) {
const guild = client . guilds . get ( message . d . guild _id )
if ( guild ) {
guild . stickers = message . d . stickers
}
2023-09-22 05:47:36 +00:00
} else if ( message . t === "GUILD_ROLE_CREATE" || message . t === "GUILD_ROLE_UPDATE" || message . t === "GUILD_ROLE_DELETE" ) {
const guild = client . guilds . get ( message . d . guild _id )
/** Delete this in case of UPDATE or DELETE */
const targetID = "role_id" in message . d ? message . d . role _id : message . d . role . id
/** Add this in case of CREATE or UPDATE */
const newRoles = [ ]
if ( "role" in message . d ) newRoles . push ( message . d . role )
if ( guild ) {
const targetIndex = guild . roles . findIndex ( r => r . id === targetID )
if ( targetIndex !== - 1 ) {
// Role already exists. Delete it and maybe replace it.
guild . roles . splice ( targetIndex , 1 , ... newRoles )
} else {
// Role doesn't already exist.
guild . roles . push ( ... newRoles )
}
}
2023-08-20 20:07:05 +00:00
} else if ( message . t === "THREAD_CREATE" ) {
client . channels . set ( message . d . id , message . d )
2023-08-19 11:12:36 +00:00
} else if ( message . t === "CHANNEL_UPDATE" || message . t === "THREAD_UPDATE" ) {
client . channels . set ( message . d . id , message . d )
2023-03-05 16:05:35 +00:00
} else if ( message . t === "GUILD_DELETE" ) {
client . guilds . delete ( message . d . id )
const channels = client . guildChannelMap . get ( message . d . id )
if ( channels ) {
for ( const id of channels ) client . channels . delete ( id )
}
client . guildChannelMap . delete ( message . d . id )
} else if ( message . t === "CHANNEL_CREATE" || message . t === "CHANNEL_DELETE" ) {
if ( message . t === "CHANNEL_CREATE" ) {
client . channels . set ( message . d . id , message . d )
if ( message . d [ "guild_id" ] ) { // obj[prop] notation can be used to access a property without typescript complaining that it doesn't exist on all values something can have
const channels = client . guildChannelMap . get ( message . d [ "guild_id" ] )
if ( channels && ! channels . includes ( message . d . id ) ) channels . push ( message . d . id )
}
} else {
client . channels . delete ( message . d . id )
if ( message . d [ "guild_id" ] ) {
const channels = client . guildChannelMap . get ( message . d [ "guild_id" ] )
if ( channels ) {
const previous = channels . indexOf ( message . d . id )
if ( previous !== - 1 ) channels . splice ( previous , 1 )
}
}
}
2023-08-17 13:22:14 +00:00
}
2023-03-05 16:05:35 +00:00
2023-08-17 13:22:14 +00:00
// Event dispatcher for OOYE bridge operations
2023-09-03 13:38:30 +00:00
if ( listen === "full" ) {
try {
if ( message . t === "GUILD_UPDATE" ) {
await eventDispatcher . onGuildUpdate ( client , message . d )
2023-08-23 00:37:25 +00:00
2023-09-18 13:45:40 +00:00
} else if ( message . t === "GUILD_EMOJIS_UPDATE" || message . t === "GUILD_STICKERS_UPDATE" ) {
await eventDispatcher . onExpressionsUpdate ( client , message . d )
2023-09-03 13:38:30 +00:00
} else if ( message . t === "CHANNEL_UPDATE" ) {
await eventDispatcher . onChannelOrThreadUpdate ( client , message . d , false )
2023-08-19 11:12:36 +00:00
2023-09-03 13:38:30 +00:00
} else if ( message . t === "THREAD_CREATE" ) {
// @ts-ignore
await eventDispatcher . onThreadCreate ( client , message . d )
2023-08-20 20:07:05 +00:00
2023-09-03 13:38:30 +00:00
} else if ( message . t === "THREAD_UPDATE" ) {
await eventDispatcher . onChannelOrThreadUpdate ( client , message . d , true )
2023-08-19 11:12:36 +00:00
2023-09-03 13:38:30 +00:00
} else if ( message . t === "MESSAGE_CREATE" ) {
await eventDispatcher . onMessageCreate ( client , message . d )
2023-03-05 16:05:35 +00:00
2023-09-03 13:38:30 +00:00
} else if ( message . t === "MESSAGE_UPDATE" ) {
await eventDispatcher . onMessageUpdate ( client , message . d )
2023-04-25 20:06:08 +00:00
2023-09-03 13:38:30 +00:00
} else if ( message . t === "MESSAGE_DELETE" ) {
await eventDispatcher . onMessageDelete ( client , message . d )
2023-04-25 20:06:08 +00:00
2023-09-17 11:07:33 +00:00
} else if ( message . t === "TYPING_START" ) {
await eventDispatcher . onTypingStart ( client , message . d )
2023-09-03 13:38:30 +00:00
} else if ( message . t === "MESSAGE_REACTION_ADD" ) {
await eventDispatcher . onReactionAdd ( client , message . d )
2023-09-25 09:20:23 +00:00
} else if ( message . t === "MESSAGE_REACTION_REMOVE" ) {
await eventDispatcher . onReactionRemove ( client , message . d )
2023-09-25 10:15:36 +00:00
} else if ( message . t === "MESSAGE_REACTION_REMOVE_EMOJI" ) {
await eventDispatcher . onReactionEmojiRemove ( client , message . d )
} else if ( message . t === "MESSAGE_REACTION_REMOVE_ALL" ) {
await eventDispatcher . onRemoveAllReactions ( client , message . d )
2023-09-03 13:38:30 +00:00
}
} catch ( e ) {
// Let OOYE try to handle errors too
eventDispatcher . onError ( client , e , message )
2023-08-17 13:22:14 +00:00
}
2023-04-25 20:06:08 +00:00
}
2023-03-05 16:05:35 +00:00
}
}
module . exports = utils