Festo Support finished

This commit is contained in:
Sean Chen 2022-08-14 18:14:01 +08:00
parent 89deb428e1
commit a4fef0a05b
18 changed files with 2099 additions and 460 deletions

View File

@ -1,18 +1,26 @@
# jubeat
# Jubeat Plugin
Plugin Version: **v1.0.0**
Jubeat Plugin for Asphyxia Core
---
# Supported Versions
**jubeat** is music simulation game.
Touch the panel on a screen at the right timing and rhythm to the music.
- Festo
## Supported Versions
# Versions
- ripples
- V1.0.0 (2021/12/16)
- Only support normal mode score saving.
## Changelog
- V2.0.0 (2022/08/14)
- Now Support Festo Final
- Support hard mode score saving
- Support Turn Run
### 1.0.0
# TODO
- Initial Release
- [ ] Customized Turn Run. (Currently can't cuz Jubeat courses limit is 60, need someone to find how to patch it.)
# Credits
- Thanks [asesidaa](https://github.com/asesidaa?tab=repositories) for help!
- And also the other open-soured Jubeat lovers!

View File

@ -1,22 +0,0 @@
import { getVersion } from '../utils';
export const shopRegist: EPR = (i, data, send) => {
const locId = $(data).content('shop.locationid');
const cabId = $(data).number('shop.testmode.network.cabinet_id', 1);
const version = getVersion(i);
if (version <= 0) return send.deny();
return send.object({
data: {
cabid: K.ITEM('u32', cabId),
locationid: K.ITEM('str', locId),
...(version >= 1 && version <= 3 && { is_send: K.ITEM('u8', 1) }),
},
});
};
export const demodata = {
getNews: (_, __, send) =>
send.object({ data: { officialnews: K.ATTR({ count: '0' }) } }),
};

View File

@ -1,55 +0,0 @@
import { getVersion } from '../utils';
export const lobby = {
check: (info, data, send) => {
const version = getVersion(info);
if (version <= 0) return send.deny();
return send.object({
data: {
entrant_nr: K.ITEM('u32', 1, { time: 0 + '' }),
interval: K.ITEM('s16', 3),
entry_timeout: K.ITEM('s16', 15),
waitlist: K.ATTR({ count: '0' }),
},
});
},
entry: (info, data, send) => {
const version = getVersion(info);
if (version <= 0) return send.deny();
const musicId = $(data).number('data.music.id', 20000037);
const musicSeq = $(data).number('data.music', 0);
return send.object({
data: {
roomid: K.ITEM('s64', BigInt(1), { master: '1' }),
refresh_intr: K.ITEM('s16', 5),
music: {
id: K.ITEM('u32', musicId),
seq: K.ITEM('u8', musicSeq),
},
},
});
},
refresh: (info, data, send) => {
const version = getVersion(info);
if (version <= 0) return send.deny();
return send.object({
data: {
refresh_intr: K.ITEM('s16', 3),
},
});
},
report: (info, data, send) => {
const version = getVersion(info);
if (version <= 0) return send.deny();
return send.object({
data: {
refresh_intr: K.ITEM('s16', 3),
},
});
},
};

View File

@ -1,232 +0,0 @@
import { getVersion } from '../utils';
import Profile from '../models/profile';
import { Score } from '../models/score';
export const profile: { regist: EPR; get: EPR; meeting: EPR; save: EPR } = {
regist: async (info, data, send) => {
const version = getVersion(info);
const refId = $(data).str('data.player.pass.refid');
const newName = $(data).str('data.player.name', 'JUBEAT');
if (version <= 0) return send.deny();
if (!refId || !newName) return send.deny();
let profile = await DB.FindOne<Profile>(refId, { collection: 'profile' });
if (profile) return send.deny();
await DB.Insert<Profile>(refId, {
collection: 'profile',
jid: _.random(1, 99999999),
name: newName.toUpperCase(),
});
profile = await DB.FindOne<Profile>(refId, { collection: 'profile' });
if (version === 2)
return send.pugFile('templates/profile/ripples.pug', {
profile,
scores: [],
});
},
get: async (info, data, send) => {
const version = getVersion(info);
const refId = $(data).str('data.player.pass.refid');
if (version <= 0) return send.deny();
if (!refId) return send.deny();
const profile = await DB.FindOne<Profile>(refId, { collection: 'profile' });
if (!profile) return send.deny();
const playerScores = await DB.Find<Score>(refId, { collection: 'score' });
const scores = {};
console.dir(playerScores, { depth: null });
playerScores.map(v => {
if (!scores[v.musicId]) scores[v.musicId] = [{}, {}, {}];
scores[v.musicId][v.seqId] = {
score: v.score,
clearFlag: v.clearFlag,
mbar: v.musicBar,
};
});
console.dir(scores, { depth: null });
if (version === 2)
return send.pugFile('templates/profile/ripples.pug', { profile, scores });
},
meeting: async (info, data, send) => {
const version = getVersion(info);
if (version <= 0) return send.deny();
if (version === 2)
return send.object({
data: {
entryinfo: K.ATTR(
{ count: '0' },
{
meeting: [],
}
),
holdinfo: {
meeting: [],
},
reward: {
total: K.ITEM('s32', 0),
point: K.ITEM('s32', 0),
},
},
});
},
save: async (info, data, send) => {
const version = getVersion(info);
if (version <= 0) return send.deny();
const retry = $(data).number('retry', 0);
if (retry > 0) return send.deny();
const refId = $(data).str('data.player.refid');
if (!refId) return send.deny();
const profile = await DB.FindOne<Profile>(refId, { collection: 'profile' });
if (!profile) return send.deny();
if (version === 2) {
let lastMusicId: number;
let lastSeqId: number;
let lastUsedMarker: number;
let lastUsedTheme: number;
let lastUsedTitle: number;
let lastUsedSort: number;
let lastUsedFilter: number;
let lastShowRankSort: number;
let lastComboDisp: number;
const tunes = $(data).elements('data.result.tune');
for (let i = 0; i < tunes.length; i++) {
const musicId = tunes[i].number('music');
const seqId = Number(tunes[i].attr('music')?.seq);
const marker = tunes[i].number('marker');
const theme = tunes[i].number('theme');
const title = tunes[i].number('title');
const sort = tunes[i].number('sort');
const filter = tunes[i].number('filter');
const rankSort = tunes[i].number('rank_sort');
const comboDisp = tunes[i].number('combo_disp');
const score = tunes[i].number('player.score');
const clearFlag = Number(tunes[i].attr('player.score')?.clear);
const maxCombo = Number(tunes[i].attr('player.score')?.combo);
const mbar = tunes[i].numbers('player.mbar');
lastMusicId = musicId;
lastSeqId = seqId;
lastUsedMarker = marker;
lastUsedTheme = theme;
lastUsedTitle = title;
lastUsedSort = sort;
lastUsedFilter = filter;
lastShowRankSort = rankSort;
lastComboDisp = comboDisp;
let oldScore = await DB.FindOne<Score>(refId, {
collection: 'score',
musicId,
seqId,
});
if (!oldScore) {
await DB.Insert<Score>(refId, {
collection: 'score',
musicId,
seqId,
score: 0,
clearFlag: 0,
maxCombo: 0,
marker: 0,
theme: 0,
musicBar: new Array(20).fill(0),
playCount: 0,
clearCount: 0,
fullComboCount: 0,
excCount: 0,
});
oldScore = await DB.FindOne<Score>(refId, {
collection: 'score',
musicId,
seqId,
});
}
await DB.Update<Score>(
refId,
{ collection: 'score', musicId, seqId },
{
$set: {
score: Math.max(oldScore.score, score),
clearFlag: Math.max(oldScore.clearFlag, clearFlag),
maxCombo: Math.max(oldScore.maxCombo, maxCombo),
marker,
theme,
...(score > oldScore.score && { musicBar: mbar }),
},
$inc: {
playCount: 1,
...(clearFlag === 2 && { clearCount: 1 }),
...(clearFlag === 4 && { fullComboCount: 1 }),
...(clearFlag === 8 && { excCount: 1 }),
},
}
);
}
const mode = $(data).number('data.player.mode', 0);
await DB.Update<Profile>(
refId,
{ collection: 'profile' },
{
$set: {
'ripples.info': {
grade: $(data).number('data.player.grade', 0),
gradePoint: $(data).number('data.player.grade_point', 0),
},
'ripples.last': {
mode,
musicId: lastMusicId,
seqId: lastSeqId,
marker: lastUsedMarker,
title: lastUsedTitle,
theme: lastUsedTheme,
sort: lastUsedSort,
filter: lastUsedFilter,
rankSort: lastShowRankSort,
comboDisp: lastComboDisp,
},
},
$inc: {
...(mode === 1 && { 'ripples.info.onlineCount': 1 }),
...(mode === 0 && { 'ripples.info.multiCount': 1 }),
},
}
);
return send.object({
data: {
player: {
session_id: K.ITEM('u32', 1),
ranking: K.ITEM('u32', 0),
},
},
});
}
return send.deny();
},
};

View File

@ -1,38 +1,31 @@
// nodemon --exec "asphyxia-core-x64 --dev" -e ts --watch plugins
import ShopInfo from "./routes/shopinfo";
import {getProfile, Getinfo, loadScore, Meeting} from "./routes/gametop";
import {saveProfile} from "./routes/gameend";
import {Check, Entry, Refresh, Report} from "./routes/lobby";
import { demodata, shopRegist } from './handlers/common';
import { lobby } from './handlers/matching';
import { profile } from './handlers/profile';
export async function register() {
if (CORE_VERSION_MAJOR <= 1 && CORE_VERSION_MINOR < 31) {
console.error("The current version of Asphyxia Core is not supported. Requires version '1.31' or later.");
return;
}
R.GameCode("L44");
R.Contributor("yuanqiuye", "https://github.com/yuanqiuye")
R.Route("gametop.regist",getProfile);
R.Route("gametop.get_info", Getinfo);
R.Route("gametop.get_pdata", getProfile);
R.Route("gametop.get_mdata", loadScore);
R.Route("gametop.get_meeting", Meeting);
R.Route("gameend.final", true);
R.Route("gameend.regist", saveProfile);
export function register() {
if (CORE_VERSION_MAJOR <= 1 && CORE_VERSION_MINOR < 31) {
console.error(
"The current version of Asphyxia Core is not supported. Requires version '1.31' or later."
);
return;
}
R.Contributor('Kirito', 'https://github.com/Kirito3481');
R.GameCode('I44');
R.Route('shopinfo.regist', shopRegist);
R.Route('demodata.getnews', demodata.getNews);
R.Route('gametop.regist', profile.regist);
R.Route('gametop.get', profile.get);
R.Route('meeting.get', profile.meeting);
R.Route('gameend.regist', profile.save);
R.Route('gameend.log', true);
R.Route('lobby.check', lobby.check);
R.Route('lobby.entry', lobby.entry);
R.Route('lobby.refresh', lobby.refresh);
R.Route('lobby.report', lobby.report);
R.Route('netlog.send', true);
R.Unhandled();
}
R.Route("shopinfo.regist", ShopInfo);
R.Route("lobby.check", Check);
R.Route("lobby.entry", Entry);
R.Route("lobby.refresh", Refresh);
R.Route("lobby.report", Report);
R.Route("netlog.send", true);
R.Route("logger.report", true);
R.Unhandled();
}

View File

@ -0,0 +1,8 @@
export interface Course {
collection: "course";
courseId: number;
seen: boolean,
played: boolean,
cleared: boolean
}

View File

@ -1,34 +1,57 @@
export default interface Profile {
collection: 'profile';
collection: "profile";
navi?: number,
jubeatId: number;
eventFlag: number;
name: string;
emo: number[];
lastPlayTime?: number;
lastShopname: string;
lastAreaname: string;
isFirstplay: boolean;
musicId?: number;
seqId?: number;
seqEditId?: string;
rankSort?: number;
comboDisp?: number;
jid: number;
name: string;
jubility?: number;
jubilityYday?: number;
tuneCount?: number;
clearCount?: number;
saveCount?: number;
savedCount?: number;
fcCount?: number;
exCount?: number;
matchCount?: number;
bonusPoints?: number;
isBonusPlayed?: boolean;
totalBestScore?: number;
clearMaxLevel?: number;
fcMaxLevel?: number;
exMaxLevel?: number;
ripples?: Ripples;
}
emblem?: number[];
marker?: number;
theme?: number;
title?: number;
parts?: number;
sort?: number;
category?: number;
expertOption?: number;
matching?: number;
hazard?: number;
hard?: number;
export interface Ripples {
info?: {
onlineCount: number;
multiCount: number;
matchCount: number;
beatCount: number;
saveCount: number;
savedCount: number;
grade: number;
gradePoint: number;
};
secretList?: number[];
themeList?: number;
markerList?: number[];
titleList?: number[];
commuList?: number[];
partsList?: number[];
last?: {
mode: number;
musicId: number;
seqId: number;
marker: number;
title: number;
theme: number;
sort: number;
filter: number;
rankSort: number;
comboDisp: number;
};
}
secretListNew?: number[];
themeListNew?: number[];
markerListNew?: number[];
titleListNew?: number[];
}

View File

@ -1,16 +1,15 @@
export interface Score {
collection: 'score';
musicId: number;
seqId: number;
score: number;
clearFlag: number;
maxCombo: number;
marker: number;
theme: number;
musicBar: number[];
playCount: number;
clearCount: number;
fullComboCount: number;
excCount: number;
}
collection: "score";
musicId: number;
seq: number;
score: number;
clear: number;
musicRate: number;
bar: number[];
playCount: number;
clearCount: number;
fullcomboCount: number;
excellentCount: number;
isHardMode: boolean;
}

