mirror of
https://github.com/asphyxia-core/plugins.git
synced 2026-03-21 17:34:46 -05:00
Merge pull request #76 from JamesLewisLiu/gitadora-feature-add
GITADORA Plugin Feature Add
This commit is contained in:
commit
997d141b3b
|
|
@ -1,15 +1,18 @@
|
|||
GITADORA Plugin for Asphyxia-Core
|
||||
=================================
|
||||

|
||||

|
||||
|
||||
This plugin is based on converted from public-exported Asphyxia's Routes.
|
||||
|
||||
Supported Versions
|
||||
==================
|
||||
- Tri-Boost Re:EVOLVE
|
||||
- Matixx
|
||||
- Exchain
|
||||
- EXCHAIN
|
||||
- NEX+AGE
|
||||
|
||||
- HIGH-VOLTAGE
|
||||
- FUZZ-UP
|
||||
- GALAXY WAVE
|
||||
|
||||
When Plugin Doesn't work correctly / Startup Error on Plugin
|
||||
------------------------------------------------------------
|
||||
|
|
@ -26,9 +29,42 @@ Known Issues
|
|||
* Special Premium Encore on Nextage is unimplemented. However, a workaround is available. Try it.
|
||||
* Friends and Rivals are unimplemented.
|
||||
|
||||
Shared Data Options
|
||||
===================
|
||||
Two experimental options allow operators to share data across versions:
|
||||
|
||||
* **Shared Favorite Songs** (`shared_favorite_songs`, default: `false`): When enabled, favorite lists are unified across Guitar Freaks, DrumMania, and supported versions.
|
||||
* **Shared Song Scores** (`shared_song_scores`, default: `false`): When enabled, the server merges the best results for each chart across every stored version and saves them under a shared version identifier. The merged record uses the following shape (fields marked with `//` describe their meaning):
|
||||
|
||||
```
|
||||
scores: {
|
||||
"<musicid>": {
|
||||
update: [<seq>, <new_skill>], // Highest new_skill value seen and its associated seq
|
||||
diffs: {
|
||||
"<seq>": {
|
||||
perc: <number>, // Highest achievement percentage
|
||||
rank: <number>, // Highest rank reached for the chart
|
||||
clear: <boolean>, // Whether the chart has been cleared
|
||||
fc: <boolean>, // Whether a full combo was achieved
|
||||
ex: <boolean>, // Whether an excellent was achieved
|
||||
meter: "<string>",// Best meter value as a stringified bigint
|
||||
prog: <number>, // Highest progression value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Scores are stored under `version: "shared"` but are automatically applied to the active module when loading a profile, ensuring players benefit from their best combined results regardless of the client version.
|
||||
|
||||
Release Notes
|
||||
=============
|
||||
|
||||
v1.4.0
|
||||
----------------
|
||||
* Added support for Tri-Boost Re:EVOLVE, HIGH-VOLTAGE, FUZZ-UP, GALAXY WAVE
|
||||
* Bugfix for launch core with "--dev/--console"
|
||||
|
||||
v1.3.0
|
||||
----------------
|
||||
* Added experimental 'Shared Favorite Songs' option. If disabled, players will be able to keep separate lists of favorite songs for each version of Gitadora, as well as between Guitar Freaks and Drummania. Enable this option to have a single unified list of favorite songs for both games, and across all versions. Default is false, to match original arcade behaviour.
|
||||
|
|
|
|||
|
|
@ -11,6 +11,37 @@ export function getEncoreStageData(info: EamuseInfo): EncoreStageData {
|
|||
const level: number = U.GetConfig("encore_version")
|
||||
const ntDummyEncore = U.GetConfig("nextage_dummy_encore")
|
||||
switch (getVersion(info)) {
|
||||
case 'galaxywave':
|
||||
return {
|
||||
level,
|
||||
musics: [
|
||||
2866, // Calm days
|
||||
2893, // 愛はToxic! feat.Lilymone
|
||||
2885, // Astrum
|
||||
2897, // DESPERATE ERROR
|
||||
2884, // Multiverse
|
||||
2919, // DOGMA
|
||||
2922, // Stay By My Side
|
||||
2937, // Prog for your Soul
|
||||
2963, // Zero Visibility
|
||||
2939, // Hopeful Daybreak!!!
|
||||
2956, // Over Time Groove
|
||||
]
|
||||
}
|
||||
case 'fuzzup':
|
||||
return {
|
||||
level,
|
||||
musics: [
|
||||
2812, // THE LAST OF FIREFACE
|
||||
2814, // ENCOUNT
|
||||
2783, // Q転直下
|
||||
2848, // Bloody Iron Maiden
|
||||
2860, // Serious Joke
|
||||
2844, // HyperNebula
|
||||
2877, // AVEL
|
||||
2892, // Elliptic Orbits
|
||||
]
|
||||
}
|
||||
case 'highvoltage':
|
||||
return {
|
||||
level,
|
||||
|
|
@ -58,7 +89,7 @@ export function getEncoreStageData(info: EamuseInfo): EncoreStageData {
|
|||
5060, // EXCELSIOR DIVE (CLASSIC)
|
||||
2530, // The ULTIMATES -CHRONICLE-
|
||||
2581, // 幸せの代償
|
||||
5046 // Rock to Infinity (CLASSIC)
|
||||
5046, // Rock to Infinity (CLASSIC)
|
||||
]
|
||||
}
|
||||
case 'matixx':
|
||||
|
|
@ -77,7 +108,22 @@ export function getEncoreStageData(info: EamuseInfo): EncoreStageData {
|
|||
2496, // CAPTURING XANADU
|
||||
2497, // Physical Decay
|
||||
2499, // Cinnamon
|
||||
2498 // けもののおうじゃ★めうめう
|
||||
2498, // けもののおうじゃ★めうめう
|
||||
]
|
||||
}
|
||||
case 're':
|
||||
return {
|
||||
level,
|
||||
musics: [
|
||||
2341, // Anathema
|
||||
2384, // White Forest
|
||||
2393, // REFLEXES MANIPULATION
|
||||
2392, // 主亡き機械人形のまなざし
|
||||
2406, // Exclamation
|
||||
2414, // MEDUSA
|
||||
2422, // BLACK ROSES
|
||||
2411, // ギタドラシカ
|
||||
2432, // Durian
|
||||
]
|
||||
}
|
||||
default:
|
||||
|
|
|
|||
12064
gitadora@asphyxia/data/mdb/fz.b64
Normal file
12064
gitadora@asphyxia/data/mdb/fz.b64
Normal file
File diff suppressed because it is too large
Load Diff
12499
gitadora@asphyxia/data/mdb/gw.b64
Normal file
12499
gitadora@asphyxia/data/mdb/gw.b64
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -1,12 +1,14 @@
|
|||
import Logger from "../../utils/logger";
|
||||
import { CommonMusicData } from "../../models/commonmusicdata";
|
||||
|
||||
|
||||
export enum DATAVersion {
|
||||
GALAXYWAVE = "gw",
|
||||
FUZZUP = "fz",
|
||||
HIGHVOLTAGE = "hv",
|
||||
NEXTAGE = "nt",
|
||||
EXCHAIN = "ex",
|
||||
MATTIX = "mt"
|
||||
MATTIX = "mt",
|
||||
TBRE = "re"
|
||||
}
|
||||
|
||||
const allowedFormats = ['.json', '.xml', '.b64']
|
||||
|
|
@ -46,7 +48,15 @@ export async function readMDBFile(path: string, processHandler?: processRawDataH
|
|||
break;
|
||||
case '.b64':
|
||||
const buff = await IO.ReadFile(path, 'utf-8');
|
||||
const json = Buffer.from(buff, 'base64').toString('utf-8')
|
||||
const bufferCtor = (globalThis as {
|
||||
Buffer?: {
|
||||
from(input: string, encoding: string): { toString(encoding: string): string }
|
||||
}
|
||||
}).Buffer
|
||||
if (!bufferCtor) {
|
||||
throw new Error('Buffer is not available in the current environment.')
|
||||
}
|
||||
const json = bufferCtor.from(buff, 'base64').toString('utf-8')
|
||||
// Uncomment to save the decoded base64 file as JSON.
|
||||
// await IO.WriteFile(path.replace(".b64",".json"), json)
|
||||
result = JSON.parse(json)
|
||||
|
|
@ -54,6 +64,13 @@ export async function readMDBFile(path: string, processHandler?: processRawDataH
|
|||
default:
|
||||
throw `Invalid MDB file type: ${fileType}. Only .json, .xml, .b64 are supported.`
|
||||
}
|
||||
|
||||
// Some MDB sources may not provide seq_release_state. Ensure it is present for every song entry.
|
||||
result.music.forEach((entry) => {
|
||||
if (entry.seq_release_state == null) {
|
||||
entry.seq_release_state = K.ITEM('s32', 1)
|
||||
}
|
||||
})
|
||||
|
||||
let gfCount = result.music.filter((e) => e.cont_gf["@content"][0]).length
|
||||
let dmCount = result.music.filter((e) => e.cont_dm["@content"][0]).length
|
||||
|
|
@ -63,6 +80,10 @@ export async function readMDBFile(path: string, processHandler?: processRawDataH
|
|||
|
||||
export function gameVerToDataVer(ver: string): DATAVersion {
|
||||
switch(ver) {
|
||||
case 'galaxywave':
|
||||
return DATAVersion.GALAXYWAVE
|
||||
case 'fuzzup':
|
||||
return DATAVersion.FUZZUP
|
||||
case 'highvoltage':
|
||||
return DATAVersion.HIGHVOLTAGE
|
||||
case 'nextage':
|
||||
|
|
@ -70,8 +91,9 @@ export function gameVerToDataVer(ver: string): DATAVersion {
|
|||
case 'exchain':
|
||||
return DATAVersion.EXCHAIN
|
||||
case 'matixx':
|
||||
default:
|
||||
return DATAVersion.MATTIX
|
||||
default:
|
||||
return DATAVersion.TBRE
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -93,9 +115,18 @@ export function findMDBFile(fileNameWithoutExtension: string, path: string = nul
|
|||
}
|
||||
|
||||
for (const ext of allowedFormats) {
|
||||
const filePath = path + fileNameWithoutExtension + ext
|
||||
if (IO.Exists(filePath)) {
|
||||
return filePath
|
||||
const candidateFileNames = ext === ".xml"
|
||||
? [
|
||||
`mdb_${fileNameWithoutExtension}${ext}`,
|
||||
`${fileNameWithoutExtension}${ext}`,
|
||||
]
|
||||
: [`${fileNameWithoutExtension}${ext}`]
|
||||
|
||||
for (const fileName of candidateFileNames) {
|
||||
const filePath = path + fileName
|
||||
if (IO.Exists(filePath)) {
|
||||
return filePath
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -108,7 +139,7 @@ export async function loadSongsForGameVersion(gameVer: string, processHandler?:
|
|||
let mdbFile = findMDBFile(ver, mdbFolder)
|
||||
|
||||
if (mdbFile == null) {
|
||||
throw `No valid MDB files were found in the data/mdb subfolder. Ensure that this folder contains at least one of the following: ${ver}.json, ${ver}.xml or ${ver}.b64`
|
||||
throw `No valid MDB files were found in the data/mdb subfolder. Ensure that this folder contains at least one of the following: ${ver}.json, mdb_${ver}.xml (${ver}.xml as fallback) or ${ver}.b64`
|
||||
}
|
||||
|
||||
const music = await readMDBFile(mdbFile, processHandler ?? defaultProcessRawXmlData)
|
||||
|
|
@ -140,7 +171,8 @@ export async function defaultProcessRawXmlData(path: string): Promise<CommonMusi
|
|||
cont_dm: K.ITEM('bool', dm == 0 ? 0 : 1),
|
||||
is_secret: K.ITEM('bool', m.number("is_secret", 0)),
|
||||
is_hot: K.ITEM('bool', type == 2 ? 0 : 1),
|
||||
data_ver: K.ITEM('s32', m.number("data_ver", 115)),
|
||||
data_ver: K.ITEM('s32', m.number("data_ver", 255)),
|
||||
seq_release_state: K.ITEM('s32', 1),
|
||||
diff: K.ARRAY('u16', [
|
||||
d[0],
|
||||
d[1],
|
||||
|
|
|
|||
7276
gitadora@asphyxia/data/mdb/re.b64
Normal file
7276
gitadora@asphyxia/data/mdb/re.b64
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -60,7 +60,6 @@ export async function applySharedFavoriteMusicToExtra(refid : string, extra : Ex
|
|||
let favoriteMusic = await loadFavoriteMusic(refid)
|
||||
|
||||
if (favoriteMusic == null) {
|
||||
logger.debugInfo(`No shared favourite music available for profile ${refid}. Using game specific favorites. Favorites will be saved as shared favorites at the end of the game session.`);
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -84,10 +83,17 @@ export async function saveFavoriteMusic(refid: string, data : FavoriteMusic) : P
|
|||
}, data)
|
||||
}
|
||||
|
||||
export async function loadFavoriteMusic(refid : string) : Promise<FavoriteMusic>
|
||||
export async function loadFavoriteMusic(refid : string) : Promise<FavoriteMusic | null>
|
||||
{
|
||||
return await DB.FindOne<FavoriteMusic>(refid, {
|
||||
const favoriteMusic = await DB.FindOne<FavoriteMusic>(refid, {
|
||||
collection: 'favoritemusic'
|
||||
})
|
||||
|
||||
if (!favoriteMusic) {
|
||||
logger.debugInfo(`No shared favourite music available for profile ${refid}. Using game specific favorites. Favorites will be saved as shared favorites at the end of the game session.`);
|
||||
return null
|
||||
}
|
||||
|
||||
return favoriteMusic
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ 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";
|
||||
|
||||
const logger = new Logger("MusicList")
|
||||
|
||||
|
|
@ -31,5 +32,10 @@ export const playableMusic: EPR = async (info, data, send) => {
|
|||
|
||||
let response : PlayableMusicResponse = getPlayableMusicResponse(music)
|
||||
await send.object(response)
|
||||
|
||||
if (isAsphyxiaDebugMode()) {
|
||||
await IO.WriteFile(`apisamples/playableMusicList.json`, JSON.stringify(music, null, 4))
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
90
gitadora@asphyxia/handlers/SharedScores.ts
Normal file
90
gitadora@asphyxia/handlers/SharedScores.ts
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
import { PLUGIN_VER } from "../const";
|
||||
import { Scores } from "../models/scores";
|
||||
|
||||
type ScoreDiff = Scores['scores'][string]['diffs'][string];
|
||||
type ScoreEntry = Scores['scores'][string];
|
||||
|
||||
function selectBetterMeter(existing?: string, incoming?: string): string {
|
||||
if (!incoming) return existing ?? "0";
|
||||
if (!existing) return incoming;
|
||||
|
||||
try {
|
||||
return BigInt(incoming) > BigInt(existing) ? incoming : existing;
|
||||
} catch (e) {
|
||||
return incoming || existing;
|
||||
}
|
||||
}
|
||||
|
||||
function mergeScoreDiff(existing: ScoreDiff | undefined, incoming: ScoreDiff): ScoreDiff {
|
||||
if (!existing) return incoming;
|
||||
|
||||
return {
|
||||
perc: Math.max(existing.perc ?? 0, incoming.perc ?? 0),
|
||||
rank: Math.max(existing.rank ?? 0, incoming.rank ?? 0),
|
||||
meter: selectBetterMeter(existing.meter, incoming.meter),
|
||||
prog: Math.max(existing.prog ?? 0, incoming.prog ?? 0),
|
||||
clear: (existing.clear ?? false) || (incoming.clear ?? false),
|
||||
fc: (existing.fc ?? false) || (incoming.fc ?? false),
|
||||
ex: (existing.ex ?? false) || (incoming.ex ?? false),
|
||||
};
|
||||
}
|
||||
|
||||
function mergeScoreEntry(existing: ScoreEntry | undefined, incoming: ScoreEntry): ScoreEntry {
|
||||
const mergedDiffs: ScoreEntry['diffs'] = existing ? { ...existing.diffs } : {};
|
||||
|
||||
for (const [seq, diff] of Object.entries(incoming.diffs)) {
|
||||
mergedDiffs[seq] = mergeScoreDiff(mergedDiffs[seq], diff);
|
||||
}
|
||||
|
||||
const mergedUpdate = existing?.update ? [...existing.update] : [0, 0];
|
||||
if (incoming.update && (mergedUpdate[1] ?? 0) < incoming.update[1]) {
|
||||
mergedUpdate[0] = incoming.update[0];
|
||||
mergedUpdate[1] = incoming.update[1];
|
||||
}
|
||||
|
||||
return {
|
||||
update: mergedUpdate,
|
||||
diffs: mergedDiffs,
|
||||
};
|
||||
}
|
||||
|
||||
function mergeScoreCollections(target: Scores['scores'], incoming: Scores['scores']): Scores['scores'] {
|
||||
const merged = { ...target } as Scores['scores'];
|
||||
|
||||
for (const [mid, entry] of Object.entries(incoming)) {
|
||||
merged[mid] = mergeScoreEntry(merged[mid], entry);
|
||||
}
|
||||
|
||||
return merged;
|
||||
}
|
||||
|
||||
async function persistSharedScores(refid: string, game: 'gf' | 'dm', scores: Scores['scores']) {
|
||||
await DB.Upsert<Scores>(refid, { collection: 'scores', game, version: 'shared' }, {
|
||||
collection: 'scores',
|
||||
version: 'shared',
|
||||
pluginVer: PLUGIN_VER,
|
||||
game,
|
||||
scores,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Load and merge scores across all versions for a player/game pair and persist them under version "shared".
|
||||
*/
|
||||
export async function getMergedSharedScores(refid: string, game: 'gf' | 'dm'): Promise<Scores['scores']> {
|
||||
const scoreDocs = await DB.Find<Scores>(refid, { collection: 'scores', game });
|
||||
const mergedScores = scoreDocs.reduce<Scores['scores']>((acc, doc) => mergeScoreCollections(acc, doc.scores), {} as Scores['scores']);
|
||||
|
||||
await persistSharedScores(refid, game, mergedScores);
|
||||
return mergedScores;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge the provided score set into the shared scores document for the player/game pair.
|
||||
*/
|
||||
export async function mergeScoresIntoShared(refid: string, game: 'gf' | 'dm', scores: Scores['scores']) {
|
||||
const existingShared = await DB.FindOne<Scores>(refid, { collection: 'scores', game, version: 'shared' });
|
||||
const mergedScores = mergeScoreCollections(existingShared?.scores ?? {}, scores);
|
||||
|
||||
await persistSharedScores(refid, game, mergedScores);
|
||||
}
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
/// <reference lib="es2020.bigint" />
|
||||
|
||||
import { getEncoreStageData } from "../data/extrastage";
|
||||
import Logger from "../utils/logger";
|
||||
import { getVersion } from "../utils";
|
||||
|
||||
const logger = new Logger('info');
|
||||
export const shopInfoRegist: EPR = async (info, data, send) => {
|
||||
|
|
@ -21,90 +24,343 @@ export const gameInfoGet: EPR = async (info, data, send) => {
|
|||
|
||||
const eventData = getEventDataResponse()
|
||||
const extraData = getEncoreStageData(info)
|
||||
|
||||
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),
|
||||
},
|
||||
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),
|
||||
get_border: K.ITEM('u8', 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),
|
||||
infect_music: { term: K.ITEM('u8', 0) },
|
||||
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_id: K.ARRAY('s32', [0, 0, 0, 0, 0, 0]),
|
||||
music: {
|
||||
musicid: K.ITEM('s32', 0),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
...eventData,
|
||||
});
|
||||
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)),
|
||||
}
|
||||
},
|
||||
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]),
|
||||
},
|
||||
},
|
||||
},
|
||||
...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() {
|
||||
|
|
@ -114,6 +370,41 @@ function getEventDataResponse() {
|
|||
},
|
||||
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);
|
||||
|
||||
|
|
@ -129,7 +420,8 @@ function getEventDataResponse() {
|
|||
term: K.ITEM('u8', 0),
|
||||
start_date_ms: K.ITEM('u64', time),
|
||||
end_date_ms: K.ITEM('u64', time),
|
||||
bonus_musicid: {},
|
||||
//bonus_musicid: {},
|
||||
bonus_musicid: K.ITEM('s32', 0),
|
||||
};
|
||||
addition[`sdvx_stamprally3`] = obj;
|
||||
addition[`chronicle_1`] = obj;
|
||||
|
|
@ -159,14 +451,42 @@ function getEventDataResponse() {
|
|||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
/// <reference lib="es2020.bigint" />
|
||||
|
||||
import { getDefaultPlayerInfo, PlayerInfo } from "../models/playerinfo";
|
||||
import { PlayerRanking } from "../models/playerranking";
|
||||
import { getDefaultProfile, Profile } from "../models/profile";
|
||||
|
|
@ -8,7 +10,7 @@ import { getDefaultScores, Scores } from "../models/scores";
|
|||
|
||||
import { PLUGIN_VER } from "../const";
|
||||
import Logger from "../utils/logger"
|
||||
import { isAsphyxiaDebugMode } from "../utils/index";
|
||||
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";
|
||||
|
|
@ -18,6 +20,7 @@ import { getDefaultBattleDataResponse } from "../models/Responses/battledataresp
|
|||
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")
|
||||
|
||||
|
|
@ -70,6 +73,7 @@ export const getPlayer: EPR = async (info, data, send) => {
|
|||
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, {
|
||||
|
|
@ -82,8 +86,8 @@ export const getPlayer: EPR = async (info, data, send) => {
|
|||
const gfRecord = await getRecord(refid, version, 'gf')
|
||||
const dmExtra = await getExtra(refid, version, 'dm')
|
||||
const gfExtra = await getExtra(refid, version, 'gf')
|
||||
const dmScores = (await getScore(refid, version, 'dm')).scores
|
||||
const gfScores = (await getScore(refid, version, 'gf')).scores
|
||||
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;
|
||||
|
|
@ -213,13 +217,33 @@ export const getPlayer: EPR = async (info, data, send) => {
|
|||
recommend_musicid_list: K.ARRAY('s32', extra.recommend_musicid_list ?? Array(5).fill(-1)),
|
||||
record,
|
||||
groove: {
|
||||
extra_gauge: K.ITEM('s32', profile.extra_gauge),
|
||||
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)
|
||||
|
|
@ -227,15 +251,55 @@ export const getPlayer: EPR = async (info, data, send) => {
|
|||
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;
|
||||
} else {
|
||||
addition['gitadora_oracle_1'] = obj;
|
||||
addition['gitadora_oracle_2'] = obj;
|
||||
} else {
|
||||
addition[`phrase_combo_challenge_${i}`] = obj;
|
||||
}
|
||||
|
||||
|
|
@ -254,6 +318,15 @@ export const getPlayer: EPR = async (info, data, send) => {
|
|||
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),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -307,6 +380,21 @@ export const getPlayer: EPR = async (info, data, send) => {
|
|||
},
|
||||
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) },
|
||||
|
|
@ -325,6 +413,20 @@ export const getPlayer: EPR = async (info, data, send) => {
|
|||
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),
|
||||
|
|
@ -424,6 +526,7 @@ export const savePlayers: EPR = async (info, data, send) => {
|
|||
const version = getVersion(info);
|
||||
const dm = isDM(info);
|
||||
const game = dm ? 'dm' : 'gf';
|
||||
const sharedScoresEnabled = isSharedSongScoresEnabled();
|
||||
|
||||
let players = $(data).elements("player")
|
||||
|
||||
|
|
@ -449,7 +552,7 @@ export const savePlayers: EPR = async (info, data, send) => {
|
|||
throw "Request data is missing required parameter: player.refid"
|
||||
}
|
||||
|
||||
await saveSinglePlayer(player, refid, no, version, game);
|
||||
await saveSinglePlayer(player, refid, no, version, game, sharedScoresEnabled);
|
||||
|
||||
let ranking = await getPlayerRanking(refid, version, game)
|
||||
let responsePart = getSaveProfileResponse(no, ranking)
|
||||
|
|
@ -469,7 +572,7 @@ export const savePlayers: EPR = async (info, data, send) => {
|
|||
}
|
||||
};
|
||||
|
||||
async function saveSinglePlayer(dataplayer: KDataReader, refid: string, no: number, version: string, game: 'gf' | 'dm')
|
||||
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;
|
||||
|
|
@ -612,7 +715,11 @@ async function saveSinglePlayer(dataplayer: KDataReader, refid: string, no: numb
|
|||
logStagesPlayed(playedStages)
|
||||
|
||||
const scores = await updatePlayerScoreCollection(refid, playedStages, version, game)
|
||||
await saveScore(refid, version, game, scores);
|
||||
await saveScore(refid, version, game, scores);
|
||||
|
||||
if (sharedScoresEnabled) {
|
||||
await mergeScoresIntoShared(refid, game, scores);
|
||||
}
|
||||
await saveSharedFavoriteMusicFromExtra(refid, extra)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,12 +40,19 @@ export function register() {
|
|||
|
||||
R.Config("shared_favorite_songs", {
|
||||
name: "Shared Favorite Songs (Experimental)",
|
||||
desc: "If disabled, players will be able to keep separate lists of favorite songs for each version of Gitadora, as well as between Guitar Freaks and Drummania. " +
|
||||
desc: "If disabled, players will be able to keep separate lists of favorite songs for each version of Gitadora, as well as between Guitar Freaks and Drummania. " +
|
||||
"Enable this option to have a single unified list of favorite songs for both games, and across all versions. Default is false, to match original arcade behaviour.",
|
||||
type: "boolean",
|
||||
default: false,
|
||||
})
|
||||
|
||||
R.Config("shared_song_scores", {
|
||||
name: "Shared Song Scores (Experimental)",
|
||||
desc: "If disabled, players will keep separate scoreboards per version. Enable to merge best scores across all versions and games into a shared store.",
|
||||
type: "boolean",
|
||||
default: false,
|
||||
})
|
||||
|
||||
R.DataFile("data/mdb/custom.xml", {
|
||||
accept: ".xml",
|
||||
name: "Custom MDB",
|
||||
|
|
@ -56,11 +63,17 @@ export function register() {
|
|||
|
||||
const MultiRoute = (method: string, handler: EPR | boolean) => {
|
||||
// Helper for register multiple versions.
|
||||
R.Route(`${method}`, handler);
|
||||
R.Route(`re_${method}`, handler);
|
||||
R.Route(`matixx_${method}`, handler);
|
||||
R.Route(`exchain_${method}`, handler);
|
||||
R.Route(`matixx_${method}`, handler);
|
||||
R.Route(`nextage_${method}`, handler)
|
||||
R.Route(`highvoltage_${method}`, handler)
|
||||
// TODO: TB, TBRE and more older version?
|
||||
R.Route(`fuzzup_${method}`, handler)
|
||||
R.Route(`galaxywave_${method}`, handler)
|
||||
R.Route(`galaxywave_delta_${method}`, handler)
|
||||
// TODO: TB, and more older version?
|
||||
};
|
||||
|
||||
// Info
|
||||
|
|
|
|||
|
|
@ -24,16 +24,16 @@ export interface BattleDataResponse
|
|||
|
||||
score: {
|
||||
battle_class: KITEM<'s32'>,
|
||||
max_battle_class: KITEM<'s32'>,
|
||||
battle_point: KITEM<'s32'>,
|
||||
win: KITEM<'s32'>,
|
||||
lose: KITEM<'s32'>,
|
||||
draw: KITEM<'s32'>,
|
||||
consecutive_win: KITEM<'s32'>,
|
||||
max_consecutive_win: KITEM<'s32'>,
|
||||
glorious_win: KITEM<'s32'>,
|
||||
max_defeat_skill: KITEM<'s32'>,
|
||||
latest_result: KITEM<'s32'>,
|
||||
max_battle_class: KITEM<'s32'>,
|
||||
battle_point: KITEM<'s32'>,
|
||||
win: KITEM<'s32'>,
|
||||
lose: KITEM<'s32'>,
|
||||
draw: KITEM<'s32'>,
|
||||
consecutive_win: KITEM<'s32'>,
|
||||
max_consecutive_win: KITEM<'s32'>,
|
||||
glorious_win: KITEM<'s32'>,
|
||||
max_defeat_skill: KITEM<'s32'>,
|
||||
latest_result: KITEM<'s32'>,
|
||||
|
||||
}
|
||||
history: {}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ export interface CommonMusicDataField {
|
|||
is_hot: KITEM<"bool">;
|
||||
data_ver: KITEM<"s32">;
|
||||
diff: KARRAY<"u16">;
|
||||
seq_release_state: KITEM<"s32">;
|
||||
}
|
||||
|
||||
export interface CommonMusicData {
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ 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[36] = 20 // Unknown
|
||||
result.playstyle[48] = 20 // Unknown
|
||||
result.playstyle[36] = 20 // Target Timing Adjustment
|
||||
result.playstyle[48] = 20 // Note Display Adjustment
|
||||
|
||||
return result
|
||||
}
|
||||
|
|
|
|||
8
gitadora@asphyxia/models/playerstickerresponse.ts
Normal file
8
gitadora@asphyxia/models/playerstickerresponse.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
export interface PlayerStickerResponse {
|
||||
id: KITEM<'s32'>,
|
||||
pos_x: KITEM<'float'> ,
|
||||
pos_y: KITEM<'float'>,
|
||||
scale_x: KITEM<'float'> ,
|
||||
scale_y: KITEM<'float'>,
|
||||
rotate: KITEM<'float'>
|
||||
}
|
||||
5
gitadora@asphyxia/models/secretmusicresponse.ts
Normal file
5
gitadora@asphyxia/models/secretmusicresponse.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
export interface SecretMusicResponse {
|
||||
musicid: KITEM<'s32'>;
|
||||
seq: KITEM<'u16'>;
|
||||
kind: KITEM<'s32'>;
|
||||
}
|
||||
|
|
@ -8,7 +8,14 @@ export const isDM = (info: EamuseInfo) => {
|
|||
|
||||
export const getVersion = (info: EamuseInfo) => {
|
||||
const moduleName: string = info.module;
|
||||
return moduleName.match(/([^_]*)_(.*)/)[1];
|
||||
const moduleMatch = moduleName.match(/([^_]*)_(.*)/);
|
||||
|
||||
if (moduleMatch && moduleMatch[1]) {
|
||||
return moduleMatch[1];
|
||||
}
|
||||
|
||||
console.error(`Unable to parse version from module name "${moduleName}".`);
|
||||
return "unknown";
|
||||
};
|
||||
|
||||
export function isRequiredCoreVersion(major: number, minor: number) {
|
||||
|
|
@ -19,10 +26,14 @@ export function isRequiredCoreVersion(major: number, minor: number) {
|
|||
};
|
||||
|
||||
export function isAsphyxiaDebugMode() : boolean {
|
||||
const argv = process.argv
|
||||
return argv.includes("--dev") || argv.includes("--console")
|
||||
const argv = (globalThis as { process?: { argv?: string[] } }).process?.argv ?? [];
|
||||
return argv.includes("--dev") || argv.includes("--console");
|
||||
}
|
||||
|
||||
export function isSharedFavoriteMusicEnabled() : boolean{
|
||||
return Boolean(U.GetConfig("shared_favorite_songs"))
|
||||
}
|
||||
}
|
||||
|
||||
export function isSharedSongScoresEnabled() : boolean{
|
||||
return Boolean(U.GetConfig("shared_song_scores"))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,21 +14,31 @@
|
|||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
function getFullVersionName(shortName) {
|
||||
switch (shortName) {
|
||||
case "exchain" :
|
||||
return "GITADORA EXCHAIN"
|
||||
|
||||
function getFullGameVersion(shortVer) {
|
||||
switch (shortVer) {
|
||||
case "re" :
|
||||
return "Tri-Boost Re:EVOLVE"
|
||||
case "matixx":
|
||||
return "Matixx"
|
||||
case "EXCHAIN":
|
||||
return "exchain"
|
||||
case "nextage":
|
||||
return "GITADORA NEX+AGE"
|
||||
return "NEX+AGE"
|
||||
case "highvoltage":
|
||||
return "GITADORA HIGH-VOLTAGE"
|
||||
default:
|
||||
return "HIGH-VOLTAGE"
|
||||
case "fuzzup":
|
||||
return "FUZZ-UP"
|
||||
case "galaxywave":
|
||||
return "GALAXY WAVE"
|
||||
case "galaxywave_delta":
|
||||
return "GALAXY WAVE DELTA"
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
const versions = ["exchain", "nextage", "highvoltage"]
|
||||
const versions = ["re", "matixx", "exchain", "nextage", "highvoltage", "fuzzup", "galaxywave", "galaxywave_delta"]
|
||||
const games = ["gf", "dm"]
|
||||
|
||||
function generateLeaderboards(infos, profiles) {
|
||||
|
|
@ -77,7 +87,7 @@
|
|||
-
|
||||
|
||||
each board in generateLeaderboards(infos, profiles)
|
||||
h3 #{getFullVersionName(board.version)} #{getFullGameName(board.game)}
|
||||
h3 #{getFullGameName(board.game)} #{getFullGameVersion(board.version)}
|
||||
table
|
||||
tr
|
||||
th Rank
|
||||
|
|
|
|||
|
|
@ -6,11 +6,34 @@
|
|||
-
|
||||
function getFullGameName(shortName) {
|
||||
switch (shortName) {
|
||||
case "gf":
|
||||
return "GuitarFreaks"
|
||||
case "dm" :
|
||||
return "Drummania"
|
||||
case "gf":
|
||||
return "Guitar Freaks"
|
||||
default:
|
||||
return "DrumMania"
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
function getFullGameVersion(shortVer) {
|
||||
switch (shortVer) {
|
||||
case "re" :
|
||||
return "Tri-Boost Re:EVOLVE"
|
||||
case "matixx":
|
||||
return "Matixx"
|
||||
case "EXCHAIN":
|
||||
return "exchain"
|
||||
case "nextage":
|
||||
return "NEX+AGE"
|
||||
case "highvoltage":
|
||||
return "HIGH-VOLTAGE"
|
||||
case "fuzzup":
|
||||
return "FUZZ-UP"
|
||||
case "galaxywave":
|
||||
return "GALAXY WAVE"
|
||||
case "galaxywave_delta":
|
||||
return "GALAXY WAVE DELTA"
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
|
@ -23,7 +46,7 @@ div
|
|||
p.card-header-title
|
||||
span.icon
|
||||
i.mdi.mdi-account-edit
|
||||
| User Detail (#{i.version})
|
||||
| User Detail (#{getFullGameVersion(i.version)})
|
||||
.card-content
|
||||
form(method="post" action="/emit/updatePlayerInfo")
|
||||
.field
|
||||
|
|
@ -55,7 +78,7 @@ div
|
|||
p.card-header-title
|
||||
span.icon
|
||||
i.mdi.mdi-account-details
|
||||
| Profile Detail (#{getFullGameName(pr.game)} #{pr.version})
|
||||
| Profile Detail (#{getFullGameName(pr.game)} #{getFullGameVersion(pr.version)})
|
||||
.card-content
|
||||
form(method="post")
|
||||
.field
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user