Skip to content
This repository has been archived by the owner on Jan 20, 2021. It is now read-only.

Commit

Permalink
Merge pull request #90 from GabrielPlassard/master
Browse files Browse the repository at this point in the history
Add support for !shuffle, !shuffleon and !shuffleoff commands #39
  • Loading branch information
matthieugrieger committed Oct 12, 2015
2 parents a1b9575 + 5e6b72c commit ae61d8c
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 23 deletions.
51 changes: 51 additions & 0 deletions commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,31 @@ func parseCommand(user *gumble.User, username, command string) {
} else {
dj.SendPrivateMessage(user, NO_PERMISSION_MSG)
}

// Shuffle command
case dj.conf.Aliases.ShuffleAlias:
if dj.HasPermission(username, dj.conf.Permissions.AdminShuffle) {
shuffleSongs(user, username)
} else {
dj.SendPrivateMessage(user, NO_PERMISSION_MSG)
}

// Shuffleon command
case dj.conf.Aliases.ShuffleOnAlias:
if dj.HasPermission(username, dj.conf.Permissions.AdminShuffleToggle) {
toggleAutomaticShuffle(true, user, username)
} else {
dj.SendPrivateMessage(user, NO_PERMISSION_MSG)
}

// Shuffleoff command
case dj.conf.Aliases.ShuffleOffAlias:
if dj.HasPermission(username, dj.conf.Permissions.AdminShuffleToggle) {
toggleAutomaticShuffle(false, user, username)
} else {
dj.SendPrivateMessage(user, NO_PERMISSION_MSG)
}

default:
dj.SendPrivateMessage(user, COMMAND_DOESNT_EXIST_MSG)
}
Expand Down Expand Up @@ -391,3 +416,29 @@ func deleteSongs() error {
}
return nil
}

// shuffles the song list
func shuffleSongs(user *gumble.User, username string) {
if dj.queue.Len() > 1 {
dj.queue.ShuffleSongs()
dj.client.Self.Channel.Send(fmt.Sprintf(SHUFFLE_SUCCESS_MSG, username), false)
} else {
dj.SendPrivateMessage(user, CANT_SHUFFLE_MSG)
}
}

// handles toggling of automatic shuffle playing
func toggleAutomaticShuffle(activate bool, user *gumble.User, username string){
if (dj.conf.General.AutomaticShuffleOn != activate){
dj.conf.General.AutomaticShuffleOn = activate
if (activate){
dj.client.Self.Channel.Send(fmt.Sprintf(SHUFFLE_ON_MESSAGE, username), false)
} else{
dj.client.Self.Channel.Send(fmt.Sprintf(SHUFFLE_OFF_MESSAGE, username), false)
}
} else if (activate){
dj.SendPrivateMessage(user, SHUFFLE_ACTIVATED_ERROR_MESSAGE)
} else{
dj.SendPrivateMessage(user, SHUFFLE_DEACTIVATED_ERROR_MESSAGE)
}
}
26 changes: 25 additions & 1 deletion config.gcfg
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ DefaultComment = "Hello! I am a bot. Type !help for a list of commands."
# Default Value: 0
MaxSongDuration = 0

# Is playlist shuffling enabled when the bot starts?
# Default Value: false
AutomaticShuffleOn = false

[Cache]

# Cache songs as they are downloaded?
Expand Down Expand Up @@ -55,7 +59,7 @@ LowestVolume = 0.01
# DEFAULT VALUE: 0.8
HighestVolume = 0.8


[Aliases]

# Alias used for add command
Expand Down Expand Up @@ -126,6 +130,17 @@ CacheSizeAlias = "cachesize"
# DEFAULT VALUE: "kill"
KillAlias = "kill"

# Alias used for shuffle command
# DEFAULT VALUE: "shuffle"
ShuffleAlias = "shuffle"

# Alias used for shuffleon command
# DEFAULT VALUE: "shuffleon"
ShuffleOnAlias = "shuffleon"

# Alias used for shuffleoff command
# DEFAULT VALUE: "shuffleoff"
ShuffleOffAlias = "shuffleoff"

[Permissions]

Expand Down Expand Up @@ -201,3 +216,12 @@ AdminCacheSize = true
# Make kill an admin command?
# DEFAULT VALUE: true (I recommend never changing this to false)
AdminKill = true

# Make shuffle an admin command?
# DEFAULT VALUE: true
AdminShuffle = true


