IIDX: Initial support added for DJ TROOPERS

This commit is contained in:
duel0213 2024-02-25 19:20:56 +09:00
parent 50f54ee2bb
commit f4d2a81f07
7 changed files with 202 additions and 12 deletions

View File

@ -6,6 +6,7 @@ Plugin Version: **v0.1.12**
Supported Versions
- beatmaniaIIDX 15 DJ TROOPERS
- beatmaniaIIDX 17 SIRIUS
- beatmaniaIIDX 18 Resort Anthem
- beatmaniaIIDX 19 Lincle
@ -107,10 +108,13 @@ Changelogs
- Added Experimental WebUI (WIP)
- Added music.crate/music.breg response
- CLEAR RATE and BEGINNER clear lamp may not work on certain versions
- Added Initial support for SIRIUS (profile only)
- Added Initial support for SIRIUS
- Fixed where Venue Top didn't save correctly (BISTROVER ~)
- Fixed where music.appoint send empty response even rival has score data when player doesn't have score data
- Fixed where FAVORITE may work only on specific version
- Fixed where shop name always displayed as "CORE" instead of saved one
- Fixed where rlist STEP UP achieve value was fixed value instead of saved one
- Fixed where fcombo isn't saving (Resort Anthem)
**v0.1.13**
- Added Initial support for DJ TROOPERS (WIP)

View File