View File

@ -0,0 +1,179 @@
import {Score} from "../models/score"
import Profile from "../models/profile";
import { Course } from "../models/course";
import { COURSE_STATUS } from "../static/data";
export const saveProfile = async (info, {data}, send) => {
console.log("gameend.regist");
console.log(data, {depth:null});
const refId = $(data).str("player.refid");
if (!refId) return send.deny();
const profile = await DB.FindOne<Profile>(refId, { collection: "profile" });
if (!profile) return send.deny();
let lastMarker = 0;
let lastTheme = 0;
let lastTitle = 0;
let lastParts = 0;
let lastSort = 0;
let lastCategory = 0;
const courses = $(data).elements("player.course_list.course");
const tunes = $(data).elements("result.tune");
const select_course = $(data).elements("player.select_course");
const course_cleared : { [couseId: number]: { is_cleared: boolean} } = {};
if(select_course){
for(const course of select_course){
course_cleared[course.attr("").id] = course.bool("is_cleared");
}
}
for (const course of courses){
const courseID = course.attr("").id;
await updateCourse(refId, {
courseID: courseID,
seen: (course.number("status") & COURSE_STATUS.SEEN) != 0,
played: (course.number("status") & COURSE_STATUS.PLAYED) != 0,
cleared: course_cleared[courseID] || (course.number("status") & COURSE_STATUS.CLEARED) != 0,
});
}
for (const tune of tunes) {
profile.musicId = tune.number("music");
profile.seqId = parseInt(tune.attr("player.score").seq);
await updateScore(refId, {
bestmusicRate: tune.number("player.best_music_rate"),
musicRate: tune.number("player.music_rate"),
musicId: tune.number("music"),
seq: parseInt(tune.attr("player.score").seq),
score: tune.number("player.score"),
clear: parseInt(tune.attr("player.score").clear),
isHard: tune.bool("player.is_hard_mode"),
bestScore: tune.number("player.best_score"),
bestClear: tune.number("player.best_clear"),
playCount: tune.number("player.play_cnt"),
clearCount: tune.number("player.clear_cnt"),
fullcomboCount: tune.number("player.fc_cnt"),
excellentCount: tune.number("player.ex_cnt"),
...tune.element("player.mbar") && { mbar: tune.numbers("player.mbar") }
});
}
lastMarker = $(data).number("player.last.settings.marker");
lastTheme = $(data).number("player.last.settings.theme");
lastTitle = $(data).number("player.last.settings.title");
lastParts = $(data).number("player.last.settings.parts");
lastSort = $(data).number("player.last.sort");
lastCategory = $(data).number("player.last.category");
profile.eventFlag = Number($(data).bigint("player.event_flag"));
profile.rankSort = $(data).number("player.last.settings.rank_sort");
profile.comboDisp = $(data).number("player.last.settings.combo_disp");
profile.lastPlayTime = Number($(data).bigint("info.play_time"));
profile.lastShopname = $(data).str("info.shopname");
profile.lastAreaname = $(data).str("info.areaname");
profile.tuneCount = $(data).number("player.info.tune_cnt");
profile.saveCount = $(data).number("player.info.save_cnt");
profile.savedCount = $(data).number("player.info.saved_cnt");
profile.fcCount = $(data).number("player.info.fc_cnt");
profile.exCount = $(data).number("player.info.ex_cnt");
profile.clearCount = $(data).number("player.info.clear_cnt");
profile.matchCount = $(data).number("player.info.match_cnt");
profile.expertOption = $(data).number("player.last.expert_option");
profile.matching = $(data).number("player.last.settings.matching");
profile.hazard =$(data).number("player.last.settings.hazard");
profile.hard = $(data).number("player.last.settings.hard");
profile.bonusPoints = $(data).number("player.info.bonus_tune_points");
profile.isBonusPlayed = $(data).bool("player.info.is_bonus_tune_played");
profile.totalBestScore = $(data).number("player.info.total_best_score.normal");
profile.clearMaxLevel = $(data).number("player.info.clear_max_level");
profile.fcMaxLevel = $(data).number("player.info.fc_max_level");
profile.exMaxLevel = $(data).number("player.info.ex_max_level");
profile.navi = Number($(data).bigint("player.navi.flag"));
profile.isFirstplay = $(data).bool("player.free_first_play.is_applied");
profile.marker = lastMarker;
profile.theme = lastTheme;
profile.title = lastTitle;
profile.parts = lastParts;
profile.sort = lastSort;
profile.category = lastCategory;
profile.commuList = $(data).numbers("player.item.commu_list");
profile.secretList = $(data).numbers("player.item.secret_list");
profile.themeList = $(data).number("player.item.theme_list");
profile.markerList = $(data).numbers("player.item.marker_list");
profile.titleList = $(data).numbers("player.item.title_list");
profile.partsList = $(data).numbers("player.item.parts_list");
profile.secretListNew = $(data).numbers("player.item.new.secret_list");
profile.themeListNew = $(data).numbers("player.item.new.theme_list");
profile.markerListNew = $(data).numbers("player.item.new.marker_list");
try {
await DB.Update<Profile>(refId, { collection: "profile" }, profile);
return send.object({
data: {
player: { session_id: K.ITEM("s32", 1) },
collabo: { deller: K.ITEM("s32", 0) }
}
}, {compress:true});
} catch (e) {
console.error(`Profile save failed: ${e.message}`);
return send.deny();
}
}
const updateScore = async (refId: string, data: any): Promise<boolean> => {
try {
await DB.Upsert<Score>(refId, {
collection: "score",
musicId: data.musicId,
seq: data.seq,
isHardMode: data.isHard,
}, {
$set: {
musicId: data.musicId,
seq: data.seq,
score: data.bestScore,
clear: data.bestClear,
musicRate: data.musicRate>data.bestmusicRate?data.musicRate:data.bestmusicRate,
...data.mbar && { bar: data.mbar, },
playCount: data.playCount,
clearCount: data.clearCount,
fullcomboCount: data.fullcomboCount,
excellentCount: data.excellentCount,
isHardMode: data.isHard
}
});
return true;
} catch (e) {
console.error("Score saving failed: ", e.stack);
return false;
}
};
const updateCourse = async (refId: string, data: any): Promise<boolean> => {
try {
await DB.Upsert<Course>(refId, {
collection: "course",
courseId: data.courseID,
}, {
$set: {
courseId: data.courseID,
seen: data.seen,
played: data.played,
cleared: data.cleared
}
});
return true;
} catch (e) {
console.error("Course saving failed: ", e.stack);
return false;
}
};

