Skip to content

Commit

Permalink
fix: pvp response
Browse files Browse the repository at this point in the history
  • Loading branch information
bhoopesh369 committed Jan 26, 2024
1 parent c870223 commit 61bff55
Show file tree
Hide file tree
Showing 13 changed files with 128 additions and 100 deletions.
20 changes: 6 additions & 14 deletions docs/spec/CodeCharacter-API.yml
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ paths:
schema:
type: array
items:
$ref: '#/components/schemas/Match'
type: object
examples:
Example:
value:
Expand Down Expand Up @@ -989,7 +989,7 @@ paths:
schema:
type: array
items:
$ref: '#/components/schemas/Match'
type: object
examples:
Example:
value:
Expand Down Expand Up @@ -1986,26 +1986,18 @@ components:
type: string
format: uuid
example: 123e4567-e89b-12d3-a456-426614174000
destructionPlayer1:
type: number
example: 100
destructionPlayer2:
type: number
example: 100
coinsUsedPlayer1:
scorePlayer1:
type: integer
example: 69
coinsUsedPlayer2:
scorePlayer2:
type: integer
example: 69
status:
$ref: '#/components/schemas/PvPGameStatus'
required:
- id
- destructionPlayer1
- destructionPlayer2
- coinsUsedPlayer1
- coinsUsedPlayer2
- scorePlayer1
- scorePlayer2
- status
PvPGameLog:
type: string
Expand Down
9 changes: 4 additions & 5 deletions library/src/main/kotlin/delta/codecharacter/core/MatchApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ package delta.codecharacter.core

