Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import com.snackgame.server.game.session.domain.Session

data class SessionEndEvent(
val metadata: Metadata,
val ownerId: Long,
val sessionId: Long,
override val ownerId: Long,
override val sessionId: Long,
val score: Int
) {
) : SessionStateEvent {

companion object {
fun of(session: Session): SessionEndEvent {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.snackgame.server.game.session.event

import com.snackgame.server.game.session.domain.Session
import java.time.LocalDateTime

data class SessionPauseEvent(
override val sessionId: Long,
override val ownerId: Long,
val occurredAt: LocalDateTime
) : SessionStateEvent {

companion object {
fun of(session: Session): SessionPauseEvent {
return SessionPauseEvent(
session.sessionId,
session.ownerId,
LocalDateTime.now()
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.snackgame.server.game.session.event

import com.snackgame.server.game.session.domain.Session
import java.time.LocalDateTime

data class SessionResumeEvent(
override val sessionId: Long,
override val ownerId: Long,
val occurredAt: LocalDateTime
) : SessionStateEvent {

companion object {
fun of(session: Session): SessionResumeEvent {
return SessionResumeEvent(
session.sessionId,
session.ownerId,
LocalDateTime.now()
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.snackgame.server.game.session.event

interface SessionStateEvent {
val sessionId: Long
val ownerId: Long
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@ import com.snackgame.server.game.snackgame.core.domain.Board
import com.snackgame.server.game.snackgame.core.domain.BoardConverter
import com.snackgame.server.game.snackgame.core.domain.Snackgame.Companion.DEFAULT_HEIGHT
import com.snackgame.server.game.snackgame.core.domain.Snackgame.Companion.DEFAULT_WIDTH
import com.snackgame.server.game.snackgame.core.domain.Snackgame.Companion.FEVER_MULTIPLIER
import com.snackgame.server.game.snackgame.core.domain.Snackgame.Companion.NORMAL_MULTIPLIER
import com.snackgame.server.game.snackgame.core.domain.Snackgame.Companion.SESSION_TIME
import com.snackgame.server.game.snackgame.core.domain.Snackgame.Companion.SPARE_TIME
import com.snackgame.server.game.snackgame.core.domain.Streak
import com.snackgame.server.game.snackgame.core.domain.item.FeverTime
import com.snackgame.server.game.snackgame.core.domain.snack.Snack
import com.snackgame.server.game.snackgame.core.service.dto.StreakWithFever
import java.time.Duration
import javax.persistence.Convert
import javax.persistence.Embedded
import javax.persistence.Entity
import javax.persistence.Lob

Expand All @@ -33,6 +38,11 @@ open class SnackgameBiz(
this.score = score
}

@Embedded
var feverTime: FeverTime? = null
private set


fun remove(streak: Streak) {
val removedSnacks = board.removeSnacksIn(streak)
this.score += removedSnacks.size
Expand All @@ -41,5 +51,25 @@ open class SnackgameBiz(
}
}

fun remove(streakWithFever: StreakWithFever) {
val streak = streakWithFever.streak
val removedSnacks = board.removeSnacksIn(streak)

val serverIsFever = feverTime?.isActive(streakWithFever.occurredAt) == true
val isValid = streakWithFever.clientIsFever && serverIsFever

val multiplier = if (isValid) FEVER_MULTIPLIER else NORMAL_MULTIPLIER
increaseScore(streak.length * multiplier)

if (removedSnacks.any(Snack::isGolden)) {
this.board = board.reset()
}
}

private fun increaseScore(earn: Int) {
val multiplier = if (feverTime?.isActive() == true) FEVER_MULTIPLIER else NORMAL_MULTIPLIER
this.score += earn * multiplier
}

override val metadata = SNACK_GAME_BIZ
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@ import com.snackgame.server.game.snackgame.core.domain.Board
import com.snackgame.server.game.snackgame.core.domain.BoardConverter
import com.snackgame.server.game.snackgame.core.domain.Snackgame.Companion.DEFAULT_HEIGHT
import com.snackgame.server.game.snackgame.core.domain.Snackgame.Companion.DEFAULT_WIDTH
import com.snackgame.server.game.snackgame.core.domain.Snackgame.Companion.FEVER_MULTIPLIER
import com.snackgame.server.game.snackgame.core.domain.Snackgame.Companion.NORMAL_MULTIPLIER
import com.snackgame.server.game.snackgame.core.domain.Snackgame.Companion.SESSION_TIME
import com.snackgame.server.game.snackgame.core.domain.Snackgame.Companion.SPARE_TIME
import com.snackgame.server.game.snackgame.core.domain.Streak
import com.snackgame.server.game.snackgame.core.domain.item.FeverTime
import com.snackgame.server.game.snackgame.core.domain.snack.Snack
import com.snackgame.server.game.snackgame.core.service.dto.StreakWithFever
import java.time.Duration
import javax.persistence.Convert
import javax.persistence.Embedded
import javax.persistence.Entity
import javax.persistence.Lob

Expand All @@ -28,6 +33,10 @@ open class SnackgameBizV2(
var board = board
private set

@Embedded
var feverTime: FeverTime? = null
private set

fun remove(streak: Streak) {
val removedSnacks = board.removeSnacksIn(streak)
this.score += removedSnacks.size
Expand All @@ -36,5 +45,25 @@ open class SnackgameBizV2(
}
}

fun remove(streakWithFever: StreakWithFever) {
val streak = streakWithFever.streak
val removedSnacks = board.removeSnacksIn(streak)

val serverIsFever = feverTime?.isActive(streakWithFever.occurredAt) == true
val isValid = streakWithFever.clientIsFever && serverIsFever

val multiplier = if (isValid) FEVER_MULTIPLIER else NORMAL_MULTIPLIER
increaseScore(streak.length * multiplier)

if (removedSnacks.any(Snack::isGolden)) {
this.board = board.reset()
}
}

private fun increaseScore(earn: Int) {
val multiplier = if (feverTime?.isActive() == true) FEVER_MULTIPLIER else NORMAL_MULTIPLIER
this.score += earn * multiplier
}

override val metadata = SNACK_GAME_BIZ_V2
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.snackgame.server.game.metadata.Metadata.SNACK_GAME
import com.snackgame.server.game.session.domain.Session
import com.snackgame.server.game.snackgame.core.domain.item.FeverTime
import com.snackgame.server.game.snackgame.core.domain.snack.Snack
import com.snackgame.server.game.snackgame.core.service.dto.StreakWithFever
import java.time.Duration
import javax.persistence.Convert
import javax.persistence.Embedded
Expand Down Expand Up @@ -32,6 +33,7 @@ open class Snackgame(
this.score = score
}

//todo : 제거 예정
fun remove(streak: Streak) {
val removedSnacks = board.removeSnacksIn(streak)
increaseScore(streak.length)
Expand All @@ -41,6 +43,21 @@ open class Snackgame(
}
}

fun remove(streakWithFever: StreakWithFever) {
val streak = streakWithFever.streak
val removedSnacks = board.removeSnacksIn(streak)

val serverIsFever = feverTime?.isActive(streakWithFever.occurredAt) == true
val isValid = streakWithFever.clientIsFever && serverIsFever

val multiplier = if (isValid) FEVER_MULTIPLIER else NORMAL_MULTIPLIER
increaseScore(streak.length * multiplier)

if (removedSnacks.any(Snack::isGolden)) {
this.board = board.reset()
}
}

fun removeBomb(streak: Streak) {
val removedSnacks = board.bombSnacksIn(streak)
increaseScore(removedSnacks.size)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,28 @@ import javax.persistence.Embeddable

@Embeddable
class FeverTime(
private val feverStartedAt: LocalDateTime? = null
private var feverStartedAt: LocalDateTime? = null,
private var feverPausedAt: LocalDateTime? = null
) {
fun isActive(now: LocalDateTime = LocalDateTime.now()): Boolean {
return feverStartedAt != null && Duration.between(feverStartedAt, now) < DURATION
if (feverStartedAt == null) return false
val effectiveStart = feverPausedAt?.let { feverStartedAt!!.plus(Duration.between(it, now)) } ?: feverStartedAt
return Duration.between(effectiveStart, now) < DURATION
}

fun pause() {
if (feverStartedAt != null && feverPausedAt == null) {
feverPausedAt = LocalDateTime.now()
}
}

fun resume() {
if (feverStartedAt != null && feverPausedAt != null) {
val now = LocalDateTime.now()
val pausedDuration = Duration.between(feverPausedAt, now)
feverStartedAt = feverStartedAt!!.plus(pausedDuration)
feverPausedAt = null
}
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.snackgame.server.game.snackgame.core.domain.item

import com.snackgame.server.game.session.event.SessionPauseEvent
import com.snackgame.server.game.session.event.SessionResumeEvent
import com.snackgame.server.game.snackgame.core.domain.SnackgameRepository
import com.snackgame.server.game.snackgame.core.domain.getBy
import org.springframework.stereotype.Component
import org.springframework.transaction.event.TransactionPhase
import org.springframework.transaction.event.TransactionalEventListener

@Component
class FeverTimeListener(
private val snackgameRepository: SnackgameRepository
) {
@TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT)
fun onSessionPaused(event: SessionPauseEvent) {
val game = snackgameRepository.getBy(event.ownerId, event.sessionId)
game.feverTime?.pause()
}

@TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT)
fun onSessionResumed(event: SessionResumeEvent) {
val game = snackgameRepository.getBy(event.ownerId, event.sessionId)
game.feverTime?.resume()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.snackgame.server.game.snackgame.core.service


import com.snackgame.server.game.session.event.SessionEndEvent
import com.snackgame.server.game.session.event.SessionPauseEvent
import com.snackgame.server.game.session.event.SessionResumeEvent
import com.snackgame.server.game.snackgame.core.domain.Snackgame
import com.snackgame.server.game.snackgame.core.domain.SnackgameRepository
import com.snackgame.server.game.snackgame.core.domain.Streak
Expand Down Expand Up @@ -78,6 +80,7 @@ class SnackgameService(
val game = snackGameRepository.getBy(memberId, sessionId)

game.pause()
eventPublisher.publishEvent(SessionPauseEvent.of(game))

return SnackgameResponse.of(game)
}
Expand All @@ -87,6 +90,7 @@ class SnackgameService(
val game = snackGameRepository.getBy(memberId, sessionId)

game.resume()
eventPublisher.publishEvent(SessionResumeEvent.of(game))

return SnackgameResponse.of(game)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,29 @@ package com.snackgame.server.game.snackgame.core.service.dto
import com.fasterxml.jackson.annotation.JsonCreator
import com.snackgame.server.game.snackgame.core.domain.Coordinate
import com.snackgame.server.game.snackgame.core.domain.Streak
import java.time.LocalDateTime

data class StreaksRequest @JsonCreator constructor(
val streaks: List<List<CoordinateRequest>>
val streaks: List<StreakWithMeta>
) {
fun toStreaks(now: LocalDateTime = LocalDateTime.now()): List<StreakWithFever> =
streaks.map { it.toDomain(now) }
}

fun toStreaks(): List<Streak> = streaks.map { streak ->
Streak.of(streak.map { Coordinate(it.y, it.x) })
}
data class StreakWithMeta(
val coordinates: List<CoordinateRequest>,
val isFever: Boolean
) {
fun toDomain(now: LocalDateTime): StreakWithFever =
StreakWithFever(
streak = Streak.of(coordinates.map { Coordinate(it.y, it.x) }),
clientIsFever = isFever,
occurredAt = now
)
}

data class StreakWithFever(
val streak: Streak,
val clientIsFever: Boolean,
val occurredAt: LocalDateTime
)
Loading
Loading