# Make shuffleon and shuffleoff admin commands?
# DEFAULT VALUE: true
AdminShuffleToggle = true
50 changes: 28 additions & 22 deletions parseconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ import (
// DjConfig is a Golang struct representation of mumbledj.gcfg file structure for parsing.
type DjConfig struct {
General struct {
CommandPrefix string
SkipRatio float32
PlaylistSkipRatio float32
DefaultComment string
MaxSongDuration int
CommandPrefix string
SkipRatio float32
PlaylistSkipRatio float32
DefaultComment string
MaxSongDuration int
AutomaticShuffleOn bool
}
Cache struct {
Enabled bool
Expand Down Expand Up @@ -51,25 +52,30 @@ type DjConfig struct {
NumCachedAlias string
CacheSizeAlias string
KillAlias string
ShuffleAlias string
ShuffleOnAlias string
ShuffleOffAlias string
}
Permissions struct {
AdminsEnabled bool
Admins []string
AdminAdd bool
AdminAddPlaylists bool
AdminSkip bool
AdminHelp bool
AdminVolume bool
AdminMove bool
AdminReload bool
AdminReset bool
AdminNumSongs bool
AdminNextSong bool
AdminCurrentSong bool
AdminSetComment bool
AdminNumCached bool
AdminCacheSize bool
AdminKill bool
AdminsEnabled bool
Admins []string
AdminAdd bool
AdminAddPlaylists bool
AdminSkip bool
AdminHelp bool
AdminVolume bool
AdminMove bool
AdminReload bool
AdminReset bool
AdminNumSongs bool
AdminNextSong bool
AdminCurrentSong bool
AdminSetComment bool
AdminNumCached bool
AdminCacheSize bool
AdminKill bool
AdminShuffle bool
AdminShuffleToggle bool
}
}

Expand Down
3 changes: 3 additions & 0 deletions service.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ func FindServiceAndAdd(user *gumble.User, url string) error {

// Starts playing the new song if nothing else is playing
if oldLength == 0 && dj.queue.Len() != 0 && !dj.audioStream.IsPlaying() {
if (dj.conf.General.AutomaticShuffleOn){
dj.queue.RandomNextSong(true)
}
if err := dj.queue.CurrentSong().Download(); err == nil {
dj.queue.CurrentSong().Play()
} else {
Expand Down
27 changes: 27 additions & 0 deletions songqueue.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,13 @@ import (
"errors"
"fmt"
"time"
"math/rand"
)

func init() {
rand.Seed(time.Now().UTC().UnixNano())
}

// SongQueue type declaration.
type SongQueue struct {
queue []Song
Expand Down Expand Up @@ -59,6 +64,9 @@ func (q *SongQueue) NextSong() {
// PeekNext peeks at the next Song and returns it.
func (q *SongQueue) PeekNext() (Song, error) {
if q.Len() > 1 {
if dj.conf.General.AutomaticShuffleOn{ //Shuffle mode is active
q.RandomNextSong(false)
}
return q.queue[1], nil
}
return nil, errors.New("There isn't a Song coming up next.")
Expand Down Expand Up @@ -104,3 +112,22 @@ func (q *SongQueue) PrepareAndPlayNextSong() {
q.OnSongFinished()
}
}

// Shuffles the songqueue using inside-out algorithm
func (q *SongQueue) ShuffleSongs() {
for i := range q.queue[1:] { //Don't touch currently playing song
j := rand.Intn(i + 1)
q.queue[i + 1], q.queue[j + 1] = q.queue[j + 1], q.queue[i + 1]
}
}

// Sets a random song as next song to be played
// queueWasEmpty wether the queue was empty before adding the last song
func (q *SongQueue) RandomNextSong(queueWasEmpty bool){
nextSongIndex := 1
if queueWasEmpty{
nextSongIndex = 0
}
swapIndex := nextSongIndex + rand.Intn(q.Len())
q.queue[nextSongIndex], q.queue[swapIndex] = q.queue[swapIndex], q.queue[nextSongIndex]
}
21 changes: 21 additions & 0 deletions strings.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,24 @@ const CACHE_SIZE_MSG = "The cache is currently %g MB in size."
// Message shown to user when they attempt to issue a cache-related command when caching is not enabled.
const CACHE_NOT_ENABLED_MSG = "The cache is not currently enabled."

// Message shown to user when they attempt to shuffle the queue and it has less than 2 elements.
const CANT_SHUFFLE_MSG = "Can't shuffle the queue if there is less than 2 songs."

// Message shown to users when the songqueue has been successfully shuffled.
const SHUFFLE_SUCCESS_MSG = "The current songqueue has been successfully shuffled by <b>%s</b> (starting from next song)."

// Message shown to users when automatic shuffle is activated
const SHUFFLE_ON_MESSAGE = "<b>%s</b> has turned automatic shuffle on."

// Message shown to users when automatic shuffle is deactivated
const SHUFFLE_OFF_MESSAGE = "<b>%s</b> has turned automatic shuffle off."

// Message shown to user when they attempt to enable automatic shuffle while it's already activated
const SHUFFLE_ACTIVATED_ERROR_MESSAGE = "Automatic shuffle is already activated."

// Message shown to user when they attempt to disable automatic shuffle while it's already deactivated
const SHUFFLE_DEACTIVATED_ERROR_MESSAGE = "Automatic shuffle is already deactivated."

// Message shown to channel when a song is added to the queue by a user.
const SONG_ADDED_HTML = `
<b>%s</b> has added "%s" to the queue.
Expand Down Expand Up @@ -107,6 +125,9 @@ const HELP_HTML = `<br/>
<p><b>!reset</b> - An admin command that resets the song queue. </p>
<p><b>!forceskip</b> - An admin command that forces a song skip. </p>
<p><b>!forceskipplaylist</b> - An admin command that forces a playlist skip. </p>
<p><b>!shuffle</b> - An admin command that shuffles the current queue. </p>
<p><b>!shuffleon</b> - An admin command that enables auto shuffling.</p>
<p><b>!shuffleoff</b> - An admin command that disables auto shuffling.</p>
<p><b>!move </b>- Moves MumbleDJ into channel if it exists.</p>
<p><b>!reload</b> - Reloads mumbledj.gcfg configuration settings.</p>
<p><b>!setcomment</b> - Sets the comment for the bot.</p>
Expand Down

0 comments on commit ae61d8c

Please sign in to comment.