From 9e5cb5265ebedde1f7dae195e8f069bc3f5716a7 Mon Sep 17 00:00:00 2001 From: b1otch Date: Sat, 31 Dec 2022 07:40:21 +0530 Subject: [PATCH 01/26] feat(Daily Challenge Leaderboard): Added the DailyChallengeLeaderboard in PublicUserService --- library/build.gradle.kts | 3 +++ .../codecharacter/core/DailyChallengesApi.kt | 10 +++++++++- .../daily_challenges/DailyChallengeEntity.kt | 14 ++++++++++++++ .../DailyChallengesRepository.kt | 7 +++++++ .../DailyChallengeLeaderboardController.kt | 16 ++++++++++++++++ 5 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengeEntity.kt create mode 100644 server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengesRepository.kt create mode 100644 server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt diff --git a/library/build.gradle.kts b/library/build.gradle.kts index 7f0af371..5dc0a949 100644 --- a/library/build.gradle.kts +++ b/library/build.gradle.kts @@ -41,6 +41,9 @@ dependencies { implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.0") implementation("io.swagger.core.v3:swagger-annotations:2.2.7") implementation("io.swagger.core.v3:swagger-core:2.2.7") + implementation("org.hibernate:hibernate-core:6.1.6.Final") + implementation("mysql:mysql-connector-java:8.0.30") + implementation("org.apache.commons:commons-dbcp2:2.9.0") testImplementation("org.jetbrains.kotlin:kotlin-test-junit5:1.6.0") testImplementation("org.springframework.boot:spring-boot-starter-test:3.0.0") { diff --git a/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt b/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt index 2950dd4e..aa8925ec 100644 --- a/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt +++ b/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt @@ -23,8 +23,16 @@ import org.springframework.validation.annotation.Validated import org.springframework.web.context.request.NativeWebRequest import org.springframework.beans.factory.annotation.Autowired -import jakarta.validation.constraints.* import jakarta.validation.Valid +import jakarta.validation.constraints.DecimalMax +import jakarta.validation.constraints.DecimalMin +import jakarta.validation.constraints.Email +import jakarta.validation.constraints.Max +import jakarta.validation.constraints.Min +import jakarta.validation.constraints.NotNull +import jakarta.validation.constraints.Pattern +import jakarta.validation.constraints.Size +import java.util.Date import kotlin.collections.List import kotlin.collections.Map diff --git a/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengeEntity.kt b/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengeEntity.kt new file mode 100644 index 00000000..bdb521eb --- /dev/null +++ b/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengeEntity.kt @@ -0,0 +1,14 @@ +package delta.codecharacter.server.daily_challenges + +import delta.codecharacter.dtos.ChallengeTypeDto +import org.springframework.data.annotation.Id +import org.springframework.data.mongodb.core.mapping.Document +import java.util.* + +@Document(collection = "daily_challenges") // change it later +data class DailyChallengeEntity( + @Id val id: UUID, + val challName: String, + val challType: ChallengeTypeDto, + val chall: String, + ) diff --git a/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengesRepository.kt b/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengesRepository.kt new file mode 100644 index 00000000..87edf65e --- /dev/null +++ b/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengesRepository.kt @@ -0,0 +1,7 @@ +package delta.codecharacter.server.daily_challenges + +import org.springframework.data.mongodb.repository.MongoRepository +import java.util.UUID + +interface DailyChallengesRepository : MongoRepository { +} diff --git a/server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt b/server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt new file mode 100644 index 00000000..58d95c38 --- /dev/null +++ b/server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt @@ -0,0 +1,16 @@ +package delta.codecharacter.server.leaderboard + +import delta.codecharacter.core.DailyChallengesApi +import delta.codecharacter.dtos.DailyChallengeLeaderBoardResponseDto +import delta.codecharacter.server.user.public_user.PublicUserService +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.RestController + +@RestController +class DailyChallengeLeaderboardController(@Autowired private val publicUserService: PublicUserService) : + DailyChallengesApi { + override fun getDailyChallengeLeaderBoard(page : Int?, size : Int?): ResponseEntity> { + return ResponseEntity.ok(publicUserService.getDailyChallengeLeaderboard(page, size)) + } +} From c8ef61f55a3415007b0030fc94c335b97fc43818 Mon Sep 17 00:00:00 2001 From: b1otch Date: Sun, 1 Jan 2023 09:11:50 +0530 Subject: [PATCH 02/26] fixed the changing of core files --- library/build.gradle.kts | 3 --- .../kotlin/delta/codecharacter/core/DailyChallengesApi.kt | 2 +- .../server/leaderboard/DailyChallengeLeaderboardController.kt | 4 ++-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/library/build.gradle.kts b/library/build.gradle.kts index 5dc0a949..7f0af371 100644 --- a/library/build.gradle.kts +++ b/library/build.gradle.kts @@ -41,9 +41,6 @@ dependencies { implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.0") implementation("io.swagger.core.v3:swagger-annotations:2.2.7") implementation("io.swagger.core.v3:swagger-core:2.2.7") - implementation("org.hibernate:hibernate-core:6.1.6.Final") - implementation("mysql:mysql-connector-java:8.0.30") - implementation("org.apache.commons:commons-dbcp2:2.9.0") testImplementation("org.jetbrains.kotlin:kotlin-test-junit5:1.6.0") testImplementation("org.springframework.boot:spring-boot-starter-test:3.0.0") { diff --git a/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt b/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt index aa8925ec..c5554253 100644 --- a/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt +++ b/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt @@ -100,7 +100,7 @@ interface DailyChallengesApi { value = ["/dc/leaderboard"], produces = ["application/json"] ) - fun getDailyChallengeLeaderBoard(@Parameter(description = "Index of the page") @Valid @RequestParam(value = "page", required = false) page: kotlin.Int?,@Parameter(description = "Size of the page") @Valid @RequestParam(value = "size", required = false) size: kotlin.Int?): ResponseEntity> { + fun getDailyChallengeLeaderBoard(): ResponseEntity> { return ResponseEntity(HttpStatus.NOT_IMPLEMENTED) } } diff --git a/server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt b/server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt index 58d95c38..d4da7bad 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt @@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.RestController @RestController class DailyChallengeLeaderboardController(@Autowired private val publicUserService: PublicUserService) : DailyChallengesApi { - override fun getDailyChallengeLeaderBoard(page : Int?, size : Int?): ResponseEntity> { - return ResponseEntity.ok(publicUserService.getDailyChallengeLeaderboard(page, size)) + override fun getDailyChallengeLeaderBoard(): ResponseEntity> { + return ResponseEntity.ok(publicUserService.getDailyChallengeLeaderboard()) } } From 6e63e65b1b0ed0089df789679fca103a53b43729 Mon Sep 17 00:00:00 2001 From: Ram-20062003 Date: Mon, 2 Jan 2023 22:50:29 +0530 Subject: [PATCH 03/26] update: Added pagination parameters to dc-leaderboard in open-api --- .../main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt b/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt index c5554253..60fdb5f7 100644 --- a/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt +++ b/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt @@ -32,7 +32,6 @@ import jakarta.validation.constraints.Min import jakarta.validation.constraints.NotNull import jakarta.validation.constraints.Pattern import jakarta.validation.constraints.Size -import java.util.Date import kotlin.collections.List import kotlin.collections.Map @@ -100,7 +99,7 @@ interface DailyChallengesApi { value = ["/dc/leaderboard"], produces = ["application/json"] ) - fun getDailyChallengeLeaderBoard(): ResponseEntity> { + fun getDailyChallengeLeaderBoard(@Parameter(description = "Index of the page") @Valid @RequestParam(value = "page", required = false) page: kotlin.Int?,@Parameter(description = "Size of the page") @Valid @RequestParam(value = "size", required = false) size: kotlin.Int?): ResponseEntity> { return ResponseEntity(HttpStatus.NOT_IMPLEMENTED) } } From 943eba5df60ceb28dfc6b98e91f535bf24e1af0b Mon Sep 17 00:00:00 2001 From: b1otch Date: Mon, 2 Jan 2023 23:09:09 +0530 Subject: [PATCH 04/26] fix(): Fixed the type of score(dc) --- .../server/leaderboard/DailyChallengeLeaderboardController.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt b/server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt index d4da7bad..e220d7c8 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt @@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.RestController @RestController class DailyChallengeLeaderboardController(@Autowired private val publicUserService: PublicUserService) : DailyChallengesApi { - override fun getDailyChallengeLeaderBoard(): ResponseEntity> { - return ResponseEntity.ok(publicUserService.getDailyChallengeLeaderboard()) + override fun getDailyChallengeLeaderBoard(page :Int?, size : Int?): ResponseEntity> { + return ResponseEntity.ok(publicUserService.getDailyChallengeLeaderboard(page, size)) } } From d67a1ea3daeeac7bd62e9b2d9c13ef96134824d9 Mon Sep 17 00:00:00 2001 From: b1otch Date: Mon, 2 Jan 2023 23:32:24 +0530 Subject: [PATCH 05/26] fix(lint issues): fixed lint issues --- .../server/daily_challenges/DailyChallengeEntity.kt | 4 ++-- .../daily_challenges/DailyChallengesRepository.kt | 3 +-- .../leaderboard/DailyChallengeLeaderboardController.kt | 10 +++++++--- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengeEntity.kt b/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengeEntity.kt index bdb521eb..30fa3790 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengeEntity.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengeEntity.kt @@ -3,7 +3,7 @@ package delta.codecharacter.server.daily_challenges import delta.codecharacter.dtos.ChallengeTypeDto import org.springframework.data.annotation.Id import org.springframework.data.mongodb.core.mapping.Document -import java.util.* +import java.util.UUID @Document(collection = "daily_challenges") // change it later data class DailyChallengeEntity( @@ -11,4 +11,4 @@ data class DailyChallengeEntity( val challName: String, val challType: ChallengeTypeDto, val chall: String, - ) +) diff --git a/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengesRepository.kt b/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengesRepository.kt index 87edf65e..9709b16d 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengesRepository.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengesRepository.kt @@ -3,5 +3,4 @@ package delta.codecharacter.server.daily_challenges import org.springframework.data.mongodb.repository.MongoRepository import java.util.UUID -interface DailyChallengesRepository : MongoRepository { -} +interface DailyChallengesRepository : MongoRepository diff --git a/server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt b/server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt index e220d7c8..8e6084b3 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt @@ -8,9 +8,13 @@ import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.RestController @RestController -class DailyChallengeLeaderboardController(@Autowired private val publicUserService: PublicUserService) : - DailyChallengesApi { - override fun getDailyChallengeLeaderBoard(page :Int?, size : Int?): ResponseEntity> { +class DailyChallengeLeaderboardController( + @Autowired private val publicUserService: PublicUserService +) : DailyChallengesApi { + override fun getDailyChallengeLeaderBoard( + page: Int?, + size: Int? + ): ResponseEntity> { return ResponseEntity.ok(publicUserService.getDailyChallengeLeaderboard(page, size)) } } From 9037a5df1ab6f3b6bed40be3b8b35ee715a31dc8 Mon Sep 17 00:00:00 2001 From: b1otch Date: Thu, 5 Jan 2023 07:12:29 +0530 Subject: [PATCH 06/26] fix(Removed Unnecessary Files): Removed Entity and Repository files --- .../daily_challenges/DailyChallengeEntity.kt | 14 -------------- .../daily_challenges/DailyChallengesRepository.kt | 6 ------ 2 files changed, 20 deletions(-) delete mode 100644 server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengeEntity.kt delete mode 100644 server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengesRepository.kt diff --git a/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengeEntity.kt b/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengeEntity.kt deleted file mode 100644 index 30fa3790..00000000 --- a/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengeEntity.kt +++ /dev/null @@ -1,14 +0,0 @@ -package delta.codecharacter.server.daily_challenges - -import delta.codecharacter.dtos.ChallengeTypeDto -import org.springframework.data.annotation.Id -import org.springframework.data.mongodb.core.mapping.Document -import java.util.UUID - -@Document(collection = "daily_challenges") // change it later -data class DailyChallengeEntity( - @Id val id: UUID, - val challName: String, - val challType: ChallengeTypeDto, - val chall: String, -) diff --git a/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengesRepository.kt b/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengesRepository.kt deleted file mode 100644 index 9709b16d..00000000 --- a/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengesRepository.kt +++ /dev/null @@ -1,6 +0,0 @@ -package delta.codecharacter.server.daily_challenges - -import org.springframework.data.mongodb.repository.MongoRepository -import java.util.UUID - -interface DailyChallengesRepository : MongoRepository From a093eb98429eeea61f9fc9973bf309d855cabb52 Mon Sep 17 00:00:00 2001 From: b1otch Date: Thu, 9 Feb 2023 19:32:39 +0530 Subject: [PATCH 07/26] feat(Auto Matches): Added auto matches functionality and rating --- docs/spec/CodeCharacter-API.yml | 37 ++++++++++ .../server/match/AutoMatchEntity.kt | 11 +++ .../server/match/AutoMatchRepository.kt | 7 ++ .../server/match/MatchRepository.kt | 1 + .../server/match/MatchService.kt | 40 ++++++++++- .../user/public_user/PublicUserRepository.kt | 1 + .../user/public_user/PublicUserService.kt | 8 +++ .../rating_history/RatingHistoryService.kt | 70 +++++++++++++++++++ 8 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 server/src/main/kotlin/delta/codecharacter/server/match/AutoMatchEntity.kt create mode 100644 server/src/main/kotlin/delta/codecharacter/server/match/AutoMatchRepository.kt diff --git a/docs/spec/CodeCharacter-API.yml b/docs/spec/CodeCharacter-API.yml index ed6e545e..db96f820 100644 --- a/docs/spec/CodeCharacter-API.yml +++ b/docs/spec/CodeCharacter-API.yml @@ -303,6 +303,33 @@ paths: description: Leaderboard Tier description: Get leaderboard parameters: [] + + /leaderboard/size: + get: + summary: Get LeaderboardSize + tags: + - leaderboard + responses: + '200': + description: OK + content: + application/json: + schema: + type: number + items: + $ref: '#/components/schemas/LeaderboardSize' + examples: + Example: + value: + - leaderboardSize: 10 + '401' : + description: Unauthorized + '404' : + description: Not Found + operationId: getLeaderboardSize + description: Get Leaderboard Size + parameters: [] + /top-matches: get: summary: Get top matches @@ -1934,6 +1961,16 @@ components: - user - stats description: Leaderboard entry model + LeaderboardSize: + title: LeaderboardSize + type: object + properties: + leaderboardSize: + type: number + example: 10 + required: + - leaderboardSize + DailyChallengeGetRequest: title: Get daily challenge description: Get current-user daily challenge diff --git a/server/src/main/kotlin/delta/codecharacter/server/match/AutoMatchEntity.kt b/server/src/main/kotlin/delta/codecharacter/server/match/AutoMatchEntity.kt new file mode 100644 index 00000000..73e5751e --- /dev/null +++ b/server/src/main/kotlin/delta/codecharacter/server/match/AutoMatchEntity.kt @@ -0,0 +1,11 @@ +package delta.codecharacter.server.match + +import org.springframework.data.annotation.Id +import org.springframework.data.mongodb.core.mapping.Document +import java.util.UUID + +@Document(collection = "auto_match") +data class AutoMatchEntity( + @Id val matchId: UUID, + val tries: Int, +) diff --git a/server/src/main/kotlin/delta/codecharacter/server/match/AutoMatchRepository.kt b/server/src/main/kotlin/delta/codecharacter/server/match/AutoMatchRepository.kt new file mode 100644 index 00000000..6637962f --- /dev/null +++ b/server/src/main/kotlin/delta/codecharacter/server/match/AutoMatchRepository.kt @@ -0,0 +1,7 @@ +package delta.codecharacter.server.match + +import org.springframework.data.mongodb.repository.MongoRepository +import org.springframework.stereotype.Repository +import java.util.UUID + +@Repository interface AutoMatchRepository : MongoRepository diff --git a/server/src/main/kotlin/delta/codecharacter/server/match/MatchRepository.kt b/server/src/main/kotlin/delta/codecharacter/server/match/MatchRepository.kt index 124ba5b8..a5d94a55 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/match/MatchRepository.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/match/MatchRepository.kt @@ -9,4 +9,5 @@ import java.util.UUID interface MatchRepository : MongoRepository { fun findTop10ByOrderByTotalPointsDesc(): List fun findByPlayer1OrderByCreatedAtDesc(player1: PublicUserEntity): List + fun findByIdIn(matchIds: List): List } 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 7a2949ba..3f38a759 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt @@ -35,6 +35,7 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.http.HttpStatus import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder import org.springframework.messaging.simp.SimpMessagingTemplate +import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Service import java.math.BigDecimal import java.time.Duration @@ -206,6 +207,22 @@ class MatchService( } } + @Scheduled(cron = "* */6 * * * *") + fun createAutoMatch() { + val top20Users = publicUserService.getTop20() + val userIds = top20Users.map { it.userId } + val usernames = top20Users.map { it.username } + autoMatchRepository.deleteAll() + userIds.forEachIndexed { i, userId -> + run { + for (j in i + 1 until userIds.size) { + val opponentUsername = usernames[j] + createDualMatch(userId, opponentUsername) + } + } + } + } + private fun mapMatchEntitiesToDtos(matchEntities: List): List { return matchEntities.map { matchEntity -> MatchDto( @@ -360,7 +377,28 @@ class MatchService( } against ${match.player2.username}", ) } - + if (match.mode == MatchModeEnum.AUTO) { + if (autoMatchRepository.findAll().all { autoMatch -> + matchRepository.findById(autoMatch.matchId).get().games.all { game -> + game.status == GameStatusEnum.EXECUTED || game.status == GameStatusEnum.EXECUTE_ERROR + } + } + ) { + val matches = matchRepository.findByIdIn(autoMatchRepository.findAll().map { it.matchId }) + val userIds = + matches.map { it.player1.userId }.toSet() + matches.map { it.player2.userId }.toSet() + val newRatings = + ratingHistoryService.updateAndGetAutoMatchRatings(userIds.toList(), matches) + newRatings.forEach { (userId, newRating) -> + publicUserService.updatePublicRating( + userId = userId, + isInitiator = true, + verdict = verdict, + newRating = newRating.rating + ) + } + } + } matchRepository.save(finishedMatch) } } else if (dailyChallengeMatchRepository.findById(matchId).isPresent) { diff --git a/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserRepository.kt b/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserRepository.kt index 09883522..e5dbca65 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserRepository.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserRepository.kt @@ -8,6 +8,7 @@ import java.util.UUID interface PublicUserRepository : MongoRepository { fun findByUsername(username: String): Optional + fun findTop20ByOrderByRatingDesc(): List fun findAllByTier(tier: TierTypeDto?, pageRequest: PageRequest): List } diff --git a/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserService.kt b/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserService.kt index e2e4eec6..69b1b4a5 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserService.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserService.kt @@ -142,6 +142,10 @@ class PublicUserService(@Autowired private val publicUserRepository: PublicUserR } } + fun getLeaderboardSize(): Long { + return publicUserRepository.count() + } + fun getDailyChallengeLeaderboard( page: Int?, size: Int? @@ -282,4 +286,8 @@ class PublicUserService(@Autowired private val publicUserRepository: PublicUserR val updatedUser = user.copy(score = user.score + score, dailyChallengeHistory = current) publicUserRepository.save(updatedUser) } + + fun getTop20(): List { + return publicUserRepository.findTop20ByOrderByRatingDesc() + } } diff --git a/server/src/main/kotlin/delta/codecharacter/server/user/rating_history/RatingHistoryService.kt b/server/src/main/kotlin/delta/codecharacter/server/user/rating_history/RatingHistoryService.kt index a838d5f7..7de0ada7 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/user/rating_history/RatingHistoryService.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/user/rating_history/RatingHistoryService.kt @@ -3,6 +3,7 @@ package delta.codecharacter.server.user.rating_history import delta.codecharacter.dtos.RatingHistoryDto import delta.codecharacter.server.logic.rating.GlickoRating import delta.codecharacter.server.logic.rating.RatingAlgorithm +import delta.codecharacter.server.match.MatchEntity import delta.codecharacter.server.match.MatchVerdictEnum import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Service @@ -93,4 +94,73 @@ class RatingHistoryService( return Pair(newUserRating.rating, newOpponentRating.rating) } + + private fun getNewRatingAfterAutoMatches( + userId: UUID, + userRatings: Map, + autoMatches: List + ): GlickoRating { + val userAsInitiatorMatches = autoMatches.filter { it.player1.userId == userId } + val userAsOpponentMatches = autoMatches.filter { it.player2.userId == userId } + + val usersWeightedRatingDeviations = + userRatings + .map { + it.key to + ratingAlgorithm.getWeightedRatingDeviationSinceLastCompetition( + it.value.ratingDeviation, it.value.validFrom + ) + } + .toMap() + + val ratingsForUserAsPlayer1 = + userAsInitiatorMatches.map { match -> + GlickoRating(match.player2.rating, usersWeightedRatingDeviations[match.player2.userId]!!) + } + val verdictsForUserAsPlayer1 = + userAsInitiatorMatches.map { match -> convertVerdictToMatchResult(match.verdict) } + + val ratingsForUserAsPlayer2 = + userAsOpponentMatches.map { match -> + GlickoRating(match.player1.rating, usersWeightedRatingDeviations[match.player1.userId]!!) + } + val verdictsForUserAsPlayer2 = + userAsOpponentMatches.map { match -> 1.0 - convertVerdictToMatchResult(match.verdict) } + + val ratings = ratingsForUserAsPlayer1 + ratingsForUserAsPlayer2 + val verdicts = verdictsForUserAsPlayer1 + verdictsForUserAsPlayer2 + + return ratingAlgorithm.calculateNewRating( + GlickoRating(userRatings[userId]!!.rating, usersWeightedRatingDeviations[userId]!!), + ratings, + verdicts + ) + } + + fun updateAndGetAutoMatchRatings( + userIds: List, + matches: List + ): Map { + val userRatings = + userIds.associateWith { userId -> + ratingHistoryRepository.findFirstByUserIdOrderByValidFromDesc(userId) + } + val newRatings = + userIds.associateWith { userId -> + getNewRatingAfterAutoMatches(userId, userRatings, matches) + } + val currentInstant = Instant.now() + newRatings.forEach { (userId, rating) -> + ratingHistoryRepository.save( + RatingHistoryEntity( + userId = userId, + rating = rating.rating, + ratingDeviation = rating.ratingDeviation, + validFrom = currentInstant + ) + ) + } + + return newRatings + } } From 2b5d05c6031403967670d42ce5b3a8cf484caa79 Mon Sep 17 00:00:00 2001 From: b1otch Date: Sat, 31 Dec 2022 07:40:21 +0530 Subject: [PATCH 08/26] feat(Daily Challenge Leaderboard): Added the DailyChallengeLeaderboard in PublicUserService --- library/build.gradle.kts | 3 +++ .../delta/codecharacter/core/DailyChallengesApi.kt | 1 + .../daily_challenges/DailyChallengeEntity.kt | 14 ++++++++++++++ .../daily_challenges/DailyChallengesRepository.kt | 7 +++++++ 4 files changed, 25 insertions(+) create mode 100644 server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengeEntity.kt create mode 100644 server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengesRepository.kt diff --git a/library/build.gradle.kts b/library/build.gradle.kts index 7f0af371..5dc0a949 100644 --- a/library/build.gradle.kts +++ b/library/build.gradle.kts @@ -41,6 +41,9 @@ dependencies { implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.0") implementation("io.swagger.core.v3:swagger-annotations:2.2.7") implementation("io.swagger.core.v3:swagger-core:2.2.7") + implementation("org.hibernate:hibernate-core:6.1.6.Final") + implementation("mysql:mysql-connector-java:8.0.30") + implementation("org.apache.commons:commons-dbcp2:2.9.0") testImplementation("org.jetbrains.kotlin:kotlin-test-junit5:1.6.0") testImplementation("org.springframework.boot:spring-boot-starter-test:3.0.0") { diff --git a/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt b/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt index 60fdb5f7..aa8925ec 100644 --- a/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt +++ b/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt @@ -32,6 +32,7 @@ import jakarta.validation.constraints.Min import jakarta.validation.constraints.NotNull import jakarta.validation.constraints.Pattern import jakarta.validation.constraints.Size +import java.util.Date import kotlin.collections.List import kotlin.collections.Map diff --git a/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengeEntity.kt b/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengeEntity.kt new file mode 100644 index 00000000..bdb521eb --- /dev/null +++ b/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengeEntity.kt @@ -0,0 +1,14 @@ +package delta.codecharacter.server.daily_challenges + +import delta.codecharacter.dtos.ChallengeTypeDto +import org.springframework.data.annotation.Id +import org.springframework.data.mongodb.core.mapping.Document +import java.util.* + +@Document(collection = "daily_challenges") // change it later +data class DailyChallengeEntity( + @Id val id: UUID, + val challName: String, + val challType: ChallengeTypeDto, + val chall: String, + ) diff --git a/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengesRepository.kt b/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengesRepository.kt new file mode 100644 index 00000000..87edf65e --- /dev/null +++ b/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengesRepository.kt @@ -0,0 +1,7 @@ +package delta.codecharacter.server.daily_challenges + +import org.springframework.data.mongodb.repository.MongoRepository +import java.util.UUID + +interface DailyChallengesRepository : MongoRepository { +} From a8062f6f9bed311860ee00e47a05a29f843688dd Mon Sep 17 00:00:00 2001 From: b1otch Date: Sat, 31 Dec 2022 07:40:21 +0530 Subject: [PATCH 09/26] feat(Daily Challenge Leaderboard): Added the DailyChallengeLeaderboard in PublicUserService --- .../main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt b/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt index aa8925ec..ab165718 100644 --- a/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt +++ b/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt @@ -23,6 +23,7 @@ import org.springframework.validation.annotation.Validated import org.springframework.web.context.request.NativeWebRequest import org.springframework.beans.factory.annotation.Autowired +import jakarta.validation.constraints.* import jakarta.validation.Valid import jakarta.validation.constraints.DecimalMax import jakarta.validation.constraints.DecimalMin From c45cc47483643fcd1a7ea807906c3ca8079bcf83 Mon Sep 17 00:00:00 2001 From: b1otch Date: Sun, 19 Feb 2023 19:08:44 +0530 Subject: [PATCH 10/26] fix(lint fixes): Fixed lint issues --- .../DailyChallengeLeaderboardController.kt | 20 ------------------- .../server/match/MatchService.kt | 12 ++++++----- 2 files changed, 7 insertions(+), 25 deletions(-) delete mode 100644 server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt diff --git a/server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt b/server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt deleted file mode 100644 index 8e6084b3..00000000 --- a/server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt +++ /dev/null @@ -1,20 +0,0 @@ -package delta.codecharacter.server.leaderboard - -import delta.codecharacter.core.DailyChallengesApi -import delta.codecharacter.dtos.DailyChallengeLeaderBoardResponseDto -import delta.codecharacter.server.user.public_user.PublicUserService -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.http.ResponseEntity -import org.springframework.web.bind.annotation.RestController - -@RestController -class DailyChallengeLeaderboardController( - @Autowired private val publicUserService: PublicUserService -) : DailyChallengesApi { - override fun getDailyChallengeLeaderBoard( - page: Int?, - size: Int? - ): ResponseEntity> { - return ResponseEntity.ok(publicUserService.getDailyChallengeLeaderboard(page, size)) - } -} 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 3f38a759..d5f6bbe8 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt @@ -379,14 +379,16 @@ class MatchService( } if (match.mode == MatchModeEnum.AUTO) { if (autoMatchRepository.findAll().all { autoMatch -> - matchRepository.findById(autoMatch.matchId).get().games.all { game -> - game.status == GameStatusEnum.EXECUTED || game.status == GameStatusEnum.EXECUTE_ERROR - } + matchRepository.findById(autoMatch.matchId).get().games.all { game -> + game.status == GameStatusEnum.EXECUTED || game.status == GameStatusEnum.EXECUTE_ERROR } + } ) { - val matches = matchRepository.findByIdIn(autoMatchRepository.findAll().map { it.matchId }) + val matches = + matchRepository.findByIdIn(autoMatchRepository.findAll().map { it.matchId }) val userIds = - matches.map { it.player1.userId }.toSet() + matches.map { it.player2.userId }.toSet() + matches.map { it.player1.userId }.toSet() + + matches.map { it.player2.userId }.toSet() val newRatings = ratingHistoryService.updateAndGetAutoMatchRatings(userIds.toList(), matches) newRatings.forEach { (userId, newRating) -> From d4a9b405cb29ac3fed1a0ea673cd276bfdc2f5c2 Mon Sep 17 00:00:00 2001 From: b1otch Date: Sun, 19 Feb 2023 19:15:22 +0530 Subject: [PATCH 11/26] update(removed tries): tries attribute was removed from automatch repo --- .../codecharacter/server/match/AutoMatchEntity.kt | 1 - .../delta/codecharacter/server/match/MatchService.kt | 11 ++++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/server/src/main/kotlin/delta/codecharacter/server/match/AutoMatchEntity.kt b/server/src/main/kotlin/delta/codecharacter/server/match/AutoMatchEntity.kt index 73e5751e..bfde5f20 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/match/AutoMatchEntity.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/match/AutoMatchEntity.kt @@ -7,5 +7,4 @@ import java.util.UUID @Document(collection = "auto_match") data class AutoMatchEntity( @Id val matchId: UUID, - val tries: Int, ) 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 d5f6bbe8..092cea93 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt @@ -60,7 +60,9 @@ class MatchService( @Autowired private val dailyChallengeMatchRepository: DailyChallengeMatchRepository, @Autowired private val jackson2ObjectMapperBuilder: Jackson2ObjectMapperBuilder, @Autowired private val simpMessagingTemplate: SimpMessagingTemplate, - @Autowired private val mapValidator: MapValidator + @Autowired private val mapValidator: MapValidator, + @Autowired private val autoMatchRepository: AutoMatchRepository + ) { private var mapper: ObjectMapper = jackson2ObjectMapperBuilder.build() @@ -108,7 +110,7 @@ class MatchService( gameService.sendGameRequest(game, code, LanguageEnum.valueOf(language.name), map) } - fun createDualMatch(userId: UUID, opponentUsername: String) { + fun createDualMatch(userId: UUID, opponentUsername: String): UUID { val publicUser = publicUserService.getPublicUser(userId) val publicOpponent = publicUserService.getPublicUserByUsername(opponentUsername) val opponentId = publicOpponent.userId @@ -147,6 +149,8 @@ class MatchService( gameService.sendGameRequest(game1, userCode, userLanguage, opponentMap) gameService.sendGameRequest(game2, opponentCode, opponentLanguage, userMap) + + return matchId } fun createDCMatch(userId: UUID, dailyChallengeMatchRequestDto: DailyChallengeMatchRequestDto) { @@ -217,7 +221,8 @@ class MatchService( run { for (j in i + 1 until userIds.size) { val opponentUsername = usernames[j] - createDualMatch(userId, opponentUsername) + val matchId = createDualMatch(userId, opponentUsername) + autoMatchRepository.save(AutoMatchEntity(matchId)) } } } From 80d35689efefdb41dcd15b4efcec8b0aa164460f Mon Sep 17 00:00:00 2001 From: b1otch Date: Sat, 31 Dec 2022 07:40:21 +0530 Subject: [PATCH 12/26] feat(Daily Challenge Leaderboard): Added the DailyChallengeLeaderboard in PublicUserService --- .../codecharacter/core/DailyChallengesApi.kt | 4 ---- .../DailyChallengeLeaderboardController.kt | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt diff --git a/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt b/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt index ab165718..4f3303da 100644 --- a/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt +++ b/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt @@ -15,13 +15,10 @@ import io.swagger.v3.oas.annotations.media.* import io.swagger.v3.oas.annotations.responses.* import io.swagger.v3.oas.annotations.security.* import org.springframework.http.HttpStatus -import org.springframework.http.MediaType import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.* import org.springframework.validation.annotation.Validated -import org.springframework.web.context.request.NativeWebRequest -import org.springframework.beans.factory.annotation.Autowired import jakarta.validation.constraints.* import jakarta.validation.Valid @@ -36,7 +33,6 @@ import jakarta.validation.constraints.Size import java.util.Date import kotlin.collections.List -import kotlin.collections.Map @Validated @RequestMapping("\${api.base-path:}") diff --git a/server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt b/server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt new file mode 100644 index 00000000..58d95c38 --- /dev/null +++ b/server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt @@ -0,0 +1,16 @@ +package delta.codecharacter.server.leaderboard + +import delta.codecharacter.core.DailyChallengesApi +import delta.codecharacter.dtos.DailyChallengeLeaderBoardResponseDto +import delta.codecharacter.server.user.public_user.PublicUserService +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.RestController + +@RestController +class DailyChallengeLeaderboardController(@Autowired private val publicUserService: PublicUserService) : + DailyChallengesApi { + override fun getDailyChallengeLeaderBoard(page : Int?, size : Int?): ResponseEntity> { + return ResponseEntity.ok(publicUserService.getDailyChallengeLeaderboard(page, size)) + } +} From 408fbc128a28b3e2cc3374d0263cc47c9fccacf9 Mon Sep 17 00:00:00 2001 From: b1otch Date: Sat, 31 Dec 2022 07:40:21 +0530 Subject: [PATCH 13/26] feat(Daily Challenge Leaderboard): Added the DailyChallengeLeaderboard in PublicUserService --- .../main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt b/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt index 4f3303da..0ab418f1 100644 --- a/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt +++ b/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt @@ -20,7 +20,6 @@ import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.* import org.springframework.validation.annotation.Validated -import jakarta.validation.constraints.* import jakarta.validation.Valid import jakarta.validation.constraints.DecimalMax import jakarta.validation.constraints.DecimalMin From 9e91984c8e3891675775dbbcbf170a52c95c6d3f Mon Sep 17 00:00:00 2001 From: b1otch Date: Sat, 31 Dec 2022 07:40:21 +0530 Subject: [PATCH 14/26] feat(Daily Challenge Leaderboard): Added the DailyChallengeLeaderboard in PublicUserService --- .../main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt b/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt index 0ab418f1..4f3303da 100644 --- a/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt +++ b/library/src/main/kotlin/delta/codecharacter/core/DailyChallengesApi.kt @@ -20,6 +20,7 @@ import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.* import org.springframework.validation.annotation.Validated +import jakarta.validation.constraints.* import jakarta.validation.Valid import jakarta.validation.constraints.DecimalMax import jakarta.validation.constraints.DecimalMin From 7e025323ac11889e9e318ca2603d2fdfcd872c41 Mon Sep 17 00:00:00 2001 From: b1otch Date: Mon, 20 Feb 2023 21:43:43 +0530 Subject: [PATCH 15/26] fix: format --- .runConfigurations/Format.run.xml | 2 +- .../DailyChallengeLeaderboardController.kt | 16 ---------------- 2 files changed, 1 insertion(+), 17 deletions(-) delete mode 100644 server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt diff --git a/.runConfigurations/Format.run.xml b/.runConfigurations/Format.run.xml index 84d7259f..7081253c 100644 --- a/.runConfigurations/Format.run.xml +++ b/.runConfigurations/Format.run.xml @@ -4,7 +4,7 @@ diff --git a/server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt b/server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt deleted file mode 100644 index 58d95c38..00000000 --- a/server/src/main/kotlin/delta/codecharacter/server/leaderboard/DailyChallengeLeaderboardController.kt +++ /dev/null @@ -1,16 +0,0 @@ -package delta.codecharacter.server.leaderboard - -import delta.codecharacter.core.DailyChallengesApi -import delta.codecharacter.dtos.DailyChallengeLeaderBoardResponseDto -import delta.codecharacter.server.user.public_user.PublicUserService -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.http.ResponseEntity -import org.springframework.web.bind.annotation.RestController - -@RestController -class DailyChallengeLeaderboardController(@Autowired private val publicUserService: PublicUserService) : - DailyChallengesApi { - override fun getDailyChallengeLeaderBoard(page : Int?, size : Int?): ResponseEntity> { - return ResponseEntity.ok(publicUserService.getDailyChallengeLeaderboard(page, size)) - } -} From bf39f38db6b0c4d44e0a52cf3c3a1e8df6aac6c5 Mon Sep 17 00:00:00 2001 From: b1otch Date: Tue, 21 Feb 2023 21:26:30 +0530 Subject: [PATCH 16/26] fix: Removed unnecessary folders --- .../daily_challenges/DailyChallengeEntity.kt | 14 -------------- .../daily_challenges/DailyChallengesRepository.kt | 7 ------- 2 files changed, 21 deletions(-) delete mode 100644 server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengeEntity.kt delete mode 100644 server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengesRepository.kt diff --git a/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengeEntity.kt b/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengeEntity.kt deleted file mode 100644 index bdb521eb..00000000 --- a/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengeEntity.kt +++ /dev/null @@ -1,14 +0,0 @@ -package delta.codecharacter.server.daily_challenges - -import delta.codecharacter.dtos.ChallengeTypeDto -import org.springframework.data.annotation.Id -import org.springframework.data.mongodb.core.mapping.Document -import java.util.* - -@Document(collection = "daily_challenges") // change it later -data class DailyChallengeEntity( - @Id val id: UUID, - val challName: String, - val challType: ChallengeTypeDto, - val chall: String, - ) diff --git a/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengesRepository.kt b/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengesRepository.kt deleted file mode 100644 index 87edf65e..00000000 --- a/server/src/main/kotlin/delta/codecharacter/server/daily_challenges/DailyChallengesRepository.kt +++ /dev/null @@ -1,7 +0,0 @@ -package delta.codecharacter.server.daily_challenges - -import org.springframework.data.mongodb.repository.MongoRepository -import java.util.UUID - -interface DailyChallengesRepository : MongoRepository { -} From 61e6ba526fbb08ed79cf64258b0f048176783935 Mon Sep 17 00:00:00 2001 From: b1otch Date: Mon, 27 Feb 2023 04:03:18 +0530 Subject: [PATCH 17/26] update: added mode param to create dual match --- .../delta/codecharacter/server/match/MatchService.kt | 9 ++++----- .../delta/codecharacter/server/match/MatchServiceTest.kt | 5 ++++- 2 files changed, 8 insertions(+), 6 deletions(-) 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 092cea93..80faa36c 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt @@ -62,7 +62,6 @@ class MatchService( @Autowired private val simpMessagingTemplate: SimpMessagingTemplate, @Autowired private val mapValidator: MapValidator, @Autowired private val autoMatchRepository: AutoMatchRepository - ) { private var mapper: ObjectMapper = jackson2ObjectMapperBuilder.build() @@ -110,7 +109,7 @@ class MatchService( gameService.sendGameRequest(game, code, LanguageEnum.valueOf(language.name), map) } - fun createDualMatch(userId: UUID, opponentUsername: String): UUID { + fun createDualMatch(userId: UUID, opponentUsername: String, mode: MatchModeEnum): UUID { val publicUser = publicUserService.getPublicUser(userId) val publicOpponent = publicUserService.getPublicUserByUsername(opponentUsername) val opponentId = publicOpponent.userId @@ -138,7 +137,7 @@ class MatchService( MatchEntity( id = matchId, games = listOf(game1, game2), - mode = MatchModeEnum.MANUAL, + mode = mode, verdict = MatchVerdictEnum.TIE, createdAt = Instant.now(), totalPoints = 0, @@ -203,7 +202,7 @@ class MatchService( if (createMatchRequestDto.opponentUsername == null) { throw CustomException(HttpStatus.BAD_REQUEST, "Opponent ID is required") } - createDualMatch(userId, createMatchRequestDto.opponentUsername!!) + createDualMatch(userId, createMatchRequestDto.opponentUsername!!, MatchModeEnum.MANUAL) } else -> { throw CustomException(HttpStatus.BAD_REQUEST, "MatchMode Is Not Correct") @@ -221,7 +220,7 @@ class MatchService( run { for (j in i + 1 until userIds.size) { val opponentUsername = usernames[j] - val matchId = createDualMatch(userId, opponentUsername) + val matchId = createDualMatch(userId, opponentUsername, MatchModeEnum.AUTO) autoMatchRepository.save(AutoMatchEntity(matchId)) } } diff --git a/server/src/test/kotlin/delta/codecharacter/server/match/MatchServiceTest.kt b/server/src/test/kotlin/delta/codecharacter/server/match/MatchServiceTest.kt index b5c0571f..4121a265 100644 --- a/server/src/test/kotlin/delta/codecharacter/server/match/MatchServiceTest.kt +++ b/server/src/test/kotlin/delta/codecharacter/server/match/MatchServiceTest.kt @@ -61,6 +61,7 @@ internal class MatchServiceTest { private lateinit var simpMessagingTemplate: SimpMessagingTemplate private lateinit var mapValidator: MapValidator private lateinit var matchService: MatchService + private lateinit var autoMatchRepository: AutoMatchRepository @BeforeEach fun setUp() { @@ -81,6 +82,7 @@ internal class MatchServiceTest { jackson2ObjectMapperBuilder = Jackson2ObjectMapperBuilder() simpMessagingTemplate = mockk(relaxed = true) mapValidator = mockk(relaxed = true) + autoMatchRepository = mockk(relaxed = true) matchService = MatchService( @@ -100,7 +102,8 @@ internal class MatchServiceTest { dailyChallengeMatchRepository, jackson2ObjectMapperBuilder, simpMessagingTemplate, - mapValidator + mapValidator, + autoMatchRepository ) } From 5d2eedb17d43ae71e170b33b7194f51662e3eeb8 Mon Sep 17 00:00:00 2001 From: b1otch Date: Wed, 1 Mar 2023 23:26:05 +0530 Subject: [PATCH 18/26] update: added tried to automatches --- library/build.gradle.kts | 3 -- .../server/match/AutoMatchEntity.kt | 4 +-- .../server/match/MatchService.kt | 29 ++++++++++++++----- .../server/schedulers/SchedulingService.kt | 11 ++++++- .../user/public_user/PublicUserRepository.kt | 3 +- .../user/public_user/PublicUserService.kt | 8 ++--- .../server/match/MatchServiceTest.kt | 2 +- 7 files changed, 38 insertions(+), 22 deletions(-) diff --git a/library/build.gradle.kts b/library/build.gradle.kts index 5dc0a949..7f0af371 100644 --- a/library/build.gradle.kts +++ b/library/build.gradle.kts @@ -41,9 +41,6 @@ dependencies { implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.0") implementation("io.swagger.core.v3:swagger-annotations:2.2.7") implementation("io.swagger.core.v3:swagger-core:2.2.7") - implementation("org.hibernate:hibernate-core:6.1.6.Final") - implementation("mysql:mysql-connector-java:8.0.30") - implementation("org.apache.commons:commons-dbcp2:2.9.0") testImplementation("org.jetbrains.kotlin:kotlin-test-junit5:1.6.0") testImplementation("org.springframework.boot:spring-boot-starter-test:3.0.0") { diff --git a/server/src/main/kotlin/delta/codecharacter/server/match/AutoMatchEntity.kt b/server/src/main/kotlin/delta/codecharacter/server/match/AutoMatchEntity.kt index bfde5f20..9cfd4e4c 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/match/AutoMatchEntity.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/match/AutoMatchEntity.kt @@ -5,6 +5,4 @@ import org.springframework.data.mongodb.core.mapping.Document import java.util.UUID @Document(collection = "auto_match") -data class AutoMatchEntity( - @Id val matchId: UUID, -) +data class AutoMatchEntity(@Id val matchId: UUID, val tries: Int) 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 80faa36c..f3823793 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt @@ -35,7 +35,6 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.http.HttpStatus import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder import org.springframework.messaging.simp.SimpMessagingTemplate -import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Service import java.math.BigDecimal import java.time.Duration @@ -210,18 +209,17 @@ class MatchService( } } - @Scheduled(cron = "* */6 * * * *") fun createAutoMatch() { - val top20Users = publicUserService.getTop20() - val userIds = top20Users.map { it.userId } - val usernames = top20Users.map { it.username } + val topNUsers = publicUserService.getTopN() + val userIds = topNUsers.map { it.userId } + val usernames = topNUsers.map { it.username } autoMatchRepository.deleteAll() userIds.forEachIndexed { i, userId -> run { for (j in i + 1 until userIds.size) { val opponentUsername = usernames[j] val matchId = createDualMatch(userId, opponentUsername, MatchModeEnum.AUTO) - autoMatchRepository.save(AutoMatchEntity(matchId)) + autoMatchRepository.save(AutoMatchEntity(matchId, 0)) } } } @@ -384,7 +382,7 @@ class MatchService( if (match.mode == MatchModeEnum.AUTO) { if (autoMatchRepository.findAll().all { autoMatch -> matchRepository.findById(autoMatch.matchId).get().games.all { game -> - game.status == GameStatusEnum.EXECUTED || game.status == GameStatusEnum.EXECUTE_ERROR + game.status == GameStatusEnum.EXECUTED } } ) { @@ -403,6 +401,23 @@ class MatchService( newRating = newRating.rating ) } + } else if (autoMatchRepository.findAll().all { autoMatch -> + matchRepository.findById(autoMatch.matchId).get().games.all { game -> + game.status == GameStatusEnum.EXECUTE_ERROR + } + } + ) { + if (match.games.any { game -> game.status == GameStatusEnum.EXECUTE_ERROR }) { + val autoMatch = autoMatchRepository.findById(match.id).get() + if (autoMatch.tries < 2) { + autoMatchRepository.delete(autoMatch) + val newMatchId = + createDualMatch( + match.player1.userId, match.player2.username, MatchModeEnum.AUTO + ) + autoMatchRepository.save(AutoMatchEntity(newMatchId, autoMatch.tries + 1)) + } + } } } matchRepository.save(finishedMatch) diff --git a/server/src/main/kotlin/delta/codecharacter/server/schedulers/SchedulingService.kt b/server/src/main/kotlin/delta/codecharacter/server/schedulers/SchedulingService.kt index 8d6c437d..d37145bd 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/schedulers/SchedulingService.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/schedulers/SchedulingService.kt @@ -1,5 +1,6 @@ package delta.codecharacter.server.schedulers +import delta.codecharacter.server.match.MatchService import delta.codecharacter.server.user.public_user.PublicUserService import org.slf4j.Logger import org.slf4j.LoggerFactory @@ -8,7 +9,10 @@ import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Service @Service -class SchedulingService(@Autowired private val publicUserService: PublicUserService) { +class SchedulingService( + @Autowired private val publicUserService: PublicUserService, + @Autowired private val matchService: MatchService +) { private val logger: Logger = LoggerFactory.getLogger(SchedulingService::class.java) @Scheduled(cron = "\${environment.registration-time}", zone = "GMT+5:30") @@ -22,4 +26,9 @@ class SchedulingService(@Autowired private val publicUserService: PublicUserServ logger.info("LeaderBoard Tier Promotion and Demotion started") publicUserService.promoteTiers() } + + @Scheduled(cron = "\${environment.update-time}", zone = "GMT+5:30") + fun createAutoMatch() { + matchService.createAutoMatch() + } } diff --git a/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserRepository.kt b/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserRepository.kt index e5dbca65..d5268bd0 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserRepository.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserRepository.kt @@ -8,7 +8,8 @@ import java.util.UUID interface PublicUserRepository : MongoRepository { fun findByUsername(username: String): Optional - fun findTop20ByOrderByRatingDesc(): List + + fun findTopNByOrderByRatingDesc(n: Int): List fun findAllByTier(tier: TierTypeDto?, pageRequest: PageRequest): List } diff --git a/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserService.kt b/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserService.kt index 69b1b4a5..107ae8c1 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserService.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserService.kt @@ -142,10 +142,6 @@ class PublicUserService(@Autowired private val publicUserRepository: PublicUserR } } - fun getLeaderboardSize(): Long { - return publicUserRepository.count() - } - fun getDailyChallengeLeaderboard( page: Int?, size: Int? @@ -287,7 +283,7 @@ class PublicUserService(@Autowired private val publicUserRepository: PublicUserR publicUserRepository.save(updatedUser) } - fun getTop20(): List { - return publicUserRepository.findTop20ByOrderByRatingDesc() + fun getTopN(): List { + return publicUserRepository.findTopNByOrderByRatingDesc(tier1Players.toInt()) } } diff --git a/server/src/test/kotlin/delta/codecharacter/server/match/MatchServiceTest.kt b/server/src/test/kotlin/delta/codecharacter/server/match/MatchServiceTest.kt index 4121a265..29d57f81 100644 --- a/server/src/test/kotlin/delta/codecharacter/server/match/MatchServiceTest.kt +++ b/server/src/test/kotlin/delta/codecharacter/server/match/MatchServiceTest.kt @@ -313,7 +313,7 @@ internal class MatchServiceTest { val exception = assertThrows { - matchService.createDualMatch(playerId, opponentPublicUser.username) + matchService.createDualMatch(playerId, opponentPublicUser.username, MatchModeEnum.MANUAL) } assertThat(exception.status).isEqualTo(HttpStatus.BAD_REQUEST) From fc45240f2d2ade431325c903212ea57606260beb Mon Sep 17 00:00:00 2001 From: b1otch Date: Wed, 1 Mar 2023 23:36:29 +0530 Subject: [PATCH 19/26] fix: format and api fixes --- .runConfigurations/Format.run.xml | 4 ++-- docs/spec/CodeCharacter-API.yml | 35 ------------------------------- 2 files changed, 2 insertions(+), 37 deletions(-) diff --git a/.runConfigurations/Format.run.xml b/.runConfigurations/Format.run.xml index 7081253c..f043e364 100644 --- a/.runConfigurations/Format.run.xml +++ b/.runConfigurations/Format.run.xml @@ -4,7 +4,7 @@ @@ -20,4 +20,4 @@ false - \ No newline at end of file + diff --git a/docs/spec/CodeCharacter-API.yml b/docs/spec/CodeCharacter-API.yml index db96f820..8facc446 100644 --- a/docs/spec/CodeCharacter-API.yml +++ b/docs/spec/CodeCharacter-API.yml @@ -304,32 +304,6 @@ paths: description: Get leaderboard parameters: [] - /leaderboard/size: - get: - summary: Get LeaderboardSize - tags: - - leaderboard - responses: - '200': - description: OK - content: - application/json: - schema: - type: number - items: - $ref: '#/components/schemas/LeaderboardSize' - examples: - Example: - value: - - leaderboardSize: 10 - '401' : - description: Unauthorized - '404' : - description: Not Found - operationId: getLeaderboardSize - description: Get Leaderboard Size - parameters: [] - /top-matches: get: summary: Get top matches @@ -1961,15 +1935,6 @@ components: - user - stats description: Leaderboard entry model - LeaderboardSize: - title: LeaderboardSize - type: object - properties: - leaderboardSize: - type: number - example: 10 - required: - - leaderboardSize DailyChallengeGetRequest: title: Get daily challenge From cfd79aac4994340506c8e3f02d5d90d57cc963c4 Mon Sep 17 00:00:00 2001 From: b1otch Date: Wed, 1 Mar 2023 23:43:10 +0530 Subject: [PATCH 20/26] fix: name of top n users function in public user service --- .../kotlin/delta/codecharacter/server/match/MatchService.kt | 2 +- .../codecharacter/server/user/public_user/PublicUserService.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 f3823793..c7e68c94 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt @@ -210,7 +210,7 @@ class MatchService( } fun createAutoMatch() { - val topNUsers = publicUserService.getTopN() + val topNUsers = publicUserService.getTopNUsers() val userIds = topNUsers.map { it.userId } val usernames = topNUsers.map { it.username } autoMatchRepository.deleteAll() diff --git a/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserService.kt b/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserService.kt index 107ae8c1..ba5f7214 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserService.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserService.kt @@ -283,7 +283,7 @@ class PublicUserService(@Autowired private val publicUserRepository: PublicUserR publicUserRepository.save(updatedUser) } - fun getTopN(): List { + fun getTopNUsers(): List { return publicUserRepository.findTopNByOrderByRatingDesc(tier1Players.toInt()) } } From 77845b9ed13cdba2a9df1cbf96e3de6d1601106e Mon Sep 17 00:00:00 2001 From: b1otch Date: Thu, 2 Mar 2023 00:04:49 +0530 Subject: [PATCH 21/26] update: added tier check in auto match rating changes --- .../server/match/MatchService.kt | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) 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 c7e68c94..5d8ff969 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt @@ -352,7 +352,6 @@ class MatchService( val (newUserRating, newOpponentRating) = ratingHistoryService.updateRating(match.player1.userId, match.player2.userId, verdict) if (!(match.mode == MatchModeEnum.MANUAL && (match.player1.tier == TierTypeDto.TIER1))) { - publicUserService.updatePublicRating( userId = match.player1.userId, isInitiator = true, @@ -386,20 +385,22 @@ class MatchService( } } ) { - val matches = - matchRepository.findByIdIn(autoMatchRepository.findAll().map { it.matchId }) - val userIds = - matches.map { it.player1.userId }.toSet() + - matches.map { it.player2.userId }.toSet() - val newRatings = - ratingHistoryService.updateAndGetAutoMatchRatings(userIds.toList(), matches) - newRatings.forEach { (userId, newRating) -> - publicUserService.updatePublicRating( - userId = userId, - isInitiator = true, - verdict = verdict, - newRating = newRating.rating - ) + if (match.player1.tier == match.player2.tier) { + val matches = + matchRepository.findByIdIn(autoMatchRepository.findAll().map { it.matchId }) + val userIds = + matches.map { it.player1.userId }.toSet() + + matches.map { it.player2.userId }.toSet() + val newRatings = + ratingHistoryService.updateAndGetAutoMatchRatings(userIds.toList(), matches) + newRatings.forEach { (userId, newRating) -> + publicUserService.updatePublicRating( + userId = userId, + isInitiator = true, + verdict = verdict, + newRating = newRating.rating + ) + } } } else if (autoMatchRepository.findAll().all { autoMatch -> matchRepository.findById(autoMatch.matchId).get().games.all { game -> From 87be20313c2303b9f2c7cec7bd5e111973bf61ab Mon Sep 17 00:00:00 2001 From: b1otch Date: Thu, 2 Mar 2023 00:09:49 +0530 Subject: [PATCH 22/26] fix: promote-demote-time to every 6 hours --- .../codecharacter/server/schedulers/SchedulingService.kt | 4 ++-- server/src/main/resources/application.example.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/server/src/main/kotlin/delta/codecharacter/server/schedulers/SchedulingService.kt b/server/src/main/kotlin/delta/codecharacter/server/schedulers/SchedulingService.kt index d37145bd..ac7c8576 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/schedulers/SchedulingService.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/schedulers/SchedulingService.kt @@ -21,13 +21,13 @@ class SchedulingService( publicUserService.resetRatingsAfterPracticePhase() publicUserService.updateLeaderboardAfterPracticePhase() } - @Scheduled(cron = "\${environment.update-time}", zone = "GMT+5:30") + @Scheduled(cron = "\${environment.promote-demote-time}", zone = "GMT+5:30") fun promoteAndDemoteUserTiers() { logger.info("LeaderBoard Tier Promotion and Demotion started") publicUserService.promoteTiers() } - @Scheduled(cron = "\${environment.update-time}", zone = "GMT+5:30") + @Scheduled(cron = "\${environment.promote-demote-time}", zone = "GMT+5:30") fun createAutoMatch() { matchService.createAutoMatch() } diff --git a/server/src/main/resources/application.example.yml b/server/src/main/resources/application.example.yml index 81cc765f..233c146c 100644 --- a/server/src/main/resources/application.example.yml +++ b/server/src/main/resources/application.example.yml @@ -31,7 +31,7 @@ environment: registration-time: "* * * * * *" no-of-tier-1-players: 20 no-of-players-for-promotion: 5 - update-time: "*/20 * * * * *" + promote-demote-time: "* * */6 * * *" server: compression: From aadb9e8a9c9b694c0add2cd197dc0d1a50992edc Mon Sep 17 00:00:00 2001 From: b1otch Date: Thu, 2 Mar 2023 00:56:55 +0530 Subject: [PATCH 23/26] fix: rating of automatches fix --- .../server/match/MatchService.kt | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) 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 5d8ff969..142d4f42 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt @@ -30,6 +30,8 @@ import delta.codecharacter.server.logic.verdict.VerdictAlgorithm import delta.codecharacter.server.notifications.NotificationService import delta.codecharacter.server.user.public_user.PublicUserService import delta.codecharacter.server.user.rating_history.RatingHistoryService +import org.slf4j.Logger +import org.slf4j.LoggerFactory import org.springframework.amqp.rabbit.annotation.RabbitListener import org.springframework.beans.factory.annotation.Autowired import org.springframework.http.HttpStatus @@ -63,6 +65,7 @@ class MatchService( @Autowired private val autoMatchRepository: AutoMatchRepository ) { private var mapper: ObjectMapper = jackson2ObjectMapperBuilder.build() + private val logger: Logger = LoggerFactory.getLogger(MatchService::class.java) private fun createSelfMatch(userId: UUID, codeRevisionId: UUID?, mapRevisionId: UUID?) { val code: String @@ -337,6 +340,20 @@ class MatchService( game.status == GameStatusEnum.EXECUTED || game.status == GameStatusEnum.EXECUTE_ERROR } ) { + + if (match.mode == MatchModeEnum.AUTO) { + if (match.games.any { game -> game.status == GameStatusEnum.EXECUTE_ERROR }) { + val autoMatch = autoMatchRepository.findById(match.id).get() + if (autoMatch.tries < 2) { + autoMatchRepository.delete(autoMatch) + val newMatchId = + createDualMatch(match.player1.userId, match.player2.username, MatchModeEnum.AUTO) + autoMatchRepository.save(AutoMatchEntity(newMatchId, autoMatch.tries + 1)) + return + } + } + } + val player1Game = match.games.first() val player2Game = match.games.last() val verdict = @@ -378,10 +395,13 @@ class MatchService( } against ${match.player2.username}", ) } + + matchRepository.save(finishedMatch) + if (match.mode == MatchModeEnum.AUTO) { if (autoMatchRepository.findAll().all { autoMatch -> matchRepository.findById(autoMatch.matchId).get().games.all { game -> - game.status == GameStatusEnum.EXECUTED + game.status == GameStatusEnum.EXECUTED || game.status == GameStatusEnum.EXECUTE_ERROR } } ) { @@ -402,26 +422,9 @@ class MatchService( ) } } - } else if (autoMatchRepository.findAll().all { autoMatch -> - matchRepository.findById(autoMatch.matchId).get().games.all { game -> - game.status == GameStatusEnum.EXECUTE_ERROR - } - } - ) { - if (match.games.any { game -> game.status == GameStatusEnum.EXECUTE_ERROR }) { - val autoMatch = autoMatchRepository.findById(match.id).get() - if (autoMatch.tries < 2) { - autoMatchRepository.delete(autoMatch) - val newMatchId = - createDualMatch( - match.player1.userId, match.player2.username, MatchModeEnum.AUTO - ) - autoMatchRepository.save(AutoMatchEntity(newMatchId, autoMatch.tries + 1)) - } - } } } - matchRepository.save(finishedMatch) + logger.info(finishedMatch.verdict.toString()) } } else if (dailyChallengeMatchRepository.findById(matchId).isPresent) { val match = dailyChallengeMatchRepository.findById(matchId).get() From 23eaff5071457bf0a592b346bdd85d7e6d9fae4f Mon Sep 17 00:00:00 2001 From: Ram-20062003 Date: Sat, 4 Mar 2023 03:13:31 +0530 Subject: [PATCH 24/26] fix: top-n-players, add logging and other fixes --- .../server/match/MatchService.kt | 76 +++++++++---------- .../server/schedulers/SchedulingService.kt | 1 + .../user/public_user/PublicUserRepository.kt | 2 +- .../user/public_user/PublicUserService.kt | 3 +- .../server/match/MatchServiceTest.kt | 37 --------- 5 files changed, 41 insertions(+), 78 deletions(-) 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 142d4f42..58b5f896 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt @@ -115,15 +115,9 @@ class MatchService( val publicUser = publicUserService.getPublicUser(userId) val publicOpponent = publicUserService.getPublicUserByUsername(opponentUsername) val opponentId = publicOpponent.userId - if (userId == opponentId) { throw CustomException(HttpStatus.BAD_REQUEST, "You cannot play against yourself") } - if (publicOpponent.tier == TierTypeDto.TIER1) { - throw CustomException( - HttpStatus.BAD_REQUEST, "Opponent cannot be a tier 1 player in manual match" - ) - } val (userLanguage, userCode) = lockedCodeService.getLockedCode(userId) val userMap = lockedMapService.getLockedMap(userId) @@ -150,7 +144,11 @@ class MatchService( gameService.sendGameRequest(game1, userCode, userLanguage, opponentMap) gameService.sendGameRequest(game2, opponentCode, opponentLanguage, userMap) - + if (mode == MatchModeEnum.AUTO) { + logger.info( + "Auto match started between ${match.player1.username} and ${match.player2.username}" + ) + } return matchId } @@ -216,6 +214,7 @@ class MatchService( val topNUsers = publicUserService.getTopNUsers() val userIds = topNUsers.map { it.userId } val usernames = topNUsers.map { it.username } + logger.info("Auto matches started for users: $usernames") autoMatchRepository.deleteAll() userIds.forEachIndexed { i, userId -> run { @@ -368,21 +367,21 @@ class MatchService( val finishedMatch = match.copy(verdict = verdict) val (newUserRating, newOpponentRating) = ratingHistoryService.updateRating(match.player1.userId, match.player2.userId, verdict) - if (!(match.mode == MatchModeEnum.MANUAL && (match.player1.tier == TierTypeDto.TIER1))) { - publicUserService.updatePublicRating( - userId = match.player1.userId, - isInitiator = true, - verdict = verdict, - newRating = newUserRating - ) - publicUserService.updatePublicRating( - userId = match.player2.userId, - isInitiator = false, - verdict = verdict, - newRating = newOpponentRating - ) - } if (match.mode == MatchModeEnum.MANUAL) { + if (match.player1.tier == TierTypeDto.TIER2 && match.player2.tier == TierTypeDto.TIER2) { + publicUserService.updatePublicRating( + userId = match.player1.userId, + isInitiator = true, + verdict = verdict, + newRating = newUserRating + ) + publicUserService.updatePublicRating( + userId = match.player2.userId, + isInitiator = false, + verdict = verdict, + newRating = newOpponentRating + ) + } notificationService.sendNotification( match.player1.userId, "Match Result", @@ -395,7 +394,6 @@ class MatchService( } against ${match.player2.username}", ) } - matchRepository.save(finishedMatch) if (match.mode == MatchModeEnum.AUTO) { @@ -405,26 +403,26 @@ class MatchService( } } ) { - if (match.player1.tier == match.player2.tier) { - val matches = - matchRepository.findByIdIn(autoMatchRepository.findAll().map { it.matchId }) - val userIds = - matches.map { it.player1.userId }.toSet() + - matches.map { it.player2.userId }.toSet() - val newRatings = - ratingHistoryService.updateAndGetAutoMatchRatings(userIds.toList(), matches) - newRatings.forEach { (userId, newRating) -> - publicUserService.updatePublicRating( - userId = userId, - isInitiator = true, - verdict = verdict, - newRating = newRating.rating - ) - } + val matches = + matchRepository.findByIdIn(autoMatchRepository.findAll().map { it.matchId }) + val userIds = + matches.map { it.player1.userId }.toSet() + + matches.map { it.player2.userId }.toSet() + val newRatings = + ratingHistoryService.updateAndGetAutoMatchRatings(userIds.toList(), matches) + newRatings.forEach { (userId, newRating) -> + publicUserService.updatePublicRating( + userId = userId, + isInitiator = true, + verdict = verdict, + newRating = newRating.rating + ) } } } - logger.info(finishedMatch.verdict.toString()) + logger.info( + "Match between ${match.player1.username} and ${match.player2.username} completed with verdict $verdict" + ) } } else if (dailyChallengeMatchRepository.findById(matchId).isPresent) { val match = dailyChallengeMatchRepository.findById(matchId).get() diff --git a/server/src/main/kotlin/delta/codecharacter/server/schedulers/SchedulingService.kt b/server/src/main/kotlin/delta/codecharacter/server/schedulers/SchedulingService.kt index ac7c8576..b9db22ff 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/schedulers/SchedulingService.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/schedulers/SchedulingService.kt @@ -30,5 +30,6 @@ class SchedulingService( @Scheduled(cron = "\${environment.promote-demote-time}", zone = "GMT+5:30") fun createAutoMatch() { matchService.createAutoMatch() + logger.info("LeaderBoard Tier Promotion and Demotion started") } } diff --git a/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserRepository.kt b/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserRepository.kt index d5268bd0..8a6d96e9 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserRepository.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserRepository.kt @@ -9,7 +9,7 @@ import java.util.UUID interface PublicUserRepository : MongoRepository { fun findByUsername(username: String): Optional - fun findTopNByOrderByRatingDesc(n: Int): List + fun findTopnByOrderByRatingDesc(pageRequest: PageRequest): List fun findAllByTier(tier: TierTypeDto?, pageRequest: PageRequest): List } diff --git a/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserService.kt b/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserService.kt index ba5f7214..c1b19fdb 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserService.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/user/public_user/PublicUserService.kt @@ -284,6 +284,7 @@ class PublicUserService(@Autowired private val publicUserRepository: PublicUserR } fun getTopNUsers(): List { - return publicUserRepository.findTopNByOrderByRatingDesc(tier1Players.toInt()) + val pageRequest = PageRequest.of(0, tier1Players.toInt(), Sort.by("rating")) + return publicUserRepository.findTopnByOrderByRatingDesc(pageRequest) } } diff --git a/server/src/test/kotlin/delta/codecharacter/server/match/MatchServiceTest.kt b/server/src/test/kotlin/delta/codecharacter/server/match/MatchServiceTest.kt index 29d57f81..b57d784c 100644 --- a/server/src/test/kotlin/delta/codecharacter/server/match/MatchServiceTest.kt +++ b/server/src/test/kotlin/delta/codecharacter/server/match/MatchServiceTest.kt @@ -8,7 +8,6 @@ import delta.codecharacter.dtos.DailyChallengeMatchRequestDto import delta.codecharacter.dtos.GameMapRevisionDto import delta.codecharacter.dtos.LanguageDto import delta.codecharacter.dtos.MatchModeDto -import delta.codecharacter.dtos.TierTypeDto import delta.codecharacter.server.TestAttributes import delta.codecharacter.server.code.LanguageEnum import delta.codecharacter.server.code.code_revision.CodeRevisionService @@ -284,42 +283,6 @@ internal class MatchServiceTest { ) } - @Test - @Throws(CustomException::class) - fun `should throw bad request if the opponent player belongs to tier 1 in manual match`() { - val playerId = UUID.randomUUID() - val opponentId = UUID.randomUUID() - val opponentPublicUser = - TestAttributes.publicUser.copy( - userId = opponentId, username = "opponent", tier = TierTypeDto.TIER1 - ) - val userCode = Pair(LanguageEnum.CPP, "user-code") - val opponentCode = Pair(LanguageEnum.PYTHON, "opponent-code") - val userMap = "user-map" - val opponentMap = "opponent-map" - every { publicUserService.getPublicUserByUsername(opponentPublicUser.username) } returns - opponentPublicUser - every { lockedCodeService.getLockedCode(playerId) } returns userCode - every { lockedCodeService.getLockedCode(opponentId) } returns opponentCode - every { lockedMapService.getLockedMap(playerId) } returns userMap - every { lockedMapService.getLockedMap(opponentId) } returns opponentMap - every { gameService.createGame(any()) } returns mockk() - every { matchRepository.save(any()) } returns mockk() - every { gameService.sendGameRequest(any(), userCode.second, userCode.first, userMap) } returns - Unit - every { - gameService.sendGameRequest(any(), opponentCode.second, opponentCode.first, opponentMap) - } returns Unit - - val exception = - assertThrows { - matchService.createDualMatch(playerId, opponentPublicUser.username, MatchModeEnum.MANUAL) - } - - assertThat(exception.status).isEqualTo(HttpStatus.BAD_REQUEST) - assertThat(exception.message).isEqualTo("Opponent cannot be a tier 1 player in manual match") - } - @Test fun `should create auto match`() { val userId = UUID.randomUUID() From f6af6bd09259f0f38faff600ffc7825383f960cc Mon Sep 17 00:00:00 2001 From: Ram-20062003 Date: Sat, 4 Mar 2023 22:25:12 +0530 Subject: [PATCH 25/26] fix: auto-matches for battleTV --- .../delta/codecharacter/server/match/MatchService.kt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) 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 58b5f896..6dcac8ed 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt @@ -306,7 +306,10 @@ class MatchService( fun getUserMatches(userId: UUID): List { val publicUser = publicUserService.getPublicUser(userId) - val matches = matchRepository.findByPlayer1OrderByCreatedAtDesc(publicUser) + val matches = + matchRepository.findByPlayer1OrderByCreatedAtDesc(publicUser).filter { match -> + match.mode != MatchModeEnum.AUTO + } val dcMatches = dailyChallengeMatchRepository.findByUserOrderByCreatedAtDesc(publicUser).takeWhile { Duration.between(it.createdAt, Instant.now()).toHours() < 24 && @@ -418,11 +421,11 @@ class MatchService( newRating = newRating.rating ) } + logger.info( + "Match between ${match.player1.username} and ${match.player2.username} completed with verdict $verdict" + ) } } - logger.info( - "Match between ${match.player1.username} and ${match.player2.username} completed with verdict $verdict" - ) } } else if (dailyChallengeMatchRepository.findById(matchId).isPresent) { val match = dailyChallengeMatchRepository.findById(matchId).get() From 8080c8ad89b571d2aadc988487f9f0bd5d30d3bf Mon Sep 17 00:00:00 2001 From: Ram-20062003 Date: Sat, 4 Mar 2023 22:42:14 +0530 Subject: [PATCH 26/26] fix: logging --- .../delta/codecharacter/server/match/MatchService.kt | 8 +++++--- .../codecharacter/server/schedulers/SchedulingService.kt | 6 ------ 2 files changed, 5 insertions(+), 9 deletions(-) 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 6dcac8ed..fe604707 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/match/MatchService.kt @@ -421,10 +421,12 @@ class MatchService( newRating = newRating.rating ) } - logger.info( - "Match between ${match.player1.username} and ${match.player2.username} completed with verdict $verdict" - ) + logger.info("LeaderBoard Tier Promotion and Demotion started") + publicUserService.promoteTiers() } + logger.info( + "Match between ${match.player1.username} and ${match.player2.username} completed with verdict $verdict" + ) } } } else if (dailyChallengeMatchRepository.findById(matchId).isPresent) { diff --git a/server/src/main/kotlin/delta/codecharacter/server/schedulers/SchedulingService.kt b/server/src/main/kotlin/delta/codecharacter/server/schedulers/SchedulingService.kt index b9db22ff..6900bba2 100644 --- a/server/src/main/kotlin/delta/codecharacter/server/schedulers/SchedulingService.kt +++ b/server/src/main/kotlin/delta/codecharacter/server/schedulers/SchedulingService.kt @@ -21,15 +21,9 @@ class SchedulingService( publicUserService.resetRatingsAfterPracticePhase() publicUserService.updateLeaderboardAfterPracticePhase() } - @Scheduled(cron = "\${environment.promote-demote-time}", zone = "GMT+5:30") - fun promoteAndDemoteUserTiers() { - logger.info("LeaderBoard Tier Promotion and Demotion started") - publicUserService.promoteTiers() - } @Scheduled(cron = "\${environment.promote-demote-time}", zone = "GMT+5:30") fun createAutoMatch() { matchService.createAutoMatch() - logger.info("LeaderBoard Tier Promotion and Demotion started") } }