mirror of
https://github.com/asphyxia-core/plugins.git
synced 2026-04-26 02:02:29 -05:00
sdvx initial support
This commit is contained in:
parent
db46898cdb
commit
ff16ea5f96
11
.prettierrc
Normal file
11
.prettierrc
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"tabWidth": 2,
|
||||||
|
"useTabs": false,
|
||||||
|
"endOfLine": "lf",
|
||||||
|
"semi": true,
|
||||||
|
"singleQuote": true,
|
||||||
|
"bracketSpacing": true,
|
||||||
|
"arrowParens": "avoid",
|
||||||
|
"quoteProps": "consistent"
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
# SOUND VOLTEX
|
# SOUND VOLTEX
|
||||||
|
|
||||||
Supported Versions:
|
(WORK IN PROGRESS)
|
||||||
* HEAVENLY HAVEN
|
|
||||||
* VIVID WAVE
|
|
||||||
|
|
|
||||||
4521
sdvx@asphyxia/data/hvn.ts
Normal file
4521
sdvx@asphyxia/data/hvn.ts
Normal file
File diff suppressed because it is too large
Load Diff
2594
sdvx@asphyxia/data/vvw.ts
Normal file
2594
sdvx@asphyxia/data/vvw.ts
Normal file
File diff suppressed because it is too large
Load Diff
90
sdvx@asphyxia/handlers/common.ts
Normal file
90
sdvx@asphyxia/handlers/common.ts
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
import { EVENT4, COURSES4, EXTENDS4 } from '../data/hvn';
|
||||||
|
import { EVENT5, COURSES5, EXTENDS5 } from '../data/vvw';
|
||||||
|
export const common: EPR = async (info, data, send) => {
|
||||||
|
let events = [];
|
||||||
|
let courses = [];
|
||||||
|
let extend = [];
|
||||||
|
|
||||||
|
switch (info.method) {
|
||||||
|
case 'sv4_common': {
|
||||||
|
events = EVENT4;
|
||||||
|
courses = COURSES4;
|
||||||
|
extend = EXTENDS4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'sv5_common': {
|
||||||
|
events = EVENT5;
|
||||||
|
courses = COURSES5;
|
||||||
|
extend = EXTENDS5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let songs = [];
|
||||||
|
|
||||||
|
if (U.GetConfig('unlock_all_songs')) {
|
||||||
|
for (let i = 1; i < 1600; ++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),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
send.object(
|
||||||
|
{
|
||||||
|
event: {
|
||||||
|
info: events.map(e => ({
|
||||||
|
event_id: K.ITEM('str', e),
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
extend: {
|
||||||
|
info: extend.map(e => ({
|
||||||
|
extend_id: K.ITEM('u32', e.id),
|
||||||
|
extend_type: K.ITEM('u32', e.type),
|
||||||
|
param_num_1: K.ITEM('s32', e.params[0]),
|
||||||
|
param_num_2: K.ITEM('s32', e.params[1]),
|
||||||
|
param_num_3: K.ITEM('s32', e.params[2]),
|
||||||
|
param_num_4: K.ITEM('s32', e.params[3]),
|
||||||
|
param_num_5: K.ITEM('s32', e.params[4]),
|
||||||
|
param_str_1: K.ITEM('str', e.params[5]),
|
||||||
|
param_str_2: K.ITEM('str', e.params[6]),
|
||||||
|
param_str_3: K.ITEM('str', e.params[7]),
|
||||||
|
param_str_4: K.ITEM('str', e.params[8]),
|
||||||
|
param_str_5: K.ITEM('str', e.params[9]),
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
music_limited: { info: songs },
|
||||||
|
skill_course: {
|
||||||
|
info: courses.reduce(
|
||||||
|
(acc, s) =>
|
||||||
|
acc.concat(
|
||||||
|
s.courses.map(c => ({
|
||||||
|
season_id: K.ITEM('s32', s.id),
|
||||||
|
season_name: K.ITEM('str', s.name),
|
||||||
|
season_new_flg: K.ITEM('bool', s.isNew),
|
||||||
|
course_type: K.ITEM('s16', 0),
|
||||||
|
course_id: K.ITEM('s16', c.id),
|
||||||
|
course_name: K.ITEM('str', c.name),
|
||||||
|
skill_level: K.ITEM('s16', c.level),
|
||||||
|
skill_name_id: K.ITEM('s16', c.nameID),
|
||||||
|
matching_assist: K.ITEM('bool', c.assist),
|
||||||
|
clear_rate: K.ITEM('s32', 5000),
|
||||||
|
avg_score: K.ITEM('u32', 15000000),
|
||||||
|
track: c.tracks.map(t => ({
|
||||||
|
track_no: K.ITEM('s16', t.no),
|
||||||
|
music_id: K.ITEM('s32', t.mid),
|
||||||
|
music_type: K.ITEM('s8', t.mty),
|
||||||
|
})),
|
||||||
|
}))
|
||||||
|
),
|
||||||
|
[]
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ encoding: 'utf8' }
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
/*
|
|
||||||
EamusePluginRoute. Handle your game message like this
|
|
||||||
|
|
||||||
You can send a plain XML request to test this route:
|
|
||||||
<call model="NULL:example">
|
|
||||||
<example method="method" card="E0040123456789AB"></example>
|
|
||||||
</call>
|
|
||||||
*/
|
|
||||||
export const example: EPR = async (info, data, send) => {
|
|
||||||
/* [Check documentation for the entire API] */
|
|
||||||
|
|
||||||
/*
|
|
||||||
Access data from request like this
|
|
||||||
NOTE: all card number will be automatically converted to refid.
|
|
||||||
This is to support older game that doesn't use cardmng,
|
|
||||||
yet still allow them to register with internal profile manager.
|
|
||||||
And they can show up in WebUI as a profile, along with card binding feature.
|
|
||||||
*/
|
|
||||||
const refid = $(data).attr().card;
|
|
||||||
|
|
||||||
/* Access config like this */
|
|
||||||
const event = U.GetConfig('event');
|
|
||||||
|
|
||||||
/*
|
|
||||||
Create user data in profile space if not exists
|
|
||||||
WebUI will try to find a "name" field in profile documents and display them.
|
|
||||||
If you are using a collection of data for each profile,
|
|
||||||
make sure to avoid using name field in supplementary documents.
|
|
||||||
If you have multiple documents per refid, it is recommended to provide a field to
|
|
||||||
simulate collections in NoSQL database (e.g. MongoDB)
|
|
||||||
*/
|
|
||||||
await DB.Upsert(
|
|
||||||
refid,
|
|
||||||
{
|
|
||||||
collection: 'profile',
|
|
||||||
name: 'PLAYER',
|
|
||||||
},
|
|
||||||
{ $inc: { login_count: 1 } }
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Send your response like this
|
|
||||||
There are more methods for sending request.
|
|
||||||
*/
|
|
||||||
send.pugFile('templates/example.pug', { refid, event });
|
|
||||||
|
|
||||||
/* Or you can send ejs template (plain xml works as well) */
|
|
||||||
// send.xmlFile('templates/example.xml', { refid, event });
|
|
||||||
};
|
|
||||||
|
|
||||||
export const changeName = async (data: any) => {
|
|
||||||
await DB.Update(data.refid, { collection: 'profile' }, { $set: { name: data.name } });
|
|
||||||
};
|
|
||||||
97
sdvx@asphyxia/handlers/profile.ts
Normal file
97
sdvx@asphyxia/handlers/profile.ts
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
import { Profile } from '../models/profile';
|
||||||
|
import { VersionData } from '../models/version_data';
|
||||||
|
|
||||||
|
export const loadScores: EPR = async (info, data, send) => {
|
||||||
|
const refid = $(data).str('refid');
|
||||||
|
const records = await DB.Find(refid, { collection: 'music' });
|
||||||
|
|
||||||
|
send.pugFile('templates/load_m.pug', { records });
|
||||||
|
};
|
||||||
|
|
||||||
|
export const load: EPR = async (info, data, send) => {
|
||||||
|
const refid = $(data).str('refid');
|
||||||
|
|
||||||
|
let version = 0;
|
||||||
|
switch (info.method) {
|
||||||
|
case 'sv4_load':
|
||||||
|
version = 4;
|
||||||
|
break;
|
||||||
|
case 'sv5_load':
|
||||||
|
version = 5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const profile = await DB.FindOne(refid, { collection: 'profile' });
|
||||||
|
let versionData: VersionData = await DB.FindOne(refid, {
|
||||||
|
collection: 'version',
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!versionData) {
|
||||||
|
versionData = {
|
||||||
|
collection: 'version',
|
||||||
|
version,
|
||||||
|
items: {},
|
||||||
|
params: {},
|
||||||
|
skill: {
|
||||||
|
base: 0,
|
||||||
|
level: 0,
|
||||||
|
name: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
await DB.Insert(refid, versionData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!profile) {
|
||||||
|
send.object({ result: K.ITEM('u8', 1) });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const courses = await DB.Find(refid, { collection: 'course' });
|
||||||
|
|
||||||
|
send.pugFile('templates/load.pug', {
|
||||||
|
courses,
|
||||||
|
...profile,
|
||||||
|
...versionData,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const create: EPR = async (info, data, send) => {
|
||||||
|
const refid = $(data).str('refid');
|
||||||
|
const name = $(data).str('name', 'GUEST');
|
||||||
|
|
||||||
|
const profile: Profile = {
|
||||||
|
pluginVer: 1,
|
||||||
|
|
||||||
|
collection: 'profile',
|
||||||
|
name,
|
||||||
|
appeal: 0,
|
||||||
|
akaname: 0,
|
||||||
|
currency: {
|
||||||
|
blocks: 0,
|
||||||
|
packets: 0,
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
arsOption: 0,
|
||||||
|
drawAdjust: 0,
|
||||||
|
earlyLateDisp: 0,
|
||||||
|
effCLeft: 0,
|
||||||
|
effCRight: 1,
|
||||||
|
gaugeOption: 0,
|
||||||
|
hiSpeed: 0,
|
||||||
|
laneSpeed: 0,
|
||||||
|
narrowDown: 0,
|
||||||
|
notesOption: 0,
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
blasterCount: 0,
|
||||||
|
blasterEnergy: 0,
|
||||||
|
headphone: 0,
|
||||||
|
lastMusicID: 0,
|
||||||
|
lastMusicType: 0,
|
||||||
|
sortType: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
await DB.Upsert(refid, { collection: 'profile' }, profile);
|
||||||
|
send.object({ result: K.ITEM('u8', 0) });
|
||||||
|
};
|
||||||
|
|
@ -1,7 +1,17 @@
|
||||||
import { example, changeName } from './handlers/example';
|
import { common } from './handlers/common';
|
||||||
|
import { load, create, loadScores } from './handlers/profile';
|
||||||
export function register() {
|
export function register() {
|
||||||
R.GameCode('KFC');
|
R.GameCode('KFC');
|
||||||
|
|
||||||
R.Route('example.method', example);
|
R.Config('unlock_all_songs', { type: 'boolean', default: false });
|
||||||
|
R.Config('unlock_all_navigators', { type: 'boolean', default: false });
|
||||||
|
|
||||||
|
R.Route('game.sv4_common', common);
|
||||||
|
R.Route('game.sv4_load', load);
|
||||||
|
R.Route('game.sv4_load_m', loadScores);
|
||||||
|
R.Route('game.sv4_new', create);
|
||||||
|
R.Route('game.sv4_frozen', true);
|
||||||
|
R.Route('game.sv4_load_r', true);
|
||||||
|
|
||||||
|
R.Route('game.sv5_common', common);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
export interface CourseRecord {
|
||||||
|
collection: 'course';
|
||||||
|
|
||||||
|
sid: number;
|
||||||
|
cid: number;
|
||||||
|
score: number;
|
||||||
|
clearType: number;
|
||||||
|
grade: number;
|
||||||
|
achieveRate: number;
|
||||||
|
playCount: number;
|
||||||
|
}
|
||||||
12
sdvx@asphyxia/models/music_record.ts
Normal file
12
sdvx@asphyxia/models/music_record.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
export interface MusicRecord {
|
||||||
|
collection: 'music';
|
||||||
|
|
||||||
|
mid: number;
|
||||||
|
type: number;
|
||||||
|
score: number;
|
||||||
|
clear: number;
|
||||||
|
grade: number;
|
||||||
|
buttonRate: number;
|
||||||
|
longRate: number;
|
||||||
|
volRate: number;
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
export interface Profile {
|
export interface Profile {
|
||||||
modelVer: string;
|
collection: 'profile';
|
||||||
|
|
||||||
|
pluginVer: number;
|
||||||
|
|
||||||
name: string;
|
name: string;
|
||||||
appeal: number;
|
appeal: number;
|
||||||
|
|
@ -9,7 +11,7 @@ export interface Profile {
|
||||||
packets: number;
|
packets: number;
|
||||||
blocks: number;
|
blocks: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
state: {
|
state: {
|
||||||
lastMusicID: number;
|
lastMusicID: number;
|
||||||
lastMusicType: number;
|
lastMusicType: number;
|
||||||
|
|
@ -17,7 +19,7 @@ export interface Profile {
|
||||||
headphone: number;
|
headphone: number;
|
||||||
blasterEnergy: number;
|
blasterEnergy: number;
|
||||||
blasterCount: number;
|
blasterCount: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
settings: {
|
settings: {
|
||||||
hiSpeed: number;
|
hiSpeed: number;
|
||||||
|
|
@ -30,5 +32,5 @@ export interface Profile {
|
||||||
effCLeft: number;
|
effCLeft: number;
|
||||||
effCRight: number;
|
effCRight: number;
|
||||||
narrowDown: number;
|
narrowDown: number;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,17 @@
|
||||||
// Version specific data (e.g. skills level)
|
// Version specific data (e.g. skills level)
|
||||||
export interface VersionData {
|
export interface VersionData {
|
||||||
|
collection: 'version';
|
||||||
|
|
||||||
version: number;
|
version: number;
|
||||||
skillLevel: number;
|
skill: {
|
||||||
skillBaseID: number;
|
level: number;
|
||||||
skillNameID: number;
|
base: number;
|
||||||
|
name: number;
|
||||||
|
};
|
||||||
items: {
|
items: {
|
||||||
[key: string]: number;
|
[key: string]: number;
|
||||||
};
|
};
|
||||||
params: {
|
params: {
|
||||||
[key: string]: number[];
|
[key: string]: number[];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
//-
|
|
||||||
Learn pug here: https://pugjs.org/api/getting-started.html
|
|
||||||
example(status="0")
|
|
||||||
refid(__type="str") #{refid}
|
|
||||||
event(__type="str") #{event}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
<!--
|
|
||||||
Learn ejs here: https://ejs.co/#docs
|
|
||||||
-->
|
|
||||||
<example status="0">
|
|
||||||
<refid __type="str"> <%= refid %> </refid>
|
|
||||||
<event __type="str"> <%= event %> </event>
|
|
||||||
</example>
|
|
||||||
98
sdvx@asphyxia/templates/load.pug
Normal file
98
sdvx@asphyxia/templates/load.pug
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
game
|
||||||
|
result(__type="u8") 0
|
||||||
|
name(__type="str") #{name}
|
||||||
|
code(__type="str") 1337-6666
|
||||||
|
sdvx_id(__type="str") 1337-6666
|
||||||
|
gamecoin_packet(__type="u32") #{currency.packets}
|
||||||
|
gamecoin_block(__type="u32") #{currency.blocks}
|
||||||
|
appeal_id(__type="u16") #{appeal}
|
||||||
|
|
||||||
|
last_music_id(__type="s32") #{state.lastMusicID}
|
||||||
|
last_music_type(__type="u8") #{state.lastMusicType}
|
||||||
|
sort_type(__type="u8") #{state.sortType}
|
||||||
|
headphone(__type="u8") #{state.headphone}
|
||||||
|
blaster_energy(__type="u32") #{state.blasterEnergy}
|
||||||
|
blaster_count(__type="u32") #{state.blasterCount}
|
||||||
|
|
||||||
|
hispeed(__type="s32") #{settings.hiSpeed}
|
||||||
|
lanespeed(__type="u32") #{settings.laneSpeed}
|
||||||
|
gauge_option(__type="u8") #{settings.gaugeOption}
|
||||||
|
ars_option(__type="u8") #{settings.arsOption}
|
||||||
|
notes_option(__type="u8") #{settings.notesOption}
|
||||||
|
early_late_disp(__type="u8") #{settings.earlyLateDisp}
|
||||||
|
draw_adjust(__type="s32") #{settings.drawAdjust}
|
||||||
|
eff_c_left(__type="u8") #{settings.effCLeft}
|
||||||
|
eff_c_right(__type="u8") #{settings.effCRight}
|
||||||
|
narrow_down(__type="u8") #{settings.narrowDown}
|
||||||
|
|
||||||
|
kac_id(__type="str") #{name}
|
||||||
|
skill_level(__type="s16") #{skill.level}
|
||||||
|
skill_base_id(__type="s16") #{skill.base}
|
||||||
|
skill_name_id(__type="s16") #{skill.name}
|
||||||
|
|
||||||
|
ea_shop
|
||||||
|
packet_booster(__type="s32") 1
|
||||||
|
if version != 5
|
||||||
|
block_booster(__type="s32") 1
|
||||||
|
|
||||||
|
eaappli
|
||||||
|
relation(__type="s8") 1
|
||||||
|
cloud
|
||||||
|
relation(__type="s8") 1
|
||||||
|
block_no(__type="s32") 0
|
||||||
|
|
||||||
|
skill
|
||||||
|
each course in courses
|
||||||
|
course
|
||||||
|
ssnid(__type="s16") #{course.sid}
|
||||||
|
crsid(__type="s16") #{course.cid}
|
||||||
|
sc(__type="s32") #{course.score}
|
||||||
|
ct(__type="s16") #{course.clearType}
|
||||||
|
gr(__type="s16") #{course.grade}
|
||||||
|
ar(__type="s16") #{course.achieveRate}
|
||||||
|
cnt(__type="s16") #{course.playCount}
|
||||||
|
|
||||||
|
item
|
||||||
|
each item in items
|
||||||
|
info
|
||||||
|
type(__type="u8") #{item.type}
|
||||||
|
id(__type="u32") #{item.id}
|
||||||
|
param(__type="u32") #{item.param}
|
||||||
|
|
||||||
|
param
|
||||||
|
each param in params
|
||||||
|
info
|
||||||
|
type(__type="u8") #{param.type}
|
||||||
|
id(__type="u32") #{param.id}
|
||||||
|
param(__type="u32" __count=param.param.length) #{param.param.join(" ")}
|
||||||
|
|
||||||
|
//- Akaname
|
||||||
|
each id in [0, 1, 2]
|
||||||
|
info
|
||||||
|
type(__type="u8") 6
|
||||||
|
id(__type="u32") #{id}
|
||||||
|
param(__type="u32" __count="1") #{akaname}
|
||||||
|
|
||||||
|
play_count(__type="u32") 1001
|
||||||
|
day_count(__type="u32") 301
|
||||||
|
today_count(__type="u32") 21
|
||||||
|
play_chain(__type="u32") 31
|
||||||
|
max_play_chain(__type="u32") 31
|
||||||
|
week_count(__type="u32") 9
|
||||||
|
week_play_count(__type="u32") 101
|
||||||
|
week_chain(__type="u32") 31
|
||||||
|
max_week_chain(__type="u32") 31
|
||||||
|
|
||||||
|
if mixes
|
||||||
|
each mix in mixes
|
||||||
|
automation
|
||||||
|
mix_id(__type="s32") #{mix.id}
|
||||||
|
mix_code(__type="str") #{mix.code}
|
||||||
|
seq(__type="str")
|
||||||
|
mix_name(__type="str") #{mix.name}
|
||||||
|
player_name(__type="str") #{mix.creator}
|
||||||
|
generate_param(__type="str") #{mix.param}
|
||||||
|
distribution_date(__type="u32") 19990101
|
||||||
|
jacket_id(__type="s32") #{mix.jacketID}
|
||||||
|
tag_bit(__type="s32") #{mix.tag}
|
||||||
|
like_flg(__type="u8") 0
|
||||||
15
sdvx@asphyxia/templates/load_m.pug
Normal file
15
sdvx@asphyxia/templates/load_m.pug
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
game
|
||||||
|
music
|
||||||
|
for record in records
|
||||||
|
info
|
||||||
|
param(__type="u32" __count="16")
|
||||||
|
| #{record.mid}
|
||||||
|
| #{record.type}
|
||||||
|
| #{record.score}
|
||||||
|
| #{record.type}
|
||||||
|
| #{record.grade}
|
||||||
|
| 0 0
|
||||||
|
| #{record.buttonRate}
|
||||||
|
| #{record.longRate}
|
||||||
|
| #{record.volRate}
|
||||||
|
| 0 0 0 0 0 0
|
||||||
Loading…
Reference in New Issue
Block a user