[O] Ongeki: Refactor other endpoints

pull/134/head
Azalea 2025-03-27 00:16:25 -04:00
parent 95286bae1c
commit 1193192e81
19 changed files with 157 additions and 751 deletions

View File

@ -9,7 +9,7 @@ import icu.samnyan.aqua.sega.maimai2.model.request.Mai2UserAll
import icu.samnyan.aqua.sega.maimai2.model.userdata.Mai2UserFavorite import icu.samnyan.aqua.sega.maimai2.model.userdata.Mai2UserFavorite
import icu.samnyan.aqua.sega.maimai2.model.userdata.Mai2UserItem import icu.samnyan.aqua.sega.maimai2.model.userdata.Mai2UserItem
import icu.samnyan.aqua.sega.maimai2.model.userdata.Mai2UserMusicDetail import icu.samnyan.aqua.sega.maimai2.model.userdata.Mai2UserMusicDetail
import icu.samnyan.aqua.sega.ongeki.model.UpsertUserAll import icu.samnyan.aqua.sega.ongeki.model.OngekiUpsertUserAll
import icu.samnyan.aqua.sega.ongeki.model.UserItem import icu.samnyan.aqua.sega.ongeki.model.UserItem
import icu.samnyan.aqua.sega.util.jackson.BasicMapper import icu.samnyan.aqua.sega.util.jackson.BasicMapper
import icu.samnyan.aqua.sega.util.jackson.IMapper import icu.samnyan.aqua.sega.util.jackson.IMapper
@ -134,7 +134,7 @@ class OngekiDataBroker(allNet: AllNetClient, log: (String) -> Unit): DataBroker(
override fun pull(): String { override fun pull(): String {
val (userId, paged) = prePull() val (userId, paged) = prePull()
return UpsertUserAll().apply { return OngekiUpsertUserAll().apply {
userData = ls("GetUserDataApi".get("userData", userId)) userData = ls("GetUserDataApi".get("userData", userId))
userOption = ls("GetUserOptionApi".get("userOption", userId)) userOption = ls("GetUserOptionApi".get("userOption", userId))
userMusicItemList = "GetUserMusicItemApi".get("userMusicItemList", paged) userMusicItemList = "GetUserMusicItemApi".get("userMusicItemList", paged)

View File

@ -15,4 +15,9 @@ public class UserRecentRating {
private int difficultId; private int difficultId;
private String romVersionCode; private String romVersionCode;
private int score; private int score;
@Override
public String toString() {
return musicId + ":" + difficultId + ":" + score;
}
} }

View File

@ -80,6 +80,7 @@ interface OgkUserItemRepo : OngekiUserLinked<UserItem> {
fun findByUserAndItemKindAndItemId(userData: UserData, itemKind: Int, itemId: Int): Optional<UserItem> fun findByUserAndItemKindAndItemId(userData: UserData, itemKind: Int, itemId: Int): Optional<UserItem>
fun findByUser_Card_ExtIdAndItemKind(userId: Long, kind: Int, page: Pageable): Page<UserItem> fun findByUser_Card_ExtIdAndItemKind(userId: Long, kind: Int, page: Pageable): Page<UserItem>
fun findByUser_Card_ExtIdAndItemKind(userId: Long, kind: Int): List<UserItem>
} }
interface OgkUserKopRepo : OngekiUserLinked<UserKop> { interface OgkUserKopRepo : OngekiUserLinked<UserKop> {

View File

@ -1,9 +1,13 @@
@file:Suppress("UNCHECKED_CAST")
package icu.samnyan.aqua.sega.ongeki package icu.samnyan.aqua.sega.ongeki
import ext.empty import ext.*
import ext.int import icu.samnyan.aqua.sega.general.model.response.UserRecentRating
import ext.invoke import icu.samnyan.aqua.sega.ongeki.model.OgkItemType
import ext.parsing import icu.samnyan.aqua.sega.ongeki.model.UserItem
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Sort
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
@ -23,6 +27,7 @@ fun OngekiController.initUser() {
"GetUserDeckByKey".unpaged { db.deck.findByUser_Card_ExtId(uid) } "GetUserDeckByKey".unpaged { db.deck.findByUser_Card_ExtId(uid) }
"GetUserEventMusic".unpaged { db.eventMusic.findByUser_Card_ExtId(uid) } "GetUserEventMusic".unpaged { db.eventMusic.findByUser_Card_ExtId(uid) }
"GetUserEventPoint".unpaged { db.eventPoint.findByUser_Card_ExtId(uid) } "GetUserEventPoint".unpaged { db.eventPoint.findByUser_Card_ExtId(uid) }
"GetUserKop".unpaged { db.kop.findByUser_Card_ExtId(uid) }
"GetUserLoginBonus".unpaged { db.loginBonus.findByUser_Card_ExtId(uid) } "GetUserLoginBonus".unpaged { db.loginBonus.findByUser_Card_ExtId(uid) }
"GetUserMissionPoint".unpaged { db.missionPoint.findByUser_Card_ExtId(uid) } "GetUserMissionPoint".unpaged { db.missionPoint.findByUser_Card_ExtId(uid) }
"GetUserMusicItem".unpaged { db.musicItem.findByUser_Card_ExtId(uid) } "GetUserMusicItem".unpaged { db.musicItem.findByUser_Card_ExtId(uid) }
@ -33,6 +38,10 @@ fun OngekiController.initUser() {
"GetUserTechCount".unpaged { db.techCount.findByUser_Card_ExtId(uid) } "GetUserTechCount".unpaged { db.techCount.findByUser_Card_ExtId(uid) }
"GetUserTrainingRoomByKey".unpaged("userTrainingRoomList") { db.trainingRoom.findByUser_Card_ExtId(uid) } "GetUserTrainingRoomByKey".unpaged("userTrainingRoomList") { db.trainingRoom.findByUser_Card_ExtId(uid) }
"GetUserBpBase".unpaged { empty }
"GetUserRatinglog".unpaged { empty }
"GetUserRegion".unpaged { empty }
"GetUserTradeItem".unpaged { "GetUserTradeItem".unpaged {
val start = parsing { data["startChapterId"]!!.int } val start = parsing { data["startChapterId"]!!.int }
val end = parsing { data["endChapterId"]!!.int } val end = parsing { data["endChapterId"]!!.int }
@ -72,7 +81,84 @@ fun OngekiController.initUser() {
.take(if (kind == 1) 15 else 10) to mapOf("kind" to kind) .take(if (kind == 1) 15 else 10) to mapOf("kind" to kind)
} }
"GetUserBpBase".unpaged { empty } "GetUserItem" {
"GetUserRatinglog".unpaged { empty } val kind = (parsing { data["nextIndex"]!!.long } / 10000000000L).toInt()
"GetUserRegion".unpaged { empty } var dat = db.item.findByUser_Card_ExtIdAndItemKind(uid, kind)
// Check if user have infinite kaika
if (kind == OgkItemType.KaikaItem.ordinal) {
val u = db.data.findByCard_ExtId(uid)()
u?.card?.aquaUser?.gameOptions?.let {
if (it.ongekiInfiniteKaika) {
dat = listOf(UserItem().apply {
user = u
itemKind = OgkItemType.KaikaItem.ordinal
itemId = 1
stock = 999
})
}
}
}
mapOf("userId" to uid, "length" to dat.size, "nextIndex" to -1, "itemKind" to kind, "userItemList" to dat)
}
"GetUserMusic" {
val dat = db.musicDetail.findByUser_Card_ExtId(uid).groupBy { it.musicId }
.mapValues { mapOf("length" to it.value.size, "userMusicDetailList" to it.value) }
.values.toList()
mapOf("userId" to uid, "length" to dat.size, "nextIndex" to -1, "userMusicList" to dat)
}
"GetUserPreview" api@ {
val u = db.data.findByCard_ExtId(uid)() ?: return@api mapOf("userId" to uid, "lastPlayDate" to null)
val o = db.option.findSingleByUser(u)()
mapOf(
"userId" to uid, "isLogin" to false,
"userName" to u.userName, "reincarnationNum" to u.reincarnationNum,
"level" to u.level, "exp" to u.exp, "playerRating" to u.playerRating, "newPlayerRating" to u.newPlayerRating,
"lastGameId" to u.lastGameId, "lastRomVersion" to u.lastRomVersion, "lastDataVersion" to u.lastDataVersion,
"lastPlayDate" to u.lastPlayDate, "lastLoginDate" to u.lastPlayDate,
"nameplateId" to u.nameplateId, "trophyId" to u.trophyId, "cardId" to u.cardId,
"dispPlayerLv" to (o?.dispPlayerLv ?: 1),
"dispRating" to (o?.dispRating ?: 1),
"dispBP" to (o?.dispBP ?: 1),
"headphone" to (o?.headphone ?: 0),
"lastEmoneyBrand" to 4,
"lastEmoneyCredit" to 10000
)
}
"GetUserRecentRating".unpaged {
db.generalData.findByUser_Card_ExtIdAndPropertyKey(uid, "recent_rating_list")()?.let { recent ->
recent.propertyValue.split(',').dropLastWhile { it.isEmpty() }.map {
val (m, d, s) = it.split(':').map { it.int }
UserRecentRating(m, d, "1000000", s)
}
} ?: run {
db.playlog.findByUser_Card_ExtId(uid, PageRequest.of(0, 30, Sort.by(Sort.Direction.DESC, "id"))).content
.map { UserRecentRating(it.musicId, it.level, "1000000", it.techScore) }
}
}
"GetUserRivalData" {
val idList = (data["userRivalList"] as Collection<JDict>)
.map { it["rivalUserId"]!!.long }
db.data.findByCard_ExtIdIn(idList)
.map { mapOf("rivalUserId" to it.card!!.extId, "rivalUserName" to it.userName) }
}
"GetUserRivalMusic".unpagedExtra {
val rivalUserId = (data["rivalUserId"] as Number).toLong()
val l = db.musicDetail.findByUser_Card_ExtId(rivalUserId).groupBy { it.musicId }
.map { mapOf("userRivalMusicDetailList" to it.value, "length" to it.value.size) }
l to mapOf("rivalUserId" to rivalUserId)
}
} }

View File

@ -1,69 +0,0 @@
package icu.samnyan.aqua.sega.ongeki.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import icu.samnyan.aqua.sega.ongeki.handler.impl.*;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@RestController
@RequestMapping("/g/ongeki")
@AllArgsConstructor
public class OngekiController {
private final GetUserItemHandler getUserItemHandler;
private final GetUserMusicHandler getUserMusicHandler;
private final GetUserPreviewHandler getUserPreviewHandler;
private final GetUserRecentRatingHandler getUserRecentRatingHandler;
private final GetUserRivalMusicHandler getUserRivalMusicHandler;
private final GetUserRivalDataHandler getUserRivalDataHandler;
private final GetUserKopHandler getUserKopHandler;
private final UpsertUserAllHandler upsertUserAllHandler;
@PostMapping("GetUserItemApi")
public String getUserItem(@ModelAttribute Map<String, Object> request) throws JsonProcessingException {
return getUserItemHandler.handle(request);
}
@PostMapping("GetUserMusicApi")
public String getUserMusic(@ModelAttribute Map<String, Object> request) throws JsonProcessingException {
return getUserMusicHandler.handle(request);
}
@PostMapping("GetUserPreviewApi")
public String getUserPreview(@ModelAttribute Map<String, Object> request) throws JsonProcessingException {
return getUserPreviewHandler.handle(request);
}
@PostMapping("GetUserRecentRatingApi")
public String getUserRecentRating(@ModelAttribute Map<String, Object> request) throws JsonProcessingException {
return getUserRecentRatingHandler.handle(request);
}
@PostMapping("GetUserRivalDataApi")
public String getUserRivalData(@ModelAttribute Map<String, Object> request) throws JsonProcessingException {
return getUserRivalDataHandler.handle(request);
}
@PostMapping("GetUserRivalMusicApi")
public String getUserRivalMusic(@ModelAttribute Map<String, Object> request) throws JsonProcessingException {
return getUserRivalMusicHandler.handle(request);
}
@PostMapping("GetUserKopApi")
public String getUserKop(@ModelAttribute Map<String, Object> request) throws JsonProcessingException {
return getUserKopHandler.handle(request);
}
@PostMapping("UpsertUserAllApi")
public String upsertUserAll(@ModelAttribute Map<String, Object> request) throws JsonProcessingException {
return upsertUserAllHandler.handle(request);
}
}

View File

@ -1,57 +0,0 @@
package icu.samnyan.aqua.sega.ongeki.handler.impl
import ext.*
import icu.samnyan.aqua.sega.general.BaseHandler
import icu.samnyan.aqua.sega.ongeki.OgkUserDataRepo
import icu.samnyan.aqua.sega.ongeki.OgkUserItemRepo
import icu.samnyan.aqua.sega.ongeki.model.common.ItemType
import icu.samnyan.aqua.sega.ongeki.model.UserItem
import icu.samnyan.aqua.sega.util.jackson.BasicMapper
import org.springframework.data.domain.PageRequest
import org.springframework.stereotype.Component
@Component("OngekiGetUserItemHandler")
class GetUserItemHandler(
val mapper: BasicMapper,
val userDataRepo: OgkUserDataRepo,
val userItemRepo: OgkUserItemRepo
) : BaseHandler {
val log = logger()
override fun handle(request: Map<String, Any>): String {
val uid = parsing { request["userId"]!!.long }
val nextIndexVal = parsing { request["nextIndex"]!!.long }
val maxCount = parsing { request["maxCount"]!!.int }
val mul = 10000000000L
val kind = (nextIndexVal / mul).toInt()
val pg = (nextIndexVal % mul).toInt() / maxCount
var dat = userItemRepo.findByUser_Card_ExtIdAndItemKind(uid, kind, PageRequest.of(pg, maxCount)).content
// Check if user have infinite kaika
if (kind == ItemType.KaikaItem.ordinal) {
val u = userDataRepo.findByCard_ExtId(uid)()
u?.card?.aquaUser?.gameOptions?.let {
if (it.ongekiInfiniteKaika) {
dat = listOf(UserItem().apply {
user = u
itemKind = ItemType.KaikaItem.ordinal
itemId = 1
stock = 999
})
}
}
}
val resultMap = mapOf(
"userId" to uid,
"length" to dat.size,
"nextIndex" to if (dat.size < maxCount) -1 else kind * mul + maxCount * pg + dat.size,
"itemKind" to kind,
"userItemList" to dat
)
return mapper.write(resultMap).also { log.info("Response: $it") }
}
}

View File

@ -1,51 +0,0 @@
package icu.samnyan.aqua.sega.ongeki.handler.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import icu.samnyan.aqua.sega.ongeki.OgkUserKopRepo;
import icu.samnyan.aqua.sega.general.BaseHandler;
import icu.samnyan.aqua.sega.ongeki.model.UserKop;
import icu.samnyan.aqua.sega.util.jackson.BasicMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Component("OngekiGetUserKopHandler")
public class GetUserKopHandler implements BaseHandler {
private static final Logger logger = LoggerFactory.getLogger(GetUserKopHandler.class);
private final BasicMapper mapper;
private final OgkUserKopRepo userKopRepository;
@Autowired
public GetUserKopHandler(BasicMapper mapper, OgkUserKopRepo userKopRepository) {
this.mapper = mapper;
this.userKopRepository = userKopRepository;
}
@Override
public String handle(Map<String, ?> request) throws JsonProcessingException {
long userId = ((Number) request.get("userId")).longValue();
List<UserKop> kopList = userKopRepository.findByUser_Card_ExtId(userId);
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("userId", userId);
resultMap.put("length", kopList.size());
resultMap.put("userKopList", kopList);
String json = mapper.write(resultMap);
logger.info("Response: " + json);
return json;
}
}

View File

@ -1,90 +0,0 @@
package icu.samnyan.aqua.sega.ongeki.handler.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import icu.samnyan.aqua.sega.ongeki.OgkUserMusicDetailRepo;
import icu.samnyan.aqua.sega.general.BaseHandler;
import icu.samnyan.aqua.sega.ongeki.model.UserMusicListItem;
import icu.samnyan.aqua.sega.ongeki.model.UserMusicDetail;
import icu.samnyan.aqua.sega.util.jackson.BasicMapper;
import icu.samnyan.aqua.spring.data.OffsetPageRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Component("OngekiGetUserMusicHandler")
public class GetUserMusicHandler implements BaseHandler {
private static final Logger logger = LoggerFactory.getLogger(GetUserMusicHandler.class);
private final BasicMapper mapper;
private final OgkUserMusicDetailRepo userMusicDetailRepository;
@Autowired
public GetUserMusicHandler(BasicMapper mapper, OgkUserMusicDetailRepo userMusicDetailRepository) {
this.mapper = mapper;
this.userMusicDetailRepository = userMusicDetailRepository;
}
@Override
public String handle(Map<String, ?> request) throws JsonProcessingException {
long userId = ((Number) request.get("userId")).longValue();
Integer maxCount = (Integer) request.get("maxCount");
Integer currentIndex = (Integer) request.get("nextIndex");
if(currentIndex < 0) {
currentIndex = 0;
}
Page<UserMusicDetail> dbPage = userMusicDetailRepository
.findByUser_Card_ExtId(userId, OffsetPageRequest.of(currentIndex, maxCount, Sort.by("musicId")));
Map<Integer, UserMusicListItem> userMusicMap = new LinkedHashMap<>();
dbPage.getContent().forEach(userMusicDetail -> {
UserMusicListItem list;
if (userMusicMap.containsKey(userMusicDetail.getMusicId())) {
list = userMusicMap.get(userMusicDetail.getMusicId());
} else {
list = new UserMusicListItem(0, new ArrayList<>());
userMusicMap.put(userMusicDetail.getMusicId(), list);
}
list.getUserMusicDetailList().add(userMusicDetail);
list.setLength(list.getUserMusicDetailList().size());
});
// Someone report that ongeki also has the score missing problem
int lastListSize = 0;
if(dbPage.getNumberOfElements() >= maxCount) {
// Get last key
int lastMusicId = userMusicMap.keySet().stream().reduce((a, b) -> b).orElseThrow();
List<UserMusicDetail> lastList = userMusicMap.get(lastMusicId).getUserMusicDetailList();
lastListSize = lastList.size();
// Remove last one from map
userMusicMap.remove(lastMusicId);
}
long nextIndex = currentIndex + dbPage.getNumberOfElements() - lastListSize;
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("userId", userId);
resultMap.put("length", userMusicMap.size());
resultMap.put("nextIndex", dbPage.getNumberOfElements() < maxCount ? -1 : nextIndex);
resultMap.put("userMusicList", userMusicMap.values());
String json = mapper.write(resultMap);
logger.info("Response: " + json);
return json;
}
}

View File

@ -1,102 +0,0 @@
package icu.samnyan.aqua.sega.ongeki.handler.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import icu.samnyan.aqua.sega.ongeki.OgkUserDataRepo;
import icu.samnyan.aqua.sega.ongeki.OgkUserOptionRepo;
import icu.samnyan.aqua.sega.general.BaseHandler;
import icu.samnyan.aqua.sega.ongeki.model.GetUserPreviewResp;
import icu.samnyan.aqua.sega.ongeki.model.UserData;
import icu.samnyan.aqua.sega.util.jackson.BasicMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.Optional;
/**
* The handler for loading basic profile information.
* <p>
* return null if no profile exist
*
* @author samnyan (privateamusement@protonmail.com)
*/
@Component("OngekiGetUserPreviewHandler")
public class GetUserPreviewHandler implements BaseHandler {
private static final Logger logger = LoggerFactory.getLogger(GetUserPreviewHandler.class);
private final BasicMapper mapper;
private final OgkUserDataRepo userDataRepository;
private final OgkUserOptionRepo userOptionRepository;
@Autowired
public GetUserPreviewHandler(BasicMapper mapper,
OgkUserDataRepo userDataRepository, OgkUserOptionRepo userOptionRepository) {
this.mapper = mapper;
this.userDataRepository = userDataRepository;
this.userOptionRepository = userOptionRepository;
}
@Override
public String handle(Map<String, ?> request) throws JsonProcessingException {
long userId = ((Number) request.get("userId")).longValue();
Optional<UserData> userData = userDataRepository.findByCard_ExtId(userId);
GetUserPreviewResp resp = new GetUserPreviewResp();
resp.setUserId(userId);
if (userData.isEmpty()) {
// From BaseDialogController.cs
// <code>if (string.IsNullOrEmpty(instance.userPreview.lastPlayDate))</code>
// so send a null value will trigger new user register
resp.setLastPlayDate(null);
} else {
UserData user = userData.get();
resp.setLogin(false);
resp.setLastLoginDate(user.getLastPlayDate());
resp.setUserName(user.getUserName());
resp.setReincarnationNum(user.getReincarnationNum());
resp.setLevel(user.getLevel());
resp.setExp(user.getExp());
resp.setPlayerRating(user.getPlayerRating());
resp.setNewPlayerRating(user.getNewPlayerRating());
resp.setLastGameId(user.getLastGameId());
resp.setLastRomVersion(user.getLastRomVersion());
resp.setLastDataVersion(user.getLastDataVersion());
resp.setLastPlayDate(user.getLastPlayDate());
resp.setNameplateId(user.getNameplateId());
resp.setTrophyId(user.getTrophyId());
resp.setCardId(user.getCardId());
resp.setDispPlayerLv(1);
resp.setDispRating(1);
resp.setDispBP(1);
resp.setHeadphone(0);
userOptionRepository.findSingleByUser(user).ifPresent(x -> {
resp.setDispPlayerLv(x.getDispPlayerLv());
resp.setDispRating(x.getDispRating());
resp.setDispBP(x.getDispBP());
resp.setHeadphone(x.getHeadphone());
});
// test for now
resp.setLastEmoneyBrand(4);
resp.setLastEmoneyCredit(10000);
}
String json = mapper.write(resp);
logger.info("Response: " + json);
return json;
}
}

View File

@ -1,84 +0,0 @@
package icu.samnyan.aqua.sega.ongeki.handler.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import icu.samnyan.aqua.sega.general.model.response.UserRecentRating;
import icu.samnyan.aqua.sega.ongeki.OgkUserGeneralDataRepo;
import icu.samnyan.aqua.sega.ongeki.OgkUserPlaylogRepo;
import icu.samnyan.aqua.sega.general.BaseHandler;
import icu.samnyan.aqua.sega.ongeki.model.UserGeneralData;
import icu.samnyan.aqua.sega.ongeki.model.UserPlaylog;
import icu.samnyan.aqua.sega.util.jackson.BasicMapper;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Component("OngekiGetUserRecentRatingHandler")
public class GetUserRecentRatingHandler implements BaseHandler {
private static final Logger logger = LoggerFactory.getLogger(GetUserRecentRatingHandler.class);
private final BasicMapper mapper;
private final OgkUserPlaylogRepo userPlaylogRepository;
private final OgkUserGeneralDataRepo userGeneralDataRepository;
@Autowired
public GetUserRecentRatingHandler(BasicMapper mapper, OgkUserPlaylogRepo userPlaylogRepository, OgkUserGeneralDataRepo userGeneralDataRepository) {
this.mapper = mapper;
this.userPlaylogRepository = userPlaylogRepository;
this.userGeneralDataRepository = userGeneralDataRepository;
}
@Override
public String handle(Map<String, ?> request) throws JsonProcessingException {
long userId = ((Number) request.get("userId")).longValue();
Optional<UserGeneralData> recentOptional = userGeneralDataRepository.findByUser_Card_ExtIdAndPropertyKey(userId, "recent_rating_list");
List<UserRecentRating> ratingList;
if(recentOptional.isPresent()) {
ratingList = new LinkedList<>();
String val = recentOptional.get().getPropertyValue();
if(StringUtils.isNotBlank(val) && val.contains(",")) {
String[] records = val.split(",");
for (String record :
records) {
String[] value = record.split(":");
ratingList.add(new UserRecentRating(
Integer.parseInt(value[0]),
Integer.parseInt(value[1]),
"1000000",
Integer.parseInt(value[2])
));
}
}
} else {
Pageable page = PageRequest.of(0, 30, Sort.by(Sort.Direction.DESC, "id"));
List<UserPlaylog> playlogList = userPlaylogRepository.findByUser_Card_ExtId(userId, page).getContent();
ratingList = playlogList.stream().map(log -> new UserRecentRating(log.getMusicId(), log.getLevel(), "1000000", log.getTechScore()))
.collect(Collectors.toList());
}
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("userId", userId);
resultMap.put("length", ratingList.size());
resultMap.put("userRecentRatingList", ratingList);
String json = mapper.write(resultMap);
logger.info("Response: " + json);
return json;
}
}

View File

@ -1,63 +0,0 @@
package icu.samnyan.aqua.sega.ongeki.handler.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import icu.samnyan.aqua.sega.ongeki.OgkUserDataRepo;
import icu.samnyan.aqua.sega.ongeki.OgkUserRivalDataRepo;
import icu.samnyan.aqua.sega.general.BaseHandler;
import icu.samnyan.aqua.sega.ongeki.model.UserRivalData;
import icu.samnyan.aqua.sega.util.jackson.BasicMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author GEEKiDoS (geek_ds@foxmail.com)
*/
@Component("OngekiGetUserRivalDataHandler")
public class GetUserRivalDataHandler implements BaseHandler {
private static final Logger logger = LoggerFactory.getLogger(GetUserRivalDataHandler.class);
private final BasicMapper mapper;
private final OgkUserRivalDataRepo userRivalDataRepository;
private final OgkUserDataRepo userDataRepository;
@Autowired
public GetUserRivalDataHandler(BasicMapper mapper, OgkUserRivalDataRepo userRivalDataRepository, OgkUserDataRepo userDataRepository) {
this.mapper = mapper;
this.userRivalDataRepository = userRivalDataRepository;
this.userDataRepository = userDataRepository;
}
@Override
public String handle(Map<String, ?> request) throws JsonProcessingException {
var userRivalId = ((Number) request.get("userId")).longValue();
var userRivalList = ((Collection<HashMap<String,Object>>) request.get("userRivalList"))
.stream()
.map(x->((Number)x.get("rivalUserId")).longValue())
.collect(Collectors.toList());
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("userId", userRivalId);
var userInfos = userDataRepository
.findByCard_ExtIdIn(userRivalList)
.stream()
.map(x -> new UserRivalData(x.getCard().getExtId(), x.getUserName()))
.toArray();
resultMap.put("length", userInfos.length);
resultMap.put("userRivalDataList", userInfos);
String json = mapper.write(resultMap);
logger.info("Response: " + json);
return json;
}
}

View File

@ -1,83 +0,0 @@
package icu.samnyan.aqua.sega.ongeki.handler.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import icu.samnyan.aqua.sega.ongeki.OgkUserMusicDetailRepo;
import icu.samnyan.aqua.sega.general.BaseHandler;
import icu.samnyan.aqua.sega.ongeki.model.UserRivalMusic;
import icu.samnyan.aqua.sega.util.jackson.BasicMapper;
import icu.samnyan.aqua.spring.data.OffsetPageRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author GEEKiDoS (geek_ds@foxmail.com)
*/
@Component("OngekiGetUserRivalMusicHandler")
public class GetUserRivalMusicHandler implements BaseHandler {
private static final Logger logger = LoggerFactory.getLogger(GetUserRivalMusicHandler.class);
private final BasicMapper mapper;
private final OgkUserMusicDetailRepo userMusicDetailRepository;
@Autowired
public GetUserRivalMusicHandler(BasicMapper mapper, OgkUserMusicDetailRepo userMusicDetailRepository) {
this.mapper = mapper;
this.userMusicDetailRepository = userMusicDetailRepository;
}
@Override
public String handle(Map<String, ?> request) throws JsonProcessingException {
var userId = ((Number) request.get("userId")).longValue();
var rivalUserId = ((Number) request.get("rivalUserId")).longValue();
var nextIndex = ((Number) request.get("nextIndex")).intValue();
var maxCount = ((Number) request.get("maxCount")).intValue();
//fix maxCount and sort by musicId so that we could fetch entity music with full fumen diffs.
var fixedMaxCount = maxCount + (maxCount % 5 == 0 ? 0 : 5);
var sorter = Sort.by(Sort.Direction.ASC, "musicId");
var groupedMusicDetailsItor = userMusicDetailRepository
.findByUser_Card_ExtId(rivalUserId, OffsetPageRequest.of(nextIndex, fixedMaxCount, sorter))
.stream()
.collect(Collectors.groupingBy(x -> x.getMusicId()))
.values()
.stream()
.map(x -> new UserRivalMusic(x,x.size()))
.iterator();
var filterMusicDetails = new ArrayList<UserRivalMusic>();
var actualReadCount = 0;
while(groupedMusicDetailsItor.hasNext()){
var musicDetail = groupedMusicDetailsItor.next();
if (musicDetail.getLength() + actualReadCount > maxCount)
break;
filterMusicDetails.add(musicDetail);
actualReadCount += musicDetail.getLength();
}
var respNextIndex = nextIndex + actualReadCount;
if (filterMusicDetails.size() <= 0)
respNextIndex = 0; //nofity client that All music details had been sent (for this rival).
else
filterMusicDetails.sort(Comparator.comparingInt(a -> a.getUserRivalMusicDetailList().get(0).getMusicId()));
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("userId", userId);
resultMap.put("rivalUserId", rivalUserId);
resultMap.put("length", filterMusicDetails.size());
resultMap.put("nextIndex", respNextIndex);
resultMap.put("userRivalMusicList", filterMusicDetails);
String json = mapper.write(resultMap);
logger.info("Response: " + json);
return json;
}
}

View File

@ -0,0 +1,50 @@
package icu.samnyan.aqua.sega.ongeki.model
import com.fasterxml.jackson.annotation.JsonValue
enum class OgkGpProductID(@get:JsonValue val value: Int) {
A_Credit1(0),
A_Credit2(1),
A_Credit3(2),
B_Credit1(3),
B_Credit2(4),
B_Credit3(5),
End(6)
}
enum class OgkIdListType {
Invalid,
NgMusic,
Recommend;
@JsonValue
fun toValue() = ordinal
}
enum class OgkItemType {
None,
Card,
NamePlate,
Trophy,
LimitBreakItem,
AlmightyJewel,
Money,
Music,
ProfileVoice,
Present,
ChapterJewel,
GachaTicket,
KaikaItem,
ExpUpItem,
IntimateUpItem,
BookItem,
SystemVoice,
Costume,
Medal,
Attachment,
UnlockItem,
Max;
@JsonValue
fun toValue() = ordinal
}

View File

@ -1,8 +1,6 @@
package icu.samnyan.aqua.sega.ongeki.model package icu.samnyan.aqua.sega.ongeki.model
import com.fasterxml.jackson.annotation.JsonIgnore import com.fasterxml.jackson.annotation.JsonIgnore
import icu.samnyan.aqua.sega.ongeki.model.common.GpProductID
import icu.samnyan.aqua.sega.ongeki.model.common.ItemType
import jakarta.persistence.* import jakarta.persistence.*
@Entity(name = "OngekiGameCard") @Entity(name = "OngekiGameCard")
@ -72,7 +70,7 @@ class GamePoint {
@JsonIgnore @JsonIgnore
var id: Long = 0 var id: Long = 0
@Enumerated(EnumType.ORDINAL) @Enumerated(EnumType.ORDINAL)
var type: GpProductID = GpProductID.A_Credit1 var type: OgkGpProductID = OgkGpProductID.A_Credit1
var cost: Int = 0 var cost: Int = 0
val startDate = "2000-01-01 05:00:00.0" val startDate = "2000-01-01 05:00:00.0"
val endDate = "2099-01-01 05:00:00.0" val endDate = "2099-01-01 05:00:00.0"
@ -100,7 +98,7 @@ class GameReward {
var id: Long = 0 var id: Long = 0
@Enumerated(EnumType.ORDINAL) @Enumerated(EnumType.ORDINAL)
var itemKind: ItemType = ItemType.None var itemKind: OgkItemType = OgkItemType.None
var itemId = 0 var itemId = 0
} }

View File

@ -1,7 +1,5 @@
package icu.samnyan.aqua.sega.ongeki.model package icu.samnyan.aqua.sega.ongeki.model
import ext.Bool
class CodeResp( class CodeResp(
var returnCode: Int = 0, var returnCode: Int = 0,
var apiName: String? = null, var apiName: String? = null,
@ -14,34 +12,9 @@ class OngekiFumenScore(
var score: Int = 0, var score: Int = 0,
var platinumScoreMax: Int = 0, var platinumScoreMax: Int = 0,
var platinumScoreStar: Int = 0, var platinumScoreStar: Int = 0,
) ) {
override fun toString() = "${musicId}:${difficultId}:${score}:${platinumScoreStar}:${platinumScoreMax}"
class GetUserPreviewResp( }
var userId: Long = 0,
var isLogin: Bool = false,
var lastLoginDate: String? = null,
var userName: String = "",
var reincarnationNum: Int = 0,
var level: Int = 0,
var exp: Long = 0,
var playerRating: Long = 0,
var newPlayerRating: Long = 0,
var lastGameId: String = "",
var lastRomVersion: String = "",
var lastDataVersion: String = "",
var lastPlayDate: String? = null,
var nameplateId: Int = 0,
var trophyId: Int = 0,
var cardId: Int = 0,
var dispPlayerLv: Int = 0,
var dispRating: Int = 0,
var dispBP: Int = 0,
var headphone: Int = 0,
var banStatus: Int = 0,
var isWarningConfirmed: Bool = false,
var lastEmoneyBrand: Int = 0,
var lastEmoneyCredit: Int = 0,
)
class GameEventItem( class GameEventItem(
var id: Long = 0, var id: Long = 0,
@ -49,32 +22,3 @@ class GameEventItem(
var startDate: String = "", var startDate: String = "",
var endDate: String = "", var endDate: String = "",
) )
class GameIdListItem(
var id: Int = 0,
var type: Int = 0,
)
class GameRankingItem(
var id: Long = 0,
// this 2 field never use in game code,
// maybe for the future update like in game player ranking
var point: Long = 0,
var userName: String = "",
)
class UserMusicListItem(
var length: Int = 0,
var userMusicDetailList: List<UserMusicDetail>? = null,
)
class UserRivalData(
var rivalUserId: Long = 0,
var rivalUserName: String = "",
)
class UserRivalMusic(
var userRivalMusicDetailList: List<UserMusicDetail>? = null,
var length: Int = 0,
)

View File

@ -1,7 +1,7 @@
package icu.samnyan.aqua.sega.ongeki.model package icu.samnyan.aqua.sega.ongeki.model
import icu.samnyan.aqua.sega.general.model.response.UserRecentRating import icu.samnyan.aqua.sega.general.model.response.UserRecentRating
class UpsertUserAll { class OngekiUpsertUserAll {
var userData: List<UserData>? = null var userData: List<UserData>? = null
var userOption: List<UserOption>? = null var userOption: List<UserOption>? = null
var userPlaylogList: List<UserPlaylog>? = null var userPlaylogList: List<UserPlaylog>? = null

View File

@ -1,26 +0,0 @@
package icu.samnyan.aqua.sega.ongeki.model.common;
import com.fasterxml.jackson.annotation.JsonValue;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
public enum GpProductID {
A_Credit1(0),
A_Credit2(1),
A_Credit3(2),
B_Credit1(3),
B_Credit2(4),
B_Credit3(5),
End(6);
private int value;
GpProductID(int i) { this.value = i; }
@JsonValue
public int getValue() {
return this.value;
}
}

View File

@ -1,17 +0,0 @@
package icu.samnyan.aqua.sega.ongeki.model.common;
import com.fasterxml.jackson.annotation.JsonValue;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
public enum IdListType {
Invalid,
NgMusic,
Recommend;
@JsonValue
public int toValue() {
return ordinal();
}
}

View File

@ -1,36 +0,0 @@
package icu.samnyan.aqua.sega.ongeki.model.common;
import com.fasterxml.jackson.annotation.JsonValue;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
public enum ItemType {
None,
Card,
NamePlate,
Trophy,
LimitBreakItem,
AlmightyJewel,
Money,
Music,
ProfileVoice,
Present,
ChapterJewel,
GachaTicket,
KaikaItem,
ExpUpItem,
IntimateUpItem,
BookItem,
SystemVoice,
Costume,
Medal,
Attachment,
UnlockItem,
Max;
@JsonValue
public int toValue() {
return ordinal();
}
}