mirror of
https://github.com/asphyxia-core/plugins.git
synced 2026-03-21 17:34:46 -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
|
||||
|
||||
Supported Versions:
|
||||
* HEAVENLY HAVEN
|
||||
* VIVID WAVE
|
||||
(WORK IN PROGRESS)
|
||||
|
|
|
|||
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() {
|
||||
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 {
|
||||
modelVer: string;
|
||||
collection: 'profile';
|
||||
|
||||
pluginVer: number;
|
||||
|
||||
name: string;
|
||||
appeal: number;
|
||||
|
|
@ -9,7 +11,7 @@ export interface Profile {
|
|||
packets: number;
|
||||
blocks: number;
|
||||
};
|
||||
|
||||
|
||||
state: {
|
||||
lastMusicID: number;
|
||||
lastMusicType: number;
|
||||
|
|
@ -17,7 +19,7 @@ export interface Profile {
|
|||
headphone: number;
|
||||
blasterEnergy: number;
|
||||
blasterCount: number;
|
||||
}
|
||||
};
|
||||
|
||||
settings: {
|
||||
hiSpeed: number;
|
||||
|
|
@ -30,5 +32,5 @@ export interface Profile {
|
|||
effCLeft: number;
|
||||
effCRight: number;
|
||||
narrowDown: number;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
// Version specific data (e.g. skills level)
|
||||
export interface VersionData {
|
||||
collection: 'version';
|
||||
|
||||
version: number;
|
||||
skillLevel: number;
|
||||
skillBaseID: number;
|
||||
skillNameID: number;
|
||||
skill: {
|
||||
level: number;
|
||||
base: number;
|
||||
name: number;
|
||||
};
|
||||
items: {
|
||||
[key: string]: number;
|
||||
};
|
||||
params: {
|
||||
[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