mirror of
https://github.com/asphyxia-core/plugins.git
synced 2026-03-21 17:34:46 -05:00
Add support for Hello! Pop'n Music.
This commit is contained in:
parent
7e52d72c26
commit
13aaaca1b2
7
popn-hello@asphyxia/README.md
Normal file
7
popn-hello@asphyxia/README.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
Hello! Pop'n Music
|
||||
==================
|
||||
|
||||
This plugin supports _Hello! Pop'n Music_.
|
||||
|
||||
# ! IMPORTANT !
|
||||
You may need proper data to connect a network. Otherwise, it won't work!
|
||||
161
popn-hello@asphyxia/handler/player.ts
Normal file
161
popn-hello@asphyxia/handler/player.ts
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
import { Profile } from '../models/profile';
|
||||
import { Scores } from '../models/scores';
|
||||
|
||||
export const newProfile: EPR = async (req, data, send) => {
|
||||
const refid = $(data).attr().refid;
|
||||
if (!refid) return send.deny();
|
||||
|
||||
await writeProfile(refid, await readProfile(refid));
|
||||
send.success();
|
||||
};
|
||||
|
||||
export const load: EPR = async (req, data, send) => {
|
||||
try{
|
||||
const refid = $(data).attr().refid;
|
||||
if (!refid) return send.deny();
|
||||
|
||||
const profile = await readProfile(refid);
|
||||
const chara: any[] = [];
|
||||
|
||||
if (profile.unlockAll) {
|
||||
for (let i = 0; i < 11; ++i) {
|
||||
chara.push(K.ATTR({ id: `${i}`, love: '5' }));
|
||||
}
|
||||
} else {
|
||||
for (const i in profile.charas) {
|
||||
chara.push(K.ATTR({ id: `${i}`, love: `${profile.charas[i]}` }));
|
||||
}
|
||||
}
|
||||
|
||||
send.object({
|
||||
last: K.ATTR({
|
||||
chara: `${profile.history.chara}`,
|
||||
level: `${profile.history.level}`,
|
||||
music_id: `${profile.history.mid}`,
|
||||
style: `${profile.history.style}`,
|
||||
}),
|
||||
chara,
|
||||
// threshold: {
|
||||
// '@attr': { id: 0, point: 100 },
|
||||
// },
|
||||
})
|
||||
} catch (e) { console.log(e.stack || e.stacktrace )}
|
||||
};
|
||||
|
||||
export const load_m: EPR = async (req, data, send) => {
|
||||
const refid = $(data).attr().refid;
|
||||
if (!refid) return send.deny();
|
||||
|
||||
const scores = (await readScores(refid)).scores;
|
||||
|
||||
const music: any[] = [];
|
||||
for (const mid in scores) {
|
||||
const style: any[] = [];
|
||||
for (const sid in scores[mid]) {
|
||||
const level: any[] = [];
|
||||
for (const lid in scores[mid][sid]) {
|
||||
level.push(K.ATTR({
|
||||
id: lid,
|
||||
score: `${scores[mid][sid][lid].score}`,
|
||||
clear_type: `${scores[mid][sid][lid].clear}`,
|
||||
}),
|
||||
);
|
||||
}
|
||||
style.push(K.ATTR({ id: sid }, { level }));
|
||||
}
|
||||
music.push(K.ATTR({ music_id: mid }, { style }));
|
||||
}
|
||||
|
||||
send.object({
|
||||
music,
|
||||
});
|
||||
};
|
||||
|
||||
export const save_m: EPR = async (req, data, send) => {
|
||||
const refid = $(data).attr().refid;
|
||||
if (!refid) return send.deny();
|
||||
|
||||
const scores = (await readScores(refid)).scores;
|
||||
|
||||
const clear = parseInt($(data).attr().clear_type || '-1');
|
||||
const level = parseInt($(data).attr().level || '-1');
|
||||
const mid = parseInt($(data).attr().music_id || '-1');
|
||||
const score = parseInt($(data).attr().score || '-1');
|
||||
const style = parseInt($(data).attr().style || '-1');
|
||||
|
||||
if (clear < 0 || level < 0 || mid < 0 || score < 0 || style < 0) {
|
||||
return send.success();
|
||||
}
|
||||
|
||||
if (!scores[mid]) {
|
||||
scores[mid] = {};
|
||||
}
|
||||
|
||||
if (!scores[mid][style]) {
|
||||
scores[mid][style] = {};
|
||||
}
|
||||
|
||||
scores[mid][style][level] = {
|
||||
score: Math.max(_.get(scores[mid][style][level], 'score', 0), score),
|
||||
clear: Math.max(_.get(scores[mid][style][level], 'clear', 0), clear),
|
||||
};
|
||||
|
||||
writeScores(refid, { collection: 'scores', scores });
|
||||
|
||||
send.success();
|
||||
};
|
||||
|
||||
export const save: EPR = async (req, data, send) => {
|
||||
const refid = $(data).attr().refid;
|
||||
if (!refid) return send.deny();
|
||||
|
||||
const profile = await readProfile(refid);
|
||||
|
||||
const chara = parseInt($(data).attr('last').chara || '-1');
|
||||
const level = parseInt($(data).attr('last').level || '-1');
|
||||
const love = parseInt($(data).attr('last').love || '-1');
|
||||
const mid = parseInt($(data).attr('last').music_id || '-1');
|
||||
const style = parseInt($(data).attr('last').style || '-1');
|
||||
|
||||
if (chara < 0 || level < 0 || mid < 0 || love < 0 || style < 0) {
|
||||
return send.success();
|
||||
}
|
||||
|
||||
if (!profile.unlockAll) {
|
||||
profile.charas[chara] = _.get(profile.charas, chara, 0) + love;
|
||||
}
|
||||
|
||||
profile.history = {
|
||||
chara,
|
||||
mid,
|
||||
level,
|
||||
style,
|
||||
};
|
||||
|
||||
await writeProfile(refid, profile);
|
||||
|
||||
send.success();
|
||||
};
|
||||
|
||||
async function readProfile(refid: string): Promise<Profile> {
|
||||
const profile = await DB.FindOne<Profile>(refid, { collection: 'profile'} )
|
||||
return profile || {
|
||||
collection: 'profile',
|
||||
unlockAll: false,
|
||||
history: { chara: 0, level: 0, mid: 0, style: 0 },
|
||||
charas: {},
|
||||
}
|
||||
}
|
||||
|
||||
async function writeProfile(refid: string, profile: Profile) {
|
||||
await DB.Upsert<Profile>(refid, { collection: 'profile'}, profile)
|
||||
}
|
||||
|
||||
async function readScores(refid: string): Promise<Scores> {
|
||||
const score = await DB.FindOne<Scores>(refid, { collection: 'scores'} )
|
||||
return score || { collection: 'scores', scores: {}}
|
||||
}
|
||||
|
||||
async function writeScores(refid: string, scores: Scores) {
|
||||
await DB.Upsert<Scores>(refid, { collection: 'scores'}, scores)
|
||||
}
|
||||
15
popn-hello@asphyxia/handler/webui.ts
Normal file
15
popn-hello@asphyxia/handler/webui.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { Profile } from "../models/profile";
|
||||
|
||||
export const setUnlockState = async (data: {
|
||||
refid: string;
|
||||
unlock_all: string;
|
||||
}) => {
|
||||
await DB.Update<Profile>(
|
||||
data.refid,
|
||||
{ collection: 'profile' },
|
||||
{ $set: {
|
||||
unlockAll: data.unlock_all == "on"
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
39
popn-hello@asphyxia/index.ts
Normal file
39
popn-hello@asphyxia/index.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import { load, load_m, newProfile, save, save_m } from "./handler/player";
|
||||
import { setUnlockState } from "./handler/webui";
|
||||
|
||||
const common: EPR = async (req, data, send) => {
|
||||
send.object(
|
||||
{
|
||||
flag: K.ATTR({ id: '1', s1: '1', s2: '1', t: '1' }),
|
||||
cnt_music: K.ITEM('u32', 36),
|
||||
},
|
||||
{ encoding: 'euc-jp' }
|
||||
);
|
||||
};
|
||||
|
||||
const shop: EPR = async (req, data, send) => {
|
||||
send.success()
|
||||
}
|
||||
|
||||
export function register() {
|
||||
R.GameCode("JMP")
|
||||
|
||||
R.WebUIEvent("setUnlockState", setUnlockState)
|
||||
|
||||
// const Route = (method: string, handler: EPR) =>
|
||||
// R.Route(`game.${method}`, handler)
|
||||
|
||||
// Common
|
||||
R.Route("game.common", common)
|
||||
R.Route("game.shop", shop)
|
||||
|
||||
// Player
|
||||
R.Route("game.new", newProfile)
|
||||
R.Route("game.load", load)
|
||||
R.Route("game.load_m", load_m)
|
||||
R.Route("game.save", save)
|
||||
R.Route("game.save_m", save_m)
|
||||
|
||||
|
||||
R.Unhandled()
|
||||
}
|
||||
12
popn-hello@asphyxia/models/profile.ts
Normal file
12
popn-hello@asphyxia/models/profile.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
export interface Profile {
|
||||
collection: 'profile',
|
||||
|
||||
unlockAll: boolean;
|
||||
history: {
|
||||
chara: number;
|
||||
level: number;
|
||||
mid: number;
|
||||
style: number;
|
||||
};
|
||||
charas: { [id: string]: number };
|
||||
}
|
||||
14
popn-hello@asphyxia/models/scores.ts
Normal file
14
popn-hello@asphyxia/models/scores.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
export interface Scores {
|
||||
collection: 'scores',
|
||||
|
||||
scores: {
|
||||
[mid: string]: {
|
||||
[style: string]: {
|
||||
[level: string]: {
|
||||
score: number;
|
||||
clear: number;
|
||||
};
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
26
popn-hello@asphyxia/webui/profile_unlock.pug
Normal file
26
popn-hello@asphyxia/webui/profile_unlock.pug
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
//DATA//
|
||||
profile: DB.FindOne(refid, { collection: 'profile' })
|
||||
|
||||
div
|
||||
.card
|
||||
.card-header
|
||||
p.card-header-title
|
||||
span.icon
|
||||
i.mdi.mdi-account-edit
|
||||
| Detail Change
|
||||
.card-content
|
||||
form(method="post" action="/emit/setUnlockState")
|
||||
.field
|
||||
label.label ID
|
||||
.control
|
||||
input.input(type="text" name="refid", value=refid readonly)
|
||||
.field
|
||||
label.label Unlock All
|
||||
.control
|
||||
input(type="checkbox" name="unlock_all", checked=profile.unlockAll)
|
||||
| Turn this on to max out all characters and unlock 11 hidden songs.
|
||||
.field
|
||||
button.button.is-primary(type="submit")
|
||||
span.icon
|
||||
i.mdi.mdi-check
|
||||
span Submit
|
||||
Loading…
Reference in New Issue
Block a user