Skip to content
Closed
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 api/proto/realtime/realtime.proto
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ message TournamentDivisionDeletedResponse {
// Communication

// When we go to a new path in our SPA, we send a JoinPath. When we leave the
// path, we send an Unjoin realm. d
// path, we send an Unjoin realm.
message JoinPath { string path = 1; }

message UnjoinRealm {}
10 changes: 7 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: "3"

services:
app:
app: &appsetup
build:
context: .
dockerfile: Dockerfile-dev
Expand All @@ -23,13 +23,13 @@ services:
depends_on: ["db", "proxy", "nats", "socket", "redis"]
networks:
- aeronet
ports:
- "8001:8001"
labels:
- "traefik.http.routers.liwords.rule=Host(`liwords.localhost`) && PathPrefix(`/twirp/`)"
- "traefik.http.routers.liwords.entrypoints=web"
- "traefik.http.services.liwords.loadbalancer.server.port=8001"
- traefik.enable=true
# Scaling.
app2: *appsetup

bot:
build:
Expand Down Expand Up @@ -151,3 +151,7 @@ volumes:
external: false
redis-data-volume:
external: false

# bringing up multiple servers, e.g.
# docker-compose up --scale socket=2
# docker-compose up --scale app=2
10 changes: 0 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,7 @@ github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUz
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
Expand Down Expand Up @@ -139,7 +137,6 @@ github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o=
github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.0.1 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M=
github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jinzhu/now v1.1.1 h1:g39TucaRWyV3dwDO++eEc6qf8TVIQ/Da48WmqjZ3i7E=
github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
Expand All @@ -151,13 +148,11 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxv
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
Expand All @@ -168,7 +163,6 @@ github.com/mailgun/mailgun-go/v4 v4.1.4 h1:Kz8wBBsw/i2PxylxpL6UwoKndlkCUKPID+b+2
github.com/mailgun/mailgun-go/v4 v4.1.4/go.mod h1:R9kHUQBptF4iSEjhriCQizplCDwrnDShy8w/iPiOfaM=
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/matryer/is v1.3.0 h1:9qiso3jaJrOe6qBRJRBt2Ldht05qDiFP9le0JOIhRSI=
github.com/matryer/is v1.3.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
Expand Down Expand Up @@ -197,7 +191,6 @@ github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
Expand All @@ -222,7 +215,6 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
Expand Down Expand Up @@ -304,7 +296,6 @@ golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down Expand Up @@ -334,7 +325,6 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c h1:grhR+C34yXImVGp7EzNk+DTIk+323eIUWOmEevy6bDo=
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
2 changes: 2 additions & 0 deletions liwords-ui/src/gameroom/board_panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ export const BoardPanel = React.memo((props: Props) => {
if (!moveEvt) {
return;
}
moveEvt.setEventIndex(gameContext.turns.length);
sendSocketMsg(
encodeToSocketFmt(
MessageType.CLIENT_GAMEPLAY_EVENT,
Expand All @@ -294,6 +295,7 @@ export const BoardPanel = React.memo((props: Props) => {
},
[
gameContext.nickToPlayerOrder,
gameContext.turns,
examinableGameContext.onturn,
isExamining,
isMyTurn,
Expand Down
1 change: 1 addition & 0 deletions liwords-ui/src/store/socket_handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import {
SoughtGame,
} from './reducers/lobby_reducer';
import { BoopSounds } from '../sound/boop';

import {
GameInfoResponse,
GameInfoResponses,
Expand Down
5 changes: 1 addition & 4 deletions pkg/bus/bus.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,19 +409,15 @@ func (b *Bus) handleNatsPublish(ctx context.Context, subtopics []string, data []
if err != nil {
return err
}
entGame.RLock()
// Determine if one of our players is a bot (no bot-vs-bot supported yet?)
// and if it is the bot's turn.
if entGame.GameReq != nil &&
entGame.GameReq.PlayerVsBot &&
entGame.Game.Playing() != macondopb.PlayState_GAME_OVER &&
entGame.PlayerIDOnTurn() != userID {

entGame.RUnlock()
// Do this in a separate goroutine as it blocks while waiting for bot move.
go b.handleBotMove(ctx, entGame)
} else {
entGame.RUnlock()
}
return nil

Expand Down Expand Up @@ -822,6 +818,7 @@ func (b *Bus) sendPresenceContext(ctx context.Context, userID, username string,
if err != nil {
return err
}

// Also send OUR presence to users in this channel.
return b.broadcastPresence(username, userID, anon, []string{presenceChan}, false)
}
6 changes: 2 additions & 4 deletions pkg/bus/gameplay.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

"github.com/domino14/liwords/pkg/entity"
"github.com/domino14/liwords/pkg/gameplay"
gstore "github.com/domino14/liwords/pkg/stores/game"
"github.com/domino14/liwords/pkg/tournament"
pb "github.com/domino14/liwords/rpc/api/proto/realtime"
"github.com/domino14/macondo/game"
Expand Down Expand Up @@ -417,16 +418,13 @@ func (b *Bus) adjudicateGames(ctx context.Context) error {
now := time.Now()
log.Debug().Interface("active-games", gs).Msg("maybe-adjudicating...")
for _, g := range gs.GameInfo {
// These will likely be in the cache.
entGame, err := b.gameStore.Get(ctx, g.GameId)
entGame, err := b.gameStore.(*gstore.Cache).GetFromBacking(ctx, g.GameId)
if err != nil {
return err
}
entGame.RLock()
onTurn := entGame.Game.PlayerOnTurn()
started := entGame.Started
timeRanOut := entGame.TimeRanOut(onTurn)
entGame.RUnlock()
if started && timeRanOut {
log.Debug().Str("gid", g.GameId).Msg("adjudicating-time-ran-out")
err = gameplay.TimedOut(ctx, b.gameStore, b.userStore,
Expand Down
16 changes: 13 additions & 3 deletions pkg/entity/game.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package entity

import (
"sync"
"time"

gameservicepb "github.com/domino14/liwords/rpc/api/proto/game_service"
Expand All @@ -25,12 +24,15 @@ type Timers struct {
TimeRemaining []int `json:"tr"`
// MaxOvertime is in minutes. All others are in milliseconds.
MaxOvertime int `json:"mo"`
// Nower is the name of the timer module. Should only change for tests.
Nower string `json:"n,omitempty"`
}

// Nower is an interface for determining the current time
type Nower interface {
// Now returns a timestamp in milliseconds
Now() int64
Name() string
}

// FakeNower uses a fake timer. It is used for tests so we don't actually sleep.
Expand All @@ -47,6 +49,10 @@ func (f FakeNower) Now() int64 {
return f.fakeMeow
}

func (f FakeNower) Name() string {
return "FakeNower"
}

// Sleep simulates a sleep.
func (f *FakeNower) Sleep(t int64) {
f.fakeMeow += t
Expand Down Expand Up @@ -76,7 +82,6 @@ type TournamentData struct {
// and we should save most of the included fields here, especially the
// macondo.game.History (which can be exported as GCG, etc in the future)
type Game struct {
sync.RWMutex
game.Game

PlayerDBIDs [2]uint // needed to associate the games to the player IDs in the db.
Expand Down Expand Up @@ -114,6 +119,10 @@ func (g GameTimer) Now() int64 {
return time.Now().UnixNano() / (int64(time.Millisecond) / int64(time.Nanosecond))
}

func (g GameTimer) Name() string {
return ""
}

// NewGame takes in a Macondo game that was just "started". Note that
// Macondo games when they start do not log any time, they just deal tiles.
// The time of start must be logged later, when both players are in the table
Expand All @@ -135,6 +144,7 @@ func NewGame(mcg *game.Game, req *pb.GameRequest) *Game {
// SetTimerModule sets the timer for a game to the given Nower.
func (g *Game) SetTimerModule(n Nower) {
g.nower = n
g.Timers.Nower = n.Name()
}

// Reset timers to _now_. The game is actually starting.
Expand Down Expand Up @@ -260,7 +270,7 @@ func (g *Game) CreationRequest() *pb.GameRequest {
// RegisterChangeHook registers a channel with the game. Events will
// be sent down this channel.
func (g *Game) RegisterChangeHook(eventChan chan<- *EventWrapper) error {
log.Debug().Msg("register-change-hook")
log.Debug().Msgf("register-change-hook: %v", eventChan)
g.ChangeHook = eventChan
return nil
}
Expand Down
16 changes: 13 additions & 3 deletions pkg/gameplay/end.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/domino14/liwords/pkg/entity"
"github.com/domino14/liwords/pkg/stats"
"github.com/domino14/liwords/pkg/stores/game"
"github.com/domino14/liwords/pkg/tournament"
"github.com/domino14/liwords/pkg/user"
pb "github.com/domino14/liwords/rpc/api/proto/realtime"
Expand All @@ -29,7 +30,18 @@ func performEndgameDuties(ctx context.Context, g *entity.Game, gameStore GameSto
}
}

// evts := []*pb.ServerGameplayEvent{}
// this function should not run more than once. We call an atomic
// function in the game store to ensure this.
// The proper way to do this is to write a transaction around the latter
// functions, but this will have to do for now.
err := gameStore.SetGameEndReason(ctx, g)
if err != nil {
if err == game.ErrGameAlreadyOver {
log.Debug().Msg("not-executing-endgameduties-twice")
return nil
}
return err
}

var p0penalty, p1penalty int
// Limit time penalties to the max OT. This is so that we don't get situations
Expand Down Expand Up @@ -292,8 +304,6 @@ func AbortGame(ctx context.Context, gameStore GameStore, gameID string) error {
if err != nil {
return err
}
entGame.Lock()
defer entGame.Unlock()
entGame.SetGameEndReason(pb.GameEndReason_CANCELLED)

entGame.History().PlayState = macondopb.PlayState_GAME_OVER
Expand Down
Loading