2019-06-08 21:14:57 +02:00
package moe.kageru.kagebot
2019-06-15 12:27:20 +02:00
import moe.kageru.kagebot.Log.log
2019-07-13 15:39:50 +02:00
import moe.kageru.kagebot.config.Config
import moe.kageru.kagebot.config.Config.server
2019-06-12 23:43:36 +02:00
import org.javacord.api.entity.channel.TextChannel
2019-06-10 09:19:03 +02:00
import org.javacord.api.entity.message.MessageAuthor
2019-06-15 12:27:20 +02:00
import org.javacord.api.entity.message.embed.EmbedBuilder
2019-06-12 23:43:36 +02:00
import org.javacord.api.entity.permission.Role
2019-07-11 22:16:02 +02:00
import org.javacord.api.entity.user.User
import org.javacord.api.event.message.MessageCreateEvent
2019-06-15 12:27:20 +02:00
import java.awt.Color
2019-07-13 15:39:50 +02:00
import java.util.*
2019-06-13 00:19:02 +02:00
import java.util.concurrent.CompletableFuture
import java.util.concurrent.CompletionException
2019-06-08 23:50:05 +02:00
2019-06-08 21:14:57 +02:00
object Util {
inline fun < T > T . doIf ( condition : ( T ) -> Boolean , op : ( T ) -> T ) : T {
return if ( condition ( this ) ) op ( this ) else this
}
2019-06-08 23:50:05 +02:00
2019-06-12 23:43:36 +02:00
/ * *
* Mimics the behavior of [ Optional . ifPresent ] , but returns null if the optional is empty ,
* allowing easier fallback behavior via Kotlin ’ s ?: operator .
* /
2019-07-13 14:52:05 +02:00
private inline fun < T , R > Optional < T > . ifNotEmpty ( op : ( T ) -> R ) : R ? {
2019-06-09 18:41:51 +02:00
if ( this . isPresent ) {
return op ( this . get ( ) )
}
return null
}
2019-06-10 09:19:03 +02:00
2019-06-12 23:43:36 +02:00
fun hasOneOf ( messageAuthor : MessageAuthor , roles : Set < Role > ) : Boolean {
2019-06-10 09:19:03 +02:00
return messageAuthor . asUser ( ) . ifNotEmpty { user ->
2019-06-14 23:16:31 +02:00
user . getRoles ( server ) . toSet ( ) . intersect ( roles ) . isNotEmpty ( )
2019-06-10 09:19:03 +02:00
} ?: false
}
2019-06-12 23:43:36 +02:00
private val channelIdRegex = Regex ( " \\ d{18} " )
2019-06-15 11:47:11 +02:00
private fun String . isEntityId ( ) = channelIdRegex . matches ( this )
2019-06-12 23:43:36 +02:00
@Throws ( IllegalArgumentException :: class )
fun findRole ( idOrName : String ) : Role {
return when {
idOrName . isEntityId ( ) -> server . getRoleById ( idOrName ) . ifNotEmpty { it }
?: throw IllegalArgumentException ( " Role $idOrName not found. " )
else -> server . getRolesByNameIgnoreCase ( idOrName ) . let {
when ( it . size ) {
0 -> throw IllegalArgumentException ( " Role $idOrName not found. " )
1 -> it [ 0 ]
else -> throw IllegalArgumentException ( " More than one role found with name $idOrName . Please specify the role ID instead " )
}
}
}
}
2019-06-13 00:19:02 +02:00
fun < T > wasSuccessful ( future : CompletableFuture < T > ) : Boolean {
try {
future . join ( )
} catch ( e : CompletionException ) {
// we don’t care about this error, but I don’t want to spam stdout
}
return ! future . isCompletedExceptionally
}
2019-06-12 23:43:36 +02:00
@Throws ( IllegalArgumentException :: class )
fun findChannel ( idOrName : String ) : TextChannel {
return when {
idOrName . isEntityId ( ) -> server . getTextChannelById ( idOrName ) . ifNotEmpty { it }
?: throw IllegalArgumentException ( " Channel ID $idOrName not found. " )
else -> if ( idOrName . startsWith ( '@' ) ) {
2019-07-13 15:39:50 +02:00
Globals . api . getCachedUserByDiscriminatedName ( idOrName . removePrefix ( " @ " ) ) . ifNotEmpty { user ->
2019-07-11 23:30:39 +02:00
val channelFuture = user . openPrivateChannel ( )
val channel = channelFuture . join ( )
if ( channelFuture . isCompletedExceptionally ) {
throw IllegalArgumentException ( " Could not open private channel with user $idOrName for redirection. " )
}
channel
2019-06-12 23:43:36 +02:00
}
?: throw IllegalArgumentException ( " Can’t find user $idOrName for redirection. " )
} else {
server . getTextChannelsByName ( idOrName ) . let {
when ( it . size ) {
0 -> throw IllegalArgumentException ( " Channel $idOrName not found. " )
1 -> it [ 0 ]
else -> throw IllegalArgumentException ( " More than one channel found with name $idOrName . Please specify the channel ID instead " )
}
}
}
}
}
2019-06-15 12:27:20 +02:00
inline fun checked ( op : ( ( ) -> Unit ) ) {
try {
op ( )
} catch ( e : Exception ) {
log . warning ( " An uncaught exception occurred. \n $e " )
Globals . api . owner . get ( ) . sendMessage (
EmbedBuilder ( )
. setTimestampToNow ( )
. setColor ( Color . RED )
. addField ( " Error " , " kagebot has encountered an error " )
. addField (
" $e " , """ ```
$ { e . stackTrace . joinToString ( " \n " ) }
` ` ` """ .trimIndent()
)
)
}
}
2019-07-11 22:16:02 +02:00
fun userFromMessage ( message : MessageCreateEvent ) : User ? {
return message . messageAuthor . id . let { id ->
2019-07-13 15:39:50 +02:00
Config . server . getMemberById ( id ) . orElse ( null )
2019-07-11 22:16:02 +02:00
}
}
2019-07-13 14:52:05 +02:00
}