mirror of
https://github.com/asphyxia-core/plugins.git
synced 2026-04-25 16:21:44 -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
|
# Nostalgia
|
||||||
|
|
||||||
Plugin Version: **v1.1.0**
|
Plugin Version: **v1.2.0**
|
||||||
|
|
||||||
Supported Versions
|
Supported Versions
|
||||||
-------------------
|
-------------------
|
||||||
- Forte (Experiment)
|
- ノスタルジア/ First Version (Experiment-Old)
|
||||||
|
- Forte (Experiment-Old)
|
||||||
- Op.2
|
- 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
|
If you have a problem that move from old version to new version, There's webui for mitigate the issue.
|
||||||
-------------------
|
|
||||||
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.
|
|
||||||
|
|
||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
1.1.0 (Current)
|
1.2.0 (Current)
|
||||||
---------------
|
---------------
|
||||||
|
- Nostalgia First version support.
|
||||||
|
|
||||||
|
1.1.0
|
||||||
|
-----
|
||||||
- Fix saving issue with brooch, island, and kentei.
|
- Fix saving issue with brooch, island, and kentei.
|
||||||
- Moved to Base64 encoded data base.
|
- Moved to Base64 encoded data base.
|
||||||
- Forte support.
|
- 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";
|
import { CommonMusicDataField, readB64JSON, readXML } from "./helper";
|
||||||
|
|
||||||
export async function processData() {
|
export async function processData(): Promise<CommonMusicData> {
|
||||||
if (IO.Exists("data/forte_mdb.json.b64")) {
|
if (IO.Exists("data/forte_mdb.json.b64")) {
|
||||||
return await readB64JSON("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")
|
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> {
|
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": {
|
"@attr": {
|
||||||
revision: string,
|
revision: string,
|
||||||
release_code: 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 { readB64JSON } from "../data/helper";
|
||||||
|
import { NosVersionHelper } from "../utils";
|
||||||
|
|
||||||
export const permitted_list = {
|
export const permitted_list = {
|
||||||
flag: [
|
flag: [
|
||||||
|
|
@ -80,7 +82,7 @@ export const get_common_info = async (info, data, send) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const get_music_info: EPR = 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 = [];
|
const music_spec: any = [];
|
||||||
for (let i = 1; i < 400; ++i) {
|
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,
|
permitted_list: forte_permitted_list,
|
||||||
music_list: await processData()
|
music_list: await music_list()
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
permitted_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 { Profile } from '../models/profile';
|
||||||
import { Scores } from '../models/scores';
|
import { Scores } from '../models/scores';
|
||||||
|
import { NosVersionHelper } from '../utils';
|
||||||
import { permitted_list, forte_permitted_list } from './common';
|
import { permitted_list, forte_permitted_list } from './common';
|
||||||
// import { getValue, getArray, getAttr, getStr, getBigInt } from '../../util/Helper';
|
|
||||||
|
|
||||||
|
|
||||||
// export const event_list = {
|
// export const event_list = {
|
||||||
// event: {
|
// 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: any[] = [];
|
||||||
const event_num = isForte ? 10 : 17
|
const event_num = version.getEventMaxIndex()
|
||||||
for (let i = 1; i <= event_num; ++i) {
|
for (let i = 1; i <= event_num; ++i) {
|
||||||
event.push({
|
event.push({
|
||||||
type: K.ITEM('s32', 4),
|
type: K.ITEM('s32', 4),
|
||||||
|
|
@ -37,7 +33,7 @@ const getEventInfo = (isForte: boolean) => {
|
||||||
|
|
||||||
const getPlayerData = async (refid: string, info: EamuseInfo, name?: string) => {
|
const getPlayerData = async (refid: string, info: EamuseInfo, name?: string) => {
|
||||||
const p = await readProfile(refid);
|
const p = await readProfile(refid);
|
||||||
const isForte = !info.module.includes("op")
|
const version = new NosVersionHelper(info)
|
||||||
|
|
||||||
if (name && name.length > 0) {
|
if (name && name.length > 0) {
|
||||||
p.name = name;
|
p.name = name;
|
||||||
|
|
@ -55,7 +51,7 @@ const getPlayerData = async (refid: string, info: EamuseInfo, name?: string) =>
|
||||||
|
|
||||||
const brooch: any[] = [];
|
const brooch: any[] = [];
|
||||||
for (const b in p.brooches) {
|
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];
|
const bData = p.brooches[b];
|
||||||
brooch.push(K.ATTR({ index: b }, {
|
brooch.push(K.ATTR({ index: b }, {
|
||||||
watch_count: K.ITEM('s32', bData.watch),
|
watch_count: K.ITEM('s32', bData.watch),
|
||||||
|
|
@ -67,6 +63,7 @@ const getPlayerData = async (refid: string, info: EamuseInfo, name?: string) =>
|
||||||
|
|
||||||
// Unlock brooches
|
// Unlock brooches
|
||||||
for (let i = 101; i <= 124; ++i) {
|
for (let i = 101; i <= 124; ++i) {
|
||||||
|
if (i > version.getBroochMaxIndex()) continue;
|
||||||
brooch.push(K.ATTR({ index: `${i}` }, {
|
brooch.push(K.ATTR({ index: `${i}` }, {
|
||||||
'watch_count': K.ITEM('s32', 0),
|
'watch_count': K.ITEM('s32', 0),
|
||||||
'level': K.ITEM('s8', 1),
|
'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 = [
|
const music_list = [
|
||||||
K.ARRAY('s32', p.musicList.type_0, { sheet_type: '0' }),
|
K.ARRAY('s32', p.musicList.type_0, { sheet_type: '0' }),
|
||||||
K.ARRAY('s32', p.musicList.type_1, { sheet_type: '1' }),
|
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' }),
|
K.ARRAY('s32', p.musicList2.type_3, { sheet_type: '3' }),
|
||||||
];
|
];
|
||||||
|
|
||||||
if(isForte) {
|
if(version.isFirstOrForte()) {
|
||||||
music_list.pop();
|
music_list.pop();
|
||||||
music_list2.pop();
|
music_list2.pop();
|
||||||
}
|
}
|
||||||
|
|
@ -161,8 +158,8 @@ const getPlayerData = async (refid: string, info: EamuseInfo, name?: string) =>
|
||||||
play_count: K.ITEM('s32', p.playCount),
|
play_count: K.ITEM('s32', p.playCount),
|
||||||
today_play_count: K.ITEM('s32', p.todayPlayCount),
|
today_play_count: K.ITEM('s32', p.todayPlayCount),
|
||||||
permitted_list: correct_permitted_list,
|
permitted_list: correct_permitted_list,
|
||||||
event_info_list: { event: getEventInfo(isForte) }, // Op2
|
event_info_list: { event: getEventInfo(version) }, // Op2
|
||||||
event_control_list: { event: getEventInfo(isForte) }, // Forte
|
event_control_list: { event: getEventInfo(version) }, // Forte
|
||||||
music_list: {
|
music_list: {
|
||||||
flag: music_list,
|
flag: music_list,
|
||||||
},
|
},
|
||||||
|
|
@ -170,17 +167,17 @@ const getPlayerData = async (refid: string, info: EamuseInfo, name?: string) =>
|
||||||
flag: music_list2,
|
flag: music_list2,
|
||||||
},
|
},
|
||||||
last: {
|
last: {
|
||||||
music_index: K.ITEM('s32', forteNumericHandler(isForte, p.music, 195, 0)),
|
music_index: K.ITEM('s32', version.numericHandler('music_index', p.music, 0)),
|
||||||
sheet_type: K.ITEM('s8', forteNumericHandler(isForte, p.sheet, 3, 0)),
|
sheet_type: K.ITEM('s8', version.numericHandler('sheet_type', p.sheet, 0)),
|
||||||
brooch_index: K.ITEM('s32', forteNumericHandler(isForte, p.brooch, 147, 0)),
|
brooch_index: K.ITEM('s32', version.numericHandler('brooch_index', p.brooch, 0)),
|
||||||
hi_speed_level: K.ITEM('s32', p.hispeed),
|
hi_speed_level: K.ITEM('s32', p.hispeed),
|
||||||
beat_guide: K.ITEM('s8', p.beatGuide),
|
beat_guide: K.ITEM('s8', p.beatGuide),
|
||||||
headphone_volume: K.ITEM('s8', p.headphone),
|
headphone_volume: K.ITEM('s8', p.headphone),
|
||||||
judge_bar_pos: K.ITEM('s32', p.judgeBar),
|
judge_bar_pos: K.ITEM('s32', p.judgeBar),
|
||||||
music_group: K.ITEM('s32', p.group),
|
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),
|
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),
|
bingo_index: K.ITEM('s32', p.bingo),
|
||||||
total_skill_value: K.ITEM('u64', BigInt(p.skill)),
|
total_skill_value: K.ITEM('u64', BigInt(p.skill)),
|
||||||
key_beam_level: K.ITEM('s8', p.keyBeam),
|
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');
|
const refid = $(data).str('refid');
|
||||||
if (!refid) return send.deny();
|
if (!refid) return send.deny();
|
||||||
|
|
||||||
const isForte = !info.module.includes("op")
|
const isForte = new NosVersionHelper(info).isFirstOrForte()
|
||||||
const p = await readProfile(refid);
|
const p = await readProfile(refid);
|
||||||
|
|
||||||
p.playCount = $(data).number('play_count', p.playCount);
|
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');
|
const refid = $(data).str('refid');
|
||||||
if (!refid) return send.deny();
|
if (!refid) return send.deny();
|
||||||
|
|
||||||
const isForte = !info.module.includes("op")
|
const version = new NosVersionHelper(info)
|
||||||
const scoreData = await readScores(refid);
|
const scoreData = await readScores(refid);
|
||||||
|
|
||||||
const recital_record: any[] = [];
|
const recital_record: any[] = [];
|
||||||
|
|
@ -499,7 +496,7 @@ export const get_musicdata: EPR = async (info, data, send) => {
|
||||||
const mdata = m.split(':');
|
const mdata = m.split(':');
|
||||||
const musi = scoreData.scores[m];
|
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.push(K.ATTR({
|
||||||
music_index: mdata[0],
|
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> {
|
async function readProfile(refid: string): Promise<Profile> {
|
||||||
const profile = await DB.FindOne<Profile>(refid, { collection: 'profile' })
|
const profile = await DB.FindOne<Profile>(refid, { collection: 'profile' })
|
||||||
return profile || defaultProfile
|
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_common_info, get_music_info } from "./handler/common";
|
||||||
import { get_musicdata, get_playdata, regist_playdata, set_total_result } from "./handler/player"
|
import { get_musicdata, get_playdata, regist_playdata, set_total_result } from "./handler/player"
|
||||||
|
import { fixIndexBug } from "./handler/webui";
|
||||||
|
|
||||||
export function register() {
|
export function register() {
|
||||||
R.GameCode('PAN');
|
R.GameCode('PAN');
|
||||||
|
|
||||||
|
R.WebUIEvent("nosFixIndexBug", fixIndexBug)
|
||||||
|
|
||||||
const MultiRoute = (method: string, handler: EPR | boolean) => {
|
const MultiRoute = (method: string, handler: EPR | boolean) => {
|
||||||
// Helper for register multiple versions.
|
// Helper for register multiple versions.
|
||||||
R.Route(method, handler); // First version and Forte.
|
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