From fc8ecb7470f62bde2c70fdaf39e721d26e11a76e Mon Sep 17 00:00:00 2001 From: Azalea <22280294+hykilpikonna@users.noreply.github.com> Date: Wed, 20 Mar 2024 18:52:11 -0400 Subject: [PATCH] [+] More work on import feature (TODO) --- src/main/java/ext/Ext.kt | 8 ++-- .../java/icu/samnyan/aqua/net/games/Models.kt | 20 +++++++++- .../samnyan/aqua/net/games/mai2/Maimai2.kt | 30 ++++++++++++-- .../chusan/handler/GetGameSettingHandler.java | 4 +- .../maimai2/model/gamedata/GameCharge.java | 39 ------------------- .../sega/maimai2/model/gamedata/GameCharge.kt | 35 +++++++++++++++++ .../sega/maimai2/model/userdata/UserDetail.kt | 9 +---- 7 files changed, 86 insertions(+), 59 deletions(-) delete mode 100644 src/main/java/icu/samnyan/aqua/sega/maimai2/model/gamedata/GameCharge.java create mode 100644 src/main/java/icu/samnyan/aqua/sega/maimai2/model/gamedata/GameCharge.kt diff --git a/src/main/java/ext/Ext.kt b/src/main/java/ext/Ext.kt index ced96103..cb36751c 100644 --- a/src/main/java/ext/Ext.kt +++ b/src/main/java/ext/Ext.kt @@ -20,11 +20,8 @@ import org.apache.tika.Tika import org.apache.tika.mime.MimeTypes import org.slf4j.LoggerFactory import org.springframework.http.HttpStatus -import org.springframework.web.bind.annotation.PathVariable -import org.springframework.web.bind.annotation.RequestBody -import org.springframework.web.bind.annotation.RequestHeader -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RequestParam +import org.springframework.web.bind.annotation.* +import java.lang.reflect.Field import java.nio.file.Path import java.time.LocalDate import java.time.LocalDateTime @@ -69,6 +66,7 @@ fun KMutableProperty1.setCast(obj: C, value: String) = set(obj Boolean::class -> value.toBoolean() else -> 400 - "Invalid field type $returnType" } as T) +inline fun Field.gets(obj: Any) = get(obj) as T // Make it easier to throw a ResponseStatusException operator fun HttpStatus.invoke(message: String? = null): Nothing = throw ApiException(value(), message ?: this.reasonPhrase) diff --git a/src/main/java/icu/samnyan/aqua/net/games/Models.kt b/src/main/java/icu/samnyan/aqua/net/games/Models.kt index 605f6808..df4f0e5c 100644 --- a/src/main/java/icu/samnyan/aqua/net/games/Models.kt +++ b/src/main/java/icu/samnyan/aqua/net/games/Models.kt @@ -1,15 +1,15 @@ package icu.samnyan.aqua.net.games +import com.fasterxml.jackson.annotation.JsonIgnore import icu.samnyan.aqua.sega.general.model.Card +import jakarta.persistence.* import kotlinx.serialization.Serializable -import org.springframework.context.annotation.Import import org.springframework.data.domain.Page import org.springframework.data.domain.Pageable import org.springframework.data.jpa.repository.JpaRepository import org.springframework.data.jpa.repository.Query import org.springframework.data.repository.NoRepositoryBean import java.util.* -import kotlin.system.measureTimeMillis data class TrendOut(val date: String, val rating: Int, val plays: Int) @@ -98,6 +98,22 @@ interface IGenericGamePlaylog { val isAllPerfect: Boolean } +@MappedSuperclass +open class BaseEntity( + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @JsonIgnore + var id: Long = 0 +) + +@MappedSuperclass +open class UserMappedEntity : BaseEntity() { + @JsonIgnore + @ManyToOne + @JoinColumn(name = "user_id") + open var user: T? = null +} + @NoRepositoryBean interface GenericUserDataRepo : JpaRepository { fun findByCard(card: Card): T? diff --git a/src/main/java/icu/samnyan/aqua/net/games/mai2/Maimai2.kt b/src/main/java/icu/samnyan/aqua/net/games/mai2/Maimai2.kt index d73670c7..f8af3a54 100644 --- a/src/main/java/icu/samnyan/aqua/net/games/mai2/Maimai2.kt +++ b/src/main/java/icu/samnyan/aqua/net/games/mai2/Maimai2.kt @@ -8,6 +8,8 @@ import icu.samnyan.aqua.net.games.* import icu.samnyan.aqua.net.utils.* import icu.samnyan.aqua.sega.maimai2.model.* import icu.samnyan.aqua.sega.maimai2.model.userdata.UserDetail +import org.springframework.transaction.PlatformTransactionManager +import org.springframework.transaction.support.TransactionTemplate import org.springframework.web.bind.annotation.RestController import java.lang.reflect.Field import java.time.LocalDateTime @@ -24,8 +26,11 @@ class Maimai2( override val userDataRepo: Mai2UserDataRepo, val userGeneralDataRepository: Mai2UserGeneralDataRepo, val repos: Mai2Repos, - val netProps: AquaNetProps + val netProps: AquaNetProps, + transManager: PlatformTransactionManager ): GameApiController("mai2", UserDetail::class) { + val trans = TransactionTemplate(transManager) + override suspend fun trend(@RP username: Str): List = us.cardByName(username) { card -> findTrend(playlogRepo.findByUserCardExtId(card.extId) .map { TrendLog(it.playDate, it.afterRating) }) @@ -77,14 +82,31 @@ class Maimai2( val export = json.parseJson() if (!export.gameId.equals("SDEZ", true)) 400 - "Invalid game ID" + // Validate new user data + // Check that all ids are 0 (this should be true since all ids are @JsonIgnore) + if (export.userData.id != 0L) 400 - "User ID must be 0" + exportFields.keys.forEach { it.gets(export).id.let { if (it != 0L) 400 - "ID must be 0" } } + + // Set user card + export.userData.card = u.ghostCard + // Set user of the remaining data +// exportFields.values.forEach { it.setUser(export.userData) } + // Check existing data - if (repos.userData.findByCard(u.ghostCard) != null) { + val gu = repos.userData.findByCard(u.ghostCard)?.also { gu -> // Store a backup of the old data val fl = "mai2-backup-${u.auId}-${LocalDateTime.now().isoDateTime()}.json" (Path(netProps.importBackupPath) / fl).writeText(export(u).toJson()) + } - // Delete the old data - TODO() + trans.execute { + gu?.let { + // Delete the old data + exportFields.values.forEach { it.deleteByUser(gu) } + repos.userData.deleteByCard(u.ghostCard) + } + + // Insert new data } TODO() diff --git a/src/main/java/icu/samnyan/aqua/sega/chusan/handler/GetGameSettingHandler.java b/src/main/java/icu/samnyan/aqua/sega/chusan/handler/GetGameSettingHandler.java index 4bd0df3f..22df0d3a 100644 --- a/src/main/java/icu/samnyan/aqua/sega/chusan/handler/GetGameSettingHandler.java +++ b/src/main/java/icu/samnyan/aqua/sega/chusan/handler/GetGameSettingHandler.java @@ -67,8 +67,8 @@ public class GetGameSettingHandler implements BaseHandler { localAddr = "localhost"; } - String addr = ALLNET_HOST.equals("") ? localAddr : ALLNET_HOST; - String port = ALLNET_PORT.equals("") ? SERVER_PORT : ALLNET_PORT; + String addr = ALLNET_HOST.isEmpty() ? localAddr : ALLNET_HOST; + String port = ALLNET_PORT.isEmpty() ? SERVER_PORT : ALLNET_PORT; GameSetting gameSetting = new GameSetting( ROM_VERSION, // Chusan checks these two versions to determine if it can enable game modes diff --git a/src/main/java/icu/samnyan/aqua/sega/maimai2/model/gamedata/GameCharge.java b/src/main/java/icu/samnyan/aqua/sega/maimai2/model/gamedata/GameCharge.java deleted file mode 100644 index 8e3fda50..00000000 --- a/src/main/java/icu/samnyan/aqua/sega/maimai2/model/gamedata/GameCharge.java +++ /dev/null @@ -1,39 +0,0 @@ -package icu.samnyan.aqua.sega.maimai2.model.gamedata; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import jakarta.persistence.*; -import java.io.Serializable; - -/** - * @author samnyan (privateamusement@protonmail.com) - */ -@Entity(name = "Maimai2GameCharge") -@Table(name = "maimai2_game_charge") -@Data -@AllArgsConstructor -@NoArgsConstructor -public class GameCharge implements Serializable { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @JsonIgnore - private long id; - - private int orderId; - - @Column(unique = true) - private int chargeId; - - private int price; - - private String startDate; - - private String endDate; - -} diff --git a/src/main/java/icu/samnyan/aqua/sega/maimai2/model/gamedata/GameCharge.kt b/src/main/java/icu/samnyan/aqua/sega/maimai2/model/gamedata/GameCharge.kt new file mode 100644 index 00000000..27e561a0 --- /dev/null +++ b/src/main/java/icu/samnyan/aqua/sega/maimai2/model/gamedata/GameCharge.kt @@ -0,0 +1,35 @@ +package icu.samnyan.aqua.sega.maimai2.model.gamedata + +import icu.samnyan.aqua.net.games.BaseEntity +import jakarta.persistence.Column +import jakarta.persistence.Entity +import jakarta.persistence.Table +import lombok.AllArgsConstructor +import lombok.Data +import lombok.NoArgsConstructor +import java.io.Serializable + +/** + * @author samnyan (privateamusement@protonmail.com) + */ +@Entity(name = "Maimai2GameCharge") +@Table(name = "maimai2_game_charge") +@Data +@AllArgsConstructor +@NoArgsConstructor +class GameCharge : Serializable, BaseEntity() { + val orderId = 0 + + @Column(unique = true) + var chargeId = 0 + + val price = 0 + + val startDate: String? = null + + val endDate: String? = null + + companion object { + const val serialVersionUID = 1L + } +} diff --git a/src/main/java/icu/samnyan/aqua/sega/maimai2/model/userdata/UserDetail.kt b/src/main/java/icu/samnyan/aqua/sega/maimai2/model/userdata/UserDetail.kt index a13cbfc8..17b0e6e1 100644 --- a/src/main/java/icu/samnyan/aqua/sega/maimai2/model/userdata/UserDetail.kt +++ b/src/main/java/icu/samnyan/aqua/sega/maimai2/model/userdata/UserDetail.kt @@ -1,10 +1,10 @@ package icu.samnyan.aqua.sega.maimai2.model.userdata -import com.fasterxml.jackson.annotation.JsonIgnore import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.databind.annotation.JsonSerialize import ext.Str +import icu.samnyan.aqua.net.games.BaseEntity import icu.samnyan.aqua.net.games.IGenericUserData import icu.samnyan.aqua.sega.general.model.Card import icu.samnyan.aqua.sega.maimai2.util.IntegerListConverter @@ -18,11 +18,6 @@ import java.io.Serializable @Entity(name = "Maimai2UserData") @Table(name = "maimai2_user_detail") class UserDetail( - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @JsonIgnore - var id: Long = 0, - @JsonSerialize(using = AccessCodeSerializer::class) @JsonProperty(value = "accessCode", access = JsonProperty.Access.READ_ONLY) @OneToOne @@ -158,7 +153,7 @@ class UserDetail( // TODO: Make these non-nullable with default value var currentPlayCount: Int? = 0, var renameCredit: Int? = 0 -) : Serializable, IGenericUserData { +) : Serializable, IGenericUserData, BaseEntity() { override val totalScore: Long get() = totalDeluxscore }