plugins/museca@asphyxia/handlers/player.ts

223 lines
6.6 KiB
TypeScript

import { Profile } from "../models/profile";
import { Scores } from "../models/scores";
import { IDToCode } from "../utils";
export const load: EPR = async (info, data, send) => {
const refid = $(data).str('refid');
if (!refid) return send.deny();
const profile = await DB.FindOne<Profile>(refid, { collection: "profile" })
if (profile == null) {
// Request New Profile from game side.
return send.object({
result: K.ITEM("u8", 1)
})
}
const item = _.map(profile.item, (v, k) => {
const id = k.replace("g", "")
return {
type: K.ITEM("u8", v.type),
id: K.ITEM("u32", parseInt(id)),
param: K.ITEM("u32", v.param)
}
})
send.object({
hidden_param: K.ARRAY("s32", profile.hidden_param),
play_count: K.ITEM("u32", profile.play_count),
daily_count: K.ITEM("u32", profile.daily_count),
play_chain: K.ITEM("u32", profile.play_chain),
last: {
headphone: K.ITEM("u8", profile.last.headphone),
appeal_id: K.ITEM("u16", profile.last.appeal_id),
comment_id: K.ITEM("u16", profile.last.comment_id),
music_id: K.ITEM("s32", profile.last.music_id),
music_type: K.ITEM("u8", profile.last.music_type),
sort_type: K.ITEM("u8", profile.last.sort_type),
narrow_down: K.ITEM("u8", profile.last.narrow_down),
gauge_option: K.ITEM("u8", profile.last.gauge_option),
},
blaster_energy: K.ITEM("u32", profile.blaster_energy),
blaster_count: K.ITEM("u32", profile.blaster_count),
code: K.ITEM("str", IDToCode(profile.code)),
name: K.ITEM("str", profile.name),
creator_id: K.ITEM("u32", profile.creator_id),
skill_level: K.ITEM("s16", profile.skill_level),
skill_name_id: K.ITEM("s16", profile.skill_name_id),
gamecoin_packet: K.ITEM("u32", profile.gamecoin_packet),
gamecoin_block: K.ITEM("u32", profile.gamecoin_block),
item: {
info: item
},
param: {},
result: K.ITEM("u8", 0),
ea_shop: {
packet_booster: K.ITEM("s32", 0),
block_booster: K.ITEM("s32", 0)
}
})
}
export const load_m: EPR = async (info, data, send) => {
const refid = $(data).str('dataid');
if (!refid) return send.deny();
const scores = (await DB.FindOne<Scores>(refid, { collection: 'scores'})).scores
const music: any[] = [];
for (const mid in scores) {
for (const type in scores[mid]) {
let score = scores[mid][type]
music.push({
music_id: K.ITEM("u32", parseInt(mid)),
music_type: K.ITEM("u32", parseInt(type)),
score: K.ITEM("u32", score.score),
cnt: K.ITEM("u32", score.count),
clear_type: K.ITEM("u32", score.clear_type),
score_grade: K.ITEM("u32", score.score_grade),
btn_rate: K.ITEM("u32", score.btn_rate),
long_rate: K.ITEM("u32", score.long_rate),
vol_rate: K.ITEM("u32", score.vol_rate)
})
};
};
send.object({
new: {
music
},
// This field seems used on Museca 1, Ignore this.
old: {}
})
}
export const save: EPR = async (info, data, send) => {
const refid = $(data).str('refid');
if (!refid) return send.deny();
const dbItem = (await DB.FindOne<Profile>(refid, { collection: "profile" })).item
for(const item of $(data).elements("item.info")) {
const id = item.number("id");
const type = item.number("type")
// Grafica and Mission shares same ID. Why?????
dbItem[type == 16 ? `g${id}` : id] = {
type,
param : item.number("param")
}
}
await DB.Upsert<Profile>(refid, { collection: "profile" }, {
$set: {
last: {
headphone: $(data).number("headphone"),
appeal_id: $(data).number("appeal_id"),
comment_id: $(data).number("comment_id"),
music_id: $(data).number("music_id"),
music_type: $(data).number("music_type"),
sort_type: $(data).number("sort_type"),
narrow_down: $(data).number("narrow_down"),
gauge_option: $(data).number("gauge_option"),
},
hidden_param: $(data).numbers("hidden_param"),
blaster_count: $(data).number("blaster_count"),
item: dbItem,
},
$inc: {
blaster_energy: $(data).number("earned_blaster_energy"),
gamecoin_block: $(data).number("earned_gamecoin_block"),
gamecoin_packet: $(data).number("earned_gamecoin_packet")
}
})
send.success()
}
export const save_m: EPR = async (info, data, send) => {
const refid = $(data).str('refid');
if (!refid) return send.deny();
const scores = (await DB.FindOne<Scores>(refid, { collection: "scores" })).scores
const mid = $(data).number("music_id")
const type = $(data).number("music_type")
if (!scores[mid]) {
scores[mid] = {};
}
scores[mid][type] = {
score: Math.max(_.get(scores[mid][type], 'score', 0), $(data).number("score")),
clear_type: Math.max(_.get(scores[mid][type], 'clear_type', 0), $(data).number("clear_type")),
score_grade: Math.max(_.get(scores[mid][type], 'score_grade', 0), $(data).number("score_grade")),
count: _.get(scores[mid][type], 'count', 0) + 1,
btn_rate: Math.max(_.get(scores[mid][type], 'btn_rate', 0), $(data).number("btn_rate")),
long_rate: Math.max(_.get(scores[mid][type], 'long_rate', 0), $(data).number("long_rate")),
vol_rate: Math.max(_.get(scores[mid][type], 'vol_rate', 0), $(data).number("vol_rate")),
};
const store: Scores = {
collection: "scores",
scores
}
await DB.Upsert<Scores>(refid, { collection: "scores" }, store)
send.success()
}
export const newProfile: EPR = async (info, data, send) => {
const refid = $(data).str('refid');
if (!refid) return send.deny();
const name = $(data).str('name', 'NONAME');
let code = _.random(0, 99999999);
while (await DB.FindOne<Profile>(null, { collecttion: 'profile', code })) {
code = _.random(0, 99999999);
}
let defItem = {};
for(let i = 1; i < 801; i++) {
defItem[i] = {
type: 4,
param : 1
}
}
const profile: Profile = {
collection: "profile",
code,
name,
hidden_param: Array(20).fill(0),
play_count: 0,
daily_count: 0,
play_chain: 0,
last: {
headphone: 0,
appeal_id: 0,
comment_id: 0,
music_id: 0,
music_type: 0,
sort_type: 0,
narrow_down: 0,
gauge_option: 0,
},
blaster_energy: 0,
blaster_count: 0,
creator_id: 0,
skill_level: 0,
skill_name_id: 0,
gamecoin_packet: 0,
gamecoin_block: 0,
item: defItem,
packet_booster: 0,
block_booster: 0,
}
await DB.Upsert<Profile>(refid, { collection: "profile"}, profile)
await DB.Upsert<Scores>(refid, { collection: "scores" }, { collection: "scores", scores: {}})
send.success()
}