2023-02-26 14:46:18 -06:00
import hxdiscord . DiscordClient ;
import hxdiscord . types . * ;
import hxdiscord . endpoints . Endpoints ;
2024-11-09 14:22:29 -06:00
import htmlparser . HtmlDocument ;
2024-10-18 23:49:35 -05:00
import haxe . Timer ;
2023-02-26 14:46:18 -06:00
import haxe . Json ;
import sys . io . File ;
import sys . FileSystem ;
2025-04-01 23:01:39 -05:00
import BigInt ;
2024-10-16 18:55:09 -05:00
import izzcomlib . IzzComLib . * ;
2023-02-26 17:53:53 -06:00
using StringTools ;
2023-02-26 14:46:18 -06:00
class Onequestionmark {
2024-11-10 22:19:47 -06:00
// Initialize vars
2023-03-02 12:57:23 -06:00
static var Bot: DiscordClient ;
2023-02-26 14:46:18 -06:00
static var settings: Dynamic ;
2023-02-26 19:00:02 -06:00
static var botInfo: Dynamic ;
static var iceRegex: EReg = ~/\bicc?ed?\b/i ;
2023-09-03 00:00:11 -05:00
2023-03-02 12:09:41 -06:00
static var hugDB: Array < String > ;
2023-04-17 21:55:46 -05:00
static var motdDB: haxe . DynamicAccess < Dynamic > = { } ;
2023-03-02 22:14:13 -06:00
static var yesnoDB: Dynamic ;
2023-09-03 00:00:11 -05:00
static var echoboxDB: haxe . DynamicAccess < Dynamic > = { } ;
2023-02-26 14:46:18 -06:00
2024-10-18 23:49:35 -05:00
static var motdTimer: Timer ;
static var saveTimer: Timer ;
2023-09-02 18:54:33 -05:00
static var saveQueue: Array < String > = [ ] ;
2024-10-29 18:47:25 -05:00
static var timerInit: Bool = false ;
2023-09-02 18:54:33 -05:00
2024-11-10 22:19:47 -06:00
static function main ( ) {
2023-02-26 14:46:18 -06:00
2023-02-26 17:53:53 -06:00
Sys . println ( ' [ ${ timestamp ( ) } ] S t a r t i n g o n e q u e s t i o n m a r k - c h a t ' ) ;
2023-02-26 14:46:18 -06:00
2023-03-02 12:57:23 -06:00
// Load files
2023-02-26 14:46:18 -06:00
if ( FileSystem . exists ( " s e t t i n g s . j s o n " ) ) {
2023-02-26 17:53:53 -06:00
Sys . println ( ' [ ${ timestamp ( ) } ] F o u n d s e t t i n g s . j s o n , l o a d i n g ' ) ;
2023-02-26 14:46:18 -06:00
settings = Json . parse ( File . getContent ( " s e t t i n g s . j s o n " ) ) ;
} e lse {
2023-02-26 17:53:53 -06:00
Sys . println ( ' [ ${ timestamp ( ) } ] D i d n o t f i n d s e t t i n g s . j s o n , e x i t i n g ' ) ;
2023-02-26 14:46:18 -06:00
Sys . exit ( 0 ) ;
}
2023-03-02 12:09:41 -06:00
if ( FileSystem . exists ( " h u g - d b . j s o n " ) ) {
Sys . println ( ' [ ${ timestamp ( ) } ] F o u n d h u g - d b . j s o n , l o a d i n g ' ) ;
hugDB = Json . parse ( File . getContent ( " h u g - d b . j s o n " ) ) ;
} e lse {
Sys . println ( ' [ ${ timestamp ( ) } ] D i d n o t f i n d h u g - d b . j s o n , s k i p p i n g ' ) ;
2024-10-16 16:18:03 -05:00
hugDB = [ ] ; // Fallback
2023-03-02 12:09:41 -06:00
}
2023-03-02 12:57:23 -06:00
if ( FileSystem . exists ( " m o t d - d b . j s o n " ) ) {
Sys . println ( ' [ ${ timestamp ( ) } ] F o u n d m o t d - d b . j s o n , l o a d i n g ' ) ;
motdDB = Json . parse ( File . getContent ( " m o t d - d b . j s o n " ) ) ;
} e lse {
Sys . println ( ' [ ${ timestamp ( ) } ] D i d n o t f i n d m o t d - d b . j s o n , s k i p p i n g ' ) ;
2024-10-16 16:18:03 -05:00
motdDB = Json . parse ( ' { } ' ) ; // Fallback
2023-03-02 12:57:23 -06:00
}
2023-03-02 22:14:13 -06:00
if ( FileSystem . exists ( " y e s n o - d b . j s o n " ) ) {
Sys . println ( ' [ ${ timestamp ( ) } ] F o u n d y e s n o - d b . j s o n , l o a d i n g ' ) ;
yesnoDB = Json . parse ( File . getContent ( " y e s n o - d b . j s o n " ) ) ;
} e lse {
Sys . println ( ' [ ${ timestamp ( ) } ] D i d n o t f i n d y e s n o - d b . j s o n , s k i p p i n g ' ) ;
yesnoDB = { " y e s " : [ ] , " n o " : [ ] } ; // Fallback
}
2023-09-03 00:00:11 -05:00
if ( FileSystem . exists ( " e c h o b o x - d b . j s o n " ) ) {
Sys . println ( ' [ ${ timestamp ( ) } ] F o u n d e c h o b o x - d b . j s o n , l o a d i n g ' ) ;
2023-09-03 00:14:46 -05:00
echoboxDB = Json . parse ( File . getContent ( " e c h o b o x - d b . j s o n " ) ) ;
2023-09-03 00:00:11 -05:00
} e lse {
Sys . println ( ' [ ${ timestamp ( ) } ] D i d n o t f i n d e c h o b o x - d b . j s o n , g e n e r a t i n g ' ) ;
File . saveContent ( " e c h o b o x - d b . j s o n " , Json . stringify ( echoboxDB , " \t " ) ) ;
}
2024-11-10 13:14:17 -06:00
if ( ! FileSystem . exists ( " e x p o r t " ) ) {
FileSystem . createDirectory ( " e x p o r t " ) ;
}
2024-10-29 18:47:25 -05:00
saveSystem ( ) ;
2023-09-03 00:00:11 -05:00
2023-02-26 14:46:18 -06:00
// Start the bot
2024-11-10 22:19:47 -06:00
Bot = new DiscordClient ( settings . token , [ 3276799 ] , settings . debug ) ;
Bot . onReady = onReady ;
Bot . onMessageCreate = onMessageCreate ;
2023-09-02 17:04:48 -05:00
Bot . connect ( ) ;
2024-11-10 22:19:47 -06:00
}
2023-02-26 14:46:18 -06:00
2024-10-18 15:05:47 -05:00
/ * *
2024-10-27 11:23:12 -05:00
* The ` onReady ( ) ` function is r u n u p o n a s u c c e s s f u l ` B o t . c o n n e c t ( ) `
* /
2024-11-10 22:19:47 -06:00
public static function onReady ( ) {
2023-09-03 00:14:46 -05:00
Sys . sleep ( 1 ) ;
2023-02-26 17:53:53 -06:00
Sys . println ( ' [ ${ timestamp ( ) } ] B o t i s o n l i n e ' ) ;
2023-09-04 22:04:07 -05:00
// Join message from program args
if ( Sys . args ( ) . length > 0 ) {
Endpoints . sendMessage ( settings . devchannel , { content : Sys . args ( ) . join ( " " ) } , null , false ) ;
}
2023-09-02 17:04:48 -05:00
botInfo = Endpoints . getCurrentUser ( ) ;
2023-09-02 18:54:33 -05:00
2024-10-29 18:47:25 -05:00
if ( timerInit == false ) {
timerInit = true ;
startMotd ( ) ;
}
2024-11-10 22:19:47 -06:00
}
2023-02-26 14:46:18 -06:00
2024-10-18 15:05:47 -05:00
/ * *
2024-10-27 11:23:12 -05:00
* The ` onMessageCreate ( ) ` event provides the bulk of onequestionmark ' s f u n c t i o n a l i t y .
* This is what triggers when a new Discord m e s s a g e i s r e c e i v e d , a n d c o n t a i n s t h e b o t ' s c o m m a n d p r o c e s s o r .
* /
2024-11-10 22:19:47 -06:00
public static function onMessageCreate ( m : Message ) {
2023-02-26 16:11:00 -06:00
// DevMode check
2024-11-10 22:19:47 -06:00
if ( ( ! settings . devmode ) || ( m . guild_id == settings . devserver ) ) {
2023-02-26 16:11:00 -06:00
var msg = m . content ;
2023-09-04 18:44:46 -05:00
var sender: String ;
if ( m . getMember ( ) . nick == null ) { sender = m . author . global_name ; } else { sender = m . getMember ( ) . nick ; }
2023-02-26 16:11:00 -06:00
// Command processor
if ( msg . charAt ( 0 ) == " ? " ) {
var command = " " ;
2023-09-04 18:44:46 -05:00
var args: Array < String > = [ ] ;
2023-02-26 16:11:00 -06:00
if ( msg . indexOf ( " " ) != - 1 ) {
// Separate command from rest of message, if necessary
command = msg . substring ( 1 , msg . indexOf ( " " ) ) . toLowerCase ( ) ;
msg = msg . substring ( msg . indexOf ( " " ) + 1 ) ;
} e lse {
// Otherwise, remove msg
command = msg . substring ( 1 ) . toLowerCase ( ) ;
msg = " " ;
}
2023-09-04 18:44:46 -05:00
// Separate arguments from command
if ( command . indexOf ( " . " ) != - 1 ) {
args = command . substring ( command . indexOf ( " . " ) + 1 ) . toLowerCase ( ) . split ( " . " ) ;
command = command . substring ( 0 , command . indexOf ( " . " ) ) . toLowerCase ( ) ;
}
2023-02-26 16:11:00 -06:00
switch ( command ) {
// Commands that require authorization
c ase " q u i t " :
if ( m . author . id == settings . botowner ) {
2023-09-02 13:53:28 -05:00
m . react ( ' ✅ ' ) ;
2023-02-26 17:53:53 -06:00
Sys . println ( ' [ ${ timestamp ( ) } ] S h u t d o w n c o m m a n d r e c e i v e d f r o m b o t o w n e r , e x i t i n g ' ) ;
2023-02-26 17:41:40 -06:00
shutdown ( ) ;
2023-02-26 16:11:00 -06:00
}
2023-02-26 17:43:36 -06:00
c ase " d e v m o d e " :
if ( m . author . id == settings . botowner ) {
if ( ! settings . devmode ) {
settings . devmode = true ;
m . reply ( { content : " D e v M o d e e n a b l e d . " } , false ) ;
} e lse {
settings . devmode = false ;
m . reply ( { content : " D e v M o d e d i s a b l e d . " } , false ) ;
}
}
c ase " m o t d " :
if ( m . author . id == settings . botowner ) {
2024-10-27 16:05:44 -05:00
if ( args . length != 0 ) {
if ( args [ 0 ] == " f o r c e " ) {
m . reply ( { content : ' ${ getMotd ( true ) } ' } , false ) ;
}
2023-02-26 17:43:36 -06:00
} e lse {
2024-10-27 16:05:44 -05:00
if ( ! settings . motd . channels . contains ( m . channel_id ) ) {
settings . motd . channels . push ( m . channel_id ) ;
m . reply ( { content : ' M O T D h a s b e e n e n a b l e d f o r < # ${ m . channel_id } > ' } , false ) ;
} e lse {
settings . motd . channels . remove ( m . channel_id ) ;
m . reply ( { content : ' M O T D h a s b e e n d i s a b l e d f o r < # ${ m . channel_id } > ' } , false ) ;
}
saveQueue . push ( " s e t t i n g s " ) ;
2023-02-26 17:43:36 -06:00
}
}
2025-02-15 13:55:05 -06:00
c ase " t r a c e " :
if ( m . author . id == settings . botowner ) {
if ( m . referenced_message == null ) {
Sys . println ( ' [ ${ timestamp ( ) } ] t r a c e : ${ Json . stringify ( getMessage ( m . channel_id , m . id ) ) } ' ) ;
} e lse {
Sys . println ( ' [ ${ timestamp ( ) } ] t r a c e : ${ Json . stringify ( getMessage ( m . referenced_message . channel_id , m . referenced_message . id ) ) } ' ) ;
}
m . react ( ' ✅ ' ) ;
}
2023-02-26 16:11:00 -06:00
// System for WIP commands that only work in testing server
c ase " w i p c o m m a n d " :
if ( m . guild_id == settings . devserver ) {
m . reply ( { content : " D e v S e r v e r r e s p o n s e . " } , true ) ;
}
// Basic response commands
2023-03-01 14:26:52 -06:00
c ase " h e l p " :
2023-09-04 19:01:14 -05:00
m . reply ( { embeds : [
{
" c o l o r " : 13733022 ,
" u r l " : " h t t p s : / / d i s c o r d . c o m " ,
" a u t h o r " : {
" n a m e " : " o n e q u e s t i o n m a r k h e l p " ,
" u r l " : " h t t p s : / / d i s c o r d . c o m " ,
" i c o n _ u r l " : " h t t p s : / / c d n . d i s c o r d a p p . c o m / a v a t a r s / 1 0 7 1 5 2 4 9 9 1 0 8 4 0 1 5 7 5 6 / d 6 2 3 b 4 5 d 3 3 e 8 1 1 9 5 9 9 b 2 9 c 5 c f 5 e d 5 3 2 e . p n g "
} ,
" t h u m b n a i l " : {
" u r l " : " h t t p s : / / c d n . d i s c o r d a p p . c o m / e m o j i s / 1 0 7 1 5 6 0 2 4 3 0 5 1 5 1 1 8 0 8 . p n g "
} ,
" f i e l d s " : [
{
" n a m e " : " * * B o t c o m m a n d s : * * " ,
2025-02-15 13:55:05 -06:00
" v a l u e " : " ` ? h e l p ` : P o s t s t h i s h e l p d o c u m e n t . : b o o k : \n ` ? c h k ` : R e p l i e s w i t h \" a c k \" . : s p e a k i n g _ h e a d : \n ` ? s l a p < t a r g e t > ` : T h e c l a s s i c m I R C t r o u t s l a p . : f i s h : \n ` ? h u g < t a r g e t ( o p t i o n a l ) > ` : P o s t s r a n d o m i z e d h u g i m a g e . : p e o p l e _ h u g g i n g : \n ` ? y e s ` : P o s t s r a n d o m i z e d \" y e s \" i m a g e o r v i d e o . : t h u m b s u p : \n ` ? n o ` : P o s t s r a n d o m i z e d \" n o \" i m a g e o r v i d e o . : n o _ e n t r y _ s i g n : \n ` ? m r k r a b s ` : S i m i l a r t o ` ? c h k ` . : c r a b : \n ` ? t u f a c ` : T h e o f f i c i a l T u f a c T h e m e S o n g . : b u s t s _ i n _ s i l h o u e t t e : \n ` ? c o i n < c o u n t ( o p t i o n a l ) > ` : F l i p s b e t w e e n 1 a n d 1 0 0 c o i n s . : c o i n : \n ` ? d i c e . < a r g > < n u m > ` : R o l l s < a r g > - s i d e d d i e < n u m > t i m e s : g a m e _ d i e : \n ` ? 8 b a l l ` : A n s w e r s y o u r y e s o r n o q u e s t i o n s . : 8 b a l l : \n ` ? e c h o b o x ` : P o s t s r a n d o m i z e d q u o t e f r o m t h e q u o t e d a t a b a s e . : l o u d s p e a k e r : \n ` ? e c h o b o x < q u o t e > ` : A d d s p r o v i d e d q u o t e t o t h e d a t a b a s e . : w r i t i n g _ h a n d : \n ` ? y o u t u b e < q u e r y > ` : R e t u r n f i r s t r e s u l t o f a Y o u T u b e s e a r c h . : c i n e m a : " ,
" i n l i n e " : false
} ,
{
" n a m e " : " * * P i r a t e v s . N i n j a : * * " ,
" v a l u e " : " ` ? p i r a t e < n a m e > ` : L o o k u p s t a t s f o r a p i r a t e . : p i r a t e _ f l a g : \n ` ? n i n j a < n a m e > ` : L o o k u p s t a t s f o r a n i n j a . : n i n j a : \n ` ? p v n < p i r a t e > | < n i n j a > ` : L e t t h e m f i g h t ! : c r o s s e d _ s w o r d s : \n ` ? n v p < n i n j a > | < p i r a t e > ` : S a m e a s a b o v e b u t r e v e r s e d o r d e r . " ,
2023-09-04 19:01:14 -05:00
" i n l i n e " : false
} ,
{
" n a m e " : " * * B a s i c R e s p o n s e A l i a s e s : * * " ,
2025-02-15 13:55:05 -06:00
" v a l u e " : " ` ? a n g e r y ` : * I t a s t e a v e g e t a l . * : r a g e : \n ` ? s u b w a y ` : A r i n ' s i n f a m o u s S u b w a y r a n t . : s a n d w i c h : \n ` ? i l l u m i n a t i ` : A l w a y s w a t c h i n g . : e y e : \n ` ? c u b e ` : * T h e C u b e * \n ` ? c o o l s v i l l e ` : P o p u l a t i o n : U s : s u n g l a s s e s : \n ` ? c o m m u n i s m ` : T h e o l d 3 D r o t a t i n g g i f . \n ` ? o p i n i o n s ` : H e r e t h e y c o m e . : s c r e a m : \n ` ? f i n e a r t ` : T h e g r e a t m a s t e r p i e c e . : a r t : \n ` ? a r t i s h a r d ` : A r t * i s * h a r d . : c o r n : \n ` ? f l o r i d a ` : : c a r p e n t r y _ s a w : : r a b b i t : \n ` ? s t o p ` : : s t o p _ s i g n : : s m i l e y : \n ` ? i n d e e d ` " ,
2023-09-04 19:01:14 -05:00
" i n l i n e " : false
} ,
{
" n a m e " : " * * A u t h - R e q u i r i n g C o m m a n d s : * * " ,
2025-02-15 13:55:05 -06:00
" v a l u e " : " ` ? m o t d ` : E n a b l e s M O T D f o r c u r r e n t c h a n n e l . \n ` ? d e v m o d e ` : T o g g l e s D e v M o d e . \n ` ? t r a c e ` : D e b u g g i n g t o o l . \n ` ? q u i t ` : S h u t d o w n c o m m a n d . " ,
2023-09-04 19:01:14 -05:00
" i n l i n e " : true
} ,
{
" n a m e " : " * * N o n - c o m m a n d b o t f u n c t i o n s : * * " ,
" v a l u e " : " * * M O T D * * : * M e m e o f t h e D a y * i s p o s t e d i n e n a b l e d c h a n n e l s . \n * * I c c e * * : B o t p r o v i d e s u s e r s w i t h i c e c u b o i d s . : i c e _ c u b e : " ,
" i n l i n e " : true
}
]
}
] } ) ;
2023-02-26 16:11:00 -06:00
c ase " c h k " :
m . reply ( { content : ' < @ ${ m . author . id } > : a c k ' } , false ) ;
2023-09-02 13:53:28 -05:00
c ase " m r k r a b s " :
m . reply ( { content : ' < @ ${ m . author . id } > : a c k a c k a c k a c k a c k ' } , false ) ;
2023-02-26 16:11:00 -06:00
c ase " s l a p " :
if ( msg . length != 0 ) { m . reply ( { content : ' * o n e q u e s t i o n m a r k s l a p s ${ msg } a r o u n d a b i t w i t h a l a r g e t r o u t * ' } , false ) ; }
2023-09-04 18:44:46 -05:00
c ase " t u f a c " :
m . reply ( { content : " * N o t T e h F a c e , b u t b e t t e r , * \n * T u f a c t o t h e l e t t e r ! * \n * A l w a y s t w o f a c e s , n e v e r o n e , * \n * T u f a c h a s y o u o n t h e r u n ! * " } , false ) ;
2024-11-09 14:22:29 -06:00
c ase " y o u t u b e " :
if ( msg . length > 0 ) { ytlookup ( m , msg ) ; }
2024-11-10 13:14:17 -06:00
c ase " y t d e b u g " :
if ( FileSystem . exists ( " e x p o r t / y t l o o k u p _ r e s u l t . t x t " ) ) {
var debugRename = ' e x p o r t / ${ datestamp ( ) } _ ${ StringTools . lpad ( Std . string ( Date . now ( ) . getHours ( ) ) , " 0 " , 2 ) } - ${ StringTools . lpad ( Std . string ( Date . now ( ) . getMinutes ( ) ) , " 0 " , 2 ) } - ${ StringTools . lpad ( Std . string ( Date . now ( ) . getSeconds ( ) ) , " 0 " , 2 ) } _ y t d e b u g . t x t ' ;
FileSystem . rename ( " e x p o r t / y t l o o k u p _ r e s u l t . t x t " , debugRename ) ;
Sys . println ( ' [ ${ timestamp ( ) } ] y t d e b u g : C r e a t e d d e b u g f i l e ${ debugRename } ' ) ;
m . react ( ' ✅ ' ) ;
} e lse {
Sys . println ( ' [ ${ timestamp ( ) } ] y t d e b u g : N o r e s u l t t o d e b u g ' ) ;
m . reply ( { content : " y t d e b u g : N o r e s u l t t o d e b u g " } , false ) ;
}
2024-11-14 19:07:33 -06:00
c ase " p i r a t e " :
if ( msg . length > 0 ) { pvn ( " p " , msg , m ) ; }
c ase " n i n j a " :
if ( msg . length > 0 ) { pvn ( " n " , msg , m ) ; }
c ase " p v n " :
if ( msg . length > 0 ) { pvn ( " p v n " , msg , m ) ; }
c ase " n v p " :
if ( msg . length > 0 ) { pvn ( " n v p " , msg , m ) ; }
2023-09-04 18:44:46 -05:00
// Gaming functions
c ase " c o i n " :
if ( ( msg . length == 0 ) || ( Std . parseInt ( msg ) == null ) || ( Std . parseInt ( msg ) == 1 ) ) {
var coin = randInt ( 0 , 1 ) ;
if ( coin == 1 ) {
m . reply ( { content : ' ${ sender } f l i p p e d a c o i n a n d g o t h e a d s . ' } , false ) ;
} e lse {
m . reply ( { content : ' ${ sender } f l i p p e d a c o i n a n d g o t t a i l s . ' } , false ) ;
}
} e lse {
if ( ( Std . parseInt ( msg ) > 1 ) && ( Std . parseInt ( msg ) < 101 ) ) {
var heads: Int = 0 ;
for ( i in 1 ... ( Std . parseInt ( msg ) + 1 ) ) {
heads += randInt ( 0 , 1 ) ;
}
m . reply ( { content : ' ${ sender } f l i p p e d ${ Std . parseInt ( msg ) } c o i n s . \n * * H e a d s : * * ${ heads } \n * * T a i l s : * * ${ Std . parseInt ( msg ) - heads } ' } , false ) ;
} e lse {
m . reply ( { content : ' P l e a s e e n t e r a v a l u e b e t w e e n 1 a n d 1 0 0 . ' } , false ) ;
}
}
c ase " d i c e " :
var sides: Int = 6 ;
// Set number of sides
if ( args . length != 0 ) {
if ( Std . parseInt ( args [ 0 ] ) != null ) {
sides = Std . parseInt ( args [ 0 ] ) ;
}
}
// Validate sides
if ( sides == 1 ) {
m . reply ( { content : ' ${ sender } r o l l e d a b a l l o r s o m e t h i n g , i d k . ' } , false ) ;
} e lse if ( sides == 2 ) {
m . reply ( { content : ' ${ sender } t r i e d t o r o l l a 2 - s i d e d d i e ( t h i s i s c a l l e d a c o i n b t w ) . ' } , false ) ;
} e lse if ( ( sides < 1 ) || ( sides > 100 ) ) {
m . reply ( { content : ' P l e a s e e n t e r a v a l u e b e t w e e n 1 a n d 1 0 0 . ' } , false ) ;
} e lse {
// Roll a single die
if ( ( msg . length == 0 ) || ( Std . parseInt ( msg ) == null ) || ( Std . parseInt ( msg ) == 1 ) ) {
m . reply ( { content : ' ${ sender } r o l l e d a ${ sides } - s i d e d d i e a n d g o t ${ randInt ( 1 , sides ) } . ' } , false ) ;
} e lse {
// Roll multiple dice
if ( ( Std . parseInt ( msg ) > 1 ) && ( Std . parseInt ( msg ) < 101 ) ) {
var results: Array < Int > = [ ] ;
for ( i in 1 ... ( Std . parseInt ( msg ) + 1 ) ) {
results . push ( randInt ( 1 , sides ) ) ;
}
// Sort results high-to-low
results . sort ( ( a , b ) - > b - a ) ;
m . reply ( { content : ' ${ sender } r o l l e d a ${ sides } - s i d e d d i e ${ Std . parseInt ( msg ) } t i m e s . \n * * R e s u l t s : * * ${ results . toString ( ) } ' } , false ) ;
} e lse {
m . reply ( { content : ' P l e a s e e n t e r a v a l u e b e t w e e n 1 a n d 1 0 0 . ' } , false ) ;
}
}
}
2023-09-04 22:04:07 -05:00
c ase " 8 b a l l " :
var response: Array < String > = [ " I t i s c e r t a i n . " , " I t i s d e c i d e d l y s o . " , " W i t h o u t a d o u b t . " , " Y e s d e f i n i t e l y . " , " Y o u m a y r e l y o n i t . " , " A s I s e e i t , y e s . " , " M o s t l i k e l y . " , " O u t l o o k g o o d . " , " Y e s . " , " S i g n s p o i n t t o y e s . " , " R e p l y h a z y , t r y a g a i n . " , " A s k a g a i n l a t e r . " , " B e t t e r n o t t e l l y o u n o w . " , " C a n n o t p r e d i c t n o w . " , " C o n c e n t r a t e a n d a s k a g a i n . " , " D o n ' t c o u n t o n i t . " , " M y r e p l y i s n o . " , " M y s o u r c e s s a y n o . " , " O u t l o o k n o t s o g o o d . " , " V e r y d o u b t f u l . " ] ;
m . reply ( { content : ' 🎱 ${ response [ randInt ( 0 , 19 ) ] } 🎱 ' } , false ) ;
2023-09-02 13:53:28 -05:00
// Basic aliases
2023-02-26 16:11:00 -06:00
c ase " a n g e r y " :
m . reply ( { content : " h t t p s : / / c d n . d i s c o r d a p p . c o m / a t t a c h m e n t s / 1 0 7 1 5 4 7 5 1 7 8 4 7 7 3 2 3 0 5 / 1 0 7 9 5 1 8 5 0 4 4 1 3 3 1 1 1 0 8 / a n g e r y . j p g " } , false ) ;
c ase " s u b w a y " :
m . reply ( { content : " h t t p s : / / w w w . y o u t u b e . c o m / w a t c h ? v = y 3 V R X V v r 6 X U " } , false ) ;
2023-09-02 13:53:28 -05:00
c ase " i l l u m i n a t i " :
m . reply ( { content : " h t t p s : / / c d n . d i s c o r d a p p . c o m / a t t a c h m e n t s / 1 0 7 1 5 4 7 5 1 7 8 4 7 7 3 2 3 0 5 / 1 1 4 7 2 0 4 2 5 3 0 3 9 9 8 4 6 7 1 / i l l u m i n a t i . g i f " } , false ) ;
c ase " c u b e " :
m . reply ( { content : " h t t p s : / / c d n . d i s c o r d a p p . c o m / a t t a c h m e n t s / 2 7 0 1 1 3 4 2 2 2 3 2 9 1 1 8 8 3 / 5 0 2 6 9 0 4 5 8 7 7 9 1 2 3 7 2 2 / t h e _ c u b e . j p g " } , false ) ;
c ase " c o o l s v i l l e " :
m . reply ( { content : " h t t p s : / / c d n . d i s c o r d a p p . c o m / a t t a c h m e n t s / 1 0 7 1 5 4 7 5 1 7 8 4 7 7 3 2 3 0 5 / 1 1 4 7 5 8 3 7 6 5 2 1 2 8 3 5 9 2 1 / c o o l s v i l l e . g i f " } , false ) ;
c ase " c o m m u n i s m " :
m . reply ( { content : " h t t p s : / / c d n . d i s c o r d a p p . c o m / a t t a c h m e n t s / 1 0 7 1 5 4 7 5 1 7 8 4 7 7 3 2 3 0 5 / 1 1 4 7 5 9 0 2 2 9 9 6 0 6 9 1 7 4 2 / c o m m u n i s m . g i f " } , false ) ;
2023-09-04 18:44:46 -05:00
c ase " o p i n i o n s " :
m . reply ( { content : " h t t p s : / / c d n . d i s c o r d a p p . c o m / a t t a c h m e n t s / 1 0 7 1 5 4 7 5 1 7 8 4 7 7 3 2 3 0 5 / 1 1 4 7 9 8 3 3 7 5 7 0 1 9 2 1 8 9 2 / o p i n i o n s . j p g " } , false ) ;
2024-11-10 22:19:47 -06:00
c ase " f i n e a r t " :
m . reply ( { content : " h t t p s : / / c d n . d i s c o r d a p p . c o m / a t t a c h m e n t s / 2 7 0 1 1 3 4 2 2 2 3 2 9 1 1 8 8 3 / 4 2 3 3 2 3 6 2 9 1 1 6 3 2 5 8 9 8 / u n k n o w n . p n g " } , false ) ;
c ase " a r t i s h a r d " :
m . reply ( { content : " h t t p s : / / c d n . d i s c o r d a p p . c o m / a t t a c h m e n t s / 2 7 0 1 1 3 4 2 2 2 3 2 9 1 1 8 8 3 / 3 5 6 6 3 8 5 6 5 8 3 4 4 2 4 3 3 0 / t u m b l r _ n r x h z o F 0 K M 1 t 7 5 i o q o 2 _ 2 5 0 . j p g " } , false ) ;
c ase " i n d e e d " :
m . reply ( { content : " h t t p s : / / c d n . d i s c o r d a p p . c o m / a t t a c h m e n t s / 1 0 7 1 5 4 7 5 1 7 8 4 7 7 3 2 3 0 5 / 1 3 0 5 2 5 2 8 9 2 4 9 1 6 4 9 1 4 5 / i n d e e d . g i f " } , false ) ;
c ase " f l o r i d a " :
m . reply ( { content : " h t t p s : / / c d n . d i s c o r d a p p . c o m / a t t a c h m e n t s / 1 0 7 1 5 4 7 5 1 7 8 4 7 7 3 2 3 0 5 / 1 3 0 5 2 5 3 5 6 6 3 4 8 5 2 9 6 9 6 / f l o r i d a . g i f " } , false ) ;
c ase " s t o p " :
m . reply ( { content : " h t t p s : / / c d n . d i s c o r d a p p . c o m / a t t a c h m e n t s / 1 0 7 1 5 4 7 5 1 7 8 4 7 7 3 2 3 0 5 / 1 3 0 5 2 5 3 9 8 5 0 3 6 2 7 5 7 1 2 / s t o p . j p g " } , false ) ;
2023-02-26 17:41:40 -06:00
// Image database commands
c ase " h u g " :
2024-10-16 16:18:03 -05:00
if ( hugDB . length > 0 ) {
m . reply ( { content : ' 🫂 * h u g s ${ msg } * \n ${ hugDB [ randInt ( 0 , hugDB . length - 1 ) ] } ' } , false ) ;
}
2023-03-02 22:14:13 -06:00
c ase " y e s " :
var yes = yesnoDB . yes ;
2024-10-16 16:18:03 -05:00
if ( yes . length > 0 ) {
m . reply ( { content : ' ${ yes [ randInt ( 0 , yes . length - 1 ) ] } ' } , false ) ;
}
2023-03-02 22:14:13 -06:00
c ase " n o " :
var no = yesnoDB . no ;
2024-10-16 16:18:03 -05:00
if ( no . length > 0 ) {
m . reply ( { content : ' ${ no [ randInt ( 0 , no . length - 1 ) ] } ' } , false ) ;
}
2023-09-03 00:00:11 -05:00
// Echobox
c ase " e c h o b o x " :
// Create Echobox array for the server if missing
if ( ! echoboxDB . exists ( ' s e r v e r ${ m . guild_id } ' ) ) {
echoboxDB . set ( ' s e r v e r ${ m . guild_id } ' , [ ] ) ;
}
var echobox: Array < String > = echoboxDB . get ( ' s e r v e r ${ m . guild_id } ' ) ;
var quote: String = " " ;
// Echobox response
2023-09-04 19:01:14 -05:00
if ( ( ! m . mention_everyone ) && ( m . mentions . length == 0 ) && ( m . mention_roles . length == 0 ) ) {
2023-09-03 00:00:11 -05:00
if ( echobox . length > 0 ) {
var ebchoice = randInt ( 0 , echobox . length - 1 ) ;
quote = ' * * E c h o b o x , q u o t e # ${ ebchoice + 1 } : * * ${ echobox [ ebchoice ] } ' ;
} e lse {
quote = ' * * E c h o b o x : * * T h e r e a r e n o q u o t e s i n t h i s s e r v e r \' s E c h o b o x y e t . ' ;
}
// Add quote to Echobox
if ( msg . length != 0 ) {
if ( ! echobox . contains ( msg ) ) {
echobox . push ( msg ) ;
echoboxDB . set ( ' s e r v e r ${ m . guild_id } ' , echobox ) ;
saveQueue . push ( " e c h o b o x " ) ;
m . reply ( { content : quote } , false ) ;
} e lse {
m . reply ( { content : ' * * E c h o b o x : * * T h i s q u o t e i s a l r e a d y i n t h e d a t a b a s e . ' } , false ) ;
}
} e lse {
m . reply ( { content : quote } , false ) ;
}
} e lse {
2023-09-04 19:01:14 -05:00
m . reply ( { content : ' * * E c h o b o x : * * Y o u c a n n o t a d d m e n t i o n s t o t h e E c h o b o x . ' } , false ) ;
2023-09-03 00:00:11 -05:00
}
2023-02-26 16:11:00 -06:00
}
}
// Non-command responses
if ( ( msg . charAt ( 0 ) == " . " ) && ( msg . length == 1 ) ) { m . reply ( { content : " o m g a m e t e o r " } , true ) ; }
2023-02-26 19:00:02 -06:00
if ( ( iceRegex . match ( msg ) ) && ( m . author . id != botInfo . id ) ) { m . reply ( { content : " D i d s o m e c a r b o n - b a s e d l i f e f o r m j u s t s a y * * I C E * * ? " } ) ; }
2023-09-02 13:53:28 -05:00
if ( ( m . mention_everyone == true ) && ( msg . charAt ( 0 ) != " ? " ) ) { m . reply ( { content : " h t t p s : / / c d n . d i s c o r d a p p . c o m / a t t a c h m e n t s / 1 0 7 1 5 4 7 5 1 7 8 4 7 7 3 2 3 0 5 / 1 1 4 7 5 9 8 6 3 7 2 4 1 7 4 1 3 4 3 / a t _ e v e r y o n e . j p g " } , true ) ; }
2023-02-26 16:11:00 -06:00
}
2024-11-10 22:19:47 -06:00
}
2023-02-26 17:41:40 -06:00
2024-10-18 15:05:47 -05:00
/ * *
2024-10-27 11:23:12 -05:00
* This function starts t h e " M e m e o f t h e D a y " s y s t e m .
* A temporary timer is set that counts down to the next MOTD event , at which point the main timer is started on a 24 hour loop .
* /
2024-10-18 23:49:35 -05:00
public static function startMotd ( ) {
var now = Date . now ( ) ;
var nextPost = new Date ( now . getFullYear ( ) , now . getMonth ( ) , now . getDate ( ) , settings . motd . time , 0 , 0 ) ;
if ( now . getHours ( ) >= settings . motd . time ) {
if ( settings . motd . date != datestamp ( ) ) {
settings . motd . date = datestamp ( ) ;
postMotd ( ) ;
2024-10-27 16:05:44 -05:00
saveQueue . push ( " s e t t i n g s " ) ;
2024-10-18 23:49:35 -05:00
}
nextPost = DateTools . delta ( nextPost , 86400000 ) ; // Add one day in milliseconds
2023-02-27 20:28:19 -06:00
}
2023-03-02 12:09:41 -06:00
2024-10-18 23:49:35 -05:00
// Calculate delay for timers
var delay = Std . int ( nextPost . getTime ( ) - now . getTime ( ) ) ;
Timer . delay ( function ( ) {
settings . motd . date = datestamp ( ) ;
postMotd ( ) ;
2024-10-27 16:05:44 -05:00
saveQueue . push ( " s e t t i n g s " ) ;
2024-10-18 23:49:35 -05:00
// Start the looped MOTD timer
motdTimer = new Timer ( 86400000 ) ;
2024-11-10 22:19:47 -06:00
motdTimer . run = function ( ) {
2024-10-18 23:49:35 -05:00
settings . motd . date = datestamp ( ) ;
postMotd ( ) ;
2024-10-27 16:05:44 -05:00
saveQueue . push ( " s e t t i n g s " ) ;
2023-02-27 20:28:19 -06:00
}
2024-10-18 23:49:35 -05:00
} , delay ) ;
}
2023-02-27 20:28:19 -06:00
2023-03-02 12:57:23 -06:00
2024-10-18 23:49:35 -05:00
/ * *
2024-10-27 11:23:12 -05:00
* Sends the MOTD to the channels specified in the bot settings .
* May just move this code into the places it ' s n e e d e d i n s t e a d o f k e e p i n g t h i s f u n c t i o n .
* /
2024-10-18 23:49:35 -05:00
public static function postMotd ( ) {
2024-10-27 16:05:44 -05:00
var msg = getMotd ( true ) ;
2024-10-18 23:49:35 -05:00
var channels: Array < String > = settings . motd . channels ; // Because it won't let me do this directly
2023-02-27 20:28:19 -06:00
2024-10-18 23:49:35 -05:00
if ( channels . length > 0 ) { for ( i in channels ) { if ( msg . length > 0 ) { Endpoints . sendMessage ( i , { content : msg } , null , false ) ; } } }
}
/ * *
2024-10-27 11:23:12 -05:00
* This function checks t h e M O T D d a t a b a s e t o f i n d t h e e n t r y m o s t r e l e v a n t t o t h e c u r r e n t d a t e a n d r e t u r n s t h e a p p r o p r i a t e d a t a .
2024-10-27 16:05:44 -05:00
*
* @ param update Whether the result should be stored to exclude from the next run .
2024-10-27 11:23:12 -05:00
* /
2024-10-27 16:05:44 -05:00
public static function getMotd ( update : Bool = false ) {
2024-10-18 23:49:35 -05:00
var msg = " " ;
var day: Array < String > = [ ] ;
2024-10-27 16:05:44 -05:00
var special = true ;
2024-10-18 23:49:35 -05:00
// Check for exact date
if ( motdDB . exists ( ' ${ datestamp ( ) } ' ) ) {
day = motdDB . get ( ' ${ datestamp ( ) } ' ) ;
}
// Else, check for special date
e lse if ( motdDB . exists ( ' ${ printMonth ( ) . substr ( 0 , 3 ) } ${ printDate ( ) } ' ) ) {
day = motdDB . get ( ' ${ printMonth ( ) . substr ( 0 , 3 ) } ${ printDate ( ) } ' ) ;
}
// Else, check for special day/date combo
e lse if ( motdDB . exists ( ' ${ printDay ( ) . substr ( 0 , 3 ) } ${ printDate ( ) } ' ) ) {
day = motdDB . get ( ' ${ printDay ( ) . substr ( 0 , 3 ) } ${ printDate ( ) } ' ) ;
2023-02-27 20:28:19 -06:00
}
2024-10-19 17:43:47 -05:00
// Else, check for just the date
e lse if ( motdDB . exists ( ' ${ printDate ( ) } ' ) ) {
day = motdDB . get ( ' ${ printDate ( ) } ' ) ;
}
2024-10-18 23:49:35 -05:00
// Otherwise, post daily meme
e lse if ( motdDB . exists ( printDay ( ) . substr ( 0 , 3 ) ) ) {
day = motdDB . get ( printDay ( ) . substr ( 0 , 3 ) ) ;
2024-10-27 16:05:44 -05:00
special = false ;
2024-10-18 23:49:35 -05:00
}
2024-10-27 16:05:44 -05:00
if ( day . length > 0 ) {
if ( update && ! special && ( day . length > 2 ) ) {
var today = Date . now ( ) . getDay ( ) ;
var previous: Array < Int > = settings . motd . previous ;
var choice = randIntExclude ( 0 , day . length - 1 , [ previous [ today ] ] ) ;
previous [ today ] = choice ;
settings . motd . previous = previous ;
msg = day [ choice ] ;
} e lse {
msg = day [ randInt ( 0 , day . length - 1 ) ] ;
}
}
2024-10-18 23:49:35 -05:00
return msg ;
2023-02-27 20:28:19 -06:00
}
2024-11-14 19:07:33 -06:00
/ * *
2025-04-01 23:01:39 -05:00
* This function performs t h e * P i r a t e v s N i n j a * s t a t c a l c u l a t i o n s a n d r e p l i e s w i t h t h e a p p r o p r i a t e r e s u l t s .
2024-11-14 19:07:33 -06:00
* @ param choice ` p ` , ` n ` , ` pvn ` , or ` nvp ` .
2025-04-01 23:01:39 -05:00
* @ param query The name of the character . For dual - character choices , separate names with a pipe .
* /
2024-11-14 19:07:33 -06:00
public static function pvn ( choice : String , query : String , m : Message ) {
if ( choice . length > 1 ) {
2025-04-01 23:01:39 -05:00
var splitQuery: Array < String > = [ ] ;
2024-11-14 19:07:33 -06:00
if ( query . contains ( " | " ) ) {
2025-04-01 23:01:39 -05:00
splitQuery = query . split ( " | " ) ;
2024-11-14 19:07:33 -06:00
} e lse {
2025-04-01 23:01:39 -05:00
splitQuery . push ( query ) ;
splitQuery . push ( query ) ;
}
if ( choice == " p v n " ) {
var pirate = getPirate ( splitQuery [ 0 ] ) ;
var ninja = getNinja ( splitQuery [ 1 ] ) ;
printPirate ( pirate , m ) ;
printNinja ( ninja , m ) ;
if ( pirate . total > ninja . total ) {
m . reply ( { content : ' # # ${ pirate . rank } ${ pirate . name } w i n s ! ' } , false ) ;
} e lse if ( pirate . total < ninja . total ) {
m . reply ( { content : ' # # ${ ninja . rank } ${ ninja . name } w i n s ! ' } , false ) ;
} e lse {
m . reply ( { content : ' # # I t \' s a T I E ! ' } , false ) ;
}
} e lse if ( choice == " n v p " ) {
var ninja = getNinja ( splitQuery [ 0 ] ) ;
var pirate = getPirate ( splitQuery [ 1 ] ) ;
printNinja ( ninja , m ) ;
printPirate ( pirate , m ) ;
if ( pirate . total > ninja . total ) {
m . reply ( { content : ' # # ${ pirate . rank } ${ pirate . name } w i n s ! ' } , false ) ;
} e lse if ( pirate . total < ninja . total ) {
m . reply ( { content : ' # # ${ ninja . rank } ${ ninja . name } w i n s ! ' } , false ) ;
} e lse {
m . reply ( { content : ' # # I t \' s a T I E ! ' } , false ) ;
}
2024-11-14 19:07:33 -06:00
}
} e lse {
2025-04-01 23:01:39 -05:00
if ( choice == " p " ) { printPirate ( getPirate ( query ) , m ) ; }
if ( choice == " n " ) { printNinja ( getNinja ( query ) , m ) ; }
}
}
public static function getPirate ( name ) {
var pirate: Dynamic = { } ;
pirate . name = name ;
var pweapons = [ ' C u t l a s s ' , ' P i s t o l ' , ' B r o k e n B o t t l e ' , ' C a n n o n ' , ' A t t a c k P a r r o t ' , ' H o o k H a n d ' , ' B e l a y i n g P i n ' , ' D a g g e r ' , ' G r a p p l i n g H o o k ' , ' A M e a n S t r e a k A M i l e W i d e ' ] ;
pirate . swash = ( hashString ( name , " s w a s h b u c k l i n g " , 20 ) + 1 ) ;
pirate . drunk = ( hashString ( name , ' d r u n k e n n e s s ' , 20 ) + 1 ) ;
pirate . booty = ( hashString ( name , ' b o o t y ' , 20 ) + 1 ) ;
var weapons: Array < String > = [ ] ;
var wnum = ( hashString ( name , " p w e a p o n s " , 5 ) - 1 ) ;
while ( wnum > 0 ) {
var wsel = pweapons [ hashString ( name , ' $ wnum p w e a p o n ' , pweapons . length - 1 ) ] ;
if ( ! weapons . contains ( wsel ) ) { weapons . push ( wsel ) ; }
wnum -- ;
2024-11-14 19:07:33 -06:00
}
2025-04-01 23:01:39 -05:00
pirate . weapons = " " ;
for ( i in 0 ... weapons . length ) {
if ( Std . string ( pirate . weapons ) . length != 0 ) { pirate . weapons += " , " ; }
pirate . weapons = pirate . weapons + weapons [ i ] ;
}
2024-11-14 19:07:33 -06:00
2025-04-01 23:01:39 -05:00
pirate . total = pirate . swash + pirate . drunk + pirate . booty + weapons . length ;
pirate . rank = " C a b i n B o y " ;
if ( pirate . total > 15 ) { pirate . rank = ' P i r a t e ' ; }
if ( pirate . total > 30 ) { pirate . rank = ' D r e a d P i r a t e ' ; }
if ( pirate . total > 45 ) { pirate . rank = ' C a p t a i n ' ; }
if ( pirate . total >= 60 ) { pirate . rank = ' P i r a t e K i n g ' ; }
2024-11-14 19:07:33 -06:00
2025-04-01 23:01:39 -05:00
return ( pirate ) ;
}
2024-11-14 19:07:33 -06:00
2025-04-01 23:01:39 -05:00
public static function getNinja ( name ) {
var ninja: Dynamic = { } ;
ninja . name = name ;
var nweapons = [ ' S h u r i k e n ' , ' K a t a n a ' , ' P o i s o n D a r t ' , ' D e a t h T o u c h ' , ' N i n j a - T o ' , ' S m o k e B o m b ' , ' T h o u s a n d B l o s s o m F i n g e r ' , ' A P o i n t y S t i c k ' , ' J o S t i c k ' , ' N u n c h a k u ' ] ;
ninja . sneak = ( hashString ( name , " s n e a k i n e s s " , 20 ) + 1 ) ;
ninja . peejs = ( hashString ( name , ' p a j a m a s ' , 20 ) + 1 ) ;
ninja . point = ( hashString ( name , ' p o i n t y t h i n g s ' , 20 ) + 1 ) ;
var weapons: Array < String > = [ ] ;
var wnum = ( hashString ( name , " n w e a p o n s " , 5 ) - 1 ) ;
while ( wnum > 0 ) {
var wsel = nweapons [ hashString ( name , ' $ wnum n w e a p o n ' , nweapons . length - 1 ) ] ;
if ( ! weapons . contains ( wsel ) ) { weapons . push ( wsel ) ; }
wnum -- ;
}
ninja . weapons = " " ;
for ( i in 0 ... weapons . length ) {
if ( Std . string ( ninja . weapons ) . length != 0 ) { ninja . weapons += " , " ; }
ninja . weapons = ninja . weapons + weapons [ i ] ;
2024-11-14 19:07:33 -06:00
}
2025-04-01 23:01:39 -05:00
ninja . total = ninja . sneak + ninja . peejs + ninja . point + weapons . length ;
ninja . rank = " A p p r e n t i c e " ;
if ( ninja . total > 15 ) { ninja . rank = ' N i n j a ' ; }
if ( ninja . total > 30 ) { ninja . rank = ' D e a d l y N i n j a ' ; }
if ( ninja . total > 45 ) { ninja . rank = ' N i n j a M a s t e r ' ; }
if ( ninja . total >= 60 ) { ninja . rank = ' G r a n d m a s t e r ' ; }
return ( ninja ) ;
}
2024-11-14 19:07:33 -06:00
2025-04-01 23:01:39 -05:00
public static function printPirate ( pirate , m : Message ) {
m . reply ( { content : ' # # ${ pirate . rank } ${ pirate . name } \n S w a s h b u c k l i n g : ${ pirate . swash } \n D r u n k e n n e s s : ${ pirate . drunk } \n B o o t y : ${ pirate . booty } \n W e a p o n s : ${ pirate . weapons } \n * * T o t a l : ${ pirate . total } * * ' } , false ) ;
}
public static function printNinja ( ninja , m : Message ) {
m . reply ( { content : ' # # ${ ninja . rank } ${ ninja . name } \n S n e a k i n e s s : ${ ninja . sneak } \n P a j a m a s : ${ ninja . peejs } \n P o i n t y T h i n g s : ${ ninja . point } \n W e a p o n s : ${ ninja . weapons } \n * * T o t a l : ${ ninja . total } * * ' } , false ) ;
}
/ * *
* Marc Majcher ' s s t r i n g h a s h e r f r o m * P i r a t e v s N i n j a ! *
* @ param input The input string .
* @ param seed An identifying salt to make strings come out differently for d i f f e r e n t , b u t s a m e - s i z e d l i s t s .
* @ param num The number of buckets you wish to hash into .
* /
public static function hashString ( input : String , seed : String , num : BigInt ) {
var count: BigInt = 0 ;
var total: BigInt = 0 ;
var xorResult = " " ;
// Pad strings until they're equal in length
input = StringTools . rpad ( input , String . fromCharCode ( 0 ) , seed . length ) ;
seed = StringTools . rpad ( seed , String . fromCharCode ( 0 ) , input . length ) ;
// XOR the input and seed
for ( i in 0 ... ( input . length ) ) {
xorResult = xorResult + String . fromCharCode ( input . charCodeAt ( i ) ^ seed . charCodeAt ( i ) ) ;
2024-11-14 19:07:33 -06:00
}
2025-04-01 23:01:39 -05:00
// Calculate stats
for ( i in 0 ... xorResult . length ) {
total += ( xorResult . charCodeAt ( i ) : BigInt ) * ( ( 128 : BigInt ) . pow ( count ) ) ;
count ++ ;
}
return ( ( ( total * ( total + ( 523 : BigInt ) ) ) % num ) . toInt ( ) ) ;
2024-11-14 19:07:33 -06:00
}
2024-10-18 15:05:47 -05:00
2024-11-09 14:22:29 -06:00
/ * *
2024-11-10 22:19:47 -06:00
* This function performs a Y o u T u b e s e a r c h a n d r e p l i e s w i t h t h e f i r s t r e s u l t .
* @ param m The message data .
* @ param query The string to search .
* /
2024-11-09 14:22:29 -06:00
public static function ytlookup ( m : Message , query : String ) {
2024-11-14 18:48:27 -06:00
var req = new haxe . Http ( ' h t t p s : / / w w w . y o u t u b e . c o m / r e s u l t s ? s e a r c h _ q u e r y = ${ query . urlEncode ( ) } ' ) ;
2024-11-10 22:19:47 -06:00
Sys . println ( ' [ ${ timestamp ( ) } ] y t l o o k u p : U R L - h t t p s : / / w w w . y o u t u b e . c o m / r e s u l t s ? s e a r c h _ q u e r y = ${ query . urlEncode ( ) } ' ) ;
2024-11-09 14:22:29 -06:00
2024-11-14 18:48:27 -06:00
req . onData = function ( request ) {
2024-11-10 22:19:47 -06:00
File . saveContent ( " e x p o r t / y t l o o k u p _ r e s u l t . t x t " , request ) ;
2024-11-09 14:22:29 -06:00
var data = new HtmlDocument ( request ) ;
var search = data . find ( " s c r i p t " ) ; // YouTube obfuscates everything into JS garbage so we have to check every <script>
var gotcha = " " ;
var result = " E r r o r : U n a b l e t o p a r s e Y o u T u b e s e a r c h r e s u l t . " ;
for ( i in search ) {
2024-11-10 13:14:17 -06:00
if ( i . toString ( ) . contains ( " \" v i d e o R e n d e r e r \" : { \" v i d e o I d \" : \" " ) || i . toString ( ) . contains ( " \" r e e l W a t c h E n d p o i n t \" : { \" v i d e o I d \" : \" " ) ) {
2024-11-09 14:22:29 -06:00
gotcha = i . toString ( ) ;
2024-11-10 13:14:17 -06:00
if ( ( i . toString ( ) . contains ( " \" r e e l W a t c h E n d p o i n t \" : { \" v i d e o I d \" : \" " ) ) && ( gotcha . indexOf ( " \" r e e l W a t c h E n d p o i n t \" : { \" v i d e o I d \" : \" " ) < gotcha . indexOf ( " \" v i d e o R e n d e r e r \" : { \" v i d e o I d \" : \" " ) ) ) {
// Top result is a Short
result = " h t t p s : / / y o u t u . b e / " + gotcha . substring ( gotcha . indexOf ( " \" r e e l W a t c h E n d p o i n t \" : { \" v i d e o I d \" : \" " ) + 32 , gotcha . indexOf ( " \" " , gotcha . indexOf ( " \" r e e l W a t c h E n d p o i n t \" : { \" v i d e o I d \" : \" " ) + 32 ) ) ;
2024-11-10 22:19:47 -06:00
Sys . println ( ' [ ${ timestamp ( ) } ] y t l o o k u p : R e s u l t - $ result ( S h o r t ) ' ) ;
2024-11-10 13:14:17 -06:00
break ;
} e lse {
// Top result is a normal video
result = " h t t p s : / / y o u t u . b e / " + gotcha . substring ( gotcha . indexOf ( " \" v i d e o R e n d e r e r \" : { \" v i d e o I d \" : \" " ) + 28 , gotcha . indexOf ( " \" " , gotcha . indexOf ( " \" v i d e o R e n d e r e r \" : { \" v i d e o I d \" : \" " ) + 28 ) ) ;
2024-11-10 22:19:47 -06:00
Sys . println ( ' [ ${ timestamp ( ) } ] y t l o o k u p : R e s u l t - $ result ( N o r m a l ) ' ) ;
2024-11-10 13:14:17 -06:00
break ;
2024-11-09 14:22:29 -06:00
}
}
}
2024-11-10 22:19:47 -06:00
m . reply ( { content : result } , false ) ;
m . reply ( { content : " - # Y o u T u b e L o o k u p i s s t i l l i n b e t a . I f t h e r e s u l t s e e m s i n a c c u r a t e , p l e a s e u s e t h e c o m m a n d ` ? y t d e b u g ` s o t h e d e v e l o p e r c a n r e v i e w t h e d a t a t h a t w a s r e c e i v e d . " } , false ) ;
2024-11-09 14:22:29 -06:00
}
2024-11-14 18:48:27 -06:00
req . onError = function ( error ) {
2024-11-10 22:19:47 -06:00
m . reply ( { content : ' E r r o r i n Y o u T u b e L o o k u p : $ error ' } , false ) ;
2024-11-10 13:14:17 -06:00
Sys . println ( ' [ ${ timestamp ( ) } ] y t l o o k u p : E r r o r - $ error , r e q u e s t w a s $ query ' ) ;
2024-11-09 14:22:29 -06:00
}
2024-11-14 18:48:27 -06:00
req . request ( ) ;
}
/ * *
* Retrieves a specific message in the channel and returns it as a JSON object .
* @ param channel_id Numerical ID of the channel .
* @ param m_id Numerical ID of the message .
* /
public static function getMessage ( channel_id : String , m_id : String ) {
var req: hxdiscord . utils . Http = new hxdiscord . utils . Http ( " h t t p s : / / d i s c o r d . c o m / a p i / v " + hxdiscord . gateway . Gateway . API_VERSION + " / c h a n n e l s / " + channel_id + " / m e s s a g e s / " + m_id ) ;
req . addHeader ( " U s e r - A g e n t " , " h x d i s c o r d ( h t t p s : / / g i t h u b . c o m / F u r r e t D e v / h x d i s c o r d ) " ) ;
req . addHeader ( " A u t h o r i z a t i o n " , DiscordClient . authHeader ) ;
req . setMethod ( " G E T " ) ;
var msg: Dynamic = null ;
req . onData = function ( data : String ) {
msg = haxe . Json . parse ( data ) ;
}
req . onError = function ( error ) {
Sys . println ( ' [ ${ timestamp ( ) } ] g e t M e s s a g e : E r r o r - $ error ' ) ;
Sys . println ( ' [ ${ timestamp ( ) } ] g e t M e s s a g e : ${ req . responseData } ' ) ;
}
req . send ( ) ;
return msg ;
2024-11-09 14:22:29 -06:00
}
2024-10-18 15:05:47 -05:00
/ * *
2024-10-27 11:23:12 -05:00
* The ` saveSystem ( ) ` function handles a l l f i l e s y s t e m w r i t e s . W h e n t h e b o t n e e d s t o s a v e a f i l e , i t p u s h e s d a t a t o t h e ` s a v e Q u e u e ` a r r a y .
* The save system checks the queue regularly and operates on the first entry provided .
* This throttles filesystem access , to prevent multiple commands from writing to the drive at the same time .
* /
2023-09-02 18:54:33 -05:00
public static function saveSystem ( ) {
2024-10-18 23:49:35 -05:00
Timer . delay ( function ( ) {
saveTimer = new Timer ( 60 * 1000 ) ;
2024-11-10 22:19:47 -06:00
saveTimer . run = function ( ) {
2024-10-18 23:49:35 -05:00
if ( saveQueue . length > 0 ) { // See if there's anything in the queue
2023-09-02 18:54:33 -05:00
switch ( saveQueue . shift ( ) ) {
c ase " s e t t i n g s " :
saveSettings ( ) ;
Sys . println ( ' [ ${ timestamp ( ) } ] S a v e d s e t t i n g s . j s o n ' ) ;
2023-09-03 00:00:11 -05:00
c ase " e c h o b o x " :
saveEchoboxDB ( ) ;
Sys . println ( ' [ ${ timestamp ( ) } ] S a v e d e c h o b o x - d b . j s o n ' ) ;
2024-10-18 23:49:35 -05:00
}
2023-09-02 18:54:33 -05:00
}
}
2024-10-18 23:49:35 -05:00
} , ( 60 - Date . now ( ) . getSeconds ( ) ) * 1000 ) ;
2023-02-27 20:28:19 -06:00
}
2024-10-18 15:05:47 -05:00
/ * *
2024-10-27 11:23:12 -05:00
* Writes the modified ` settings . json ` from memory back to the drive .
* /
2023-02-26 17:41:40 -06:00
public static function saveSettings ( ) {
File . saveContent ( " s e t t i n g s . j s o n " , Json . stringify ( settings , " \t " ) ) ;
}
2024-10-18 15:05:47 -05:00
/ * *
2024-10-27 11:23:12 -05:00
* Writes the modified ` echobox - db . json ` from memory back to the drive .
* /
2023-09-03 00:00:11 -05:00
public static function saveEchoboxDB ( ) {
File . saveContent ( " e c h o b o x - d b . j s o n " , Json . stringify ( echoboxDB , " \t " ) ) ;
}
2024-10-18 15:05:47 -05:00
/ * *
2024-10-27 11:23:12 -05:00
* Performs a clean shutdown of the bot , after saving relevant files to the disk .
* /
2023-02-26 17:41:40 -06:00
public static function shutdown ( ) {
saveSettings ( ) ;
2023-09-03 00:00:11 -05:00
saveEchoboxDB ( ) ;
2023-02-26 17:41:40 -06:00
Sys . exit ( 0 ) ;
}
2023-02-26 14:46:18 -06:00
}