[O] Modelless

This commit is contained in:
Azalea 2025-10-25 09:26:45 +08:00
parent 8fc2a74f95
commit 55869f9d07
15 changed files with 107 additions and 470 deletions

View File

@ -5,7 +5,6 @@ import ext.MutJDict
import ext.emptyMap
import ext.logger
import icu.samnyan.aqua.sega.diva.handler.AttendHandler
import icu.samnyan.aqua.sega.diva.handler.GameInitHandler
import icu.samnyan.aqua.sega.diva.handler.PingHandler
import icu.samnyan.aqua.sega.diva.handler.card.CardProcedureHandler
import icu.samnyan.aqua.sega.diva.handler.card.ChangeNameHandler
@ -27,6 +26,7 @@ import icu.samnyan.aqua.sega.diva.model.request.user.PdUnlockRequest
import icu.samnyan.aqua.sega.diva.model.request.user.PreStartRequest
import icu.samnyan.aqua.sega.diva.model.request.user.SpendCreditRequest
import icu.samnyan.aqua.sega.diva.model.request.user.StartRequest
import icu.samnyan.aqua.sega.diva.util.DivaDateTimeUtil
import icu.samnyan.aqua.sega.diva.util.DivaMapper
import jakarta.servlet.http.HttpServletRequest
import lombok.AllArgsConstructor
@ -38,9 +38,11 @@ import org.springframework.web.bind.annotation.RestController
import org.springframework.web.multipart.MultipartFile
import java.net.URLDecoder
import java.nio.charset.StandardCharsets
import java.time.LocalDateTime
val DIVA_BAD = mapOf("stat" to "0")
val DIVA_OK = emptyMap
val DIVA_INIT = mapOf("db_close" to "0,0", "retry_time" to "FFFF")
/**
* @author samnyan (privateamusement@protonmail.com)
@ -49,7 +51,6 @@ val DIVA_OK = emptyMap
@RequestMapping("/g/diva")
@AllArgsConstructor
class DivaController(
val gameInitHandler: GameInitHandler,
val attendHandler: AttendHandler,
val cardProcedureHandler: CardProcedureHandler,
val changeNameHandler: ChangeNameHandler,
@ -59,15 +60,12 @@ class DivaController(
val bannerDataHandler: BannerDataHandler,
val contestInfoHandler: ContestInfoHandler,
val cstmzItmCtlgHandler: CstmzItmCtlgHandler,
val cstmzItmNgMdlListHandler: CstmzItmNgMdlListHandler,
val festaInfoHandler: FestaInfoHandler,
val nvRankingHandler: NvRankingHandler,
val psRankingHandler: PsRankingHandler,
val pstdHCtrlHandler: PstdHCtrlHandler,
val pstdItemNgLstHandler: PstdItemNgLstHandler,
val pvDefChrLstHandler: PvDefChrLstHandler,
val pvListHandler: PvListHandler,
val pvNgMdlLstHandler: PvNgMdlLstHandler,
val qstInfHandler: QstInfHandler,
val rmtWpLstHandler: RmtWpLstHandler,
val shopCatalogHandler: ShopCatalogHandler,
@ -101,9 +99,9 @@ class DivaController(
logger.info("{}: {}", command, body)
val respObj = when (command) {
"game_init" -> gameInitHandler.handle(mapper.convert(body, GameInitRequest::class.java))
"game_init" -> DIVA_INIT
"attend" -> attendHandler.handle(mapper.convert(body, GameInitRequest::class.java))
"test" -> gameInitHandler.handle(mapper.convert(body, BaseRequest::class.java))
"test" -> DIVA_INIT
"nv_ranking" -> nvRankingHandler.handle(mapper.convert(body, BaseRequest::class.java))
"ps_ranking" -> psRankingHandler.handle(mapper.convert(body, PsRankingRequest::class.java))
@ -112,9 +110,9 @@ class DivaController(
"rmt_wp_list" -> rmtWpLstHandler.handle(mapper.convert(body, BaseRequest::class.java))
"festa_info" -> festaInfoHandler.handle(mapper.convert(body, BaseRequest::class.java))
"contest_info" -> contestInfoHandler.handle(mapper.convert(body, BaseRequest::class.java))
"pv_def_chr_list" -> pvDefChrLstHandler.handle(mapper.convert(body, BaseRequest::class.java))
"pv_ng_mdl_list" -> pvNgMdlLstHandler.handle(mapper.convert(body, BaseRequest::class.java))
"cstmz_itm_ng_mdl_list" -> cstmzItmNgMdlListHandler.handle(mapper.convert(body, BaseRequest::class.java))
"pv_def_chr_list" -> mapOf("pdcl_lut" to DivaDateTimeUtil.getString(LocalDateTime.now()), "pdc_lst" to "***")
"pv_ng_mdl_list" -> mapOf("pnml_lut" to DivaDateTimeUtil.getString(LocalDateTime.now()), "pnm_lst" to "***")
"cstmz_itm_ng_mdl_list" -> mapOf("cinml_lut" to DivaDateTimeUtil.getString(LocalDateTime.now()), "cinm_lst" to "***")
"banner_info" -> bannerInfoHandler.handle(mapper.convert(body, BaseRequest::class.java))
"banner_data" -> bannerDataHandler.handle(mapper.convert(body, BannerDataRequest::class.java))
@ -141,7 +139,7 @@ class DivaController(
"pd_unlock" -> pdUnlockHandler.handle(mapper.convert(body, PdUnlockRequest::class.java))
"spend_credit" -> spendCreditHandler.handle(mapper.convert(body, SpendCreditRequest::class.java))
"no_card_end" -> gameInitHandler.handle(mapper.convert(body, GameInitRequest::class.java))
"no_card_end" -> DIVA_INIT
"end" -> endHandler.handle(mapper.convert(body, StageResultRequest::class.java))
"get_pv_pd" -> getPvPdHandler.handle(mapper.convert(body, GetPvPdRequest::class.java))
"buy_module" -> buyModuleHandler.handle(mapper.convert(body, BuyModuleRequest::class.java))
@ -153,7 +151,7 @@ class DivaController(
"stage_result" -> stageResultHandler.handle(mapper.convert(body, StageResultRequest::class.java))
"store_ss" -> gameInitHandler.handle(mapper.convert(body, GameInitRequest::class.java))
"store_ss" -> DIVA_INIT
else -> DIVA_BAD
}
val resp = respObj as? String
@ -171,7 +169,7 @@ class DivaController(
val respObj = when (command) {
"ping" -> pingHandler.handle(mapper.convert(body, BaseRequest::class.java))
"investigate" -> gameInitHandler.handle(mapper.convert(body, BaseRequest::class.java))
"investigate" -> DIVA_INIT
"store_ss" -> storeSsHandler.handle(mapper.convert(body, StoreSsRequest::class.java), bin)
else -> "stat=1"
}

View File

@ -1,32 +1,65 @@
package icu.samnyan.aqua.sega.diva.handler
import icu.samnyan.aqua.sega.diva.model.common.attend.DispersalParameter
import icu.samnyan.aqua.sega.diva.model.common.attend.EtcParameter
import icu.samnyan.aqua.sega.diva.model.common.attend.GameBalanceParameter
import ext.csv
import icu.samnyan.aqua.sega.diva.model.request.BaseRequest
import icu.samnyan.aqua.sega.diva.model.response.boot.AttendResponse
import icu.samnyan.aqua.sega.diva.model.response.boot.GameInitResponse
import icu.samnyan.aqua.sega.diva.model.response.operation.PingResponse
import icu.samnyan.aqua.sega.general.dao.PropertyEntryRepository
import icu.samnyan.aqua.sega.general.model.PropertyEntry
import org.springframework.stereotype.Component
import java.time.LocalDateTime
import java.util.*
@Component
class GameInitHandler {
fun handle(request: BaseRequest) = GameInitResponse(
"0,0",
"FFFF"
)
fun gameBalanceParameter(): String {
val name_change_price = 100
// Trial bids: clear.pay, clear.win, great.pay, great.win, excellent.pay, excellent.win, perfect.pay, perfect.win
val easy_trials = listOf(5, 10, 10, 25, 20, 50, 30, 90)
val normal_trials = listOf(5, 10, 10, 25, 20, 50, 30, 90)
val hard_trials = listOf(5, 10, 10, 25, 20, 50, 30, 90)
val extreme_trials = listOf(5, 10, 10, 25, 20, 50, 30, 90)
val extra_extreme_trials = listOf(5, 10, 10, 25, 20, 50, 30, 90)
return (listOf(name_change_price, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 1, 1, 1, 3, 4, 5, 1, 1, 1, 4, 5, 6, 1, 1, 1, 5, 6, 7, 4, 4, 4, 9, 10, 14) +
easy_trials + normal_trials + hard_trials +
extreme_trials + extra_extreme_trials + listOf(10, 30) + Collections.nCopies(100, 0)).take(100).csv
}
fun EtcParameter(): String {
val module_shop_close = false
val card_reissue_close = true
val card_renewal_close = true
val reset_passwd_close = true
val change_passwd_close = false
val change_name_close = false
val encore_mode_close = true
val third_stg_mode_close = false
val slow_down_threshold = 0
val log_write_flag = false
val daily_quest_close = true
val weekly_quest_close = true
val special_quest_close = true
val nppg_close = false
val list = listOf(module_shop_close, card_reissue_close, card_renewal_close, reset_passwd_close,
change_passwd_close, change_name_close, encore_mode_close, third_stg_mode_close,
slow_down_threshold, log_write_flag, daily_quest_close, weekly_quest_close,
special_quest_close, nppg_close) + Collections.nCopies(100, 0)
return list.take(100).map {
if (it is Boolean) if (it) "1" else "0"
else if (it is Int) it.toString()
else "0"
}.csv
}
@Component
class AttendHandler {
fun handle(request: BaseRequest) = AttendResponse(
EtcParameter().toInternal(),
DispersalParameter().toInternal(),
GameBalanceParameter().toInternal(),
LocalDateTime.now()
fun handle(request: BaseRequest) = mapOf(
"atnd_prm1" to EtcParameter(),
"atnd_prm2" to mapOf(
"max_pd_items" to 30, "" to 1, "max_ps_rankings" to 100,
"max_screenshots" to 2, "ss_upload_delay" to 1, "" to 1
).values.plus(Collections.nCopies(100, 0)).take(100).csv,
"atnd_prm3" to gameBalanceParameter(),
"atnd_lut" to LocalDateTime.now()
)
}

View File

@ -1,18 +0,0 @@
package icu.samnyan.aqua.sega.diva.handler.databank
import icu.samnyan.aqua.sega.diva.model.request.BaseRequest
import icu.samnyan.aqua.sega.diva.model.response.databank.CstmzItmNgMdlListResponse
import icu.samnyan.aqua.sega.diva.util.DivaDateTimeUtil
import org.springframework.stereotype.Component
import java.time.LocalDateTime
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Component
class CstmzItmNgMdlListHandler {
fun handle(request: BaseRequest) = CstmzItmNgMdlListResponse(
DivaDateTimeUtil.getString(LocalDateTime.now()),
"***"
)
}

View File

@ -1,18 +0,0 @@
package icu.samnyan.aqua.sega.diva.handler.databank
import icu.samnyan.aqua.sega.diva.model.request.BaseRequest
import icu.samnyan.aqua.sega.diva.model.response.databank.PvDefChrLstResponse
import icu.samnyan.aqua.sega.diva.util.DivaDateTimeUtil
import org.springframework.stereotype.Component
import java.time.LocalDateTime
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Component
class PvDefChrLstHandler {
fun handle(request: BaseRequest) = PvDefChrLstResponse(
DivaDateTimeUtil.getString(LocalDateTime.now()),
"***"
)
}

View File

@ -1,18 +0,0 @@
package icu.samnyan.aqua.sega.diva.handler.databank
import icu.samnyan.aqua.sega.diva.model.request.BaseRequest
import icu.samnyan.aqua.sega.diva.model.response.databank.PvNgMdlLstResponse
import icu.samnyan.aqua.sega.diva.util.DivaDateTimeUtil
import org.springframework.stereotype.Component
import java.time.LocalDateTime
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Component
class PvNgMdlLstHandler {
fun handle(request: BaseRequest) = PvNgMdlLstResponse(
DivaDateTimeUtil.getString(LocalDateTime.now()),
"***"
)
}

View File

@ -1,5 +1,6 @@
package icu.samnyan.aqua.sega.diva.handler.user
import ext.invoke
import ext.logger
import icu.samnyan.aqua.sega.diva.DivaRepos
import icu.samnyan.aqua.sega.diva.model.common.PreStartResult
@ -18,67 +19,54 @@ import java.util.concurrent.ThreadLocalRandom
class PreStartHandler(val db: DivaRepos) {
var logger = logger()
fun handle(request: PreStartRequest): Any {
val profileOptional = db.profile.findByPdId(request.aime_id)
if (profileOptional.isEmpty) {
return PreStartResponse(
PreStartResult.NEW_REGISTRATION
)
} else {
val profile = profileOptional.get()
val profile = db.profile.findByPdId(request.aime_id)() ?: return PreStartResponse(PreStartResult.NEW_REGISTRATION)
val sessionOptional = db.gameSession.findByPdId(profile)
if (sessionOptional.isPresent) {
val session = sessionOptional.get()
if (!session.lastUpdateTime
.isBefore(LocalDateTime.now().minusMinutes(5)) && session.startMode == StartMode.START
) {
return PreStartResponse(
PreStartResult.ALREADY_PLAYING
)
} else {
db.gameSession.delete(session)
}
db.gameSession.findByPdId(profile)()?.let { session ->
if (!session.lastUpdateTime.isBefore(LocalDateTime.now().minusMinutes(5)) && session.startMode == StartMode.START) {
return PreStartResponse(PreStartResult.ALREADY_PLAYING)
} else {
db.gameSession.delete(session)
}
val session = GameSession(
ThreadLocalRandom.current().nextInt(100, 99999),
profile,
StartMode.PRE_START,
LocalDateTime.now(),
LocalDateTime.now(),
-1,
-1,
-1,
profile.level,
profile.levelExp,
profile.level,
profile.levelExp,
profile.vocaloidPoints
)
db.gameSession.save(session)
return PreStartResponse(
PreStartResult.SUCCESS,
session.acceptId,
profile.pdId,
profile.playerName,
profile.sortMode,
profile.level,
profile.levelExp,
profile.levelTitle,
profile.plateEffectId,
profile.plateId,
profile.commonModule,
profile.commonModuleSetTime,
profile.commonSkin,
profile.buttonSe,
profile.slideSe,
profile.chainSlideSe,
profile.sliderTouchSe,
profile.vocaloidPoints,
profile.passwordStatus
)
}
val session = GameSession(
ThreadLocalRandom.current().nextInt(100, 99999),
profile,
StartMode.PRE_START,
LocalDateTime.now(),
LocalDateTime.now(),
-1,
-1,
-1,
profile.level,
profile.levelExp,
profile.level,
profile.levelExp,
profile.vocaloidPoints
)
db.gameSession.save(session)
return PreStartResponse(
PreStartResult.SUCCESS,
session.acceptId,
profile.pdId,
profile.playerName,
profile.sortMode,
profile.level,
profile.levelExp,
profile.levelTitle,
profile.plateEffectId,
profile.plateId,
profile.commonModule,
profile.commonModuleSetTime,
profile.commonSkin,
profile.buttonSe,
profile.slideSe,
profile.chainSlideSe,
profile.sliderTouchSe,
profile.vocaloidPoints,
profile.passwordStatus
)
}
}

View File

@ -1,35 +0,0 @@
package icu.samnyan.aqua.sega.diva.model.common.attend;
import icu.samnyan.aqua.sega.diva.model.Internalizable;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Data
@NoArgsConstructor
public class DispersalParameter implements Internalizable {
private int max_pd_items = 30;
private int max_ps_rankings = 100;
private int max_uploadable_screenshots = 2;
private int ss_upload_delay = 1;
@Override
public String toInternal() {
List<Integer> list = new LinkedList<>();
list.add(max_pd_items);
list.add(1);
list.add(max_ps_rankings);
list.add(max_uploadable_screenshots);
list.add(ss_upload_delay);
list.add(1);
list.addAll(Collections.nCopies(100, 0));
return list.stream().limit(100).map(Object::toString).collect(Collectors.joining(","));
}
}

View File

@ -1,61 +0,0 @@
package icu.samnyan.aqua.sega.diva.model.common.attend;
import icu.samnyan.aqua.sega.diva.model.Internalizable;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Data
@NoArgsConstructor
public class EtcParameter implements Internalizable {
private Boolean module_shop_close = false;
private Boolean card_reissue_close = true;
private Boolean card_renewal_close = true;
private Boolean reset_passwd_close = true;
private Boolean change_passwd_close = false;
private Boolean change_name_close = false;
private Boolean encore_mode_close = true;
private Boolean third_stg_mode_close = false;
private Integer slow_down_threshold = 0;
private Boolean log_write_flag = false;
private Boolean daily_quest_close = true;
private Boolean weekly_quest_close = true;
private Boolean special_quest_close = true;
private Boolean nppg_close = false;
@Override
public String toInternal() {
List<Object> list = new LinkedList<>();
list.add(module_shop_close);
list.add(card_reissue_close);
list.add(card_renewal_close);
list.add(reset_passwd_close);
list.add(change_passwd_close);
list.add(change_name_close);
list.add(encore_mode_close);
list.add(third_stg_mode_close);
list.add(slow_down_threshold);
list.add(log_write_flag);
list.add(daily_quest_close);
list.add(weekly_quest_close);
list.add(special_quest_close);
list.add(nppg_close);
list.addAll(Collections.nCopies(100, 0));
return list.stream().limit(100).map(x -> {
if (x instanceof Boolean) {
return (Boolean) x ? "1" : "0";
}
if (x instanceof Integer) {
return String.valueOf(x);
}
return "0";
}).collect(Collectors.joining(","));
}
}

View File

@ -1,104 +0,0 @@
package icu.samnyan.aqua.sega.diva.model.common.attend;
import icu.samnyan.aqua.sega.diva.model.Internalizable;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Data
@NoArgsConstructor
public class GameBalanceParameter implements Internalizable {
private int name_change_price = 100;
private GameBalanceTrialBidSet easy_trials = new GameBalanceTrialBidSet(
new GameBalanceTrialBid(5, 10),
new GameBalanceTrialBid(10, 25),
new GameBalanceTrialBid(20, 50),
new GameBalanceTrialBid(30, 90)
);
private GameBalanceTrialBidSet normal_trials = new GameBalanceTrialBidSet(
new GameBalanceTrialBid(5, 10),
new GameBalanceTrialBid(10, 25),
new GameBalanceTrialBid(20, 50),
new GameBalanceTrialBid(30, 90)
);
private GameBalanceTrialBidSet hard_trials = new GameBalanceTrialBidSet(
new GameBalanceTrialBid(5, 10),
new GameBalanceTrialBid(10, 25),
new GameBalanceTrialBid(20, 50),
new GameBalanceTrialBid(30, 90)
);
private GameBalanceTrialBidSet extreme_trials = new GameBalanceTrialBidSet(
new GameBalanceTrialBid(5, 10),
new GameBalanceTrialBid(10, 25),
new GameBalanceTrialBid(20, 50),
new GameBalanceTrialBid(30, 90)
);
private GameBalanceTrialBidSet extra_extreme_trials = new GameBalanceTrialBidSet(
new GameBalanceTrialBid(5, 10),
new GameBalanceTrialBid(10, 25),
new GameBalanceTrialBid(20, 50),
new GameBalanceTrialBid(30, 90)
);
@Override
public String toInternal() {
Integer[] arr = new Integer[]{
this.name_change_price,
0, // unkn
1,
1,
1,
1,
1,
1,
1,
1,
2,
3,
4, // unkn
1,
1,
1,
3,
4,
5, // unkn
1,
1,
1,
4,
5,
6, // unkn
1,
1,
1,
5,
6,
7, // unkn
4,
4,
4,
9,
10,
14 // unkn
};
List<Integer> list = new LinkedList<>(Arrays.asList(arr));
list.addAll(easy_trials.getArr());
list.addAll(normal_trials.getArr());
list.addAll(hard_trials.getArr());
list.addAll(extreme_trials.getArr());
list.addAll(extra_extreme_trials.getArr());
list.add(10);
list.add(30);
list.addAll(Collections.nCopies(100, 0));
return list.stream().limit(100).map(Object::toString).collect(Collectors.joining(","));
}
}

View File

@ -1,18 +0,0 @@
package icu.samnyan.aqua.sega.diva.model.common.attend;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Data
@AllArgsConstructor
public class GameBalanceTrialBid {
private int pay;
private int win;
public String getString() {
return pay + "," + win;
}
}

View File

@ -1,34 +0,0 @@
package icu.samnyan.aqua.sega.diva.model.common.attend;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Data
@AllArgsConstructor
public class GameBalanceTrialBidSet {
private GameBalanceTrialBid clear;
private GameBalanceTrialBid great;
private GameBalanceTrialBid excellent;
private GameBalanceTrialBid perfect;
public List<Integer> getArr() {
Integer[] arr = new Integer[]{
clear.getPay(),
clear.getWin(),
great.getPay(),
great.getWin(),
excellent.getPay(),
excellent.getWin(),
perfect.getPay(),
perfect.getWin(),
};
return new LinkedList<>(Arrays.asList(arr));
}
}

View File

@ -1,19 +0,0 @@
package icu.samnyan.aqua.sega.diva.model.response.boot;
import lombok.Getter;
import lombok.Setter;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Getter
@Setter
public class GameInitResponse {
private String db_close;
private String retry_time;
public GameInitResponse(String db_close, String retry_time) {
this.db_close = db_close;
this.retry_time = retry_time;
}
}

View File

@ -1,19 +0,0 @@
package icu.samnyan.aqua.sega.diva.model.response.databank;
import lombok.Getter;
import lombok.Setter;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Getter
@Setter
public class CstmzItmNgMdlListResponse {
private String cinml_lut;
private String cinm_lst;
public CstmzItmNgMdlListResponse(String cinml_lut, String cinm_lst) {
this.cinml_lut = cinml_lut;
this.cinm_lst = cinm_lst;
}
}

View File

@ -1,19 +0,0 @@
package icu.samnyan.aqua.sega.diva.model.response.databank;
import lombok.Getter;
import lombok.Setter;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Getter
@Setter
public class PvDefChrLstResponse {
private String pdcl_lut;
private String pdc_lst;
public PvDefChrLstResponse(String pdcl_lut, String pdc_lst) {
this.pdcl_lut = pdcl_lut;
this.pdc_lst = pdc_lst;
}
}

View File

@ -1,19 +0,0 @@
package icu.samnyan.aqua.sega.diva.model.response.databank;
import lombok.Getter;
import lombok.Setter;
/**
* @author samnyan (privateamusement@protonmail.com)
*/
@Getter
@Setter
public class PvNgMdlLstResponse {
private String pnml_lut;
private String pnm_lst;
public PvNgMdlLstResponse(String pnml_lut, String pnm_lst) {
this.pnml_lut = pnml_lut;
this.pnm_lst = pnm_lst;
}
}