Skip to content

Commit

Permalink
Add challenge and takeback events and some tweaks
Browse files Browse the repository at this point in the history
related #857
  • Loading branch information
WandererXII committed Sep 18, 2024
1 parent 8159fe5 commit 04a7439
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 39 deletions.
24 changes: 19 additions & 5 deletions modules/api/src/main/EventStream.scala
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ final class EventStream(

blueprint mapMaterializedValue { queue =>
gamesInProgress map { gameJson(_, "gameStart", me) } foreach queue.offer
challenges map toJson map some foreach queue.offer
challenges map challengeJson("challenge") map some foreach queue.offer

val actor = system.actorOf(Props(mkActor(me, queue)))

Expand Down Expand Up @@ -102,16 +102,30 @@ final class EventStream(

case FinishGame(game, _, _) => queue.offer(gameJson(game, "gameFinish", me)).unit

case lila.challenge.Event.Create(c) if c.destUserId has me.id => queue.offer(toJson(c).some).unit
case lila.challenge.Event.Create(c) if isMyChallenge(c) =>
lila.common.Future // give time for anon challenger to load the challenge page
.delay(if (c.challengerIsAnon) 2.seconds else 0.seconds) {
queue.offer(challengeJson("challenge")(c).some).void
}
.unit

case lila.challenge.Event.Decline(c) if isMyChallenge(c) =>
queue.offer(challengeJson("challengeDeclined")(c).some).unit

case lila.challenge.Event.Cancel(c) if isMyChallenge(c) =>
queue.offer(challengeJson("challengeCanceled")(c).some).unit

// pretend like the rematch is a challenge
case lila.hub.actorApi.round.RematchOffer(gameId) =>
challengeMaker.makeRematchFor(gameId, me) foreach {
_ foreach { c =>
queue offer toJson(c.copy(_id = gameId)).some
queue offer challengeJson("challenge")(c.copy(_id = gameId)).some
}
}
}

private def isMyChallenge(c: Challenge) =
c.destUserId.has(me.id) || c.challengerUserId.has(me.id)
}

private def gameJson(game: Game, tpe: String, me: User) =
Expand All @@ -131,9 +145,9 @@ final class EventStream(
)
}

private def toJson(c: Challenge) =
private def challengeJson(tpe: String)(c: Challenge) =
Json.obj(
"type" -> "challenge",
"type" -> tpe,
"challenge" -> challengeJsonView(none)(c)(lila.i18n.defaultLang)
)