import delta.codecharacter.dtos.CreateMatchRequestDto
import delta.codecharacter.dtos.GenericErrorDto
import delta.codecharacter.dtos.MatchDto
import io.swagger.v3.oas.annotations.*
import io.swagger.v3.oas.annotations.enums.*
import io.swagger.v3.oas.annotations.media.*
Expand Down Expand Up @@ -65,7 +64,7 @@ interface MatchApi {
operationId = "getTopMatches",
description = """Get top matches""",
responses = [
ApiResponse(responseCode = "200", description = "OK", content = [Content(array = ArraySchema(schema = Schema(implementation = MatchDto::class)))]),
ApiResponse(responseCode = "200", description = "OK", content = [Content(array = ArraySchema(schema = Schema(implementation = kotlin.Any::class)))]),
ApiResponse(responseCode = "401", description = "Unauthorized")
],
security = [ SecurityRequirement(name = "http-bearer") ]
Expand All @@ -75,7 +74,7 @@ interface MatchApi {
value = ["/top-matches"],
produces = ["application/json"]
)
fun getTopMatches(): ResponseEntity<List<MatchDto>> {
fun getTopMatches(): ResponseEntity<List<kotlin.Any>> {
return ResponseEntity(HttpStatus.NOT_IMPLEMENTED)
}

Expand All @@ -84,7 +83,7 @@ interface MatchApi {
operationId = "getUserMatches",
description = """Get matches played by authenticated user""",
responses = [
ApiResponse(responseCode = "200", description = "OK", content = [Content(array = ArraySchema(schema = Schema(implementation = MatchDto::class)))]),
ApiResponse(responseCode = "200", description = "OK", content = [Content(array = ArraySchema(schema = Schema(implementation = kotlin.Any::class)))]),
ApiResponse(responseCode = "401", description = "Unauthorized")
],
security = [ SecurityRequirement(name = "http-bearer") ]
Expand All @@ -94,7 +93,7 @@ interface MatchApi {
value = ["/user/matches"],
produces = ["application/json"]
)
fun getUserMatches(): ResponseEntity<List<MatchDto>> {
fun getUserMatches(): ResponseEntity<List<kotlin.Any>> {
return ResponseEntity(HttpStatus.NOT_IMPLEMENTED)
}
}
16 changes: 4 additions & 12 deletions library/src/main/kotlin/delta/codecharacter/dtos/PvPGameDto.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,20 @@ import io.swagger.v3.oas.annotations.media.Schema
/**
* PvP Game model
* @param id
* @param destructionPlayer1
* @param destructionPlayer2
* @param coinsUsedPlayer1
* @param coinsUsedPlayer2
* @param scorePlayer1
* @param scorePlayer2
* @param status
*/
data class PvPGameDto(

@Schema(example = "123e4567-e89b-12d3-a456-426614174000", required = true, description = "")
@get:JsonProperty("id", required = true) val id: java.util.UUID,

@Schema(example = "100", required = true, description = "")
@get:JsonProperty("destructionPlayer1", required = true) val destructionPlayer1: java.math.BigDecimal,

@Schema(example = "100", required = true, description = "")
@get:JsonProperty("destructionPlayer2", required = true) val destructionPlayer2: java.math.BigDecimal,

@Schema(example = "69", required = true, description = "")
@get:JsonProperty("coinsUsedPlayer1", required = true) val coinsUsedPlayer1: kotlin.Int,
@get:JsonProperty("scorePlayer1", required = true) val scorePlayer1: kotlin.Int,

@Schema(example = "69", required = true, description = "")
@get:JsonProperty("coinsUsedPlayer2", required = true) val coinsUsedPlayer2: kotlin.Int,
@get:JsonProperty("scorePlayer2", required = true) val scorePlayer2: kotlin.Int,

@field:Valid
@Schema(example = "null", required = true, description = "")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,11 @@ interface VerdictAlgorithm {
player2CoinsUsed: Int,
player2Destruction: Double
): MatchVerdictEnum

fun getPvPVerdict(
player1HasErrors: Boolean,
player1Score: Int,
player2HasErrors: Boolean,
player2Score: Int,
) : MatchVerdictEnum
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,19 @@ class WinnerAlgorithm : VerdictAlgorithm {
if (player1Score > player2Score) return MatchVerdictEnum.PLAYER1
return MatchVerdictEnum.PLAYER2
}

override fun getPvPVerdict(
player1HasErrors: Boolean,
player1Score: Int,
player2HasErrors: Boolean,
player2Score: Int
): MatchVerdictEnum {
if (player1HasErrors && player2HasErrors) return MatchVerdictEnum.TIE
if (player1HasErrors) return MatchVerdictEnum.PLAYER2
if (player2HasErrors) return MatchVerdictEnum.PLAYER1

if (player1Score == player2Score) return MatchVerdictEnum.TIE
if (player1Score > player2Score) return MatchVerdictEnum.PLAYER1
return MatchVerdictEnum.PLAYER2
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ class MatchController(@Autowired private val matchService: MatchService) : Match
}

@Secured("ROLE_USER")
override fun getTopMatches(): ResponseEntity<List<MatchDto>> {
override fun getTopMatches(): ResponseEntity<List<Any>> {
return ResponseEntity.ok(matchService.getTopMatches())
}

@Secured("ROLE_USER")
override fun getUserMatches(): ResponseEntity<List<MatchDto>> {
override fun getUserMatches(): ResponseEntity<List<Any>> {
val user = SecurityContextHolder.getContext().authentication.principal as UserEntity
return ResponseEntity.ok(matchService.getUserMatches(user.id))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,28 +319,20 @@ class MatchService(
}
}

private fun mapPvPMatchEntitiesToDtos(pvPMatchEntities: List<PvPMatchEntity>): List<MatchDto> {
private fun mapPvPMatchEntitiesToDtos(pvPMatchEntities: List<PvPMatchEntity>): List<PvPMatchDto> {
return pvPMatchEntities.map { pvPMatchEntity ->
MatchDto(
PvPMatchDto(
id = pvPMatchEntity.id,
matchMode = MatchModeDto.valueOf(pvPMatchEntity.mode.name),
matchVerdict = VerdictDto.valueOf(pvPMatchEntity.verdict.name),
createdAt = pvPMatchEntity.createdAt,
games =
setOf(
GameDto (
game =
PvPGameDto (
id = pvPMatchEntity.game.matchId,
destruction = BigDecimal(pvPMatchEntity.game.destructionPlayer1),
coinsUsed = pvPMatchEntity.game.coinsUsedPlayer1,
status = GameStatusDto.valueOf(pvPMatchEntity.game.status.name)
),
GameDto (
id = pvPMatchEntity.game.matchId,
destruction = BigDecimal(pvPMatchEntity.game.destructionPlayer2),
coinsUsed = pvPMatchEntity.game.coinsUsedPlayer2,
status = GameStatusDto.valueOf(pvPMatchEntity.game.status.name)
)
),
scorePlayer1 = pvPMatchEntity.game.scorePlayer1,
scorePlayer2 = pvPMatchEntity.game.scorePlayer2,
status = PvPGameStatusDto.valueOf(pvPMatchEntity.game.status.name),
),
user1 =
PublicUserDto(
username = pvPMatchEntity.player1.username,
Expand Down Expand Up @@ -394,13 +386,13 @@ class MatchService(
}
}

fun getTopMatches(): List<MatchDto> {
fun getTopMatches(): List<Any> {
val matches = matchRepository.findTop10ByOrderByTotalPointsDesc()
val pvPMatches = pvPMatchRepository.findTop10ByOrderByTotalPointsDesc()
return mapMatchEntitiesToDtos(matches) + mapPvPMatchEntitiesToDtos(pvPMatches)
return listOf(mapMatchEntitiesToDtos(matches) + mapPvPMatchEntitiesToDtos(pvPMatches))
}

fun getUserMatches(userId: UUID): List<MatchDto> {
fun getUserMatches(userId: UUID): List<Any> {
val publicUser = publicUserService.getPublicUser(userId)
val matches = matchRepository.findByPlayer1OrderByCreatedAtDesc(publicUser)
val pvPMatches = pvPMatchRepository.findByPlayer1OrderByCreatedAtDesc(publicUser)
Expand All @@ -418,7 +410,7 @@ class MatchService(
mapper.readValue(gameStatusUpdateJson, GameStatusUpdateEntity::class.java)
val gameId = gameStatusUpdateEntity.gameId

var matchId: UUID
val matchId: UUID
if(gameRepository.findById(gameId).isPresent) {
val game = gameRepository.findById(gameId).get()
matchId = game.matchId // for normal matches, each match has 2 games
Expand Down Expand Up @@ -600,24 +592,22 @@ class MatchService(
simpMessagingTemplate.convertAndSend(
"/updates/${match.player1.userId}",
mapper.writeValueAsString(
GameDto(
PvPGameDto(
id = updatedGame.matchId,
destruction = BigDecimal(updatedGame.destructionPlayer1),
coinsUsed = updatedGame.coinsUsedPlayer1,
status = GameStatusDto.valueOf(updatedGame.status.name),
scorePlayer1 = updatedGame.scorePlayer1,
scorePlayer2 = updatedGame.scorePlayer2,
status = PvPGameStatusDto.valueOf(updatedGame.status.name),
)
)
)
}
if (match.game.status == PvPGameStatusEnum.EXECUTED) {
val verdict =
verdictAlgorithm.getVerdict(
verdictAlgorithm.getPvPVerdict(
match.game.status == PvPGameStatusEnum.EXECUTE_ERROR,
match.game.coinsUsedPlayer1,
match.game.destructionPlayer1,
match.game.scorePlayer1,
match.game.status == PvPGameStatusEnum.EXECUTE_ERROR,
match.game.coinsUsedPlayer2,
match.game.destructionPlayer2
match.game.scorePlayer2,
)
val finishedMatch = match.copy(verdict = verdict)
val (newUserRating, newOpponentRating) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import java.util.UUID
@Document(collection = "pvp_game")
data class PvPGameEntity (
@Id val matchId: UUID,
var destructionPlayer1: Double,
var destructionPlayer2: Double,
var coinsUsedPlayer1: Int,
var coinsUsedPlayer2: Int,
var scorePlayer1: Int,
var scorePlayer2: Int,
var status: PvPGameStatusEnum
)
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,8 @@ class PvPGameService(
val pvPGame =
PvPGameEntity(
matchId = matchId,
destructionPlayer1 = 0.0,
destructionPlayer2 = 0.0,
coinsUsedPlayer1 = 0,
coinsUsedPlayer2 = 0,
scorePlayer1 = 0,
scorePlayer2 = 0,
status = PvPGameStatusEnum.IDLE,
)
return pvPGameRepository.save(pvPGame)
Expand All @@ -63,15 +61,16 @@ class PvPGameService(
if(gameStatusUpdateEntity.gameResultPlayer1 == null || gameStatusUpdateEntity.gameResultPlayer2 == null) {
val newPvPGameEntity = oldPvPGameEntity.copy(status = gameStatusUpdateEntity.gameStatus)
println("newPvPGameEntity: $newPvPGameEntity")
return pvPGameRepository.save(newPvPGameEntity)
println("type of newPvPGameEntity: ${newPvPGameEntity::class.java}")
println("pvPGame: ${pvPGameRepository.save(newPvPGameEntity)}")
println("type of pvPGame: ${pvPGameRepository.save(newPvPGameEntity)::class.java}")
//val pvPGame = pvPGameRepository.save(newPvPGameEntity)
return oldPvPGameEntity
}

val gameResultPlayer1 = gameStatusUpdateEntity.gameResultPlayer1
val gameResultPlayer2 = gameStatusUpdateEntity.gameResultPlayer2

val (destructionPercentagePlayer1, coinsUsedPlayer1) = gameResultPlayer1
val (destructionPercentagePlayer2, coinsUsedPlayer2) = gameResultPlayer2

val gameStatus =
if (gameResultPlayer1.hasErrors || gameResultPlayer2.hasErrors) {
PvPGameStatusEnum.EXECUTE_ERROR
Expand All @@ -81,10 +80,8 @@ class PvPGameService(

val newPvPGameEntity =
oldPvPGameEntity.copy(
destructionPlayer1 = destructionPercentagePlayer1,
coinsUsedPlayer1 = coinsUsedPlayer1,
destructionPlayer2 = destructionPercentagePlayer2,
coinsUsedPlayer2 = coinsUsedPlayer2,
scorePlayer1 = gameResultPlayer1.score,
scorePlayer2 = gameResultPlayer2.score,
status = gameStatus
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ package delta.codecharacter.server.pvp_game.queue.entities
import com.fasterxml.jackson.annotation.JsonProperty

data class PvPGameResultEntity (
@field:JsonProperty("destruction_percentage", required = true) val destructionPercentage: Double,
@field:JsonProperty("coins_used", required = true) val coinsUsed: Int,
@field:JsonProperty("score", required = true) val score: Int,
@field:JsonProperty("has_errors", required = true) val hasErrors: Boolean,
@field:JsonProperty("log", required = true) val log: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ internal class RabbitIntegrationTest(@Autowired val mockMvc: MockMvc) {
mongoTemplate.save<PublicUserEntity>(TestAttributes.publicUser)
try {
rabbitAdmin.purgeQueue("gameRequestQueue", true)
rabbitAdmin.purgeQueue("gamePvPRequestQueue", true)
rabbitAdmin.purgeQueue("gameStatusUpdateQueue", true)
} catch (e: Exception) {
println("RabbitMQ queues are not available")
Expand Down Expand Up @@ -370,6 +371,7 @@ internal class RabbitIntegrationTest(@Autowired val mockMvc: MockMvc) {

try {
rabbitAdmin.purgeQueue("gameRequestQueue", true)
rabbitAdmin.purgeQueue("gamePvPRequestQueue", true)
rabbitAdmin.purgeQueue("gameStatusUpdateQueue", true)
} catch (e: Exception) {
println("RabbitMQ queues are not available")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,8 @@ internal class PvPGameControllerIntegrationTest(@Autowired val mockMvc: MockMvc)
val pvPGameEntity =
PvPGameEntity(
matchId = UUID.randomUUID(),
destructionPlayer1 = 100.0,
destructionPlayer2 = 100.0,
coinsUsedPlayer1 = 100,
coinsUsedPlayer2 = 100,
scorePlayer1 = 0,
scorePlayer2 = 0,
status = PvPGameStatusEnum.EXECUTED,
)
mongoTemplate.save<PvPGameEntity>(pvPGameEntity)
Expand Down
Loading

0 comments on commit 61bff55

Please sign in to comment.