Skip to content
Merged
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
2 changes: 1 addition & 1 deletion internal/infra/ws/servewebsockets.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (w WSHandler) websocketHandler(user auth.User, res http.ResponseWriter, req
return
}

userSocket := messages.NewUserSocket(newSocketClient(conn), user)
userSocket := messages.NewUserClient(newSocketClient(conn), user)
err = room.Hub().Register(userSocket)
if err != nil {
http.Error(res, feelbeaterror.RoomNotFound, feelbeaterror.StatusCode(feelbeaterror.RoomNotFound))
Expand Down
4 changes: 4 additions & 0 deletions internal/infra/ws/wshub.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ func (h *WSHub) passMessages(ctx context.Context, wg *sync.WaitGroup, from strin

func decodeMessage(from string, msgType string, payload []byte) messages.ClientMessage {
var settingsUpdate messages.SettingsUpdatePayload
var guess messages.GuessSongPayload

var err error
var result interface{}
Expand All @@ -153,6 +154,9 @@ func decodeMessage(from string, msgType string, payload []byte) messages.ClientM
result = settingsUpdate
case messages.ReadyStatus:
result, err = jsonparser.GetBoolean(payload)
case messages.GuessSong:
err = json.Unmarshal(payload, &guess)
result = guess
}

if err != nil {
Expand Down
13 changes: 6 additions & 7 deletions internal/lib/audioprovider/ytaudioprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,12 @@ func (y YTAudioProvider) pickYoutubeVideo(song lib.SongDetails) (string, error)
// return deltas[i].delta < deltas[j].delta
// })

for _, d := range deltas {
fmt.Println(d.result.Title)
fmt.Println(d.result.Duration)
fmt.Println(d.delta)
fmt.Println(song.Duration)
fmt.Println("----")
}
d := deltas[0]
fmt.Println(d.result.Title)
fmt.Println(d.result.Duration)
fmt.Println(d.delta)
fmt.Println(song.Duration)
fmt.Println("----")

return deltas[0].result.VideoId, nil
}
6 changes: 6 additions & 0 deletions internal/lib/messages/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const (
LeavingPlayer = "LEAVE"
SettingsUpdate = "SETTINGS_UPDATE"
ReadyStatus = "READY_STATUS"
GuessSong = "GUESS_SONG"
)

type ClientMessage struct {
Expand All @@ -25,3 +26,8 @@ type SettingsUpdatePayload struct {
Token string `json:"token"`
Settings lib.RoomSettings `json:"settings"`
}

type GuessSongPayload struct {
Id string `json:"id"`
Points int `json:"points"`
}
19 changes: 19 additions & 0 deletions internal/lib/messages/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ const (
RoomStage = "ROOM_STAGE"
PlayerReady = "PLAYER_READY"
PlaySong = "PLAY_SONG"
PlayerGuess = "PLAYER_GUESS"
CorrectSong = "CORRECT_SONG"
EndGame = "END_GAME"
)

type InitialGameState struct {
Expand Down Expand Up @@ -73,3 +76,19 @@ type PlaySongPayload struct {
Timestamp int64 `json:"timestamp"`
Duration int64 `json:"duration"`
}

type PlayerGuessPayload struct {
Correct bool `json:"correct"`
Points int `json:"points"`
PlayerId string `json:"playerId"`
SongId string `json:"songId"`
}

type EndGamePayload struct {
Results []PlayerResult `json:"results"`
}

type PlayerResult struct {
Profile lib.UserProfile `json:"profile"`
Points int `json:"points"`
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ type UserClient struct {
User auth.User
}

func NewUserSocket(client HubClient, user auth.User) UserClient {
func NewUserClient(client HubClient, user auth.User) UserClient {
return UserClient{
Client: client,
User: user,
Expand Down
6 changes: 6 additions & 0 deletions internal/lib/room/processMessages.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ func (r *Room) processMessages() {
} else {
logIncorrectPayload("Incorrect paylod in ready status", message.Payload, message.From)
}
case messages.GuessSong:
if payload, ok := message.Payload.(messages.GuessSongPayload); ok {
r.verifyGuess(message.From, payload.Id, payload.Points)
} else {
logIncorrectPayload("Incorrect paylod in ready status", message.Payload, message.From)
}
default:
fblog.Warn(component.Room, "Received unexpected message", "room", r.id, "from", message.From, "type", message.Type, "payload", message.Payload)
}
Expand Down
146 changes: 139 additions & 7 deletions internal/lib/room/room.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type Room struct {
playlist lib.PlaylistData
owner lib.UserProfile
settings lib.RoomSettings
players map[string]Player
players map[string]*Player
readyMap map[string]bool
stage RoomStage
hub messages.Hub
Expand All @@ -29,10 +29,18 @@ type Room struct {
onCleanup func(*Room)
spotifyApi lib.SpotifyApi
audio audioprovider.AudioProvider
game gameState
}

type Player struct {
profile lib.UserProfile
points int
guessed bool
}

type gameState struct {
turn int
pickedSong *lib.Song
}

func NewRoom(id string,
Expand All @@ -49,14 +57,18 @@ func NewRoom(id string,
playlist: playlist,
owner: owner,
settings: settings,
players: make(map[string]Player),
players: make(map[string]*Player),
readyMap: make(map[string]bool),
stage: LobbyStage,
hub: hub,
snd: make(chan messages.ServerMessage),
spotifyApi: spotifyApi,
audio: audio,
onCleanup: onCleanup,
game: gameState{
turn: 0,
pickedSong: nil,
},
}
}

Expand Down Expand Up @@ -103,8 +115,10 @@ func (r *Room) addPlayer(profile lib.UserProfile) {
return
}

r.players[profile.Id] = Player{
r.players[profile.Id] = &Player{
profile: profile,
points: 0,
guessed: false,
}

fblog.Info(component.Room, "new player", "roomId", r.id, "userId", profile.Id)
Expand Down Expand Up @@ -186,6 +200,34 @@ func (r *Room) removePlayer(id string) {
r.broadcastRoomStage(GameStage)
r.provideSong()
}

if r.stage == GameStage && r.guessCount() == len(r.players) {
r.finishTurn()
if r.game.turn == r.settings.TurnCount {
r.endGame()
return
}
r.provideSong()
}

}

func (r *Room) guessCount() int {
c := 0
for _, p := range r.players {
if p.guessed {
c++
}
}

return c
}

func (r *Room) finishTurn() {
r.game.turn++
for _, p := range r.players {
p.guessed = false
}
}

func (r *Room) updateSettings(from string, settingsPayload messages.SettingsUpdatePayload) {
Expand Down Expand Up @@ -264,11 +306,10 @@ func (r *Room) broadcastRoomStage(stage RoomStage) {
}

func (r *Room) provideSong() {
var pickedSong lib.Song
var url string
for {
pickedSong = r.playlist.Songs[rand.IntN(len(r.playlist.Songs))]
u, err := r.audio.GetUrl(pickedSong.Details)
r.game.pickedSong = &r.playlist.Songs[rand.IntN(len(r.playlist.Songs))]
u, err := r.audio.GetUrl(r.game.pickedSong.Details)
url = u
if err == nil {
break
Expand All @@ -288,11 +329,102 @@ func (r *Room) provideSong() {
Payload: messages.PlaySongPayload{
Url: url,
Timestamp: start.Unix(),
Duration: pickedSong.Details.Duration.Milliseconds(),
Duration: r.game.pickedSong.Details.Duration.Milliseconds(),
},
}
}

func (r *Room) verifyGuess(from string, guess string, points int) {
if r.stage != GameStage || r.game.pickedSong == nil {
return
}

var correct bool
var receivedPoints int

if points == 0 {
correct = false
receivedPoints = 0
} else {
if r.game.pickedSong.Id == guess {
r.players[from].points += points
receivedPoints = points
correct = true
} else {
r.players[from].points -= r.settings.IncorrectGuessPenalty
receivedPoints = -r.settings.IncorrectGuessPenalty
correct = false
}
}

r.sendToAllExcept(from, messages.PlayerGuess, messages.PlayerGuessPayload{
Correct: correct,
Points: receivedPoints,
PlayerId: from,
SongId: "",
})

if points == 0 {
r.snd <- messages.ServerMessage{
Type: messages.CorrectSong,
To: []string{from},
Payload: r.game.pickedSong.Id,
}
} else {
r.snd <- messages.ServerMessage{
Type: messages.PlayerGuess,
To: []string{from},
Payload: messages.PlayerGuessPayload{
Correct: correct,
Points: receivedPoints,
PlayerId: from,
SongId: guess,
},
}
}

if points == 0 || correct {
r.players[from].guessed = true

if r.guessCount() == len(r.players) {
r.finishTurn()

if r.game.turn == r.settings.TurnCount {
r.endGame()
return
}

r.provideSong()
}
}
}

func (r *Room) endGame() {
recipents := make([]string, 0)
results := make([]messages.PlayerResult, 0)
for _, p := range r.players {
recipents = append(recipents, p.profile.Id)
results = append(results, messages.PlayerResult{
Profile: p.profile,
Points: p.points,
})
r.readyMap[p.profile.Id] = false
}

time.Sleep(time.Second * 3)
r.snd <- messages.ServerMessage{
Type: messages.EndGame,
To: recipents,
Payload: messages.EndGamePayload{
Results: results,
},
}

r.stage = LobbyStage
r.game.turn = 0
r.game.pickedSong = nil
}

func (r *Room) sendToAllExcept(id string, messageType messages.ServerMessageType, payload interface{}) {
recipents := make([]string, 0)
for _, p := range r.players {
Expand Down
Loading