[sdvx] score saving

This commit is contained in:
Freddie
2020-05-30 02:48:58 +01:00
parent 3a1952a478
commit 510453ce09
6 changed files with 147 additions and 57 deletions
+11 -5
View File
@@ -81,7 +81,7 @@ declare interface EamuseInfo {
/** /**
* Detail of a config * Detail of a config
*/ */
declare interface CONFIG_OPTIONS { declare interface ConfigOption {
/** Provide a name to display in webui. If not provided, webui will use key as the name. */ /** Provide a name to display in webui. If not provided, webui will use key as the name. */
name?: string; name?: string;
/** Provide a description for the option */ /** Provide a description for the option */
@@ -288,11 +288,11 @@ declare namespace R {
* Register a configuration option. * Register a configuration option.
* *
* @param key config key * @param key config key
* @param options See [[CONFIG_OPTIONS]] * @param options See [[ConfigOption]]
* *
* __NOTE__: `options.validator` will only notify user about invalid value. It wouldn't stop user from saving invalid value. * __NOTE__: `options.validator` will only notify user about invalid value. It wouldn't stop user from saving invalid value.
*/ */
function Config(key: string, options: CONFIG_OPTIONS): void; function Config(key: string, options: ConfigOption): void;
/** /**
* Register a WebUI event callback * Register a WebUI event callback
@@ -967,7 +967,7 @@ type Update<T> = Partial<T> & {
* If `refid` is a string, query will match a specific profile data in __ProfileSpace__. * If `refid` is a string, query will match a specific profile data in __ProfileSpace__.
* *
* If `refid` is null, query will match all profile data in __ProfileSpace__. * If `refid` is null, query will match all profile data in __ProfileSpace__.
* (doesn't apply to [[DB.FindOne]] and [[DB.Insert]]) * (doesn't apply to [[DB.Insert]])
* *
* If `refid` is not provided, query will match data in ___PluginSpace___. * If `refid` is not provided, query will match data in ___PluginSpace___.
* *
@@ -980,7 +980,7 @@ type Update<T> = Partial<T> & {
* There will be 16 profiles maximum which is small enough to manage. * There will be 16 profiles maximum which is small enough to manage.
*/ */
declare namespace DB { declare namespace DB {
function FindOne<T>(refid: string, query: Query<T>): Promise<Doc<T>>; function FindOne<T>(refid: string | null, query: Query<T>): Promise<Doc<T>>;
function FindOne<T>(query: Query<T>): Promise<Doc<T>>; function FindOne<T>(query: Query<T>): Promise<Doc<T>>;
function Find<T>(refid: string | null, query: Query<T>): Promise<Doc<T>[]>; function Find<T>(refid: string | null, query: Query<T>): Promise<Doc<T>[]>;
@@ -1029,3 +1029,9 @@ declare namespace DB {
function Count<T>(refid: string | null, query: Query<T>): Promise<number>; function Count<T>(refid: string | null, query: Query<T>): Promise<number>;
function Count<T>(query: Query<T>): Promise<number>; function Count<T>(query: Query<T>): Promise<number>;
} }
/** @ignore */
declare namespace _ {}
/** @ignore */
declare const _: any;
/// <reference types="lodash" />
+2 -2
View File
@@ -2,8 +2,8 @@
"name": "asphyxia-plugins", "name": "asphyxia-plugins",
"version": "1.0.0", "version": "1.0.0",
"description": "Community Plugins for Asphyxia CORE", "description": "Community Plugins for Asphyxia CORE",
"dependencies": {}, "dependencies": {
"devDependencies": { "@types/lodash": "^4.14.153",
"@types/node": "^14.0.5" "@types/node": "^14.0.5"
} }
} }
+108 -22
View File
@@ -4,16 +4,102 @@ import { SDVX_AUTOMATION_SONGS } from '../data/vvw';
import { CourseRecord } from '../models/course_record'; import { CourseRecord } from '../models/course_record';
import { Item } from '../models/item'; import { Item } from '../models/item';
import { Param } from '../models/param'; import { Param } from '../models/param';
import { MusicRecord } from '../models/music_record';
function getVersion(info: EamuseInfo) {
if (info.module == 'game_3') return 0;
if (info.method.startsWith('sv4')) return 4;
if (info.method.startsWith('sv5')) return 5;
return 0;
}
export const loadScores: EPR = async (info, data, send) => { export const loadScores: EPR = async (info, data, send) => {
const refid = $(data).str('refid'); const refid = $(data).str('refid');
const records = await DB.Find(refid, { collection: 'music' }); if (!refid) return send.deny();
send.pugFile('templates/load_m.pug', { records }); const records = await DB.Find<MusicRecord>(refid, { collection: 'music' });
send.object({
music: {
info: records.map(r => ({
param: K.ARRAY('u32', [
r.mid,
r.type,
r.score,
r.clear,
r.grade,
0,
0,
r.buttonRate,
r.longRate,
r.volRate,
0,
0,
0,
0,
0,
0,
]),
})),
},
});
};
export const saveScores: EPR = async (info, data, send) => {
const refid = $(data).str('refid');
if (!refid) return send.deny();
const musicID = $(data).number('music_id');
const musicType = $(data).number('music_type');
if (musicID == null || musicType == null) return send.deny();
const record = (await DB.FindOne<MusicRecord>(refid, {
collection: 'music',
mid: musicID,
type: musicType,
})) || {
collection: 'music',
mid: musicID,
type: musicType,
score: 0,
clear: 0,
grade: 0,
buttonRate: 0,
longRate: 0,
volRate: 0,
};
const score = $(data).number('score', 0);
if (score > record.score) {
record.score = score;
record.buttonRate = $(data).number('btn_rate', 0);
record.longRate = $(data).number('long_rate', 0);
record.volRate = $(data).number('vol_rate', 0);
}
record.clear = Math.max($(data).number('clear_type', 0), record.clear);
record.grade = Math.max($(data).number('score_grade', 0), record.grade);
await DB.Upsert<MusicRecord>(
refid,
{
collection: 'music',
mid: musicID,
type: musicType,
},
record
);
send.success();
}; };
export const save: EPR = async (info, data, send) => { export const save: EPR = async (info, data, send) => {
const refid = $(data).str('refid'); const refid = $(data).str('refid');
if (!refid) return send.deny();
const version = getVersion(info);
if (version == 0) return send.deny();
await DB.Update<Profile>( await DB.Update<Profile>(
refid, refid,
@@ -47,21 +133,29 @@ export const save: EPR = async (info, data, send) => {
} }
); );
await DB.Upsert<VersionData>(
{
collection: 'version',
version,
},
{
$set: {
skillBase: $(data).number('skill_base_id'),
skillLevel: $(data).number('skill_level'),
skillName: $(data).number('skill_name_id'),
},
}
);
send.success(); send.success();
}; };
export const load: EPR = async (info, data, send) => { export const load: EPR = async (info, data, send) => {
const refid = $(data).str('refid'); const refid = $(data).str('refid');
if (!refid) return send.deny();
let version = 0; const version = getVersion(info);
switch (info.method) { if (version == 0) return send.deny();
case 'sv4_load':
version = 4;
break;
case 'sv5_load':
version = 5;
break;
}
const profile = await DB.FindOne<Profile>(refid, { const profile = await DB.FindOne<Profile>(refid, {
collection: 'profile', collection: 'profile',
@@ -74,19 +168,9 @@ export const load: EPR = async (info, data, send) => {
let versionData = await DB.FindOne<VersionData>(refid, { let versionData = await DB.FindOne<VersionData>(refid, {
collection: 'version', collection: 'version',
version,
}); });
if (!versionData) {
versionData = {
collection: 'version',
version,
skillBase: 0,
skillLevel: 0,
skillName: 0,
};
await DB.Insert(refid, versionData);
}
const courses = await DB.Find<CourseRecord>(refid, { collection: 'course' }); const courses = await DB.Find<CourseRecord>(refid, { collection: 'course' });
const items = await DB.Find<Item>(refid, { collection: 'item' }); const items = await DB.Find<Item>(refid, { collection: 'item' });
const params = await DB.Find<Param>(refid, { collection: 'param' }); const params = await DB.Find<Param>(refid, { collection: 'param' });
@@ -103,6 +187,8 @@ export const load: EPR = async (info, data, send) => {
export const create: EPR = async (info, data, send) => { export const create: EPR = async (info, data, send) => {
const refid = $(data).str('refid'); const refid = $(data).str('refid');
if (!refid) return send.deny();
const name = $(data).str('name', 'GUEST'); const name = $(data).str('name', 'GUEST');
const profile: Profile = { const profile: Profile = {
+23 -10
View File
@@ -1,19 +1,32 @@
import { common } from './handlers/common'; import { common } from './handlers/common';
import { load, create, loadScores, save } from './handlers/profile'; import { load, create, loadScores, save, saveScores } from './handlers/profile';
export function register() { export function register() {
R.GameCode('KFC'); R.GameCode('KFC');
R.Config('unlock_all_songs', { type: 'boolean', default: false }); R.Config('unlock_all_songs', { type: 'boolean', default: false });
R.Config('unlock_all_navigators', { type: 'boolean', default: false }); R.Config('unlock_all_navigators', { type: 'boolean', default: false });
R.Route('game.sv4_common', common); const MultiRoute = (method: string, handler: EPR | boolean) => {
R.Route('game.sv4_load', load); // Helper for register multiple versions.
R.Route('game.sv4_load_m', loadScores); R.Route(`game.sv4_${method}`, handler);
R.Route('game.sv4_new', create); R.Route(`game.sv5_${method}`, handler);
R.Route('game.sv4_frozen', true); };
R.Route('game.sv4_load_r', true);
R.Route('game.sv4_save', save);
R.Route('game.sv4_save_m', true);
R.Route('game.sv5_common', common); // Common
MultiRoute('common', common);
// Profile
MultiRoute('new', create);
MultiRoute('load', load);
MultiRoute('load_m', loadScores);
MultiRoute('load_r', true);
MultiRoute('save', save);
MultiRoute('save_m', saveScores);
MultiRoute('frozen', true);
// Useless
MultiRoute('lounge', false);
R.Unhandled();
} }
+3 -3
View File
@@ -26,9 +26,9 @@ game
narrow_down(__type="u8") #{narrowDown} narrow_down(__type="u8") #{narrowDown}
kac_id(__type="str") #{name} kac_id(__type="str") #{name}
skill_level(__type="s16") #{skillLevel} skill_level(__type="s16") #{skillLevel || 0}
skill_base_id(__type="s16") #{skillBase} skill_base_id(__type="s16") #{skillBase || 0}
skill_name_id(__type="s16") #{skillName} skill_name_id(__type="s16") #{skillName || 0}
ea_shop ea_shop
packet_booster(__type="s32") 1 packet_booster(__type="s32") 1
-15
View File
@@ -1,15 +0,0 @@
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