Skip to content

Commit

Permalink
Merge branch 'master' into nico-shitcoin-wallet
Browse files Browse the repository at this point in the history
  • Loading branch information
ornicar authored Feb 13, 2025
2 parents 2d78246 + 49e3457 commit 0325727
Show file tree
Hide file tree
Showing 17 changed files with 168 additions and 126 deletions.
2 changes: 1 addition & 1 deletion app/controllers/Tournament.scala
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ final class Tournament(env: Env, apiC: => Api)(using akka.stream.Materializer) e

private def doJoin(tourId: TourId, data: TournamentForm.TournamentJoin)(using me: Me) =
data.team
.so { env.team.api.isGranted(_, me, _.Tour) }
.so(env.team.api.isGranted(_, me, _.Tour))
.flatMap: isLeader =>
api.joinWithResult(tourId, data = data, isLeader)

Expand Down
6 changes: 2 additions & 4 deletions modules/db/src/main/BSON.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,8 @@ abstract class BSONReadOnly[T] extends BSONDocumentReader[T]:

def reads(reader: Reader): T

def readDocument(doc: Bdoc) =
Try {
reads(new Reader(doc))
}
def readDocument(doc: Bdoc) = Try:
reads(new Reader(doc))

def read(doc: Bdoc) = readDocument(doc).get

Expand Down
5 changes: 3 additions & 2 deletions modules/gathering/src/main/ui/GatheringUi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ final class GatheringFormUi(helpers: Helpers):
half = true
)

def bots(field: Field)(using Translate) =
def bots(field: Field, disabledAfterStart: Boolean)(using Translate) =
form3.checkbox(
field,
"Allow bot accounts",
Expand All @@ -118,5 +118,6 @@ final class GatheringFormUi(helpers: Helpers):
a(href := "/@/lichess/blog/welcome-lichess-bots/WvDNticA")("bots"),
" join the tournament and play with their engines."
).some,
half = true
half = true,
disabled = disabledAfterStart
)
6 changes: 4 additions & 2 deletions modules/tournament/src/main/BSONHandlers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ object BSONHandlers:
score = r.intD("s"),
fire = r.boolD("f"),
performance = r.getO[IntRating]("e"),
team = r.getO[TeamId]("t")
team = r.getO[TeamId]("t"),
bot = r.boolD("bot")
)
def writes(w: BSON.Writer, o: Player) =
$doc(
Expand All @@ -131,7 +132,8 @@ object BSONHandlers:
"m" -> o.magicScore,
"f" -> w.boolO(o.fire),
"e" -> o.performance,
"t" -> o.team
"t" -> o.team,
"bot" -> w.boolO(o.bot)
)

given pairingHandler: BSON[Pairing] with
Expand Down
3 changes: 3 additions & 0 deletions modules/tournament/src/main/PairingRepo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ final class PairingRepo(coll: Coll)(using Executor, Materializer):
def isPlaying(tourId: TourId, userId: UserId): Fu[Boolean] =
coll.exists(selectTourUser(tourId, userId) ++ selectPlaying)

def playingUserIds(tourId: TourId): Fu[Set[UserId]] =
coll.distinctEasy[UserId, Set]("u", selectTour(tourId) ++ selectPlaying)

private[tournament] def finishedByPlayerChronological(
tourId: TourId,
userId: UserId
Expand Down
15 changes: 8 additions & 7 deletions modules/tournament/src/main/Player.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,14 @@ case class Player(
score: Int = 0,
fire: Boolean = false,
performance: Option[IntRating] = None,
team: Option[TeamId] = None
team: Option[TeamId] = None,
bot: Boolean = false
):

inline def id = _id

def active = !withdraw

def is(uid: UserId): Boolean = uid == userId
def is(user: User): Boolean = is(user.id)
def is(other: Player): Boolean = is(other.userId)

def doWithdraw = copy(withdraw = true)
def unWithdraw = copy(withdraw = false)

Expand All @@ -37,19 +34,23 @@ case class Player(

object Player:

given UserIdOf[Player] = _.userId

case class WithUser(player: Player, user: User)

case class Result(player: Player, lightUser: LightUser, rank: Int, sheet: Option[arena.Sheet])

private[tournament] def make(
tourId: TourId,
user: WithPerf,
team: Option[TeamId]
team: Option[TeamId],
bot: Boolean
): Player = Player(
_id = TourPlayerId(ThreadLocalRandom.nextString(8)),
tourId = tourId,
userId = user.id,
rating = user.perf.intRating,
provisional = user.perf.provisional,
team = team
team = team,
bot = bot
)
21 changes: 9 additions & 12 deletions modules/tournament/src/main/PlayerRepo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ final class PlayerRepo(private[tournament] val coll: Coll)(using Executor):
"uid" -> userId
)
private val selectActive = $doc("w".$ne(true))
private val selectBot = $doc("bot" -> true)
private val selectWithdraw = $doc("w" -> true)
private val bestSort = $doc("m" -> -1)

Expand Down Expand Up @@ -86,7 +87,7 @@ final class PlayerRepo(private[tournament] val coll: Coll)(using Executor):
)
)
)
.map {
.map:
_.flatMap: doc =>
for
teamId <- doc.getAsOpt[TeamId]("_id")
Expand All @@ -99,8 +100,7 @@ final class PlayerRepo(private[tournament] val coll: Coll)(using Executor):
yield new RankedTeam(0, teamId, leaders)
.sorted.mapWithIndex: (rt, pos) =>
rt.updateRank(pos + 1)
}
.map { ranked =>
.map: ranked =>
if ranked.sizeIs == battle.teams.size then ranked
else
ranked ::: battle.teams
Expand All @@ -110,7 +110,6 @@ final class PlayerRepo(private[tournament] val coll: Coll)(using Executor):
case (acc, _) => acc
}
.reverse
}