View File

@ -0,0 +1,166 @@
import Profile from "../models/profile";
import { Score } from "../models/score";
export const getProfile = async (info: EamuseInfo, data: any, send: EamuseSend) => {
console.log("gametop.regist");
let refId = $(data).str("data.player.refid");
const name = $(data).str("data.player.name");
console.log(data, {depth:null});
if (!refId) return send.deny();
let profile = await DB.FindOne<Profile>(refId, { collection: "profile" });
if (!profile && name) {
const newProfile: Profile = {
collection: "profile",
jubeatId: Math.round(Math.random() * 99999999),
eventFlag: 0,
name: name,
isFirstplay: true,
emo: [],
lastShopname: "",
lastAreaname: ""
};
await DB.Upsert<Profile>(refId, { collection: "profile" }, newProfile);
profile = newProfile;
}else if (!profile && !name) {
return send.deny();
}
return send.object({
data: {
...require("../templates/gameInfos.ts")(),
player: {
jid: K.ITEM("s32", profile.jubeatId),
session_id: K.ITEM("s32", 1),
name: K.ITEM("str", profile.name),
event_flag: K.ITEM("u64", BigInt(profile.eventFlag || 0)),
...await require("../templates/profiles.ts")(profile),
}
}
}, {compress: true}
);
};
export const Getinfo = (info: EamuseInfo, data: any, send: EamuseSend) =>{
console.log(data, {depth:null});
return send.object({ data: require("../templates/gameInfos")() }, { compress: true });
}
export const loadScore = async (info, data, send) => {
console.log("gametop.get_mdata");
console.log(data,{depth:null});
const mdata_ver = $(data).number("data.player.mdata_ver");
const jubeatId = $(data).number("data.player.jid");
if (!jubeatId) return send.deny();
const profile = await DB.FindOne<Profile>(null, { collection: "profile", jubeatId });
if (!profile) return send.deny();
const scores = await DB.Find<Score>(profile.__refid, { collection: "score" });
const scoreData: {
[musicId: number]: {
[isHardMode: number]: {
musicRate: number[], score: number[], clear: number[], playCnt: number[], clearCnt: number[], fcCnt: number[], exCnt: number[], bar: number[][]
}
}
} = {};
for (const score of scores) {
if (!scoreData[score.musicId]) {
scoreData[score.musicId] = {};
}
if(!scoreData[score.musicId][score.isHardMode & 1]) {
scoreData[score.musicId][score.isHardMode & 1] = {
musicRate: [0, 0, 0],
playCnt: [0, 0, 0],
clearCnt: [0, 0, 0],
fcCnt: [0, 0, 0],
exCnt: [0, 0, 0],
clear: [0, 0, 0],
score: [0, 0, 0],
bar: [Array(30).fill(0), Array(30).fill(0), Array(30).fill(0)],
};
}
const data = scoreData[score.musicId][score.isHardMode & 1];
data.musicRate[score.seq] = score.musicRate;
data.playCnt[score.seq] = score.playCount;
data.clearCnt[score.seq] = score.clearCount;
data.fcCnt[score.seq] = score.fullcomboCount;
data.exCnt[score.seq] = score.excellentCount;
data.clear[score.seq] = score.clear;
data.score[score.seq] = score.score;
data.bar[score.seq] = score.bar;
}
var sendobj = {
data: {
player: {
jid: K.ITEM("s32", jubeatId),
mdata_list: {
music: (() => {
var musicArray = [];
Object.keys(scoreData).forEach(musicId =>
Object.keys(scoreData[musicId]).forEach(isHardMode => {
musicArray.push(
K.ATTR({ music_id: String(musicId) }, {
[isHardMode === "1" ? "hard" : "normal"]:
{
score: K.ARRAY("s32", scoreData[musicId][isHardMode].score),
clear: K.ARRAY("s8", scoreData[musicId][isHardMode].clear),
music_rate: K.ARRAY("s32", scoreData[musicId][isHardMode].musicRate),
play_cnt: K.ARRAY("s32", scoreData[musicId][isHardMode].playCnt),
clear_cnt: K.ARRAY("s32", scoreData[musicId][isHardMode].clearCnt),
fc_cnt: K.ARRAY("s32", scoreData[musicId][isHardMode].fcCnt),
ex_cnt: K.ARRAY("s32", scoreData[musicId][isHardMode].exCnt),
bar: scoreData[musicId][isHardMode].bar.map((bar, seq) => K.ARRAY("u8", bar, { seq: String(seq) }))
}
})
);
})
)
return musicArray;
})()
}
}
}
};
if(mdata_ver!=1){
sendobj = {
data:{
player:{
jid: K.ITEM("s32", jubeatId),
mdata_list: []
}
}
}
};
console.log(sendobj, {depth:null});
return send.object(sendobj, {compress:true});
}
export const Meeting = (req: EamuseInfo, data: any, send: EamuseSend) => {
return send.object({
data: {
meeting: {
single: K.ATTR({ count: "0" }),
},
reward: {
total: K.ITEM("s32", 0),
point: K.ITEM("s32", 0),
},
},
}, {compress:true});
};

