1
0
mirror of synced 2024-12-03 10:07:17 +01:00
bemaniutils/bemani/backend/museca/common.py
2023-02-17 03:40:07 +00:00

199 lines
6.8 KiB
Python

from bemani.backend.museca.base import MusecaBase
from bemani.common import ID
from bemani.protocol import Node
class MusecaGameShopHandler(MusecaBase):
def handle_game_3_shop_request(self, request: Node) -> Node:
self.update_machine_name(request.child_value("shopname"))
# Respond with number of milliseconds until next request
game = Node.void("game_3")
game.add_child(Node.u32("nxt_time", 1000 * 5 * 60))
return game
class MusecaGameHiscoreHandler(MusecaBase):
def handle_game_3_hiscore_request(self, request: Node) -> Node:
# Grab location for local scores
locid = ID.parse_machine_id(request.child_value("locid"))
# Start the response packet
game = Node.void("game_3")
# First, grab hit chart
playcounts = self.data.local.music.get_hit_chart(self.game, self.version, 1024)
hitchart = Node.void("hitchart")
game.add_child(hitchart)
for songid, count in playcounts:
info = Node.void("info")
hitchart.add_child(info)
info.add_child(Node.u32("id", songid))
info.add_child(Node.u32("cnt", count))
# Now, grab user records
records = self.data.remote.music.get_all_records(self.game, self.version)
users = {
uid: prof for (uid, prof) in self.get_any_profiles([r[0] for r in records])
}
hiscore_allover = Node.void("hiscore_allover")
game.add_child(hiscore_allover)
# Output records
for userid, score in records:
info = Node.void("info")
if userid not in users:
raise Exception("Logic error, could not find profile for user!")
profile = users[userid]
info.add_child(Node.u32("id", score.id))
info.add_child(Node.u32("type", score.chart))
info.add_child(Node.string("name", profile.get_str("name")))
info.add_child(Node.string("seq", ID.format_extid(profile.extid)))
info.add_child(Node.u32("score", score.points))
# Add to global scores
hiscore_allover.add_child(info)
# Now, grab local records
area_users = [
uid
for (uid, prof) in self.data.local.user.get_all_profiles(
self.game, self.version
)
if prof.get_int("loc", -1) == locid
]
records = self.data.local.music.get_all_records(
self.game, self.version, userlist=area_users
)
missing_players = [uid for (uid, _) in records if uid not in users]
for uid, prof in self.get_any_profiles(missing_players):
users[uid] = prof
hiscore_location = Node.void("hiscore_location")
game.add_child(hiscore_location)
# Output records
for userid, score in records:
info = Node.void("info")
if userid not in users:
raise Exception("Logic error, could not find profile for user!")
profile = users[userid]
info.add_child(Node.u32("id", score.id))
info.add_child(Node.u32("type", score.chart))
info.add_child(Node.string("name", profile.get_str("name")))
info.add_child(Node.string("seq", ID.format_extid(profile.extid)))
info.add_child(Node.u32("score", score.points))
# Add to global scores
hiscore_location.add_child(info)
# Now, grab clear rates
clear_rate = Node.void("clear_rate")
game.add_child(clear_rate)
clears = self.get_clear_rates()
for songid in clears:
for chart in clears[songid]:
if clears[songid][chart]["total"] > 0:
rate = float(clears[songid][chart]["clears"]) / float(
clears[songid][chart]["total"]
)
dnode = Node.void("d")
clear_rate.add_child(dnode)
dnode.add_child(Node.u32("id", songid))
dnode.add_child(Node.u32("type", chart))
dnode.add_child(Node.s16("cr", int(rate * 10000)))
return game
class MusecaGameFrozenHandler(MusecaBase):
def handle_game_3_frozen_request(self, request: Node) -> Node:
game = Node.void("game_3")
game.add_child(Node.u8("result", 0))
return game
class MusecaGameNewHandler(MusecaBase):
def handle_game_3_new_request(self, request: Node) -> Node:
refid = request.child_value("refid")
name = request.child_value("name")
loc = ID.parse_machine_id(request.child_value("locid"))
self.new_profile_by_refid(refid, name, loc)
root = Node.void("game_3")
return root
class MusecaGameSaveMusicHandler(MusecaBase):
def handle_game_3_save_m_request(self, request: Node) -> Node:
refid = request.child_value("refid")
if refid is not None:
userid = self.data.remote.user.from_refid(self.game, self.version, refid)
else:
userid = None
# Doesn't matter if userid is None here, that's an anonymous score
musicid = request.child_value("music_id")
chart = request.child_value("music_type")
points = request.child_value("score")
combo = request.child_value("max_chain")
clear_type = self.game_to_db_clear_type(request.child_value("clear_type"))
grade = self.game_to_db_grade(request.child_value("score_grade"))
stats = {
"btn_rate": request.child_value("btn_rate"),
"long_rate": request.child_value("long_rate"),
"vol_rate": request.child_value("vol_rate"),
"critical": request.child_value("critical"),
"near": request.child_value("near"),
"error": request.child_value("error"),
}
# Save the score
self.update_score(
userid,
musicid,
chart,
points,
clear_type,
grade,
combo,
stats,
)
# Return a blank response
return Node.void("game_3")
class MusecaGamePlayEndHandler(MusecaBase):
def handle_game_3_play_e_request(self, request: Node) -> Node:
return Node.void("game_3")
class MusecaGameSaveHandler(MusecaBase):
def handle_game_3_save_request(self, request: Node) -> Node:
refid = request.child_value("refid")
if refid is not None:
userid = self.data.remote.user.from_refid(self.game, self.version, refid)
else:
userid = None
if userid is not None:
oldprofile = self.get_profile(userid)
newprofile = self.unformat_profile(userid, request, oldprofile)
else:
newprofile = None
if userid is not None and newprofile is not None:
self.put_profile(userid, newprofile)
return Node.void("game_3")