// very expensive
private[tournament] def teamInfo(
Expand Down Expand Up @@ -215,18 +214,20 @@ final class PlayerRepo(private[tournament] val coll: Coll)(using Executor):
) = prev match
case Some(p) if p.withdraw => coll.update.one($id(p._id), $unset("w"))
case Some(_) => funit
case None => coll.insert.one(Player.make(tourId, user, team))
case None => coll.insert.one(Player.make(tourId, user, team, user.user.isBot))

def withdraw(tourId: TourId, userId: UserId) =
coll.update.one(selectTourUser(tourId, userId), $set("w" -> true)).void

private[tournament] def withPoints(tourId: TourId): Fu[List[Player]] =
coll.list[Player]:
selectTour(tourId) ++ $doc("m".$gt(0))
coll.list[Player](selectTour(tourId) ++ $doc("m".$gt(0)))

private[tournament] def nbActivePlayers(tourId: TourId): Fu[Int] =
coll.countSel(selectTour(tourId) ++ selectActive)

private[tournament] def activeBotIds(tourId: TourId): Fu[Set[UserId]] =
coll.distinctEasy[UserId, Set]("uid", selectTour(tourId) ++ selectActive ++ selectBot)

def winner(tourId: TourId): Fu[Option[Player]] =
coll.find(selectTour(tourId)).sort(bestSort).one[Player]

Expand All @@ -243,11 +244,7 @@ final class PlayerRepo(private[tournament] val coll: Coll)(using Executor):
List(
Match(selectTour(tourId)),
Sort(Descending("m")),
Group(BSONNull)(
"all" -> Push(
$doc("$concat" -> $arr("$_id", "$uid"))
)
)
Group(BSONNull)("all" -> Push($doc("$concat" -> $arr("$_id", "$uid"))))
)
.headOption
.map:
Expand Down
26 changes: 18 additions & 8 deletions modules/tournament/src/main/StartedOrganizer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ final private class StartedOrganizer(
api: TournamentApi,
tournamentRepo: TournamentRepo,
playerRepo: PlayerRepo,
pairingRepo: PairingRepo,
waitingUsersApi: WaitingUsersApi,
socket: TournamentSocket
)(using Executor, Scheduler, akka.stream.Materializer):

Expand Down Expand Up @@ -49,11 +51,19 @@ final private class StartedOrganizer(
else startPairing(tour)

private def startPairing(tour: Tournament, smallTourNbActivePlayers: Option[Int] = None): Funit =
(!tour.pairingsClosed).so(
socket
.getWaitingUsers(tour)
.monSuccess(_.tournament.startedOrganizer.waitingUsers)
.flatMap: waiting =>
lila.mon.tournament.waitingPlayers.record(waiting.size)
api.makePairings(tour, waiting, smallTourNbActivePlayers)
)
tour.pairingsClosed.not.so:
for
waitingBots <- fetchWaitingBots(tour)
_ = if waitingBots.nonEmpty then waitingUsersApi.addApiUsers(tour, waitingBots)
waiting <- socket.getWaitingUsers(tour).monSuccess(_.tournament.startedOrganizer.waitingUsers)
_ = waiting.hash
_ = lila.mon.tournament.waitingPlayers.record(waiting.size)
_ <- api.makePairings(tour, waiting, smallTourNbActivePlayers)
yield ()

private def fetchWaitingBots(tour: Tournament): Fu[Set[UserId]] =
tour.conditions.allowsBots.so:
for
activeBots <- playerRepo.activeBotIds(tour.id)
playingUsers <- activeBots.nonEmpty.so(pairingRepo.playingUserIds(tour.id))
yield activeBots.diff(playingUsers)
Loading

0 comments on commit 0325727

Please sign in to comment.