mirror of
https://github.com/DragonMinded/bemaniutils.git
synced 2026-03-21 17:24:33 -05:00
Add playtracking chart, store attempts there since we don't have a real chart.
Juggle some stuff around for upcoming frontend.
This commit is contained in:
parent
d07ed02e9a
commit
8af63c2013
|
|
@ -1,11 +1,11 @@
|
|||
# vim: set fileencoding=utf-8
|
||||
from typing import Optional
|
||||
from typing_extensions import Final
|
||||
|
||||
from bemani.backend.base import Base
|
||||
from bemani.backend.core import CoreHandler, CardManagerHandler, PASELIHandler
|
||||
from bemani.common import (
|
||||
GameConstants,
|
||||
)
|
||||
from bemani.common import GameConstants, ValidatedDict
|
||||
from bemani.data import UserID
|
||||
|
||||
|
||||
class DanceEvolutionBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
|
||||
|
|
@ -15,9 +15,101 @@ class DanceEvolutionBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
|
|||
|
||||
game: GameConstants = GameConstants.DANCE_EVOLUTION
|
||||
|
||||
CHART_TYPE_LIGHT: Final[int] = 0
|
||||
CHART_TYPE_STANDARD: Final[int] = 1
|
||||
CHART_TYPE_EXTREME: Final[int] = 2
|
||||
CHART_TYPE_STEALTH: Final[int] = 3
|
||||
CHART_TYPE_MASTER: Final[int] = 4
|
||||
CHART_TYPE_PLAYTRACKING: Final[int] = 5
|
||||
|
||||
GRADE_FAILED: Final[int] = 100
|
||||
GRADE_E: Final[int] = 200
|
||||
GRADE_D: Final[int] = 300
|
||||
GRADE_C: Final[int] = 400
|
||||
GRADE_B: Final[int] = 500
|
||||
GRADE_A: Final[int] = 600
|
||||
GRADE_AA: Final[int] = 700
|
||||
GRADE_AAA: Final[int] = 800
|
||||
|
||||
def previous_version(self) -> Optional["DanceEvolutionBase"]:
|
||||
"""
|
||||
Returns the previous version of the game, based on this game. Should
|
||||
be overridden.
|
||||
"""
|
||||
return None
|
||||
|
||||
def update_score(
|
||||
self,
|
||||
userid: UserID,
|
||||
songid: int,
|
||||
chart: int,
|
||||
points: int,
|
||||
grade: int,
|
||||
combo: int,
|
||||
full_combo: bool,
|
||||
) -> None:
|
||||
"""
|
||||
Given various pieces of a score, update the user's high score.
|
||||
"""
|
||||
if chart not in {
|
||||
self.CHART_TYPE_LIGHT,
|
||||
self.CHART_TYPE_STANDARD,
|
||||
self.CHART_TYPE_EXTREME,
|
||||
self.CHART_TYPE_STEALTH,
|
||||
self.CHART_TYPE_MASTER,
|
||||
}:
|
||||
raise Exception(f"Invalid chart {chart}")
|
||||
if grade not in {
|
||||
self.GRADE_FAILED,
|
||||
self.GRADE_E,
|
||||
self.GRADE_D,
|
||||
self.GRADE_C,
|
||||
self.GRADE_B,
|
||||
self.GRADE_A,
|
||||
self.GRADE_AA,
|
||||
self.GRADE_AAA,
|
||||
}:
|
||||
raise Exception(f"Invalid grade {grade}")
|
||||
|
||||
oldscore = self.data.local.music.get_score(
|
||||
self.game,
|
||||
self.version,
|
||||
userid,
|
||||
songid,
|
||||
chart,
|
||||
)
|
||||
|
||||
if oldscore is None:
|
||||
# If it is a new score, create a new dictionary to add to
|
||||
scoredata = ValidatedDict({})
|
||||
highscore = True
|
||||
else:
|
||||
# Set the score to any new record achieved
|
||||
highscore = points >= oldscore.points
|
||||
points = max(oldscore.points, points)
|
||||
scoredata = oldscore.data
|
||||
|
||||
# Save combo
|
||||
scoredata.replace_int("combo", max(scoredata.get_int("combo"), combo))
|
||||
|
||||
# Save grade
|
||||
scoredata.replace_int("grade", max(scoredata.get_int("grade"), grade))
|
||||
|
||||
# Save full combo indicator.
|
||||
scoredata.replace_bool("full_combo", scoredata.get_bool("full_combo") or full_combo)
|
||||
|
||||
# Look up where this score was earned
|
||||
lid = self.get_machine_id()
|
||||
|
||||
# Write the new score back
|
||||
self.data.local.music.put_score(
|
||||
self.game,
|
||||
self.version,
|
||||
userid,
|
||||
songid,
|
||||
chart,
|
||||
lid,
|
||||
points,
|
||||
scoredata,
|
||||
highscore,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ from typing_extensions import Final
|
|||
|
||||
from bemani.backend.ess import EventLogHandler
|
||||
from bemani.backend.danevo.base import DanceEvolutionBase
|
||||
from bemani.common import ValidatedDict, VersionConstants, Profile, CardCipher, Time
|
||||
from bemani.data import UserID
|
||||
from bemani.common import VersionConstants, Profile, CardCipher, Time
|
||||
from bemani.data import ScoreSaveException
|
||||
from bemani.protocol import Node
|
||||
|
||||
|
||||
|
|
@ -84,12 +84,6 @@ class DanceEvolution(
|
|||
|
||||
DATA04_TOTAL_SCORE_EARNED_OFFSET: Final[int] = 9
|
||||
|
||||
CHART_LIGHT: Final[int] = 0
|
||||
CHART_STANDARD: Final[int] = 1
|
||||
CHART_EXTREME: Final[int] = 2
|
||||
CHART_STEALTH: Final[int] = 3
|
||||
CHART_MASTER: Final[int] = 4
|
||||
|
||||
GAME_GRADE_FAILED: Final[int] = 0
|
||||
GAME_GRADE_E: Final[int] = 1
|
||||
GAME_GRADE_D: Final[int] = 2
|
||||
|
|
@ -125,82 +119,6 @@ class DanceEvolution(
|
|||
return
|
||||
self.update_machine_name(shopname)
|
||||
|
||||
def update_score(
|
||||
self,
|
||||
userid: UserID,
|
||||
songid: int,
|
||||
chart: int,
|
||||
points: int,
|
||||
grade: int,
|
||||
combo: int,
|
||||
full_combo: bool,
|
||||
) -> None:
|
||||
"""
|
||||
Given various pieces of a score, update the user's high score.
|
||||
"""
|
||||
if chart not in {
|
||||
self.CHART_LIGHT,
|
||||
self.CHART_STANDARD,
|
||||
self.CHART_EXTREME,
|
||||
self.CHART_STEALTH,
|
||||
self.CHART_MASTER,
|
||||
}:
|
||||
raise Exception(f"Invalid chart {chart}")
|
||||
if grade not in {
|
||||
self.GAME_GRADE_FAILED,
|
||||
self.GAME_GRADE_E,
|
||||
self.GAME_GRADE_D,
|
||||
self.GAME_GRADE_C,
|
||||
self.GAME_GRADE_B,
|
||||
self.GAME_GRADE_A,
|
||||
self.GAME_GRADE_AA,
|
||||
self.GAME_GRADE_AAA,
|
||||
}:
|
||||
raise Exception(f"Invalid grade {grade}")
|
||||
|
||||
oldscore = self.data.local.music.get_score(
|
||||
self.game,
|
||||
self.version,
|
||||
userid,
|
||||
songid,
|
||||
chart,
|
||||
)
|
||||
|
||||
if oldscore is None:
|
||||
# If it is a new score, create a new dictionary to add to
|
||||
scoredata = ValidatedDict({})
|
||||
highscore = True
|
||||
else:
|
||||
# Set the score to any new record achieved
|
||||
highscore = points >= oldscore.points
|
||||
points = max(oldscore.points, points)
|
||||
scoredata = oldscore.data
|
||||
|
||||
# Save combo
|
||||
scoredata.replace_int("combo", max(scoredata.get_int("combo"), combo))
|
||||
|
||||
# Save grade
|
||||
scoredata.replace_int("grade", max(scoredata.get_int("grade"), grade))
|
||||
|
||||
# Save full combo indicator.
|
||||
scoredata.replace_bool("full_combo", scoredata.get_bool("full_combo") or full_combo)
|
||||
|
||||
# Look up where this score was earned
|
||||
lid = self.get_machine_id()
|
||||
|
||||
# Write the new score back
|
||||
self.data.local.music.put_score(
|
||||
self.game,
|
||||
self.version,
|
||||
userid,
|
||||
songid,
|
||||
chart,
|
||||
lid,
|
||||
points,
|
||||
scoredata,
|
||||
highscore,
|
||||
)
|
||||
|
||||
def handle_tax_get_phase_request(self, request: Node) -> Node:
|
||||
tax = Node.void("tax")
|
||||
tax.add_child(Node.s32("phase", 0))
|
||||
|
|
@ -389,23 +307,64 @@ class DanceEvolution(
|
|||
# Game might be set to 1 song.
|
||||
continue
|
||||
|
||||
# For the purpose of popularity tracking, save an attempt for this song into the virtual
|
||||
# attempt chart, since we can't know for certain what chart an attempt was associated with.
|
||||
now = Time.now()
|
||||
lid = self.get_machine_id()
|
||||
|
||||
for bump in range(10):
|
||||
timestamp = now + bump
|
||||
|
||||
self.data.local.music.put_score(
|
||||
self.game,
|
||||
self.version,
|
||||
userid,
|
||||
played,
|
||||
self.CHART_TYPE_PLAYTRACKING,
|
||||
lid,
|
||||
scored,
|
||||
{},
|
||||
False,
|
||||
timestamp=timestamp,
|
||||
)
|
||||
|
||||
try:
|
||||
self.data.local.music.put_attempt(
|
||||
self.game,
|
||||
self.version,
|
||||
userid,
|
||||
played,
|
||||
self.CHART_TYPE_PLAYTRACKING,
|
||||
lid,
|
||||
scored,
|
||||
{},
|
||||
False,
|
||||
timestamp=timestamp,
|
||||
)
|
||||
except ScoreSaveException:
|
||||
# Try again one second in the future
|
||||
continue
|
||||
|
||||
# We saved successfully
|
||||
break
|
||||
|
||||
# First, calculate whether we're going to look at DATA01-05 or DATA11-15.
|
||||
if played < 63:
|
||||
mapping = {
|
||||
"DATA01": self.CHART_LIGHT,
|
||||
"DATA02": self.CHART_STANDARD,
|
||||
"DATA03": self.CHART_EXTREME,
|
||||
"DATA04": self.CHART_STEALTH,
|
||||
"DATA05": self.CHART_MASTER,
|
||||
"DATA01": self.CHART_TYPE_LIGHT,
|
||||
"DATA02": self.CHART_TYPE_STANDARD,
|
||||
"DATA03": self.CHART_TYPE_EXTREME,
|
||||
"DATA04": self.CHART_TYPE_STEALTH,
|
||||
"DATA05": self.CHART_TYPE_MASTER,
|
||||
}
|
||||
offset = played * 8
|
||||
else:
|
||||
mapping = {
|
||||
"DATA11": self.CHART_LIGHT,
|
||||
"DATA12": self.CHART_STANDARD,
|
||||
"DATA13": self.CHART_EXTREME,
|
||||
"DATA14": self.CHART_STEALTH,
|
||||
"DATA15": self.CHART_MASTER,
|
||||
"DATA11": self.CHART_TYPE_LIGHT,
|
||||
"DATA12": self.CHART_TYPE_STANDARD,
|
||||
"DATA13": self.CHART_TYPE_EXTREME,
|
||||
"DATA14": self.CHART_TYPE_STEALTH,
|
||||
"DATA15": self.CHART_TYPE_MASTER,
|
||||
}
|
||||
offset = (played - 63) * 8
|
||||
|
||||
|
|
@ -432,8 +391,18 @@ class DanceEvolution(
|
|||
# Found it!
|
||||
full_combo = bool(stats & 0x10)
|
||||
letter_grade = (stats >> 1) & 0x7
|
||||
grade = {
|
||||
self.GAME_GRADE_FAILED: self.GRADE_FAILED,
|
||||
self.GAME_GRADE_E: self.GRADE_E,
|
||||
self.GAME_GRADE_D: self.GRADE_D,
|
||||
self.GAME_GRADE_C: self.GRADE_C,
|
||||
self.GAME_GRADE_B: self.GRADE_B,
|
||||
self.GAME_GRADE_A: self.GRADE_A,
|
||||
self.GAME_GRADE_AA: self.GRADE_AA,
|
||||
self.GAME_GRADE_AAA: self.GRADE_AAA,
|
||||
}[letter_grade]
|
||||
|
||||
self.update_score(userid, played, mapping[key], scored, letter_grade, combo, full_combo)
|
||||
self.update_score(userid, played, mapping[key], scored, grade, combo, full_combo)
|
||||
|
||||
playerdata.add_child(Node.s32("result", 0))
|
||||
return playerdata
|
||||
|
|
|
|||
|
|
@ -6172,7 +6172,7 @@ class ImportDanceEvolution(ImportBase):
|
|||
# Import it
|
||||
self.start_batch()
|
||||
|
||||
for chart_id in [0, 1, 2, 3, 4]:
|
||||
for chart_id in [0, 1, 2, 3, 4, 5]:
|
||||
# First, try to find in the DB from another version
|
||||
old_id = self.get_music_id_for_song(song["id"], chart_id)
|
||||
if self.no_combine or old_id is None:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user