diff --git a/internal/exts/arcon/arcon.go b/internal/exts/arcon/arcon.go new file mode 100644 index 0000000..0d58e16 --- /dev/null +++ b/internal/exts/arcon/arcon.go @@ -0,0 +1,92 @@ +package arcon + +import ( + "fmt" + "strings" + + "github.com/dustinpianalto/disgoman" + "github.com/dustinpianalto/geeksbot" + "github.com/dustinpianalto/geeksbot/internal/discord_utils" + "github.com/dustinpianalto/geeksbot/pkg/services" + "github.com/gorcon/rcon" +) + +var listplayersCommand = &disgoman.Command{ + Name: "request", + Aliases: nil, + Description: "Submit a request for the guild staff", + OwnerOnly: false, + Hidden: false, + RequiredPermissions: 0, + Invoke: listplayersCommandFunc, +} + +func listplayersCommandFunc(ctx disgoman.Context, args []string) { + guild, err := services.GuildService.GetOrCreateGuild(ctx.Guild.ID) + if err != nil { + discord_utils.SendErrorMessage(ctx, "Error getting Guild from the database", err) + return + } + author, err := services.UserService.GetOrCreateUser(ctx.Message.Author.ID) + if err != nil { + discord_utils.SendErrorMessage(ctx, "Sorry, there was a problem getting your user.", err) + return + } + if !discord_utils.IsGuildAdmin(ctx, author) && !discord_utils.IsGuildMod(ctx, author) { + return + } + if len(args) == 0 { + servers, err := services.ServerService.GuildServers(guild) + if err != nil { + discord_utils.SendErrorMessage(ctx, "Could not find any servers for this guild", err) + return + } + for _, server := range servers { + go listplayers(ctx, server) + } + } +} + +func listplayers(ctx disgoman.Context, server geeksbot.Server) { + msg, err := ctx.Send(fmt.Sprintf("**Getting data for %s**", server.Name)) + if err != nil { + discord_utils.SendErrorMessage(ctx, "There was an error getting the player list", err) + return + } + conn, err := rcon.Dial(fmt.Sprintf("%s:%d", server.IPAddr, server.Port), server.Password) + if err != nil { + _, _ = ctx.Session.ChannelMessageEdit(ctx.Channel.ID, msg.ID, + fmt.Sprintf("**Could not open connection to %s**", server.Name), + ) + return + } + defer conn.Close() + response, err := conn.Execute("listplayers") + if err != nil { + _, _ = ctx.Session.ChannelMessageEdit(ctx.Channel.ID, msg.ID, + fmt.Sprintf("**There was a problem getting a response from %s**", server.Name), + ) + return + } + if strings.HasPrefix(response, "No Players") { + _, _ = ctx.Session.ChannelMessageEdit(ctx.Channel.ID, msg.ID, + fmt.Sprintf("**%s: %s**", server.Name, response), + ) + return + } + players := strings.Split(response, "\n") + for i, player := range players { + parts := strings.Split(player, ", ") + steamID := parts[len(parts)-1] + user, err := services.UserService.GetBySteamID(steamID) + if err == nil { + duser, err := ctx.Session.GuildMember(ctx.Guild.ID, user.ID) + if err == nil { + players[i] = fmt.Sprintf("%s (%s)", player, duser.Mention()) + } + } + } + _, _ = ctx.Session.ChannelMessageEdit(ctx.Channel.ID, msg.ID, + fmt.Sprintf("**%s:**\n%s", server.Name, strings.Join(players, "\n")), + ) +} diff --git a/pkg/database/user.go b/pkg/database/user.go index 66fc344..c578aeb 100644 --- a/pkg/database/user.go +++ b/pkg/database/user.go @@ -49,3 +49,14 @@ func (s userService) GetOrCreateUser(id string) (geeksbot.User, error) { } return user, err } + +func (s userService) GetBySteamID(steamID string) (geeksbot.User, error) { + var id string + queryString := "SELECT id FROM users WHERE steam_id = $1" + err := s.db.QueryRow(queryString, steamID).Scan(&id) + if err != nil { + return geeksbot.User{}, err + } + user, err := s.User(id) + return user, err +} diff --git a/user.go b/user.go index 896ec01..31f31c1 100644 --- a/user.go +++ b/user.go @@ -16,4 +16,5 @@ type UserService interface { DeleteUser(u User) error UpdateUser(u User) (User, error) GetOrCreateUser(id string) (User, error) + GetBySteamID(steamID string) (User, error) }