Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions commands/clear.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package commands

import (
"github.com/disgoorg/disgo/discord"
"github.com/disgoorg/disgo/handler"
)

func (c *Commands) Clear(_ discord.SlashCommandInteractionData, e *handler.CommandEvent) error {
_, tracks := c.MusicQueue.Get(*e.GuildID())
if len(tracks) == 0 {
return e.CreateMessage(discord.MessageCreate{
Content: "Queue is already empty",
Flags: discord.MessageFlagEphemeral,
})
}

c.MusicQueue.Clear(*e.GuildID())

return e.CreateMessage(discord.MessageCreate{
Content: "🗑️ Cleared the queue",
})
}
4 changes: 4 additions & 0 deletions commands/disconnect.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ func (c *Commands) Disconnect(_ discord.SlashCommandInteractionData, e *handler.
ctx, cancel := context.WithTimeout(e.Ctx, 10*time.Second)
defer cancel()

player := c.Lavalink.ExistingPlayer(*e.GuildID())
if player != nil {
player.Destroy(ctx)
}
if err := c.Client.UpdateVoiceState(ctx, *e.GuildID(), nil, false, false); err != nil {
return e.CreateMessage(discord.MessageCreate{
Content: "Failed to disconnect player",
Expand Down
49 changes: 49 additions & 0 deletions commands/forward.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package commands

import (
"context"
"time"

"github.com/disgoorg/disgo/discord"
"github.com/disgoorg/disgo/handler"
"github.com/disgoorg/disgolink/v3/lavalink"

"github.com/lavalink-devs/lavalink-bot/internal/res"
)

func (c *Commands) Forward(data discord.SlashCommandInteractionData, e *handler.CommandEvent) error {
ctx, cancel := context.WithTimeout(e.Ctx, 10*time.Second)
defer cancel()
player := c.Lavalink.ExistingPlayer(*e.GuildID())

amt := data.Int("amount")
unit, ok := data.OptInt("unit")
if !ok {
unit = int(lavalink.Second)
}

cPos := int(player.State().Position)
nPos := cPos + (amt * unit)

if nPos >= int(player.Track().Info.Length) {
nPos = int(player.Track().Info.Length) - 1
}

if nPos == cPos {
return e.CreateMessage(discord.MessageCreate{
Content: "The player is already at position **`" + res.FormatDuration(lavalink.Duration(cPos)) + "`**",
Flags: discord.MessageFlagEphemeral,
})
}

if err := player.Update(ctx, lavalink.WithPosition(lavalink.Duration(nPos))); err != nil {
return e.CreateMessage(discord.MessageCreate{
Content: "Failed to forward the track.",
Flags: discord.MessageFlagEphemeral,
})
}

return e.CreateMessage(discord.MessageCreate{
Content: "⏩ Forwarded to **`" + res.FormatDuration(lavalink.Duration(nPos)) + "`**",
})
}
39 changes: 39 additions & 0 deletions commands/join.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package commands

import (
"context"
"fmt"

"github.com/disgoorg/disgo/discord"
"github.com/disgoorg/disgo/handler"
"github.com/disgoorg/snowflake/v2"
)

func (c *Commands) Join(data discord.SlashCommandInteractionData, e *handler.CommandEvent) error {
var vcID snowflake.ID

ch, ok := data.OptChannel("channel")
if ok && ch.Type == discord.ChannelTypeGuildVoice {
vcID = ch.ID
} else {
vs, ok := c.Client.Caches().VoiceState(*e.GuildID(), e.User().ID)
if !ok || vs.ChannelID == nil {
return e.CreateMessage(discord.MessageCreate{
Content: "You must be in a voice channel or mention one",
Flags: discord.MessageFlagEphemeral,
})
}
vcID = *vs.ChannelID
}

if err := c.Client.UpdateVoiceState(context.Background(), *e.GuildID(), &vcID, false, false); err != nil {
return e.CreateMessage(discord.MessageCreate{
Content: fmt.Sprintf("Failed to join voice channel: %s", err),
Flags: discord.MessageFlagEphemeral,
})
}

return e.CreateMessage(discord.MessageCreate{
Content: fmt.Sprintf("Joined <#%s>", vcID.String()),
})
}
77 changes: 77 additions & 0 deletions commands/move.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package commands

import (
"fmt"
"strconv"
"strings"

"github.com/disgoorg/disgo/discord"
"github.com/disgoorg/disgo/handler"
)

func (c *Commands) MoveAutocomplete(e *handler.AutocompleteEvent) error {
_, tracks := c.MusicQueue.Get(*e.GuildID())
if len(tracks) == 0 {
return e.AutocompleteResult(nil)
}

query := e.Data.String("from")
choices := make([]discord.AutocompleteChoice, 0, len(tracks))
for i, track := range tracks {
name := fmt.Sprintf("%d: %s - %s", i+1, track.Info.Title, track.Info.Author)
if len(name) > 100 {
name = name[:97] + "..."
}
choices = append(choices, discord.AutocompleteChoiceString{
Name: name,
Value: strconv.Itoa(i + 1),
})
}

if query != "" {
f := make([]discord.AutocompleteChoice, 0)
q := strings.ToLower(query)
for _, choice := range choices {
if strings.Contains(strings.ToLower(choice.(discord.AutocompleteChoiceString).Name), q) {
f = append(f, choice)
}
}
choices = f
}

if len(choices) > 25 {
choices = choices[:25]
}

return e.AutocompleteResult(choices)
}

func (c *Commands) Move(data discord.SlashCommandInteractionData, e *handler.CommandEvent) error {
from := data.Int("from")
to := data.Int("to")

_, tracks := c.MusicQueue.Get(*e.GuildID())
if len(tracks) < 2 {
return e.CreateMessage(discord.MessageCreate{
Content: "Queue is empty",
})
}

if from < 1 || from > len(tracks) || to < 1 || to > len(tracks) {
return e.CreateMessage(discord.MessageCreate{
Content: fmt.Sprintf("Index ust be between 1 and %d", len(tracks)),
})
}

if from == to {
return e.CreateMessage(discord.MessageCreate{
Content: "Both indexes are same",
})
}

c.MusicQueue.Move(*e.GuildID(), from-1, to-1)

return e.CreateMessage(discord.MessageCreate{
Content: fmt.Sprintf("Moved **%s** from position %d → %d", tracks[from-1].Info.Title, from, to),
})
}
12 changes: 12 additions & 0 deletions commands/music.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,18 @@ var music = discord.SlashCommandCreate{
},
},
},
discord.ApplicationCommandOptionSubCommand{
Name: "join",
Description: "Joins a voice channel",
Options: []discord.ApplicationCommandOption{
discord.ApplicationCommandOptionChannel{
Name: "channel",
Description: "The voice channel to join",
Required: false,
ChannelTypes: []discord.ChannelType{discord.ChannelTypeGuildVoice},
},
},
},
discord.ApplicationCommandOptionSubCommand{
Name: "volume",
Description: "Sets the volume of the player",
Expand Down
2 changes: 1 addition & 1 deletion commands/queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ func (c *Commands) Queue(_ discord.SlashCommandInteractionData, e *handler.Comma
_, tracks := c.MusicQueue.Get(*e.GuildID())
if len(tracks) == 0 {
return e.CreateMessage(discord.MessageCreate{
Content: fmt.Sprintf("No tracks in queue"),
Content: "No tracks in queue",
})
}

Expand Down
69 changes: 69 additions & 0 deletions commands/remove.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package commands

import (
"fmt"
"strconv"
"strings"

"github.com/disgoorg/disgo/discord"
"github.com/disgoorg/disgo/handler"
)

func (c *Commands) RemoveAutocomplete(e *handler.AutocompleteEvent) error {
_, tracks := c.MusicQueue.Get(*e.GuildID())
if len(tracks) == 0 {
return e.AutocompleteResult(nil)
}

query := e.Data.String("index")
choices := make([]discord.AutocompleteChoice, 0, len(tracks))
for i, track := range tracks {
name := fmt.Sprintf("%d: %s - %s", i+1, track.Info.Title, track.Info.Author)
if len(name) > 100 {
name = name[:97] + "..."
}
choices = append(choices, discord.AutocompleteChoiceString{
Name: name,
Value: strconv.Itoa(i + 1),
})
}
if query != "" {
f := make([]discord.AutocompleteChoice, 0)
q := strings.ToLower(query)
for _, choice := range choices {
choiceName := choice.(discord.AutocompleteChoiceString).Name
if strings.Contains(strings.ToLower(choiceName), q) {
f = append(f, choice)
}
}
choices = f
}
if len(choices) > 25 {
choices = choices[:25]
}

return e.AutocompleteResult(choices)
}

func (c *Commands) Remove(data discord.SlashCommandInteractionData, e *handler.CommandEvent) error {
index := int(data.Int("index"))

_, tracks := c.MusicQueue.Get(*e.GuildID())
if len(tracks) == 0 {
return e.CreateMessage(discord.MessageCreate{
Content: "Queue is empty",
})
}

if index < 1 || index > len(tracks) {
return e.CreateMessage(discord.MessageCreate{
Content: fmt.Sprintf("Index must be between 1 and %d", len(tracks)),
})
}

c.MusicQueue.Remove(*e.GuildID(), index-1, index)

return e.CreateMessage(discord.MessageCreate{
Content: fmt.Sprintf("🗑️ Removed track from **#%d** queue", index),
})
}
27 changes: 27 additions & 0 deletions commands/restart.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package commands

import (
"context"
"time"

"github.com/disgoorg/disgo/discord"
"github.com/disgoorg/disgo/handler"
"github.com/disgoorg/disgolink/v3/lavalink"
)

func (c *Commands) Restart(_ discord.SlashCommandInteractionData, e *handler.CommandEvent) error {
ctx, cancel := context.WithTimeout(e.Ctx, 10*time.Second)
defer cancel()
player := c.Lavalink.ExistingPlayer(*e.GuildID())

if err := player.Update(ctx, lavalink.WithPosition(0)); err != nil {
return e.CreateMessage(discord.MessageCreate{
Content: "Failed to restart the track.",
Flags: discord.MessageFlagEphemeral,
})
}

return e.CreateMessage(discord.MessageCreate{
Content: "🔄 Replaying the current track.",
})
}
49 changes: 49 additions & 0 deletions commands/rewind.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package commands

import (
"context"
"time"

"github.com/disgoorg/disgo/discord"
"github.com/disgoorg/disgo/handler"
"github.com/disgoorg/disgolink/v3/lavalink"

"github.com/lavalink-devs/lavalink-bot/internal/res"
)

func (c *Commands) Rewind(data discord.SlashCommandInteractionData, e *handler.CommandEvent) error {
ctx, cancel := context.WithTimeout(e.Ctx, 10*time.Second)
defer cancel()
player := c.Lavalink.ExistingPlayer(*e.GuildID())

amt := data.Int("amount")
unit, ok := data.OptInt("unit")
if !ok {
unit = int(lavalink.Second)
}

cPos := int(player.State().Position)
nPos := cPos - (amt * unit)

if nPos < 0 {
nPos = 0
}

if nPos == cPos {
return e.CreateMessage(discord.MessageCreate{
Content: "The player is already at position **`" + res.FormatDuration(lavalink.Duration(cPos)) + "`**",
Flags: discord.MessageFlagEphemeral,
})
}

if err := player.Update(ctx, lavalink.WithPosition(lavalink.Duration(nPos))); err != nil {
return e.CreateMessage(discord.MessageCreate{
Content: "Failed to rewind the track.",
Flags: discord.MessageFlagEphemeral,
})
}

return e.CreateMessage(discord.MessageCreate{
Content: "⏪ Rewound to `" + res.FormatDuration(lavalink.Duration(nPos)) + "`",
})
}
5 changes: 4 additions & 1 deletion commands/seek.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,16 @@ func (c *Commands) Seek(data discord.SlashCommandInteractionData, e *handler.Com
}

newPosition := lavalink.Duration(position * duration)
if newPosition < 0 {
newPosition = 0
}
if err := player.Update(ctx, lavalink.WithPosition(newPosition)); err != nil {
return e.CreateMessage(discord.MessageCreate{
Content: "Failed to seek to position",
})
}

return e.CreateMessage(discord.MessageCreate{
Content: fmt.Sprintf("Seeked to %s", res.FormatDuration(newPosition)),
Content: fmt.Sprintf("Seeked to **`%s`**", res.FormatDuration(newPosition)),
})
}
Loading