Ejemplo n.º 1
0
func (p *ReminderPlugin) Message(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message) {
	if !service.IsMe(message) {
		if bruxism.MatchesCommand(service, "remind", message) || bruxism.MatchesCommand(service, "reminder", message) {
			_, parts := bruxism.ParseCommand(service, message)

			if len(parts) < 2 {
				service.SendMessage(message.Channel(), fmt.Sprintf("Invalid reminder, no time or message. eg: %s", p.randomReminder(service)))
				return
			}

			t, r, err := p.parseReminder(parts)

			now := time.Now()

			if err != nil || t.Before(now) || t.After(now.Add(time.Hour*24*365+time.Hour)) {
				service.SendMessage(message.Channel(), fmt.Sprintf("Invalid time. eg: %s", strings.Join(randomTimes, ", ")))
				return
			}

			if r == "" {
				service.SendMessage(message.Channel(), fmt.Sprintf("Invalid reminder, no message. eg: %s", p.randomReminder(service)))
				return
			}

			requester := message.UserName()
			if service.Name() == bruxism.DiscordServiceName {
				requester = fmt.Sprintf("<@%s>", message.UserID())
			}

			err = p.AddReminder(&Reminder{
				StartTime: now,
				Time:      t,
				Requester: requester,
				Target:    message.Channel(),
				Message:   r,
				IsPrivate: service.IsPrivate(message),
			})
			if err != nil {
				service.SendMessage(message.Channel(), err.Error())
				return
			}

			service.SendMessage(message.Channel(), fmt.Sprintf("Reminder set for %s.", humanize.Time(t)))
		}
	}
}
Ejemplo n.º 2
0
// Message handler.
func (p *playingPlugin) messageFunc(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message) {
	if !service.IsMe(message) {
		if bruxism.MatchesCommand(service, "playing", message) {
			if !service.IsBotOwner(message) {
				return
			}
			query, _ := bruxism.ParseCommand(service, message)

			split := strings.Split(query, ",")

			p.Game = strings.Trim(split[0], " ")
			if len(split) > 1 {
				p.URL = strings.Trim(split[1], " ")
				service.(*bruxism.Discord).Session.UpdateStreamingStatus(0, p.Game, p.URL)
			} else {
				service.(*bruxism.Discord).Session.UpdateStatus(0, p.Game)
			}
		}
	}
}
Ejemplo n.º 3
0
func emojiMessageFunc(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message) {
	if service.Name() == bruxism.DiscordServiceName && !service.IsMe(message) {
		if bruxism.MatchesCommand(service, "emoji", message) || bruxism.MatchesCommand(service, "hugemoji", message) {
			base := "emoji/twitter"
			if bruxism.MatchesCommand(service, "hugemoji", message) {
				base = "emoji/twitterhuge"
			}
			_, parts := bruxism.ParseCommand(service, message)
			if len(parts) == 1 {
				submatches := discordRegex.FindStringSubmatch(parts[0])
				if len(submatches) != 0 {
					h, err := http.Get("https://cdn.discordapp.com/emojis/" + submatches[1] + ".png")
					if err != nil {
						return
					}

					service.SendFile(message.Channel(), "emoji.png", h.Body)
					h.Body.Close()

					return

				}

				s := strings.TrimSpace(parts[0])
				for i := range s {
					filename := emojiFile(base, s[i:])
					if filename != "" {
						if f, err := os.Open(fmt.Sprintf("%s/%s.png", base, filename)); err == nil {
							defer f.Close()
							service.SendFile(message.Channel(), "emoji.png", f)

							return
						}
					}
				}
			}
		}
	}
}
Ejemplo n.º 4
0
func (p *streamerPlugin) messageFunc(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message) {
	if !service.IsMe(message) {
		if bruxism.MatchesCommand(service, "streamer", message) {
			query, parts := bruxism.ParseCommand(service, message)

			if len(parts) == 0 {
				return
			}

			r, _ := p.requests[query]
			if r == nil {
				r = &streamerPluginRequest{}
				p.requests[query] = r
			}

			n := time.Now()
			if !n.After(r.lastUpdate.Add(60 * time.Minute)) {
				if r.lastMessage != "" {
					service.SendMessage(message.Channel(), fmt.Sprintf("%s *Last updated %s.*", r.lastMessage, humanize.Time(r.lastUpdate)))
				}
				return
			}

			service.Typing(message.Channel())

			r.lastUpdate = n

			m, err := p.streamer(query, service.Name() == bruxism.DiscordServiceName)
			if err != nil {
				service.SendMessage(message.Channel(), "There was an error while requesting the streamer, please try again later.")
				return
			}

			service.SendMessage(message.Channel(), m)
			r.lastMessage = m
		}
	}
}
Ejemplo n.º 5
0
// Message handler.
func (p *livePlugin) Message(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message) {
	defer bruxism.MessageRecover()
	if !service.IsMe(message) {
		messageChannel := message.Channel()

		if bruxism.MatchesCommand(service, "live", message) {
			ticks := ""
			if service.Name() == bruxism.DiscordServiceName {
				ticks = "`"
			}

			_, parts := bruxism.ParseCommand(service, message)

			if len(parts) == 0 {
				service.SendMessage(messageChannel, fmt.Sprintf("Incorrect command. eg: %s%slive [add|remove|list] <%s>%s", ticks, service.CommandPrefix(), "UCGmC0A8mEAPdlELQdP9xJbw", ticks))
			}

			switch parts[0] {
			case "list":
				if !service.IsModerator(message) {
					service.SendMessage(messageChannel, "I'm sorry, you must be the channel owner to list live announcements.")
					return
				}
				list := []string{}
				p.Lock()
				for ytChannel := range p.ChannelToYouTubeChannels[messageChannel] {
					list = append(list, fmt.Sprintf("%s (%s)", p.ytLiveChannel.ChannelName(ytChannel), ytChannel))
				}
				p.Unlock()
				if len(list) == 0 {
					service.SendMessage(messageChannel, "No Channels are being announced.")
				} else {
					service.SendMessage(messageChannel, fmt.Sprintf("Currently announcing: %s", strings.Join(list, ",")))
				}
			case "add":
				if !service.IsModerator(message) {
					service.SendMessage(messageChannel, "I'm sorry, you must be the channel owner to add live announcements.")
					return
				}
				if len(parts) != 2 || len(parts[1]) != 24 {
					service.SendMessage(messageChannel, fmt.Sprintf("Incorrect Channel ID. eg: %s%slive %s %s%s", ticks, service.CommandPrefix(), parts[0], "UCGmC0A8mEAPdlELQdP9xJbw", ticks))
					return
				}
				err := p.monitor(messageChannel, parts[1])
				if err != nil {
					service.SendMessage(messageChannel, fmt.Sprintf("Could not add Channel ID. %s", err))
					return
				}
				service.SendMessage(messageChannel, fmt.Sprintf("Messages will be sent here when %s goes live.", p.ytLiveChannel.ChannelName(parts[1])))
			case "remove":
				if !service.IsModerator(message) {
					service.SendMessage(messageChannel, "I'm sorry, you must be the channel owner to remove live announcements.")
					return
				}
				if len(parts) != 2 || len(parts[1]) != 24 {
					service.SendMessage(messageChannel, fmt.Sprintf("Incorrect Channel ID. eg: %s%slive %s %s%s", ticks, service.CommandPrefix(), parts[0], "UCGmC0A8mEAPdlELQdP9xJbw", ticks))
					return
				}
				p.Lock()
				delete(p.ChannelToYouTubeChannels[messageChannel], parts[1])
				delete(p.youTubeChannelToChannels[parts[1]], messageChannel)
				p.Unlock()
				service.SendMessage(messageChannel, fmt.Sprintf("Messages will no longer be sent here when %s goes live.", p.ytLiveChannel.ChannelName(parts[1])))
			}
		}
	}
}
Ejemplo n.º 6
0
// Message handler.
func (p *comicPlugin) Message(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message) {
	if service.IsMe(message) {
		return
	}

	p.Lock()
	defer p.Unlock()

	log, ok := p.log[message.Channel()]
	if !ok {
		log = []bruxism.Message{}
	}

	if bruxism.MatchesCommand(service, "customcomic", message) || bruxism.MatchesCommand(service, "customcomicsimple", message) {
		ty := comicgen.ComicTypeChat
		if bruxism.MatchesCommand(service, "customcomicsimple", message) {
			ty = comicgen.ComicTypeSimple
		}

		service.Typing(message.Channel())

		str, _ := bruxism.ParseCommand(service, message)

		messages := []*comicgen.Message{}

		splits := strings.Split(str, "|")
		for _, line := range splits {
			line := strings.Trim(line, " ")

			text := ""
			speaker := 0
			author := ""
			if strings.Index(line, ":") != -1 {
				lineSplit := strings.Split(line, ":")

				author = strings.ToLower(strings.Trim(lineSplit[0], " "))

				var err error
				speaker, err = strconv.Atoi(author)
				if err != nil {
					speaker = -1
				}

				text = strings.Trim(lineSplit[1], " ")
			} else {
				text = line
			}

			messages = append(messages, &comicgen.Message{
				Speaker: speaker,
				Text:    text,
				Author:  author,
			})
		}

		if len(messages) == 0 {
			service.SendMessage(message.Channel(), fmt.Sprintf("Sorry %s, you didn't add any text.", message.UserName()))
			return
		}

		p.makeComic(bot, service, message, &comicgen.Script{
			Messages: messages,
			Author:   fmt.Sprintf(service.UserName()),
			Type:     ty,
		})
	} else if bruxism.MatchesCommand(service, "comic", message) {
		if len(log) == 0 {
			service.SendMessage(message.Channel(), fmt.Sprintf("Sorry %s, I don't have enough messages to make a comic yet.", message.UserName()))
			return
		}

		service.Typing(message.Channel())

		lines := 0
		linesString, parts := bruxism.ParseCommand(service, message)
		if len(parts) > 0 {
			lines, _ = strconv.Atoi(linesString)
		}

		if lines <= 0 {
			lines = 1 + int(math.Floor((math.Pow(2*rand.Float64()-1, 3)/2+0.5)*float64(5)))
		}

		if lines > len(log) {
			lines = len(log)
		}

		p.makeComic(bot, service, message, makeScriptFromMessages(service, message, log[len(log)-lines:]))
	} else {
		// Don't append commands.
		if bruxism.MatchesCommand(service, "", message) {
			return
		}

		switch message.Type() {
		case bruxism.MessageTypeCreate:
			if len(log) < 10 {
				log = append(log, message)
			} else {
				log = append(log[1:], message)
			}
		case bruxism.MessageTypeUpdate:
			for i, m := range log {
				if m.MessageID() == message.MessageID() {
					log[i] = message
					break
				}
			}
		case bruxism.MessageTypeDelete:
			for i, m := range log {
				if m.MessageID() == message.MessageID() {
					log = append(log[:i], log[i+1:]...)
					break
				}
			}
		}
		p.log[message.Channel()] = log
	}
}
Ejemplo n.º 7
0
// Message handler.
func (p *MusicPlugin) Message(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message) {
	defer bruxism.MessageRecover()

	if service.IsMe(message) {
		return
	}

	if !bruxism.MatchesCommand(service, "music", message) && !bruxism.MatchesCommand(service, "mu", message) {
		return
	}

	_, parts := bruxism.ParseCommand(service, message)

	if len(parts) == 0 {
		service.SendMessage(message.Channel(), strings.Join(p.Help(bot, service, message, true), "\n"))
		return
	}

	// Get the Channel (and GuildID) for this channel because it's needed in
	// a few locations below
	channel, err := p.discord.Channel(message.Channel())
	if err != nil {
		log.Println("musicplugin: fetching channel err:", err.Error())
		return
	}

	// grab pointer to this channels voice connection, if exists.
	vc, vcok := p.VoiceConnections[channel.GuildID]

	switch parts[0] {

	case "help":
		// display extended help information
		service.SendMessage(message.Channel(), strings.Join(p.Help(bot, service, message, true), "\n"))

	case "stats":
		// TODO: maybe provide plugin stats, total channels, total song queues, etc

	case "join":
		if !service.IsBotOwner(message) {
			service.SendMessage(message.Channel(), "Sorry, only bot owner can join, please ask him to run this command.")
			return
		}
		// join the voice channel of the caller or the provided channel ID

		channelID := ""
		if len(parts) > 1 {
			channelID = parts[1]
		}

		if channelID == "" {
			messageUserID := message.UserID()
			for _, g := range p.discord.Guilds() {
				for _, v := range g.VoiceStates {
					if v.UserID == messageUserID {
						channelID = v.ChannelID
					}
				}
			}

			if channelID == "" {
				service.SendMessage(message.Channel(), "I couldn't find you in any voice channels, please join one.")
				return
			}
		}

		_, err := p.join(channelID)
		if err != nil {
			service.SendMessage(message.Channel(), err.Error())
			break
		}

		service.SendMessage(message.Channel(), "Now, let's play some music!")

	case "leave":
		// leave voice channel for this Guild
		if !service.IsBotOwner(message) {
			service.SendMessage(message.Channel(), "Sorry, only bot owner can leave, please ask him to run this command.")
			return
		}

		if !vcok {
			service.SendMessage(message.Channel(), "There is no voice connection for this Guild.")
		}

		vc.conn.Close()
		delete(p.VoiceConnections, channel.GuildID)
		service.SendMessage(message.Channel(), "Closed voice connection.")

	case "debug":
		// enable or disable debug

		if !vcok {
			service.SendMessage(message.Channel(), fmt.Sprintf("There is no voice connection for this Guild."))
		}

		vc.Lock()
		vc.debug = !vc.debug
		service.SendMessage(message.Channel(), fmt.Sprintf("debug mode set to %v", vc.debug))
		vc.Unlock()

	case "play":
		// Start queue player and optionally enqueue provided songs

		p.gostart(vc)

		for _, v := range parts[1:] {
			url, err := url.Parse(v) // doesn't check much..
			if err != nil {
				continue
			}
			err = p.enqueue(vc, url.String(), service, message)
			if err != nil {
				// TODO: Might need improving.
				service.SendMessage(message.Channel(), err.Error())
			}
		}

	case "stop":
		// stop the queue player

		if vc.close != nil {
			close(vc.close)
			vc.close = nil
		}

		if vc.control != nil {
			close(vc.control)
			vc.control = nil
		}

	case "skip":
		// skip current song

		if vc.control == nil {
			return
		}
		vc.control <- Skip

	case "pause":
		// pause the queue player
		if vc.control == nil {
			return
		}
		vc.control <- Pause

	case "resume":
		// resume the queue player
		if vc.control == nil {
			return
		}
		vc.control <- Resume

	case "info":
		// report player settings, queue info, and current song

		msg := fmt.Sprintf("`Bruxism MusicPlugin:`\n")
		msg += fmt.Sprintf("`Voice Channel:` %s\n", vc.ChannelID)
		msg += fmt.Sprintf("`Queue Size:` %d\n", len(vc.Queue))

		if vc.playing == nil {
			service.SendMessage(message.Channel(), msg)
			break
		}

		msg += fmt.Sprintf("`Now Playing:`\n")
		msg += fmt.Sprintf("`ID:` %s\n", vc.playing.ID)
		msg += fmt.Sprintf("`Title:` %s\n", vc.playing.Title)
		msg += fmt.Sprintf("`Duration:` %ds\n", vc.playing.Duration)
		msg += fmt.Sprintf("`Remaining:` %ds\n", vc.playing.Remaining)
		msg += fmt.Sprintf("`Source URL:` <%s>\n", vc.playing.URL)
		msg += fmt.Sprintf("`Thumbnail:` %s\n", vc.playing.Thumbnail)
		service.SendMessage(message.Channel(), msg)

	case "list":
		// list top items in the queue

		if len(vc.Queue) == 0 {
			service.SendMessage(message.Channel(), "The music queue is empty.")
			return
		}

		var msg string

		i := 1
		i2 := 0
		for k, v := range vc.Queue {
			np := ""
			if vc.playing != nil && *vc.playing == v {
				np = "**(Now Playing)**"
			}
			d := time.Duration(v.Duration) * time.Second
			msg += fmt.Sprintf("`%.3d:%.15s` **%s** [%s] - *%s* %s\n", k, v.ID, v.Title, d.String(), v.AddedBy, np)

			if i >= 15 {
				service.SendMessage(message.Channel(), msg)
				msg = ""
				i = 0
				i2++

				if i2 >= 8 {
					// limit response to 8 messages (120 songs)
					return
				}
			}
			i++
		}

		service.SendMessage(message.Channel(), msg)

	case "clear":
		// clear all items from the queue
		vc.Lock()
		vc.Queue = []song{}
		vc.Unlock()

	default:
		service.SendMessage(message.Channel(), "Unknown music command, try `help music`")
	}
}
Ejemplo n.º 8
0
func (p *chartPlugin) messageFunc(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message) {
	if service.IsMe(message) {
		return
	}

	if bruxism.MatchesCommand(service, "chart", message) {
		query, parts := bruxism.ParseCommand(service, message)
		if len(parts) == 0 {
			service.SendMessage(message.Channel(), fmt.Sprintf("Invalid chart eg: %s", p.randomChart(service)))
			return
		}

		start, end := 0.5, 0.5

		switch parts[0] {
		case "up":
			start, end = 0, 1
		case "down":
			start, end = 1, 0
		case "flat":
		case "straight":
		default:
			service.SendMessage(message.Channel(), fmt.Sprintf("Invalid chart direction. eg: %s", p.randomChart(service)))
			return
		}

		axes := strings.Split(query[len(parts[0]):], ",")
		if len(axes) != 2 {
			service.SendMessage(message.Channel(), fmt.Sprintf("Invalid chart axis labels eg: %s", p.randomChart(service)))
			return
		}

		pl, err := plot.New()
		if err != nil {
			service.SendMessage(message.Channel(), fmt.Sprintf("Error making chart, sorry! eg: %s", p.randomChart(service)))
			return
		}

		service.Typing(message.Channel())

		pl.Y.Label.Text = axes[0]
		pl.X.Label.Text = axes[1]

		num := 5 + rand.Intn(15)

		start *= float64(num)
		end *= float64(num)

		pts := make(plotter.XYs, num)
		for i := range pts {
			pts[i].X = float64(i) + rand.Float64()*0.5 - 0.2
			pts[i].Y = start + float64(end-start)/float64(num-1)*float64(i) + rand.Float64()*0.5 - 0.25
		}

		pl.X.Tick.Label.Color = color.Transparent
		pl.Y.Tick.Label.Color = color.Transparent

		pl.X.Min = -0.5
		pl.X.Max = float64(num) + 0.5

		pl.Y.Min = -0.5
		pl.Y.Max = float64(num) + 0.5

		lpLine, lpPoints, err := plotter.NewLinePoints(pts)
		if err != nil {
			service.SendMessage(message.Channel(), fmt.Sprintf("Sorry %s, there was a problem creating your chart.", message.UserName()))
		}
		lpLine.Color = plotutil.Color(rand.Int())
		lpLine.Width = vg.Points(1 + 0.5*rand.Float64())
		lpLine.Dashes = plotutil.Dashes(rand.Int())
		lpPoints.Shape = plotutil.Shape(rand.Int())
		lpPoints.Color = lpLine.Color

		pl.Add(lpLine, lpPoints)

		w, err := pl.WriterTo(320, 240, "png")
		if err != nil {
			service.SendMessage(message.Channel(), fmt.Sprintf("Sorry %s, there was a problem creating your chart.", message.UserName()))
			return
		}

		b := &bytes.Buffer{}
		w.WriteTo(b)

		go func() {
			if service.Name() == bruxism.DiscordServiceName {
				discord := service.(*bruxism.Discord)
				p, err := discord.UserChannelPermissions(message.UserID(), message.Channel())
				if err == nil && p&discordgo.PermissionAttachFiles != 0 {
					service.SendFile(message.Channel(), "chart.png", b)
					return
				}
			}

			url, err := bot.UploadToImgur(b, "chart.png")
			if err != nil {
				service.SendMessage(message.Channel(), fmt.Sprintf("Sorry %s, there was a problem uploading the chart to imgur.", message.UserName()))
				log.Println("Error uploading chart: ", err)
				return
			}

			if service.Name() == bruxism.DiscordServiceName {
				service.SendMessage(message.Channel(), fmt.Sprintf("Here's your chart <@%s>: %s", message.UserID(), url))
			} else {
				service.SendMessage(message.Channel(), fmt.Sprintf("Here's your chart %s: %s", message.UserName(), url))
			}
		}()
	}
}
Ejemplo n.º 9
0
// Message handler.
func (p *triviaPlugin) Message(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message) {
	defer bruxism.MessageRecover()
	if !service.IsMe(message) && !service.IsPrivate(message) {
		messageChannel := message.Channel()

		isCommand := bruxism.MatchesCommand(service, "trivia", message)

		if isCommand && (service.IsModerator(message) || service.IsBotOwner(message)) {
			p.Lock()
			tc := p.Channels[messageChannel]
			if tc == nil {
				tc = &triviaChannel{
					Channel: messageChannel,
					Scores:  map[string]*triviaScore{},
				}
				p.Channels[messageChannel] = tc
			}
			p.Unlock()

			_, parts := bruxism.ParseCommand(service, message)

			if len(parts) == 0 {
				return
			}

			switch parts[0] {
			case "start":
				theme := ""
				if len(parts) >= 2 {
					theme = parts[1]
				}
				tc.Start(bot, service, theme)
			case "stop":
				tc.Stop(bot, service)
			}

		} else {
			if isCommand {
				_, parts := bruxism.ParseCommand(service, message)
				if len(parts) == 0 {
					return
				}
				if parts[0] == "score" {
					p.RLock()
					tc := p.Channels[messageChannel]

					if tc != nil {
						ts := tc.Scores[message.UserID()]
						if ts != nil {
							service.SendMessage(message.Channel(), fmt.Sprintf("%s's score is %d.", message.UserName(), ts.Score))
						} else {
							service.SendMessage(message.Channel(), fmt.Sprintf("%s's score is 0.", message.UserName()))
						}
					}

					p.RUnlock()
				}

				return
			}

			p.RLock()
			tc := p.Channels[messageChannel]
			p.RUnlock()
			if tc != nil {
				tc.Message(bot, service, message)
			}
		}
	}
}