ghostdata fixes

This commit is contained in:
vvo
2024-09-27 13:51:24 +08:00
parent 649a30a90e
commit 02a2c7d973
4 changed files with 108 additions and 52 deletions
+23 -22
View File
@@ -1,8 +1,8 @@
# DanceDanceRevolution
**Plugin Version:** fork-mdx-3.0.0b
**Plugin Version:** fork-mdx-3.0.1
**Supported game versions:** WORLD (2024061300)
**Supported game versions:** WORLD (2024091000)
**Unsupported game versions:** Everything below A20 is unsupported. A20 untested. A3 unsupported.
@@ -17,6 +17,21 @@
Changelog
===========
## fork-mdx-3.0.1
### New:
1. Main:
- Updated events list & event loading code:
- Galaxy Play
- EXTRA SAVIOR
- MYSTICAL Re:UNION (songs automatically unlocked on login atm)
- Attempts to fix ghost data loading:
- Added ghost id to score and ghost data
- Ghost data gets created when there is no existing data; and it gets updated when getting a higher or the same score. Side effect of this is when you have set a high score prior to this update, the ghost data won't be updated unless you break or match that high score.
- Unfortunately I could not find a way to match the old scores to their respective ghost data, since the old ghost data only stored the song id and difficulty, and not the style (single/double.)
## fork-mdx-3.0.0b
### New:
@@ -41,25 +56,11 @@ Changelog
- Added musicdata for new WORLD songs (ddr@asphyxia/data/world.ts:SONGS_WORLD)
## fork-mdx-3.0.0
### New:
1. Main:
- 2024061300 support (DDR World)
- DDR profile registration for new and existing Asphyxia profiles
- For Asphyxia profiles with no prior DDR A20/A3 profiles registered.
- Transfer from A3 not supported (yet?)
- Profile saving and loading (probably incomplete)
- Score saving and loading (probably incomplete)
### To do:
1. Look for more missing features (I don't play DDR so idk what's missing lol)
2. Check flare skill value consistency
3. Transfer old save data from A3 to World (?)
4. Update re-rated song difficulties
5. WebUI Profile page
6. More work on score_str
7. Rival load
1. Look for more missing features
2. Refactor getLastScoreId and addScoreKey
3. Update re-rated song difficulties
4. WebUI stuff
5. More work on score_str
6. Rival load
+2 -4
View File
@@ -69,10 +69,8 @@ export const EVENTS_WORLD = [
{ id: 37, no: 1, cond: 1, rwrd: 38665, type: 81 }, { id: 38, no: 1, cond: 1, rwrd: 38665, type: 82 }, { id: 39, no: 1, cond: 1, rwrd: 38665, type: 83 }, { id: 40, no: 1, cond: 1, rwrd: 38665, type: 84 },
{ id: 41, no: 1, cond: 1, rwrd: 38669, type: 81 }, { id: 42, no: 1, cond: 1, rwrd: 38669, type: 82 }, { id: 43, no: 1, cond: 1, rwrd: 38669, type: 83 }, { id: 44, no: 1, cond: 1, rwrd: 38669, type: 84 },
{ id: 45, no: 1, cond: 1, rwrd: 38659, type: 81 }, { id: 46, no: 1, cond: 1, rwrd: 38659, type: 82 }, { id: 47, no: 1, cond: 1, rwrd: 38659, type: 83 }, { id: 48, no: 1, cond: 1, rwrd: 38659, type: 84 },
{ id: 49, no: 0, cond: 2, rwrd: 38736, type: 27 }, { id: 50, no: 0, cond: 2, rwrd: 38735, type: 27 }, { id: 51, no: 0, cond: 2, rwrd: 38728, type: 27 },
{ id: 52, no: 0, cond: 1, rwrd: 38624, type: 27 }, { id: 53, no: 0, cond: 1, rwrd: 38623, type: 27 }, { id: 54, no: 0, cond: 1, rwrd: 38628, type: 27 },
{ id: 55, no: 0, cond: 1, rwrd: 38736, type: 25 }, { id: 56, no: 1, cond: 1, rwrd: 38736, type: 25 }, { id: 57, no: 2, cond: 1, rwrd: 38736, type: 25 }, { id: 58, no: 3, cond: 1, rwrd: 38736, type: 25 },
{ id: 59, no: 0, cond: 1, rwrd: 38735, type: 25 }, { id: 60, no: 1, cond: 1, rwrd: 38735, type: 25 }, { id: 61, no: 2, cond: 1, rwrd: 38735, type: 25 }, { id: 62, no: 3, cond: 1, rwrd: 38735, type: 25 },
{ id: 63, no: 0, cond: 1, rwrd: 38728, type: 25 }, { id: 64, no: 1, cond: 1, rwrd: 38728, type: 25 }, { id: 65, no: 2, cond: 1, rwrd: 38728, type: 25 }, { id: 66, no: 3, cond: 1, rwrd: 38728, type: 25 },
@@ -81,11 +79,11 @@ export const EVENTS_WORLD = [
{ id: 77, no: 0, cond: 1, rwrd: 38628, type: 25 }, { id: 78, no: 1, cond: 1, rwrd: 38628, type: 25 }, { id: 79, no: 2, cond: 1, rwrd: 38628, type: 25 }, { id: 80, no: 3, cond: 1, rwrd: 38628, type: 25 },
{ id: 81, no: 0, cond: 1, rwrd: 1185, type: 201, save: 1, dep: [67, 68, 69, 70, 72, 73, 74, 75, 77, 78, 79, 80] },
{ id: 82, no: 0, cond: 1, rwrd: 1186, type: 201, save: 1, dep: [67, 68, 69, 70, 71, 72, 73, 74, 75, 77, 78, 79, 80] },
{ id: 83, no: 0, cond: 1, rwrd: 38746, type: 17, comp: 0, save: 1 },
{ id: 84, no: 0, cond: 1, rwrd: 38745, type: 17, comp: 0, save: 1 },
{ id: 85, no: 0, cond: 1, rwrd: 38744, type: 17, comp: 0, save: 1 },
{ id: 86, no: 0, cond: 1, rwrd: 38747, type: 17, comp: 0, save: 1 },
{ id: 87, no: 0, cond: 1, rwrd: 38748, type: 17, comp: 0, save: 1 },
{ id: 88, no: 0, cond: 1, rwrd: 1189, type: 201, save: 1 }
{ id: 88, no: 0, cond: 1, rwrd: 1189, type: 201, save: 1 },
{ id: 89, no: 0, cond: 1, rwrd: 1188, type: 201, save: 1 }
]
+80 -24
View File
@@ -1,16 +1,46 @@
import { Profile } from "../models/profile";
import { ProfileWorld, ScoreWorld, EventWorld, GhostWorld } from "../models/ddrworld";
import { ProfileWorld, ScoreWorld, EventWorld, GhostWorld, RivalWorld } from "../models/ddrworld";
import { SONGS_WORLD, EVENTS_WORLD } from "../data/world";
// needs to be faster
function getLastGhostId(ghost: any) {
return ghost.reduce(function(a, b) {
let aId = (a && !a.ghostId) ? 0 : a.ghostId
let bId = (!b.ghostId) ? 0 : b.ghostId
return (a && aId > bId) ? aId : bId
})
}
async function saveScores(refid: string, songId: number, style: number, difficulty: number, rank: number, clearKind: number, score: number, exScore: number, maxCombo: number, flareForce: number, ghostSize: number, ghost: string) {
let stepScore = await DB.Find<ScoreWorld>(refid, {collection: "score3", songId: songId, style: style, difficulty: difficulty})
if(stepScore.length > 0) {
rank = (rank < stepScore[0].rank) ? rank : stepScore[0].rank;
clearKind = (clearKind != 6 && clearKind > stepScore[0].clearKind) ? clearKind : stepScore[0].clearKind;
score = (score > stepScore[0].score) ? score : stepScore[0].score;
exScore = (exScore > stepScore[0].exScore) ? exScore : stepScore[0].exScore;
maxCombo = (maxCombo > stepScore[0].maxCombo) ? maxCombo : stepScore[0].maxCombo;
flareForce = (flareForce > stepScore[0].flareForce) ? flareForce : stepScore[0].flareForce;
let ghostData = await DB.Find<GhostWorld>(null, {collection: "ghost3"})
let lastGhostId = getLastGhostId(ghostData)
let stepScore = await DB.FindOne<ScoreWorld>(refid, {collection: "score3", songId: songId, style: style, difficulty: difficulty})
let ghostId = 0
if(lastGhostId === 0) {
ghostId = 1
} else ghostId = lastGhostId += 1
/*
Ghost data gets created when there is no existing data and it gets updated when getting a higher or the same score
Side effect of this is when you have set a high score prior to this update, the ghost data wouldn't be updated unless you break or match that high score.
Unfortunately I could not find a way to match the old scores to their respective ghost data, since the old ghost data only stored the song id and difficulty, and not the style (single/double.) Stupid me.
Still needs more work.
*/
if(stepScore) {
ghostId = (stepScore.ghostId) ? stepScore.ghostId : ghostId
let stepGhost = await DB.FindOne<GhostWorld>(null, {collection: "ghost3", ghostId: ghostId })
if(stepGhost) {
if(score >= stepScore.score) console.log("overwriting ghostdata")
ghostSize = (score >= stepScore.score) ? ghostSize : stepGhost.ghostSize
ghost = (score >= stepScore.score) ? ghost : stepGhost.ghost
}
rank = (rank < stepScore.rank) ? rank : stepScore.rank;
clearKind = (clearKind != 6 && clearKind > stepScore.clearKind) ? clearKind : stepScore.clearKind;
score = (score > stepScore.score) ? score : stepScore.score;
exScore = (exScore > stepScore.exScore) ? exScore : stepScore.exScore;
maxCombo = (maxCombo > stepScore.maxCombo) ? maxCombo : stepScore.maxCombo;
flareForce = (flareForce > stepScore.flareForce) ? flareForce : stepScore.flareForce;
}
await DB.Upsert<ScoreWorld>(refid, {
@@ -20,19 +50,18 @@ async function saveScores(refid: string, songId: number, style: number, difficul
difficulty
}, {
$set: {
ghostId,
rank,
clearKind,
score,
exScore,
maxCombo,
flareForce
exScore
}
});
console.log("saving ghostid: " + ghostId)
await DB.Upsert<GhostWorld>(refid, {
collection: "ghost3",
songId,
difficulty
ghostId,
}, {
$set: {
ghostSize,
@@ -41,6 +70,31 @@ async function saveScores(refid: string, songId: number, style: number, difficul
});
}
// async function addGhostId(refid: string) {
// const ghost = await DB.Find<GhostWorld>(null, { collection: "ghost3" });
// if(ghost) {
// let lastGhostId = getLastScoreId(ghost)
// if(lastGhostId === 0) {
// console.log("Modifying score data to add ghost id.")
// for(const scoreData of scores) {
// let songId = scoreData.songId
// let style = scoreData.style
// let difficulty = scoreData.difficulty
// let rank = scoreData.rank
// let clearKind = scoreData.clearKind
// let score = scoreData.score
// let exScore = scoreData.exScore
// let maxCombo = scoreData.maxCombo
// let flareForce = scoreData.flareForce
// let ghostSize = (scoreData.ghostSize) ? scoreData.ghostSize : 0
// let ghost = (scoreData.ghost) ? scoreData.ghost : '0'
// await DB.Remove<ScoreWorld>(refid, {collection: "score3", songId: songId, style: style, difficulty: difficulty})
// await saveScores(refid, songId, style, difficulty, rank, clearKind, score, exScore, maxCombo, flareForce, ghostSize, ghost)
// }
// }
// }
// }
export const playerdatanew: EPR = async (info, data, send) => {
const refid = $(data).str("data.refid");
let ddrCode = _.random(1, 99999999)
@@ -141,7 +195,7 @@ export const playerdatasave: EPR = async (info, data, send) => {
let flareForce = $(data).number("data.result.flare_force");
let ghostSize = $(data).number("data.result.ghostsize");
let ghost = $(data).str("data.result.ghost");
saveScores(refid, songId, style, difficulty, rank, clearKind, score, exScore, maxCombo, flareForce, ghostSize, ghost)
await saveScores(refid, songId, style, difficulty, rank, clearKind, score, exScore, maxCombo, flareForce, ghostSize, ghost)
}
else if($(data).number("data.savekind") === 3) {
let profile = await DB.FindOne<ProfileWorld>(refid, {collection: "profile3"})
@@ -249,7 +303,7 @@ export const playerdataload: EPR = async (info, data, send) => {
const refid = $(data).str("data.refid");
const profile = await DB.FindOne<ProfileWorld>(refid, { collection: "profile3" });
if (!profile || refid.startsWith("X000")) {
if (!profile || !profile.dancerName || refid.startsWith("X000")) {
return send.object({
result: K.ITEM("s32", 0),
refid: K.ITEM("str", refid),
@@ -257,17 +311,17 @@ export const playerdataload: EPR = async (info, data, send) => {
servertime: K.ITEM("u64", BigInt(getDate())),
is_locked: K.ITEM('bool', false),
common: {
ddrcode: K.ITEM("s32", 0),
ddrcode: K.ITEM("s32", profile ? profile.ddrCode : 0),
dancername: K.ITEM("str", ''),
is_new: K.ITEM('bool', true),
is_registering: K.ITEM('bool', false),
is_new: K.ITEM('bool', (!profile || refid.startsWith("X000")) ? true : false),
is_registering: K.ITEM('bool', (profile && !profile.dancerName) ? true : false),
is_takeover: K.ITEM('bool', false),
area: K.ITEM("s32", 0),
extrastar: K.ITEM("s32", 0),
playcount: K.ITEM("s32", 0),
weight: K.ITEM("s32", 0),
today_cal: K.ITEM("u64", BigInt(0)),
is_disp_weight: K.ITEM("bool", false),
is_takeover: K.ITEM('bool', false),
pre_playable_num: K.ITEM("s32", 0)
},
option: {
@@ -352,8 +406,8 @@ export const playerdataload: EPR = async (info, data, send) => {
})
}
else {
// await addGhostId(refid)
const scores = await DB.Find<ScoreWorld>(refid, { collection: "score3" });
let scoreFin = []
if(scores) {
for(const scoreData of scores) {
@@ -369,14 +423,14 @@ export const playerdataload: EPR = async (info, data, send) => {
*/
scr[(scoreData.style === 0) ? 'score_single' : 'score_double'] = [
{
score_str: K.ITEM('str', scoreData.difficulty + ',1,' + scoreData.rank + ',' + scoreData.clearKind + ',' + scoreData.score + ',' + scoreData.exScore + ',' + scoreData.flareForce + ',' + scoreData.flareForce)
score_str: K.ITEM('str', scoreData.difficulty + ',1,' + scoreData.rank + ',' + scoreData.clearKind + ',' + scoreData.score + ',' + scoreData.ghostId + ',' + scoreData.flareForce + ',' + scoreData.flareForce)
}
]
scoreFin.push(scr)
} else {
scoreFin[mcodeIndex][(scoreData.style === 0) ? 'score_single' : 'score_double'].push({
score_str: K.ITEM('str', scoreData.difficulty + ',1,' + scoreData.rank + ',' + scoreData.clearKind + ',' + scoreData.score + ',' + scoreData.exScore + ',' + scoreData.flareForce + ',' + scoreData.flareForce)
score_str: K.ITEM('str', scoreData.difficulty + ',1,' + scoreData.rank + ',' + scoreData.clearKind + ',' + scoreData.score + ',' + scoreData.ghostId + ',' + scoreData.flareForce + ',' + scoreData.flareForce)
})
}
}
@@ -559,9 +613,11 @@ export const rivaldataload: EPR = async (info, data, send) => {
};
export const ghostdataload: EPR = async (info, data, send) => {
// Choosing world, area and machine #1 target scores doesn't seem to call this endpoint yet (or at all)
const refid = $(data).str("data.refid");
const ghostId = $(data).number("data.ghostid");
let ghostData = await DB.FindOne<GhostWorld>(refid, {collection: 'ghost3', songId: ghostId})
console.log("loading ghostid: " + ghostId)
let ghostData = await DB.FindOne<GhostWorld>(null, {collection: 'ghost3', ghostId: ghostId})
if(ghostData) {
return send.object({
result: K.ITEM("s32", 0),
+3 -2
View File
@@ -10,9 +10,11 @@ export interface RivalWorld {
export interface ScoreWorld {
collection: "score3";
scoreId: number;
songId: number;
style: number;
difficulty: Difficulty;
ghostId: number;
rank: Rank;
clearKind: ClearKind;
score: number;
@@ -24,8 +26,7 @@ export interface ScoreWorld {
export interface GhostWorld {
collection: "ghost3"
songId: number;
difficulty: number;
ghostId: number;
ghostSize: number;
ghost: string;
}