Passed
Push — master ( 7f7da9...d308f4 )
by Viktor
01:34
created

main.onStart   A

Complexity

Conditions 1

Size

Total Lines 6
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nop 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
package main
2
3
import (
4
	"bytes"
5
	"fmt"
6
	"net/http"
7
	"net/url"
8
	"os"
9
	"os/signal"
10
	"strings"
11
	"syscall"
12
	"time"
13
14
	"gopkg.in/robfig/cron.v2"
15
16
	"github.com/FlameInTheDark/dtbot/bot"
17
	"github.com/FlameInTheDark/dtbot/cmd"
18
	"github.com/bwmarrin/discordgo"
19
)
20
21
var (
22
	conf *bot.Config
23
	// CmdHandler bot command handler
24
	CmdHandler *bot.CommandHandler
25
	// Sessions bot session manager
26
	Sessions        *bot.SessionManager
27
	botId           string
0 ignored issues
show
introduced by
var botId should be botID
Loading history...
28
	youtube         *bot.Youtube
29
	botMsg          *bot.BotMessages
30
	dataType        *bot.DataType
31
	dbWorker        *bot.DBWorker
32
	guilds          *bot.GuildsMap
33
	botCron         *cron.Cron
34
	twitch          *bot.Twitch
35
	albUpdater      *bot.AlbionUpdater
36
	messagesCounter int
37
)
38
39
func main() {
40
	botCron = cron.New()
41
	conf = bot.LoadConfig()
42
	CmdHandler = bot.NewCommandHandler()
43
	registerCommands()
44
	Sessions = bot.NewSessionManager()
45
	youtube = &bot.Youtube{Conf: conf}
46
	botMsg = bot.NewMessagesMap()
47
	dataType = bot.NewDataType()
48
	discord, err := discordgo.New("Bot " + os.Getenv("BOT_TOKEN"))
49
	if err != nil {
50
		fmt.Println("Create session error, ", err)
51
		return
52
	}
53
	usr, err := discord.User("@me")
54
	if err != nil {
55
		fmt.Println("Error obtaining account details,", err)
56
		return
57
	}
58
	botId = usr.ID
59
	discord.AddHandler(func(discord *discordgo.Session, ready *discordgo.Ready) {
60
		_ = discord.UpdateStatus(0, conf.General.Game)
61
		guilds := discord.State.Guilds
62
		fmt.Println("Ready with", len(guilds), "guilds.")
63
	})
64
65
	err = discord.Open()
66
	if err != nil {
67
		fmt.Printf("Connection open error: %v", err)
68
		return
69
	}
70
	defer discord.Close()
71
	fmt.Println("Bot is now running.")
72
73
	sc := make(chan os.Signal, 1)
74
	signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
75
	dbWorker = bot.NewDBSession(conf.General.DatabaseName)
76
	guilds = dbWorker.InitGuilds(discord, conf)
77
	botCron.Start()
78
	defer botCron.Stop()
79
	defer dbWorker.DBSession.Close()
80
	twitch = bot.TwitchInit(discord, conf, dbWorker)
81
	albUpdater = bot.AlbionGetUpdater(dbWorker)
82
	go BotUpdater(discord)
83
	// Init command handler
84
	discord.AddHandler(guildAddHandler)
85
	discord.AddHandler(commandHandler)
86
	discord.AddHandler(joinHandler)
87
	onStart()
88
	<-sc
89
}
90
91
// Handle new users
92
func joinHandler(discord *discordgo.Session, e *discordgo.GuildMemberAdd) {
93
	if _, ok := guilds.Guilds[e.GuildID]; !ok {
94
		dbWorker.InitNewGuild(e.GuildID, conf, guilds)
95
	} else {
96
		bot.Greetings(discord, e, guilds.Guilds[e.GuildID])
97
	}
98
}
99
100
// Handle new guilds
101
func guildAddHandler(discord *discordgo.Session, e *discordgo.GuildCreate) {
102
	if _, ok := guilds.Guilds[e.ID]; !ok {
103
		dbWorker.InitNewGuild(e.ID, conf, guilds)
104
	}
105
	emb := bot.NewEmbed("").
106
		Field(conf.GetLocaleLang("bot_joined_title", guilds.Guilds[e.ID].Language), conf.GetLocaleLang("bot_joined_text", guilds.Guilds[e.ID].Language), false)
107
	_, _ = discord.ChannelMessageSendEmbed(e.OwnerID, emb.GetEmbed())
108
}
109
110
// Handle discord messages
111
func commandHandler(discord *discordgo.Session, message *discordgo.MessageCreate) {
112
	messagesCounter++
113
	user := message.Author
114
	if user.ID == botId || user.Bot {
115
		return
116
	}
117
	args := strings.Split(message.Content, " ")
118
	name := strings.ToLower(args[0])
119
	command, found := CmdHandler.Get(name)
120
	if !found {
121
		return
122
	}
123
124
	var permission = true
125
	var msg string
126
	// Checking permissions
127
	perm, err := discord.State.UserChannelPermissions(botId, message.ChannelID)
128
	if err != nil {
129
		msg = fmt.Sprintf("Error whilst getting bot permissions %v\n", err)
130
		permission = false
131
	} else {
132
		if perm&discordgo.PermissionSendMessages != discordgo.PermissionSendMessages ||
133
			perm&discordgo.PermissionAttachFiles != discordgo.PermissionAttachFiles {
134
			msg = "Permissions denied"
135
			permission = false
136
		}
137
	}
138
139
	channel, err := discord.State.Channel(message.ChannelID)
140
	if err != nil {
141
		fmt.Println("Error getting channel,", err)
142
		return
143
	}
144
	guild, err := discord.State.Guild(channel.GuildID)
145
	if err != nil {
146
		fmt.Println("Error getting guild,", err)
147
		return
148
	}
149
150
	if permission {
151
		ctx := bot.NewContext(
152
			botId,
153
			discord,
154
			guild,
155
			channel,
156
			user,
157
			message,
158
			conf,
159
			CmdHandler,
160
			Sessions,
161
			youtube,
162
			botMsg,
163
			dataType,
164
			dbWorker,
165
			guilds,
166
			botCron,
167
			twitch,
168
			albUpdater)
169
		ctx.Args = args[1:]
170
		c := *command
171
		c(*ctx)
172
	} else {
173
		dbWorker.Log("Message", guild.ID, msg)
174
		query := []byte(fmt.Sprintf("logs,server=%v module=\"%v\"", guild.ID, "message"))
175
		addr := fmt.Sprintf("%v/write?db=%v", conf.Metrics.Address, conf.Metrics.Database)
176
		r := bytes.NewReader(query)
177
		_, _ = http.Post(addr, "", r)
178
	}
179
}
180
181
// Adds bot commands
182
func registerCommands() {
183
	CmdHandler.Register("!r", cmd.RadioCommand)
184
	CmdHandler.Register("!w", cmd.WeatherCommand)
185
	CmdHandler.Register("!t", cmd.TranslateCommand)
186
	CmdHandler.Register("!n", cmd.NewsCommand)
187
	CmdHandler.Register("!c", cmd.CurrencyCommand)
188
	CmdHandler.Register("!y", cmd.YoutubeCommand)
189
	CmdHandler.Register("!v", cmd.VoiceCommand)
190
	CmdHandler.Register("!b", cmd.BotCommand)
191
	CmdHandler.Register("!play", cmd.YoutubeShortCommand)
192
	CmdHandler.Register("!d", cmd.DebugCommand)
193
	CmdHandler.Register("!p", cmd.PollCommand)
194
	CmdHandler.Register("!m", cmd.YandexmapCommand)
195
	CmdHandler.Register("!dice", cmd.DiceCommand)
196
	CmdHandler.Register("!help", cmd.HelpCommand)
197
	CmdHandler.Register("!cron", cmd.CronCommand)
198
	CmdHandler.Register("!geoip", cmd.GeoIPCommand)
199
	CmdHandler.Register("!twitch", cmd.TwitchCommand)
200
	CmdHandler.Register("!greetings", cmd.GreetingsCommand)
201
	CmdHandler.Register("!alb", cmd.AlbionCommand)
202
}
203
204
// MetricsSender sends metrics to InfluxDB and another services
0 ignored issues
show
introduced by
comment on exported function BotUpdater should be of the form "BotUpdater ..."
Loading history...
205
func BotUpdater(d *discordgo.Session) {
206
	for {
207
		go twitch.Update()
208
209
		// Calculating users count
210
		usersCount := 0
211
		for _, g := range d.State.Guilds {
212
			usersCount += g.MemberCount
213
		}
214
215
		// Metrics counters
216
		queryCounters := []byte(fmt.Sprintf("counters guilds=%v,messages=%v,users=%v", len(d.State.Guilds), messagesCounter, usersCount))
217
		addrCounters := fmt.Sprintf("%v/write?db=%v&u=%v&p=%v",
218
			conf.Metrics.Address, conf.Metrics.Database, conf.Metrics.User, conf.Metrics.Password)
219
		rCounters := bytes.NewReader(queryCounters)
220
		_, _ = http.Post(addrCounters, "", rCounters)
221
222
		// Bot lists
223
		if conf.DBL.Token != "" {
224
			sendDBL(conf.DBL.BotID, conf.DBL.Token, len(d.State.Guilds))
225
		}
226
		messagesCounter = 0
227
		time.Sleep(time.Minute)
228
	}
229
}
230
231
func sendDBL(botID, token string, guilds int) {
232
	timeout := time.Duration(time.Duration(1) * time.Second)
233
	client := &http.Client{
234
		Timeout: time.Duration(timeout),
235
	}
236
	query := url.Values{}
237
	query.Add("server_count", fmt.Sprintf("%v", guilds))
238
	req, _ := http.NewRequest("POST",
239
		fmt.Sprintf("https://discordbots.org/api/bots/%v/stats",
240
			botID), strings.NewReader(query.Encode()))
241
	req.Header.Add("Authorization", token)
242
	req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
243
	_, _ = client.Do(req)
244
}
245
246
func onStart() {
247
	queryCounters := []byte(fmt.Sprintf("starts value=1"))
248
	addrCounters := fmt.Sprintf("%v/write?db=%v&u=%v&p=%v",
249
		conf.Metrics.Address, conf.Metrics.Database, conf.Metrics.User, conf.Metrics.Password)
250
	rCounters := bytes.NewReader(queryCounters)
251
	_, _ = http.Post(addrCounters, "", rCounters)
252
}
253