@ -1,4 +1,4 @@
import { IDtoRef, Base64toBuffer, GetVersion, OldMidToNewMid, NewMidToOldMid, ReftoProfile, ReftoPcdata, ClidToPlaySide, ReftoQPRO } from "../util";
import { IDtoRef, Base64toBuffer, GetVersion, OldMidToNewMid, NewMidToOldMid, ReftoProfile, ReftoPcdata, ClidToPlaySide, ReftoQPRO, NumArrayToString } from "../util";
import { score, score_top } from "../models/score";
import { profile } from "../models/profile";
import { shop_data } from "../models/shop";
@ -25,7 +25,48 @@ export const musicgetrank: EPR = async (info, data, send) => {
let m = [], top = [], b = [], t = [];
let score_data: number[];
let indices, temp_mid = 0;
if (version < 20) {
if (version == 15) { // TODO:: Debug NumArrayToString, theres weird records (invalid exscore) //
let result = {
r: [], // v - (-1, beginner/-2, tutorial) //
};
indices = cltype === 0 ? [1, 2, 3] : [6, 7, 8];
music_data.forEach((res: score) => {
temp_mid = NewMidToOldMid(res.mid);
let mVersion = Math.floor(temp_mid / 100);
let mMid = temp_mid % 100;
if (mVersion > version) return;
for (let a = 0; a < 3; a++) {
if (res.esArray[indices[a]] == 0) continue;
result.r.push(
K.ITEM("str", NumArrayToString(
[7, 4, 13, 3, 3],
[mMid, a, res.esArray[indices[a]], -1, res.cArray[indices[a]]] // mid , diff , score , rid (rank_id) , flg //
), { v: String(mVersion) } )
);
}
});
// rival data seems to be retrieve from getralive //
// tutorial //
const tutorial = await DB.Find<tutorial>(refid, {
collection: "tutorial",
version: version
});
tutorial.sort((a: tutorial, b: tutorial) => a.tid - b.tid);
tutorial.forEach((res) => {
result.r.push(
K.ITEM("str", NumArrayToString(
[5, 1],
[res.tid, res.clr]
), { v: String("-2") })
);
});
return send.object(result);
}
else if (version < 20) {
indices = cltype === 0 ? [1, 2, 3] : [6, 7, 8];
music_data.forEach((res: score) => {
temp_mid = NewMidToOldMid(res.mid);
@ -103,11 +144,11 @@ export const musicgetrank: EPR = async (info, data, send) => {
});
if (score_top.length > 0) {
if (version >= 27) {
if (version >= 27) {
score_top.forEach((res) => {
let mVersion = Math.floor(res.mid / 1000);
if (mVersion > version) return;
top.push({
"@attr": ({
name0: res.names[0],
@ -123,7 +164,7 @@ export const musicgetrank: EPR = async (info, data, send) => {
score_top.forEach((res) => {
let mVersion = Math.floor(res.mid / 1000);
if (mVersion > version) return;
top.push({
"@attr": ({
name0: res.names[1],
@ -346,7 +387,8 @@ export const musicreg: EPR = async (info, data, send) => {
let opt2Array = Array<number>(10).fill(0); // USED OPTION (CastHour) //
let update = 0;
if (version >= 17) ghost = $(data).buffer("ghost").toString("base64");
if (version == 15) ghost = Buffer.from($(data).str("ghost"), "hex").toString("base64");
else ghost = $(data).buffer("ghost").toString("base64");
if (version >= 27) {
ghost_gauge = $(data).buffer("ghost_gauge").toString("base64");

View File

@ -1,7 +1,7 @@
import { pcdata, KDZ_pcdata, IIDX27_pcdata, IIDX28_pcdata, IIDX29_pcdata, IIDX30_pcdata, JDZ_pcdata, LDJ_pcdata, IIDX21_pcdata, IIDX22_pcdata, IIDX23_pcdata, IIDX24_pcdata, IIDX25_pcdata, IIDX26_pcdata, JDJ_pcdata } from "../models/pcdata";
import { pcdata, KDZ_pcdata, IIDX27_pcdata, IIDX28_pcdata, IIDX29_pcdata, IIDX30_pcdata, JDZ_pcdata, LDJ_pcdata, IIDX21_pcdata, IIDX22_pcdata, IIDX23_pcdata, IIDX24_pcdata, IIDX25_pcdata, IIDX26_pcdata, JDJ_pcdata, HDD_pcdata } from "../models/pcdata";
import { grade } from "../models/grade";
import { custom, default_custom } from "../models/custom";
import { IDtoCode, IDtoRef, Base64toBuffer, GetVersion, ReftoProfile, ReftoPcdata, ReftoQPRO, appendSettingConverter } from "../util";
import { IDtoCode, IDtoRef, Base64toBuffer, GetVersion, ReftoProfile, ReftoPcdata, ReftoQPRO, appendSettingConverter, NumArrayToString } from "../util";
import { eisei_grade, eisei_grade_data, lightning_musicmemo, lightning_musicmemo_new, lightning_playdata, lightning_settings, lm_playdata, lm_settings, lm_settings_new, musicmemo_data, musicmemo_data_new } from "../models/lightning";
import { profile, default_profile } from "../models/profile";
import { rival, rival_data } from "../models/rival";
@ -23,6 +23,8 @@ export const pccommon: EPR = async (info, data, send) => {
// have no idea what some of attribute or value does //
// exposing these to plugin setting or use static value //
switch (version) {
case 15:
break;
case 17:
result = {
...result,
@ -239,6 +241,9 @@ export const pcreg: EPR = async (info, data, send) => {
let lightning_settings: object;
let lightning_playdata: object;
switch (version) {
case 15:
pcdata = HDD_pcdata;
break;
case 17:
pcdata = JDJ_pcdata;
break;
@ -398,7 +403,7 @@ export const pcget: EPR = async (info, data, send) => {
custom.rival_played_folder,
custom.hide_iidxid,
);
let dArray = [], eArray = [], rArray = [], mArray = [], bArray = [];
let dArray = [], eArray = [], rArray = [], mArray = [], bArray = [], gArray = [];
grade.forEach((res: grade) => {
dArray.push([res.style, res.gradeId, res.maxStage, res.archive]);
@ -454,7 +459,24 @@ export const pcget: EPR = async (info, data, send) => {
wArray.sort((a, b) => a.tour_id - b.tour_id);
}
let event;
let event, gradeStr, exStr, skinStr;
if (version == 15) {
dArray.forEach((res: grade) => {
gArray.concat([res.gradeId, res.maxStage, res.style, res.archive]);
});
gradeStr = NumArrayToString([6, 3, 2, 7], gArray);
exStr = ""; // TODO:: //
skinStr = NumArrayToString([12], [custom.frame, custom.turntable, custom.note_burst, custom.menu_music, appendsettings, custom.lane_cover, 0, custom.category_vox]);
return send.pugFile("pug/HDD/pcget.pug", {
profile,
pcdata,
gradeStr,
exStr,
skinStr,
rArray,
});
}
if (version == 17) {
expert.sort((a: expert, b: expert) => a.coid - b.coid);
expert.forEach((res) => {
@ -770,6 +792,9 @@ export const pctakeover: EPR = async (info, data, send) => {
let lightning_settings: object;
let lightning_playdata: object;
switch (version) {
case 15:
pcdata = HDD_pcdata;
break;
case 17:
pcdata = JDJ_pcdata;
break;
@ -936,7 +961,42 @@ export const pcsave: EPR = async (info, data, send) => {
pcdata.mode = parseInt($(data).attr().mode);
pcdata.pmode = parseInt($(data).attr().pmode);
if (version == 17) {
if (version == 15) {
if (cltype == 0) {
pcdata.sach = parseInt($(data).attr().achi);
pcdata.sp_opt = parseInt($(data).attr().opt);
}
else {
pcdata.dach = parseInt($(data).attr().achi);
pcdata.dp_opt = parseInt($(data).attr().opt);
pcdata.dp_opt2 = parseInt($(data).attr().opt2);
}
pcdata.gno = parseInt($(data).attr().gno);
pcdata.sflg0 = parseInt($(data).attr().sflg0);
pcdata.sflg1 = parseInt($(data).attr().sflg1);
pcdata.sflg2 = parseInt($(data).attr().sflg2);
pcdata.sdhd = parseInt($(data).attr().sdhd);
pcdata.ncomb = parseInt($(data).attr().ncomb);
pcdata.mcomb = parseInt($(data).attr().mcomb);
if (!_.isNil($(data).element("tutorial"))) {
let clr = parseInt($(data).attr("tutorial").clr);
await DB.Upsert<tutorial>(refid,
{
collection: "tutorial",
version: version,
tid: parseInt($(data).attr("tutorial").tid),
},
{
$set: {
clr
}
}
);
}
}
else if (version == 17) {
if (cltype == 0) {
pcdata.sach = parseInt($(data).attr().achi);
pcdata.sp_opt = parseInt($(data).attr().opt);

View File

@ -15,6 +15,7 @@ export function register() {
R.Contributor("duel0213");
R.GameCode("HDD");
R.GameCode("JDJ");
R.GameCode("JDZ");
R.GameCode("KDZ");

View File

@ -9,6 +9,7 @@ export interface pcdata {
dach: number;
sflg0: number;
sflg1: number;
sflg2: number;
gno: number;
timing: number;
sdhd: number;
@ -214,6 +215,30 @@ export interface pcdata {
tourism_secret_flg2: string[];
}
export const HDD_pcdata = {
version: 15,
spnum: 0,
dpnum: 0,
sach: 0,
dach: 0,
sflg0: 0,
sflg1: 0,
sflg2: 0,
gno: 0,
sdhd: 0,
sp_opt: 0,
dp_opt: 0,
dp_opt2: 0,
mcomb: 0,
ncomb: 0,
mode: 0,
pmode: 0,
sgid: -1,
dgid: -1,
}
export const JDJ_pcdata = {
version: 17,

View File

@ -0,0 +1,9 @@
pc(status="0")
pcdata(id=profile.id idstr=profile.idstr name=profile.name pid=profile.pid spnum=pcdata.spnum dpnum=pcdata.dpnum sach=pcdata.sach dach=pcdata.dach sflg0=pcdata.sflg0 sflg1=pcdata.sflg1 sflg2=pcdata.sflg2 gno=pcdata.gno sdhd=pcdata.sdhd sp_opt=pcdata.sp_opt dp_opt=pcdata.dp_opt dp_opt2=pcdata.dp_opt2 mcomb=pcdata.mcomb ncomb=pcdata.ncomb mode=pcdata.mode pmode=pcdata.pmode)
grade(sgid=pcdata.sgid dgid=pcdata.dgid __type="str") #{gradeStr}
ex(__type="str") #{exStr}
skin(__type="str") #{skinStr}
rlist
- for (let rd of rArray)
rival(spdp=rd.play_style id=rd.profile[2] id_str=rd.profile[3] djname=rd.profile[0] pid=rd.profile[1] sg=rd.pcdata[0] dg=rd.pcdata[1] sa=rd.pcdata[2] da=rd.pcdata[3])
visitor(anum="10" snum="10" pnum="10" vs_flg="1")

View File

@ -61,9 +61,58 @@ export function Base64toBuffer(s: string) {
return Buffer.from(t);
}
export function NumArrayToString(bits: number[], numArray: number[]): string {
const characters = "0123456789:;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
let byteSum = 0;
let byteIndex = 0;
if (bits.length > 0) {
do {
byteSum = bits[byteIndex] + byteSum;
byteIndex++;
} while (byteIndex < bits.length);
}
let result = "";
let numIdx = 0;
if (numArray != null && !_.isNaN(numArray[0])) {
let numArrayIdx = 0;
if (numArray.length > 0) {
let combined = 0;
do {
if (numIdx == 0) combined = 0;
const b = bits[numArrayIdx];
combined = ((numArray[numIdx] & (1 << b) - 1) | combined << b);
numArrayIdx++;
if (numArrayIdx == bits.length) {
combined <<= 32 - byteSum;
const characterCount = Math.floor((byteSum + 5) / 6);
if (characterCount > 0) {
let charaIdx = 26;
let charaLoopCnt = characterCount;
do {
const character = (combined >> charaIdx) & 63;
result += characters.charAt(character);
charaIdx -= 6;
charaLoopCnt--;
} while (charaLoopCnt > 0);
}
numArrayIdx = 0;
}
numIdx++;
} while (numIdx < numArray.length);
}
}
return result;
}
export function GetVersion(info: EamuseInfo) {
let version = -1;
switch (info.model.substring(0, 3)) {
case "HDD": return 15;
case "JDJ": return 17;
case "JDZ": return 18;
case "KDZ": return 19;