View File

@ -0,0 +1,56 @@
export const Check = (req, reqData, send) => {
const { data } = reqData;
const enter = $(data).content("enter");
const time = $(data).content("time");
return send.object(
{
data: {
entrant_nr: K.ITEM("u32", 0, { time }),
interval: K.ITEM("s16", 0),
entry_timeout: K.ITEM("s16", 15),
waitlist: K.ATTR({ count: "0" }, { music: [] }),
},
},
{ compress: true }
);
};
export const Entry = (req: EamuseInfo, data: any, send: EamuseSend) => {
const {
data: { music },
} = data;
const musicId = $(music).content("id");
const musicSeq = $(music).content("seq");
return send.object(
{
data: {
roomid: K.ITEM("s64", BigInt(1), { master: "1" }),
refresh_intr: K.ITEM("s16", 0),
music: {
id: K.ITEM("u32", musicId),
seq: K.ITEM("u8", musicSeq),
},
},
},
{ compress: true }
);
};
export const Refresh = (req: EamuseInfo, data: any, send: EamuseSend) => {
return send.object(
{
data: { refresh_intr: K.ITEM("s16", 0), start: K.ITEM("bool", true) },
},
{ compress: true }
);
};
export const Report = (req: EamuseInfo, data: any, send: EamuseSend) =>
send.object(
{
data: { refresh_intr: K.ITEM("s16", 0) },
},
{ compress: true }
);

View File

