Skip to content

Commit 0515e9e

Browse files
committed
Package and fixes
1 parent 36f10b7 commit 0515e9e

File tree

6 files changed

+48
-23
lines changed

6 files changed

+48
-23
lines changed

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
all:
2+
sbt universal:packageXzTarball
3+

build.sbt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@ lazy val webapi =
8181
.dependsOn(gameLogic)
8282
.dependsOn(wordGenerator)
8383
.dependsOn(dictionary)
84+
.enablePlugins(JavaServerAppPackaging)
8485
.settings(
86+
Universal / packageName := "zwords",
8587
sharedSettings,
8688
libraryDependencies ++= Seq(
8789
"com.softwaremill.sttp.tapir" %% "tapir-zio" % versions.tapir,

gamelogic/src/main/scala/fr/janalyse/zwords/gamelogic/Game.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import fr.janalyse.zwords.wordgen.WordGeneratorService
55
import zio.*
66
import zio.json.*
77

8-
import java.time.Instant
8+
import java.time.OffsetDateTime
99
import java.util.UUID
1010
import scala.collection.LazyZip2
1111
import scala.io.AnsiColor.*
@@ -170,7 +170,7 @@ object GameStorageIssue:
170170
given JsonCodec[GameStorageIssue] = DeriveJsonCodec.gen
171171
def apply(th: Throwable): GameStorageIssue = GameStorageIssue(th.getMessage)
172172

173-
case class Game(uuid: UUID, hiddenWord: String, board: Board, createdDate: Instant, possibleWordsCount: Int):
173+
case class Game(uuid: UUID, hiddenWord: String, board: Board, createdDate: OffsetDateTime, possibleWordsCount: Int):
174174

175175
override def toString: String = board.toString + s" $YELLOW($possibleWordsCount)$RESET"
176176

@@ -195,7 +195,7 @@ case class Game(uuid: UUID, hiddenWord: String, board: Board, createdDate: Insta
195195
yield copy(board = newBoard, possibleWordsCount = possibleWords.size)
196196

197197
object Game:
198-
def makeDefaultWordMask(word:String):String = (word.head +: word.tail.map(_ => "_")).mkString
198+
def makeDefaultWordMask(word: String): String = (word.head +: word.tail.map(_ => "_")).mkString
199199

200200
def init(maxAttemptsCount: Int): ZIO[WordGeneratorService & Random & Clock, GameIssue | GameInternalIssue, Game] =
201201
for {
@@ -210,8 +210,8 @@ object Game:
210210
def init(hiddenWord: String, wordMask: String, maxAttemptsCount: Int): ZIO[WordGeneratorService & Random & Clock, GameIssue | GameInternalIssue, Game] =
211211
for {
212212
wordGen <- ZIO.service[WordGeneratorService]
213-
createdDate <- Clock.instant
214-
_ <- Random.setSeed(createdDate.toEpochMilli)
213+
createdDate <- Clock.currentDateTime
214+
_ <- Random.setSeed(createdDate.toInstant.toEpochMilli)
215215
uuid <- Random.nextUUID
216216
board = Board(wordMask, maxAttemptsCount)
217217
possibleWords <- wordGen.matchingWords(wordMask, Map.empty, Map.empty).mapError(th => GameWordGeneratorIssue(th))

project/plugins.sbt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
addSbtPlugin("com.github.sbt" % "sbt-native-packager" % "1.9.9")

webapi/src/main/scala/fr/janalyse/zwords/webapi/PlayerStoreService.scala

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ package fr.janalyse.zwords.webapi
22

33
import zio.*
44
import zio.json.*
5+
56
import java.util.UUID
67
import fr.janalyse.zwords.gamelogic.Game
7-
import java.time.Instant
8+
9+
import java.time.OffsetDateTime
810

911
case class PlayStats(
1012
playedCount: Int = 0,
@@ -19,20 +21,20 @@ object PlayStats {
1921
case class Player(
2022
uuid: UUID,
2123
pseudo: String,
22-
createdOn: Instant,
24+
createdOn: OffsetDateTime,
2325
currentGame: Game,
2426
stats: PlayStats
2527
)
2628

2729
trait PlayerStoreService {
2830
def getPlayer(playerUUID: UUID): Task[Option[Player]]
29-
def upsertPlayer(player: Player): Task[Unit]
31+
def upsertPlayer(player: Player): Task[Player]
3032
def stats: Task[PlayStats]
3133
}
3234

3335
object PlayerStoreService {
3436
def getPlayer(playerUUID: UUID): RIO[PlayerStoreService, Option[Player]] = ZIO.serviceWithZIO(_.getPlayer(playerUUID))
35-
def upsertPlayer(player: Player): RIO[PlayerStoreService, Unit] = ZIO.serviceWithZIO(_.upsertPlayer(player))
37+
def upsertPlayer(player: Player): RIO[PlayerStoreService, Player] = ZIO.serviceWithZIO(_.upsertPlayer(player))
3638
def stats: RIO[PlayerStoreService, PlayStats] = ZIO.serviceWithZIO(_.stats)
3739

3840
val live = (for {
@@ -47,10 +49,10 @@ case class PlayerStoreServiceLive(ref: Ref[Map[UUID, Player]]) extends PlayerSto
4749
mayBePlayer = players.get(playerUUID)
4850
} yield mayBePlayer
4951

50-
def upsertPlayer(player: Player): Task[Unit] =
52+
def upsertPlayer(player: Player): Task[Player] =
5153
for {
5254
players <- ref.getAndUpdate(players => players + (player.uuid -> player))
53-
} yield ()
55+
} yield player
5456

5557
def stats: Task[PlayStats] =
5658
for {

webapi/src/main/scala/fr/janalyse/zwords/webapi/WebApiApp.scala

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ import zio.*
1414
import zio.json.*
1515
import zio.json.ast.*
1616

17-
import java.time.Instant
17+
import java.time.OffsetDateTime
18+
import java.time.temporal.ChronoField
1819
import java.util.UUID
1920

2021
case class GameGivenWord(
@@ -97,7 +98,7 @@ object PlayerCreate {
9798

9899
case class PlayerGet(
99100
pseudo: String,
100-
createdOn: Instant,
101+
createdOn: OffsetDateTime,
101102
stats: PlayStats
102103
)
103104
object PlayerGet {
@@ -113,8 +114,8 @@ object WebApiApp extends ZIOAppDefault {
113114
for {
114115
store <- ZIO.service[PlayerStoreService]
115116
game <- Game.init(6)
116-
created <- Clock.instant
117-
_ <- Random.setSeed(created.toEpochMilli)
117+
created <- Clock.currentDateTime
118+
_ <- Random.setSeed(created.toInstant.toEpochMilli)
118119
playerUUID <- Random.nextUUID
119120
player = Player(uuid = playerUUID, pseudo = playerCreate.pseudo, createdOn = created, currentGame = game, stats = PlayStats())
120121
state <- store.upsertPlayer(player).mapError(th => GameStorageIssue(th))
@@ -168,12 +169,29 @@ object WebApiApp extends ZIOAppDefault {
168169

169170
// -------------------------------------------------------------------------------------------------------------------
170171

172+
def sameDay(date1: OffsetDateTime, date2: OffsetDateTime): Boolean = {
173+
val fields = List(
174+
ChronoField.YEAR_OF_ERA,
175+
ChronoField.MONTH_OF_YEAR,
176+
ChronoField.DAY_OF_MONTH
177+
)
178+
fields.forall(field => date1.get(field) == date2.get(field))
179+
}
180+
171181
def gameGet(playerUUID: String): ZIO[GameEnv, GameIssue | GameInternalIssue, PlayerGameState] =
172182
for {
173-
store <- ZIO.service[PlayerStoreService]
174-
uuid <- ZIO.attempt(UUID.fromString(playerUUID)).mapError(th => GameInvalidUUID(playerUUID))
175-
player <- store.getPlayer(playerUUID = uuid).some.mapError(_ => GameNotFound(playerUUID))
176-
} yield PlayerGameState.fromPlayer(player)
183+
store <- ZIO.service[PlayerStoreService]
184+
uuid <- ZIO.attempt(UUID.fromString(playerUUID)).mapError(th => GameInvalidUUID(playerUUID))
185+
playerBefore <- store.getPlayer(playerUUID = uuid).some.mapError(_ => GameNotFound(playerUUID))
186+
today <- Clock.currentDateTime
187+
isSameDay <- ZIO.attempt(sameDay(playerBefore.currentGame.createdDate, today)).mapError(th => GameStorageIssue(th))
188+
playerAfter <- if (isSameDay) ZIO.succeed(playerBefore)
189+
else
190+
for {
191+
newGame <- Game.init(6)
192+
updatedPlayer <- store.upsertPlayer(playerBefore.copy(currentGame = newGame)).mapError(th => GameStorageIssue(th))
193+
} yield updatedPlayer
194+
} yield PlayerGameState.fromPlayer(playerAfter)
177195

178196
val gameGetEndPoint =
179197
endpoint
@@ -272,11 +290,10 @@ object WebApiApp extends ZIOAppDefault {
272290

273291
val server = for {
274292
clientResources <- System.env("ZWORDS_CLIENT_RESOURCES_PATH").some
275-
clientSideEndPoint = fileGetServerEndpoint("index.html")(s"$clientResources/index.html").widen[GameEnv]
276-
clientSideResourcesEndPoints = filesGetServerEndpoint("static")(s"$clientResources/static").widen[GameEnv]
277-
clientSideRoutes = List(clientSideEndPoint, clientSideEndPoint)
293+
clientSideResourcesEndPoints = filesGetServerEndpoint(emptyInput)(clientResources).widen[GameEnv]
294+
clientSideRoutes = List(clientSideResourcesEndPoints)
278295
httpApp = ZioHttpInterpreter().toHttp(gameRoutes ++ apiDocRoutes ++ clientSideRoutes)
279-
zservice <- zhttp.service.Server.start(8080, httpApp)
296+
zservice <- zhttp.service.Server.start(8090, httpApp)
280297
} yield zservice
281298

282299
override def run =

0 commit comments

Comments
 (0)