From c3119b6e4bcaeeee24d55c843ff7fbd740ed3194 Mon Sep 17 00:00:00 2001 From: cracrayol Date: Thu, 15 Apr 2021 23:45:06 +0200 Subject: [PATCH 1/4] Add rivals support for Lapistoria-peace Fix stamp not properly initialized on usaneko --- popn@asphyxia/README.md | 6 +- popn@asphyxia/handler/eclale.ts | 91 ++++++++++++++++++++-------- popn@asphyxia/handler/lapistoria.ts | 68 ++++++++++++++++++++- popn@asphyxia/handler/usaneko.ts | 91 +++++++++++++++++++++------- popn@asphyxia/handler/utils.ts | 7 ++- popn@asphyxia/index.ts | 27 ++++++++- popn@asphyxia/models/common.ts | 5 ++ popn@asphyxia/webui/profile_page.pug | 39 ++++++++++++ 8 files changed, 280 insertions(+), 54 deletions(-) diff --git a/popn@asphyxia/README.md b/popn@asphyxia/README.md index bdbca7c..da82e43 100644 --- a/popn@asphyxia/README.md +++ b/popn@asphyxia/README.md @@ -1,6 +1,6 @@ # Pop'n Music -Plugin Version: **v2.0.0** +Plugin Version: **v2.1.0** ## Supported Versions - pop'n music 19 Tune Street @@ -15,6 +15,10 @@ Important : require minimum Asphyxia Core **v1.31** ## Changelog +### 2.1.0 +* Add rivals support +* Various fixes + ### 2.0.0 * Big rewrite/reorganization of the code * Add support for Tune Street, fantasia, Sunny Park, Lapistoria diff --git a/popn@asphyxia/handler/eclale.ts b/popn@asphyxia/handler/eclale.ts index 6d071eb..9f68537 100644 --- a/popn@asphyxia/handler/eclale.ts +++ b/popn@asphyxia/handler/eclale.ts @@ -11,6 +11,7 @@ export const setRoutes = () => { R.Route(`player23.read_score`, readScore); R.Route(`player23.write_music`, writeScore); R.Route(`player23.write`, write); + R.Route(`player23.friend`, friend); } const getInfoCommon = (req: EamuseInfo) => { @@ -130,16 +131,31 @@ const readScore = async (req: EamuseInfo, data: any, send: EamuseSend): Promise< const refid = $(data).str('ref_id'); if (!refid) return send.deny(); + send.object({ music: await getScores(refid, version) }); +}; + +const getScores = async (refid: string, version: string, forFriend: boolean = false) => { const scoresData = await utils.readScores(refid, version); - const result: any = { - music: [], - }; + const result = []; for (const key in scoresData.scores) { const keyData = key.split(':'); const score = scoresData.scores[key]; const music = parseInt(keyData[0], 10); const sheet = parseInt(keyData[1], 10); + const clearType = { + 100: 1, + 200: 2, + 300: 3, + 400: 4, + 500: 5, + 600: 6, + 700: 7, + 800: 8, + 900: 9, + 1000: 10, + 1100: 11, + }[score.clear_type]; if (music > GAME_MAX_MUSIC_ID) { continue; @@ -148,28 +164,24 @@ const readScore = async (req: EamuseInfo, data: any, send: EamuseSend): Promise< continue; } - result.music.push({ - music_num: K.ITEM('s16', music), - sheet_num: K.ITEM('u8', sheet), - score: K.ITEM('s32', score.score), - clear_type: K.ITEM('u8', { - 100: 1, - 200: 2, - 300: 3, - 400: 4, - 500: 5, - 600: 6, - 700: 7, - 800: 8, - 900: 9, - 1000: 10, - 1100: 11, - }[score.clear_type]), - cnt: K.ITEM('s16', score.cnt), - }); + if(forFriend) { + result.push(K.ATTR({ + music_num: music.toString(), + sheet_num: sheet.toString(), + score: score.score.toString(), + clearmedal: clearType.toString() + })); + } else { + result.push({ + music_num: K.ITEM('s16', music), + sheet_num: K.ITEM('u8', sheet), + score: K.ITEM('s32', score.score), + clear_type: K.ITEM('u8', clearType), + cnt: K.ITEM('s16', score.cnt), + }); + } } - - send.object(result); + return result; }; const writeScore = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { @@ -223,6 +235,7 @@ const writeScore = async (req: EamuseInfo, data: any, send: EamuseSend): Promise */ const getProfile = async (refid: string, name?: string) => { const profile = await utils.readProfile(refid); + const rivals = await utils.readRivals(refid); if (name && name.length > 0) { profile.name = name; @@ -261,6 +274,7 @@ const getProfile = async (refid: string, name?: string) => { is_conv: K.ITEM('s8', 0), meteor_flg: K.ITEM('bool', true), license_data: K.ARRAY('s16', Array(20).fill(-1)), + active_fr_num: K.ITEM('u8', rivals.rivals.length), // TODO: replace with real data total_play_cnt: K.ITEM('s16', 100), @@ -270,7 +284,6 @@ const getProfile = async (refid: string, name?: string) => { interval_day: K.ITEM('s16', 1), my_best: K.ARRAY('s16', myBest), latest_music: K.ARRAY('s16', [-1, -1, -1, -1, -1]), - active_fr_num: K.ITEM('u8', 0), }, netvs: { record: K.ARRAY('s16', [0, 0, 0, 0, 0, 0]), @@ -424,6 +437,34 @@ const write = async (req: EamuseInfo, data: any, send: EamuseSend): Promise send.success(); }; +const friend = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { + const refid = $(data).attr()['ref_id']; + const no = parseInt($(data).attr()['no'], -1); + + const rivals = await utils.readRivals(refid); + + if(no < 0 || no >= rivals.rivals.length) { + send.object({result : K.ITEM('s8', 2)}); + return; + } + + const profile = await utils.readProfile(rivals.rivals[no]); + const params = await utils.readParams(rivals.rivals[no], version); + + const friend = { + friend: { + no: K.ITEM('s16', no), + g_pm_id: K.ITEM('str', 'ASPHYXIAPLAY'), + name: K.ITEM('str', profile.name), + chara: K.ITEM('s16', params.params.chara || -1), + is_open: K.ITEM('s8', 1), + music : await getScores(rivals.rivals[no], version, true), + } + } + + send.object(friend); +} + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const version: string = 'v23'; diff --git a/popn@asphyxia/handler/lapistoria.ts b/popn@asphyxia/handler/lapistoria.ts index 3828500..aa65e7d 100644 --- a/popn@asphyxia/handler/lapistoria.ts +++ b/popn@asphyxia/handler/lapistoria.ts @@ -8,6 +8,7 @@ export const setRoutes = () => { R.Route(`player22.read`, read); R.Route(`player22.write_music`, writeScore); R.Route(`player22.write`, write); + R.Route(`player22.friend`, friend); } /** @@ -110,6 +111,7 @@ const writeScore = async (req: EamuseInfo, data: any, send: EamuseSend): Promise */ const getProfile = async (refid: string, name?: string) => { const profile = await utils.readProfile(refid); + const rivals = await utils.readRivals(refid); if (name && name.length > 0) { profile.name = name; @@ -126,6 +128,7 @@ const getProfile = async (refid: string, name?: string) => { item_type: K.ITEM('s16', 0), item_id: K.ITEM('s16', 0), license_data: K.ARRAY('s16', [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1]), + active_fr_num: K.ITEM('u8', rivals.rivals.length), // TODO: replace with real data total_play_cnt: K.ITEM('s16', 100), @@ -134,7 +137,6 @@ const getProfile = async (refid: string, name?: string) => { total_days: K.ITEM('s16', 366), interval_day: K.ITEM('s16', 1), latest_music: K.ARRAY('s16', [-1, -1, -1, -1, -1]), - active_fr_num: K.ITEM('u8', 0), }, netvs: { rank_point: K.ITEM('s32', 0), @@ -372,6 +374,70 @@ const write = async (req: EamuseInfo, data: any, send: EamuseSend): Promise send.success(); }; +const friend = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { + const refid = $(data).attr()['ref_id']; + const no = parseInt($(data).attr()['no'], -1); + + const rivals = await utils.readRivals(refid); + + if(no < 0 || no >= rivals.rivals.length) { + send.object({result : K.ITEM('s8', 2)}); + return; + } + + const profile = await utils.readProfile(rivals.rivals[no]); + const params = await utils.readParams(rivals.rivals[no], version); + + // Add Score + const scoresData = await utils.readScores(rivals.rivals[no], version); + const scores = []; + for (const key in scoresData.scores) { + const keyData = key.split(':'); + const score = scoresData.scores[key]; + const music = parseInt(keyData[0], 10); + const sheet = parseInt(keyData[1], 10); + + if (music > GAME_MAX_MUSIC_ID) { + continue; + } + if ([0, 1, 2, 3].indexOf(sheet) == -1) { + continue; + } + + scores.push(K.ATTR({ + music_num: music.toString(), + sheet_num: sheet.toString(), + score: score.score.toString(), + clearmedal: { + 100: 1, + 200: 2, + 300: 3, + 400: 4, + 500: 5, + 600: 6, + 700: 7, + 800: 8, + 900: 9, + 1000: 10, + 1100: 11, + }[score.clear_type].toString(), + })); + } + + const friend = { + friend: { + no: K.ITEM('s16', no), + g_pm_id: K.ITEM('str', 'ASPHYXIAPLAY'), + name: K.ITEM('str', profile.name), + chara: K.ITEM('s16', params.params.chara || -1), + is_open: K.ITEM('s8', 1), + music: scores, + } + } + + send.object(friend); +} + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const version: string = 'v22'; diff --git a/popn@asphyxia/handler/usaneko.ts b/popn@asphyxia/handler/usaneko.ts index 783ec17..08e4dfe 100644 --- a/popn@asphyxia/handler/usaneko.ts +++ b/popn@asphyxia/handler/usaneko.ts @@ -11,6 +11,7 @@ export const setRoutes = () => { R.Route(`player24.read_score`, readScore); R.Route(`player24.write_music`, writeScore); R.Route(`player24.write`, write); + R.Route(`player24.friend`, friend); } const getInfoCommon = (req: EamuseInfo) => { @@ -148,7 +149,7 @@ const readScore = async (req: EamuseInfo, data: any, send: EamuseSend): Promise< send.object({ music: await getScores(refid, version) }); }; -const getScores = async (refid: string, version: string) => { +const getScores = async (refid: string, version: string, forFriend: boolean = false) => { const scoresData = await utils.readScores(refid, version); const result = []; @@ -157,6 +158,19 @@ const getScores = async (refid: string, version: string) => { const score = scoresData.scores[key]; const music = parseInt(keyData[0], 10); const sheet = parseInt(keyData[1], 10); + const clearType = { + 100: 1, + 200: 2, + 300: 3, + 400: 4, + 500: 5, + 600: 6, + 700: 7, + 800: 8, + 900: 9, + 1000: 10, + 1100: 11, + }[score.clear_type]; if (music > GAME_MAX_MUSIC_ID[version]) { continue; @@ -165,26 +179,24 @@ const getScores = async (refid: string, version: string) => { continue; } - result.push({ - music_num: K.ITEM('s16', music), - sheet_num: K.ITEM('u8', sheet), - score: K.ITEM('s32', score.score), - clear_type: K.ITEM('u8', { - 100: 1, - 200: 2, - 300: 3, - 400: 4, - 500: 5, - 600: 6, - 700: 7, - 800: 8, - 900: 9, - 1000: 10, - 1100: 11, - }[score.clear_type]), - clear_rank: K.ITEM('u8', getRank(score.score)), - cnt: K.ITEM('s16', score.cnt), - }); + if(forFriend) { + result.push(K.ATTR({ + music_num: music.toString(), + sheet_num: sheet.toString(), + score: score.score.toString(), + cleartype: clearType.toString(), + clearrank: getRank(score.score).toString() + })); + } else { + result.push({ + music_num: K.ITEM('s16', music), + sheet_num: K.ITEM('u8', sheet), + score: K.ITEM('s32', score.score), + clear_type: K.ITEM('u8', clearType), + clear_rank: K.ITEM('u8', getRank(score.score)), + cnt: K.ITEM('s16', score.cnt), + }); + } } return result; @@ -261,6 +273,7 @@ const writeScore = async (req: EamuseInfo, data: any, send: EamuseSend): Promise */ const getProfile = async (refid: string, version: string, name?: string) => { const profile = await utils.readProfile(refid); + const rivals = await utils.readRivals(refid); if (name && name.length > 0) { profile.name = name; @@ -299,6 +312,7 @@ const getProfile = async (refid: string, version: string, name?: string) => { is_conv: K.ITEM('s8', 0), license_data: K.ARRAY('s16', Array(20).fill(-1)), my_best: K.ARRAY('s16', myBest), + active_fr_num: K.ITEM('u8', rivals.rivals.length), // TODO: replace with real data total_play_cnt: K.ITEM('s16', 100), @@ -307,7 +321,6 @@ const getProfile = async (refid: string, version: string, name?: string) => { total_days: K.ITEM('s16', 366), interval_day: K.ITEM('s16', 1), latest_music: K.ARRAY('s16', [-1, -1, -1, -1, -1]), - active_fr_num: K.ITEM('u8', 0), }, netvs: { record: K.ARRAY('s16', [0, 0, 0, 0, 0, 0]), @@ -381,7 +394,10 @@ const getProfile = async (refid: string, version: string, name?: string) => { }); } - const profileStamps = achievements.stamps || { '0': 0 }; + let profileStamps = achievements.stamps; + if(Object.entries(profileStamps).length == 0) { + profileStamps = {"0": 0 }; + } for (const stamp_id in profileStamps) { player.stamp.push({ stamp_id: K.ITEM('s16', parseInt(stamp_id, 10)), @@ -595,6 +611,35 @@ const write = async (req: EamuseInfo, data: any, send: EamuseSend): Promise send.success(); }; +const friend = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { + const refid = $(data).attr()['ref_id']; + const no = parseInt($(data).attr()['no'], -1); + const version = getVersion(req); + + const rivals = await utils.readRivals(refid); + + if(no < 0 || no >= rivals.rivals.length) { + send.object({result : K.ITEM('s8', 2)}); + return; + } + + const profile = await utils.readProfile(rivals.rivals[no]); + const params = await utils.readParams(rivals.rivals[no], version); + + const friend = { + friend: { + no: K.ITEM('s16', no), + g_pm_id: K.ITEM('str', 'ASPHYXIAPLAY'), + name: K.ITEM('str', profile.name), + chara: K.ITEM('s16', params.params.chara || -1), + is_open: K.ITEM('s8', 1), + music : await getScores(rivals.rivals[no], version, true), + } + } + + send.object(friend); +} + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const getVersion = (req: EamuseInfo): string => { diff --git a/popn@asphyxia/handler/utils.ts b/popn@asphyxia/handler/utils.ts index a742bdd..53c7654 100644 --- a/popn@asphyxia/handler/utils.ts +++ b/popn@asphyxia/handler/utils.ts @@ -1,5 +1,5 @@ import { Achievements } from "../models/achievements"; -import { Profile, Scores, ExtraData, Params } from "../models/common"; +import { Profile, Scores, ExtraData, Params, Rivals } from "../models/common"; const CURRENT_DATA_VERSION = 2; @@ -68,6 +68,11 @@ export const writeProfile = async (refid: string, profile: Profile) => { await DB.Upsert(refid, { collection: 'profile' }, profile); } +export const readRivals = async (refid: string): Promise => { + const rivals = await DB.FindOne(refid, { collection: 'rivals' }); + return rivals || { collection: 'rivals', rivals: [] }; +} + export const readParams = async (refid: string, version: string): Promise => { const params = await DB.FindOne(refid, { collection: 'params', version }); return params || { collection: 'params', version, params: {} }; diff --git a/popn@asphyxia/index.ts b/popn@asphyxia/index.ts index 12a6877..5d3d639 100644 --- a/popn@asphyxia/index.ts +++ b/popn@asphyxia/index.ts @@ -5,6 +5,7 @@ import * as lapistoria from "./handler/lapistoria"; import * as eclale from "./handler/eclale"; import * as usaneko from "./handler/usaneko"; import { importPnmData } from "./handler/webui"; +import { Rivals } from "./models/common"; const getVersion = (req: any) => { switch (req.gameCode) { @@ -24,7 +25,7 @@ export function register() { R.Config("enable_score_sharing", { name: "Score sharing", - desc: "Enable sharing scores between versions", + desc: "Enable sharing scores between versions. This also affect rivals scores.", type: "boolean", default: true, }); @@ -35,8 +36,29 @@ export function register() { await DB.Update(data.refid, { collection: 'profile' }, { $set: { name: data.name } }); }); - // Route management for PnM <= 21 + // Rivals UI management + R.WebUIEvent('deleteRival', async (data: any) => { + const rivals = await DB.FindOne(data.refid, { collection: 'rivals' }) || {collection: 'rivals', rivals: []}; + const idx = rivals.rivals.indexOf(data.rivalid); + if(idx >= 0) { + rivals.rivals.splice(idx, 1); + await DB.Update(data.refid, { collection: 'rivals' }, rivals); + } + }); + R.WebUIEvent('addRival', async (data: any) => { + const refid = data.refid.trim(); + const profile = await DB.FindOne(refid, { collection: 'profile'}); + if(profile != undefined && profile != null) { + const rivals = await DB.FindOne(refid, { collection: 'rivals' }) || {collection: 'rivals', rivals: []}; + if(rivals.rivals.length < 4) { + rivals.rivals.push(data.rivalid); + await DB.Upsert(refid, { collection: 'rivals' }, rivals); + } + } + }); + + // Route management for PnM <= 21 R.Route(`game.get`, async (req, data, send) => getVersion(req).getInfo(req, data, send)); R.Route(`playerdata.new`, async (req, data, send) => getVersion(req).newPlayer(req, data, send)); R.Route(`playerdata.conversion`, async (req, data, send) => getVersion(req).newPlayer(req, data, send)); @@ -44,7 +66,6 @@ export function register() { R.Route(`playerdata.set`, async (req, data, send) => getVersion(req).write(req, data, send)); // For Pnm >= 22, each game set his own route - lapistoria.setRoutes(); eclale.setRoutes(); usaneko.setRoutes(); diff --git a/popn@asphyxia/models/common.ts b/popn@asphyxia/models/common.ts index 7bc4d54..b6160f1 100644 --- a/popn@asphyxia/models/common.ts +++ b/popn@asphyxia/models/common.ts @@ -28,6 +28,11 @@ export interface Params { }; } +export interface Rivals { + collection: 'rivals', + rivals: string[] +} + export interface Scores { collection: 'scores', version: string, diff --git a/popn@asphyxia/webui/profile_page.pug b/popn@asphyxia/webui/profile_page.pug index 4190081..3cecda4 100644 --- a/popn@asphyxia/webui/profile_page.pug +++ b/popn@asphyxia/webui/profile_page.pug @@ -1,5 +1,6 @@ //DATA// profile: DB.FindOne(refid, { collection: 'profile' }) + rivals: DB.FindOne(refid, { collection: 'rivals' }) div div.notification.is-success.is-hidden#import-success @@ -23,6 +24,44 @@ div span.icon i.mdi.mdi-check span Submit + .card + .card-header + p.card-header-title + span.icon + i.mdi.mdi-account-edit + | Rivals + .card-content + .columns.is-multiline + if rivals != null + - for (const rival of rivals.rivals) + form(method="post" action="/emit/deleteRival").column.is-4 + .box + input(type="hidden" id="refid" name="refid" value=refid) + input(type="hidden" id="rivalid" name="rivalid" value=rival) + .field + input.input(type="text" value=rival disabled="disabled") + .field + button.button.is-primary + span.icon + i.mdi.mdi-file-import-outline + span Delete + if rivals == null || rivals.rivals.length < 4 + form(method="post" action="/emit/addRival").column.is-4 + .box + input(type="hidden" id="refid" name="refid" value=refid) + .field + input.input(type="text" id="rivalid" name="rivalid" placeholder="Rival ID (ex. AAB56E7436549D83)") + .field + button.button.is-primary + span.icon + i.mdi.mdi-file-import-outline + span Add + div + label To add a rival, use the profile ID located on the POPN Profiles page. + div + label There is a limit of 4 rivals maximum (only the 2 firsts will be used for Sunny Park and lower). + div + label The score sharing option also affect scores get from rivals. .card .card-header p.card-header-title From af7128e3273e3f70b196b55451b4b9dec0234c1e Mon Sep 17 00:00:00 2001 From: cracrayol Date: Thu, 15 Apr 2021 23:47:00 +0200 Subject: [PATCH 2/4] Fix addRival refid check --- popn@asphyxia/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/popn@asphyxia/index.ts b/popn@asphyxia/index.ts index 5d3d639..d7fdbda 100644 --- a/popn@asphyxia/index.ts +++ b/popn@asphyxia/index.ts @@ -48,7 +48,7 @@ export function register() { R.WebUIEvent('addRival', async (data: any) => { const refid = data.refid.trim(); - const profile = await DB.FindOne(refid, { collection: 'profile'}); + const profile = await DB.FindOne(data.rivalid, { collection: 'profile'}); if(profile != undefined && profile != null) { const rivals = await DB.FindOne(refid, { collection: 'rivals' }) || {collection: 'rivals', rivals: []}; if(rivals.rivals.length < 4) { From 84113ca2e27d06619ddd841d791a7a7d01c566b2 Mon Sep 17 00:00:00 2001 From: cracrayol Date: Sat, 17 Apr 2021 00:13:02 +0200 Subject: [PATCH 3/4] Add rivals support for fantasia and sunny park Add comments --- popn@asphyxia/README.md | 4 +- popn@asphyxia/handler/eclale.ts | 46 +++++--- popn@asphyxia/handler/fantasia.ts | 146 +++++++++++++++++--------- popn@asphyxia/handler/lapistoria.ts | 20 ++-- popn@asphyxia/handler/sunny.ts | 156 ++++++++++++++++++---------- popn@asphyxia/handler/tunestreet.ts | 18 +++- popn@asphyxia/handler/usaneko.ts | 55 +++++++--- popn@asphyxia/index.ts | 13 +-- 8 files changed, 309 insertions(+), 149 deletions(-) diff --git a/popn@asphyxia/README.md b/popn@asphyxia/README.md index da82e43..68c2547 100644 --- a/popn@asphyxia/README.md +++ b/popn@asphyxia/README.md @@ -16,8 +16,8 @@ Important : require minimum Asphyxia Core **v1.31** ## Changelog ### 2.1.0 -* Add rivals support -* Various fixes +* Add rivals support (except for Tune Street) +* Some fixes ### 2.0.0 * Big rewrite/reorganization of the code diff --git a/popn@asphyxia/handler/eclale.ts b/popn@asphyxia/handler/eclale.ts index 9f68537..4eb23ef 100644 --- a/popn@asphyxia/handler/eclale.ts +++ b/popn@asphyxia/handler/eclale.ts @@ -14,6 +14,9 @@ export const setRoutes = () => { R.Route(`player23.friend`, friend); } +/** + * Return current state of the game (phase, good prices, etc...) + */ const getInfoCommon = (req: EamuseInfo) => { const result: any = { phase: [], @@ -80,7 +83,7 @@ const start = async (req: EamuseInfo, data: any, send: EamuseSend): Promise }; /** - * Create a new profile and send it. + * Handler for new profile */ const newPlayer = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).str('ref_id'); @@ -92,7 +95,7 @@ const newPlayer = async (req: EamuseInfo, data: any, send: EamuseSend): Promise< }; /** - * Read a profile and send it. + * Handler for existing profile */ const read = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).str('ref_id'); @@ -101,6 +104,9 @@ const read = async (req: EamuseInfo, data: any, send: EamuseSend): Promise send.object(await getProfile(refid)); }; +/** + * Handler fo buying goods with lumina + */ const buy = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).str('ref_id'); if (!refid) return send.deny(); @@ -127,14 +133,22 @@ const buy = async (req: EamuseInfo, data: any, send: EamuseSend): Promise = send.success(); }; +/** + * Handler for getting the user scores + */ const readScore = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).str('ref_id'); if (!refid) return send.deny(); - send.object({ music: await getScores(refid, version) }); + send.object({ music: await getScores(refid) }); }; -const getScores = async (refid: string, version: string, forFriend: boolean = false) => { +/** + * Read the user scores and format them (profile/friend) + * @param refid ID of the user + * @param forFriend If true, format the output for friend request. + */ +const getScores = async (refid: string, forFriend: boolean = false) => { const scoresData = await utils.readScores(refid, version); const result = []; @@ -164,7 +178,7 @@ const getScores = async (refid: string, version: string, forFriend: boolean = fa continue; } - if(forFriend) { + if (forFriend) { result.push(K.ATTR({ music_num: music.toString(), sheet_num: sheet.toString(), @@ -184,6 +198,9 @@ const getScores = async (refid: string, version: string, forFriend: boolean = fa return result; }; +/** + * Handler for saving the scores + */ const writeScore = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).str('ref_id'); if (!refid) return send.deny(); @@ -231,7 +248,6 @@ const writeScore = async (req: EamuseInfo, data: any, send: EamuseSend): Promise * Get/create the profile based on refid * @param refid the profile refid * @param name if defined, create/update the profile with the given name - * @returns */ const getProfile = async (refid: string, name?: string) => { const profile = await utils.readProfile(refid); @@ -244,9 +260,9 @@ const getProfile = async (refid: string, name?: string) => { let myBest = Array(10).fill(-1); const scores = await utils.readScores(refid, version, true); - if(Object.entries(scores.scores).length > 0) { + if (Object.entries(scores.scores).length > 0) { const playCount = new Map(); - for(const key in scores.scores) { + for (const key in scores.scores) { const keyData = key.split(':'); const music = parseInt(keyData[0], 10); playCount.set(music, (playCount.get(music) || 0) + scores.scores[key].cnt); @@ -255,7 +271,7 @@ const getProfile = async (refid: string, name?: string) => { const sortedPlayCount = new Map([...playCount.entries()].sort((a, b) => b[1] - a[1])); let i = 0; for (const value of sortedPlayCount.keys()) { - if(i >= 10) { + if (i >= 10) { break; } myBest[i] = value; @@ -360,6 +376,9 @@ const getProfile = async (refid: string, name?: string) => { return player; } +/** + * Handler for saving the profile + */ const write = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).str('ref_id'); if (!refid) return send.deny(); @@ -437,14 +456,17 @@ const write = async (req: EamuseInfo, data: any, send: EamuseSend): Promise send.success(); }; +/** + * Handler for sending rivals + */ const friend = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).attr()['ref_id']; const no = parseInt($(data).attr()['no'], -1); const rivals = await utils.readRivals(refid); - if(no < 0 || no >= rivals.rivals.length) { - send.object({result : K.ITEM('s8', 2)}); + if (no < 0 || no >= rivals.rivals.length) { + send.object({ result: K.ITEM('s8', 2) }); return; } @@ -458,7 +480,7 @@ const friend = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const result = { @@ -31,7 +31,7 @@ export const getInfo = async (req: EamuseInfo, data: any, send: EamuseSend): Pro }; /** - * Create a new profile and send it. + * Handler for new profile */ export const newPlayer = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).str('ref_id'); @@ -43,7 +43,7 @@ export const newPlayer = async (req: EamuseInfo, data: any, send: EamuseSend): P }; /** - * Read a profile and send it. + * Handler for existing profile */ export const read = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).str('ref_id'); @@ -59,6 +59,7 @@ export const read = async (req: EamuseInfo, data: any, send: EamuseSend): Promis */ export const getProfile = async (refid: string, name?: string) => { const profile = await utils.readProfile(refid); + const rivals = await utils.readRivals(refid); if (name && name.length > 0) { profile.name = name; @@ -66,53 +67,11 @@ export const getProfile = async (refid: string, name?: string) => { } // Get Score - let hiscore_array = Array(Math.floor((((GAME_MAX_MUSIC_ID * 4) * 17) + 7) / 8)).fill(0); - let clear_medal = Array(GAME_MAX_MUSIC_ID).fill(0); + const scores = await getScores(refid); let clear_medal_sub = Array(GAME_MAX_MUSIC_ID).fill(0); - const scoresData = await utils.readScores(refid, version); - const playCount = new Map(); - for (const key in scoresData.scores) { - const keyData = key.split(':'); - const score = scoresData.scores[key]; - const music = parseInt(keyData[0], 10); - const sheet = parseInt(keyData[1], 10); - - if (music > GAME_MAX_MUSIC_ID) { - continue; - } - if ([0, 1, 2, 3].indexOf(sheet) == -1) { - continue; - } - - const medal = { - 100: 1, - 200: 2, - 300: 3, - 400: 5, - 500: 5, - 600: 6, - 700: 7, - 800: 9, - 900: 10, - 1000: 11, - 1100: 15, - }[score.clear_type]; - clear_medal[music] = clear_medal[music] | (medal << (sheet * 4)); - - const hiscore_index = (music * 4) + sheet; - const hiscore_byte_pos = Math.floor((hiscore_index * 17) / 8); - const hiscore_bit_pos = ((hiscore_index * 17) % 8); - const hiscore_value = score.score << hiscore_bit_pos; - hiscore_array[hiscore_byte_pos] = hiscore_array[hiscore_byte_pos] | (hiscore_value & 0xFF); - hiscore_array[hiscore_byte_pos + 1] = hiscore_array[hiscore_byte_pos + 1] | ((hiscore_value >> 8) & 0xFF); - hiscore_array[hiscore_byte_pos + 2] = hiscore_array[hiscore_byte_pos + 2] | ((hiscore_value >> 16) & 0xFF); - - playCount.set(music, (playCount.get(music) || 0) + score.cnt); - } - let myBest = Array(20).fill(-1); - const sortedPlayCount = new Map([...playCount.entries()].sort((a, b) => b[1] - a[1])); + const sortedPlayCount = new Map([...scores.playCount.entries()].sort((a, b) => b[1] - a[1])); let i = 0; for (const value of sortedPlayCount.keys()) { if (i >= 20) { @@ -129,15 +88,15 @@ export const getProfile = async (refid: string, name?: string) => { staff: K.ITEM('s8', 0), is_conv: K.ITEM('s8', -1), my_best: K.ARRAY('s16', myBest), - clear_medal: K.ARRAY('u16', clear_medal), + clear_medal: K.ARRAY('u16', scores.clear_medal), clear_medal_sub: K.ARRAY('u8', clear_medal_sub), + active_fr_num: K.ITEM('u8', rivals.rivals.length), // TODO: replace with real data total_play_cnt: K.ITEM('s32', 100), today_play_cnt: K.ITEM('s16', 50), consecutive_days: K.ITEM('s16', 365), latest_music: K.ARRAY('s16', [-1, -1, -1]), - active_fr_num: K.ITEM('u8', 0), }, player_card: { // TODO: replace with real data @@ -162,7 +121,7 @@ export const getProfile = async (refid: string, name?: string) => { set_recommend: K.ARRAY('s8', [0, 0, 0]), jewelry: K.ARRAY('s8', Array(15).fill(0)), }, - hiscore: K.ITEM('bin', Buffer.from(hiscore_array)) + hiscore: K.ITEM('bin', Buffer.from(scores.hiscore_array)) }; // Add version specific datas @@ -175,7 +134,7 @@ export const getProfile = async (refid: string, name?: string) => { } /** - * Unformat and write the end game data into DB + * Handler for saving profile ans scores */ export const write = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).attr()['ref_id']; @@ -238,6 +197,91 @@ export const write = async (req: EamuseInfo, data: any, send: EamuseSend): Promi send.object(result); }; +/** + * Handler for sending rivals + */ +export const friend = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { + const refid = $(data).attr()['ref_id']; + const rivals = await utils.readRivals(refid); + let result = { + friend: [] + } + + for (const rival of rivals.rivals.slice(0, 2)) { + const profile = await utils.readProfile(rival); + const params = await utils.readParams(rival, version); + + const scores = await getScores(refid); + + result.friend.push({ + open: K.ITEM('s8', 1), + g_pm_id: K.ITEM('str', 'ASPHYXIAPLAY'), + name: K.ITEM('str', profile.name), + chara: K.ITEM('s16', params.params.chara || -1), + clear_medal: K.ARRAY('u16', scores.clear_medal), + hiscore: K.ITEM('bin', Buffer.from(scores.hiscore_array)) + }); + } + + send.object(result); +} + +/** + * Read the user scores and format them + * @param refid ID of the user + */ +const getScores = async (refid: string) => { + let hiscore_array = Array(Math.floor((((GAME_MAX_MUSIC_ID * 4) * 17) + 7) / 8)).fill(0); + let clear_medal = Array(GAME_MAX_MUSIC_ID).fill(0); + + const scoresData = await utils.readScores(refid, version); + const playCount = new Map(); + for (const key in scoresData.scores) { + const keyData = key.split(':'); + const score = scoresData.scores[key]; + const music = parseInt(keyData[0], 10); + const sheet = parseInt(keyData[1], 10); + + if (music > GAME_MAX_MUSIC_ID) { + continue; + } + if ([0, 1, 2, 3].indexOf(sheet) == -1) { + continue; + } + + const medal = { + 100: 1, + 200: 2, + 300: 3, + 400: 5, + 500: 5, + 600: 6, + 700: 7, + 800: 9, + 900: 10, + 1000: 11, + 1100: 15, + }[score.clear_type]; + clear_medal[music] = clear_medal[music] | (medal << (sheet * 4)); + + const hiscore_index = (music * 4) + sheet; + const hiscore_byte_pos = Math.floor((hiscore_index * 17) / 8); + const hiscore_bit_pos = ((hiscore_index * 17) % 8); + const hiscore_value = score.score << hiscore_bit_pos; + hiscore_array[hiscore_byte_pos] = hiscore_array[hiscore_byte_pos] | (hiscore_value & 0xFF); + hiscore_array[hiscore_byte_pos + 1] = hiscore_array[hiscore_byte_pos + 1] | ((hiscore_value >> 8) & 0xFF); + hiscore_array[hiscore_byte_pos + 2] = hiscore_array[hiscore_byte_pos + 2] | ((hiscore_value >> 16) & 0xFF); + + playCount.set(music, (playCount.get(music) || 0) + score.cnt); + } + + return { + hiscore_array, + clear_medal, + playCount + } +} + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const version: string = 'v20'; diff --git a/popn@asphyxia/handler/lapistoria.ts b/popn@asphyxia/handler/lapistoria.ts index aa65e7d..c357a3a 100644 --- a/popn@asphyxia/handler/lapistoria.ts +++ b/popn@asphyxia/handler/lapistoria.ts @@ -12,7 +12,7 @@ export const setRoutes = () => { } /** - * Return info22.common informations (phase, etc...) + * Handler for getting current state of the game. */ const getInfo = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const result: any = { @@ -39,7 +39,7 @@ const getInfo = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).str('ref_id'); @@ -51,7 +51,7 @@ const newPlayer = async (req: EamuseInfo, data: any, send: EamuseSend): Promise< }; /** - * Read a profile and send it. + * Handler for existing profile */ const read = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).str('ref_id'); @@ -60,6 +60,9 @@ const read = async (req: EamuseInfo, data: any, send: EamuseSend): Promise send.object(await getProfile(refid)); }; +/** + * Handler for saving the scores + */ const writeScore = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).str('ref_id'); if (!refid) return send.deny(); @@ -107,7 +110,6 @@ const writeScore = async (req: EamuseInfo, data: any, send: EamuseSend): Promise * Get/create the profile based on refid * @param refid the profile refid * @param name if defined, create/update the profile with the given name - * @returns */ const getProfile = async (refid: string, name?: string) => { const profile = await utils.readProfile(refid); @@ -280,6 +282,9 @@ const getProfile = async (refid: string, name?: string) => { return player; } +/** + * Handler for saving the profile + */ const write = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).str('ref_id'); if (!refid) return send.deny(); @@ -374,14 +379,17 @@ const write = async (req: EamuseInfo, data: any, send: EamuseSend): Promise send.success(); }; +/** + * Handler for sending rivals + */ const friend = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).attr()['ref_id']; const no = parseInt($(data).attr()['no'], -1); const rivals = await utils.readRivals(refid); - if(no < 0 || no >= rivals.rivals.length) { - send.object({result : K.ITEM('s8', 2)}); + if (no < 0 || no >= rivals.rivals.length) { + send.object({ result: K.ITEM('s8', 2) }); return; } diff --git a/popn@asphyxia/handler/sunny.ts b/popn@asphyxia/handler/sunny.ts index f73c50c..7dff458 100644 --- a/popn@asphyxia/handler/sunny.ts +++ b/popn@asphyxia/handler/sunny.ts @@ -2,7 +2,7 @@ import { ExtraData } from "../models/common"; import * as utils from "./utils"; /** - * Return the current phases of the game. + * Handler for getting the current state of the game (phase, good prices, etc...) */ export const getInfo = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const result = { @@ -19,15 +19,15 @@ export const getInfo = async (req: EamuseInfo, data: any, send: EamuseSend): Pro l_matching_sec: K.ITEM('s32', 60), is_check_cpu: K.ITEM('s32', 0), week_no: K.ITEM('s32', 0), - sel_ranking: K.ARRAY('s16', [-1, -1, -1, -1, -1]), - up_ranking: K.ARRAY('s16', [-1, -1, -1, -1, -1]), + sel_ranking: K.ARRAY('s16', Array(10).fill(-1)), + up_ranking: K.ARRAY('s16', Array(10).fill(-1)), }; return send.object(result); }; /** - * Create a new profile and send it. + * Handler for new profile */ export const newPlayer = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).str('ref_id'); @@ -39,7 +39,7 @@ export const newPlayer = async (req: EamuseInfo, data: any, send: EamuseSend): P }; /** - * Read a profile and send it. + * Handler for existing profile */ export const read = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).str('ref_id'); @@ -55,6 +55,7 @@ export const read = async (req: EamuseInfo, data: any, send: EamuseSend): Promis */ export const getProfile = async (refid: string, name?: string) => { const profile = await utils.readProfile(refid); + const rivals = await utils.readRivals(refid); if (name && name.length > 0) { profile.name = name; @@ -62,53 +63,11 @@ export const getProfile = async (refid: string, name?: string) => { } // Get Score - let hiscore_array = Array(Math.floor((((GAME_MAX_MUSIC_ID * 4) * 17) + 7) / 8)).fill(0); - let clear_medal = Array(GAME_MAX_MUSIC_ID).fill(0); + const scores = await getScores(refid); let clear_medal_sub = Array(GAME_MAX_MUSIC_ID).fill(0); - const scoresData = await utils.readScores(refid, version); - const playCount = new Map(); - for (const key in scoresData.scores) { - const keyData = key.split(':'); - const score = scoresData.scores[key]; - const music = parseInt(keyData[0], 10); - const sheet = parseInt(keyData[1], 10); - - if (music > GAME_MAX_MUSIC_ID) { - continue; - } - if ([0, 1, 2, 3].indexOf(sheet) == -1) { - continue; - } - - const medal = { - 100: 1, - 200: 2, - 300: 3, - 400: 5, - 500: 5, - 600: 6, - 700: 7, - 800: 9, - 900: 10, - 1000: 11, - 1100: 15, - }[score.clear_type]; - clear_medal[music] = clear_medal[music] | (medal << (sheet * 4)); - - const hiscore_index = (music * 4) + sheet; - const hiscore_byte_pos = Math.floor((hiscore_index * 17) / 8); - const hiscore_bit_pos = ((hiscore_index * 17) % 8); - const hiscore_value = score.score << hiscore_bit_pos; - hiscore_array[hiscore_byte_pos] = hiscore_array[hiscore_byte_pos] | (hiscore_value & 0xFF); - hiscore_array[hiscore_byte_pos + 1] = hiscore_array[hiscore_byte_pos + 1] | ((hiscore_value >> 8) & 0xFF); - hiscore_array[hiscore_byte_pos + 2] = hiscore_array[hiscore_byte_pos + 2] | ((hiscore_value >> 16) & 0xFF); - - playCount.set(music, (playCount.get(music) || 0) + score.cnt); - } - let myBest = Array(20).fill(-1); - const sortedPlayCount = new Map([...playCount.entries()].sort((a, b) => b[1] - a[1])); + const sortedPlayCount = new Map([...scores.playCount.entries()].sort((a, b) => b[1] - a[1])); let i = 0; for (const value of sortedPlayCount.keys()) { if (i >= 20) { @@ -126,15 +85,15 @@ export const getProfile = async (refid: string, name?: string) => { is_conv: K.ITEM('s8', -1), collabo: K.ITEM('u8', 255), my_best: K.ARRAY('s16', myBest), - clear_medal: K.ARRAY('u16', clear_medal), + clear_medal: K.ARRAY('u16', scores.clear_medal), clear_medal_sub: K.ARRAY('u8', clear_medal_sub), + active_fr_num: K.ITEM('u8', rivals.rivals.length), // TODO: replace with real data total_play_cnt: K.ITEM('s32', 100), today_play_cnt: K.ITEM('s16', 50), consecutive_days: K.ITEM('s16', 365), latest_music: K.ARRAY('s16', [-1, -1, -1]), - active_fr_num: K.ITEM('u8', 0), }, netvs: { rank_point: K.ITEM('s32', 0), @@ -154,7 +113,7 @@ export const getProfile = async (refid: string, name?: string) => { set_recommend: K.ARRAY('s8', [0, 0, 0]), netvs_play_cnt: K.ITEM('u8', 0), }, - hiscore: K.ITEM('bin', Buffer.from(hiscore_array)), + hiscore: K.ITEM('bin', Buffer.from(scores.hiscore_array)), gakuen_data: { music_list: K.ITEM('s32', -1), }, @@ -215,7 +174,7 @@ export const getProfile = async (refid: string, name?: string) => { } /** - * Unformat and write the end game data into DB + * Handler for saving profile and scores */ export const write = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).attr()['ref_id']; @@ -273,6 +232,97 @@ export const write = async (req: EamuseInfo, data: any, send: EamuseSend): Promi send.object(result); }; +/** + * Handler for sending rivals + */ +export const friend = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { + const refid = $(data).attr()['ref_id']; + const rivals = await utils.readRivals(refid); + let result = { + friend: [] + } + + for (const rival of rivals.rivals.slice(0, 2)) { + const profile = await utils.readProfile(rival); + const params = await utils.readParams(rival, version); + + const scores = await getScores(rival); + + result.friend.push({ + open: K.ITEM('s8', 1), + g_pm_id: K.ITEM('str', 'ASPHYXIAPLAY'), + name: K.ITEM('str', profile.name), + chara: K.ITEM('s16', params.params.chara || -1), + hair: K.ITEM('u8', params.params.hair || 0), + face: K.ITEM('u8', params.params.face || 0), + body: K.ITEM('u8', params.params.body || 0), + effect: K.ITEM('u8', params.params.effect || 0), + object: K.ITEM('u8', params.params.object || 0), + comment: K.ARRAY('u8', params.params.comment || [0, 0]), + clear_medal: K.ARRAY('u16', scores.clear_medal), + hiscore: K.ITEM('bin', Buffer.from(scores.hiscore_array)) + }); + } + + send.object(result); +} + +/** + * Read the user scores and format them + * @param refid ID of the user + */ +const getScores = async (refid: string) => { + let hiscore_array = Array(Math.floor((((GAME_MAX_MUSIC_ID * 4) * 17) + 7) / 8)).fill(0); + let clear_medal = Array(GAME_MAX_MUSIC_ID).fill(0); + + const scoresData = await utils.readScores(refid, version); + const playCount = new Map(); + for (const key in scoresData.scores) { + const keyData = key.split(':'); + const score = scoresData.scores[key]; + const music = parseInt(keyData[0], 10); + const sheet = parseInt(keyData[1], 10); + + if (music > GAME_MAX_MUSIC_ID) { + continue; + } + if ([0, 1, 2, 3].indexOf(sheet) == -1) { + continue; + } + + const medal = { + 100: 1, + 200: 2, + 300: 3, + 400: 5, + 500: 5, + 600: 6, + 700: 7, + 800: 9, + 900: 10, + 1000: 11, + 1100: 15, + }[score.clear_type]; + clear_medal[music] = clear_medal[music] | (medal << (sheet * 4)); + + const hiscore_index = (music * 4) + sheet; + const hiscore_byte_pos = Math.floor((hiscore_index * 17) / 8); + const hiscore_bit_pos = ((hiscore_index * 17) % 8); + const hiscore_value = score.score << hiscore_bit_pos; + hiscore_array[hiscore_byte_pos] = hiscore_array[hiscore_byte_pos] | (hiscore_value & 0xFF); + hiscore_array[hiscore_byte_pos + 1] = hiscore_array[hiscore_byte_pos + 1] | ((hiscore_value >> 8) & 0xFF); + hiscore_array[hiscore_byte_pos + 2] = hiscore_array[hiscore_byte_pos + 2] | ((hiscore_value >> 16) & 0xFF); + + playCount.set(music, (playCount.get(music) || 0) + score.cnt); + } + + return { + hiscore_array, + clear_medal, + playCount + } +} + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const version: string = 'v21'; diff --git a/popn@asphyxia/handler/tunestreet.ts b/popn@asphyxia/handler/tunestreet.ts index efca0fd..f63c937 100644 --- a/popn@asphyxia/handler/tunestreet.ts +++ b/popn@asphyxia/handler/tunestreet.ts @@ -1,5 +1,8 @@ import * as utils from "./utils"; +/** + * Handler for getting the current state of the game (phase, good prices, etc...) + */ export const getInfo = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const result = K.ATTR({ game_phase: "2", psp_phase: "2" }); @@ -7,7 +10,7 @@ export const getInfo = async (req: EamuseInfo, data: any, send: EamuseSend): Pro }; /** - * Create a new profile and send it. + * Handler for new profile */ export const newPlayer = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).attr()['ref_id']; @@ -19,7 +22,7 @@ export const newPlayer = async (req: EamuseInfo, data: any, send: EamuseSend): P }; /** - * Read a profile and send it. + * Handler for existing profile */ export const read = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).attr()['ref_id']; @@ -29,10 +32,9 @@ export const read = async (req: EamuseInfo, data: any, send: EamuseSend): Promis }; /** - * Get/create the profile based on refid + * Get/create the profile and scores based on refid * @param refid the profile refid * @param name if defined, create/update the profile with the given name - * @returns */ export const getProfile = async (refid: string, name?: string) => { const profile = await utils.readProfile(refid); @@ -185,6 +187,9 @@ const __format_flags_for_score = (sheet: number, clear_type: number) => { return (flags << shift) | playedflag } +/** + * Handler for saving profile and scores + */ export const write = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).attr()['ref_id']; if (!refid) return send.deny(); @@ -288,6 +293,11 @@ export const write = async (req: EamuseInfo, data: any, send: EamuseSend): Promi send.object(result); }; +export const friend = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { + // No rivals support for Tune street :( + send.deny(); +} + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const version: string = 'v19'; diff --git a/popn@asphyxia/handler/usaneko.ts b/popn@asphyxia/handler/usaneko.ts index 08e4dfe..9164289 100644 --- a/popn@asphyxia/handler/usaneko.ts +++ b/popn@asphyxia/handler/usaneko.ts @@ -14,6 +14,9 @@ export const setRoutes = () => { R.Route(`player24.friend`, friend); } +/** + * Return current state of the game (phase, good prices, etc...) + */ const getInfoCommon = (req: EamuseInfo) => { const result: any = { phase: [], @@ -92,7 +95,7 @@ const start = async (req: EamuseInfo, data: any, send: EamuseSend): Promise }; /** - * Create a new profile and send it. + * Handler for new profile */ const newPlayer = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).str('ref_id'); @@ -104,7 +107,7 @@ const newPlayer = async (req: EamuseInfo, data: any, send: EamuseSend): Promise< }; /** - * Read a profile and send it. + * Handler for existing profile */ const read = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).str('ref_id'); @@ -113,6 +116,9 @@ const read = async (req: EamuseInfo, data: any, send: EamuseSend): Promise send.object(await getProfile(refid, getVersion(req))); }; +/** + * Handler fo buying goods with lumina + */ const buy = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).str('ref_id'); if (!refid) return send.deny(); @@ -134,13 +140,16 @@ const buy = async (req: EamuseInfo, data: any, send: EamuseSend): Promise = params.params.player_point = lumina - price; await utils.writeParams(refid, version, params); - const achievements = await utils.readAchievements(refid, version, {...defaultAchievements, version}); + const achievements = await utils.readAchievements(refid, version, { ...defaultAchievements, version }); achievements.items[`${type}:${id}`] = param; await utils.writeAchievements(refid, version, achievements); } send.success(); }; +/** + * Handler for getting the user scores + */ const readScore = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).str('ref_id'); const version = getVersion(req); @@ -149,6 +158,11 @@ const readScore = async (req: EamuseInfo, data: any, send: EamuseSend): Promise< send.object({ music: await getScores(refid, version) }); }; +/** + * Read the user scores and format them (profile/friend) + * @param refid ID of the user + * @param forFriend If true, format the output for friend request. + */ const getScores = async (refid: string, version: string, forFriend: boolean = false) => { const scoresData = await utils.readScores(refid, version); const result = []; @@ -179,7 +193,7 @@ const getScores = async (refid: string, version: string, forFriend: boolean = fa continue; } - if(forFriend) { + if (forFriend) { result.push(K.ATTR({ music_num: music.toString(), sheet_num: sheet.toString(), @@ -202,6 +216,9 @@ const getScores = async (refid: string, version: string, forFriend: boolean = fa return result; }; +/** + * Return the rank based on the given score + */ const getRank = (score: number): number => { if (score < 50000) { return 1 @@ -221,6 +238,9 @@ const getRank = (score: number): number => { return 8 } +/** + * Handler for saving the scores + */ const writeScore = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const version = getVersion(req); const refid = $(data).str('ref_id'); @@ -269,7 +289,6 @@ const writeScore = async (req: EamuseInfo, data: any, send: EamuseSend): Promise * Get/create the profile based on refid * @param refid the profile refid * @param name if defined, create/update the profile with the given name - * @returns */ const getProfile = async (refid: string, version: string, name?: string) => { const profile = await utils.readProfile(refid); @@ -282,9 +301,9 @@ const getProfile = async (refid: string, version: string, name?: string) => { let myBest = Array(10).fill(-1); const scores = await utils.readScores(refid, version, true); - if(Object.entries(scores.scores).length > 0) { + if (Object.entries(scores.scores).length > 0) { const playCount = new Map(); - for(const key in scores.scores) { + for (const key in scores.scores) { const keyData = key.split(':'); const music = parseInt(keyData[0], 10); playCount.set(music, (playCount.get(music) || 0) + scores.scores[key].cnt); @@ -293,7 +312,7 @@ const getProfile = async (refid: string, version: string, name?: string) => { const sortedPlayCount = new Map([...playCount.entries()].sort((a, b) => b[1] - a[1])); let i = 0; for (const value of sortedPlayCount.keys()) { - if(i >= 10) { + if (i >= 10) { break; } myBest[i] = value; @@ -384,7 +403,7 @@ const getProfile = async (refid: string, version: string, name?: string) => { stamp: [], }; - const achievements = await utils.readAchievements(refid, version, {...defaultAchievements, version}); + const achievements = await utils.readAchievements(refid, version, { ...defaultAchievements, version }); const profileCharas = achievements.charas || {}; for (const chara_id in profileCharas) { @@ -395,8 +414,8 @@ const getProfile = async (refid: string, version: string, name?: string) => { } let profileStamps = achievements.stamps; - if(Object.entries(profileStamps).length == 0) { - profileStamps = {"0": 0 }; + if (Object.entries(profileStamps).length == 0) { + profileStamps = { "0": 0 }; } for (const stamp_id in profileStamps) { player.stamp.push({ @@ -465,6 +484,9 @@ const getProfile = async (refid: string, version: string, name?: string) => { return player; } +/** + * Handler for saving the profile + */ const write = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).str('ref_id'); if (!refid) return send.deny(); @@ -472,7 +494,7 @@ const write = async (req: EamuseInfo, data: any, send: EamuseSend): Promise const version = getVersion(req); const params = await utils.readParams(refid, version); - const achievements = await utils.readAchievements(refid, version, {...defaultAchievements, version}); + const achievements = await utils.readAchievements(refid, version, { ...defaultAchievements, version }); utils.getExtraData(data, params, EXTRA_DATA); @@ -611,6 +633,9 @@ const write = async (req: EamuseInfo, data: any, send: EamuseSend): Promise send.success(); }; +/** + * Handler for sending rivals + */ const friend = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).attr()['ref_id']; const no = parseInt($(data).attr()['no'], -1); @@ -618,8 +643,8 @@ const friend = async (req: EamuseInfo, data: any, send: EamuseSend): Promise= rivals.rivals.length) { - send.object({result : K.ITEM('s8', 2)}); + if (no < 0 || no >= rivals.rivals.length) { + send.object({ result: K.ITEM('s8', 2) }); return; } @@ -633,7 +658,7 @@ const friend = async (req: EamuseInfo, data: any, send: EamuseSend): Promise { - const rivals = await DB.FindOne(data.refid, { collection: 'rivals' }) || {collection: 'rivals', rivals: []}; + const rivals = await DB.FindOne(data.refid, { collection: 'rivals' }) || { collection: 'rivals', rivals: [] }; const idx = rivals.rivals.indexOf(data.rivalid); - if(idx >= 0) { + if (idx >= 0) { rivals.rivals.splice(idx, 1); await DB.Update(data.refid, { collection: 'rivals' }, rivals); } @@ -48,10 +48,10 @@ export function register() { R.WebUIEvent('addRival', async (data: any) => { const refid = data.refid.trim(); - const profile = await DB.FindOne(data.rivalid, { collection: 'profile'}); - if(profile != undefined && profile != null) { - const rivals = await DB.FindOne(refid, { collection: 'rivals' }) || {collection: 'rivals', rivals: []}; - if(rivals.rivals.length < 4) { + const profile = await DB.FindOne(data.rivalid, { collection: 'profile' }); + if (profile != undefined && profile != null) { + const rivals = await DB.FindOne(refid, { collection: 'rivals' }) || { collection: 'rivals', rivals: [] }; + if (rivals.rivals.length < 4) { rivals.rivals.push(data.rivalid); await DB.Upsert(refid, { collection: 'rivals' }, rivals); } @@ -64,6 +64,7 @@ export function register() { R.Route(`playerdata.conversion`, async (req, data, send) => getVersion(req).newPlayer(req, data, send)); R.Route(`playerdata.get`, async (req, data, send) => getVersion(req).read(req, data, send)); R.Route(`playerdata.set`, async (req, data, send) => getVersion(req).write(req, data, send)); + R.Route(`playerdata.friend`, async (req, data, send) => getVersion(req).friend(req, data, send)); // For Pnm >= 22, each game set his own route lapistoria.setRoutes(); From b9257ce08a1c60d1014645d50070b726f0c71122 Mon Sep 17 00:00:00 2001 From: cracrayol Date: Mon, 19 Apr 2021 23:09:55 +0200 Subject: [PATCH 4/4] Fix loading of rivals scores --- popn@asphyxia/handler/eclale.ts | 2 +- popn@asphyxia/handler/lapistoria.ts | 2 +- popn@asphyxia/handler/usaneko.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/popn@asphyxia/handler/eclale.ts b/popn@asphyxia/handler/eclale.ts index 4eb23ef..7540fed 100644 --- a/popn@asphyxia/handler/eclale.ts +++ b/popn@asphyxia/handler/eclale.ts @@ -461,7 +461,7 @@ const write = async (req: EamuseInfo, data: any, send: EamuseSend): Promise */ const friend = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).attr()['ref_id']; - const no = parseInt($(data).attr()['no'], -1); + const no = parseInt($(data).attr()['no'], 10); const rivals = await utils.readRivals(refid); diff --git a/popn@asphyxia/handler/lapistoria.ts b/popn@asphyxia/handler/lapistoria.ts index c357a3a..659a298 100644 --- a/popn@asphyxia/handler/lapistoria.ts +++ b/popn@asphyxia/handler/lapistoria.ts @@ -384,7 +384,7 @@ const write = async (req: EamuseInfo, data: any, send: EamuseSend): Promise */ const friend = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).attr()['ref_id']; - const no = parseInt($(data).attr()['no'], -1); + const no = parseInt($(data).attr()['no'], 10); const rivals = await utils.readRivals(refid); diff --git a/popn@asphyxia/handler/usaneko.ts b/popn@asphyxia/handler/usaneko.ts index 9164289..95a5a4e 100644 --- a/popn@asphyxia/handler/usaneko.ts +++ b/popn@asphyxia/handler/usaneko.ts @@ -638,7 +638,7 @@ const write = async (req: EamuseInfo, data: any, send: EamuseSend): Promise */ const friend = async (req: EamuseInfo, data: any, send: EamuseSend): Promise => { const refid = $(data).attr()['ref_id']; - const no = parseInt($(data).attr()['no'], -1); + const no = parseInt($(data).attr()['no'], 10); const version = getVersion(req); const rivals = await utils.readRivals(refid);