Merge pull request #26 from Kirito3481/jubeat

Matching Support (Experimental)
This commit is contained in:
Freddie Wang
2021-05-25 12:05:20 +08:00
committed by GitHub
14 changed files with 907 additions and 464 deletions
+21 -1
View File
@@ -1,6 +1,6 @@
# Jubeat # Jubeat
Plugin Version: **v1.0.0** Plugin Version: **v1.4.1**
### Supported Versions ### Supported Versions
@@ -8,11 +8,31 @@ Plugin Version: **v1.0.0**
- knit - knit
- knit APPEND - knit APPEND
- copious
- copious APPEND
- saucer
### Changelogs ### Changelogs
*** ***
#### 1.4.1
- saucer support
- Change profile structure
#### 1.3.0
- Matching Support (Experimental)
#### 1.2.0
- copious (APPEND) support
#### 1.1.0
- Fix profile structure
#### 1.0.0 #### 1.0.0
- Initial Release - Initial Release
+18 -20
View File
@@ -1,23 +1,27 @@
import {getVersion} from "../utils"; import {getVersion, VersionRange} from '../utils';
export const shopinfo: EPR = (info, data, send) => { export const gameInfo: EPR = (info, data, send) => {
const locId = $(data.shop).content("locationid"); const locId = $(data).content('shop.locationid');
const version = getVersion(info); const version = getVersion(info);
if (version === 0) return send.deny(); if (version === 0) return send.deny();
if (version === 3) return send.object({ return send.object({
data: { data: {
cabid: K.ITEM('u32', 1), ...info.module === 'shopinfo' && {
locationid: K.ITEM('str', locId), cabid: K.ITEM('u32', _.random(1, 10)),
is_send: K.ITEM("u8", 1) locationid: K.ITEM('str', locId),
} ...VersionRange(version, 3, 6) && { is_send: K.ITEM('u8', 1) },
}) },
return send.deny(); ...VersionRange(version, 5, 6) && {
} white_music_list: K.ARRAY('s32', Array(32).fill(-1))
}
}
});
};
export const demodata = { export const demodata = {
getNews: (_, __, send) => send.object({ data: { officialnews: K.ATTR({ count: "0" }) } }), getNews: (_, __, send) => send.object({ data: { officialnews: K.ATTR({ count: '0' }) } }),
getData: (_, data, send) => { getData: (_, data, send) => {
const newsId = $(data).number('officialnews.newsid'); const newsId = $(data).number('officialnews.newsid');
return send.object({ return send.object({
@@ -36,15 +40,9 @@ export const demodata = {
hitchart: { hitchart: {
update: K.ITEM('str', ''), update: K.ITEM('str', ''),
hitchart_lic: K.ATTR({ count: "0" }), hitchart_lic: K.ATTR({ count: '0' }),
hitchart_org: K.ATTR({ count: "0" }), hitchart_org: K.ATTR({ count: '0' }),
} }
} }
}), }),
}; };
export const netlog: EPR = (info, data, send) => {
const errMsg = $(data).str('msg');
console.error(errMsg);
return send.success();
}
+115 -17
View File
@@ -1,49 +1,147 @@
export const check: EPR = (info, data, send) => { import {Room} from '../models/matching';
export const check: EPR = async (info, data, send) => {
const enter = $(data).bool('data.enter'); const enter = $(data).bool('data.enter');
const time = $(data).number('data.time'); const time = $(data).number('data.time');
// enter
// 0 - game is loading
// 1 - music select screen
return send.object({ return send.object({
data: { data: {
entrant_nr: K.ITEM('u32', 1, { time: String(time) }), entrant_nr: K.ITEM('u32', 1, { time: String(time) }),
interval: K.ITEM('s16', 1), interval: K.ITEM('s16', 5),
entry_timeout: K.ITEM('s16', U.GetConfig("matching_entry_timeout")), entry_timeout: K.ITEM('s16', 30),
waitlist: K.ATTR({ count: "0" }) waitlist: K.ATTR({ count: '0' })
} }
}); });
}; };
export const entry: EPR = (info, data, send) => { export const entry: EPR = async (info, data, send) => {
const localMatchingNode = $(data).element("data.local_matching"); const localMatchingNode = $(data).element('data.local_matching');
const connectNode = $(data).element("data.connect"); const connectNode = $(data).element('data.connect');
const musicNode = $(data).element('data.music'); const musicNode = $(data).element('data.music');
const roomId = _.random(1, 999999999999999); const localKey = localMatchingNode.numbers('key');
const connectKey = connectNode.numbers('key');
// TODO Local matching support let matchRoom = await DB.FindOne<Room>({
collection: 'matching_rooms',
musicId: musicNode.number('id'),
seqId: musicNode.number('seq'),
isMatchEnd: false,
isFull: false
});
if (!matchRoom) {
matchRoom = {
collection: 'matching_rooms',
version: $(data).number('data.version'),
roomId: _.random(1, 999999999),
masterKey: connectKey,
masterGlobal: connectNode.str('global'),
masterPrivate: connectNode.str('private'),
localKey,
musicId: musicNode.number('id'),
seqId: musicNode.number('seq'),
members: [
{
cabid: $(data).number('data.cabid'),
addr: connectNode.str('private')
}
],
isFull: false,
isMatchEnd: false
};
await DB.Upsert<Room>({
collection: 'matching_rooms', localKey,
musicId: musicNode.number('id'),
seqId: musicNode.number('seq'),
isMatchEnd: false,
isFull: false
}, matchRoom);
}
return send.object({ return send.object({
data: { data: {
roomid: K.ITEM('s64', BigInt(roomId), { master: "1" }), roomid: K.ITEM('s64', BigInt(matchRoom.roomId), { master: matchRoom.masterKey === connectKey ? '1' : '0' }),
refresh_intr: K.ITEM('s16', 3), ...matchRoom.masterKey === connectKey && {
refresh_intr: K.ITEM('s16', 10),
},
...matchRoom.masterKey !== connectKey && {
connect: {
key: K.ARRAY('u8', matchRoom.masterKey),
global: K.ITEM('str', matchRoom.masterGlobal),
private: K.ITEM('str', matchRoom.masterPrivate),
}
},
music: { music: {
id: K.ITEM("u32", musicNode.number("id")), id: K.ITEM('u32', matchRoom.musicId),
seq: K.ITEM("u8", musicNode.number("seq")), seq: K.ITEM('u8', matchRoom.seqId),
} }
} }
}); });
}; };
export const refresh: EPR = (info, data, send) => { export const refresh: EPR = async (info, data, send) => {
const roomId = Number($(data).bigint('data.roomid'));
const pcbinfos = $(data).elements('data.joined.pcbinfo');
const room = await DB.FindOne<Room>({ collection: 'matching_rooms', roomId });
if (room) {
for (const i of pcbinfos) {
const cabid = i.number('cabid');
const addr = i.str('addr');
for (const i of room.members) {
if (i.addr === addr) continue;
room.members.push({
cabid,
addr
});
}
}
await DB.Update<Room>({ collection: 'matching_rooms', roomId: Number(roomId) }, {
$set: {
members: room.members
}
});
if (room.members.length >= 4) {
await DB.Update<Room>({ collection: 'matching_rooms', roomId: Number(roomId) }, {
$set: {
isFull: true
}
});
}
}
return send.object({ return send.object({
data: { data: {
refresh_intr: K.ITEM('s16', 2), refresh_intr: K.ITEM('s16', 5),
start: K.ITEM('bool', room.isFull)
} }
}); });
}; };
export const report: EPR = (info, data, send) => { export const report: EPR = async (info, data, send) => {
const roomId = $(data).bigint('data.roomid');
await DB.Update<Room>({ collection: 'matching_rooms', roomId: Number(roomId) }, {
$set: {
isMatchEnd: true
}
});
return send.object({ return send.object({
data: { data: {
refresh_intr: K.ITEM('s16', 1), refresh_intr: K.ITEM('s16', 3),
} }
}); });
}; };
+289 -188
View File
@@ -1,6 +1,6 @@
import {getVersion} from "../utils"; import {getVersion, getVersionName, VersionRange} from "../utils";
import Profile from '../models/profile'; import Profile from "../models/profile";
import {Score} from '../models/score'; import {Score} from "../models/score";
export const profile: EPR = async (info, data, send) => { export const profile: EPR = async (info, data, send) => {
let refId = $(data).str("data.player.pass.refid"); let refId = $(data).str("data.player.pass.refid");
@@ -16,155 +16,239 @@ export const profile: EPR = async (info, data, send) => {
if (!profile) { if (!profile) {
if (!name) return send.deny(); if (!name) return send.deny();
const newProfile = new Profile(); const newProfile: Profile = {
newProfile.jubeatId = _.random(1, 99999999); collection: "profile",
newProfile.name = name; jubeatId: _.random(1, 99999999),
newProfile.previous_version = version; name: name,
lastShopname: "NONE",
lastAreaname: "NONE"
};
await DB.Upsert<Profile>(refId, { collection: "profile" }, newProfile); await DB.Upsert<Profile>(refId, { collection: "profile" }, newProfile);
profile = newProfile; profile = newProfile;
} }
let migration = false; return send.object({
if (profile.previous_version < version) { data: {
migration = true; ...VersionRange(version, 5, 5) && require("../templates/gameInfos/saucer.ts")(profile),
profile.name = "";
await DB.Update<Profile>(refId, { collection: "profile" }, { $set: { name: "", previous_version: version } });
}
if (name) { player: {
profile.name = name; name: K.ITEM("str", profile.name),
await DB.Update<Profile>(refId, { collection: "profile" }, { $set: { name } }); jid: K.ITEM("s32", profile.jubeatId),
} refid: K.ITEM("str", profile.__refid),
session_id: K.ITEM("s32", 1),
if (version === 3) { ...version === 3 && require("../templates/profiles/knit.ts")(profile),
if (U.GetConfig("unlock_all_songs")) { ...version === 4 && require("../templates/profiles/copious.ts")(profile),
profile.knit.item = { ...version === 5 && require("../templates/profiles/saucer.ts")(profile),
secretList: [-1, -1], }
themeList: -1,
markerList: [-1, -1],
titleList: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
};
profile.knit.item_new = {
secretList: [0, 0],
themeList: 0,
markerList: [0, 0],
titleList: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
};
} }
return send.pugFile('templates/knit/profile.pug', { refId, migration, ...profile }, { compress: false }); });
}
return send.deny();
}; };
export const saveProfile: EPR = async (info, { data }, send) => { export const saveProfile: EPR = async (info, { data }, send) => {
console.log(U.toXML(data)); console.log(U.toXML({
const player = $(data).element("player"); call: K.ATTR({ model: info.model }, {
[info.module]: K.ATTR({ method: info.method }, { data })
})
}));
const refId = player.str("refid"); const refId = $(data).str("player.refid");
if (!refId) return send.deny(); if (!refId) return send.deny();
const version = getVersion(info); const version = getVersion(info);
if (version === 0) return send.deny(); if (version === 0) return send.deny();
const profile = await DB.FindOne<Profile>(refId, { collection: "profile" }); const profile = await DB.FindOne<Profile>(refId, { collection: "profile" });
if (!profile) return send.deny();
if (version === 3) { let lastMarker = 0;
profile.name = player.str("name"); let lastTheme = 0;
let lastTitle = 0;
let lastParts = 0;
let lastSort = 0;
let lastFilter = 0;
let lastCategory = 0;
let lastMselStat = 0;
profile.last.shopname = player.str("shopname", profile.last.shopname); const result = $(data).element("result");
profile.last.areaname = player.str("areaname", profile.last.areaname);
profile.jubility = player.number("info.jubility", profile.jubility); if (result) {
profile.jubilityYday = player.number("info.jubility_yday", profile.jubilityYday); const tunes = result.elements("tune");
const historys = {};
const historyNode = $(data).elements("player.history.tune");
profile.knit.acvProg = player.number("info.acv_prog", profile.knit.acvProg); if (historyNode) {
profile.knit.acvWool = player.number("info.acv_wool", profile.knit.acvWool); for (const history of historyNode) {
profile.knit.acvRouteProg = player.numbers("info.acv_route_prog", profile.knit.acvRouteProg); historys[history.attr().log_id] = {
profile.knit.acvPoint = player.number("info.acv_point", profile.knit.acvPoint); timestamp: history.bigint("timestamp"),
isHard: history.bool("player.result.is_hard_mode")
profile.tuneCount = player.number("info.tune_cnt", profile.tuneCount); };
profile.saveCount = player.number("info.save_cnt", profile.saveCount);
profile.savedCount = player.number("info.saved_cnt", profile.savedCount);
profile.fullcomboCount = player.number("info.fc_cnt", profile.fullcomboCount);
profile.fullcomboSeqCount = player.number("info.fc_seq_cnt", profile.fullcomboSeqCount);
profile.excellentCount = player.number("info.exc_cnt", profile.excellentCount);
profile.excellentSeqCount = player.number("info.exc_seq_cnt", profile.excellentSeqCount);
profile.matchCount = player.number("info.match_cnt", profile.matchCount);
profile.beatCount = player.number('info.beat_cnt', profile.beatCount);
profile.conciergeSelectedCount = player.number('info.con_sel_cnt', profile.conciergeSelectedCount);
profile.tagCount = player.number('info.tag_cnt', profile.tagCount);
profile.mynewsCount = player.number('info.mynews_cnt', profile.mynewsCount);
if (!U.GetConfig("unlock_all_songs")) {
profile.knit.item.secretList = player.numbers('item.secret_list', profile.knit.item.secretList);
profile.knit.item.themeList = player.number('item.theme_list', profile.knit.item.themeList);
profile.knit.item.markerList = player.numbers('item.marker_list', profile.knit.item.markerList);
profile.knit.item.titleList = player.numbers('item.title_list', profile.knit.item.titleList);
profile.knit.item_new.secretList = player.numbers('item.secret_new', profile.knit.item_new.secretList);
profile.knit.item_new.themeList = player.number('item.theme_new', profile.knit.item_new.themeList);
profile.knit.item_new.markerList = player.numbers('item.marker_new', profile.knit.item_new.markerList);
profile.knit.item_new.titleList = player.numbers('item.title_new', profile.knit.item_new.titleList);
}
profile.last.conciergeSuggestId = player.number('info.con_suggest_id', profile.last.conciergeSuggestId);
profile.last.playTime = BigInt(new Date().getMilliseconds());
// Append
const collabo = player.element("collabo");
if (collabo) {
profile.knit.collabo.success = collabo.bool("success");
profile.knit.collabo.completed = collabo.bool("completed");
}
const result = $(data).element("result");
if (result) {
const tunes = result.elements("tune");
for (const tune of tunes) {
const musicId = tune.number("music", 0);
profile.last.musicId = musicId;
profile.last.seqId = parseInt(tune.attr("player.score").seq) || 0;
profile.last.title = tune.number("title", profile.last.title);
profile.last.theme = tune.number("theme", profile.last.theme);
profile.last.marker = tune.number("marker", profile.last.marker);
profile.last.sort = tune.number("sort", profile.last.sort);
profile.last.filter = tune.number("filter", profile.last.filter);
profile.last.showRank = tune.number("combo_disp", profile.last.showRank);
profile.last.showCombo = tune.number("rank_sort", profile.last.showCombo);
profile.last.mselStat = tune.number("msel_stat", profile.last.mselStat);
const score = tune.number('player.score');
const seq = parseInt(tune.attr('player.score').seq);
const clear = parseInt(tune.attr('player.score').clear);
const combo = parseInt(tune.attr('player.score').combo);
const bestScore = tune.number('player.best_score');
const bestClear = tune.number('player.best_clear');
const playCount = tune.number('player.play_cnt');
const clearCount = tune.number('player.clear_cnt');
const fullcomboCount = tune.number('player.fc_cnt');
const excellentCount = tune.number('player.exc_cnt');
const mbar = tune.numbers('player.mbar');
await updateScore(refId, musicId, seq, score, clear, mbar, {
playCount,
clearCount,
fullcomboCount,
excellentCount
});
} }
} }
await DB.Update<Profile>(refId, { collection: "profile" }, profile); for (const tune of tunes) {
const tuneId = tune.attr().id;
return send.object({ data: { player: { session_id: K.ITEM('s32', 1) } } }); profile.musicId = tune.number("music");
profile.seqId = parseInt(tune.attr("player.score").seq);
lastMarker = tune.number("marker");
lastTheme = tune.number("theme");
lastTitle = tune.number("title");
lastParts = tune.number("parts");
lastSort = tune.number("sort");
lastFilter = tune.number("filter");
lastCategory = tune.number("category");
lastMselStat = tune.number("msel_stat");
profile.rankSort = tune.number("rank_sort");
profile.comboDisp = tune.number("combo_disp");
await updateScore(refId, {
musicId: tune.number("music"),
seq: parseInt(tune.attr("player.score").seq),
score: tune.number("player.score"),
clear: parseInt(tune.attr("player.score").clear),
isHard: historys[tuneId]?.isHard || false,
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.exc_cnt"),
...tune.element("player.mbar") && { mbar: tune.numbers("player.mbar") }
});
}
} }
return send.deny(); profile.lastPlayTime = Number($(data).bigint("player.time_gameend"));
profile.lastShopname = $(data).str("player.shopname");
profile.lastAreaname = $(data).str("player.areaname");
if (version === 3) {
if (!profile.knit) profile.knit = {};
profile.knit.jubility = $(data).number("player.info.jubility");
profile.knit.jubilityYday = $(data).number("player.info.jubility_yday");
profile.knit.acvProg = $(data).number("player.info.acv_prog");
profile.knit.acvPoint = $(data).number("player.info.acv_point");
profile.knit.acvWool = $(data).number("player.info.acv_wool");
profile.knit.acvRouteProg = $(data).numbers("player.info.acv_route_prog");
profile.knit.tuneCount = $(data).number("player.info.tune_cnt");
profile.knit.saveCount = $(data).number("player.info.save_cnt");
profile.knit.savedCount = $(data).number("player.info.saved_cnt");
profile.knit.fcCount = $(data).number("player.info.fc_cnt");
profile.knit.fcSeqCount = $(data).number("player.info.fc_seq_cnt");
profile.knit.exCount = $(data).number("player.info.exc_cnt");
profile.knit.exSeqCount = $(data).number("player.info.exc_seq_cnt");
profile.knit.matchCount = $(data).number("player.info.match_cnt");
profile.knit.conSelCount = $(data).number("player.info.con_sel_cnt");
profile.knit.marker = lastMarker;
profile.knit.theme = lastTheme;
profile.knit.title = lastTitle;
profile.knit.sort = lastSort;
profile.knit.filter = lastFilter;
profile.knit.mselStat = lastMselStat;
profile.knit.conSuggestId = $(data).number("player.info.con_suggest_id");
profile.knit.secretList = $(data).numbers("player.item.secret_list");
profile.knit.themeList = $(data).number("player.item.theme_list");
profile.knit.markerList = $(data).numbers("player.item.marker_list");
profile.knit.titleList = $(data).numbers("player.item.title_list");
profile.knit.secretListNew = $(data).numbers("player.item.secret_new");
profile.knit.themeListNew = $(data).number("player.item.theme_new");
profile.knit.markerListNew = $(data).numbers("player.item.marker_new");
profile.knit.titleListNew = $(data).numbers("player.item.title_new");
}
if (version === 4) {
if (!profile.copious) profile.copious = {};
profile.copious.jubility = $(data).number("player.info.jubility");
profile.copious.jubilityYday = $(data).number("player.info.jubility_yday");
profile.copious.acvState = $(data).number("player.info.acv_state");
profile.copious.acvPoint = $(data).number("player.info.acv_point");
profile.copious.acvOwn = $(data).number("player.info.acv_own");
profile.copious.acvThrow = $(data).numbers("player.info.acv_throw");
profile.copious.tuneCount = $(data).number("player.info.tune_cnt");
profile.copious.saveCount = $(data).number("player.info.save_cnt");
profile.copious.savedCount = $(data).number("player.info.saved_cnt");
profile.copious.fcCount = $(data).number("player.info.fc_cnt");
profile.copious.fcSeqCount = $(data).number("player.info.fc_seq_cnt");
profile.copious.exCount = $(data).number("player.info.exc_cnt");
profile.copious.exSeqCount = $(data).number("player.info.exc_seq_cnt");
profile.copious.matchCount = $(data).number("player.info.match_cnt");
profile.copious.totalBestScore = $(data).number("player.info.total_best_score");
profile.copious.marker = lastMarker;
profile.copious.theme = lastTheme;
profile.copious.title = lastTitle;
profile.copious.parts = lastParts;
profile.copious.sort = lastSort;
profile.copious.category = lastCategory;
profile.copious.mselStat = lastMselStat;
profile.copious.secretList = $(data).numbers("player.item.secret_list");
profile.copious.themeList = $(data).number("player.item.theme_list");
profile.copious.markerList = $(data).numbers("player.item.marker_list");
profile.copious.titleList = $(data).numbers("player.item.title_list");
profile.copious.partsList = $(data).numbers("player.item.parts_list");
profile.copious.secretListNew = $(data).numbers("player.item.secret_new");
profile.copious.themeListNew = $(data).number("player.item.theme_new");
profile.copious.markerListNew = $(data).numbers("player.item.marker_new");
profile.copious.titleListNew = $(data).numbers("player.item.title_new");
}
if (version === 5) {
if (!profile.saucer) profile.saucer = {};
profile.saucer.jubility = $(data).number("player.info.jubility");
profile.saucer.jubilityYday = $(data).number("player.info.jubility_yday");
profile.saucer.tuneCount = $(data).number("player.info.tune_cnt");
profile.saucer.clearCount = $(data).number("player.info.clear_cnt");
profile.saucer.saveCount = $(data).number("player.info.save_cnt");
profile.saucer.savedCount = $(data).number("player.info.saved_cnt");
profile.saucer.fcCount = $(data).number("player.info.fc_cnt");
profile.saucer.exCount = $(data).number("player.info.exc_cnt");
profile.saucer.matchCount = $(data).number("player.info.match_cnt");
profile.saucer.totalBestScore = $(data).number("player.info.total_best_score");
profile.saucer.marker = lastMarker;
profile.saucer.theme = lastTheme;
profile.saucer.title = lastTitle;
profile.saucer.parts = lastParts;
profile.saucer.sort = lastSort;
profile.saucer.category = lastCategory;
profile.saucer.secretList = $(data).numbers("player.item.secret_list");
profile.saucer.themeList = $(data).number("player.item.theme_list");
profile.saucer.markerList = $(data).numbers("player.item.marker_list");
profile.saucer.titleList = $(data).numbers("player.item.title_list");
profile.saucer.partsList = $(data).numbers("player.item.parts_list");
profile.saucer.secretListNew = $(data).numbers("player.item.secret_new");
profile.saucer.themeListNew = $(data).number("player.item.theme_new");
profile.saucer.markerListNew = $(data).numbers("player.item.marker_new");
profile.saucer.titleListNew = $(data).numbers("player.item.title_new");
if (!profile.saucer.bistro) profile.saucer.bistro = {};
profile.saucer.bistro.carry_over = $(data).number("player.bistro.carry_over");
}
try {
await DB.Update<Profile>(refId, { collection: "profile" }, profile);
return send.object({
data: {
player: { session_id: K.ITEM("s32", 1) },
...version === 4 && { collabo: { deller: K.ITEM("s32", 0) } }
}
});
} catch (e) {
console.error(`Profile save failed: ${e.message}`);
return send.deny();
}
}; };
export const loadScore: EPR = async (info, data, send) => { export const loadScore: EPR = async (info, data, send) => {
@@ -178,7 +262,7 @@ export const loadScore: EPR = async (info, data, send) => {
if (version === 0) return send.deny(); if (version === 0) return send.deny();
const scores = await DB.Find<Score>(profile.__refid, { collection: "score" }); const scores = await DB.Find<Score>(profile.__refid, { collection: "score" });
const scoreData: { [musicId: number]: any } = {}; const scoreData: { [musicId: number]: { score: number[], clear: number[], playCnt: number[], clearCnt: number[], fcCnt: number[], exCnt: number[], bar: number[][] } } = {};
for (const score of scores) { for (const score of scores) {
if (!scoreData[score.musicId]) { if (!scoreData[score.musicId]) {
@@ -198,95 +282,112 @@ export const loadScore: EPR = async (info, data, send) => {
data.clearCnt[score.seq] = score.clearCount; data.clearCnt[score.seq] = score.clearCount;
data.fcCnt[score.seq] = score.fullcomboCount; data.fcCnt[score.seq] = score.fullcomboCount;
data.exCnt[score.seq] = score.excellentCount; data.exCnt[score.seq] = score.excellentCount;
data.clear[score.seq] = score.clearType; data.clear[score.seq] = score.clear;
data.score[score.seq] = score.score; data.score[score.seq] = score.score;
data.bar[score.seq] = score.bar; data.bar[score.seq] = score.bar;
} }
if (version === 3) return send.object({ return send.object({
data: { data: {
player: { player: {
playdata: K.ATTR({ count: String(Object.keys(scoreData).length) }, { jid: K.ITEM("s32", jubeatId),
musicdata: (() => {
const musicdata = []; ...version >= 3 && {
Object.entries(scoreData).forEach(([k, v]) => { playdata: K.ATTR({ count: String(Object.keys(scoreData).length) }, {
musicdata.push(K.ATTR({ music_id: String(k) }, { musicdata: Object.keys(scoreData).map(musicId => K.ATTR({ music_id: String(musicId) }, {
play_cnt: K.ARRAY('s32', v.playCnt), score: K.ARRAY("s32", scoreData[musicId].score),
clear_cnt: K.ARRAY('s32', v.clearCnt), clear: K.ARRAY("s8", scoreData[musicId].clear),
fc_cnt: K.ARRAY('s32', v.fcCnt), play_cnt: K.ARRAY("s32", scoreData[musicId].playCnt),
ex_cnt: K.ARRAY('s32', v.exCnt), clear_cnt: K.ARRAY("s32", scoreData[musicId].clearCnt),
clear: K.ARRAY('s8', v.clear), fc_cnt: K.ARRAY("s32", scoreData[musicId].fcCnt),
score: K.ARRAY('s32', v.score), ex_cnt: K.ARRAY("s32", scoreData[musicId].exCnt),
bar: v.bar.map((v, i) => K.ARRAY('u8', v, { seq: String(i) })) bar: scoreData[musicId].bar.map((bar, seq) => K.ARRAY("u8", bar, { seq: String(seq) }))
})); }))
}); })
return musicdata; }
})()
})
} }
} }
}); });
return send.deny();
}; };
const updateScore = async (refId: string, musicId: number, seq: number, score: number, clear: number, mbar: number[], data: any) => { const updateScore = async (refId: string, data: any): Promise<boolean> => {
let raised; 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: 0,
...data.mbar && { bar: data.mbar, },
playCount: data.playCount,
clearCount: data.clearCount,
fullcomboCount: data.fullcomboCount,
excellentCount: data.excellentCount,
isHardMode: data.isHard
}
});
const oldScore = await DB.FindOne<Score>(refId, { collection: "score", musicId, seq }); return true;
} catch (e) {
let scoreData = oldScore; console.error("Score saving failed: ", e.stack);
return false;
if (!oldScore) {
scoreData = new Score();
scoreData.musicId = musicId;
scoreData.seq = seq;
raised = true;
} else {
raised = score > oldScore.score;
score = Math.max(oldScore.score, score);
} }
scoreData.clearType = Math.max(scoreData.clearType, clear);
scoreData.playCount = data.playCount;
scoreData.clearCount = data.clearCount;
scoreData.fullcomboCount = data.fullcomboCount;
scoreData.excellentCount = data.excellentCount;
scoreData.isHardmodeClear = false;
if (mbar && raised) {
scoreData.score = score;
scoreData.bar = mbar;
}
await DB.Upsert(refId, { collection: "score", musicId, seq }, scoreData);
}; };
export const meeting: EPR = (info, data, send) => { export const meeting: EPR = (info, data, send) => {
return send.object({ return send.object({
data: { data: {
meeting: { meeting: {
single: K.ATTR({ count: '0' }), single: K.ATTR({ count: "0" }),
tag: K.ATTR({ count: '0' }), tag: K.ATTR({ count: "0" }),
}, },
reward: { reward: {
total: K.ITEM('s32', 0), total: K.ITEM("s32", 0),
point: K.ITEM('s32', 0) point: K.ITEM("s32", 0)
} }
} }
}); });
}; };
export const getCollabo: EPR = (info, data, send) => send.object({ export const getCollabo: EPR = (info, data, send) => {
data: { const version = getVersion(info);
collabo: { if (version === 0) return send.deny();
played: {
iidx: K.ITEM("s8", 1), if (version === 3) {
popn: K.ITEM("s8", 1), return send.object({
ddr: K.ITEM("s8", 1), data: {
reflec: K.ITEM("s8", 1), collabo: {
gfdm: K.ITEM("s8", 1), played: {
iidx: K.ITEM("s8", 1),
popn: K.ITEM("s8", 1),
ddr: K.ITEM("s8", 1),
reflec: K.ITEM("s8", 1),
gfdm: K.ITEM("s8", 1),
}
}
} }
} });
} }
});
if (version === 4) {
return send.object({
data: {
player: {
collabo: {
reward: K.ITEM("s32", 0),
dellar: K.ITEM("s32", 0),
music_id: K.ITEM("s32", 0),
wonder_state: K.ITEM("u32", 2),
yellow_state: K.ITEM("u32", 2),
}
}
}
});
}
};
+23 -47
View File
@@ -1,60 +1,36 @@
import {demodata, netlog, shopinfo} from "./handlers/common"; import {demodata, gameInfo} from './handlers/common';
import {check, entry, refresh, report} from "./handlers/matching"; import {check, entry, refresh, report} from './handlers/matching';
import {getCollabo, loadScore, meeting, profile, saveProfile} from "./handlers/profile"; import {getCollabo, loadScore, meeting, profile, saveProfile} from './handlers/profile';
export function register() { export function register() {
if (CORE_VERSION_MAJOR <= 1 && CORE_VERSION_MINOR < 31) { 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."); console.error('The current version of Asphyxia Core is not supported. Requires version \'1.31\' or later.');
return; return;
} }
R.GameCode("J44"); R.GameCode('J44');
R.GameCode('K44');
R.GameCode('L44');
R.Config("unlock_all_songs", { R.Route('gametop.regist', profile);
name: "Unlock All Songs", R.Route('gametop.get_info', gameInfo);
desc: "Tired of unlocking songs? Have this!", R.Route('gametop.get_pdata', profile);
type: "boolean", R.Route('gametop.get_mdata', loadScore);
default: false R.Route('gametop.get_meeting', meeting);
}); R.Route('gametop.get_collabo', getCollabo);
R.Config("quick_matching_end", {
name: "Quick Matching End",
desc: "Supported from clan to festo.",
type: "boolean",
default: false
});
R.Config("matching_entry_timeout", {
name: "Online Matching Timeout",
desc: "If online matching songs are too boring, save time! (second)",
type: "integer",
default: 30,
range: [15, 99],
});
R.Route("gametop.regist", profile);
R.Route("gametop.get_pdata", profile);
R.Route("gametop.get_mdata", loadScore);
R.Route("gametop.get_meeting", meeting);
R.Route("gametop.get_collabo", getCollabo);
R.Route('gameend.regist', saveProfile); R.Route('gameend.regist', saveProfile);
R.Route('gameend.log', true); R.Route('gameend.log', true);
R.Route('gameend.set_collabo', true); R.Route('gameend.set_collabo', true);
R.Route("shopinfo.regist", shopinfo); R.Route('shopinfo.regist', gameInfo);
R.Route("netlog.send", netlog); R.Route('demodata.get_news', demodata.getNews);
R.Route("demodata.get_news", demodata.getNews); R.Route('demodata.get_data', demodata.getData);
R.Route("demodata.get_data", demodata.getData); R.Route('demodata.get_hitchart', demodata.getHitchart);
R.Route("demodata.get_hitchart", demodata.getHitchart); R.Route('lobby.check', check);
R.Route("lobby.check", check); R.Route('lobby.entry', entry);
R.Route("lobby.entry", entry); R.Route('lobby.refresh', refresh);
R.Route("lobby.refresh", refresh); R.Route('lobby.report', report);
R.Route("lobby.report", report);
R.Unhandled((info, data, send) => { R.Route('netlog.send', true);
console.log(info.module, info.method); R.Route('logger.report', true);
console.log(U.toXML(data));
return send.deny();
});
} }
+18
View File
@@ -0,0 +1,18 @@
export interface Room {
collection: 'matching_rooms';
version: number;
roomId: number;
masterKey: number[];
masterGlobal: string;
masterPrivate: string;
localKey: number[];
musicId: number;
seqId: number;
members: {
cabid: number;
addr: string;
}[];
isFull: boolean;
isMatchEnd: boolean;
}
+114 -92
View File
@@ -1,101 +1,123 @@
export default class Profile { export default interface Profile {
collection: "profile" = "profile"; collection: "profile";
jubeatId: number = _.random(1, 99999999); jubeatId: number;
name: string = "JUBEAT"; name: string;
previous_version = 0; lastPlayTime?: number;
lastShopname: string;
lastAreaname: string;
jubility: number = 0; musicId?: number;
jubilityYday: number = 0; seqId?: number;
tuneCount: number = 0; rankSort?: number;
saveCount: number = 0; comboDisp?: number;
savedCount: number = 0;
fullcomboCount: number = 0;
fullcomboSeqCount: number = 0;
excellentCount: number = 0;
excellentSeqCount: number = 0;
matchCount: number = 0;
beatCount: number = 0;
tagCount: number = 0;
mynewsCount: number = 0;
conciergeSelectedCount: number = 0;
last: { knit?: {
shopname: string; jubility?: number;
areaname: string; jubilityYday?: number;
playTime: bigint; acvProg?: number;
title: number; acvWool?: number;
theme: number; acvRouteProg?: number[];
marker: number; acvPoint?: number;
showRank: number; tuneCount?: number;
showCombo: number; saveCount?: number;
musicId: number; savedCount?: number;
seqId: number; fcCount?: number;
seqEditId: string; fcSeqCount?: number;
sort: number; exCount?: number;
filter: number; exSeqCount?: number;
mselStat: number; matchCount?: number;
conciergeSuggestId: number; conSelCount?: number;
} = {
shopname: "NONE", marker?: number;
areaname: "NONE", theme?: number;
playTime: BigInt(0), title?: number;
title: 0, sort?: number;
theme: 0, filter?: number;
marker: 0, mselStat?: number;
showRank: 1, conSuggestId?: number;
showCombo: 1,
musicId: 0, secretList?: number[];
seqId: 0, themeList?: number;
seqEditId: "", markerList?: number[];
sort: 0, titleList?: number[];
filter: 0,
mselStat: 0, secretListNew?: number[];
conciergeSuggestId: 0 themeListNew?: number;
markerListNew?: number[];
titleListNew?: number[];
}; };
knit: { copious?: {
acvProg: number; jubility?: number;
acvWool: number; jubilityYday?: number;
acvRouteProg: number[]; acvPoint?: number;
acvPoint: number; acvState?: number;
item: { acvThrow?: number[];
secretList: number[], acvOwn?: number;
themeList: number, tuneCount?: number;
markerList: number[], saveCount?: number;
titleList: number[] savedCount?: number;
}, fcCount?: number;
item_new: { fcSeqCount?: number;
secretList: number[], exCount?: number;
themeList: number, exSeqCount?: number;
markerList: number[], matchCount?: number;
titleList: number[] totalBestScore?: number;
},
collabo: { marker?: number;
success: boolean; theme?: number;
completed: boolean; title?: number;
} parts?: number;
} = { sort?: number;
acvProg: 0, category?: number;
acvWool: 0, mselStat?: number;
acvRouteProg: [0, 0, 0, 0],
acvPoint: 0, secretList?: number[];
item: { themeList?: number;
secretList: [0, 0], markerList?: number[];
themeList: 0, titleList?: number[];
markerList: [0, 0], partsList?: number[];
titleList: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
}, secretListNew?: number[];
item_new: { themeListNew?: number;
secretList: [0, 0], markerListNew?: number[];
themeList: 0, titleListNew?: number[];
markerList: [0, 0], };
titleList: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
}, saucer?: {
collabo: { jubility?: number;
success: false, jubilityYday?: number;
completed: false tuneCount?: number;
clearCount?: number;
saveCount?: number;
savedCount?: number;
fcCount?: number;
exCount?: number;
matchCount?: number;
totalBestScore?: number;
marker?: number;
theme?: number;
title?: number;
parts?: number;
sort?: number;
category?: number;
secretList?: number[];
themeList?: number;
markerList?: number[];
titleList?: number[];
partsList?: number[];
secretListNew?: number[];
themeListNew?: number;
markerListNew?: number[];
titleListNew?: number[];
bistro?: {
carry_over?: number;
} }
}; };
} }
+10 -9
View File
@@ -1,14 +1,15 @@
export class Score { export interface Score {
collection: "score" = "score"; collection: "score";
musicId: number; musicId: number;
seq: number; seq: number;
score: number = 0; score: number;
clearType: number = 0; clear: number;
playCount: number = 0; musicRate: number;
clearCount: number = 0;
fullcomboCount: number = 0;
excellentCount: number = 0;
isHardmodeClear: boolean;
bar: number[]; bar: number[];
playCount: number;
clearCount: number;
fullcomboCount: number;
excellentCount: number;
isHardMode: boolean;
} }
@@ -0,0 +1,27 @@
module.exports = () => ({
termver: K.ITEM("u8", 0),
season_etime: K.ITEM("u32", 0),
bistro_last_music_id: K.ITEM("s32", 0),
white_music_list: K.ARRAY("s32", Array(32).fill(-1)),
old_music_list: K.ARRAY("s32", Array(32).fill(0)),
open_music_list: K.ARRAY("s32", Array(32).fill(0)),
collabo_info: {
collabo: [
K.ATTR({ type: "1" }, { state: K.ITEM("u8", 0) }),
K.ATTR({ type: "2" }, { state: K.ITEM("u8", 0) }),
K.ATTR({ type: "3" }, { state: K.ITEM("u8", 0) }),
K.ATTR({ type: "4" }, { state: K.ITEM("u8", 0) }),
K.ATTR({ type: "5" }, { state: K.ITEM("u8", 0) }),
K.ATTR({ type: "8" }, { state: K.ITEM("u8", 0) })
],
run_run_marathon: {
is_report_end: K.ITEM("bool", true)
},
policy_break: {
is_report_end: K.ITEM("bool", true)
}
}
});
@@ -1,89 +0,0 @@
gametop
data
player
name(__type="str") #{name}
jid(__type="s32") #{jubeatId}
refid(__type="str") #{refId}
session_id(__type="s32") 1
info
inherit(__type="bool") #{migration ? 1 : 0}
jubility(__type="s16") #{jubility}
jubility_yday(__type="s16") #{jubilityYday}
acv_prog(__type="s8") #{knit.acvProg}
acv_wool(__type="s8") #{knit.acvWool}
acv_route_prog(__type="s8" __count="4") #{knit.acvRouteProg.join(" ")}
acv_point(__type="s32") #{knit.acvPoint}
tune_cnt(__type="s32") #{tuneCount}
save_cnt(__type="s32") #{saveCount}
saved_cnt(__type="s32") #{savedCount}
fc_cnt(__type="s32") #{fullcomboCount}
ex_cnt(__type="s32") #{excellentCount}
match_cnt(__type="s32") #{matchCount}
beat_cnt(__type="s32") #{beatCount}
mynews_cnt(__type="s32") #{mynewsCount}
con_sel_cnt(__type="s32") #{conciergeSelectedCount}
tag_cnt(__type="s32") #{tagCount}
mtg_entry_cnt(__type="s32") 0
tag_entry_cnt(__type="s32") 0
mtg_hold_cnt(__type="s32") 0
tag_hold_cnt(__type="s32") 0
mtg_result(__type="u8") 0
last
play_time(__type="s64") #{last.playTime || 0}
shopname(__type="str") #{last.shopname}
areaname(__type="str") #{last.areaname}
title(__type="s16") #{last.title}
theme(__type="s8") #{last.theme}
marker(__type="s8") #{last.marker}
rank_sort(__type="s8") #{last.showRank}
combo_disp(__type="s8") #{last.showCombo}
music_id(__type="s32") #{last.musicId}
seq_id(__type="s8") #{last.seqId}
sort(__type="s8") #{last.sort}
filter(__type="s32") #{last.filter}
msel_stat(__type="s8") #{last.mselStat}
con_suggest_id(__type="s8") #{last.conciergeSuggestId}
item
secret_list(__type="s32" __count="2") #{knit.item.secretList.join(" ")}
theme_list(__type="s16") #{knit.item.themeList}
marker_list(__type="s32" __count="2") #{knit.item.markerList.join(" ")}
title_list(__type="s32" __count="24") #{knit.item.titleList.join(" ")}
new
secret_list(__type="s32" __count="2") #{knit.item_new.secretList.join(" ")}
theme_list(__type="s16") #{knit.item_new.themeList}
marker_list(__type="s32" __count="2") #{knit.item_new.markerList.join(" ")}
title_list(__type="s32" __count="24") #{knit.item_new.titleList.join(" ")}
today_music
music_id(__type="s32") 0
news
checked(__type="s16") 0
friendlist(count="0")
lucky_music
music_id(__type="s32") 0
mylist(count="0")
group
group_id(__type="s32") 0
bingo
reward
total(__type="s32") 0
point(__type="s32") 0
collabo
success(__type="bool") #{knit.collabo.success ? 1 : 0}
completed(__type="bool") #{knit.collabo.completed ? 1 : 0}
history
play_hist(count="0")
match_hist(count="0")
@@ -0,0 +1,71 @@
import Profile from "../../models/profile";
module.exports = (data: Profile) => ({
info: {
jubility: K.ITEM("s16", data.copious?.jubility || 0),
jubility_yday: K.ITEM("s16", data.copious?.jubilityYday || 0),
acv_point: K.ITEM("s32", data.copious?.acvPoint || 0),
acv_state: K.ITEM("s8", data.copious?.acvState || 0),
acv_throw: K.ARRAY("s32", data.copious?.acvThrow || [0, 0, 0]),
acv_own: K.ITEM("s32", data.copious?.acvOwn || 0),
tune_cnt: K.ITEM("s32", data.copious?.tuneCount || 0),
save_cnt: K.ITEM("s32", data.copious?.saveCount || 0),
saved_cnt: K.ITEM("s32", data.copious?.savedCount || 0),
fc_cnt: K.ITEM("s32", data.copious?.fcCount || 0),
ex_cnt: K.ITEM("s32", data.copious?.exCount || 0),
match_cnt: K.ITEM("s32", data.copious?.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)
},
last: {
play_time: K.ITEM("s64", BigInt(0)),
shopname: K.ITEM("str", data.lastShopname),
areaname: K.ITEM("str", data.lastAreaname),
title: K.ITEM("s16", data.copious?.title || 0),
parts: K.ITEM("s16", data.copious?.parts || 0),
theme: K.ITEM("s8", data.copious?.theme || 0),
marker: K.ITEM("s8", data.copious?.marker || 0),
rank_sort: K.ITEM("s8", data.rankSort || 1),
combo_disp: K.ITEM("s8", data.comboDisp || 1),
music_id: K.ITEM("s32", data.musicId || 0),
seq_id: K.ITEM("s8", data.seqId || 0),
sort: K.ITEM("s8", data.copious?.sort || 0),
category: K.ITEM("s8", data.copious?.category || 0),
msel_stat: K.ITEM("s8", data.copious?.mselStat || 0)
},
item: {
secret_list: K.ARRAY("s32", data.copious?.secretList || Array(12).fill(0)),
theme_list: K.ITEM("s16", data.copious?.themeList || 0),
marker_list: K.ARRAY("s32", data.copious?.markerList || [0, 0]),
title_list: K.ARRAY("s32", data.copious?.titleList || Array(32).fill(0)),
parts_list: K.ARRAY("s32", data.copious?.partsList || Array(96).fill(0)),
new: {
secret_list: K.ARRAY("s32", data.copious?.secretListNew || Array(12).fill(0)),
theme_list: K.ITEM("s16", data.copious?.themeListNew || 0),
marker_list: K.ARRAY("s32", data.copious?.markerListNew || [0, 0]),
title_list: K.ARRAY("s32", data.copious?.titleListNew || Array(32).fill(0))
}
},
challenge: {
today: {
music_id: K.ITEM("s32", 0)
},
onlynow: {
magic_no: K.ITEM("s32", 0),
cycle: K.ITEM("s16", 0)
}
},
news: {
checked: K.ITEM("s16", 0)
},
rivallist: K.ATTR({ count: "0" })
});
@@ -0,0 +1,75 @@
import Profile from "../../models/profile";
module.exports = (data: Profile) => ({
info: {
jubility: K.ITEM("s16", data.knit?.jubility || 0),
jubility_yday: K.ITEM("s16", data.knit?.jubilityYday || 0),
acv_prog: K.ITEM("s8", data.knit?.acvProg || 0),
acv_wool: K.ITEM("s8", data.knit?.acvWool || 0),
acv_route_prog: K.ARRAY("s8", data.knit?.acvRouteProg || [0, 0, 0, 0]),
acv_point: K.ITEM("s32", data.knit?.acvPoint || 0),
tune_cnt: K.ITEM("s32", data.knit?.tuneCount || 0),
save_cnt: K.ITEM("s32", data.knit?.saveCount || 0),
saved_cnt: K.ITEM("s32", data.knit?.savedCount || 0),
fc_cnt: K.ITEM("s32", data.knit?.fcCount || 0),
ex_cnt: K.ITEM("s32", data.knit?.exCount || 0),
match_cnt: K.ITEM("s32", data.knit?.matchCount || 0),
beat_cnt: K.ITEM("s32", 0),
mynews_cnt: K.ITEM("s32", 0),
con_sel_cnt: K.ITEM("s32", data.knit?.conSelCount || 0),
tag_cnt: K.ITEM("s32", 0),
mtg_entry_cnt: K.ITEM("s32", 0),
tag_entry_cnt: K.ITEM("s32", 0),
mtg_hold_cnt: K.ITEM("s32", 0),
tag_hold_cnt: K.ITEM("s32", 0),
mtg_result: K.ITEM("u8", 0)
},
last: {
play_time: K.ITEM("s64", BigInt(0)),
shopname: K.ITEM("str", data.lastShopname),
areaname: K.ITEM("str", data.lastAreaname),
title: K.ITEM("s16", data.knit?.title || 0),
theme: K.ITEM("s8", data.knit?.theme || 0),
marker: K.ITEM("s8", data.knit?.marker || 0),
rank_sort: K.ITEM("s8", data.rankSort || 1),
combo_disp: K.ITEM("s8", data.comboDisp || 1),
music_id: K.ITEM("s32", data.musicId || 0),
seq_id: K.ITEM("s8", data.seqId || 0),
sort: K.ITEM("s8", data.knit?.sort || 0),
filter: K.ITEM("s32", data.knit?.filter || 0),
msel_stat: K.ITEM("s8", data.knit?.mselStat || 0),
con_suggest_id: K.ITEM("s8", data.knit?.conSuggestId || 0)
},
item: {
secret_list: K.ARRAY("s32", data.knit?.secretList || [0, 0]),
theme_list: K.ITEM("s16", data.knit?.themeList || 0),
marker_list: K.ARRAY("s32", data.knit?.markerList || [0, 0]),
title_list: K.ARRAY("s32", data.knit?.titleList || Array(24).fill(0)),
new: {
secret_list: K.ARRAY("s32", data.knit?.secretListNew || [0, 0]),
theme_list: K.ITEM("s16", data.knit?.themeListNew || 0),
marker_list: K.ARRAY("s32", data.knit?.markerListNew || [0, 0]),
title_list: K.ARRAY("s32", data.knit?.titleListNew || Array(24).fill(0))
}
},
today_music: {
music_id: K.ITEM("s32", 0)
},
news: {
checked: K.ITEM("s16", 0)
},
friendlist: K.ATTR({ count: "0" }),
mylist: K.ATTR({ count: "0" }),
collabo: {
success: K.ITEM("bool", true),
completed: K.ITEM("bool", true)
}
});
@@ -0,0 +1,101 @@
import Profile from "../../models/profile";
module.exports = (data: Profile) => ({
info: {
jubility: K.ITEM("s16", data.saucer?.jubility || 0),
jubility_yday: K.ITEM("s16", data.saucer?.jubilityYday || 0),
tune_cnt: K.ITEM("s32", data.saucer?.tuneCount || 0),
save_cnt: K.ITEM("s32", data.saucer?.saveCount || 0),
saved_cnt: K.ITEM("s32", data.saucer?.savedCount || 0),
fc_cnt: K.ITEM("s32", data.saucer?.fcCount || 0),
ex_cnt: K.ITEM("s32", data.saucer?.exCount || 0),
clear_cnt: K.ITEM("s32", data.saucer?.clearCount || 0),
pf_cnt: K.ITEM("s32", 0),
match_cnt: K.ITEM("s32", data.saucer?.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)
},
last: {
play_time: K.ITEM("s64", BigInt(0)),
shopname: K.ITEM("str", data.lastShopname),
areaname: K.ITEM("str", data.lastAreaname),
title: K.ITEM("s16", data.saucer?.title || 0),
parts: K.ITEM("s16", data.saucer?.parts || 0),
theme: K.ITEM("s8", data.saucer?.theme || 0),
marker: K.ITEM("s8", data.saucer?.marker || 0),
rank_sort: K.ITEM("s8", data.rankSort || 1),
combo_disp: K.ITEM("s8", data.comboDisp || 1),
music_id: K.ITEM("s32", data.musicId || 0),
seq_id: K.ITEM("s8", data.seqId || 0),
sort: K.ITEM("s8", data.saucer?.sort || 0),
category: K.ITEM("s8", data.saucer?.category || 0)
},
item: {
secret_list: K.ARRAY("s32", Array(32).fill(-1)),
theme_list: K.ITEM("s16", -1),
marker_list: K.ARRAY("s32", Array(2).fill(-1)),
title_list: K.ARRAY("s32", Array(96).fill(-1)),
parts_list: K.ARRAY("s32", Array(96).fill(-1)),
new: {
secret_list: K.ARRAY("s32", Array(32).fill(0)),
theme_list: K.ITEM("s16", 0),
marker_list: K.ARRAY("s32", Array(2).fill(0)),
title_list: K.ARRAY("s32", Array(96).fill(0))
}
},
history: K.ATTR({ count: "0" }),
challenge: {
today: {
music_id: K.ITEM("s32", 0),
state: K.ITEM("u8", 0)
}
},
news: {
checked: K.ITEM("s16", 0)
},
bistro: {
info: {
delicious_rate: K.ITEM("float", 1.0),
favorite_rate: K.ITEM("float", 1.0)
},
chef: {
id: K.ITEM("s32", 0),
ability: K.ITEM("u8", 0),
remain: K.ITEM("u8", 0),
rate: K.ARRAY("u8", [0, 0, 0, 0])
},
carry_over: K.ITEM("s32", data.saucer?.bistro?.carry_over || 0),
route: Array(9).fill(0).map((v, i) => (K.ATTR({ no: String(i) }, {
music: {
id: K.ITEM("s32", 0),
price_s32: K.ITEM("s32", 0)
},
gourmates: {
id: K.ITEM("s32", 0),
favorite: K.ARRAY("u8", Array(30).fill(0)),
satisfaction_s32: K.ITEM("s32", 0)
}
})))
},
rivallist: K.ATTR({ count: "0" }),
only_now_music: K.ATTR({ count: "0" }),
requested_music: K.ATTR({ count: "0" }),
lab_edit_seq: K.ATTR({ count: "0" }),
kac_music: K.ATTR({ count: "0" }),
});
+25 -1
View File
@@ -1,6 +1,30 @@
export function getVersion({ model }: EamuseInfo) { export function getVersion({ model }: EamuseInfo) {
const dateCode = model.split(':')[4]; const dateCode = parseInt(model.split(":")[4]);
if (model.startsWith("J44")) return 3; if (model.startsWith("J44")) return 3;
if (model.startsWith("K44")) return 4;
if (model.startsWith("L44")) {
if (dateCode >= 2012082400 && dateCode <= 2014022400) return 5;
if (dateCode >= 2014030303 && dateCode <= 2014121802) return 6;
return 0;
}
return 0; return 0;
} }
export function getVersionName({ model }: EamuseInfo) {
const dateCode = parseInt(model.split(":")[4]);
if (model.startsWith("J44")) return "knit";
if (model.startsWith("K44")) return "copious";
if (model.startsWith("L44")) {
if (dateCode >= 2012082400 && dateCode <= 2014022400) return "saucer";
if (dateCode >= 2014030303 && dateCode <= 2014121802) return "fulfill";
return null;
}
return null;
}
export function VersionRange(version: number, start: number, end: number = -1) {
if (end === -1) return version >= start;
return version >= start && version <= end;
}