@ -0,0 +1,20 @@
export default (_: EamuseInfo, data: any, send: EamuseSend) => {
const locId = $(data).element("shop").content("locationid");
console.log({...require("../templates/gameInfos.ts")()}, {depth:null});
return send.object(
{
data: {
cabid: K.ITEM("u32", 1),
locationid: K.ITEM("str", locId),
tax_phase: K.ITEM("u8", 0),
facility: {
exist: K.ITEM("u32", 0),
},
...require("../templates/gameInfos.ts")(),
},
},
{ compress: true }
);
};

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,919 @@
[
{
name: "オレのユビティズム",
difficulty: 3,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2100000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[20000042, 0, 0], [20000042, 1, 0], [20000042, 2, 0]],
[[70000119, 0, 0], [70000119, 1, 0], [70000119, 2, 0]],
[[50000115, 0, 0], [50000115, 1, 0], [50000115, 2, 0]],
],
},
{
name: "はじめてのビーチ",
difficulty: 1,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 700000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[60000080, 0, 0], [90000077, 0, 0], [90000139, 0, 0]],
[[60000086, 0, 0], [70000047, 0, 0]],
[[90000141, 0, 0]],
],
},
{
name: "【初段】超幸せハイテンション",
difficulty: 1,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 700000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[20000031, 0, 0], [60000100, 0, 0], [90000078, 0, 0]],
[[70000125, 0, 0], [90000050, 0, 0]],
[[70000106, 0, 1]],
],
},
{
name: "アニメランニング",
difficulty: 2,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 750000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[60000092, 0, 0], [90000031, 0, 0], [90000172, 0, 0]],
[[30000004, 0, 0], [80000059, 0, 0]],
[[50000209, 0, 0]],
],
},
{
name: "パブリックリゾート",
difficulty: 2,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 750000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[80000097, 0, 0], [90000029, 0, 0], [90000076, 0, 0]],
[[80000093, 0, 0], [90000048, 0, 0]],
[[80000038, 0, 0]],
],
},
{
name: "【二段】その笑顔は甘く蕩ける",
difficulty: 3,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 800000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[50000268, 0, 0], [70000039, 0, 0], [90000051, 0, 0]],
[[70000091, 0, 0], [80000014, 0, 0]],
[[60000053, 0, 1]],
],
},
{
name: "シャレを言いなシャレ",
difficulty: 4,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2400000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[70000003, 0, 0], [70000003, 1, 0], [70000003, 2, 0]],
[[70000045, 0, 0], [70000045, 1, 0], [70000045, 2, 0]],
[[70000076, 0, 0], [70000076, 1, 0], [70000076, 2, 0]],
],
},
{
name: "電脳享受空間",
difficulty: 4,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 800000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[70000046, 1, 0], [70000160, 1, 0], [50000233, 1, 0]],
[[80000031, 1, 0], [80000097, 1, 0]],
[[90000049, 1, 0]],
],
},
{
name: "孤高の少女は破滅を願う",
difficulty: 4,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 850000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[50000202, 0, 0], [70000117, 0, 0], [70000134, 0, 0]],
[[50000212, 0, 0], [80000124, 1, 0]],
[[90001008, 1, 1]],
],
},
{
name: "スタミナアップ!",
difficulty: 5,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2600000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[50000242, 0, 0], [50000277, 1, 0], [50000294, 1, 0]],
[[50000260, 1, 0], [50000261, 1, 0]],
[[90000143, 1, 0]],
],
},
{
name: "【四段】嗚呼、大繁盛!",
difficulty: 6,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2600000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[50000085, 2, 0], [50000237, 2, 0], [80000080, 2, 0]],
[[50000172, 2, 0], [50000235, 2, 0]],
[[70000065, 2, 1]],
],
},
{
name: "jubeat大回顧展 ROOM 1",
difficulty: 4,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 950000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[50000277, 0, 0], [50000277, 1, 0], [50000277, 2, 0]],
[[50000325, 0, 0], [50000325, 1, 0], [50000325, 2, 0]],
[[90000014, 0, 0], [90000014, 1, 0], [90000014, 2, 0]],
],
},
{
name: "jubeat大回顧展 ROOM 2",
difficulty: 4,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2750000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[30000048, 0, 0], [30000048, 1, 0], [30000048, 2, 0]],
[[30000121, 0, 0], [30000121, 1, 0], [30000121, 2, 0]],
[[90000012, 0, 0], [90000012, 1, 0], [90000012, 2, 0]],
],
},
{
name: "jubeat大回顧展 ROOM 3",
difficulty: 4,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 925000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[60000007, 0, 0], [60000007, 1, 0], [60000007, 2, 0]],
[[60000070, 0, 0], [60000070, 1, 0], [60000070, 2, 0]],
[[90000016, 0, 0], [90000016, 1, 0], [90000016, 2, 0]],
],
},
{
name: "jubeat大回顧展 ROOM 4",
difficulty: 4,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2800000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[40000051, 0, 0], [40000051, 1, 0], [40000051, 2, 0]],
[[40000129, 0, 0], [40000129, 1, 0], [40000129, 2, 0]],
[[90000013, 0, 0], [90000013, 1, 0], [90000013, 2, 0]],
],
},
{
name: "jubeat大回顧展 ROOM 5",
difficulty: 4,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2775000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[70000177, 0, 0], [70000177, 1, 0], [70000177, 2, 0]],
[[70000011, 0, 0], [70000011, 1, 0], [70000011, 2, 0]],
[[90000017, 0, 0], [90000017, 1, 0], [90000017, 2, 0]],
],
},
{
name: "jubeat大回顧展 ROOM 6",
difficulty: 4,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 940000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[20000123, 0, 0], [20000123, 1, 0], [20000123, 2, 0]],
[[20000038, 0, 0], [20000038, 1, 0], [20000038, 2, 0]],
[[90000011, 0, 0], [90000011, 1, 0], [90000011, 2, 0]],
],
},
{
name: "jubeat大回顧展 ROOM 7",
difficulty: 4,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 950000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[50000021, 0, 0], [50000021, 1, 0], [50000021, 2, 0]],
[[50000078, 0, 0], [50000078, 1, 0], [50000078, 2, 0]],
[[90000015, 0, 0], [90000015, 1, 0], [90000015, 2, 0]],
],
},
{
name: "jubeat大回顧展 ROOM 8",
difficulty: 4,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2800000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[80000028, 0, 0], [80000028, 1, 0], [80000028, 2, 0]],
[[80000087, 0, 0], [80000087, 1, 0], [80000087, 2, 0]],
[[90000018, 0, 0], [90000018, 1, 0], [90000018, 2, 0]],
],
},
{
name: "jubeat大回顧展 ROOM 9",
difficulty: 4,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 930000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[10000038, 0, 0], [10000038, 1, 0], [10000038, 2, 0]],
[[10000065, 0, 0], [10000065, 1, 0], [10000065, 2, 0]],
[[90000010, 0, 0], [90000010, 1, 0], [90000010, 2, 0]],
],
},
{
name: "【三段】この花を貴方へ",
difficulty: 4,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 850000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[90000034, 1, 0], [90000107, 1, 0], [90000140, 1, 0]],
[[80000052, 1, 0], [80001010, 1, 0]],
[[40000051, 1, 1]],
],
},
{
name: "雨上がりレインボー",
difficulty: 9,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2650000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[50000138, 2, 0]],
[[80000057, 2, 0]],
[[90000011, 2, 0]],
],
},
{
name: "Rain時々雨チ雨",
difficulty: 9,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2650000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[30000050, 2, 0]],
[[80000123, 2, 0]],
[[50000092, 2, 0]],
],
},
{
name: "心に残った曲",
difficulty: 7,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2700000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[80000136, 0, 0], [80000136, 1, 0], [80000136, 2, 0]],
[[20000038, 0, 0], [20000038, 1, 0], [20000038, 2, 0]],
[[60000065, 0, 0], [60000065, 1, 0], [70000084, 1, 0]],
],
},
{
name: "黒船来航",
difficulty: 7,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 850000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[50000086, 2, 0], [60000066, 2, 0], [80000040, 1, 0]],
[[50000096, 2, 0], [80000048, 2, 0]],
[[50000091, 2, 0]],
],
},
{
name: "【五段】濁流を乗り越えて",
difficulty: 7,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2650000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[50000343, 2, 0], [60000060, 2, 0], [60000071, 2, 0]],
[[60000027, 2, 0], [80000048, 2, 0]],
[[20000038, 2, 1]],
],
},
{
name: "のんびり。ゆったり。ほがらかに。",
difficulty: 8,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 950000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[40000154, 2, 0], [80000124, 2, 0], [90000139, 2, 0]],
[[60000048, 2, 0], [80000041, 2, 0]],
[[90000050, 2, 0]],
],
},
{
name: "海・KOI・スィニョーレ",
difficulty: 8,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2650000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[50000201, 2, 0]],
[[50000339, 2, 0]],
[[50000038, 2, 0]],
],
},
{
name: "【六段】電柱を見ると思出す",
difficulty: 9,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2750000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[50000288, 2, 0], [80000046, 2, 0], [80001008, 2, 0]],
[[50000207, 2, 0], [70000117, 2, 0]],
[[30000048, 2, 1]],
],
},
{
name: "コクがある曲",
difficulty: 12,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2400000,
is_hard: true,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[50000139, 0, 0], [50000139, 1, 0], [50000139, 2, 0]],
[[90000002, 0, 0], [90000002, 1, 0], [90000002, 2, 0]],
[[50000060, 0, 0], [50000060, 1, 0], [50000060, 2, 0]],
],
},
{
name: "超フェスタ!",
difficulty: 10,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 930000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[70000076, 2, 0], [70000077, 2, 0]],
[[20000038, 2, 0], [40000160, 2, 0]],
[[70000145, 2, 0]],
],
},
{
name: "【七段】操り人形はほくそ笑む",
difficulty: 10,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2800000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[70000006, 2, 0], [70000171, 2, 0], [80000003, 2, 0]],
[[50000078, 2, 0], [50000324, 2, 0]],
[[80000118, 2, 1]],
],
},
{
name: "絶体絶命スリーチャレンジ!",
difficulty: 11,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_HAZARD,
score: 0,
is_hard: false,
hazard_type: COURSE_HAZARD_FC3,
tune_list: [
[[50000238, 2, 0], [70000003, 2, 0], [90000051, 1, 0]],
[[50000027, 2, 0], [50000387, 2, 0]],
[[80000056, 2, 0]],
],
},
{
name: "天国の舞踏会",
difficulty: 11,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2800000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[60000065, 1, 0]],
[[80001007, 2, 0]],
[[90001007, 2, 1]],
],
},
{
name: "【八段】山の賽子",
difficulty: 12,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2820000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[50000200, 2, 0], [50000291, 2, 0], [60000003, 2, 0]],
[[50000129, 2, 0], [80000021, 2, 0]],
[[80000087, 2, 1]],
],
},
{
name: "The 8th KAC 個人部門",
difficulty: 14,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 700000,
is_hard: true,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[90000052, 2, 0]],
[[90000013, 2, 0]],
[[70000167, 2, 0]],
],
},
{
name: "The 8th KAC 団体部門",
difficulty: 14,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 700000,
is_hard: true,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[90000009, 2, 0]],
[[80000133, 2, 0]],
[[80000101, 2, 0]],
],
},/*
{
name: "BEMANI MASTER KOREA 2019",
difficulty: 14,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 700000,
is_hard: true,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[90000003, 2, 0]],
[[80000090, 2, 0]],
[[90000009, 2, 0]],
],
},*/
{
name: "The 9th KAC 1st Stage 個人部門",
difficulty: 14,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 700000,
is_hard: true,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[90000125, 2, 0]],
[[60000065, 2, 0]],
[[90000023, 2, 0]],
],
},
{
name: "The 9th KAC 1st Stage 団体部門",
difficulty: 14,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 700000,
is_hard: true,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[90000125, 2, 0]],
[[50000135, 2, 0]],
[[90000045, 2, 0]],
],
},
{
name: "The 9th KAC 2nd Stage 個人部門",
difficulty: 14,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 700000,
is_hard: true,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[90000095, 2, 0]],
[[80000085, 2, 0]],
[[80000090, 2, 0]],
],
},
{
name: "The 9th KAC 2nd Stage 団体部門",
difficulty: 14,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 700000,
is_hard: true,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[90000113, 2, 0]],
[[50000344, 2, 0]],
[[90000096, 2, 0]],
],
},
{
name: "The 10th KAC 1st Stage",
difficulty: 14,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 700000,
is_hard: true,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[90000003, 2, 0]],
[[90000151, 2, 0]],
[[90000174, 2, 0]],
],
},
{
name: "The 10th KAC 2nd Stage",
difficulty: 14,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 700000,
is_hard: true,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[90000121, 2, 0]],
[[90000113, 2, 0]],
[[90000124, 2, 0]],
],
},
{
name: "どうやって押してる?",
difficulty: 13,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2600000,
is_hard: true,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[40000127, 0, 0]],
[[50000123, 0, 0]],
[[50000126, 0, 0]],
],
},
/*
{
name: "BEMANI MASTER KOREA 2021",
difficulty: 14,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 700000,
is_hard: true,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[90000180, 2, 0]],
[[90000095, 2, 0]],
[[90000047, 2, 0]],
],
},
*/
{
name: "初めてのHARD MODE再び",
difficulty: 13,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2750000,
is_hard: true,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[50000096, 2, 0], [50000263, 2, 0], [80000119, 2, 0]],
[[60000021, 2, 0], [60000075, 2, 0]],
[[60000039, 2, 0]],
],
},
{
name: "【九段】2人からの挑戦状",
difficulty: 13,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2830000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[50000023, 2, 0], [80000025, 2, 0], [80000106, 2, 0]],
[[50000124, 2, 0], [80000082, 2, 0]],
[[60000115, 2, 1]],
],
},
{
name: "天空の庭 太陽の園",
difficulty: 13,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 965000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[40000153, 2, 0]],
[[80000007, 2, 0]],
[[70000173, 2, 0]],
],
},
{
name: "緊急!迅速!大混乱!",
difficulty: 14,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2900000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[20000040, 2, 0], [50000244, 2, 0], [60000074, 2, 0]],
[[40000152, 2, 0], [50000158, 2, 0]],
[[40000057, 2, 0]],
],
},
{
name: "【十段】時の超越者",
difficulty: 14,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2820000,
is_hard: true,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[20000051, 2, 0], [50000249, 2, 0], [70000145, 2, 0]],
[[40000046, 2, 0], [50000180, 2, 0]],
[[50000134, 2, 1]],
],
},
{
name: "jubeat大回顧展 ROOM 10",
difficulty: 13,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2850000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[30000127, 2, 1]],
[[60000078, 2, 1]],
[[90000047, 2, 1]],
],
},
{
name: "【伝導】10代目最強に挑戦",
difficulty: 14,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2998179,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[50000100, 2, 0]],
[[90000047, 2, 0]],
[[90000057, 2, 0]],
],
},
{
name: "あなたのjubeatはどこから",
difficulty: 15,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2900000,
is_hard: true,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[10000065, 0, 0], [10000065, 1, 0], [10000065, 2, 0]],
[[30000048, 0, 0], [30000048, 1, 0], [30000048, 2, 0]],
[[90000047, 0, 0], [90000047, 1, 0], [90000047, 2, 0]],
],
},
{
name: "【皆伝】甘味なのに甘くない",
difficulty: 15,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2850000,
is_hard: true,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[90000010, 2, 1]],
[[80000101, 2, 1]],
[[50000102, 2, 1]],
],
},
{
name: "【伝導】真の青が魅せた空",
difficulty: 15,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_SCORE,
score: 970000,
is_hard: true,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[50000332, 2, 0]],
[[70000098, 2, 0]],
[[90001005, 2, 1]],
],
},
{
name: "豪華絢爛高揚絶頂",
difficulty: 16,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2960000,
is_hard: true,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[10000065, 2, 1]],
[[50000323, 2, 1]],
[[50000208, 2, 1]],
],
},
{
name: "絢爛豪華激情無常",
difficulty: 16,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2960000,
is_hard: true,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[60000010, 2, 1]],
[[70000110, 2, 1]],
[[90000047, 2, 1]],
],
},
{
name: "【指神】王の降臨",
difficulty: 16,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2980000,
is_hard: true,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[70000094, 2, 1]],
[[80000088, 2, 1]],
[[70000110, 2, 1]],
],
},
{
name: "【伝導】1116全てを超越した日",
difficulty: 16,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2975000,
is_hard: true,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[50000208, 2, 0]],
[[80000050, 2, 0]],
[[90000057, 2, 1]],
],
},
{
name: "My Top9 Fav Songs",
difficulty: 7,
course_type: COURSE_TYPE_PERMANENT,
etime: 0,
clear_type: COURSE_CLEAR_COMBINED_SCORE,
score: 2700000,
is_hard: false,
hazard_type: COURSE_HAZARD_NONE,
tune_list: [
[[50000049, 2, 1], [50000101, 2, 1], [80000136, 2, 1]],
[[80000084, 2, 1], [50000071, 2, 1], [50000084, 2, 1]],
[[60000009, 2, 1], [50000024, 2, 1], [90000173, 2, 1]],
],
},
];