Expand Down
8 changes: 5 additions & 3 deletions modules/bot/src/main/GameStateStream.scala
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ final class GameStateStream(
private val classifiers = List(
MoveGameEvent makeChan id,
s"boardDrawOffer:${id}",
s"boardTakeback:$id",
"finishGame",
"abortGame",
uniqChan(game pov as),
Expand Down Expand Up @@ -99,9 +100,10 @@ final class GameStateStream(
case MoveGameEvent(g, _, _) if g.id == id => pushState(g).unit
case lila.chat.actorApi.ChatLine(chatId, UserLine(username, _, text, false, false)) =>
pushChatLine(username, text, chatId.value.sizeIs == Game.gameIdSize).unit
case FinishGame(g, _, _) if g.id == id => onGameOver(g.some).unit
case AbortedBy(pov) if pov.gameId == id => onGameOver(pov.game.some).unit
case lila.game.actorApi.BoardDrawOffer(pov) if pov.gameId == id => pushState(pov.game).unit
case FinishGame(g, _, _) if g.id == id => onGameOver(g.some).unit
case AbortedBy(pov) if pov.gameId == id => onGameOver(pov.game.some).unit
case lila.game.actorApi.BoardDrawOffer(g) if g.id == id => pushState(g).unit
case lila.game.actorApi.BoardTakeback(g) if g.id == id => pushState(g).unit
case SetOnline =>
onlineApiUsers.setOnline(user.id)
context.system.scheduler
Expand Down
10 changes: 8 additions & 2 deletions modules/challenge/src/main/ChallengeApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ final class ChallengeApi(

def createdByDestId = repo createdByDestId _

def cancel(c: Challenge) = (repo cancel c) >>- uncacheAndNotify(c)
def cancel(c: Challenge) = repo.cancel(c) >>- {
uncacheAndNotify(c)
Bus.publish(Event.Cancel(c), "challenge")
}

private def offline(c: Challenge) = (repo offline c) >>- uncacheAndNotify(c)

Expand All @@ -68,7 +71,10 @@ final class ChallengeApi(
case _ => fuccess(socketReload(id))
}

def decline(c: Challenge) = (repo decline c) >>- uncacheAndNotify(c)
def decline(c: Challenge) = repo.decline(c) >>- {
uncacheAndNotify(c)
Bus.publish(Event.Decline(c), "challenge")
}

private val acceptQueue = new lila.hub.DuctSequencer(maxSize = 64, timeout = 5 seconds, "challengeAccept")

Expand Down
2 changes: 2 additions & 0 deletions modules/challenge/src/main/model.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ object Direction {
object Event {
case class Create(c: Challenge)
case class Accept(c: Challenge, joinerId: Option[String])
case class Decline(c: Challenge)
case class Cancel(c: Challenge)
}
8 changes: 6 additions & 2 deletions modules/game/src/main/Game.scala
Original file line number Diff line number Diff line change
Expand Up @@ -751,8 +751,12 @@ object Game {
if (mode.rated) clock.estimateTotalTime >= boardApiRatedMinClock.estimateTotalTime
else shogi.Speed(clock) >= Speed.Rapid

def isBotCompatible(game: Game) =
game.hasAi || game.source.contains(Source.Friend)
def isBotCompatible(game: Game): Boolean =
(game.hasAi || game.source.contains(Source.Friend)) && isBotCompatible(game.speed)
def isBotCompatible(speed: Speed): Boolean = speed >= Speed.Bullet

def isBoardOrBotCompatible(game: Game) =
isBoardCompatible(game) || isBotCompatible(game)

private[game] val someEmptyClockHistory = Some(ClockHistory())

Expand Down
10 changes: 9 additions & 1 deletion modules/game/src/main/actorApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,12 @@ object MoveGameEvent {
def makeChan(gameId: Game.ID) = s"moveEvent:$gameId"
}

case class BoardDrawOffer(pov: Pov)
case class BoardDrawOffer(game: Game)
object BoardDrawOffer {
def makeChan(gameId: Game.ID) = s"boardDrawOffer:$gameId"
}

case class BoardTakeback(game: Game)
object BoardTakeback {
def makeChan(gameId: Game.ID) = s"boardTakeback:$gameId"
}
41 changes: 19 additions & 22 deletions modules/round/src/main/Drawer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,23 @@ final private[round] class Drawer(

implicit private val chatLang = defaultLang

def yes(pov: Pov)(implicit proxy: GameProxy): Fu[Events] =
def yes(pov: Pov)(implicit proxy: GameProxy): Fu[Events] = pov.game.drawable ?? {
pov match {
case pov if pov.opponent.isOfferingDraw =>
finisher.other(pov.game, _.Draw, None, Some(trans.drawOfferAccepted.txt()))
case Pov(g, color) if g playerCanOfferDraw color =>
proxy.save {
messenger.system(g, trans.xOffersDraw.txt(color.toString).toLowerCase.capitalize)
Progress(g) map { g =>
g.updatePlayer(color, _ offerDraw g.plies)
}
} >>- publishDrawOffer(pov) inject List(Event.DrawOffer(by = color.some))
val progress = Progress(g) map { g =>
g.updatePlayer(color, _ offerDraw g.plies)
}
messenger.system(g, trans.xOffersDraw.txt(color.toString).toLowerCase.capitalize)
proxy.save(progress) >>-
publishDrawOffer(progress.game) inject
List(Event.DrawOffer(by = color.some))
case _ => fuccess(List(Event.ReloadOwner))
}
}

def no(pov: Pov)(implicit proxy: GameProxy): Fu[Events] =
def no(pov: Pov)(implicit proxy: GameProxy): Fu[Events] = pov.game.drawable ?? {
pov match {
case Pov(g, color) if pov.player.isOfferingDraw =>
proxy.save {
Expand All @@ -44,28 +46,23 @@ final private[round] class Drawer(
} inject List(Event.DrawOffer(by = none))
case _ => fuccess(List(Event.ReloadOwner))
}
}

def claim(pov: Pov)(implicit proxy: GameProxy): Fu[Events] =
(pov.game.playable && pov.game.history.fourfoldRepetition) ?? finisher.other(pov.game, _.Draw, None)

def force(game: Game)(implicit proxy: GameProxy): Fu[Events] = finisher.other(game, _.Draw, None, None)

private def publishDrawOffer(pov: Pov)(implicit proxy: GameProxy): Unit = {
if (pov.game.isCorrespondence && pov.game.nonAi)
private def publishDrawOffer(game: Game): Unit = if (game.nonAi) {
if (game.isCorrespondence)
Bus.publish(
lila.hub.actorApi.round.CorresDrawOfferEvent(pov.gameId),
lila.hub.actorApi.round.CorresDrawOfferEvent(game.id),
"offerEventCorres"
)
if (lila.game.Game.isBoardCompatible(pov.game))
proxy
.withPov(pov.color) { p =>
fuccess(
Bus.publish(
lila.game.actorApi.BoardDrawOffer(p),
s"boardDrawOffer:${pov.gameId}"
)
)
}
.unit
if (lila.game.Game.isBoardOrBotCompatible(game))
Bus.publish(
lila.game.actorApi.BoardDrawOffer(game),
lila.game.actorApi.BoardDrawOffer makeChan game.id
)
}
}
2 changes: 1 addition & 1 deletion modules/round/src/main/Finisher.scala
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ final private class Finisher(
newGame foreach proxy.setFinishedGame
val newFinish = finish.copy(game = newGame | game)
Bus.publish(newFinish, "finishGame")
game.userIds.foreach { userId =>
game.userIds foreach { userId =>
Bus.publish(newFinish, s"userFinishGame:$userId")
}
}
Expand Down
21 changes: 18 additions & 3 deletions modules/round/src/main/Takebacker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ final private class Takebacker(
.fromPly(pov.opponent.proposeTakebackAt)
) single(game)
else double(game)
} dmap (_ -> situation.reset)
case Pov(game, _) if pov.game.playableByAi => single(game) dmap (_ -> situation)
case Pov(game, _) if pov.opponent.isAi => double(game) dmap (_ -> situation)
} >>- publishTakeback(pov) dmap (_ -> situation.reset)
case Pov(game, _) if pov.game.playableByAi =>
single(game) >>- publishTakeback(pov) dmap (_ -> situation)
case Pov(game, _) if pov.opponent.isAi => double(game) >>- publishTakeback(pov) dmap (_ -> situation)
case Pov(game, color) if (game playerCanProposeTakeback color) && situation.offerable =>
{
messenger.system(game, trans.takebackPropositionSent.txt())
Expand Down Expand Up @@ -116,4 +117,18 @@ final private class Takebacker(
messenger.system(p2.game, trans.takebackPropositionAccepted.txt())
proxy.save(p2) inject p2.events
}

private def publishTakeback(pov: Pov)(implicit proxy: GameProxy): Unit = {
if (lila.game.Game.isBoardOrBotCompatible(pov.game))
proxy
.withPov(pov.color) { p =>
fuccess(
Bus.publish(
lila.game.actorApi.BoardTakeback(p.game),
lila.game.actorApi.BoardTakeback makeChan pov.gameId
)
)
}
.unit
}
}

0 comments on commit 04a7439

Please sign in to comment.