mirror of
https://github.com/asphyxia-core/plugins.git
synced 2026-03-22 01:44:39 -05:00
Merge pull request #10 from DitFranXX/nostalgia
Nostalgia(First version) support
This commit is contained in:
commit
8f4282e711
|
|
@ -1,25 +1,28 @@
|
|||
# Nostalgia
|
||||
|
||||
Plugin Version: **v1.1.0**
|
||||
Plugin Version: **v1.2.0**
|
||||
|
||||
Supported Versions
|
||||
-------------------
|
||||
- Forte (Experiment)
|
||||
- ノスタルジア/ First Version (Experiment-Old)
|
||||
- Forte (Experiment-Old)
|
||||
- Op.2
|
||||
|
||||
About Experiment-Old Support
|
||||
----------------------------
|
||||
A version that marked as **Experiment-Old** is _Not_ Primary supported experiment version.
|
||||
Since This plugin is mainly focused on Op.2, other versions may not work correctly.
|
||||
|
||||
About Forte Support
|
||||
-------------------
|
||||
Forte support is live. But since it has much difference compared to Op.2, Forte is not-primary-supported version.
|
||||
It may works unexpectedly. Forte was tested very lightly. So this feature is tagged as **Experiment**.
|
||||
|
||||
Also, Technically, This *may* support First version of Nostalgia too.
|
||||
But It's highly not recommend to run First version with it.
|
||||
If you have a problem that move from old version to new version, There's webui for mitigate the issue.
|
||||
|
||||
Changelog
|
||||
=========
|
||||
1.1.0 (Current)
|
||||
1.2.0 (Current)
|
||||
---------------
|
||||
- Nostalgia First version support.
|
||||
|
||||
1.1.0
|
||||
-----
|
||||
- Fix saving issue with brooch, island, and kentei.
|
||||
- Moved to Base64 encoded data base.
|
||||
- Forte support.
|
||||
|
|
|
|||
11
nostalgia@asphyxia/data/FirstMusic.ts
Normal file
11
nostalgia@asphyxia/data/FirstMusic.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import { CommonMusicData, readJSONOrXML } from "./ForteMusic";
|
||||
import { readB64JSON } from "./helper";
|
||||
|
||||
export async function processData(): Promise<CommonMusicData> {
|
||||
if (IO.Exists("data/first_mdb.json.b64")) {
|
||||
return await readB64JSON("data/first_mdb.json.b64");
|
||||
}
|
||||
const data = await readJSONOrXML("data/first_mdb.json", "data/first_mdb.xml")
|
||||
// await IO.WriteFile("data/first_mdb.json.b64", Buffer.from(JSON.stringify(data)).toString("base64"))
|
||||
return data;
|
||||
}
|
||||
|
|
@ -1,12 +1,11 @@
|
|||
import { CommonMusicDataField, readB64JSON, readXML } from "./helper";
|
||||
|
||||
export async function processData() {
|
||||
export async function processData(): Promise<CommonMusicData> {
|
||||
if (IO.Exists("data/forte_mdb.json.b64")) {
|
||||
return await readB64JSON("data/forte_mdb.json.b64");
|
||||
}
|
||||
const data = await readJSONOrXML("data/forte_mdb.json", "data/forte_mdb.xml")
|
||||
// await IO.WriteFile("data/forte_mdb.json.b64", Buffer.from(JSON.stringify(data)).toString("base64"))
|
||||
return data
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function processMdbData(path: string): Promise<CommonMusicData> {
|
||||
|
|
@ -62,7 +61,7 @@ export async function readJSONOrXML(jsonPath: string, xmlPath: string): Promise<
|
|||
}
|
||||
}
|
||||
|
||||
interface CommonMusicData {
|
||||
export interface CommonMusicData {
|
||||
"@attr": {
|
||||
revision: string,
|
||||
release_code: string
|
||||
|
|
|
|||
1
nostalgia@asphyxia/data/first_mdb.json.b64
Normal file
1
nostalgia@asphyxia/data/first_mdb.json.b64
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1,6 +1,8 @@
|
|||
import * as path from "path";
|
||||
import { processData } from "../data/ForteMusic";
|
||||
|
||||
import { processData as firstData } from "../data/FirstMusic";
|
||||
import { processData as forteData } from "../data/ForteMusic";
|
||||
import { readB64JSON } from "../data/helper";
|
||||
import { NosVersionHelper } from "../utils";
|
||||
|
||||
export const permitted_list = {
|
||||
flag: [
|
||||
|
|
@ -80,7 +82,7 @@ export const get_common_info = async (info, data, send) => {
|
|||
};
|
||||
|
||||
export const get_music_info: EPR = async (info, data, send) => {
|
||||
const isForte = !info.module.includes("op")
|
||||
const version = new NosVersionHelper(info)
|
||||
|
||||
const music_spec: any = [];
|
||||
for (let i = 1; i < 400; ++i) {
|
||||
|
|
@ -99,10 +101,12 @@ export const get_music_info: EPR = async (info, data, send) => {
|
|||
}));
|
||||
}
|
||||
|
||||
const versionObject = isForte
|
||||
const music_list = async () => version.version === 'Forte' ? await forteData() : await firstData()
|
||||
|
||||
const versionObject = version.isFirstOrForte()
|
||||
? {
|
||||
permitted_list: forte_permitted_list,
|
||||
music_list: await processData()
|
||||
music_list: await music_list()
|
||||
}
|
||||
: {
|
||||
permitted_list,
|
||||
|
|
|
|||
|
|
@ -1,11 +1,7 @@
|
|||
// import { EAHandler } from '../../util/EAHandler';
|
||||
// import { get, _.isArray } from 'lodash';
|
||||
// import { Logger } from '../../util/Logger';
|
||||
import { Profile } from '../models/profile';
|
||||
import { Scores } from '../models/scores';
|
||||
import { NosVersionHelper } from '../utils';
|
||||
import { permitted_list, forte_permitted_list } from './common';
|
||||
// import { getValue, getArray, getAttr, getStr, getBigInt } from '../../util/Helper';
|
||||
|
||||
|
||||
// export const event_list = {
|
||||
// event: {
|
||||
|
|
@ -18,9 +14,9 @@ import { permitted_list, forte_permitted_list } from './common';
|
|||
// },
|
||||
// };
|
||||
|
||||
const getEventInfo = (isForte: boolean) => {
|
||||
const getEventInfo = (version: NosVersionHelper) => {
|
||||
const event: any[] = [];
|
||||
const event_num = isForte ? 10 : 17
|
||||
const event_num = version.getEventMaxIndex()
|
||||
for (let i = 1; i <= event_num; ++i) {
|
||||
event.push({
|
||||
type: K.ITEM('s32', 4),
|
||||
|
|
@ -37,7 +33,7 @@ const getEventInfo = (isForte: boolean) => {
|
|||
|
||||
const getPlayerData = async (refid: string, info: EamuseInfo, name?: string) => {
|
||||
const p = await readProfile(refid);
|
||||
const isForte = !info.module.includes("op")
|
||||
const version = new NosVersionHelper(info)
|
||||
|
||||
if (name && name.length > 0) {
|
||||
p.name = name;
|
||||
|
|
@ -55,7 +51,7 @@ const getPlayerData = async (refid: string, info: EamuseInfo, name?: string) =>
|
|||
|
||||
const brooch: any[] = [];
|
||||
for (const b in p.brooches) {
|
||||
if (isForte && parseInt(b, 10) > 147) continue; // Forte Brooch is ~147.
|
||||
if (parseInt(b, 10) > version.getBroochMaxIndex()) continue;
|
||||
const bData = p.brooches[b];
|
||||
brooch.push(K.ATTR({ index: b }, {
|
||||
watch_count: K.ITEM('s32', bData.watch),
|
||||
|
|
@ -67,6 +63,7 @@ const getPlayerData = async (refid: string, info: EamuseInfo, name?: string) =>
|
|||
|
||||
// Unlock brooches
|
||||
for (let i = 101; i <= 124; ++i) {
|
||||
if (i > version.getBroochMaxIndex()) continue;
|
||||
brooch.push(K.ATTR({ index: `${i}` }, {
|
||||
'watch_count': K.ITEM('s32', 0),
|
||||
'level': K.ITEM('s8', 1),
|
||||
|
|
@ -137,7 +134,7 @@ const getPlayerData = async (refid: string, info: EamuseInfo, name?: string) =>
|
|||
}));
|
||||
}
|
||||
|
||||
const correct_permitted_list = !isForte ? permitted_list : forte_permitted_list
|
||||
const correct_permitted_list = !version.isFirstOrForte() ? permitted_list : forte_permitted_list
|
||||
const music_list = [
|
||||
K.ARRAY('s32', p.musicList.type_0, { sheet_type: '0' }),
|
||||
K.ARRAY('s32', p.musicList.type_1, { sheet_type: '1' }),
|
||||
|
|
@ -151,7 +148,7 @@ const getPlayerData = async (refid: string, info: EamuseInfo, name?: string) =>
|
|||
K.ARRAY('s32', p.musicList2.type_3, { sheet_type: '3' }),
|
||||
];
|
||||
|
||||
if(isForte) {
|
||||
if(version.isFirstOrForte()) {
|
||||
music_list.pop();
|
||||
music_list2.pop();
|
||||
}
|
||||
|
|
@ -161,8 +158,8 @@ const getPlayerData = async (refid: string, info: EamuseInfo, name?: string) =>
|
|||
play_count: K.ITEM('s32', p.playCount),
|
||||
today_play_count: K.ITEM('s32', p.todayPlayCount),
|
||||
permitted_list: correct_permitted_list,
|
||||
event_info_list: { event: getEventInfo(isForte) }, // Op2
|
||||
event_control_list: { event: getEventInfo(isForte) }, // Forte
|
||||
event_info_list: { event: getEventInfo(version) }, // Op2
|
||||
event_control_list: { event: getEventInfo(version) }, // Forte
|
||||
music_list: {
|
||||
flag: music_list,
|
||||
},
|
||||
|
|
@ -170,17 +167,17 @@ const getPlayerData = async (refid: string, info: EamuseInfo, name?: string) =>
|
|||
flag: music_list2,
|
||||
},
|
||||
last: {
|
||||
music_index: K.ITEM('s32', forteNumericHandler(isForte, p.music, 195, 0)),
|
||||
sheet_type: K.ITEM('s8', forteNumericHandler(isForte, p.sheet, 3, 0)),
|
||||
brooch_index: K.ITEM('s32', forteNumericHandler(isForte, p.brooch, 147, 0)),
|
||||
music_index: K.ITEM('s32', version.numericHandler('music_index', p.music, 0)),
|
||||
sheet_type: K.ITEM('s8', version.numericHandler('sheet_type', p.sheet, 0)),
|
||||
brooch_index: K.ITEM('s32', version.numericHandler('brooch_index', p.brooch, 0)),
|
||||
hi_speed_level: K.ITEM('s32', p.hispeed),
|
||||
beat_guide: K.ITEM('s8', p.beatGuide),
|
||||
headphone_volume: K.ITEM('s8', p.headphone),
|
||||
judge_bar_pos: K.ITEM('s32', p.judgeBar),
|
||||
music_group: K.ITEM('s32', p.group),
|
||||
hands_mode: isForte ? K.ITEM('s32', p.mode) : K.ITEM('s8', p.mode),
|
||||
hands_mode: version.isFirstOrForte() ? K.ITEM('s32', p.mode) : K.ITEM('s8', p.mode),
|
||||
near_setting: K.ITEM('s8', p.near),
|
||||
judge_delay_offset: isForte ? K.ITEM('s32', p.offset) : K.ITEM('s8', p.offset),
|
||||
judge_delay_offset: version.isFirstOrForte() ? K.ITEM('s32', p.offset) : K.ITEM('s8', p.offset),
|
||||
bingo_index: K.ITEM('s32', p.bingo),
|
||||
total_skill_value: K.ITEM('u64', BigInt(p.skill)),
|
||||
key_beam_level: K.ITEM('s8', p.keyBeam),
|
||||
|
|
@ -250,7 +247,7 @@ export const set_total_result: EPR = async (info, data, send) => {
|
|||
const refid = $(data).str('refid');
|
||||
if (!refid) return send.deny();
|
||||
|
||||
const isForte = !info.module.includes("op")
|
||||
const isForte = new NosVersionHelper(info).isFirstOrForte()
|
||||
const p = await readProfile(refid);
|
||||
|
||||
p.playCount = $(data).number('play_count', p.playCount);
|
||||
|
|
@ -471,7 +468,7 @@ export const get_musicdata: EPR = async (info, data, send) => {
|
|||
const refid = $(data).str('refid');
|
||||
if (!refid) return send.deny();
|
||||
|
||||
const isForte = !info.module.includes("op")
|
||||
const version = new NosVersionHelper(info)
|
||||
const scoreData = await readScores(refid);
|
||||
|
||||
const recital_record: any[] = [];
|
||||
|
|
@ -499,7 +496,7 @@ export const get_musicdata: EPR = async (info, data, send) => {
|
|||
const mdata = m.split(':');
|
||||
const musi = scoreData.scores[m];
|
||||
|
||||
if (isForte && parseInt(mdata[0], 10) > 195) continue;
|
||||
if (parseInt(mdata[0], 10) > version.getMusicMaxIndex()) continue;
|
||||
|
||||
music.push(K.ATTR({
|
||||
music_index: mdata[0],
|
||||
|
|
@ -523,10 +520,6 @@ export const get_musicdata: EPR = async (info, data, send) => {
|
|||
});
|
||||
};
|
||||
|
||||
function forteNumericHandler(isForte: boolean, input: number, max: number, def: number = 0) {
|
||||
return isForte ? input > max ? def : input : input;
|
||||
}
|
||||
|
||||
async function readProfile(refid: string): Promise<Profile> {
|
||||
const profile = await DB.FindOne<Profile>(refid, { collection: 'profile' })
|
||||
return profile || defaultProfile
|
||||
|
|
|
|||
20
nostalgia@asphyxia/handler/webui.ts
Normal file
20
nostalgia@asphyxia/handler/webui.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import { Profile } from "../models/profile";
|
||||
|
||||
export const fixIndexBug = async (data: {
|
||||
refid: string;
|
||||
confirm: string;
|
||||
}) => {
|
||||
if (data.confirm == "on") {
|
||||
console.warn(`refid "${data.refid}" performs index reset!`)
|
||||
await DB.Update<Profile>(
|
||||
data.refid,
|
||||
{ collection: 'profile' },
|
||||
{ $set: {
|
||||
music: 0,
|
||||
sheet: 0,
|
||||
brooch: 0
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,9 +1,12 @@
|
|||
import { get_common_info, get_music_info } from "./handler/common";
|
||||
import { get_musicdata, get_playdata, regist_playdata, set_total_result } from "./handler/player"
|
||||
import { fixIndexBug } from "./handler/webui";
|
||||
|
||||
export function register() {
|
||||
R.GameCode('PAN');
|
||||
|
||||
R.WebUIEvent("nosFixIndexBug", fixIndexBug)
|
||||
|
||||
const MultiRoute = (method: string, handler: EPR | boolean) => {
|
||||
// Helper for register multiple versions.
|
||||
R.Route(method, handler); // First version and Forte.
|
||||
|
|
|
|||
47
nostalgia@asphyxia/utils.ts
Normal file
47
nostalgia@asphyxia/utils.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
type NostalgiaVersions = 'First' | 'Forte' | 'Op2' | 'Op3'
|
||||
type NostalgiaNumericTypes = 'music_index' | 'sheet_type' | 'brooch_index' | 'event_index'
|
||||
|
||||
export class NosVersionHelper {
|
||||
public version: NostalgiaVersions
|
||||
|
||||
private table = { // FIXME: All of Op3 values are placeholder
|
||||
music_index: { First: 87, Forte: 195, Op2: 315, Op3: 500 },
|
||||
brooch_index: { First: 120, Forte: 147, Op2: 148, Op3: 200 },
|
||||
sheet_type: { First: 2, Forte: 2, Op2: 3, Op3: 3 },
|
||||
event_index: { First: 10, Forte: 10, Op2: 17, Op3: 20 }
|
||||
}
|
||||
|
||||
constructor (info: EamuseInfo) {
|
||||
const version = parseInt(info.model.trim().substr(10), 10)
|
||||
if (version >= 2020000000) {
|
||||
this.version = 'Op3'
|
||||
} else if (version >= 2019000000) {
|
||||
this.version = 'Op2'
|
||||
} else if (version >= 2018000000) {
|
||||
this.version = 'Forte'
|
||||
} else {
|
||||
this.version = 'First'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
getMusicMaxIndex() {
|
||||
return this.table['music_index'][this.version]
|
||||
}
|
||||
|
||||
getBroochMaxIndex() {
|
||||
return this.table['brooch_index'][this.version]
|
||||
}
|
||||
|
||||
getEventMaxIndex() {
|
||||
return this.table['event_index'][this.version]
|
||||
}
|
||||
|
||||
numericHandler(type: NostalgiaNumericTypes, input: number, def: number = 0) {
|
||||
return input > this.table[type][this.version] ? def : input;
|
||||
}
|
||||
|
||||
isFirstOrForte() {
|
||||
return this.version === 'First' || this.version === 'Forte'
|
||||
}
|
||||
}
|
||||
26
nostalgia@asphyxia/webui/profile_fix_login.pug
Normal file
26
nostalgia@asphyxia/webui/profile_fix_login.pug
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
div
|
||||
.card
|
||||
.card-header
|
||||
p.card-header-title
|
||||
span.icon
|
||||
i.mdi.mdi-account-edit
|
||||
| Fix Error with Login
|
||||
.card-content
|
||||
p If you unable to login after travels of between versions, This may helpful.
|
||||
p Normally, login issue caused you played deleted song last time in previous version that not deleted time.
|
||||
p This page is about reset of last indexes that causing login problem.
|
||||
form(method="post" action="/emit/nosFixIndexBug")
|
||||
.field
|
||||
label.label ID
|
||||
.control
|
||||
input.input(type="text" name="refid", value=refid readonly)
|
||||
.field
|
||||
label.label Are you sure to reset indexes?
|
||||
.control
|
||||
input(type="checkbox" name="confirm")
|
||||
| This is not recoverable. Do this if you have a problem.
|
||||
.field
|
||||
button.button.is-primary(type="submit")
|
||||
span.icon
|
||||
i.mdi.mdi-check
|
||||
span Submit
|
||||
Loading…
Reference in New Issue
Block a user