View File

@ -0,0 +1,141 @@
import {emoList, shopList, FestoCourse, courseCategories} from "../static/data"
/*
if pos_index is not (1230 ~ 1236 or 1204 ~ 1205) and pos_index > 1200:
then all festo songs
*/
var pick_up_array = new Array(64).fill(-1);
for(var i=0; i<=36; i++){
pick_up_array[i] = 0;
}
pick_up_array[37] = -3211264;
pick_up_array[38] = -2080769;
module.exports = () => ({
info: {
white_music_list: K.ARRAY("s32", new Array(64).fill(-1)),
white_marker_list: K.ARRAY("s32", new Array(16).fill(-1)),
white_theme_list: K.ARRAY("s32", new Array(16).fill(-1)),
open_music_list: K.ARRAY("s32", new Array(64).fill(-1)),
add_default_music_list: K.ARRAY("s32", new Array(64).fill(-1)),
hot_music_list: K.ARRAY("s32", pick_up_array),
expert_option: {
is_available: K.ITEM("bool", true),
},
konami_logo_50th: {
is_available: K.ITEM("bool", true),
},
all_music_matching: {
is_available: K.ITEM("bool", false),
},
tsumtsum: {
is_available: K.ITEM("bool", false),
},
nagatanien: {
is_available: K.ITEM("bool", false),
},
digdig: {
stage_list: {
stage: [
K.ATTR({ number: "1" }, { state: K.ITEM("u8", 1) }),
K.ATTR({ number: "2" }, { state: K.ITEM("u8", 1) }),
K.ATTR({ number: "3" }, { state: K.ITEM("u8", 1) }),
K.ATTR({ number: "4" }, { state: K.ITEM("u8", 1) }),
K.ATTR({ number: "5" }, { state: K.ITEM("u8", 1) }),
K.ATTR({ number: "6" }, { state: K.ITEM("u8", 1) }),
K.ATTR({ number: "7" }, { state: K.ITEM("u8", 1) }),
],
},
},
department: {
shop_list: {
shop: shopList.map((shop, i) =>
K.ATTR(
{ id: String(i + 1) },
{
tex_id: K.ITEM("s32", shop.tex_id),
type: K.ITEM("s8", shop.type),
emo_id: K.ITEM("s32", shop.emo_id),
priority: K.ITEM("s32", shop.priority),
etime: K.ITEM("u64", BigInt(0)),
item_list: { item: [] },
}
)
),
},
},
course_list: {
course: FestoCourse.map((course, i) =>
K.ATTR(
{
release_code: "2022052400",
version_id: "0",
id: String(i + 1),
course_type: String(course.course_type),
},
{
difficulty: K.ITEM("s32", course.difficulty),
etime: K.ITEM("u64", BigInt(course.etime)),
name: K.ITEM("str", course.name),
tune_list: {
tune: course.tune_list.map((tune, i) =>
K.ATTR(
{ no: String(i + 1) },
{
seq_list: {
seq: tune.map((seq) => ({
music_id: K.ITEM("s32", seq[0]),
difficulty: K.ITEM("s32", seq[1]),
is_secret: K.ITEM("bool", seq[2]),
})),
},
}
)
),
},
clear: K.ATTR({type:String(course.clear_type)},{
ex_option:{
is_hard: K.ITEM("bool", course.is_hard),
hazard_type: K.ITEM("s32", course.hazard_type),
},
score: K.ITEM("s32", course.score),
reward_list:[],
})
}
)
),
category_list: {
category: courseCategories.map((categorie, i) =>
K.ATTR(
{ id: String(i + 1)},
{
is_secret: K.ITEM("bool", false),
level_min: K.ITEM("s32", categorie[0]),
level_max: K.ITEM("s32", categorie[1]),
}
)
)
},
},
emo_list: {
emo: emoList.map((emo, i) =>
K.ATTR(
{ id: String(i + 1) },
{
tex_id: K.ITEM("s32", emo.tex_id),
is_exchange: K.ITEM("bool", emo.is_exchange),
}
)
),
},
},
});

