Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: player online state processing #39

Merged
merged 9 commits into from
Jun 6, 2024
5 changes: 5 additions & 0 deletions cmd/2sp/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"2sp/pkg/game"
"2sp/pkg/storage"
"context"
"github.com/jonboulle/clockwork"
"os"
)

Expand All @@ -25,7 +26,11 @@ func main() {
game.WithTransport(waku),
game.WithStorage(createStorage()),
game.WithLogger(config.Logger.Named("game")),
game.WithPlayerName(config.PlayerName()),
game.WithOnlineMessagePeriod(config.OnlineMessagePeriod),
game.WithStateMessagePeriod(config.StateMessagePeriod),
game.WithEnableSymmetricEncryption(config.EnableSymmetricEncryption),
game.WithClock(clockwork.NewRealClock()),
}

game := game.NewGame(options)
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require (
github.com/ethereum/go-ethereum v1.10.26
github.com/google/go-github/v61 v61.0.0
github.com/google/uuid v1.3.0
github.com/jonboulle/clockwork v0.4.0
github.com/mr-tron/base58 v1.2.0
github.com/muesli/termenv v0.15.2
github.com/multiformats/go-multiaddr v0.10.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,8 @@ github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
Expand Down
29 changes: 29 additions & 0 deletions internal/testcommon/matchers/matcher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package matchers

import (
"github.com/stretchr/testify/require"
"testing"
"time"
)

type Matcher struct {
t *testing.T
triggered chan interface{}
}

func NewMatcher(t *testing.T) *Matcher {
return &Matcher{
t: t,
triggered: make(chan interface{}, 42),
}
}

func (m *Matcher) Wait() interface{} {
select {
case <-time.After(1 * time.Second):
require.Fail(m.t, "timeout waiting for matched call")
case result := <-m.triggered:
return result
}
return nil
}
8 changes: 8 additions & 0 deletions internal/testcommon/matchers/message_matcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,21 @@ package matchers
import (
"2sp/pkg/protocol"
"fmt"
"testing"
)

type MessageMatcher struct {
Matcher
payload []byte
message *protocol.Message
}

func NewMessageMatcher(t *testing.T) *MessageMatcher {
return &MessageMatcher{
Matcher: *NewMatcher(t),
}
}

func (m *MessageMatcher) Matches(x interface{}) bool {
m.message = nil
m.payload = x.([]byte)
Expand Down
34 changes: 30 additions & 4 deletions internal/testcommon/matchers/online_matcher.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
package matchers

import (
"2sp/internal/config"
"2sp/pkg/protocol"
"encoding/json"
"fmt"
"go.uber.org/zap"
"testing"
)

type OnlineMatcher struct {
MessageMatcher
playerID protocol.PlayerID
}

func NewOnlineMatcher() OnlineMatcher {
return OnlineMatcher{}
func NewOnlineMatcher(t *testing.T, playerID protocol.PlayerID) *OnlineMatcher {
return &OnlineMatcher{
MessageMatcher: *NewMessageMatcher(t),
playerID: playerID,
}
}

func (m OnlineMatcher) Matches(x interface{}) bool {
func (m *OnlineMatcher) Matches(x interface{}) bool {
if !m.MessageMatcher.Matches(x) {
return false
}
Expand All @@ -22,9 +30,27 @@ func (m OnlineMatcher) Matches(x interface{}) bool {
return false
}

var onlineMessage protocol.PlayerOnlineMessage
err := json.Unmarshal(m.payload, &onlineMessage)
if err != nil {
return false
}

if onlineMessage.Player.ID != m.playerID {
return false
}

config.Logger.Debug("<<< OnlineMatcher.Matches",
zap.Any("onlineMessage", onlineMessage),
)
m.triggered <- onlineMessage
return true
}

func (m OnlineMatcher) String() string {
func (m *OnlineMatcher) String() string {
return fmt.Sprintf("is user online protocol message")
}

func (m *OnlineMatcher) Wait() protocol.PlayerOnlineMessage {
return m.MessageMatcher.Wait().(protocol.PlayerOnlineMessage)
}
8 changes: 4 additions & 4 deletions internal/testcommon/matchers/room_matcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@ type RoomMatcher struct {
room *protocol.Room
}

func NewRoomMatcher(room *protocol.Room) RoomMatcher {
return RoomMatcher{
func NewRoomMatcher(room *protocol.Room) *RoomMatcher {
return &RoomMatcher{
room: room,
}
}

func (m RoomMatcher) Matches(x interface{}) bool {
func (m *RoomMatcher) Matches(x interface{}) bool {
room, ok := x.(*protocol.Room)
return ok && m.room.ToRoomID() == room.ToRoomID()
}

func (m RoomMatcher) String() string {
func (m *RoomMatcher) String() string {
return fmt.Sprintf("is equal to room %s", m.room.ToRoomID())
}
35 changes: 12 additions & 23 deletions internal/testcommon/matchers/state_matcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,25 @@ import (
"encoding/json"
"fmt"
"testing"
"time"
)

type Matcher func(state *protocol.State)
type Callback func(state *protocol.State) bool

type StateMatcher struct {
Matcher
MessageMatcher
matcher Matcher
state protocol.State

triggered chan protocol.State
cb Callback
state protocol.State
}

func NewStateMatcher(matcher Matcher) *StateMatcher {
func NewStateMatcher(t *testing.T, cb Callback) *StateMatcher {
return &StateMatcher{
matcher: matcher,
triggered: make(chan protocol.State, 1),
Matcher: *NewMatcher(t),
cb: cb,
}
}

func (m *StateMatcher) Matches(x interface{}) bool {
defer func() {
m.triggered <- m.state
}()

if !m.MessageMatcher.Matches(x) {
return false
}
Expand All @@ -45,13 +39,13 @@ func (m *StateMatcher) Matches(x interface{}) bool {
}

m.state = stateMessage.State
m.triggered <- stateMessage.State

if m.matcher == nil {
if m.cb == nil {
return true
}

m.matcher(&stateMessage.State)
return true
return m.cb(&stateMessage.State)
}

func (m *StateMatcher) String() string {
Expand All @@ -62,11 +56,6 @@ func (m *StateMatcher) State() protocol.State {
return m.state
}

func (m *StateMatcher) Wait(t *testing.T) protocol.State {
select {
case <-time.After(1 * time.Second):
t.Fatal("timeout waiting for state message")
case <-m.triggered:
}
return m.state
func (m *StateMatcher) Wait() protocol.State {
return m.Matcher.Wait().(protocol.State)
}
8 changes: 4 additions & 4 deletions internal/testcommon/matchers/vote_matcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ type VoteMatcher struct {
voteValue protocol.VoteValue
}

func NewVoteMatcher(playerID protocol.PlayerID, issue protocol.IssueID, value protocol.VoteValue) VoteMatcher {
return VoteMatcher{
func NewVoteMatcher(playerID protocol.PlayerID, issue protocol.IssueID, value protocol.VoteValue) *VoteMatcher {
return &VoteMatcher{
playerID: playerID,
issueID: issue,
voteValue: value,
}
}

func (m VoteMatcher) Matches(x interface{}) bool {
func (m *VoteMatcher) Matches(x interface{}) bool {
if !m.MessageMatcher.Matches(x) {
return false
}
Expand All @@ -40,6 +40,6 @@ func (m VoteMatcher) Matches(x interface{}) bool {
vote.Timestamp > 0
}

func (m VoteMatcher) String() string {
func (m *VoteMatcher) String() string {
return fmt.Sprintf("is any state message")
}
7 changes: 7 additions & 0 deletions pkg/game/code_control_flags_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package game

func WithEnablePublishOnlineState(enable bool) Option {
return func(game *Game) {
game.codeControls.EnablePublishOnlineState = enable
}
}
10 changes: 10 additions & 0 deletions pkg/game/config.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
package game

import "time"

type gameConfig struct {
PlayerName string
EnableSymmetricEncryption bool
OnlineMessagePeriod time.Duration
StateMessagePeriod time.Duration
PublishStateLoopEnabled bool
}

var defaultConfig = gameConfig{
PlayerName: "",
EnableSymmetricEncryption: true,
OnlineMessagePeriod: 5 * time.Second,
StateMessagePeriod: 30 * time.Second,
PublishStateLoopEnabled: true,
}
10 changes: 10 additions & 0 deletions pkg/game/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,13 @@ func defaultFeatureFlags() FeatureFlags {
EnableDeckSelection: false,
}
}

type codeControlFlags struct {
EnablePublishOnlineState bool
}

func defaultCodeControlFlags() codeControlFlags {
return codeControlFlags{
EnablePublishOnlineState: true,
}
}
Loading
Loading