[maimai2] Enable isNetUser flag and implement scorecard upload

pull/1/head
Dom Eori 2021-08-21 01:09:52 +09:00
parent b5b97c359d
commit 0cf5039ede
5 changed files with 121 additions and 3 deletions

View File

@ -43,6 +43,7 @@ public class Maimai2ServletController {
private final GetUserRegionHandler getUserRegionHandler; private final GetUserRegionHandler getUserRegionHandler;
private final GetUserChargeHandler getUserChargeHandler; private final GetUserChargeHandler getUserChargeHandler;
private final GetUserCourseHandler getUserCourseHandler; private final GetUserCourseHandler getUserCourseHandler;
private final UploadUserPhotoHandler uploadUserPhotoHandler;
public Maimai2ServletController(GetGameSettingHandler getGameSettingHandler, GetGameEventHandler getGameEventHandler, GetGameRankingHandler getGameRankingHandler, GetGameTournamentInfoHandler getGameTournamentInfoHandler, public Maimai2ServletController(GetGameSettingHandler getGameSettingHandler, GetGameEventHandler getGameEventHandler, GetGameRankingHandler getGameRankingHandler, GetGameTournamentInfoHandler getGameTournamentInfoHandler,
GetTransferFriendHandler getTransferFriendHandler, GetUserActivityHandler getUserActivityHandler, UserLoginHandler userLoginHandler, UserLogoutHandler userLogoutHandler, GetTransferFriendHandler getTransferFriendHandler, GetUserActivityHandler getUserActivityHandler, UserLoginHandler userLoginHandler, UserLogoutHandler userLogoutHandler,
@ -50,7 +51,7 @@ public class Maimai2ServletController {
GetUserOptionHandler getUserOptionHandler, GetUserItemHandler getUserItemHandler, GetUserExtendHandler getUserExtendHandler, GetUserGhostHandler getUserGhostHandler, GetUserOptionHandler getUserOptionHandler, GetUserItemHandler getUserItemHandler, GetUserExtendHandler getUserExtendHandler, GetUserGhostHandler getUserGhostHandler,
GetUserLoginBonusHandler getUserLoginBonusHandler, GetUserMapHandler getUserMapHandler, GetUserFavoriteHandler getUserFavoriteHandler, 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) { GetGameChargeHandler getGameChargeHandler, GetUserChargeHandler getUserChargeHandler, GetUserCourseHandler getUserCourseHandler, UploadUserPhotoHandler uploadUserPhotoHandler) {
this.getGameSettingHandler = getGameSettingHandler; this.getGameSettingHandler = getGameSettingHandler;
this.getGameEventHandler = getGameEventHandler; this.getGameEventHandler = getGameEventHandler;
this.getGameRankingHandler = getGameRankingHandler; this.getGameRankingHandler = getGameRankingHandler;
@ -77,6 +78,7 @@ public class Maimai2ServletController {
this.getGameChargeHandler = getGameChargeHandler; this.getGameChargeHandler = getGameChargeHandler;
this.getUserChargeHandler = getUserChargeHandler; this.getUserChargeHandler = getUserChargeHandler;
this.getUserCourseHandler = getUserCourseHandler; this.getUserCourseHandler = getUserCourseHandler;
this.uploadUserPhotoHandler = uploadUserPhotoHandler;
} }
// Mandatory for boot // Mandatory for boot
@ -196,10 +198,9 @@ public class Maimai2ServletController {
return "{}"; return "{}";
} }
// No support
@PostMapping("UploadUserPhotoApi") @PostMapping("UploadUserPhotoApi")
public String uploadUserPhotoHandler(@ModelAttribute Map<String, Object> request) throws JsonProcessingException { public String uploadUserPhotoHandler(@ModelAttribute Map<String, Object> request) throws JsonProcessingException {
return "{\"returnCode\":1,\"apiName\":\"com.sega.maimai2servlet.api.UploadUserPhotoApi\"}"; return uploadUserPhotoHandler.handle(request);
} }
@PostMapping("UploadUserPlaylogApi") @PostMapping("UploadUserPlaylogApi")

View File

@ -0,0 +1,70 @@
package icu.samnyan.aqua.sega.maimai2.handler.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import icu.samnyan.aqua.sega.maimai2.handler.BaseHandler;
import icu.samnyan.aqua.sega.maimai2.model.request.UploadUserPhoto;
import icu.samnyan.aqua.sega.maimai2.model.request.data.UserPhoto;
import icu.samnyan.aqua.sega.util.jackson.BasicMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Base64;
import java.util.Map;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Component
public class UploadUserPhotoHandler implements BaseHandler {
private static final Logger logger = LoggerFactory.getLogger(UploadUserPhotoHandler.class);
private final BasicMapper mapper;
public UploadUserPhotoHandler(BasicMapper mapper) {
this.mapper = mapper;
}
@Override
public String handle(Map<String, Object> request) throws JsonProcessingException {
/*
Maimai DX sends splited base64 data for one jpeg image.
So, make a temp file and keep append bytes until last part received.
If finished, rename it to other name so user can keep save multiple score cards in a single day.
*/
UploadUserPhoto uploadUserPhoto = mapper.convert(request, UploadUserPhoto.class);
UserPhoto userPhoto = uploadUserPhoto.getUserPhoto();
long userId = userPhoto.getUserId();
int trackNo = userPhoto.getTrackNo();
int divNumber = userPhoto.getDivNumber();
int divLength = userPhoto.getDivLength();
String divData = userPhoto.getDivData();
try {
String tmp_filename = userId + "-" + trackNo + ".tmp";
byte[] imageData = Base64.getDecoder().decode(divData);
Files.write(Paths.get("data/" + tmp_filename), imageData, StandardOpenOption.CREATE, StandardOpenOption.APPEND);
if (divNumber == (divLength - 1)) {
String filename = userId + "-" + LocalDateTime.now().toEpochSecond(ZoneOffset.UTC) + ".jpg";
Files.move(Paths.get("data/" + tmp_filename), Paths.get("data/" + filename));
}
} catch (IOException e) {
logger.error("Result: User photo save failed", e);
}
logger.info("Result: User photo saved");
return "{\"returnCode\":1,\"apiName\":\"com.sega.maimai2servlet.api.UploadUserPhotoApi\"}";
}
}

View File

@ -98,6 +98,9 @@ public class UpsertUserAllHandler implements BaseHandler {
String userName = new String(newUserData.getUserName()); String userName = new String(newUserData.getUserName());
newUserData.setUserName(userName); newUserData.setUserName(userName);
// Set isNetMember value to 1, which enables some in-game features.
newUserData.setIsNetMember(1);
userDataRepository.saveAndFlush(newUserData); userDataRepository.saveAndFlush(newUserData);
} }

View File

@ -0,0 +1,18 @@
package icu.samnyan.aqua.sega.maimai2.model.request;
import icu.samnyan.aqua.sega.maimai2.model.request.data.UserPhoto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UploadUserPhoto implements Serializable {
private UserPhoto userPhoto;
}

View File

@ -0,0 +1,26 @@
package icu.samnyan.aqua.sega.maimai2.model.request.data;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserPhoto implements Serializable {
private int orderId;
private long userId;
private int divNumber;
private int divLength;
private String divData;
private int placeId;
private String clientId;
private String uploadDate;
private long playlogId;
private int trackNo;
}