mirror of
https://github.com/asphyxia-core/plugins.git
synced 2026-06-13 02:40:45 -05:00
commit
edfa133ac5
|
|
@ -13,6 +13,7 @@ Supported Versions
|
|||
- HIGH-VOLTAGE
|
||||
- FUZZ-UP
|
||||
- GALAXY WAVE
|
||||
- GALAXY WAVE DEL
|
||||
|
||||
When Plugin Doesn't work correctly / Startup Error on Plugin
|
||||
------------------------------------------------------------
|
||||
|
|
@ -60,6 +61,10 @@ Scores are stored under `version: "shared"` but are automatically applied to the
|
|||
Release Notes
|
||||
=============
|
||||
|
||||
v1.5.0
|
||||
----------------
|
||||
* Added(more like bugfix lol) support for GALAXY WAVE DELTA
|
||||
|
||||
v1.4.0
|
||||
----------------
|
||||
* Added support for Tri-Boost Re:EVOLVE, HIGH-VOLTAGE, FUZZ-UP, GALAXY WAVE
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { getVersion } from "../utils";
|
||||
import { isGalaxyWaveDeltaModel } from "../utils";
|
||||
|
||||
interface EncoreStageData {
|
||||
level: number
|
||||
|
|
@ -8,13 +9,34 @@ interface EncoreStageData {
|
|||
|
||||
export function getEncoreStageData(info: EamuseInfo): EncoreStageData {
|
||||
const fallback = { level: 10, musics: [0] }
|
||||
const level: number = U.GetConfig("encore_version")
|
||||
const customLevel: number = U.GetConfig("encore_version")
|
||||
const useCustomLevel: boolean = U.GetConfig("use_custom_encore_level")
|
||||
const ntDummyEncore = U.GetConfig("nextage_dummy_encore")
|
||||
|
||||
const level = (ver: string) => useCustomLevel ? customLevel : getPredefinedLevel(ver);
|
||||
|
||||
// GALAXY WAVE DELTA uses same route prefix, detect by model instead
|
||||
if (isGalaxyWaveDeltaModel(info.model)) {
|
||||
return {
|
||||
level: level('galaxywave_delta'),
|
||||
musics: [
|
||||
2939, // Hopeful Daybreak!!!
|
||||
2956, // Over Time Groove
|
||||
2942, // Bellatrix
|
||||
3008, // Questions That Should Not Be Answered
|
||||
3009, // LIQUID NOTES
|
||||
3011, // D光石火
|
||||
3017, // Peyotl
|
||||
3018, // Neoverse
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
switch (getVersion(info)) {
|
||||
case 'galaxywave':
|
||||
return {
|
||||
level,
|
||||
musics: [
|
||||
level: level('galaxywave'),
|
||||
musics: [
|
||||
2866, // Calm days
|
||||
2893, // 愛はToxic! feat.Lilymone
|
||||
2885, // Astrum
|
||||
|
|
@ -30,8 +52,8 @@ export function getEncoreStageData(info: EamuseInfo): EncoreStageData {
|
|||
}
|
||||
case 'fuzzup':
|
||||
return {
|
||||
level,
|
||||
musics: [
|
||||
level: level('fuzzup'),
|
||||
musics: [
|
||||
2812, // THE LAST OF FIREFACE
|
||||
2814, // ENCOUNT
|
||||
2783, // Q転直下
|
||||
|
|
@ -44,7 +66,7 @@ export function getEncoreStageData(info: EamuseInfo): EncoreStageData {
|
|||
}
|
||||
case 'highvoltage':
|
||||
return {
|
||||
level,
|
||||
level: level('highvoltage'),
|
||||
musics: [
|
||||
2686, // CYCLONICxSTORM
|
||||
2687, // Heptagram
|
||||
|
|
@ -58,8 +80,8 @@ export function getEncoreStageData(info: EamuseInfo): EncoreStageData {
|
|||
}
|
||||
case 'nextage':
|
||||
return {
|
||||
level,
|
||||
musics: !ntDummyEncore ? [
|
||||
level: level('nextage'),
|
||||
musics: !ntDummyEncore ? [
|
||||
2587, // 悪魔のハニープリン
|
||||
2531, // The ULTIMATES -reminiscence-
|
||||
2612, // ECLIPSE 2
|
||||
|
|
@ -75,26 +97,26 @@ export function getEncoreStageData(info: EamuseInfo): EncoreStageData {
|
|||
}
|
||||
case 'exchain':
|
||||
return {
|
||||
level,
|
||||
level: level('exchain'),
|
||||
musics: [
|
||||
2246, // 箱庭の世界
|
||||
2498, // Cinnamon
|
||||
2500, // キヤロラ衛星の軌跡
|
||||
2529, // グリーンリーフ症候群
|
||||
2548, // Let's Dance
|
||||
2587, // 悪魔のハニープリン
|
||||
5020, // Timepiece phase II (CLASSIC)
|
||||
5033, // MODEL FT2 Miracle Version (CLASSIC)
|
||||
2586, // 美麗的夏日風
|
||||
2548, // Let's Dance
|
||||
2587, // 悪魔のハニープリン
|
||||
5020, // Timepiece phase II (CLASSIC)
|
||||
5033, // MODEL FT2 Miracle Version (CLASSIC)
|
||||
2586, // 美麗的夏日風
|
||||
5060, // EXCELSIOR DIVE (CLASSIC)
|
||||
2530, // The ULTIMATES -CHRONICLE-
|
||||
2581, // 幸せの代償
|
||||
5046, // Rock to Infinity (CLASSIC)
|
||||
5046, // Rock to Infinity (CLASSIC)
|
||||
]
|
||||
}
|
||||
case 'matixx':
|
||||
return {
|
||||
level,
|
||||
level: level('matixx'),
|
||||
musics: [
|
||||
2432, // Durian
|
||||
2445, // ヤオヨロズランズ
|
||||
|
|
@ -103,17 +125,17 @@ export function getEncoreStageData(info: EamuseInfo): EncoreStageData {
|
|||
2444, // Aion
|
||||
2381, // Duella Lyrica
|
||||
2471, // triangulum
|
||||
2476, // MODEL FT4
|
||||
2476, // MODEL FT4
|
||||
2486, // 煉獄事変
|
||||
2496, // CAPTURING XANADU
|
||||
2497, // Physical Decay
|
||||
2499, // Cinnamon
|
||||
2499, // Cinnamon
|
||||
2498, // けもののおうじゃ★めうめう
|
||||
]
|
||||
}
|
||||
case 're':
|
||||
return {
|
||||
level,
|
||||
level: level('re'),
|
||||
musics: [
|
||||
2341, // Anathema
|
||||
2384, // White Forest
|
||||
|
|
@ -129,4 +151,19 @@ export function getEncoreStageData(info: EamuseInfo): EncoreStageData {
|
|||
default:
|
||||
return fallback
|
||||
}
|
||||
}
|
||||
|
||||
function getPredefinedLevel(ver: string): number {
|
||||
// Placeholder values, to be replaced with real data
|
||||
switch (ver) {
|
||||
case 'galaxywave_delta': return 5;
|
||||
case 'galaxywave': return 5;
|
||||
case 'fuzzup': return 5;
|
||||
case 'highvoltage': return 5;
|
||||
case 'nextage': return 5;
|
||||
case 'exchain': return 5;
|
||||
case 'matixx': return 5;
|
||||
case 're': return 5;
|
||||
default: return 5;
|
||||
}
|
||||
}
|
||||
1
gitadora@asphyxia/data/mdb/gwd.b64
Normal file
1
gitadora@asphyxia/data/mdb/gwd.b64
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -2,6 +2,7 @@ import Logger from "../../utils/logger";
|
|||
import { CommonMusicData } from "../../models/commonmusicdata";
|
||||
|
||||
export enum DATAVersion {
|
||||
GALAXYWAVEDELTA = "gwd",
|
||||
GALAXYWAVE = "gw",
|
||||
FUZZUP = "fz",
|
||||
HIGHVOLTAGE = "hv",
|
||||
|
|
@ -78,8 +79,10 @@ export async function readMDBFile(path: string, processHandler?: processRawDataH
|
|||
return result
|
||||
}
|
||||
|
||||
export function gameVerToDataVer(ver: string): DATAVersion {
|
||||
export function gameVerToDataVer(ver: string, model?: string): DATAVersion {
|
||||
switch(ver) {
|
||||
case 'galaxywave_delta':
|
||||
return DATAVersion.GALAXYWAVEDELTA
|
||||
case 'galaxywave':
|
||||
return DATAVersion.GALAXYWAVE
|
||||
case 'fuzzup':
|
||||
|
|
@ -93,6 +96,14 @@ export function gameVerToDataVer(ver: string): DATAVersion {
|
|||
case 'matixx':
|
||||
return DATAVersion.MATTIX
|
||||
default:
|
||||
// Fallback: detect version from model string
|
||||
// GALAXY WAVE DELTA models: M32:J:C:A:... or M32:J:D:A:...
|
||||
// GALAXY WAVE models: M32:J:A:A:... or M32:J:B:A:...
|
||||
if (model) {
|
||||
const t = model.split(':')[2];
|
||||
if (t == 'C' || t == 'D') return DATAVersion.GALAXYWAVEDELTA;
|
||||
if (t == 'A' || t == 'B') return DATAVersion.GALAXYWAVE;
|
||||
}
|
||||
return DATAVersion.TBRE
|
||||
}
|
||||
}
|
||||
|
|
@ -133,8 +144,18 @@ export function findMDBFile(fileNameWithoutExtension: string, path: string = nul
|
|||
return null
|
||||
}
|
||||
|
||||
export async function loadSongsForGameVersion(gameVer: string, processHandler?: processRawDataHandler) {
|
||||
const ver = gameVerToDataVer(gameVer)
|
||||
export function modelToDataVer(model: string): DATAVersion {
|
||||
// Detects GALAXY WAVE vs GALAXY WAVE DELTA from model string.
|
||||
// Model format: M32:J:X:Y:ZZZZZZZZZZ
|
||||
// X = A (GW GF), B (GW DM), C (GWD GF), D (GWD DM)
|
||||
const t = model.split(':')[2];
|
||||
if (t == 'C' || t == 'D') return DATAVersion.GALAXYWAVEDELTA;
|
||||
if (t == 'A' || t == 'B') return DATAVersion.GALAXYWAVE;
|
||||
return DATAVersion.TBRE;
|
||||
}
|
||||
|
||||
export async function loadSongsForGameVersion(gameVer: string, processHandler?: processRawDataHandler, model?: string) {
|
||||
const ver = gameVerToDataVer(gameVer, model)
|
||||
|
||||
let mdbFile = findMDBFile(ver, mdbFolder)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,19 @@
|
|||
import { getVersion } from "../utils";
|
||||
import { isGalaxyWaveDeltaModel } from "../utils";
|
||||
import { findMDBFile, readMDBFile, loadSongsForGameVersion } from "../data/mdb";
|
||||
import { CommonMusicDataField } from "../models/commonmusicdata";
|
||||
import Logger from "../utils/logger"
|
||||
import { getPlayableMusicResponse, PlayableMusicResponse } from "../models/Responses/playablemusicresponse";
|
||||
import { isAsphyxiaDebugMode } from "../utils/index";
|
||||
import { playableMusic as playableMusicDelta } from "./MusicList_delta";
|
||||
|
||||
const logger = new Logger("MusicList")
|
||||
|
||||
export const playableMusic: EPR = async (info, data, send) => {
|
||||
if (isGalaxyWaveDeltaModel(info.model)) {
|
||||
return playableMusicDelta(info, data, send);
|
||||
}
|
||||
|
||||
const version = getVersion(info);
|
||||
const start = Date.now()
|
||||
let music: CommonMusicDataField[] = [];
|
||||
|
|
|
|||
40
gitadora@asphyxia/handlers/MusicList_delta.ts
Normal file
40
gitadora@asphyxia/handlers/MusicList_delta.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import { getVersion } from "../utils";
|
||||
import { findMDBFile, readMDBFile, loadSongsForGameVersion, modelToDataVer } from "../data/mdb";
|
||||
import { CommonMusicDataField } from "../models/commonmusicdata";
|
||||
import Logger from "../utils/logger"
|
||||
import { getPlayableMusicResponse, PlayableMusicResponse } from "../models/Responses/playablemusicresponse";
|
||||
import { isAsphyxiaDebugMode } from "../utils/index";
|
||||
|
||||
const logger = new Logger("MusicList_delta")
|
||||
|
||||
export const playableMusic: EPR = async (info, data, send) => {
|
||||
const version = modelToDataVer(info.model);
|
||||
const start = Date.now()
|
||||
let music: CommonMusicDataField[] = [];
|
||||
try {
|
||||
if (U.GetConfig("enable_custom_mdb")) {
|
||||
let customMdb = findMDBFile("custom")
|
||||
music = (await readMDBFile(customMdb)).music
|
||||
}
|
||||
} catch (e) {
|
||||
logger.warn("Read Custom MDB failed. Using default MDB as a fallback.")
|
||||
logger.debugWarn(e.stack);
|
||||
music = [];
|
||||
}
|
||||
|
||||
if (music.length == 0) {
|
||||
music = (await loadSongsForGameVersion(version, undefined, info.model)).music
|
||||
}
|
||||
|
||||
const end = Date.now()
|
||||
const timeDiff = end - start
|
||||
logger.debugInfo(`MDB loading took ${timeDiff} ms`)
|
||||
|
||||
let response : PlayableMusicResponse = getPlayableMusicResponse(music)
|
||||
await send.object(response)
|
||||
|
||||
if (isAsphyxiaDebugMode()) {
|
||||
await IO.WriteFile(`apisamples/playableMusicList.json`, JSON.stringify(music, null, 4))
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -2,10 +2,14 @@
|
|||
|
||||
import { getEncoreStageData } from "../data/extrastage";
|
||||
import Logger from "../utils/logger";
|
||||
import { getVersion } from "../utils";
|
||||
import { getVersion, isGalaxyWaveDeltaModel } from "../utils";
|
||||
import { gameInfoGet as gameInfoGetDelta, shopInfoRegist as shopInfoRegistDelta } from "./info_delta";
|
||||
|
||||
const logger = new Logger('info');
|
||||
export const shopInfoRegist: EPR = async (info, data, send) => {
|
||||
if (isGalaxyWaveDeltaModel(info.model)) {
|
||||
return shopInfoRegistDelta(info, data, send);
|
||||
}
|
||||
send.object({
|
||||
data: {
|
||||
cabid: K.ITEM('u32', 1),
|
||||
|
|
@ -21,7 +25,10 @@ export const shopInfoRegist: EPR = async (info, data, send) => {
|
|||
}
|
||||
|
||||
export const gameInfoGet: EPR = async (info, data, send) => {
|
||||
|
||||
if (isGalaxyWaveDeltaModel(info.model)) {
|
||||
return gameInfoGetDelta(info, data, send);
|
||||
}
|
||||
|
||||
const eventData = getEventDataResponse()
|
||||
const extraData = getEncoreStageData(info)
|
||||
const VER = getVersion(info)
|
||||
|
|
|
|||
491
gitadora@asphyxia/handlers/info_delta.ts
Normal file
491
gitadora@asphyxia/handlers/info_delta.ts
Normal file
|
|
@ -0,0 +1,491 @@
|
|||
/// <reference lib="es2020.bigint" />
|
||||
|
||||
import { getEncoreStageData } from "../data/extrastage";
|
||||
import Logger from "../utils/logger";
|
||||
import { getVersion } from "../utils";
|
||||
|
||||
const logger = new Logger('info_delta');
|
||||
export const shopInfoRegist: EPR = async (info, data, send) => {
|
||||
send.object({
|
||||
data: {
|
||||
cabid: K.ITEM('u32', 1),
|
||||
locationid: K.ITEM('str', 'Asphyxia'),
|
||||
},
|
||||
temperature: {
|
||||
is_send: K.ITEM('bool', 0),
|
||||
},
|
||||
tax: {
|
||||
tax_phase: K.ITEM('s32', 0),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export const gameInfoGet: EPR = async (info, data, send) => {
|
||||
|
||||
const eventData = getEventDataResponse()
|
||||
const extraData = getEncoreStageData(info)
|
||||
const VER = getVersion(info)
|
||||
if (VER == "galaxywave"){
|
||||
await send.object({
|
||||
now_date: K.ITEM('u64', BigInt(Date.now())),
|
||||
extra: {
|
||||
extra_lv: K.ITEM('s32', extraData.level),
|
||||
extramusic: {
|
||||
music: extraData.musics.map(mid => {
|
||||
return {
|
||||
musicid: K.ITEM('s32', mid),
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
unlock_challenge: { term: K.ITEM('s32', 0) },
|
||||
battle: { term: K.ITEM('s32', 0) },
|
||||
battle_chara: { term: K.ITEM('s32', 0) },
|
||||
data_ver_limit: { term: K.ITEM('s32', 0) },
|
||||
ea_pass_propel: { term: K.ITEM('s32', 0) },
|
||||
monthly_skill: {
|
||||
term: K.ITEM('u8', 0),
|
||||
target_music: {
|
||||
music: {
|
||||
musicid: K.ITEM('s32', 0),
|
||||
},
|
||||
},
|
||||
},
|
||||
update_prog: { term: K.ITEM('s32', 0) },
|
||||
rockwave: {
|
||||
event_list: {
|
||||
event: {
|
||||
data_id: K.ITEM('s32', 0),
|
||||
data_version: K.ITEM('s32', 0),
|
||||
event_id: K.ITEM('s32', 0),
|
||||
event_type: K.ITEM('s32', 0),
|
||||
start_date: K.ITEM('u64', BigInt(0)),
|
||||
end_date: K.ITEM('u64', BigInt(0)),
|
||||
is_open: K.ITEM('bool', 0),
|
||||
bg_no: K.ITEM('s32', 0),
|
||||
target_musicid: K.ITEM('s32', 0),
|
||||
clear_border: K.ITEM('s32', 0),
|
||||
reward_musicid: K.ITEM('s32', 0),
|
||||
reward_musicid_border_list: K.ITEM('s32', 0),
|
||||
reward_stickerid: K.ITEM('s32', 0),
|
||||
reward_stickerid_list: K.ITEM('s32', 0),
|
||||
reward_stickerid_border_list: K.ITEM('s32', 0),
|
||||
firstbit: K.ITEM('s32', 0),
|
||||
quest_no: K.ITEM('s32', 0),
|
||||
target_music_list: {
|
||||
music: {
|
||||
musicid: K.ITEM('s32', 0),
|
||||
}
|
||||
},
|
||||
ranking_list: K.ITEM('u64', BigInt(0)),
|
||||
}
|
||||
}
|
||||
},
|
||||
general_term: {
|
||||
termdata: {
|
||||
type: K.ITEM('str', ''),
|
||||
term: K.ITEM('s32', 0),
|
||||
state: K.ITEM('s32', 0),
|
||||
start_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
end_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
}
|
||||
},
|
||||
galaxy_parade: {
|
||||
corner_list: {},
|
||||
gacha_table: {},
|
||||
},
|
||||
gitadoradon: {},
|
||||
entry_information :{},
|
||||
trbitemdata: {},
|
||||
ctrl_movie: {},
|
||||
ng_jacket: {},
|
||||
ranking: {
|
||||
skill_0_999: {},
|
||||
skill_1000_1499: {},
|
||||
skill_1500_1999: {},
|
||||
skill_2000_2499: {},
|
||||
skill_2500_2999: {},
|
||||
skill_3000_3499: {},
|
||||
skill_3500_3999: {},
|
||||
skill_4000_4499: {},
|
||||
skill_4500_4999: {},
|
||||
skill_5000_5499: {},
|
||||
skill_5500_5999: {},
|
||||
skill_6000_6499: {},
|
||||
skill_6500_6999: {},
|
||||
skill_7000_7499: {},
|
||||
skill_7500_7999: {},
|
||||
skill_8000_8499: {},
|
||||
skill_8500_9999: {},
|
||||
total: {},
|
||||
original: {},
|
||||
bemani: {},
|
||||
famous: {},
|
||||
anime: {},
|
||||
band: {},
|
||||
western: {},
|
||||
},
|
||||
processing_report_state: K.ITEM('u8', 0),
|
||||
assert_report_state: K.ITEM('u8', 0),
|
||||
recommendmusic: { '@attr': { nr: 0 } },
|
||||
demomusic: { '@attr': { nr: 0 } },
|
||||
event_skill: {},
|
||||
temperature: { is_send: K.ITEM('bool', 0) },
|
||||
bemani_summer_2018: { is_open: K.ITEM('bool', 0) },
|
||||
kac2018: {
|
||||
event: {
|
||||
term: K.ITEM('s32', 0),
|
||||
since: K.ITEM('u64', BigInt(0)),
|
||||
till: K.ITEM('u64', BigInt(0)),
|
||||
is_open: K.ITEM('bool', 0),
|
||||
target_music: {
|
||||
music_id: K.ARRAY('s32', [0, 0, 0, 0, 0, 0]),
|
||||
},
|
||||
},
|
||||
},
|
||||
...eventData,
|
||||
});
|
||||
} else if (VER == "fuzzup"){
|
||||
await send.object({
|
||||
now_date: K.ITEM('u64', BigInt(Date.now())),
|
||||
extra: {
|
||||
extra_lv: K.ITEM('u8', extraData.level),
|
||||
extramusic: {
|
||||
music: extraData.musics.map(mid => {
|
||||
return {
|
||||
musicid: K.ITEM('s32', mid),
|
||||
get_border: K.ITEM('u8', 0),
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
infect_music: { term: K.ITEM('u8', 0) },
|
||||
unlock_challenge: { term: K.ITEM('u8', 0) },
|
||||
battle: { term: K.ITEM('u8', 0) },
|
||||
battle_chara: { term: K.ITEM('u8', 0) },
|
||||
data_ver_limit: { term: K.ITEM('s32', 0) },
|
||||
ea_pass_propel: { term: K.ITEM('u8', 0) },
|
||||
monthly_skill: {
|
||||
term: K.ITEM('u8', 0),
|
||||
target_music: {
|
||||
music: {
|
||||
musicid: K.ITEM('s32', 0),
|
||||
},
|
||||
},
|
||||
},
|
||||
update_prog: { term: K.ITEM('u8', 0) },
|
||||
rockwave: { event_list: {} },
|
||||
general_term: {},
|
||||
jubeat_omiyage_challenge: {},
|
||||
kac2017: {},
|
||||
nostalgia_concert: {},
|
||||
trbitemdata: {},
|
||||
ctrl_movie: {},
|
||||
ng_jacket: {},
|
||||
ng_recommend_music: {},
|
||||
ranking: {
|
||||
skill_0_999: {},
|
||||
skill_1000_1499: {},
|
||||
skill_1500_1999: {},
|
||||
skill_2000_2499: {},
|
||||
skill_2500_2999: {},
|
||||
skill_3000_3499: {},
|
||||
skill_3500_3999: {},
|
||||
skill_4000_4499: {},
|
||||
skill_4500_4999: {},
|
||||
skill_5000_5499: {},
|
||||
skill_5500_5999: {},
|
||||
skill_6000_6499: {},
|
||||
skill_6500_6999: {},
|
||||
skill_7000_7499: {},
|
||||
skill_7500_7999: {},
|
||||
skill_8000_8499: {},
|
||||
skill_8500_9999: {},
|
||||
total: {},
|
||||
original: {},
|
||||
bemani: {},
|
||||
famous: {},
|
||||
anime: {},
|
||||
band: {},
|
||||
western: {},
|
||||
},
|
||||
processing_report_state: K.ITEM('u8', 0),
|
||||
assert_report_state: K.ITEM('u8', 0),
|
||||
recommendmusic: { '@attr': { nr: 0 } },
|
||||
demomusic: { '@attr': { nr: 0 } },
|
||||
event_skill: {},
|
||||
temperature: { is_send: K.ITEM('bool', 0) },
|
||||
bemani_summer_2018: { is_open: K.ITEM('bool', 0) },
|
||||
kac2018: {
|
||||
event: {
|
||||
term: K.ITEM('s32', 0),
|
||||
since: K.ITEM('u64', BigInt(0)),
|
||||
till: K.ITEM('u64', BigInt(0)),
|
||||
is_open: K.ITEM('bool', 0),
|
||||
target_music: {
|
||||
music_id: K.ARRAY('s32', [0, 0, 0, 0, 0, 0]),
|
||||
},
|
||||
},
|
||||
},
|
||||
livehouse: {
|
||||
event_list: {
|
||||
event: {
|
||||
is_open: K.ITEM('bool', 0),
|
||||
term: K.ITEM('u8', 0),
|
||||
start_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
end_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
livehouse_name: K.ITEM('str', 'Asphyxia'),
|
||||
reward_list: {
|
||||
reward: {
|
||||
reward_id: K.ITEM('s32', 0),
|
||||
reward_kind: K.ITEM('s32', 0),
|
||||
reward_itemid: K.ITEM('s32', 0),
|
||||
unlock_border: K.ITEM('s32', 0),
|
||||
},
|
||||
},
|
||||
requirements_musicid: K.ITEM('s32', 0),
|
||||
member_table: K.ITEM('s32', 0),
|
||||
},
|
||||
},
|
||||
bonus: {
|
||||
term: K.ITEM('u8', 0),
|
||||
stage_bonus: K.ITEM('s32', 0),
|
||||
charm_bonus: K.ITEM('s32', 0),
|
||||
start_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
end_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
},
|
||||
},
|
||||
...eventData,
|
||||
});
|
||||
}//Older
|
||||
else {
|
||||
await send.object({
|
||||
now_date: K.ITEM('u64', BigInt(Date.now())),
|
||||
extra: {
|
||||
extra_lv: K.ITEM('u8', extraData.level),
|
||||
extramusic: {
|
||||
music: extraData.musics.map(mid => {
|
||||
return {
|
||||
musicid: K.ITEM('s32', mid),
|
||||
get_border: K.ITEM('u8', 0),
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
infect_music: { term: K.ITEM('u8', 0) },
|
||||
unlock_challenge: { term: K.ITEM('u8', 0) },
|
||||
battle: { term: K.ITEM('u8', 0) },
|
||||
battle_chara: { term: K.ITEM('u8', 0) },
|
||||
data_ver_limit: { term: K.ITEM('u8', 0) },
|
||||
ea_pass_propel: { term: K.ITEM('u8', 0) },
|
||||
monthly_skill: {
|
||||
term: K.ITEM('u8', 0),
|
||||
target_music: {
|
||||
music: {
|
||||
musicid: K.ITEM('s32', 0),
|
||||
},
|
||||
},
|
||||
},
|
||||
update_prog: { term: K.ITEM('u8', 0) },
|
||||
rockwave: { event_list: {} },
|
||||
general_term: {},
|
||||
jubeat_omiyage_challenge: {},
|
||||
kac2017: {},
|
||||
nostalgia_concert: {},
|
||||
trbitemdata: {},
|
||||
ctrl_movie: {},
|
||||
ng_jacket: {},
|
||||
ng_recommend_music: {},
|
||||
ranking: {
|
||||
skill_0_999: {},
|
||||
skill_1000_1499: {},
|
||||
skill_1500_1999: {},
|
||||
skill_2000_2499: {},
|
||||
skill_2500_2999: {},
|
||||
skill_3000_3499: {},
|
||||
skill_3500_3999: {},
|
||||
skill_4000_4499: {},
|
||||
skill_4500_4999: {},
|
||||
skill_5000_5499: {},
|
||||
skill_5500_5999: {},
|
||||
skill_6000_6499: {},
|
||||
skill_6500_6999: {},
|
||||
skill_7000_7499: {},
|
||||
skill_7500_7999: {},
|
||||
skill_8000_8499: {},
|
||||
skill_8500_9999: {},
|
||||
total: {},
|
||||
original: {},
|
||||
bemani: {},
|
||||
famous: {},
|
||||
anime: {},
|
||||
band: {},
|
||||
western: {},
|
||||
},
|
||||
processing_report_state: K.ITEM('u8', 0),
|
||||
assert_report_state: K.ITEM('u8', 0),
|
||||
recommendmusic: { '@attr': { nr: 0 } },
|
||||
demomusic: { '@attr': { nr: 0 } },
|
||||
event_skill: {},
|
||||
temperature: { is_send: K.ITEM('bool', 0) },
|
||||
bemani_summer_2018: { is_open: K.ITEM('bool', 0) },
|
||||
kac2018: {
|
||||
event: {
|
||||
term: K.ITEM('s32', 0),
|
||||
since: K.ITEM('u64', BigInt(0)),
|
||||
till: K.ITEM('u64', BigInt(0)),
|
||||
is_open: K.ITEM('bool', 0),
|
||||
target_music: {
|
||||
music_id: K.ARRAY('s32', [0, 0, 0, 0, 0, 0]),
|
||||
},
|
||||
},
|
||||
},
|
||||
KAC2016: {
|
||||
is_entry: K.ITEM('bool', 0),
|
||||
term: K.ITEM('u8', 0),
|
||||
musicid: K.ITEM('s32', 0),
|
||||
},
|
||||
KAC2016_skill_ranking: { term: K.ITEM('u8', 0) },
|
||||
season_sticker: { term: K.ITEM('u8', 0) },
|
||||
paseli_point_lose: { term: K.ITEM('u8', 0) },
|
||||
nostal_link: { term: K.ITEM('u8', 0) },
|
||||
encore_advent: { term: K.ITEM('u8', 0) },
|
||||
sdvx_stamprally: { term: K.ITEM('u8', 0) },
|
||||
sdvx_stamprally2: { term: K.ITEM('u8', 0) },
|
||||
floor_policy_2_info: { term: K.ITEM('u8', 0) },
|
||||
long_otobear_fes_2: {
|
||||
term: K.ITEM('u8', 0),
|
||||
bonus_musicid: K.ITEM('s32', 0),
|
||||
},
|
||||
...eventData,
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
function getEventDataResponse() {
|
||||
const addition: any = {
|
||||
monstar_subjugation: {
|
||||
bonus_musicid: K.ITEM('s32', 0),
|
||||
},
|
||||
bear_fes: {},
|
||||
nextadium: {},
|
||||
galaxy_parade: {
|
||||
corner_list: {
|
||||
corner: {
|
||||
is_open: K.ITEM('bool', 0),
|
||||
data_ver: K.ITEM('s32', 0),
|
||||
genre: K.ITEM('s32', 0),
|
||||
corner_id: K.ITEM('s32', 0),
|
||||
corner_name: K.ITEM('str', ''),
|
||||
start_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
end_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
requirements_musicid: K.ITEM('s32', 0),
|
||||
reward_list: {
|
||||
reward: {
|
||||
reward_id: K.ITEM('s32', 0),
|
||||
reward_kind: K.ITEM('s32', 0),
|
||||
reward_itemid: K.ITEM('s32', 0),
|
||||
unlock_border: K.ITEM('s32', 0),
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
gacha_table: {
|
||||
chara_odds: {
|
||||
chara_id: K.ITEM('s32', 0),
|
||||
odds: K.ITEM('s32', 0),
|
||||
}
|
||||
},
|
||||
bonus: {
|
||||
term: K.ITEM('s32', 0),
|
||||
stage_bonus: K.ITEM('s32', 0),
|
||||
charm_bonus: K.ITEM('s32', 0),
|
||||
start_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
end_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
}
|
||||
},
|
||||
};
|
||||
const time = BigInt(31536000);
|
||||
|
||||
for (let i = 1; i <= 20; ++i) {
|
||||
const obj = {
|
||||
term: K.ITEM('u8', 0),
|
||||
start_date_ms: K.ITEM('u64', time),
|
||||
end_date_ms: K.ITEM('u64', time),
|
||||
};
|
||||
if (i == 1) {
|
||||
addition[`phrase_combo_challenge`] = obj;
|
||||
addition[`long_otobear_fes_1`] = {
|
||||
term: K.ITEM('u8', 0),
|
||||
start_date_ms: K.ITEM('u64', time),
|
||||
end_date_ms: K.ITEM('u64', time),
|
||||
//bonus_musicid: {},
|
||||
bonus_musicid: K.ITEM('s32', 0),
|
||||
};
|
||||
addition[`sdvx_stamprally3`] = obj;
|
||||
addition[`chronicle_1`] = obj;
|
||||
addition[`paseli_point_lottery`] = obj;
|
||||
addition['sticker_campaign'] = {
|
||||
term: K.ITEM('u8', 0),
|
||||
sticker_list: {},
|
||||
};
|
||||
addition['thanksgiving'] = {
|
||||
...obj,
|
||||
box_term: {
|
||||
state: K.ITEM('u8', 0)
|
||||
}
|
||||
};
|
||||
addition['lotterybox'] = {
|
||||
...obj,
|
||||
box_term: {
|
||||
state: K.ITEM('u8', 0)
|
||||
}
|
||||
};
|
||||
} else {
|
||||
addition[`phrase_combo_challenge_${i}`] = obj;
|
||||
}
|
||||
|
||||
if (i <= 4) {
|
||||
addition['monstar_subjugation'][`monstar_subjugation_${i}`] = obj;
|
||||
addition['bear_fes'][`bear_fes_${i}`] = obj;
|
||||
}
|
||||
|
||||
if (i <= 2) {
|
||||
addition[`gitadora_oracle_${i}`] = {
|
||||
term: K.ITEM('u8', 0),
|
||||
bonus_musicid: K.ITEM('s32', 0),
|
||||
};
|
||||
addition[`gitadora_oracle_${i}`] = {
|
||||
term: K.ITEM('u8', 0),
|
||||
bonus_musicid: K.ITEM('s32', 0),
|
||||
};
|
||||
}
|
||||
|
||||
if (i <= 3) {
|
||||
addition[`kouyou_challenge_${i}`] = {
|
||||
term: K.ITEM('u8', 0),
|
||||
bonus_musicid: K.ITEM('s32', 0),
|
||||
};
|
||||
addition[`dokidoki_valentine2_${i}`] = {
|
||||
term: K.ITEM('u8', 0),
|
||||
bonus_musicid: K.ITEM('s32', 0),
|
||||
};
|
||||
addition[`wakuteka_whiteday2_${i}`] = { term: K.ITEM('u8', 0) };
|
||||
addition[`ohanami_challenge_${i}`] = {
|
||||
term: K.ITEM('u8', 0),
|
||||
bonus_musicid: K.ITEM('s32', 0),
|
||||
};
|
||||
addition[`otobear_in_the_tsubo_${i}`] = {
|
||||
term: K.ITEM('u8', 0),
|
||||
bonus_musicid: K.ITEM('s32', 0),
|
||||
};
|
||||
addition[`summer_craft_${i}`] = {
|
||||
term: K.ITEM('u8', 0),
|
||||
bonus_musicid: K.ITEM('s32', 0),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return addition
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ import { PlayerRanking } from "../models/playerranking";
|
|||
import { getDefaultProfile, Profile } from "../models/profile";
|
||||
import { getDefaultRecord, Record } from "../models/record";
|
||||
import { Extra, getDefaultExtra } from "../models/extra";
|
||||
import { getVersion, isDM } from "../utils";
|
||||
import { getVersion, isDM, isGalaxyWaveDeltaModel } from "../utils";
|
||||
import { getDefaultScores, Scores } from "../models/scores";
|
||||
|
||||
import { PLUGIN_VER } from "../const";
|
||||
|
|
@ -21,10 +21,14 @@ import { applySharedFavoriteMusicToExtra, saveSharedFavoriteMusicFromExtra } fro
|
|||
import { getPlayerRecordResponse } from "../models/Responses/playerrecordresponse";
|
||||
import { getPlayerPlayInfoResponse, PlayerPlayInfoResponse } from "../models/Responses/playerplayinforesponse";
|
||||
import { getMergedSharedScores, mergeScoresIntoShared } from "./SharedScores";
|
||||
import { regist as registDelta, check as checkDelta, getPlayer as getPlayerDelta, savePlayers as savePlayersDelta } from "./profiles_delta";
|
||||
|
||||
const logger = new Logger("profiles")
|
||||
|
||||
export const regist: EPR = async (info, data, send) => {
|
||||
if (isGalaxyWaveDeltaModel(info.model)) {
|
||||
return registDelta(info, data, send);
|
||||
}
|
||||
|
||||
const refid = $(data).str('player.refid');
|
||||
if (!refid) {
|
||||
|
|
@ -46,6 +50,9 @@ export const regist: EPR = async (info, data, send) => {
|
|||
}
|
||||
|
||||
export const check: EPR = async (info, data, send) => {
|
||||
if (isGalaxyWaveDeltaModel(info.model)) {
|
||||
return checkDelta(info, data, send);
|
||||
}
|
||||
|
||||
const refid = $(data).str('player.refid');
|
||||
if (!refid) {
|
||||
|
|
@ -62,6 +69,10 @@ export const check: EPR = async (info, data, send) => {
|
|||
}
|
||||
|
||||
export const getPlayer: EPR = async (info, data, send) => {
|
||||
if (isGalaxyWaveDeltaModel(info.model)) {
|
||||
return getPlayerDelta(info, data, send);
|
||||
}
|
||||
|
||||
const refid = $(data).str('player.refid');
|
||||
if (!refid) {
|
||||
logger.error("Request data is missing required parameter: player.refid")
|
||||
|
|
@ -522,6 +533,9 @@ async function registerUser(refid: string, version: string, id = _.random(0, 999
|
|||
}
|
||||
|
||||
export const savePlayers: EPR = async (info, data, send) => {
|
||||
if (isGalaxyWaveDeltaModel(info.model)) {
|
||||
return savePlayersDelta(info, data, send);
|
||||
}
|
||||
|
||||
const version = getVersion(info);
|
||||
const dm = isDM(info);
|
||||
|
|
|
|||
901
gitadora@asphyxia/handlers/profiles_delta.ts
Normal file
901
gitadora@asphyxia/handlers/profiles_delta.ts
Normal file
|
|
@ -0,0 +1,901 @@
|
|||
/// <reference lib="es2020.bigint" />
|
||||
|
||||
import { getDefaultPlayerInfo, PlayerInfo } from "../models/playerinfo";
|
||||
import { PlayerRanking } from "../models/playerranking";
|
||||
import { getDefaultProfile, Profile } from "../models/profile";
|
||||
import { getDefaultRecord, Record } from "../models/record";
|
||||
import { Extra, getDefaultExtra } from "../models/extra";
|
||||
import { isDM } from "../utils";
|
||||
|
||||
const DELTA_VERSION = "galaxywave_delta";
|
||||
import { getDefaultScores, Scores } from "../models/scores";
|
||||
|
||||
import { PLUGIN_VER } from "../const";
|
||||
import Logger from "../utils/logger"
|
||||
import { isAsphyxiaDebugMode, isSharedSongScoresEnabled } from "../utils/index";
|
||||
import { SecretMusicEntry } from "../models/secretmusicentry";
|
||||
import { CheckPlayerResponse, getCheckPlayerResponse } from "../models/Responses/checkplayerresponse";
|
||||
import { getPlayerStickerResponse, PlayerStickerResponse } from "../models/Responses/playerstickerresponse";
|
||||
import { getSecretMusicResponse, SecretMusicResponse } from "../models/Responses/secretmusicresponse";
|
||||
import { getSaveProfileResponse } from "../models/Responses/saveprofileresponse";
|
||||
import { getDefaultBattleDataResponse } from "../models/Responses/battledataresponse";
|
||||
import { applySharedFavoriteMusicToExtra, saveSharedFavoriteMusicFromExtra } from "./FavoriteMusic";
|
||||
import { getPlayerRecordResponse } from "../models/Responses/playerrecordresponse";
|
||||
import { getPlayerPlayInfoResponse, PlayerPlayInfoResponse } from "../models/Responses/playerplayinforesponse";
|
||||
import { getMergedSharedScores, mergeScoresIntoShared } from "./SharedScores";
|
||||
|
||||
const logger = new Logger("profiles_delta")
|
||||
|
||||
export const regist: EPR = async (info, data, send) => {
|
||||
|
||||
const refid = $(data).str('player.refid');
|
||||
if (!refid) {
|
||||
logger.error("Request data is missing required parameter: player.refid")
|
||||
return send.deny();
|
||||
}
|
||||
|
||||
const no = getPlayerNo(data);
|
||||
const version = DELTA_VERSION;
|
||||
const playerInfo = await getOrRegisterPlayerInfo(refid, version, no);
|
||||
|
||||
await send.object({
|
||||
player: K.ATTR({ no: `${no}` }, {
|
||||
is_succession: K.ITEM("bool", 0),
|
||||
did: K.ITEM("s32", playerInfo.id)
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
export const check: EPR = async (info, data, send) => {
|
||||
|
||||
const refid = $(data).str('player.refid');
|
||||
if (!refid) {
|
||||
logger.error("Request data is missing required parameter: player.refid")
|
||||
return send.deny();
|
||||
}
|
||||
|
||||
const no = getPlayerNo(data);
|
||||
const version = DELTA_VERSION;
|
||||
const playerInfo = await getOrRegisterPlayerInfo(refid, version, no)
|
||||
|
||||
const result : CheckPlayerResponse = getCheckPlayerResponse(no, playerInfo.name, playerInfo.id)
|
||||
await send.object(result)
|
||||
}
|
||||
|
||||
export const getPlayer: EPR = async (info, data, send) => {
|
||||
const refid = $(data).str('player.refid');
|
||||
if (!refid) {
|
||||
logger.error("Request data is missing required parameter: player.refid")
|
||||
return send.deny();
|
||||
}
|
||||
|
||||
const no = getPlayerNo(data);
|
||||
const version = DELTA_VERSION;
|
||||
const time = BigInt(31536000);
|
||||
const dm = isDM(info);
|
||||
const game = dm ? 'dm' : 'gf';
|
||||
const sharedScoresEnabled = isSharedSongScoresEnabled();
|
||||
|
||||
logger.debugInfo(`Loading ${game} profile for player ${no} with refid: ${refid}`)
|
||||
const name = await DB.FindOne<PlayerInfo>(refid, {
|
||||
collection: 'playerinfo',
|
||||
version
|
||||
})
|
||||
const dmProfile = await getProfile(refid, version, 'dm')
|
||||
const gfProfile = await getProfile(refid, version, 'gf')
|
||||
const dmRecord = await getRecord(refid, version, 'dm')
|
||||
const gfRecord = await getRecord(refid, version, 'gf')
|
||||
const dmExtra = await getExtra(refid, version, 'dm')
|
||||
const gfExtra = await getExtra(refid, version, 'gf')
|
||||
const dmScores = sharedScoresEnabled ? await getMergedSharedScores(refid, 'dm') : (await getScore(refid, version, 'dm')).scores
|
||||
const gfScores = sharedScoresEnabled ? await getMergedSharedScores(refid, 'gf') : (await getScore(refid, version, 'gf')).scores
|
||||
|
||||
const profile = dm ? dmProfile : gfProfile;
|
||||
const extra = dm ? dmExtra : gfExtra;
|
||||
applyPlayHudPreset(extra.playstyle);
|
||||
|
||||
await applySharedFavoriteMusicToExtra(refid, extra)
|
||||
|
||||
const record: any = {
|
||||
gf: getPlayerRecordResponse(gfProfile, gfRecord),
|
||||
dm: getPlayerRecordResponse(dmProfile, dmRecord),
|
||||
};
|
||||
|
||||
// Format scores
|
||||
const musicdata = [];
|
||||
const scores = dm ? dmScores : gfScores;
|
||||
for (const [musicid, score] of _.entries(scores)) {
|
||||
musicdata.push(K.ATTR({ musicid }, {
|
||||
mdata: K.ARRAY('s16', [
|
||||
-1,
|
||||
_.get(score, 'diffs.1.clear', false) ? _.get(score, 'diffs.1.perc', -2) : -1,
|
||||
_.get(score, 'diffs.2.clear', false) ? _.get(score, 'diffs.2.perc', -2) : -1,
|
||||
_.get(score, 'diffs.3.clear', false) ? _.get(score, 'diffs.3.perc', -2) : -1,
|
||||
_.get(score, 'diffs.4.clear', false) ? _.get(score, 'diffs.4.perc', -2) : -1,
|
||||
_.get(score, 'diffs.5.clear', false) ? _.get(score, 'diffs.5.perc', -2) : -1,
|
||||
_.get(score, 'diffs.6.clear', false) ? _.get(score, 'diffs.6.perc', -2) : -1,
|
||||
_.get(score, 'diffs.7.clear', false) ? _.get(score, 'diffs.7.perc', -2) : -1,
|
||||
_.get(score, 'diffs.8.clear', false) ? _.get(score, 'diffs.8.perc', -2) : -1,
|
||||
_.get(score, 'diffs.1.clear', false) ? _.get(score, 'diffs.1.rank', 0) : -1,
|
||||
_.get(score, 'diffs.2.clear', false) ? _.get(score, 'diffs.2.rank', 0) : -1,
|
||||
_.get(score, 'diffs.3.clear', false) ? _.get(score, 'diffs.3.rank', 0) : -1,
|
||||
_.get(score, 'diffs.4.clear', false) ? _.get(score, 'diffs.4.rank', 0) : -1,
|
||||
_.get(score, 'diffs.5.clear', false) ? _.get(score, 'diffs.5.rank', 0) : -1,
|
||||
_.get(score, 'diffs.6.clear', false) ? _.get(score, 'diffs.6.rank', 0) : -1,
|
||||
_.get(score, 'diffs.7.clear', false) ? _.get(score, 'diffs.7.rank', 0) : -1,
|
||||
_.get(score, 'diffs.8.clear', false) ? _.get(score, 'diffs.8.rank', 0) : -1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
]),
|
||||
flag: K.ARRAY('u16', [
|
||||
_.get(score, 'diffs.1.fc', false) * 2 +
|
||||
_.get(score, 'diffs.2.fc', false) * 4 +
|
||||
_.get(score, 'diffs.3.fc', false) * 8 +
|
||||
_.get(score, 'diffs.4.fc', false) * 16 +
|
||||
_.get(score, 'diffs.5.fc', false) * 32 +
|
||||
_.get(score, 'diffs.6.fc', false) * 64 +
|
||||
_.get(score, 'diffs.7.fc', false) * 128 +
|
||||
_.get(score, 'diffs.8.fc', false) * 256,
|
||||
_.get(score, 'diffs.1.ex', false) * 2 +
|
||||
_.get(score, 'diffs.2.ex', false) * 4 +
|
||||
_.get(score, 'diffs.3.ex', false) * 8 +
|
||||
_.get(score, 'diffs.4.ex', false) * 16 +
|
||||
_.get(score, 'diffs.5.ex', false) * 32 +
|
||||
_.get(score, 'diffs.6.ex', false) * 64 +
|
||||
_.get(score, 'diffs.7.ex', false) * 128 +
|
||||
_.get(score, 'diffs.8.ex', false) * 256,
|
||||
_.get(score, 'diffs.1.clear', false) * 2 +
|
||||
_.get(score, 'diffs.2.clear', false) * 4 +
|
||||
_.get(score, 'diffs.3.clear', false) * 8 +
|
||||
_.get(score, 'diffs.4.clear', false) * 16 +
|
||||
_.get(score, 'diffs.5.clear', false) * 32 +
|
||||
_.get(score, 'diffs.6.clear', false) * 64 +
|
||||
_.get(score, 'diffs.7.clear', false) * 128 +
|
||||
_.get(score, 'diffs.8.clear', false) * 256,
|
||||
0,
|
||||
0,
|
||||
]),
|
||||
sdata: K.ARRAY('s16', score.update),
|
||||
meter: K.ARRAY('u64', [
|
||||
BigInt(_.get(score, 'diffs.1.meter', '0')),
|
||||
BigInt(_.get(score, 'diffs.2.meter', '0')),
|
||||
BigInt(_.get(score, 'diffs.3.meter', '0')),
|
||||
BigInt(_.get(score, 'diffs.4.meter', '0')),
|
||||
BigInt(_.get(score, 'diffs.5.meter', '0')),
|
||||
BigInt(_.get(score, 'diffs.6.meter', '0')),
|
||||
BigInt(_.get(score, 'diffs.7.meter', '0')),
|
||||
BigInt(_.get(score, 'diffs.8.meter', '0')),
|
||||
]),
|
||||
meter_prog: K.ARRAY('s16', [
|
||||
_.get(score, 'diffs.1.prog', 0),
|
||||
_.get(score, 'diffs.2.prog', 0),
|
||||
_.get(score, 'diffs.3.prog', 0),
|
||||
_.get(score, 'diffs.4.prog', 0),
|
||||
_.get(score, 'diffs.5.prog', 0),
|
||||
_.get(score, 'diffs.6.prog', 0),
|
||||
_.get(score, 'diffs.7.prog', 0),
|
||||
_.get(score, 'diffs.8.prog', 0),
|
||||
]),
|
||||
}));
|
||||
}
|
||||
|
||||
const sticker: PlayerStickerResponse[] = getPlayerStickerResponse(name.card);
|
||||
const playinfo: PlayerPlayInfoResponse = getPlayerPlayInfoResponse(profile);
|
||||
|
||||
const playerData: any = {
|
||||
playerboard: {
|
||||
index: K.ITEM('s32', 1),
|
||||
is_active: K.ITEM('bool', _.isArray(name.card) ? 1 : 0),
|
||||
sticker,
|
||||
},
|
||||
player_info: {
|
||||
player_type: K.ITEM('s8', 0),
|
||||
did: K.ITEM('s32', 13376666),
|
||||
name: K.ITEM('str', name.name),
|
||||
title: K.ITEM('str', name.title),
|
||||
charaid: K.ITEM('s32', 0),
|
||||
},
|
||||
customdata: {
|
||||
playstyle: K.ARRAY('s32', extra.playstyle),
|
||||
custom: K.ARRAY('s32', extra.custom),
|
||||
},
|
||||
playinfo: playinfo,
|
||||
tutorial: {
|
||||
progress: K.ITEM('s32', profile.progress),
|
||||
disp_state: K.ITEM('u32', profile.disp_state),
|
||||
},
|
||||
skilldata: {
|
||||
skill: K.ITEM('s32', profile.skill),
|
||||
all_skill: K.ITEM('s32', profile.all_skill),
|
||||
old_skill: K.ITEM('s32', 0),
|
||||
old_all_skill: K.ITEM('s32', 0),
|
||||
},
|
||||
favoritemusic: {
|
||||
list_1: K.ARRAY('s32', extra.list_1),
|
||||
list_2: K.ARRAY('s32', extra.list_2),
|
||||
list_3: K.ARRAY('s32', extra.list_3),
|
||||
},
|
||||
recommend_musicid_list: K.ARRAY('s32', extra.recommend_musicid_list ?? Array(5).fill(-1)),
|
||||
record,
|
||||
groove: {
|
||||
extra_gauge: K.ITEM('s32', (profile.extra_gauge+95)),
|
||||
encore_gauge: K.ITEM('s32', profile.encore_gauge),
|
||||
encore_cnt: K.ITEM('s32', profile.encore_cnt),
|
||||
encore_success: K.ITEM('s32', profile.encore_success),
|
||||
unlock_point: K.ITEM('s32', profile.unlock_point),
|
||||
},
|
||||
musiclist: { '@attr': { nr: musicdata.length }, musicdata },
|
||||
deluxe: {
|
||||
deluxe_content: K.ITEM('s32', 0),
|
||||
target_id: K.ITEM('s32', 0),
|
||||
multiply: K.ITEM('s32', 0),
|
||||
point: K.ITEM('s32', 0),
|
||||
},
|
||||
galaxy_parade: {
|
||||
score_list: {},
|
||||
last_corner_id: K.ITEM('s32', 0),
|
||||
chara_list: {},
|
||||
last_sort_category: K.ITEM('s32', 0),
|
||||
last_sort_order: K.ITEM('s32', 0),
|
||||
team_member: {
|
||||
chara_id_guitar: K.ITEM('s32', 0),
|
||||
chara_id_bass: K.ITEM('s32', 0),
|
||||
chara_id_drum: K.ITEM('s32', 0),
|
||||
chara_id_free1: K.ITEM('s32', 0),
|
||||
chara_id_free2: K.ITEM('s32', 0),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const playerRanking = await getPlayerRanking(refid, version, game)
|
||||
|
||||
const addition: any = {
|
||||
monstar_subjugation: {},
|
||||
bear_fes: {},
|
||||
galaxy_parade: {
|
||||
corner_list: {
|
||||
corner: {
|
||||
is_open: K.ITEM('bool', 0),
|
||||
data_ver: K.ITEM('s32', 0),
|
||||
genre: K.ITEM('s32', 0),
|
||||
corner_id: K.ITEM('s32', 0),
|
||||
corner_name: K.ITEM('str', ''),
|
||||
start_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
end_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
requirements_musicid: K.ITEM('s32', 0),
|
||||
reward_list: {
|
||||
reward: {
|
||||
reward_id: K.ITEM('s32', 0),
|
||||
reward_kind: K.ITEM('s32', 0),
|
||||
reward_itemid: K.ITEM('s32', 0),
|
||||
unlock_border: K.ITEM('s32', 0),
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
gacha_table: {
|
||||
chara_odds: {
|
||||
chara_id: K.ITEM('s32', 0),
|
||||
odds: K.ITEM('s32', 0),
|
||||
}
|
||||
},
|
||||
bonus: {
|
||||
term: K.ITEM('s32', 0),
|
||||
stage_bonus: K.ITEM('s32', 0),
|
||||
charm_bonus: K.ITEM('s32', 0),
|
||||
start_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
end_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
}
|
||||
},
|
||||
};
|
||||
for (let i = 1; i <= 20; ++i) {
|
||||
const obj = { point: K.ITEM('s32', 0) };
|
||||
if (i == 1) {
|
||||
addition['long_otobear_fes_1'] = obj;
|
||||
addition['long_otobear_fes_2'] = obj;
|
||||
addition['phrase_combo_challenge'] = obj;
|
||||
addition['sdvx_stamprally'] = obj;
|
||||
addition['sdvx_stamprally2'] = obj;
|
||||
addition['sdvx_stamprally3'] = obj;
|
||||
addition['chronicle_1'] = obj;
|
||||
addition['gitadora_oracle_1'] = obj;
|
||||
addition['gitadora_oracle_2'] = obj;
|
||||
} else {
|
||||
addition[`phrase_combo_challenge_${i}`] = obj;
|
||||
}
|
||||
|
||||
if (i <= 4) {
|
||||
addition.bear_fes[`bear_fes_${i}`] = {
|
||||
stage: K.ITEM('s32', 0),
|
||||
point: K.ARRAY('s32', [0, 0, 0, 0, 0, 0, 0, 0]),
|
||||
};
|
||||
}
|
||||
|
||||
if (i <= 3) {
|
||||
addition.monstar_subjugation[`monstar_subjugation_${i}`] = {
|
||||
stage: K.ITEM('s32', 0),
|
||||
point_1: K.ITEM('s32', 0),
|
||||
point_2: K.ITEM('s32', 0),
|
||||
point_3: K.ITEM('s32', 0),
|
||||
};
|
||||
addition[`kouyou_challenge_${i}`] = { point: K.ITEM('s32', 0) };
|
||||
addition[`dokidoki_valentine2_${i}`] = { point: K.ITEM('s32', 0) };
|
||||
addition[`ohanami_challenge_${i}`] = { point: K.ITEM('s32', 0) };
|
||||
addition[`otobear_in_the_tsubo_${i}`] = { point: K.ITEM('s32', 0) };
|
||||
addition[`summer_craft_${i}`] = { point: K.ITEM('s32', 0) };
|
||||
addition[`wakuteka_whiteday2_${i}`] = {
|
||||
point_1: K.ITEM('s32', 0),
|
||||
point_2: K.ITEM('s32', 0),
|
||||
point_3: K.ITEM('s32', 0),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const innerSecretMusic = getSecretMusicResponse(profile)
|
||||
const innerFriendData = getFriendDataResponse(profile)
|
||||
const innerBattleData = getDefaultBattleDataResponse()
|
||||
|
||||
const response = {
|
||||
player: K.ATTR({ 'no': `${no}` }, {
|
||||
now_date: K.ITEM('u64', time),
|
||||
secretmusic: {
|
||||
music: innerSecretMusic
|
||||
},
|
||||
chara_list: {},
|
||||
title_parts: {},
|
||||
information: {
|
||||
info: K.ARRAY('u32', Array(50).fill(0)),
|
||||
},
|
||||
reward: {
|
||||
status: K.ARRAY('u32', extra.reward_status ?? Array(50).fill(0)),
|
||||
},
|
||||
rivaldata: {},
|
||||
frienddata: {
|
||||
friend: innerFriendData
|
||||
},
|
||||
|
||||
thanks_medal: {
|
||||
medal: K.ITEM('s32', 0),
|
||||
grant_medal: K.ITEM('s32', 0),
|
||||
grant_total_medal: K.ITEM('s32', 0),
|
||||
},
|
||||
recommend_musicid_list: K.ARRAY('s32', extra.recommend_musicid_list ?? Array(5).fill(-1)),
|
||||
skindata: {
|
||||
skin: K.ARRAY('u32', Array(100).fill(-1)),
|
||||
},
|
||||
battledata: innerBattleData,
|
||||
is_free_ok: K.ITEM('bool', 0),
|
||||
ranking: {
|
||||
skill: { rank: K.ITEM('s32', playerRanking.skill), total_nr: K.ITEM('s32', playerRanking.totalPlayers) },
|
||||
all_skill: { rank: K.ITEM('s32', playerRanking.all_skill), total_nr: K.ITEM('s32', playerRanking.totalPlayers) },
|
||||
},
|
||||
stage_result: {},
|
||||
monthly_skill: {},
|
||||
event_skill: {
|
||||
skill: K.ITEM('s32', 0),
|
||||
ranking: {
|
||||
rank: K.ITEM('s32', 0),
|
||||
total_nr: K.ITEM('s32', 0),
|
||||
},
|
||||
eventlist: {},
|
||||
},
|
||||
event_score: { eventlist: {} },
|
||||
rockwave: { score_list: {} },
|
||||
livehouse: {
|
||||
score_list: {
|
||||
score: {
|
||||
term: K.ITEM('u8', -1),
|
||||
reward_id: K.ITEM('s32', -1),
|
||||
unlock_point: K.ITEM('s32', -1),
|
||||
chara_id_guitar: K.ITEM('s32', -1),
|
||||
chara_id_bass: K.ITEM('s32', -1),
|
||||
chara_id_drum: K.ITEM('s32', -1),
|
||||
chara_id_other: K.ITEM('s32', -1),
|
||||
leader: K.ITEM('s32', -1),
|
||||
},
|
||||
last_livehouse: K.ITEM('s32', -1),
|
||||
}
|
||||
},
|
||||
jubeat_omiyage_challenge: {},
|
||||
light_mode_reward_item: { itemid: K.ITEM('s32', -1), rarity: K.ITEM('s32', 0) },
|
||||
standard_mode_reward_item: { itemid: K.ITEM('s32', -1), rarity: K.ITEM('s32', 0) },
|
||||
delux_mode_reward_item: { itemid: K.ITEM('s32', -1), rarity: K.ITEM('s32', 0) },
|
||||
kac2018: {
|
||||
entry_status: K.ITEM('s32', 0),
|
||||
data: {
|
||||
term: K.ITEM('s32', 0),
|
||||
total_score: K.ITEM('s32', 0),
|
||||
score: K.ARRAY('s32', [0, 0, 0, 0, 0, 0]),
|
||||
music_type: K.ARRAY('s32', [0, 0, 0, 0, 0, 0]),
|
||||
play_count: K.ARRAY('s32', [0, 0, 0, 0, 0, 0]),
|
||||
},
|
||||
},
|
||||
sticker_campaign: {},
|
||||
kac2017: {
|
||||
entry_status: K.ITEM('s32', 0),
|
||||
},
|
||||
KAC2016: {
|
||||
is_entry: K.ITEM('bool', 0),
|
||||
},
|
||||
KAC2016_skill_ranking: {
|
||||
skill: {
|
||||
skill: K.ITEM('s32', -1),
|
||||
rank: K.ITEM('s32', -1),
|
||||
total_nr: K.ITEM('s32', -1),
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
nostalgia_concert: {},
|
||||
bemani_summer_2018: {
|
||||
linkage_id: K.ITEM('s32', -1),
|
||||
is_entry: K.ITEM('bool', 0),
|
||||
target_music_idx: K.ITEM('s32', -1),
|
||||
point_1: K.ITEM('s32', 0),
|
||||
point_2: K.ITEM('s32', 0),
|
||||
point_3: K.ITEM('s32', 0),
|
||||
point_4: K.ITEM('s32', 0),
|
||||
point_5: K.ITEM('s32', 0),
|
||||
point_6: K.ITEM('s32', 0),
|
||||
point_7: K.ITEM('s32', 0),
|
||||
reward_1: K.ITEM('bool', 0),
|
||||
reward_2: K.ITEM('bool', 0),
|
||||
reward_3: K.ITEM('bool', 0),
|
||||
reward_4: K.ITEM('bool', 0),
|
||||
reward_5: K.ITEM('bool', 0),
|
||||
reward_6: K.ITEM('bool', 0),
|
||||
reward_7: K.ITEM('bool', 0),
|
||||
unlock_status_1: K.ITEM('s32', 0),
|
||||
unlock_status_2: K.ITEM('s32', 0),
|
||||
unlock_status_3: K.ITEM('s32', 0),
|
||||
unlock_status_4: K.ITEM('s32', 0),
|
||||
unlock_status_5: K.ITEM('s32', 0),
|
||||
unlock_status_6: K.ITEM('s32', 0),
|
||||
unlock_status_7: K.ITEM('s32', 0),
|
||||
},
|
||||
thanksgiving: {
|
||||
term: K.ITEM("u8", 0),
|
||||
score: {
|
||||
one_day_play_cnt: K.ITEM("s32", 0),
|
||||
one_day_lottery_cnt: K.ITEM("s32", 0),
|
||||
lucky_star: K.ITEM("s32", 0),
|
||||
bear_mark: K.ITEM("s32", 0),
|
||||
play_date_ms: K.ITEM("u64", BigInt(0))
|
||||
},
|
||||
lottery_result: {
|
||||
unlock_bit: K.ITEM("u64", BigInt(0))
|
||||
}
|
||||
},
|
||||
lotterybox: {},
|
||||
...addition,
|
||||
...playerData,
|
||||
finish: K.ITEM('bool', 1),
|
||||
}),
|
||||
}
|
||||
|
||||
if (isAsphyxiaDebugMode()) {
|
||||
await IO.WriteFile(`apisamples/lastGetPlayerRequest.json`, JSON.stringify(data, null, 4))
|
||||
await IO.WriteFile(`apisamples/lastGetPlayerResponse.json`, JSON.stringify(response, null, 4))
|
||||
}
|
||||
send.object(response);
|
||||
}
|
||||
|
||||
async function getOrRegisterPlayerInfo(refid: string, version: string, no: number) {
|
||||
let playerInfo = await DB.FindOne<PlayerInfo>(refid, {
|
||||
collection: 'playerinfo',
|
||||
version
|
||||
});
|
||||
|
||||
if (!playerInfo) {
|
||||
logger.debugInfo(`Registering new profile for player ${no} with refid: ${refid}`);
|
||||
playerInfo = await registerUser(refid, version);
|
||||
}
|
||||
return playerInfo;
|
||||
}
|
||||
|
||||
function getPlayerNo(data: any): number {
|
||||
return parseInt($(data).attr("player").no || '1', 10)
|
||||
}
|
||||
|
||||
async function registerUser(refid: string, version: string, id = _.random(0, 99999999)) {
|
||||
while (await DB.FindOne<Profile>(null, { collection: 'profile', id })) {
|
||||
id = _.random(0, 99999999);
|
||||
}
|
||||
|
||||
const defaultInfo: PlayerInfo = getDefaultPlayerInfo(version, id)
|
||||
|
||||
const gf = { game: 'gf', version };
|
||||
const dm = { game: 'dm', version };
|
||||
|
||||
await DB.Upsert(refid, { collection: 'playerinfo', version }, defaultInfo);
|
||||
await DB.Upsert(refid, { collection: 'profile', ...gf }, getDefaultProfile('gf', version, id));
|
||||
await DB.Upsert(refid, { collection: 'profile', ...dm }, getDefaultProfile('dm', version, id));
|
||||
await DB.Upsert(refid, { collection: 'record', ...gf }, getDefaultRecord('gf', version));
|
||||
await DB.Upsert(refid, { collection: 'record', ...dm }, getDefaultRecord('dm', version));
|
||||
await DB.Upsert(refid, { collection: 'extra', ...gf }, getDefaultExtra('gf', version, id));
|
||||
await DB.Upsert(refid, { collection: 'extra', ...dm }, getDefaultExtra('dm', version, id));
|
||||
await DB.Upsert(refid, { collection: 'scores', ...gf }, getDefaultScores('gf', version));
|
||||
await DB.Upsert(refid, { collection: 'scores', ...dm }, getDefaultScores('dm', version));
|
||||
|
||||
return defaultInfo
|
||||
}
|
||||
|
||||
export const savePlayers: EPR = async (info, data, send) => {
|
||||
|
||||
const version = DELTA_VERSION;
|
||||
const dm = isDM(info);
|
||||
const game = dm ? 'dm' : 'gf';
|
||||
const sharedScoresEnabled = isSharedSongScoresEnabled();
|
||||
|
||||
let players = $(data).elements("player")
|
||||
|
||||
let response = {
|
||||
player: [],
|
||||
gamemode: _.get(data, 'gamemode'),
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
for (let player of players) {
|
||||
|
||||
const no = parseInt(player.attr().no || '1', 10)
|
||||
// Only save players that are using a profile. Don't try to save guest players.
|
||||
const hasCard = player.attr().card === 'use'
|
||||
if (!hasCard) {
|
||||
logger.debugInfo(`Skipping save for guest ${game} player ${no}.`)
|
||||
continue
|
||||
}
|
||||
|
||||
const refid = player.str('refid')
|
||||
if (!refid) {
|
||||
throw "Request data is missing required parameter: player.refid"
|
||||
}
|
||||
|
||||
await saveSinglePlayer(player, refid, no, version, game, sharedScoresEnabled);
|
||||
|
||||
let ranking = await getPlayerRanking(refid, version, game)
|
||||
let responsePart = getSaveProfileResponse(no, ranking)
|
||||
response.player.push(responsePart)
|
||||
}
|
||||
|
||||
if (isAsphyxiaDebugMode()) {
|
||||
await IO.WriteFile(`apisamples/lastSavePlayersRequest.json`, JSON.stringify(data, null, 4))
|
||||
await IO.WriteFile(`apisamples/lastSavePlayersResponse.json`, JSON.stringify(response, null, 4))
|
||||
}
|
||||
await send.object(response);
|
||||
}
|
||||
catch (e) {
|
||||
logger.error(e)
|
||||
logger.error(e.stack)
|
||||
return send.deny();
|
||||
}
|
||||
};
|
||||
|
||||
async function saveSinglePlayer(dataplayer: KDataReader, refid: string, no: number, version: string, game: 'gf' | 'dm', sharedScoresEnabled: boolean)
|
||||
{
|
||||
logger.debugInfo(`Saving ${game} profile for player ${no} with refid: ${refid}`)
|
||||
const profile = await getProfile(refid, version, game) as any;
|
||||
const extra = await getExtra(refid, version, game) as any;
|
||||
const rec = await getRecord(refid, version, game) as any;
|
||||
|
||||
const autoSet = function (field: keyof Profile, path: string, array = false): void {
|
||||
if (array) {
|
||||
profile[field] = dataplayer.numbers(path, profile[field])
|
||||
} else {
|
||||
profile[field] = dataplayer.number(path, profile[field])
|
||||
}
|
||||
};
|
||||
|
||||
const autoExtra = (field: keyof Extra, path: string, array = false): void => {
|
||||
if (array) {
|
||||
extra[field] = dataplayer.numbers(path, extra[field])
|
||||
} else {
|
||||
extra[field] = dataplayer.number(path, extra[field])
|
||||
}
|
||||
};
|
||||
|
||||
const autoRec = (field: keyof Record, path: string, array = false): void => {
|
||||
if (array) {
|
||||
rec[field] = dataplayer.numbers(path, rec[field])
|
||||
} else {
|
||||
rec[field] = dataplayer.number(path, rec[field])
|
||||
}
|
||||
};
|
||||
|
||||
let newSecretMusic = parseSecretMusic(dataplayer)
|
||||
profile.secretmusic = {
|
||||
music: newSecretMusic
|
||||
}
|
||||
|
||||
autoSet('max_skill', 'record.max.skill');
|
||||
autoSet('max_all_skill', 'record.max.all_skill');
|
||||
autoSet('clear_diff', 'record.max.clear_diff');
|
||||
autoSet('full_diff', 'record.max.full_diff');
|
||||
autoSet('exce_diff', 'record.max.exce_diff');
|
||||
autoSet('clear_music_num', 'record.max.clear_music_num');
|
||||
autoSet('full_music_num', 'record.max.full_music_num');
|
||||
autoSet('exce_music_num', 'record.max.exce_music_num');
|
||||
autoSet('clear_seq_num', 'record.max.clear_seq_num');
|
||||
autoSet('classic_all_skill', 'record.max.classic_all_skill');
|
||||
|
||||
autoSet('play', 'playinfo.play');
|
||||
autoSet('playtime', 'playinfo.playtime');
|
||||
autoSet('playterm', 'playinfo.playterm');
|
||||
autoSet('session_cnt', 'playinfo.session_cnt');
|
||||
autoSet('extra_stage', 'playinfo.extra_stage');
|
||||
autoSet('extra_play', 'playinfo.extra_play');
|
||||
autoSet('extra_clear', 'playinfo.extra_clear');
|
||||
autoSet('encore_play', 'playinfo.encore_play');
|
||||
autoSet('encore_clear', 'playinfo.encore_clear');
|
||||
autoSet('pencore_play', 'playinfo.pencore_play');
|
||||
autoSet('pencore_clear', 'playinfo.pencore_clear');
|
||||
autoSet('max_clear_diff', 'playinfo.max_clear_diff');
|
||||
autoSet('max_full_diff', 'playinfo.max_full_diff');
|
||||
autoSet('max_exce_diff', 'playinfo.max_exce_diff');
|
||||
autoSet('clear_num', 'playinfo.clear_num');
|
||||
autoSet('full_num', 'playinfo.full_num');
|
||||
autoSet('exce_num', 'playinfo.exce_num');
|
||||
autoSet('no_num', 'playinfo.no_num');
|
||||
autoSet('e_num', 'playinfo.e_num');
|
||||
autoSet('d_num', 'playinfo.d_num');
|
||||
autoSet('c_num', 'playinfo.c_num');
|
||||
autoSet('b_num', 'playinfo.b_num');
|
||||
autoSet('a_num', 'playinfo.a_num');
|
||||
autoSet('s_num', 'playinfo.s_num');
|
||||
autoSet('ss_num', 'playinfo.ss_num');
|
||||
autoSet('last_category', 'playinfo.last_category');
|
||||
autoSet('last_musicid', 'playinfo.last_musicid');
|
||||
autoSet('last_seq', 'playinfo.last_seq');
|
||||
autoSet('disp_level', 'playinfo.disp_level');
|
||||
|
||||
autoSet('extra_gauge', 'groove.extra_gauge');
|
||||
autoSet('encore_gauge', 'groove.encore_gauge');
|
||||
autoSet('encore_cnt', 'groove.encore_cnt');
|
||||
autoSet('encore_success', 'groove.encore_success');
|
||||
autoSet('unlock_point', 'groove.unlock_point');
|
||||
|
||||
autoSet('progress', 'tutorial.progress');
|
||||
autoSet('disp_state', 'tutorial.disp_state');
|
||||
|
||||
autoSet('skill', 'skilldata.skill');
|
||||
autoSet('all_skill', 'skilldata.all_skill');
|
||||
|
||||
autoRec('diff_100_nr', 'record.diff.diff_100_nr');
|
||||
autoRec('diff_150_nr', 'record.diff.diff_150_nr');
|
||||
autoRec('diff_200_nr', 'record.diff.diff_200_nr');
|
||||
autoRec('diff_250_nr', 'record.diff.diff_250_nr');
|
||||
autoRec('diff_300_nr', 'record.diff.diff_300_nr');
|
||||
autoRec('diff_350_nr', 'record.diff.diff_350_nr');
|
||||
autoRec('diff_400_nr', 'record.diff.diff_400_nr');
|
||||
autoRec('diff_450_nr', 'record.diff.diff_450_nr');
|
||||
autoRec('diff_500_nr', 'record.diff.diff_500_nr');
|
||||
autoRec('diff_550_nr', 'record.diff.diff_550_nr');
|
||||
autoRec('diff_600_nr', 'record.diff.diff_600_nr');
|
||||
autoRec('diff_650_nr', 'record.diff.diff_650_nr');
|
||||
autoRec('diff_700_nr', 'record.diff.diff_700_nr');
|
||||
autoRec('diff_750_nr', 'record.diff.diff_750_nr');
|
||||
autoRec('diff_800_nr', 'record.diff.diff_800_nr');
|
||||
autoRec('diff_850_nr', 'record.diff.diff_850_nr');
|
||||
autoRec('diff_900_nr', 'record.diff.diff_900_nr');
|
||||
autoRec('diff_950_nr', 'record.diff.diff_950_nr');
|
||||
autoRec('diff_100_clear', 'record.diff.diff_100_clear', true);
|
||||
autoRec('diff_150_clear', 'record.diff.diff_150_clear', true);
|
||||
autoRec('diff_200_clear', 'record.diff.diff_200_clear', true);
|
||||
autoRec('diff_250_clear', 'record.diff.diff_250_clear', true);
|
||||
autoRec('diff_300_clear', 'record.diff.diff_300_clear', true);
|
||||
autoRec('diff_350_clear', 'record.diff.diff_350_clear', true);
|
||||
autoRec('diff_400_clear', 'record.diff.diff_400_clear', true);
|
||||
autoRec('diff_450_clear', 'record.diff.diff_450_clear', true);
|
||||
autoRec('diff_500_clear', 'record.diff.diff_500_clear', true);
|
||||
autoRec('diff_550_clear', 'record.diff.diff_550_clear', true);
|
||||
autoRec('diff_600_clear', 'record.diff.diff_600_clear', true);
|
||||
autoRec('diff_650_clear', 'record.diff.diff_650_clear', true);
|
||||
autoRec('diff_700_clear', 'record.diff.diff_700_clear', true);
|
||||
autoRec('diff_750_clear', 'record.diff.diff_750_clear', true);
|
||||
autoRec('diff_800_clear', 'record.diff.diff_800_clear', true);
|
||||
autoRec('diff_850_clear', 'record.diff.diff_850_clear', true);
|
||||
autoRec('diff_900_clear', 'record.diff.diff_900_clear', true);
|
||||
autoRec('diff_950_clear', 'record.diff.diff_950_clear', true);
|
||||
|
||||
autoExtra('list_1', 'favoritemusic.music_list_1', true);
|
||||
autoExtra('list_2', 'favoritemusic.music_list_2', true);
|
||||
autoExtra('list_3', 'favoritemusic.music_list_3', true);
|
||||
autoExtra('recommend_musicid_list', 'recommend_musicid_list', true);
|
||||
|
||||
autoExtra('playstyle', 'customdata.playstyle', true);
|
||||
autoExtra('custom', 'customdata.custom', true);
|
||||
autoExtra('reward_status', 'reward.status', true)
|
||||
|
||||
await DB.Upsert(refid, { collection: 'profile', game, version }, profile)
|
||||
await DB.Upsert(refid, { collection: 'record', game, version }, rec)
|
||||
await DB.Upsert(refid, { collection: 'extra', game, version }, extra)
|
||||
|
||||
const playedStages = dataplayer.elements('stage');
|
||||
logStagesPlayed(playedStages)
|
||||
|
||||
const scores = await updatePlayerScoreCollection(refid, playedStages, version, game)
|
||||
await saveScore(refid, version, game, scores);
|
||||
|
||||
if (sharedScoresEnabled) {
|
||||
await mergeScoresIntoShared(refid, game, scores);
|
||||
}
|
||||
await saveSharedFavoriteMusicFromExtra(refid, extra)
|
||||
}
|
||||
|
||||
async function updatePlayerScoreCollection(refid, playedStages, version, game) {
|
||||
const scores = (await getScore(refid, version, game)).scores;
|
||||
for (const stage of playedStages) {
|
||||
const mid = stage.number('musicid', -1);
|
||||
const seq = stage.number('seq', -1);
|
||||
|
||||
if (mid < 0 || seq < 0) continue;
|
||||
|
||||
// const skill = stage.number('skill', 0);
|
||||
const newSkill = stage.number('new_skill', 0);
|
||||
const clear = stage.bool('clear');
|
||||
const fc = stage.bool('fullcombo');
|
||||
const ex = stage.bool('excellent');
|
||||
const newMeter = stage.bool('is_new_meter');
|
||||
|
||||
const perc = stage.number('perc', 0);
|
||||
const rank = stage.number('rank', 0);
|
||||
const meter = stage.bigint('meter', BigInt(0));
|
||||
const prog = stage.number('meter_prog', 0);
|
||||
|
||||
if(!scores[mid]) {
|
||||
scores[mid] = {
|
||||
update: [0, 0],
|
||||
diffs: {}
|
||||
}
|
||||
}
|
||||
|
||||
if (newSkill > scores[mid].update[1]) {
|
||||
scores[mid].update[0] = seq;
|
||||
scores[mid].update[1] = newSkill;
|
||||
}
|
||||
|
||||
scores[mid].diffs[seq] = { //FIXME: Real server is bit complicated. this one is too buggy.
|
||||
perc: Math.max(_.get(scores[mid].diffs[seq], 'perc', 0), perc),
|
||||
rank: Math.max(_.get(scores[mid].diffs[seq], 'rank', 0), rank),
|
||||
meter: newMeter ? meter.toString() : _.get(scores[mid].diffs[seq], 'meter', 0),
|
||||
prog: Math.max(_.get(scores[mid].diffs[seq], 'prog', 0), prog),
|
||||
clear: _.get(scores[mid].diffs[seq], 'clear') || clear,
|
||||
fc: _.get(scores[mid].diffs[seq], 'fc') || fc,
|
||||
ex: _.get(scores[mid].diffs[seq], 'ex') || ex,
|
||||
};
|
||||
}
|
||||
|
||||
return scores
|
||||
}
|
||||
|
||||
function applyPlayHudPreset(playstyle: number[]): void {
|
||||
if (!Array.isArray(playstyle)) return;
|
||||
|
||||
// Only pad array to required length for version upgrades (50→70).
|
||||
// Do NOT overwrite any existing values — let the user's saved settings persist.
|
||||
if (playstyle.length < 70) {
|
||||
for (let i = playstyle.length; i < 70; i++) {
|
||||
playstyle[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function getPlayerRanking(refid: string, version: string, game: 'gf' | 'dm') : Promise<PlayerRanking> {
|
||||
let profiles = await getAllProfiles(version, game)
|
||||
let playerCount = profiles.length
|
||||
let sortedProfilesA = profiles.sort((a,b) => b.skill - a.skill)
|
||||
let sortedProfilesB = profiles.sort((a,b) => b.all_skill - a.all_skill)
|
||||
|
||||
let idxA = _.findIndex(sortedProfilesA, (e) => e.__refid === refid)
|
||||
idxA = idxA > -1 ? idxA + 1 : playerCount // Default to last place if not found in the DB.
|
||||
let idxB = _.findIndex(sortedProfilesB, (e) => e.__refid === refid)
|
||||
idxB = idxB > -1 ? idxB + 1 : playerCount // Default to last place if not found in the DB.
|
||||
|
||||
return {
|
||||
refid,
|
||||
skill: idxA,
|
||||
all_skill: idxB,
|
||||
totalPlayers: playerCount
|
||||
}
|
||||
}
|
||||
|
||||
async function getAllProfiles( version: string, game: 'gf' | 'dm') {
|
||||
return await DB.Find<Profile>(null, {
|
||||
collection: 'profile',
|
||||
version: version,
|
||||
game: game
|
||||
})
|
||||
}
|
||||
|
||||
async function getProfile(refid: string, version: string, game: 'gf' | 'dm') {
|
||||
return await DB.FindOne<Profile>(refid, {
|
||||
collection: 'profile',
|
||||
version: version,
|
||||
game: game
|
||||
})
|
||||
}
|
||||
|
||||
async function getExtra(refid: string, version: string, game: 'gf' | 'dm') {
|
||||
return await DB.FindOne<Extra>(refid, {
|
||||
collection: 'extra',
|
||||
version: version,
|
||||
game: game
|
||||
})
|
||||
}
|
||||
|
||||
async function getRecord(refid: string, version: string, game: 'gf' | 'dm') {
|
||||
return await DB.FindOne<Record>(refid, {
|
||||
collection: 'record',
|
||||
version: version,
|
||||
game: game
|
||||
})
|
||||
}
|
||||
|
||||
async function getScore(refid: string, version: string, game: 'gf' | 'dm'): Promise<Scores> {
|
||||
return (await DB.FindOne<Scores>(refid, {
|
||||
collection: 'scores',
|
||||
version: version,
|
||||
game: game
|
||||
})) || {
|
||||
collection: 'scores',
|
||||
version: version,
|
||||
pluginVer: PLUGIN_VER,
|
||||
game: game,
|
||||
scores: {}
|
||||
}
|
||||
}
|
||||
|
||||
async function saveScore(refid: string, version: string, game: 'gf' | 'dm', scores: Scores['scores']) {
|
||||
return await DB.Upsert<Scores>(refid, {
|
||||
collection: 'scores',
|
||||
version,
|
||||
game
|
||||
}, {
|
||||
collection: 'scores',
|
||||
version,
|
||||
game,
|
||||
scores
|
||||
})
|
||||
}
|
||||
|
||||
function parseSecretMusic(playerData: KDataReader) : SecretMusicEntry[]
|
||||
{
|
||||
let response : SecretMusicEntry[] = []
|
||||
|
||||
let elements = playerData.element('secretmusic')?.elements('music')
|
||||
if (!elements) {
|
||||
return response
|
||||
}
|
||||
|
||||
for (let el of elements) {
|
||||
let item : SecretMusicEntry = {
|
||||
musicid: el.number('musicid'),
|
||||
seq: el.number('seq'),
|
||||
kind: el.number('kind')
|
||||
}
|
||||
|
||||
response.push(item)
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
function getFriendDataResponse(profile: Profile) {
|
||||
let response = []
|
||||
return response;
|
||||
}
|
||||
|
||||
function logStagesPlayed(playedStages: KDataReader[]) {
|
||||
|
||||
let result = "Stages played: "
|
||||
for (let stage of playedStages) {
|
||||
let id = stage.number('musicid')
|
||||
result += `${id}, `
|
||||
}
|
||||
|
||||
logger.debugLog(result)
|
||||
}
|
||||
|
|
@ -21,6 +21,14 @@ export function register() {
|
|||
default: 13,
|
||||
})
|
||||
|
||||
R.Config("use_custom_encore_level", {
|
||||
name: "Use Custom Encore Level",
|
||||
desc: "If enabled, the encore level is controlled by the 'Encore Version' setting above. " +
|
||||
"If disabled, predefined encore levels per version are used instead.",
|
||||
type: "boolean",
|
||||
default: true,
|
||||
})
|
||||
|
||||
R.Config("nextage_dummy_encore", {
|
||||
name: "Dummy Encore for SPE (Nextage Only)",
|
||||
desc: "Since Nextage's Special Premium Encore system is bit complicated, \n"
|
||||
|
|
@ -70,9 +78,8 @@ export function register() {
|
|||
R.Route(`matixx_${method}`, handler);
|
||||
R.Route(`nextage_${method}`, handler)
|
||||
R.Route(`highvoltage_${method}`, handler)
|
||||
R.Route(`fuzzup_${method}`, handler)
|
||||
R.Route(`fuzzup_${method}`, handler)
|
||||
R.Route(`galaxywave_${method}`, handler)
|
||||
R.Route(`galaxywave_delta_${method}`, handler)
|
||||
// TODO: TB, and more older version?
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ export interface Extra {
|
|||
}
|
||||
|
||||
export function getDefaultExtra(game: 'gf' | 'dm', version: string, id: number) : Extra {
|
||||
const playstyleLength = version == 'galaxywave' || version == 'galaxywave_delta' ? 70 : 50;
|
||||
const result : Extra = {
|
||||
collection: 'extra',
|
||||
pluginVer: PLUGIN_VER,
|
||||
|
|
@ -25,7 +26,7 @@ export function getDefaultExtra(game: 'gf' | 'dm', version: string, id: number)
|
|||
game,
|
||||
version,
|
||||
id,
|
||||
playstyle: Array(50).fill(0),
|
||||
playstyle: Array(playstyleLength).fill(0),
|
||||
custom: Array(50).fill(0),
|
||||
list_1: Array(100).fill(-1),
|
||||
list_2: Array(100).fill(-1),
|
||||
|
|
@ -34,8 +35,34 @@ export function getDefaultExtra(game: 'gf' | 'dm', version: string, id: number)
|
|||
reward_status: Array(50).fill(0),
|
||||
}
|
||||
result.playstyle[1] = 1 // Note scroll speed (should default to 1.0x)
|
||||
result.playstyle[25] = 0
|
||||
result.playstyle[26] = 1
|
||||
result.playstyle[27] = 1
|
||||
result.playstyle[28] = 1
|
||||
result.playstyle[29] = 1
|
||||
result.playstyle[30] = 1
|
||||
result.playstyle[31] = 1
|
||||
result.playstyle[32] = 1
|
||||
result.playstyle[33] = 1
|
||||
result.playstyle[34] = 1
|
||||
result.playstyle[35] = 3
|
||||
result.playstyle[36] = 20 // Target Timing Adjustment
|
||||
result.playstyle[48] = 20 // Note Display Adjustment
|
||||
|
||||
if (playstyleLength >= 70) {
|
||||
result.playstyle[21] = 50 //DELTA 判定ライン位置
|
||||
result.playstyle[26] = 0 //DELTA 判定エフェクト位置
|
||||
result.playstyle[27] = 0 //DELTA SHUTTER IN
|
||||
result.playstyle[28] = 0 //DELTA SHUTTER OUT
|
||||
result.playstyle[56] = 0
|
||||
result.playstyle[57] = 1
|
||||
result.playstyle[58] = 1
|
||||
result.playstyle[59] = 1
|
||||
result.playstyle[60] = 17
|
||||
result.playstyle[61] = 1
|
||||
result.playstyle[62] = 1
|
||||
result.playstyle[63] = 1
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,16 @@
|
|||
export const isGF = (info: EamuseInfo) => {
|
||||
return info.model.split(':')[2] == 'A';
|
||||
const t = info.model.split(':')[2];
|
||||
return t == 'A' || t == 'C';
|
||||
};
|
||||
|
||||
export const isDM = (info: EamuseInfo) => {
|
||||
return info.model.split(':')[2] == 'B';
|
||||
const t = info.model.split(':')[2];
|
||||
return t == 'B' || t == 'D';
|
||||
};
|
||||
|
||||
export const isGalaxyWaveDeltaModel = (model: string) => {
|
||||
const t = model.split(':')[2];
|
||||
return t == 'C' || t == 'D';
|
||||
};
|
||||
|
||||
export const getVersion = (info: EamuseInfo) => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user