From fb38e43ba12837dee49394cafce18ed6ed5d5259 Mon Sep 17 00:00:00 2001 From: Bhoopesh Date: Fri, 2 Feb 2024 16:39:34 +0530 Subject: [PATCH] feat: add self match for pvp --- docs/spec/CodeCharacter-API.yml | 6 ++ .../dtos/CreateMatchRequestDto.kt | 6 +- .../delta/codecharacter/dtos/MatchModeDto.kt | 5 +- .../server/match/MatchModeEnum.kt | 1 + .../server/match/MatchService.kt | 69 +++++++++++++++++-- 5 files changed, 78 insertions(+), 9 deletions(-) diff --git a/docs/spec/CodeCharacter-API.yml b/docs/spec/CodeCharacter-API.yml index 3b54fa7..f1c4088 100644 --- a/docs/spec/CodeCharacter-API.yml +++ b/docs/spec/CodeCharacter-API.yml @@ -1949,6 +1949,11 @@ components: format: uuid description: Revision of the code nullable: true + codeRevisionId2: + type: string + format: uuid + description: Revision of the code (for SELF-PVP mode) + nullable: true required: - mode Game: @@ -2110,6 +2115,7 @@ components: - AUTO - DAILYCHALLENGE - PVP + - SELFPVP description: Match Mode Verdict: type: string diff --git a/library/src/main/kotlin/delta/codecharacter/dtos/CreateMatchRequestDto.kt b/library/src/main/kotlin/delta/codecharacter/dtos/CreateMatchRequestDto.kt index 8e50f95..8a64198 100644 --- a/library/src/main/kotlin/delta/codecharacter/dtos/CreateMatchRequestDto.kt +++ b/library/src/main/kotlin/delta/codecharacter/dtos/CreateMatchRequestDto.kt @@ -21,6 +21,7 @@ import io.swagger.v3.oas.annotations.media.Schema * @param opponentUsername Username of the opponent * @param mapRevisionId Revision ID of the map * @param codeRevisionId Revision of the code + * @param codeRevisionId2 Revision of the code (for SELF-PVP mode) */ data class CreateMatchRequestDto( @@ -35,7 +36,10 @@ data class CreateMatchRequestDto( @get:JsonProperty("mapRevisionId") val mapRevisionId: java.util.UUID? = null, @Schema(example = "null", description = "Revision of the code") - @get:JsonProperty("codeRevisionId") val codeRevisionId: java.util.UUID? = null + @get:JsonProperty("codeRevisionId") val codeRevisionId: java.util.UUID? = null, + + @Schema(example = "null", description = "Revision of the code (for SELF-PVP mode)") + @get:JsonProperty("codeRevisionId2") val codeRevisionId2: java.util.UUID? = null ) { } diff --git a/library/src/main/kotlin/delta/codecharacter/dtos/MatchModeDto.kt b/library/src/main/kotlin/delta/codecharacter/dtos/MatchModeDto.kt index 3e70651..1904ec6 100644 --- a/library/src/main/kotlin/delta/codecharacter/dtos/MatchModeDto.kt +++ b/library/src/main/kotlin/delta/codecharacter/dtos/MatchModeDto.kt @@ -16,7 +16,7 @@ import io.swagger.v3.oas.annotations.media.Schema /** * Match Mode -* Values: SELF,MANUAL,AUTO,DAILYCHALLENGE,PVP +* Values: SELF,MANUAL,AUTO,DAILYCHALLENGE,PVP,SELFPVP */ enum class MatchModeDto(val value: kotlin.String) { @@ -24,6 +24,7 @@ enum class MatchModeDto(val value: kotlin.String) { @JsonProperty("MANUAL") MANUAL("MANUAL"), @JsonProperty("AUTO") AUTO("AUTO"), @JsonProperty("DAILYCHALLENGE") DAILYCHALLENGE("DAILYCHALLENGE"), - @JsonProperty("PVP") PVP("PVP") + @JsonProperty("PVP") PVP("PVP"), + @JsonProperty("SELFPVP") SELFPVP("SELFPVP") } diff --git a/server/src/main/kotlin/delta/codecharacter/server/match/MatchModeEnum.kt b/server/src/main/kotlin/delta/codecharacter/server/match/MatchModeEnum.kt index 4564376..b5b27be 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/match/MatchModeEnum.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/match/MatchModeEnum.kt @@ -2,6 +2,7 @@ package delta.codecharacter.server.match enum class MatchModeEnum { SELF, + SELFPVP, MANUAL, AUTO, PVP diff --git a/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt b/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt index 6152bd6..951f864 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt @@ -69,7 +69,7 @@ class MatchService( private var mapper: ObjectMapper = jackson2ObjectMapperBuilder.build() private val logger: Logger = LoggerFactory.getLogger(MatchService::class.java) - private fun createSelfMatch(userId: UUID, codeRevisionId: UUID?, mapRevisionId: UUID?) { + private fun createNormalSelfMatch(userId: UUID, codeRevisionId: UUID?, mapRevisionId: UUID?) { val code: String val language: LanguageEnum if (codeRevisionId == null) { @@ -113,7 +113,60 @@ class MatchService( gameService.sendGameRequest(game, code, LanguageEnum.valueOf(language.name), map) } - fun createNormalMatch( + private fun createPvPSelfMatch(userId: UUID, codeRevisionId1: UUID?, codeRevisionId2: UUID?) { + val code1: String + val code2: String + val language1: LanguageEnum + val language2: LanguageEnum + + if (codeRevisionId1 == null && codeRevisionId2 == null) { + throw CustomException(HttpStatus.BAD_REQUEST, "At least one revision ID is required") + } + + if (codeRevisionId1 == null) { + val latestCode = latestCodeService.getLatestCode(userId, CodeTypeDto.PVP) + code1 = latestCode.code + language1 = LanguageEnum.valueOf(latestCode.language.name) + } else { + val codeRevision = + codeRevisionService.getCodeRevisions(userId, CodeTypeDto.PVP).find { it.id == codeRevisionId1 } + ?: throw CustomException(HttpStatus.BAD_REQUEST, "Invalid revision ID") + code1 = codeRevision.code + language1 = LanguageEnum.valueOf(codeRevision.language.name) + } + + if (codeRevisionId2 == null) { + val latestCode = latestCodeService.getLatestCode(userId, CodeTypeDto.PVP) + code2 = latestCode.code + language2 = LanguageEnum.valueOf(latestCode.language.name) + } + else { + val codeRevision = + codeRevisionService.getCodeRevisions(userId, CodeTypeDto.PVP).find { it.id == codeRevisionId2 } + ?: throw CustomException(HttpStatus.BAD_REQUEST, "Invalid revision ID") + code2 = codeRevision.code + language2 = LanguageEnum.valueOf(codeRevision.language.name) + } + + val matchId = UUID.randomUUID() + val game = pvPGameService.createPvPGame(matchId) + val publicUser = publicUserService.getPublicUser(userId) + val match = + PvPMatchEntity( + id = matchId, + game = game, + mode = MatchModeEnum.PVP, + verdict = MatchVerdictEnum.TIE, + createdAt = Instant.now(), + totalPoints = 0, + player1 = publicUser, + player2 = publicUser, + ) + pvPMatchRepository.save(match) + pvPGameService.sendPvPGameRequest(game, GameCode(code1, language1), GameCode(code2, language2)) + } + + private fun createNormalMatch( publicUser: PublicUserEntity, publicOpponent: PublicUserEntity, mode: MatchModeEnum @@ -154,7 +207,7 @@ class MatchService( return matchId } - fun createPvPMatch(publicUser: PublicUserEntity, publicOpponent: PublicUserEntity) : UUID { + private fun createPvPMatch(publicUser: PublicUserEntity, publicOpponent: PublicUserEntity) : UUID { val userId = publicUser.userId val opponentId = publicOpponent.userId @@ -183,7 +236,7 @@ class MatchService( return matchId } - fun createDualMatch(userId: UUID, opponentUsername: String, mode: MatchModeEnum): UUID { + private fun createDualMatch(userId: UUID, opponentUsername: String, mode: MatchModeEnum): UUID { val publicUser = publicUserService.getPublicUser(userId) val publicOpponent = publicUserService.getPublicUserByUsername(opponentUsername) val opponentId = publicOpponent.userId @@ -246,8 +299,12 @@ class MatchService( fun createMatch(userId: UUID, createMatchRequestDto: CreateMatchRequestDto) { when (createMatchRequestDto.mode) { MatchModeDto.SELF -> { - val (_, _, mapRevisionId, codeRevisionId) = createMatchRequestDto - createSelfMatch(userId, codeRevisionId, mapRevisionId) + val (_, _, mapRevisionId, codeRevisionId, _) = createMatchRequestDto + createNormalSelfMatch(userId, codeRevisionId, mapRevisionId) + } + MatchModeDto.SELFPVP -> { + val (_, _, codeRevisionId1, _, codeRevisionId2) = createMatchRequestDto + createPvPSelfMatch(userId, codeRevisionId1, codeRevisionId2) } MatchModeDto.MANUAL, MatchModeDto.AUTO , MatchModeDto.PVP -> { if (createMatchRequestDto.opponentUsername == null) {