mirror of
https://github.com/asphyxia-core/plugins.git
synced 2026-09-22 22:27:56 +03:00
[sdvx] score saving
This commit is contained in:
Vendored
+11
-5
@@ -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
@@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
|
||||||
Reference in New Issue
Block a user