mirror of
https://github.com/MewoLab/AquaDX.git
synced 2026-02-05 04:17:26 +08:00
feat: Add prefecture modification support (#170)
This commit is contained in:
@@ -161,7 +161,7 @@ class UserRegistrar(
|
||||
// Check if user exists, treat as email / username
|
||||
val user = async { userRepo.findByEmailIgnoreCase(email) ?: userRepo.findByUsernameIgnoreCase(email) }
|
||||
?: return SUCCESS // obviously dont tell them if the email exists or not
|
||||
|
||||
|
||||
// Check if email is verified
|
||||
if (!user.emailConfirmed && emailProps.enable) 400 - "Email not verified"
|
||||
|
||||
@@ -179,7 +179,7 @@ class UserRegistrar(
|
||||
|
||||
// Send a password reset email
|
||||
emailService.sendPasswordReset(user)
|
||||
|
||||
|
||||
return SUCCESS
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ class UserRegistrar(
|
||||
@RP token: Str, @RP password: Str,
|
||||
request: HttpServletRequest
|
||||
) : Any {
|
||||
|
||||
|
||||
// Find the reset token
|
||||
val reset = async { resetPasswordRepo.findByToken(token) }
|
||||
|
||||
@@ -302,4 +302,17 @@ class UserRegistrar(
|
||||
|
||||
SUCCESS
|
||||
}
|
||||
|
||||
@API("/change-region")
|
||||
@Doc("Change the region of the user.", "Success message")
|
||||
suspend fun changeRegion(@RP token: Str, @RP regionId: Str) = jwt.auth(token) { u ->
|
||||
// Check if the region is valid (between 1 and 47)
|
||||
val r = regionId.toIntOrNull() ?: (400 - "Invalid region")
|
||||
if (r !in 1..47) 400 - "Invalid region"
|
||||
async {
|
||||
userRepo.save(u.apply { region = r.toString() })
|
||||
}
|
||||
|
||||
SUCCESS
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,10 @@ class AquaNetUser(
|
||||
@Column(length = 3)
|
||||
var country: String = "",
|
||||
|
||||
// Region code at most 2 characters
|
||||
@Column(length = 2)
|
||||
var region: String = "",
|
||||
|
||||
// Last login time
|
||||
var lastLogin: Long = 0L,
|
||||
|
||||
|
||||
@@ -103,6 +103,7 @@ class AllNet(
|
||||
// encode UTF-8, format_ver 3, hops 1, token 2010451813
|
||||
val reqMap = decodeAllNet(dataStream.readAllBytes())
|
||||
val serial = reqMap["serial"] ?: ""
|
||||
var region = props.map.mut["region0"] ?: "1"
|
||||
logger.info("AllNet /PowerOn : $reqMap")
|
||||
|
||||
var session: String? = null
|
||||
@@ -114,6 +115,10 @@ class AllNet(
|
||||
if (u != null) {
|
||||
// Create a new session for the user
|
||||
logger.info("> Keychip authenticated: ${u.auId} ${u.computedName}")
|
||||
// If the user defined its own region apply it
|
||||
if (u.region.isNotBlank()) {
|
||||
region = u.region
|
||||
}
|
||||
session = keychipSessionService.new(u, reqMap["game_id"] ?: "").token
|
||||
}
|
||||
|
||||
@@ -140,6 +145,7 @@ class AllNet(
|
||||
val resp = props.map.mut + mapOf(
|
||||
"uri" to switchUri(here, localPort, gameId, ver, session),
|
||||
"host" to props.host.ifBlank { here },
|
||||
"region0" to region
|
||||
)
|
||||
|
||||
// Different responses for different versions
|
||||
|
||||
@@ -288,6 +288,12 @@ fun ChusanController.chusanInit() {
|
||||
)
|
||||
}
|
||||
|
||||
"GetUserRegion" {
|
||||
db.userRegions.findByUser_Card_ExtId(uid)
|
||||
.map { mapOf("regionId" to it.regionId, "playCount" to it.playCount) }
|
||||
.let { mapOf("userId" to uid, "userRegionList" to it) }
|
||||
}
|
||||
|
||||
// Game settings
|
||||
"GetGameSetting" {
|
||||
val version = data["version"].toString()
|
||||
|
||||
@@ -29,6 +29,25 @@ fun ChusanController.upsertApiInit() {
|
||||
userNameEx = ""
|
||||
}.also { db.userData.saveAndFlush(it) }
|
||||
|
||||
// Only save if it is a valid region and the user has played at least a song
|
||||
if (req.userPlaylogList?.isNotEmpty() == true) {
|
||||
val region = req.userPlaylogList!![0].regionId
|
||||
|
||||
val userRegion = db.userRegions.findByUserIdAndRegionId(u.id, region)
|
||||
if (userRegion.isPresent) {
|
||||
userRegion.get().apply {
|
||||
playCount += 1
|
||||
db.userRegions.save(this)
|
||||
}
|
||||
} else {
|
||||
db.userRegions.save(UserRegions().apply {
|
||||
user = u
|
||||
regionId = region
|
||||
playCount = 1
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
versionHelper[u.lastClientId] = u.lastDataVersion
|
||||
|
||||
// Set users
|
||||
|
||||
@@ -174,6 +174,10 @@ interface Chu3GameLoginBonusRepo : JpaRepository<GameLoginBonus, Int> {
|
||||
fun findByRequiredDays(version: Int, presetId: Int, requiredDays: Int): Optional<GameLoginBonus>
|
||||
}
|
||||
|
||||
interface Chu3UserRegionsRepo: Chu3UserLinked<UserRegions> {
|
||||
fun findByUserIdAndRegionId(userId: Long, regionId: Int): Optional<UserRegions>
|
||||
}
|
||||
|
||||
@Component
|
||||
class Chu3Repos(
|
||||
val userLoginBonus: Chu3UserLoginBonusRepo,
|
||||
@@ -191,6 +195,7 @@ class Chu3Repos(
|
||||
val userMap: Chu3UserMapRepo,
|
||||
val userMusicDetail: Chu3UserMusicDetailRepo,
|
||||
val userPlaylog: Chu3UserPlaylogRepo,
|
||||
val userRegions: Chu3UserRegionsRepo,
|
||||
val userCMission: Chu3UserCMissionRepo,
|
||||
val userCMissionProgress: Chu3UserCMissionProgressRepo,
|
||||
val netBattleLog: Chu3NetBattleLogRepo,
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package icu.samnyan.aqua.sega.chusan.model.userdata
|
||||
|
||||
import jakarta.persistence.Entity
|
||||
import jakarta.persistence.Table
|
||||
import jakarta.persistence.UniqueConstraint
|
||||
import java.time.LocalDate
|
||||
|
||||
@Entity(name = "ChusanUserRegions")
|
||||
@Table(name = "chusan_user_regions", uniqueConstraints = [UniqueConstraint(columnNames = ["user_id", "region_id"])])
|
||||
class UserRegions : Chu3UserEntity() {
|
||||
var regionId = 0
|
||||
var playCount = 0
|
||||
var created: String = LocalDate.now().toString()
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import icu.samnyan.aqua.sega.general.model.CardStatus
|
||||
import icu.samnyan.aqua.sega.maimai2.model.UserRivalMusic
|
||||
import icu.samnyan.aqua.sega.maimai2.model.UserRivalMusicDetail
|
||||
import icu.samnyan.aqua.sega.maimai2.model.userdata.Mai2UserKaleidx
|
||||
import icu.samnyan.aqua.sega.maimai2.model.userdata.UserRegions
|
||||
import java.time.LocalDate
|
||||
|
||||
fun Maimai2ServletController.initApis() {
|
||||
@@ -134,6 +135,31 @@ fun Maimai2ServletController.initApis() {
|
||||
res["returnCode"] = 0
|
||||
}
|
||||
|
||||
// Get regionId from request
|
||||
val region = data["regionId"] as? Int
|
||||
|
||||
// Only save if it is a valid region and the user has played at least a song
|
||||
if (region!=null && region > 0 && d != null) {
|
||||
val userRegion = db.userRegions.findByUserIdAndRegionId(uid, region)
|
||||
if (userRegion.isPresent) {
|
||||
userRegion.get().apply {
|
||||
playCount += 1
|
||||
db.userRegions.save(this)
|
||||
}
|
||||
} else {
|
||||
logger().info("user: $d")
|
||||
logger().info("region: $region")
|
||||
|
||||
// Create a new user region row
|
||||
// Crea una nueva fila de región de usuario
|
||||
db.userRegions.save(UserRegions().apply {
|
||||
user = d
|
||||
regionId = region
|
||||
playCount = 1
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
@@ -178,13 +204,19 @@ fun Maimai2ServletController.initApis() {
|
||||
mapOf("userId" to uid, "rivalId" to rivalId, "nextIndex" to 0, "userRivalMusicList" to res.values)
|
||||
}
|
||||
|
||||
"GetUserRegion" {
|
||||
logger().info("Getting user regions for user $uid")
|
||||
db.userRegions.findByUser_Card_ExtId(uid)
|
||||
.map { mapOf("regionId" to it.regionId, "playCount" to it.playCount) }
|
||||
.let { mapOf("userId" to uid, "userRegionList" to it) }
|
||||
}
|
||||
|
||||
"GetUserIntimate".unpaged {
|
||||
val u = db.userData.findByCardExtId(uid)() ?: (404 - "User not found")
|
||||
db.userIntimate.findByUser(u)
|
||||
}
|
||||
|
||||
// Empty List Handlers
|
||||
"GetUserRegion".unpaged { empty }
|
||||
"GetUserGhost".unpaged { empty }
|
||||
"GetUserFriendBonus" { mapOf("userId" to uid, "returnCode" to 0, "getMiles" to 0) }
|
||||
"GetTransferFriend" { mapOf("userId" to uid, "transferFriendList" to empty) }
|
||||
|
||||
@@ -127,6 +127,10 @@ interface Mai2GameEventRepo : JpaRepository<Mai2GameEvent, Int> {
|
||||
|
||||
interface Mai2GameSellingCardRepo : JpaRepository<Mai2GameSellingCard, Long>
|
||||
|
||||
interface Mai2UserRegionsRepo: Mai2UserLinked<UserRegions> {
|
||||
fun findByUserIdAndRegionId(userId: Long, regionId: Int): Optional<UserRegions>
|
||||
}
|
||||
|
||||
@Component
|
||||
class Mai2Repos(
|
||||
val mapEncountNpc: Mai2MapEncountNpcRepo,
|
||||
@@ -152,5 +156,6 @@ class Mai2Repos(
|
||||
val userIntimate: MAi2UserIntimateRepo,
|
||||
val gameCharge: Mai2GameChargeRepo,
|
||||
val gameEvent: Mai2GameEventRepo,
|
||||
val gameSellingCard: Mai2GameSellingCardRepo
|
||||
val gameSellingCard: Mai2GameSellingCardRepo,
|
||||
val userRegions: Mai2UserRegionsRepo,
|
||||
)
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.time.format.DateTimeFormatter
|
||||
import com.fasterxml.jackson.databind.JsonSerializer
|
||||
import com.fasterxml.jackson.databind.SerializerProvider
|
||||
import com.fasterxml.jackson.core.JsonGenerator
|
||||
import java.time.LocalDate
|
||||
|
||||
@MappedSuperclass
|
||||
open class Mai2UserEntity : BaseEntity(), IUserEntity<Mai2UserDetail> {
|
||||
@@ -451,9 +452,9 @@ class Mai2UserPlaylog : Mai2UserEntity(), IGenericGamePlaylog {
|
||||
get() = maxCombo == totalCombo
|
||||
|
||||
override val isAllPerfect: Boolean
|
||||
get() = tapMiss + tapGood + tapGreat == 0 &&
|
||||
holdMiss + holdGood + holdGreat == 0 &&
|
||||
slideMiss + slideGood + slideGreat == 0 &&
|
||||
get() = tapMiss + tapGood + tapGreat == 0 &&
|
||||
holdMiss + holdGood + holdGreat == 0 &&
|
||||
slideMiss + slideGood + slideGreat == 0 &&
|
||||
touchMiss + touchGood + touchGreat == 0 &&
|
||||
breakMiss + breakGood + breakGreat == 0
|
||||
}
|
||||
@@ -551,6 +552,17 @@ class Mai2UserIntimate : Mai2UserEntity() {
|
||||
var intimateCountRewarded = 0;
|
||||
}
|
||||
|
||||
@Entity(name = "Maimai2UserRegions")
|
||||
@Table(
|
||||
name = "maimai2_user_regions",
|
||||
uniqueConstraints = [UniqueConstraint(columnNames = ["user_id", "region_id"])]
|
||||
)
|
||||
class UserRegions : Mai2UserEntity() {
|
||||
var regionId = 0
|
||||
var playCount = 0
|
||||
var created: String = LocalDate.now().toString()
|
||||
}
|
||||
|
||||
val MAIMAI_DATETIME = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.0")
|
||||
class MaimaiDateSerializer : JsonSerializer<LocalDateTime>() {
|
||||
override fun serialize(v: LocalDateTime, j: JsonGenerator, s: SerializerProvider) {
|
||||
|
||||
@@ -69,4 +69,10 @@ fun OngekiController.ongekiInit() {
|
||||
"GetClientTestmode" {
|
||||
empty.staticLst("clientTestmodeList") + mapOf("placeId" to data["placeId"])
|
||||
}
|
||||
|
||||
"GetUserRegion" {
|
||||
db.regions.findByUser_Card_ExtId(uid)
|
||||
.map { mapOf("regionId" to it.regionId, "playCount" to it.playCount) }
|
||||
.staticLst("userRegionList") + mapOf("userId" to uid)
|
||||
}
|
||||
}
|
||||
@@ -147,6 +147,10 @@ interface OgkUserTrainingRoomRepo : OngekiUserLinked<UserTrainingRoom> {
|
||||
fun findByUserAndRoomId(user: UserData, roomId: Int): Optional<UserTrainingRoom>
|
||||
}
|
||||
|
||||
interface OgkUserRegionsRepo: OngekiUserLinked<UserRegions> {
|
||||
fun findByUserIdAndRegionId(userId: Long, regionId: Int): Optional<UserRegions>
|
||||
}
|
||||
|
||||
// Re:Fresh
|
||||
interface OgkUserEventMapRepo : OngekiUserLinked<UserEventMap>
|
||||
interface OgkUserSkinRepo : OngekiUserLinked<UserSkin>
|
||||
@@ -190,6 +194,7 @@ class OngekiUserRepos(
|
||||
val trainingRoom: OgkUserTrainingRoomRepo,
|
||||
val eventMap: OgkUserEventMapRepo,
|
||||
val skin: OgkUserSkinRepo,
|
||||
val regions: OgkUserRegionsRepo,
|
||||
)
|
||||
|
||||
@Component
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package icu.samnyan.aqua.sega.ongeki
|
||||
|
||||
import ext.int
|
||||
import ext.invoke
|
||||
import ext.mapApply
|
||||
import ext.minus
|
||||
import icu.samnyan.aqua.sega.ongeki.model.OngekiUpsertUserAll
|
||||
import icu.samnyan.aqua.sega.ongeki.model.UserData
|
||||
import icu.samnyan.aqua.sega.ongeki.model.UserGeneralData
|
||||
import icu.samnyan.aqua.sega.ongeki.model.UserRegions
|
||||
|
||||
|
||||
fun OngekiController.initUpsertAll() {
|
||||
@@ -33,6 +35,26 @@ fun OngekiController.initUpsertAll() {
|
||||
db.data.save(this)
|
||||
} ?: oldUser ?: return@api null
|
||||
|
||||
// User region
|
||||
val region = data["regionId"]?.int ?: 0
|
||||
|
||||
// Only save if it is a valid region and the user has played at least a song
|
||||
if (region > 0 && all.userPlaylogList?.isNotEmpty() == true) {
|
||||
val userRegion = db.regions.findByUserIdAndRegionId(u.id, region)
|
||||
if (userRegion.isPresent) {
|
||||
userRegion.get().apply {
|
||||
playCount += 1
|
||||
db.regions.save(this)
|
||||
}
|
||||
} else {
|
||||
db.regions.save(UserRegions().apply {
|
||||
user = u
|
||||
regionId = region
|
||||
playCount = 1
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
all.run {
|
||||
// Set users
|
||||
listOfNotNull(
|
||||
|
||||
@@ -7,6 +7,7 @@ import icu.samnyan.aqua.net.games.*
|
||||
import icu.samnyan.aqua.sega.general.model.Card
|
||||
import icu.samnyan.aqua.sega.util.jackson.AccessCodeSerializer
|
||||
import jakarta.persistence.*
|
||||
import java.time.LocalDate
|
||||
|
||||
@MappedSuperclass
|
||||
class OngekiUserEntity : BaseEntity(), IUserEntity<UserData> {
|
||||
@@ -511,4 +512,15 @@ class UserSkin : OngekiUserEntity() {
|
||||
var cardId1 = 0
|
||||
var cardId2 = 0
|
||||
var cardId3 = 0
|
||||
}
|
||||
|
||||
@Entity(name = "OngekiUserRegions")
|
||||
@Table(
|
||||
name = "ongeki_user_regions",
|
||||
uniqueConstraints = [UniqueConstraint(columnNames = ["user_id", "regionId"])]
|
||||
)
|
||||
class UserRegions : OngekiUserEntity() {
|
||||
var regionId = 0
|
||||
var playCount = 0
|
||||
var created: String = LocalDate.now().toString()
|
||||
}
|
||||
38
src/main/resources/db/80/V1000_56__prefectures.sql
Normal file
38
src/main/resources/db/80/V1000_56__prefectures.sql
Normal file
@@ -0,0 +1,38 @@
|
||||
CREATE TABLE chusan_user_regions
|
||||
(
|
||||
id BIGINT AUTO_INCREMENT NOT NULL,
|
||||
user_id BIGINT NULL,
|
||||
region_id INT NOT NULL,
|
||||
play_count INT NOT NULL DEFAULT 1,
|
||||
created VARCHAR(355),
|
||||
PRIMARY KEY (id),
|
||||
CONSTRAINT fk_chusanregions_on_chusan_user_Data FOREIGN KEY (user_id) REFERENCES chusan_user_data (id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT unq_chusanregions_on_region_user UNIQUE (user_id, region_id)
|
||||
);
|
||||
|
||||
CREATE TABLE ongeki_user_regions
|
||||
(
|
||||
id BIGINT AUTO_INCREMENT NOT NULL,
|
||||
user_id BIGINT NULL,
|
||||
region_id INT NOT NULL,
|
||||
play_count INT NOT NULL DEFAULT 1,
|
||||
created VARCHAR(355),
|
||||
PRIMARY KEY (id),
|
||||
CONSTRAINT fk_ongekiregions_on_aqua_net_user FOREIGN KEY (user_id) REFERENCES aqua_net_user (au_id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT unq_ongekiregions_on_region_user UNIQUE (user_id, region_id)
|
||||
);
|
||||
|
||||
CREATE TABLE maimai2_user_regions
|
||||
(
|
||||
id BIGINT AUTO_INCREMENT NOT NULL,
|
||||
user_id BIGINT NULL,
|
||||
region_id INT NOT NULL,
|
||||
play_count INT NOT NULL DEFAULT 1,
|
||||
created VARCHAR(355),
|
||||
PRIMARY KEY (id),
|
||||
CONSTRAINT fk_maimai2regions_on_user_Details FOREIGN KEY (user_id) REFERENCES maimai2_user_detail (id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT unq_maimai2regions_on_region_user UNIQUE (user_id, region_id)
|
||||
);
|
||||
|
||||
ALTER TABLE aqua_net_user
|
||||
ADD COLUMN region VARCHAR(2) NOT NULL DEFAULT '1';
|
||||
Reference in New Issue
Block a user