2024-09-29 14:35:25 +02:00
package wat
import (
"fmt"
"strconv"
"strings"
"github.com/go-irc/irc"
)
type BotGameConfig map [ string ] [ ] string
type WatIntegrationConfig struct {
BotHosts [ ] string
BotGames BotGameConfig
}
type WatIntegration struct {
bot * WatBot
db * WatDb
c * WatIntegrationConfig
}
func NewWatIntegration ( bot * WatBot , db * WatDb , c * WatIntegrationConfig ) * WatIntegration {
return & WatIntegration { bot , db , c }
}
func ( w * WatIntegration ) Bot ( m * irc . Message ) ( bool , [ ] string ) {
isBot := w . bot . Allowed ( m . Prefix . Host , w . c . BotHosts )
var games [ ] string
if isBot {
for b , g := range w . c . BotGames {
if b == m . Prefix . Name {
games = g
break
}
}
}
return isBot , games
}
func ( w * WatIntegration ) HandleIntegration ( m * irc . Message , msgargs [ ] string ) bool {
isBot , games := w . Bot ( m )
if isBot {
// handles a message "Top finishers: (nick1: 1300) (nick2: 1200)" from an authorized Jeopardy game bot
if msgargs [ 0 ] == "Top" && msgargs [ 1 ] == "finishers:" && w . bot . Allowed ( "jeopardy" , games ) {
w . Jeopardy ( m , msgargs )
return true
}
}
// not an authorized bot or no integration matched the given message
return false
}
func ( w * WatIntegration ) Jeopardy ( m * irc . Message , msgargs [ ] string ) {
// hey, I avoided regex!
2024-10-01 20:55:33 +02:00
// 1. Starts parsing an array of message arguments containing "Top finishers: (nick1: 1000) (nick2: 2000)", where
// the "($nick: $value)" pairs can contain arbitrary nicknames + integer values and can repeat one to any amount of times
// 2. Join the array on spaces to a string, but skip the first two elements to remove "Top" and "finishers:"
// 3. Replace ") (" in the string with ";" - the semicolon is chosen as a temporary delimiter because it does not conflict with any other characters in the message
// 4. Replace ": " in the string with ":"
// 5. Replace "(" in the string with "" (relevant for the first nick/value pair)
// 6. Replace ")" in the string with "" (relevant for the last nick/value pair)
// 7. Now, we have a string like "nick1:1000;nick2:2000" - split it back into an array on ";"
// 8. The result is an array like "[nick1:1000, nick2:2000]"
2024-09-29 14:35:25 +02:00
finisherPrizes := strings . Split ( strings . Replace ( strings . Replace ( strings . Replace ( strings . Replace ( strings . Join ( msgargs [ 2 : ] , " " ) , ") (" , ";" , - 1 ) , ": " , ":" , - 1 ) , "(" , "" , 1 ) , ")" , "" , 1 ) , ";" )
fmt . Printf ( "Processing Jeopardy: %s\n" , finisherPrizes )
2024-10-01 20:55:33 +02:00
// iterate over the "$nick:$value" string elements
2024-09-29 14:35:25 +02:00
for _ , pair := range finisherPrizes {
2024-10-01 20:55:33 +02:00
// turn the string element into an array, where the first entry is the nickname, and the second the value
2024-09-29 14:35:25 +02:00
nameCoinPair := strings . Split ( pair , ":" )
coins , err := strconv . ParseUint ( nameCoinPair [ 1 ] , 10 , 64 )
if err != nil {
fmt . Printf ( "Invalid coins, cannot process pair for cashout: %s.\n" , nameCoinPair )
continue
}
name := nameCoinPair [ 0 ]
// Jeopardy prizes are quite a lot of $$$, make it a bit more sane
coins = coins / 40
// name = we assume the Jeopardy player name to match a Watbot player name
// host = we could use some WHO logic to find the host, but assuming nickname lookup to be sufficient here
// create = based on the above, maybe rather not create Watbot players based on only a nick?
// but it expects someone to have played with Watbot before to be eligible for Jeopardy cashout ..
player := w . db . User ( name , "" , false )
if player . Nick == "" {
fmt . Printf ( "Player %s does not exist in Watbot, skipping cashout.\n" , name )
continue
} else {
w . bot . reply ( m , fmt . Sprintf ( "smartass %s, gave u %d :)" , player . Nick , coins ) )
player . Coins += coins
w . db . Update ( player )
}
}
}