[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 GetUserChargeHandler getUserChargeHandler;
private final GetUserCourseHandler getUserCourseHandler;
private final UploadUserPhotoHandler uploadUserPhotoHandler;
public Maimai2ServletController(GetGameSettingHandler getGameSettingHandler, GetGameEventHandler getGameEventHandler, GetGameRankingHandler getGameRankingHandler, GetGameTournamentInfoHandler getGameTournamentInfoHandler,
GetTransferFriendHandler getTransferFriendHandler, GetUserActivityHandler getUserActivityHandler, UserLoginHandler userLoginHandler, UserLogoutHandler userLogoutHandler,
@ -50,7 +51,7 @@ public class Maimai2ServletController {
GetUserOptionHandler getUserOptionHandler, GetUserItemHandler getUserItemHandler, GetUserExtendHandler getUserExtendHandler, GetUserGhostHandler getUserGhostHandler,
GetUserLoginBonusHandler getUserLoginBonusHandler, GetUserMapHandler getUserMapHandler, GetUserFavoriteHandler getUserFavoriteHandler,
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.getGameEventHandler = getGameEventHandler;
this.getGameRankingHandler = getGameRankingHandler;
@ -77,6 +78,7 @@ public class Maimai2ServletController {
this.getGameChargeHandler = getGameChargeHandler;
this.getUserChargeHandler = getUserChargeHandler;
this.getUserCourseHandler = getUserCourseHandler;
this.uploadUserPhotoHandler = uploadUserPhotoHandler;
}
// Mandatory for boot
@ -196,10 +198,9 @@ public class Maimai2ServletController {
return "{}";
}
// No support
@PostMapping("UploadUserPhotoApi")
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")

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());
newUserData.setUserName(userName);
// Set isNetMember value to 1, which enables some in-game features.
newUserData.setIsNetMember(1);
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;
}