Booth support

This commit is contained in:
Kirito 2021-04-20 22:46:02 +09:00
parent 0c925ca0e0
commit d1eb39e944
9 changed files with 246 additions and 48 deletions

View File

@ -4,5 +4,6 @@ Plugin Version: **v1.1**
Supported Versions:
- BOOTH
- HEAVENLY HAVEN
- VIVID WAVE

View File

@ -6,6 +6,12 @@ export const common: EPR = async (info, data, send) => {
let courses = [];
let extend = [];
const version = parseInt(info.model.split(":")[4]);
if (version <= 2013052900) {
return send.pugFile('templates/booth/common.pug');
}
switch (info.method) {
case 'sv4_common': {
events = EVENT4;
@ -26,13 +32,13 @@ export const common: EPR = async (info, data, send) => {
if (U.GetConfig('unlock_all_songs')) {
for (let i = 1; i < 1700; ++i) {
for (let j = 0; j < 5; ++j) {
songs.push({
music_id: K.ITEM('s32', i),
music_type: K.ITEM('u8', j),
limited: K.ITEM('u8', 3),
});
}
}
}

View File

@ -1,17 +1,46 @@
import { Profile } from '../models/profile';
import { MusicRecord } from '../models/music_record';
import { IDToCode, GetCounter } from '../utils';
import { Mix } from '../models/mix';
import {Profile} from '../models/profile';
import {MusicRecord} from '../models/music_record';
import {getVersion, IDToCode, GetCounter} from '../utils';
import {Mix} from '../models/mix';
export const hiscore: EPR = async (info, data, send) => {
const records = await DB.Find<MusicRecord>(null, { collection: 'music' });
const version = getVersion(info);
const profiles = _.groupBy(
await DB.Find<Profile>(null, { collection: 'profile' }),
'__refid'
);
send.object({
if (version === 1) {
return send.object({
hiscore: K.ATTR({ type: "1" }, {
music: _.map(
_.groupBy(records, r => {
return `${r.mid}:${r.type}`;
}),
r => _.maxBy(r, 'score')
).map(r => (K.ATTR({ id: String(r.mid) }, {
note: (() => {
const notes = [];
for (let i = 1; i <= 3; i++) {
if (r.type !== i) continue;
notes.push(K.ATTR({ type: String(r.type) }, {
name: K.ITEM('str', profiles[r.__refid][0].name),
score: K.ITEM('u32', r.score)
}))
}
return notes;
})()
}))),
})
})
}
return send.object({
sc: {
d: _.map(
_.groupBy(records, r => {
@ -40,7 +69,7 @@ export const rival: EPR = async (info, data, send) => {
await DB.Find<Profile>(null, { collection: 'profile' })
).filter(p => p.__refid != refid);
send.object({
return send.object({
rival: await Promise.all(
rivals.map(async (p, index) => {
return {
@ -84,7 +113,7 @@ export const saveMix: EPR = async (info, data, send) => {
jacket: mix.number('jacket_id'),
});
send.object({
return send.object({
automation: {
mix_id: K.ITEM('s32', id),
mix_code: K.ITEM('str', doc.code),
@ -105,11 +134,10 @@ export const loadMix: EPR = async (info, data, send) => {
const mix = await DB.FindOne<Mix>({ collection: 'mix', code });
if (!mix) {
send.object({ result: K.ITEM('s32', 1) });
return;
return send.object({ result: K.ITEM('s32', 1) });
}
send.object({
return send.object({
automation: {
mix_id: K.ITEM('s32', mix.id),
mix_code: K.ITEM('str', mix.code),

View File

@ -1,18 +1,12 @@
import { Skill } from '../models/skill';
import { SDVX_AUTOMATION_SONGS } from '../data/vvw';
import { Item } from '../models/item';
import { Param } from '../models/param';
import { MusicRecord } from '../models/music_record';
import { CourseRecord } from '../models/course_record';
import { Profile } from '../models/profile';
import { IDToCode } from '../utils';
import { Mix } from '../models/mix';
function getVersion(info: EamuseInfo) {
if (info.method.startsWith('sv4')) return 4;
if (info.method.startsWith('sv5')) return 5;
return 0;
}
import {Skill} from '../models/skill';
import {SDVX_AUTOMATION_SONGS} from '../data/vvw';
import {Item} from '../models/item';
import {Param} from '../models/param';
import {MusicRecord} from '../models/music_record';
import {CourseRecord} from '../models/course_record';
import {Profile} from '../models/profile';
import {getVersion, IDToCode} from '../utils';
import {Mix} from '../models/mix';
async function getAutomationMixes(params: Param[]) {
const mixids = params
@ -30,12 +24,37 @@ function unlockNavigators(items: Partial<Item>[]) {
}
export const loadScore: EPR = async (info, data, send) => {
const refid = $(data).str('refid');
const refid = $(data).str('refid', $(data).attr().dataid);
if (!refid) return send.deny();
const records = await DB.Find<MusicRecord>(refid, { collection: 'music' });
send.object({
const version = getVersion(info);
if (version === 1) {
return send.object({
music: records.map(r => (K.ATTR({ music_id: String(r.mid) }, {
type: (() => {
const records = [];
for (let i = 1; i <= 3; i++) {
if (r.type != i) continue;
records.push(K.ATTR({
type_id: String(i),
score: String(r.score),
clear_type: String(r.clear),
score_grade: String(r.grade),
cnt: "0"
}));
}
return records;
})()
})))
});
}
return send.object({
music: {
info: records.map(r => ({
param: K.ARRAY('u32', [
@ -62,9 +81,57 @@ export const loadScore: EPR = async (info, data, send) => {
};
export const saveScore: EPR = async (info, data, send) => {
const refid = $(data).str('refid');
const refid = $(data).str('refid', $(data).attr().dataid);
if (!refid) return send.deny();
const version = getVersion(info);
// Booth - Save score
if (version === 1) {
try {
const mid = parseInt($(data).attr().music_id);
const type = parseInt($(data).attr().music_type);
if (_.isNil(mid) || _.isNil(type)) return send.deny();
const record = (await DB.FindOne<MusicRecord>(refid, {
collection: 'music',
mid,
type,
})) || {
collection: 'music',
mid,
type,
score: 0,
clear: 0,
grade: 0,
buttonRate: 0,
longRate: 0,
volRate: 0,
};
const score = $(data).attr().score ? parseInt($(data).attr().score) : 0;
const clear = $(data).attr().clear_type ? parseInt($(data).attr().clear_type) : 0;
const grade = $(data).attr().score_grade ? parseInt($(data).attr().score_grade) : 0;
if (score > record.score) {
record.score = score;
}
record.clear = Math.max(clear, record.clear);
record.grade = Math.max(grade, record.grade);
await DB.Upsert<MusicRecord>(
refid,
{ collection: 'music', mid, type },
record
);
return send.success();
} catch {
return send.deny();
}
}
const mid = $(data).number('music_id');
const type = $(data).number('music_type');
@ -103,7 +170,7 @@ export const saveScore: EPR = async (info, data, send) => {
record
);
send.success();
return send.success();
};
export const saveCourse: EPR = async (info, data, send) => {
@ -134,16 +201,47 @@ export const saveCourse: EPR = async (info, data, send) => {
}
);
send.success();
return send.success();
};
export const save: EPR = async (info, data, send) => {
const refid = $(data).str('refid');
const refid = $(data).str('refid', $(data).attr().refid);
if (!refid) return send.deny();
const version = getVersion(info);
if (version == 0) return send.deny();
if (version === 1) {
try {
// Save Profile
await DB.Update<Profile>(
refid,
{ collection: 'profile' },
{
$set: {
headphone: $(data).number('headphone'),
hiSpeed: $(data).number('hispeed'),
appeal: $(data).number('appeal_id'),
boothFrame: [$(data).number('frame0'), $(data).number('frame1'), $(data).number('frame2'), $(data).number('frame3'), $(data).number('frame4')],
musicID: parseInt($(data).attr("last").music_id),
musicType: parseInt($(data).attr("last").music_type),
sortType: parseInt($(data).attr("last").sort_type),
mUserCnt: $(data).number('m_user_cnt'),
},
$inc: {
expPoint: $(data).number('gain_exp'),
packets: $(data).number('earned_gamecoin_packet'),
blocks: $(data).number('earned_gamecoin_block'),
},
}
);
return send.success();
} catch {
return send.deny();
}
}
// Save Profile
await DB.Update<Profile>(
refid,
@ -226,11 +324,11 @@ export const save: EPR = async (info, data, send) => {
}
);
send.success();
return send.success();
};
export const load: EPR = async (info, data, send) => {
const refid = $(data).str('refid');
const refid = $(data).str('refid', $(data).attr().dataid);
if (!refid) return send.deny();
const version = getVersion(info);
@ -241,8 +339,8 @@ export const load: EPR = async (info, data, send) => {
});
if (!profile) {
send.object({ result: K.ITEM('u8', 1) });
return;
if (version === 1) return send.object(K.ATTR({ none: "1" }));
return send.object({ result: K.ITEM('u8', 1) });
}
let skill = (await DB.FindOne<Skill>(refid, {
@ -263,7 +361,11 @@ export const load: EPR = async (info, data, send) => {
const currentTime = time.getTime();
const mixes = version == 5 ? await getAutomationMixes(params) : [];
send.pugFile('templates/load.pug', {
if (version === 1) {
return send.pugFile('templates/booth/load.pug', { code: IDToCode(profile.id), ...profile });
}
return send.pugFile('templates/load.pug', {
courses,
items: U.GetConfig('unlock_all_navigators')
? unlockNavigators(items)
@ -279,10 +381,10 @@ export const load: EPR = async (info, data, send) => {
};
export const create: EPR = async (info, data, send) => {
const refid = $(data).str('refid');
const refid = $(data).str('refid', $(data).attr().refid);
if (!refid) return send.deny();
const name = $(data).str('name', 'GUEST');
const name = $(data).str('name', $(data).attr().name ? $(data).attr().name : 'GUEST');
let id = _.random(0, 99999999);
while (await DB.FindOne<Profile>(null, { collecttion: 'profile', id })) {
id = _.random(0, 99999999);
@ -314,10 +416,13 @@ export const create: EPR = async (info, data, send) => {
musicID: 0,
musicType: 0,
sortType: 0,
expPoint: 0,
mUserCnt: 0,
boothFrame: [0, 0, 0, 0, 0]
};
await DB.Upsert(refid, { collection: 'profile' }, profile);
send.object({ result: K.ITEM('u8', 0) });
return send.object({ result: K.ITEM('u8', 0) });
};
export const buy: EPR = async (info, data, send) => {
@ -356,11 +461,11 @@ export const buy: EPR = async (info, data, send) => {
);
}
send.object({
return send.object({
gamecoin_packet: K.ITEM('u32', updated.docs[0].packets),
gamecoin_block: K.ITEM('u32', updated.docs[0].blocks),
});
} else {
send.success();
return send.success();
}
};

View File

@ -1,5 +1,5 @@
import { common } from './handlers/common';
import { hiscore, rival, saveMix, loadMix } from './handlers/features';
import {common} from './handlers/common';
import {hiscore, rival, saveMix, loadMix} from './handlers/features';
import {
updateProfile,
updateMix,
@ -29,6 +29,7 @@ export function register() {
const MultiRoute = (method: string, handler: EPR | boolean) => {
// Helper for register multiple versions.
R.Route(`game.${method}`, handler);
R.Route(`game.sv4_${method}`, handler);
R.Route(`game.sv5_${method}`, handler);
};
@ -53,8 +54,12 @@ export function register() {
MultiRoute('load_ap', loadMix);
// Lazy
MultiRoute('lounge', false);
MultiRoute('shop', true);
MultiRoute('lounge', (_, __, send) => send.object({
interval: K.ITEM('u32', 30)
}));
MultiRoute('shop', (_, __, send) => send.object({
nxt_time: K.ITEM('u32', 1000 * 5 * 60)
}));
MultiRoute('save_e', true);
MultiRoute('play_e', true);
MultiRoute('play_s', true);

View File

@ -11,6 +11,9 @@ export interface Profile {
packets: number;
blocks: number;
expPoint: number;
mUserCnt: number;
musicID: number;
musicType: number;
sortType: number;
@ -28,4 +31,6 @@ export interface Profile {
effCLeft: number;
effCRight: number;
narrowDown: number;
boothFrame: number[];
}

View File

@ -0,0 +1,16 @@
- let music = 0;
- let event = 0;
- let catalog = 0;
game
limited
while music < 200
music(id=music++, flag=2)
event
while event < 16
info(id=event++)
catalog
while catalog < 256
info(id=catalog++, currency=1, price=1)

View File

@ -0,0 +1,23 @@
game
name(__type="str") #{name}
code(__type="str") #{code}
gamecoin_packet(__type="u32") #{packets}
gamecoin_block(__type="u32") #{blocks}
exp_point(__type="u32") #{expPoint ? expPoint : 0}
m_user_cnt(__type="u32") #{mUserCnt ? mUserCnt : 0}
have_item(__type="bool" __count=512) #{Array(512).fill(1).join(" ")}
have_note(__type="bool" __count=512) #{Array(512).fill(1).join(" ")}
last(
music_id=musicID,
music_type=musicType,
sort_type=sortType,
headphone=headphone,
hispeed=hiSpeed,
appeal_id=appeal,
frame0=boothFrame ? boothFrame[0] : 0,
frame1=boothFrame ? boothFrame[1] : 0,
frame2=boothFrame ? boothFrame[2] : 0,
frame3=boothFrame ? boothFrame[3] : 0,
frame4=boothFrame ? boothFrame[4] : 0,
)

View File

@ -1,4 +1,5 @@
import { Counter } from './models/counter';
import {Counter} from './models/counter';
export function IDToCode(id: number) {
const padded = _.padStart(id.toString(), 8);
return `${padded.slice(0, 4)}-${padded.slice(4)}`;
@ -12,3 +13,11 @@ export async function GetCounter(key: string) {
)
).docs[0].value;
}
export function getVersion(info: EamuseInfo) {
const dateCode = parseInt(info.model.split(":")[4]);
if (dateCode <= 2013052900) return 1;
if (info.method.startsWith('sv4')) return 4;
if (info.method.startsWith('sv5')) return 5;
return 0;
}