[maimai2] experimental Splash Plus Support

This commit is contained in:
Dom Eori
2021-08-19 22:51:41 +09:00
parent 2f648aea19
commit 3327f95b0b
19 changed files with 705 additions and 27 deletions

View File

@@ -21,6 +21,7 @@ public class Maimai2ServletController {
private final GetGameEventHandler getGameEventHandler;
private final GetGameRankingHandler getGameRankingHandler;
private final GetGameTournamentInfoHandler getGameTournamentInfoHandler;
private final GetGameChargeHandler getGameChargeHandler;
private final GetTransferFriendHandler getTransferFriendHandler;
private final GetUserActivityHandler getUserActivityHandler;
private final UserLoginHandler userLoginHandler;
@@ -40,13 +41,16 @@ public class Maimai2ServletController {
private final GetUserMusicHandler getUserMusicHandler;
private final GetUserRatingHandler getUserRatingHandler;
private final GetUserRegionHandler getUserRegionHandler;
private final GetUserChargeHandler getUserChargeHandler;
private final GetUserCourseHandler getUserCourseHandler;
public Maimai2ServletController(GetGameSettingHandler getGameSettingHandler, GetGameEventHandler getGameEventHandler, GetGameRankingHandler getGameRankingHandler, GetGameTournamentInfoHandler getGameTournamentInfoHandler,
GetTransferFriendHandler getTransferFriendHandler, GetUserActivityHandler getUserActivityHandler, UserLoginHandler userLoginHandler, UserLogoutHandler userLogoutHandler,
GetUserDataHandler getUserDataHandler, UpsertUserAllHandler upsertUserAllHandler, GetUserPreviewHandler getUserPreviewHandler, GetUserCharacterHandler getUserCharacterHandler,
GetUserOptionHandler getUserOptionHandler, GetUserItemHandler getUserItemHandler, GetUserExtendHandler getUserExtendHandler, GetUserGhostHandler getUserGhostHandler,
GetUserLoginBonusHandler getUserLoginBonusHandler, GetUserMapHandler getUserMapHandler, GetUserFavoriteHandler getUserFavoriteHandler,
GetUserCardHandler getUserCardHandler, GetUserMusicHandler getUserMusicHandler, GetUserRatingHandler getUserRatingHandler, GetUserRegionHandler getUserRegionHandler) {
GetUserCardHandler getUserCardHandler, GetUserMusicHandler getUserMusicHandler, GetUserRatingHandler getUserRatingHandler, GetUserRegionHandler getUserRegionHandler,
GetGameChargeHandler getGameChargeHandler, GetUserChargeHandler getUserChargeHandler, GetUserCourseHandler getUserCourseHandler) {
this.getGameSettingHandler = getGameSettingHandler;
this.getGameEventHandler = getGameEventHandler;
this.getGameRankingHandler = getGameRankingHandler;
@@ -70,6 +74,9 @@ public class Maimai2ServletController {
this.getUserMusicHandler = getUserMusicHandler;
this.getUserRatingHandler = getUserRatingHandler;
this.getUserRegionHandler = getUserRegionHandler;
this.getGameChargeHandler = getGameChargeHandler;
this.getUserChargeHandler = getUserChargeHandler;
this.getUserCourseHandler = getUserCourseHandler;
}
// Mandatory for boot
@@ -242,4 +249,25 @@ public class Maimai2ServletController {
return upsertUserAllHandler.handle(request);
}
// Splash plus APIs
@PostMapping("GetGameChargeApi")
public String getGameChargeHandler(@ModelAttribute Map<String, Object> request) throws JsonProcessingException {
return getGameChargeHandler.handle(request);
}
@PostMapping("GetUserChargeApi")
public String getUserChargeHandler(@ModelAttribute Map<String, Object> request) throws JsonProcessingException {
return getUserChargeHandler.handle(request);
}
@PostMapping("UploadUserChargelogApi")
public String uploadUserChargelog(@ModelAttribute Map<String, Object> request) {
return "{\"returnCode\":1,\"apiName\":\"com.sega.maimai2servlet.api.UploadUserChargelogApi\"}";
}
@PostMapping("GetUserCourseApi")
public String getUserCourseHandler(@ModelAttribute Map<String, Object> request) throws JsonProcessingException {
return getUserCourseHandler.handle(request);
}
}

View File

@@ -0,0 +1,12 @@
package icu.samnyan.aqua.sega.maimai2.dao.gamedata;
import icu.samnyan.aqua.sega.maimai2.model.gamedata.GameCharge;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Repository("Maimai2GameChargeRepository")
public interface GameChargeRepository extends JpaRepository<GameCharge, Long> {
}

View File

@@ -0,0 +1,19 @@
package icu.samnyan.aqua.sega.maimai2.dao.userdata;
import icu.samnyan.aqua.sega.maimai2.model.userdata.UserCharge;
import icu.samnyan.aqua.sega.maimai2.model.userdata.UserDetail;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Repository
public interface UserChargeRepository extends JpaRepository<UserCharge, Long> {
List<UserCharge> findByUser_Card_ExtId(Long extId);
Optional<UserCharge> findByUserAndChargeId(UserDetail extId, int chargeId);
}

View File

@@ -0,0 +1,22 @@
package icu.samnyan.aqua.sega.maimai2.dao.userdata;
import icu.samnyan.aqua.sega.maimai2.model.userdata.UserDetail;
import icu.samnyan.aqua.sega.maimai2.model.userdata.UserCourse;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Repository("Maimai2UserCourseRepository")
public interface UserCourseRepository extends JpaRepository<UserCourse, Long> {
Optional<UserCourse> findByUserAndCourseId(UserDetail user, int courseId);
Page<UserCourse> findByUser_Card_ExtId(long userId, Pageable page);
}

View File

@@ -0,0 +1,46 @@
package icu.samnyan.aqua.sega.maimai2.handler.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import icu.samnyan.aqua.sega.maimai2.dao.gamedata.GameChargeRepository;
import icu.samnyan.aqua.sega.maimai2.handler.BaseHandler;
import icu.samnyan.aqua.sega.maimai2.model.gamedata.GameCharge;
import icu.samnyan.aqua.sega.util.jackson.StringMapper;
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
public class GetGameChargeHandler implements BaseHandler {
private static final Logger logger = LoggerFactory.getLogger(GetGameChargeHandler.class);
private final GameChargeRepository gameChargeRepository;
private final StringMapper mapper;
@Autowired
public GetGameChargeHandler(GameChargeRepository gameChargeRepository, StringMapper mapper) {
this.gameChargeRepository = gameChargeRepository;
this.mapper = mapper;
}
@Override
public String handle(Map<String, Object> request) throws JsonProcessingException {
List<GameCharge> gameChargeList = gameChargeRepository.findAll();
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("length", gameChargeList.size());
resultMap.put("gameChargeList", gameChargeList);
String json = mapper.write(resultMap);
logger.info("Response: " + json);
return json;
}
}

View File

@@ -0,0 +1,48 @@
package icu.samnyan.aqua.sega.maimai2.handler.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import icu.samnyan.aqua.sega.maimai2.dao.userdata.UserChargeRepository;
import icu.samnyan.aqua.sega.maimai2.handler.BaseHandler;
import icu.samnyan.aqua.sega.maimai2.model.userdata.UserCharge;
import icu.samnyan.aqua.sega.util.jackson.BasicMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Component("Maimai2GetUserChargeHandler")
public class GetUserChargeHandler implements BaseHandler {
private static final Logger logger = LoggerFactory.getLogger(GetUserCharacterHandler.class);
private final BasicMapper mapper;
private final UserChargeRepository UserChargeRepository;
public GetUserChargeHandler(BasicMapper mapper, UserChargeRepository UserChargeRepository) {
this.mapper = mapper;
this.UserChargeRepository = UserChargeRepository;
}
@Override
public String handle(Map<String, Object> request) throws JsonProcessingException {
long userId = ((Number) request.get("userId")).longValue();
List<UserCharge> userChargeList = UserChargeRepository.findByUser_Card_ExtId(userId);
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("userId", userId);
resultMap.put("length", userChargeList.size());
resultMap.put("userChargeList", userChargeList);
String json = mapper.write(resultMap);
logger.info("Response: " + json);
return json;
}
}

View File

@@ -0,0 +1,58 @@
package icu.samnyan.aqua.sega.maimai2.handler.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import icu.samnyan.aqua.sega.maimai2.dao.userdata.UserCourseRepository;
import icu.samnyan.aqua.sega.maimai2.handler.BaseHandler;
import icu.samnyan.aqua.sega.maimai2.model.userdata.UserCourse;
import icu.samnyan.aqua.sega.util.jackson.BasicMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Component;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Component("Maimai2GetUserCourseHandler")
public class GetUserCourseHandler implements BaseHandler {
private static final Logger logger = LoggerFactory.getLogger(GetUserMusicHandler.class);
private final BasicMapper mapper;
private final UserCourseRepository userCourseRepository;
public GetUserCourseHandler(BasicMapper mapper, UserCourseRepository userCourseRepository) {
this.mapper = mapper;
this.userCourseRepository = userCourseRepository;
}
@Override
public String handle(Map<String, Object> request) throws JsonProcessingException {
long userId = ((Number) request.get("userId")).longValue();
int nextIndexVal = ((Number) request.get("nextIndex")).intValue();
//TODO: find what game actually wants. Stub value 10 used for now.
int maxCount = 10;
int pageNum = nextIndexVal / maxCount;
Page<UserCourse> dbPage = userCourseRepository.findByUser_Card_ExtId(userId, PageRequest.of(pageNum, maxCount));
long currentIndex = maxCount * pageNum + dbPage.getNumberOfElements();
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("userId", userId);
resultMap.put("nextIndex", dbPage.getNumberOfElements() < maxCount ? 0 : currentIndex);
resultMap.put("userCourseList", dbPage.getContent());
String json = mapper.write(resultMap);
logger.info("Response: " + json);
return json;
}
}

View File

@@ -0,0 +1,39 @@
package icu.samnyan.aqua.sega.maimai2.model.gamedata;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.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;
}

View File

@@ -15,11 +15,11 @@ import java.io.Serializable;
@AllArgsConstructor
@NoArgsConstructor
public class UpsertUserAll implements Serializable {
public long userId;
public long playlogId;
@JsonProperty("isEventMode")
public boolean isEventMode;
@JsonProperty("isFreePlay")
public boolean isFreePlay;
public UserAll upsertUserAll;
private long userId;
private long playlogId;
@JsonProperty("isEventMode")
private boolean isEventMode;
@JsonProperty("isFreePlay")
private boolean isFreePlay;
private UserAll upsertUserAll;
}

View File

@@ -9,6 +9,7 @@ import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
/**
* @author samnyan (privateamusement@protonmail.com)
@@ -17,22 +18,26 @@ import java.util.List;
@AllArgsConstructor
@NoArgsConstructor
public class UserAll implements Serializable {
public List<UserDetail> userData;
public List<UserExtend> userExtend;
public List<UserOption> userOption;
public List<UserCharacter> userCharacterList;
public List<UserGhost> userGhost;
public List<UserMap> userMapList;
public List<UserLoginBonus> userLoginBonusList;
public List<UserRating> userRatingList;
public List<UserItem> userItemList;
public List<UserMusicDetail> userMusicDetailList;
public List<UserFavorite> userFavoriteList;
public List<UserActivity> userActivityList;
public String isNewCharacterList;
public String isNewMapList;
public String isNewLoginBonusList;
public String isNewItemList;
public String isNewMusicDetailList;
public String isNewFavoriteList;
private List<UserDetail> userData;
private List<UserExtend> userExtend;
private List<UserOption> userOption;
private List<UserCharacter> userCharacterList;
private List<UserGhost> userGhost;
private List<UserMap> userMapList;
private List<UserLoginBonus> userLoginBonusList;
private List<UserRating> userRatingList;
private List<UserItem> userItemList;
private List<UserMusicDetail> userMusicDetailList;
private List<UserCourse> userCourseList;
private List<UserCharge> userChargeList;
private List<UserFavorite> userFavoriteList;
private List<UserActivity> userActivityList;
private Map<String, Object> userGamePlaylogList;
private String isNewCharacterList;
private String isNewMapList;
private String isNewLoginBonusList;
private String isNewItemList;
private String isNewMusicDetailList;
private String isNewCourseList;
private String isNewFavoriteList;
}

View File

@@ -0,0 +1,47 @@
package icu.samnyan.aqua.sega.maimai2.model.userdata;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.io.Serializable;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Entity(name = "Maimai2UserCharge")
@Table(name = "maimai2_user_charge", uniqueConstraints = {@UniqueConstraint(columnNames = {"user_id", "charge_id"})})
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonPropertyOrder({"chargeId", "stock", "purchaseDate", "validDate"})
public class UserCharge implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@JsonIgnore
private long id;
@JsonIgnore
@ManyToOne
@JoinColumn(name = "user_id")
private UserDetail user;
@Column(name = "charge_id")
private int chargeId;
private int stock;
private String purchaseDate;
private String validDate;
public UserCharge(UserDetail user) {
this.user = user;
}
}

View File

@@ -0,0 +1,51 @@
package icu.samnyan.aqua.sega.maimai2.model.userdata;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Entity(name = "MaiMai2UserCourse")
@Table(name = "maimai2_user_course")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserCourse implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@JsonIgnore
private long id;
@JsonIgnore
@ManyToOne
@JoinColumn(name = "user_id")
private UserDetail user;
private int courseId;
@JsonProperty("isLastClear")
private boolean isLastClear;
private int totalRestlife;
private int totalAchievement;
private int totalDeluxscore;
private int playCount;
private String clearDate;
private String lastPlayDate;
private int bestAchievement;
private String bestAchievementDate;
private int bestDeluxscore;
private String bestDeluxscoreDate;
public UserCourse(UserDetail user) {
this.user = user;
}
}

View File

@@ -52,6 +52,8 @@ public class UserDetail implements Serializable {
private int playerRating;
private int highestRating;
private int gradeRank;
private int classRank;
private int courseRank;
@Convert(converter = IntegerListConverter.class)
private List<Integer> charaSlot; // Entries: 5
@@ -67,6 +69,8 @@ public class UserDetail implements Serializable {
private String lastDataVersion;
private String lastLoginDate;
private String lastPlayDate;
private int lastPlayCredit;
private int lastPlayMode;
private int lastPlaceId;
private String lastPlaceName;
private int lastAllNetId;
@@ -74,12 +78,17 @@ public class UserDetail implements Serializable {
private String lastRegionName;
private String lastClientId;
private String lastCountryCode;
private int lastSelectEMoney;
private int lastSelectTicket;
private int lastSelectCourse;
private int lastCountCourse;
private String firstGameId;
private String firstRomVersion;
private String firstDataVersion;
private String firstPlayDate;
private String compatibleCmVersion;
private String dailyBonusDate;
private String dailyCourseBonusDate;
private int playVsCount;
private int playSyncCount;
private int winCount;

View File

@@ -34,7 +34,7 @@ public class UserFavorite implements Serializable {
@JoinColumn(name = "user_id")
private UserDetail user;
@JsonProperty("id")
@JsonProperty("userId")
private long favUserId;
private int itemKind;

View File

@@ -19,6 +19,9 @@ public class UserGhost {
private int titleId;
private int rate;
private int udemaeRate;
private int courseRank;
private int classRank;
private int classValue;
private String playDatetime;
private int shopId;
private int regionCode;

View File

@@ -58,6 +58,7 @@ public class UserOption implements Serializable {
private int dispJudgePos;
private int dispJudgeTouchPos;
private int adjustTiming;
private int judgeTiming;
private int ansVolume;
private int tapHoldVolume;
private int criticalSe;

View File

@@ -32,6 +32,8 @@ public class UserUdemae implements Serializable {
private int rate;
private int maxRate;
private int classValue;
private int maxClassValue;
private int totalWinNum;
private int totalLoseNum;
private int maxWinNum;