View File

@ -1,55 +0,0 @@
gametop
data
player
session_id(__type="u32") 1
jid(__type="u32") #{profile.jid}
name(__type="str") #{profile.name}
info
online_cnt(__type="s32") #{profile.ripples ? (profile.ripples.info ? profile.ripples.info.onlineCount : 0) : 0}
multi_cnt(__type="s32") #{profile.ripples ? (profile.ripples.info ? profile.ripples.info.multiCount : 0) : 0}
match_cnt(__type="s32") #{profile.ripples ? (profile.ripples.info ? profile.ripples.info.matchCount : 0) : 0}
beat_cnt(__type="s32") #{profile.ripples ? (profile.ripples.info ? profile.ripples.info.beatCount : 0) : 0}
save_cnt(__type="s32") #{profile.ripples ? (profile.ripples.info ? profile.ripples.info.saveCount : 0) : 0}
saved_cnt(__type="s32") #{profile.ripples ? (profile.ripples.info ? profile.ripples.info.savedCount : 0) : 0}
grade(__type="u8") #{profile.ripples ? (profile.ripples.info ? profile.ripples.info.grade : 0) : 0}
grade_point(__type="s32") #{profile.ripples ? (profile.ripples.info ? profile.ripples.info.gradePoint : 0) : 0}
item
secret_list(__type="u32" __count="2") -1 -1
marker_list(__type="u32") -1
theme_list(__type="u8") -1
title_list(__type="u32" __count="20") -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
new
secret_list(__type="u32" __count="2") 0 0
marker_list(__type="u32") 0
theme_list(__type="u8") 0
title_list(__type="u32" __count="20") 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
bm2dx(__type="u8") 0
last
mode(__type="u8") #{profile.ripples ? (profile.ripples.last ? profile.ripples.last.mode : 0) : 0}
music_id(__type="u32") #{profile.ripples ? (profile.ripples.last ? profile.ripples.last.musicId : 0) : 0}
seq_id(__type="u8") #{profile.ripples ? (profile.ripples.last ? profile.ripples.last.seqId : 0) : 0}
marker(__type="u8") #{profile.ripples ? (profile.ripples.last ? profile.ripples.last.marker : 0) : 0}
title(__type="s16") #{profile.ripples ? (profile.ripples.last ? profile.ripples.last.title : 0) : 0}
theme(__type="u8") #{profile.ripples ? (profile.ripples.last ? profile.ripples.last.theme : 0) : 0}
sort(__type="u8") #{profile.ripples ? (profile.ripples.last ? profile.ripples.last.sort : 0) : 0}
filter(__type="u32") #{profile.ripples ? (profile.ripples.last ? profile.ripples.last.filter : 0) : 0}
rank_sort(__type="u8") #{profile.ripples ? (profile.ripples.last ? profile.ripples.last.rankSort : 0) : 0}
combo_disp(__type="u8") #{profile.ripples ? (profile.ripples.last ? profile.ripples.last.comboDisp : 0) : 0}
playdata
each v, k in scores
musicdata(music_id=k)
score(__type="s32" __count="3") #{(v[0].score || 0) + " " + (v[1].score || 0) + " " + (v[2].score || 0)}
clear(__type="u8" __count="3") #{(v[0].clearFlag || 0) + " " + (v[1].clearFlag || 0) + " " + (v[2].clearFlag || 0)}
bar(__type="u8" __count="30" seq="0") #{v[0].mbar ? v[0].mbar.join(" ") : new Array(30).fill(0).join(" ")}
bar(__type="u8" __count="30" seq="1") #{v[1].mbar ? v[1].mbar.join(" ") : new Array(30).fill(0).join(" ")}
bar(__type="u8" __count="30" seq="2") #{v[2].mbar ? v[2].mbar.join(" ") : new Array(30).fill(0).join(" ")}
today_music
music_id(__type="u32") 0
rate(__type="float") 1.0

View File

