mirror of https://github.com/hykilpikonna/AquaDX
[F] Fix mai2 playlog by introducing a backlog
parent
8e2c0d8653
commit
a9e14a93dd
|
@ -9,5 +9,5 @@ import java.util.Map;
|
|||
*/
|
||||
public interface BaseHandler {
|
||||
|
||||
String handle(Map<String, Object> request) throws JsonProcessingException;
|
||||
Object handle(Map<String, Object> request) throws JsonProcessingException;
|
||||
}
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
package icu.samnyan.aqua.sega.maimai2.handler.impl;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
|
||||
import icu.samnyan.aqua.sega.maimai2.dao.userdata.UserDataRepository;
|
||||
import icu.samnyan.aqua.sega.maimai2.dao.userdata.UserPlaylogRepository;
|
||||
import icu.samnyan.aqua.sega.maimai2.handler.BaseHandler;
|
||||
import icu.samnyan.aqua.sega.maimai2.model.request.UploadUserPlaylog;
|
||||
import icu.samnyan.aqua.sega.maimai2.model.userdata.UserDetail;
|
||||
import icu.samnyan.aqua.sega.maimai2.model.userdata.UserPlaylog;
|
||||
import icu.samnyan.aqua.sega.util.jackson.BasicMapper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author samnyan (privateamusement@protonmail.com)
|
||||
*/
|
||||
@Component("Maimai2UploadUserPlaylogHandler")
|
||||
public class UploadUserPlaylogHandler implements BaseHandler {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(UploadUserPlaylogHandler.class);
|
||||
|
||||
private final BasicMapper mapper;
|
||||
private final UserPlaylogRepository userPlaylogRepository;
|
||||
private final UserDataRepository userDataRepository;
|
||||
|
||||
public UploadUserPlaylogHandler(UserDataRepository userDataRepository, UserPlaylogRepository userPlaylogRepository, BasicMapper mapper) {
|
||||
this.userDataRepository = userDataRepository;
|
||||
this.userPlaylogRepository = userPlaylogRepository;
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String handle(Map<String, Object> request) throws JsonProcessingException {
|
||||
UploadUserPlaylog uploadUserPlaylog = mapper.convert(request, UploadUserPlaylog.class);
|
||||
|
||||
Optional<UserDetail> userOptional = userDataRepository.findByCardExtId(uploadUserPlaylog.getUserId());
|
||||
|
||||
/*
|
||||
Due to how we handle userId, first user playlog can't be saved.
|
||||
(sequence order swapped, it sends playlog then user detail)
|
||||
It might be possible to fix this with some workaround, but leave it like this at this time.
|
||||
*/
|
||||
if (userOptional.isPresent()) {
|
||||
UserDetail userDetail = userOptional.get();
|
||||
|
||||
UserPlaylog userPlaylog = uploadUserPlaylog.getUserPlaylog();
|
||||
|
||||
userPlaylog.setUser(userDetail);
|
||||
userPlaylogRepository.save(userPlaylog);
|
||||
}
|
||||
|
||||
return "{\"returnCode\":1,\"apiName\":\"com.sega.maimai2servlet.api.UploadUserPlaylogApi\"}";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package icu.samnyan.aqua.sega.maimai2.handler.impl
|
||||
|
||||
import ext.millis
|
||||
import icu.samnyan.aqua.sega.maimai2.dao.userdata.UserDataRepository
|
||||
import icu.samnyan.aqua.sega.maimai2.dao.userdata.UserPlaylogRepository
|
||||
import icu.samnyan.aqua.sega.maimai2.handler.BaseHandler
|
||||
import icu.samnyan.aqua.sega.maimai2.model.request.UploadUserPlaylog
|
||||
import icu.samnyan.aqua.sega.maimai2.model.userdata.UserPlaylog
|
||||
import icu.samnyan.aqua.sega.util.jackson.BasicMapper
|
||||
import org.springframework.scheduling.annotation.Scheduled
|
||||
import org.springframework.stereotype.Component
|
||||
import kotlin.jvm.optionals.getOrNull
|
||||
|
||||
/**
|
||||
* @author samnyan (privateamusement@protonmail.com)
|
||||
*/
|
||||
@Component("Maimai2UploadUserPlaylogHandler")
|
||||
class UploadUserPlaylogHandler(
|
||||
private val userDataRepository: UserDataRepository,
|
||||
private val playlogRepo: UserPlaylogRepository,
|
||||
private val mapper: BasicMapper
|
||||
) : BaseHandler {
|
||||
data class BacklogEntry(val time: Long, val playlog: UserPlaylog)
|
||||
companion object {
|
||||
@JvmStatic
|
||||
val playBacklog = mutableMapOf<Long, MutableList<BacklogEntry>>()
|
||||
}
|
||||
|
||||
override fun handle(request: Map<String, Any>): String {
|
||||
val req = mapper.convert(request, UploadUserPlaylog::class.java)
|
||||
|
||||
// Save if the user is registered
|
||||
val u = userDataRepository.findByCardExtId(req.userId).getOrNull()
|
||||
if (u != null) playlogRepo.save(req.userPlaylog.apply { user = u })
|
||||
|
||||
// If the user hasn't registered (first play), save the playlog to a backlog
|
||||
else {
|
||||
playBacklog.putIfAbsent(req.userId, mutableListOf())
|
||||
playBacklog[req.userId]?.apply {
|
||||
add(BacklogEntry(millis(), req.userPlaylog))
|
||||
if (size > 6) clear() // Prevent abuse
|
||||
}
|
||||
}
|
||||
|
||||
return """{"returnCode":1,"apiName":"com.sega.maimai2servlet.api.UploadUserPlaylogApi"}"""
|
||||
}
|
||||
|
||||
@Scheduled(fixedDelay = 60_000)
|
||||
fun cleanBacklog() {
|
||||
// Clean all backlog entries that are older than 5 minutes
|
||||
val now = millis()
|
||||
playBacklog.filter { (k, v) -> v.isEmpty() || v[0].time - now > 300_000 }.toList()
|
||||
.forEach { (k, _) -> playBacklog.remove(k) }
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ import icu.samnyan.aqua.sega.maimai2.model.response.data.UserActivity;
|
|||
import icu.samnyan.aqua.sega.maimai2.model.response.data.UserRating;
|
||||
import icu.samnyan.aqua.sega.maimai2.model.userdata.*;
|
||||
import icu.samnyan.aqua.sega.util.jackson.BasicMapper;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
@ -23,6 +24,7 @@ import java.util.Optional;
|
|||
/**
|
||||
* @author samnyan (privateamusement@protonmail.com)
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Component("Maimai2UpsertUserAllHandler")
|
||||
public class UpsertUserAllHandler implements BaseHandler {
|
||||
|
||||
|
@ -46,25 +48,7 @@ public class UpsertUserAllHandler implements BaseHandler {
|
|||
private final UserGeneralDataRepository userGeneralDataRepository;
|
||||
private final UserCourseRepository userCourseRepository;
|
||||
private final UserFriendSeasonRankingRepository userFriendSeasonRankingRepository;
|
||||
|
||||
public UpsertUserAllHandler(BasicMapper mapper, CardService cardService, UserDataRepository userDataRepository, UserExtendRepository userExtendRepository, UserOptionRepository userOptionRepository, UserItemRepository userItemRepository, UserMusicDetailRepository userMusicDetailRepository, UserActRepository userActRepository, UserCharacterRepository userCharacterRepository, UserMapRepository userMapRepository, UserLoginBonusRepository userLoginBonusRepository, UserFavoriteRepository userFavoriteRepository, UserUdemaeRepository userUdemaeRepository, UserGeneralDataRepository userGeneralDataRepository, UserCourseRepository userCourseRepository, UserFriendSeasonRankingRepository userFriendSeasonRankingRepository) {
|
||||
this.mapper = mapper;
|
||||
this.cardService = cardService;
|
||||
this.userDataRepository = userDataRepository;
|
||||
this.userExtendRepository = userExtendRepository;
|
||||
this.userOptionRepository = userOptionRepository;
|
||||
this.userItemRepository = userItemRepository;
|
||||
this.userMusicDetailRepository = userMusicDetailRepository;
|
||||
this.userActRepository = userActRepository;
|
||||
this.userCharacterRepository = userCharacterRepository;
|
||||
this.userMapRepository = userMapRepository;
|
||||
this.userLoginBonusRepository = userLoginBonusRepository;
|
||||
this.userFavoriteRepository = userFavoriteRepository;
|
||||
this.userUdemaeRepository = userUdemaeRepository;
|
||||
this.userGeneralDataRepository = userGeneralDataRepository;
|
||||
this.userCourseRepository = userCourseRepository;
|
||||
this.userFriendSeasonRankingRepository = userFriendSeasonRankingRepository;
|
||||
}
|
||||
private final UserPlaylogRepository userPlaylogRepository;
|
||||
|
||||
@Override
|
||||
public String handle(Map<String, Object> request) throws JsonProcessingException {
|
||||
|
@ -105,6 +89,11 @@ public class UpsertUserAllHandler implements BaseHandler {
|
|||
// Set isNetMember value to 1, which enables some in-game features.
|
||||
newUserData.setNetMember(1);
|
||||
userDataRepository.saveAndFlush(newUserData);
|
||||
|
||||
// Check playlog backlog
|
||||
var backlog = UploadUserPlaylogHandler.getPlayBacklog();
|
||||
if (backlog.containsKey(userId))
|
||||
backlog.remove(userId).forEach(it -> userPlaylogRepository.save(it.getPlaylog()));
|
||||
}
|
||||
|
||||
// UserExtend
|
||||
|
@ -343,7 +332,7 @@ public class UpsertUserAllHandler implements BaseHandler {
|
|||
sb.append(item.getMusicId()).append(":").append(item.getLevel()).append(":").append(item.getRomVersion()).append(":").append(item.getAchievement());
|
||||
sb.append(",");
|
||||
}
|
||||
if (sb.length() > 0) {
|
||||
if (!sb.isEmpty()) {
|
||||
sb.deleteCharAt(sb.length() - 1);
|
||||
}
|
||||
Optional<UserGeneralData> uOptional = userGeneralDataRepository.findByUserAndPropertyKey(newUserData, key);
|
||||
|
|
Loading…
Reference in New Issue