mirror of
https://github.com/mgerb/ServerStatus
synced 2026-01-09 18:52:50 +00:00
feat: new features/improvements
- update dependencies - add up/down time #14 - add workers with retry to help with spam
This commit is contained in:
@@ -1,12 +1,14 @@
|
||||
package serverstatus
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/anvie/port-scanner"
|
||||
portscanner "github.com/anvie/port-scanner"
|
||||
"github.com/bwmarrin/discordgo"
|
||||
steam "github.com/kidoman/go-steam"
|
||||
"github.com/mgerb/ServerStatus/bot"
|
||||
@@ -24,6 +26,8 @@ func Start() {
|
||||
//set each server status as online to start
|
||||
for i := range config.Config.Servers {
|
||||
config.Config.Servers[i].Online = true
|
||||
config.Config.Servers[i].OnlineTimestamp = time.Now()
|
||||
config.Config.Servers[i].OfflineTimestamp = time.Now()
|
||||
}
|
||||
|
||||
err := bot.Session.UpdateStatus(0, config.Config.GameStatus)
|
||||
@@ -48,49 +52,74 @@ func scanServers() {
|
||||
|
||||
for {
|
||||
|
||||
for index, server := range config.Config.Servers {
|
||||
prevServerUp := server.Online //set value to previous server status
|
||||
// use waitgroup to scan all servers concurrently
|
||||
var wg sync.WaitGroup
|
||||
|
||||
serverScanner := portscanner.NewPortScanner(server.Address, time.Second*2, 1)
|
||||
serverUp := serverScanner.IsOpen(server.Port) //check if the port is open
|
||||
|
||||
// if server isn't up check RCON protocol (UDP)
|
||||
if !serverUp {
|
||||
host := server.Address + ":" + strconv.Itoa(server.Port)
|
||||
steamConnection, err := steam.Connect(host)
|
||||
if err == nil {
|
||||
defer steamConnection.Close()
|
||||
_, err := steamConnection.Ping()
|
||||
if err == nil {
|
||||
serverUp = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if serverUp && serverUp != prevServerUp {
|
||||
sendMessageToRooms(green, server.Name, "Is now online :smiley:", true)
|
||||
} else if !serverUp && serverUp != prevServerUp {
|
||||
sendMessageToRooms(red, server.Name, "Has gone offline :frowning2:", true)
|
||||
}
|
||||
|
||||
config.Config.Servers[index].Online = serverUp
|
||||
for index := range config.Config.Servers {
|
||||
wg.Add(1)
|
||||
go worker(index, &config.Config.Servers[index], &wg)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
time.Sleep(time.Second * config.Config.PollingInterval)
|
||||
}
|
||||
}
|
||||
|
||||
func worker(index int, server *config.Server, wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
|
||||
prevServerUp := server.Online //set value to previous server status
|
||||
|
||||
var serverUp bool
|
||||
retryCounter := 0
|
||||
|
||||
// try reconnecting 5 times if failure persists (every 2 seconds)
|
||||
for {
|
||||
serverScanner := portscanner.NewPortScanner(server.Address, time.Second*2, 1)
|
||||
serverUp = serverScanner.IsOpen(server.Port) //check if the port is open
|
||||
if serverUp || retryCounter >= 5 {
|
||||
break
|
||||
}
|
||||
retryCounter++
|
||||
time.Sleep(time.Second * 2)
|
||||
}
|
||||
|
||||
// if server isn't up check RCON protocol (UDP)
|
||||
if !serverUp {
|
||||
host := server.Address + ":" + strconv.Itoa(server.Port)
|
||||
steamConnection, err := steam.Connect(host)
|
||||
if err == nil {
|
||||
defer steamConnection.Close()
|
||||
_, err := steamConnection.Ping()
|
||||
if err == nil {
|
||||
serverUp = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if serverUp && serverUp != prevServerUp {
|
||||
server.OnlineTimestamp = time.Now()
|
||||
sendMessageToRooms(green, server.Name, "Is now online :smiley:", true)
|
||||
} else if !serverUp && serverUp != prevServerUp {
|
||||
server.OfflineTimestamp = time.Now()
|
||||
sendMessageToRooms(red, server.Name, "Has gone offline :frowning2:", true)
|
||||
}
|
||||
|
||||
server.Online = serverUp
|
||||
}
|
||||
|
||||
func sendMessageToRooms(color int, title, description string, mentionRoles bool) {
|
||||
for _, roomID := range config.Config.RoomIDList {
|
||||
if mentionRoles {
|
||||
content := strings.Join(config.Config.RolesToNotify, " ")
|
||||
bot.Session.ChannelMessageSend(roomID, content)
|
||||
}
|
||||
sendEmbededMessage(roomID, color, title, description)
|
||||
sendEmbeddedMessage(roomID, color, title, description)
|
||||
}
|
||||
}
|
||||
|
||||
func sendEmbededMessage(roomID string, color int, title, description string) {
|
||||
func sendEmbeddedMessage(roomID string, color int, title, description string) {
|
||||
|
||||
embed := &discordgo.MessageEmbed{
|
||||
Color: color,
|
||||
@@ -110,13 +139,23 @@ func MessageHandler(s *discordgo.Session, m *discordgo.MessageCreate) {
|
||||
return
|
||||
}
|
||||
|
||||
if m.Content == "!ServerStatus" {
|
||||
if m.Content == config.Config.BotPrefix+"ServerStatus" {
|
||||
for _, server := range config.Config.Servers {
|
||||
if server.Online {
|
||||
sendEmbededMessage(m.ChannelID, green, server.Name, "Online!")
|
||||
sendEmbeddedMessage(m.ChannelID, green, server.Name, "Online!\nUptime: "+fmtDuration(time.Since(server.OnlineTimestamp)))
|
||||
} else {
|
||||
sendEmbededMessage(m.ChannelID, red, server.Name, "Offline!")
|
||||
sendEmbeddedMessage(m.ChannelID, red, server.Name, "Offline!\nDowntime: "+fmtDuration(time.Since(server.OfflineTimestamp)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func fmtDuration(d time.Duration) string {
|
||||
|
||||
days := int(d.Hours()) / 24
|
||||
hours := int(d.Hours()) % 60
|
||||
minutes := int(d.Minutes()) % 60
|
||||
seconds := int(d.Seconds()) % 60
|
||||
|
||||
return fmt.Sprintf("%dd %dh %dm %ds", days, hours, minutes, seconds)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user