summaryrefslogtreecommitdiffstats
path: root/wat/integration.go
blob: b4ff8e9e3dfd7ad147cb4455bcbc69cdebfc214b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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!
	//   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]"
	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)
	// iterate over the "$nick:$value" string elements
	for _, pair := range finisherPrizes {
		// turn the string element into an array, where the first entry is the nickname, and the second the value
		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)
		}
	}
}