@ -0,0 +1,441 @@
import Profile from "../models/profile";
import {Course} from "../models/course";
import {emoList, shopList, FestoCourse, courseCategories, COURSE_STATUS} from "../static/data"
module.exports = async (data: Profile) => ({
info: {
tune_cnt: K.ITEM("s32", data?.tuneCount || 0),
save_cnt: K.ITEM("s32", data?.saveCount || 0),
saved_cnt: K.ITEM("s32", data?.savedCount || 0),
fc_cnt: K.ITEM("s32", data?.fcCount || 0),
ex_cnt: K.ITEM("s32", data?.exCount || 0),
clear_cnt: K.ITEM("s32", data?.clearCount || 0),
match_cnt: K.ITEM("s32", data?.matchCount || 0),
beat_cnt: K.ITEM("s32", 0),
mynews_cnt: K.ITEM("s32", 0),
mtg_entry_cnt: K.ITEM("s32", 0),
mtg_hold_cnt: K.ITEM("s32", 0),
mtg_result: K.ITEM("u8", 0),
bonus_tune_points: K.ITEM("s32", data?.bonusPoints || 0),
is_bonus_tune_played: K.ITEM("bool", data?.isBonusPlayed || false),
last_play_time: K.ITEM("s64", data?.lastPlayTime || 0),
},
last: {
play_time: K.ITEM("s64", data?.lastPlayTime || 0),
shopname: K.ITEM("str", data.lastShopname),
areaname: K.ITEM("str", data.lastAreaname),
music_id: K.ITEM("s32", data.musicId || 0),
seq_id: K.ITEM("s8", data.seqId || 0),
seq_edit_id: K.ITEM("str", data.seqEditId || ""),
sort: K.ITEM("s8", data?.sort || 0),
category: K.ITEM("s8", data?.category || 0),
expert_option: K.ITEM("s8", data?.expertOption || 0),
dig_select: K.ITEM("s32", 0),
settings: {
marker: K.ITEM("s8", data?.marker || 0),
theme: K.ITEM("s8", data?.theme || 0),
title: K.ITEM("s16", data?.title || 0),
parts: K.ITEM("s16", data?.parts || 0),
rank_sort: K.ITEM("s8", data?.rankSort || 0),
combo_disp: K.ITEM("s8", data?.comboDisp || 0),
emblem: K.ARRAY("s16", data?.emblem || [0, 0, 0, 0, 0]),
matching: K.ITEM("s8", data?.matching || 0),
hard: K.ITEM("s8", data?.hard || 0),
hazard: K.ITEM("s8", data?.hazard || 0),
},
},
item: {
music_list: K.ARRAY("s32", new Array(64).fill(-1)),
secret_list: K.ARRAY("s32", new Array(64).fill(-1)),
theme_list: K.ARRAY("s32", new Array(16).fill(-1)),
marker_list: K.ARRAY("s32", new Array(16).fill(-1)),
title_list: K.ARRAY("s32", new Array(160).fill(-1)),
parts_list: K.ARRAY("s32", data?.partsList || new Array(160).fill(0)),
emblem_list: K.ARRAY("s32", new Array(96).fill(-1)),
commu_list: K.ARRAY("s32", data?.commuList || new Array(16).fill(0)),
new: {
secret_list: K.ARRAY("s32", new Array(64).fill(0)),
theme_list: K.ARRAY("s32", new Array(16).fill(0)),
marker_list: K.ARRAY("s32", new Array(16).fill(0)),
},
},
rivallist: {
rival: [].map((rival) => ({
jid: K.ITEM("s32", rival.jubeatId),
name: K.ITEM("str", rival.name),
career: {
level: K.ITEM("s16", 0),
},
})),
},
lab_edit_seq: K.ATTR({ count: "0" }, { seq: [] }),
fc_challenge: {
today: {
music_id: K.ITEM("s32", -1),
state: K.ITEM("u8", 0),
},
whim: {
music_id: K.ITEM("s32", -1),
state: K.ITEM("u8", 0),
},
},
official_news: {
news_list: { news: [] },
},
news: {
checked: K.ITEM("s16", 0),
checked_flag: K.ITEM("u32", 0),
},
history: K.ATTR({ count: "0" }, { tune: [] }),
free_first_play: {
is_available: K.ITEM("bool", data?.isFirstplay || false),
},
event_info: { event: [] },
jbox: {
point: K.ITEM("s32", 0),
emblem: {
normal: { index: K.ITEM("s16", 2) },
premium: { index: K.ITEM("s16", 1) },
},
},
new_music: {},
navi: {
flag: K.ITEM("u64", BigInt(data?.navi || 0)),
},
gift_list: {},
question_list: {},
team_battle: {},
server: {},
course_list: {
course: await (async () =>{
let courseData = await DB.Find<Course>(data.__refid, { collection: "course" });
let courseStatus = {};
courseData.forEach(course =>{
courseStatus[course.courseId] |= (course.seen ? COURSE_STATUS.SEEN : 0);
courseStatus[course.courseId] |= (course.played ? COURSE_STATUS.PLAYED : 0);
courseStatus[course.courseId] |= (course.cleared ? COURSE_STATUS.CLEARED : 0);
});
return FestoCourse.map((course, i) =>
K.ATTR({ id: String(i + 1) }, { status: K.ITEM("s8", courseStatus[i+1] || 0) })
);
})()
},
category_list: {
category: courseCategories.map((categorie, i) =>
K.ATTR(
{ id: String(i + 1)},
{
is_display: K.ITEM("bool", true),
}
)
)
},
fill_in_category: {
no_gray_flag_list: K.ARRAY("s32", [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
]),
all_yellow_flag_list: K.ARRAY("s32", [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
]),
full_combo_flag_list: K.ARRAY("s32", [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
]),
excellent_flag_list: K.ARRAY("s32", [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
]),
normal: {
no_gray_flag_list: K.ARRAY("s32", [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
]),
all_yellow_flag_list: K.ARRAY("s32", [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
]),
full_combo_flag_list: K.ARRAY("s32", [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
]),
excellent_flag_list: K.ARRAY("s32", [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
]),
},
hard: {
no_gray_flag_list: K.ARRAY("s32", [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
]),
all_yellow_flag_list: K.ARRAY("s32", [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
]),
full_combo_flag_list: K.ARRAY("s32", [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
]),
excellent_flag_list: K.ARRAY("s32", [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
]),
},
},
emo_list: {
emo: emoList.map((emo, i) => {
return K.ATTR({ id: String(i + 1) }, { num: K.ITEM("s32", 0) });
}),
},
eamuse_gift_list: { gift: [] },
department: {
shop_list: { shop: [] },
},
clan_course_list: {},
team: K.ATTR(
{ id: "0" },
{
section: K.ITEM("s32", 0),
street: K.ITEM("s32", 0),
house_number_1: K.ITEM("s32", 0),
house_number_2: K.ITEM("s32", 0),
move: K.ATTR({
id: "1",
section: "1",
street: "1",
house_number_1: "1",
house_number_2: "1",
}),
}
),
daily_bonus_list: {},
ticket_list: {},
digdig: {
flag: K.ITEM("u64", BigInt(0)),
main: {
stage: K.ATTR(
{ number: "0" },
{
point: K.ITEM("s32", 0),
param: K.ITEM("s32", 0),
}
),
},
eternal: {
ratio: K.ITEM("s32", 0),
used_point: K.ITEM("s64", BigInt(0)),
point: K.ITEM("s64", BigInt(0)),
cube: {
state: K.ITEM("s8", 0),
item: [],
},
norma: {
till_time: K.ITEM("s64", BigInt(0)),
kind: K.ITEM("s32", 0),
value: K.ITEM("s32", 0),
param: K.ITEM("s32", 0),
},
old: {
need_point: K.ITEM("s32", 0),
point: K.ITEM("s32", 0),
excavated_point: K.ITEM("s32", 0),
excavated: K.ITEM("s32", 0),
param: K.ITEM("s32", 0),
music_list: {},
},
},
},
unlock: {},
generic_dig: {},
});

View File

@ -1,6 +0,0 @@
export function getVersion({ model }: EamuseInfo): number {
if (model.startsWith('H44')) return 1;
if (model.startsWith('I44')) return 2;
return 0;
}