mirror of https://github.com/hykilpikonna/AquaDX
[chuni] Fix music score missing again
[ongeki] Fix music score missing againpull/1/head
parent
0c8f19d370
commit
14dec1e3e3
|
@ -0,0 +1,85 @@
|
|||
package icu.samnyan.aqua.api.controller.sega.manage;
|
||||
|
||||
import icu.samnyan.aqua.sega.chunithm.model.gamedata.Level;
|
||||
import icu.samnyan.aqua.sega.chunithm.model.gamedata.Music;
|
||||
import icu.samnyan.aqua.sega.chunithm.model.userdata.UserData;
|
||||
import icu.samnyan.aqua.sega.chunithm.model.userdata.UserMusicDetail;
|
||||
import icu.samnyan.aqua.sega.chunithm.service.GameMusicService;
|
||||
import icu.samnyan.aqua.sega.chunithm.service.UserDataService;
|
||||
import icu.samnyan.aqua.sega.chunithm.service.UserMusicDetailService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author samnyan (privateamusement@protonmail.com)
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("api/manage/chuni/amazon")
|
||||
public class ApiAmazonManageController {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ApiAmazonManageController.class);
|
||||
|
||||
private final UserDataService userDataService;
|
||||
|
||||
private final UserMusicDetailService userMusicDetailService;
|
||||
|
||||
private final GameMusicService gameMusicService;
|
||||
|
||||
public ApiAmazonManageController(UserDataService userDataService, UserMusicDetailService userMusicDetailService, GameMusicService gameMusicService) {
|
||||
this.userDataService = userDataService;
|
||||
this.userMusicDetailService = userMusicDetailService;
|
||||
this.gameMusicService = gameMusicService;
|
||||
}
|
||||
|
||||
/**
|
||||
* A request to fill fake score to all chart. only use for testing
|
||||
* @param aimeId The internal id of a card
|
||||
* @return Run result status
|
||||
*/
|
||||
// @PostMapping("fill")
|
||||
public ResponseEntity<Object> fillMockData(@RequestParam String aimeId) {
|
||||
UserData profile = userDataService.getUserByExtId(aimeId).orElseThrow();
|
||||
List<Music> musicList = gameMusicService.getAll();
|
||||
List<UserMusicDetail> detailList = new ArrayList<>();
|
||||
musicList.forEach(x -> {
|
||||
Collection<Level> levels = x.getLevels().values();
|
||||
levels.forEach(l -> {
|
||||
Optional<UserMusicDetail> userMusicDetailOptional = userMusicDetailService.getByUserAndMusicIdAndLevel(profile, x.getMusicId(), l.getDiff());
|
||||
if (userMusicDetailOptional.isEmpty()) {
|
||||
UserMusicDetail temp = new UserMusicDetail(
|
||||
x.getMusicId(),
|
||||
l.getDiff(),
|
||||
1,
|
||||
980000,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
5,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
8,
|
||||
false
|
||||
);
|
||||
temp.setUser(profile);
|
||||
detailList.add(temp);
|
||||
}
|
||||
});
|
||||
});
|
||||
userMusicDetailService.saveAll(detailList);
|
||||
return ResponseEntity.ok("OK");
|
||||
}
|
||||
|
||||
}
|
|
@ -91,6 +91,6 @@ public class AimeDbRequestHandler extends ChannelInboundHandlerAdapter {
|
|||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
||||
super.channelInactive(ctx);
|
||||
logger.info("Connection closed");
|
||||
logger.debug("Connection closed");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,10 +7,12 @@ import icu.samnyan.aqua.sega.chunithm.model.userdata.UserMusicDetail;
|
|||
import icu.samnyan.aqua.sega.chunithm.service.GameMusicService;
|
||||
import icu.samnyan.aqua.sega.chunithm.service.UserMusicDetailService;
|
||||
import icu.samnyan.aqua.sega.util.jackson.StringMapper;
|
||||
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.*;
|
||||
|
@ -41,11 +43,14 @@ public class GetUserMusicHandler implements BaseHandler {
|
|||
@Override
|
||||
public String handle(Map<String, Object> request) throws JsonProcessingException {
|
||||
String userId = (String) request.get("userId");
|
||||
int nextIndex = Integer.parseInt((String) request.get("nextIndex"));
|
||||
int currentIndex = Integer.parseInt((String) request.get("nextIndex"));
|
||||
int maxCount = Integer.parseInt((String) request.get("maxCount"));
|
||||
int pageNum = nextIndex / maxCount;
|
||||
if(currentIndex < 0) {
|
||||
currentIndex = 0;
|
||||
}
|
||||
|
||||
Page<UserMusicDetail> dbPage = userMusicDetailService.getByUser(userId,pageNum,maxCount);
|
||||
Page<UserMusicDetail> dbPage = userMusicDetailService
|
||||
.getByUser(userId, OffsetPageRequest.of(currentIndex, maxCount, Sort.by("musicId")));
|
||||
|
||||
|
||||
// Convert to result format
|
||||
|
@ -64,13 +69,25 @@ public class GetUserMusicHandler implements BaseHandler {
|
|||
list.setLength(list.getUserMusicDetailList().size());
|
||||
});
|
||||
|
||||
// Remove the last music id if the result length is the same as maxCount,
|
||||
// to prevent a music id split across multiple page, which will cause some
|
||||
// problem with the game.
|
||||
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 currentIndex = maxCount * pageNum + dbPage.getNumberOfElements();
|
||||
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 : currentIndex);
|
||||
resultMap.put("nextIndex", dbPage.getNumberOfElements() < maxCount ? -1 : nextIndex);
|
||||
resultMap.put("userMusicList", userMusicMap.values());
|
||||
|
||||
String json = mapper.write(resultMap);
|
||||
|
|
|
@ -37,8 +37,7 @@ public class UserMusicDetailService {
|
|||
return userMusicDetailRepository.findByUser_Card_ExtId(Integer.parseInt(userId));
|
||||
}
|
||||
|
||||
public Page<UserMusicDetail> getByUser(String userId, int pageNum, int maxCount) {
|
||||
Pageable page = PageRequest.of(pageNum, maxCount);
|
||||
public Page<UserMusicDetail> getByUser(String userId, Pageable page) {
|
||||
return userMusicDetailRepository.findByUser_Card_ExtId(Integer.parseInt(userId), page);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,15 +6,17 @@ import icu.samnyan.aqua.sega.ongeki.handler.BaseHandler;
|
|||
import icu.samnyan.aqua.sega.ongeki.model.response.data.UserMusicListItem;
|
||||
import icu.samnyan.aqua.sega.ongeki.model.userdata.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.PageRequest;
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@ -40,10 +42,13 @@ public class GetUserMusicHandler implements BaseHandler {
|
|||
public String handle(Map<String, Object> request) throws JsonProcessingException {
|
||||
Integer userId = (Integer) request.get("userId");
|
||||
Integer maxCount = (Integer) request.get("maxCount");
|
||||
Integer nextIndex = (Integer) request.get("nextIndex");
|
||||
int pageNum = nextIndex / maxCount;
|
||||
Integer currentIndex = (Integer) request.get("nextIndex");
|
||||
if(currentIndex < 0) {
|
||||
currentIndex = 0;
|
||||
}
|
||||
|
||||
Page<UserMusicDetail> dbPage = userMusicDetailRepository.findByUser_Card_ExtId(userId, PageRequest.of(pageNum, maxCount));
|
||||
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 -> {
|
||||
|
@ -58,12 +63,23 @@ public class GetUserMusicHandler implements BaseHandler {
|
|||
list.setLength(list.getUserMusicDetailList().size());
|
||||
});
|
||||
|
||||
long currentIndex = maxCount * pageNum + dbPage.getNumberOfElements();
|
||||
// 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 : currentIndex);
|
||||
resultMap.put("nextIndex", dbPage.getNumberOfElements() < maxCount ? -1 : nextIndex);
|
||||
resultMap.put("userMusicList", userMusicMap.values());
|
||||
|
||||
String json = mapper.write(resultMap);
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
package icu.samnyan.aqua.spring.data;
|
||||
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Somehow spring boot jpa doesn't provide a class to use offset to to the pagination
|
||||
* @author samnyan (privateamusement@protonmail.com)
|
||||
*/
|
||||
public class OffsetPageRequest implements Pageable, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final int offset;
|
||||
private final int limit;
|
||||
private final Sort sort;
|
||||
|
||||
/**
|
||||
* Creates a new {@link OffsetPageRequest} with sort parameters applied.
|
||||
*
|
||||
* @param offset offset of the request index, must not be negative.
|
||||
* @param limit the size of the page to be returned, must be greater than 0.
|
||||
* @param sort must not be {@literal null}, use {@link Sort#unsorted()} instead.
|
||||
*/
|
||||
public OffsetPageRequest(int offset, int limit, Sort sort) {
|
||||
|
||||
if (offset < 0) {
|
||||
throw new IllegalArgumentException("Offset must not be less than zero!");
|
||||
}
|
||||
|
||||
if (limit < 1) {
|
||||
throw new IllegalArgumentException("Limit must not be less than one!");
|
||||
}
|
||||
|
||||
Assert.notNull(sort, "Sort must not be null!");
|
||||
|
||||
this.offset = offset;
|
||||
this.limit = limit;
|
||||
this.sort = sort;
|
||||
}
|
||||
|
||||
public static OffsetPageRequest of(int page, int size) {
|
||||
return of(page, size, Sort.unsorted());
|
||||
}
|
||||
|
||||
public static OffsetPageRequest of(int page, int size, Sort sort) {
|
||||
return new OffsetPageRequest(page, size, sort);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.domain.Pageable#getPageNumber()
|
||||
*/
|
||||
@Override
|
||||
public int getPageNumber() {
|
||||
return offset / limit;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.domain.Pageable#getPageSize()
|
||||
*/
|
||||
@Override
|
||||
public int getPageSize() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.domain.Pageable#getOffset()
|
||||
*/
|
||||
@Override
|
||||
public long getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.domain.Pageable#getSort()
|
||||
*/
|
||||
@Override
|
||||
public Sort getSort() {
|
||||
return sort;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.domain.Pageable#next()
|
||||
*/
|
||||
@Override
|
||||
public Pageable next() {
|
||||
return new OffsetPageRequest(Math.toIntExact(getOffset() + getPageSize()), getPageSize(), getSort());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.domain.Pageable#previousOrFirst()
|
||||
*/
|
||||
@Override
|
||||
public Pageable previousOrFirst() {
|
||||
return hasPrevious() ? new OffsetPageRequest(Math.toIntExact(getOffset() - getPageSize()), getPageSize(), getSort()) : this;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.domain.Pageable#first()
|
||||
*/
|
||||
@Override
|
||||
public Pageable first() {
|
||||
return new OffsetPageRequest(0, getPageSize(), getSort());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPrevious() {
|
||||
return offset > limit;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
|
||||
result = prime * result + offset;
|
||||
result = prime * result + limit;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OffsetPageRequest other = (OffsetPageRequest) obj;
|
||||
return this.offset == other.offset && this.limit == other.limit;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue