Save more game end data

This commit is contained in:
573dev 2020-11-12 22:02:20 -06:00
parent aed03a5fdb
commit 1d6530b4dd
7 changed files with 156 additions and 37 deletions

View File

@ -6,7 +6,7 @@ from lxml import etree
from v8_server import db
from v8_server.eamuse.services.services import ServiceRequest
from v8_server.eamuse.xml.utils import get_xml_attrib, load_xml_template
from v8_server.model.user import User, UserAccount
from v8_server.model.user import User, UserAccount, UserData
from v8_server.utils.convert import int_to_bool as itob
@ -81,10 +81,16 @@ class Check(object):
}
# Existing User
if not new_user and account is not None:
if not new_user and account is not None and user is not None:
user_data = user.user_data
# TODO: Add GDP, skill, all_skill here
args = {
"state": CheckStatus.EXISTING_USER,
"name": account.name,
"gdp": 0,
"skill": 0,
"all_skill": 0,
"syogo": " ".join(map(str, user_data.syogo)),
"chara": account.chara,
}
drop_children = None
@ -156,6 +162,22 @@ class Regist(object):
is_succession=self.data.is_succession,
)
db.session.add(user_account)
user_data = UserData(
userid=user.userid,
style=2097152,
style_2=0,
secret_music=[0 for _ in range(0, 32)],
secret_chara=0,
syogo=[0, 0],
perfect=0,
great=0,
good=0,
poor=0,
miss=0,
time=0,
)
db.session.add(user_data)
db.session.commit()
return load_xml_template("cardutil", "regist")

View File

@ -2,8 +2,10 @@ import logging
from lxml import etree
from v8_server import db
from v8_server.eamuse.services.services import ServiceRequest
from v8_server.eamuse.xml.utils import get_xml_attrib, load_xml_template
from v8_server.model.user import User
logger = logging.getLogger(__name__)
@ -79,4 +81,13 @@ class Regist(object):
return f"Customize.Regist<players = {self.players}>"
def response(self) -> etree:
# Save the syogo data (assume single player right now)
user = User.from_refid(self.players[0].refid)
if user is None:
raise Exception("user should not be none")
user_data = user.user_data
user_data.syogo = self.players[0].syogodata.get.syogo
db.session.commit()
return load_xml_template("customize", "regist")

View File

@ -7,7 +7,7 @@ from v8_server import db
from v8_server.eamuse.services.services import ServiceRequest
from v8_server.eamuse.xml.utils import get_xml_attrib, load_xml_template
from v8_server.model.song import HitChart
from v8_server.model.user import User, UserData
from v8_server.model.user import PlayData, User, UserData
from v8_server.utils.convert import int_to_bool as itob
@ -247,12 +247,12 @@ class Playdata(object):
def __init__(self, root: etree) -> None:
self.no = int(root.find("no").text)
self.seqmode = int(root.find("seqmode").text)
self.clear = int(root.find("clear").text)
self.auto_clear = int(root.find("auto_clear").text)
self.clear = itob(int(root.find("clear").text))
self.auto_clear = itob(int(root.find("auto_clear").text))
self.score = int(root.find("score").text)
self.flags = int(root.find("flags").text)
self.fullcombo = int(root.find("fullcombo").text)
self.excellent = int(root.find("excellent").text)
self.fullcombo = itob(int(root.find("fullcombo").text))
self.excellent = itob(int(root.find("excellent").text))
self.combo = int(root.find("combo").text)
self.skill_point = int(root.find("skill_point").text)
self.skill_perc = int(root.find("skill_perc").text)
@ -456,20 +456,47 @@ class Regist(object):
user_data = UserData.from_userid(user.userid)
if user_data is None:
user_data = UserData(
userid=user.userid,
style=playerinfo.styles,
style_2=playerinfo.styles_2,
)
db.session.add(user_data)
else:
user_data.style = playerinfo.styles
user_data.style_2 = playerinfo.styles_2
raise Exception("user data shouldn't be none here")
user_data.style = playerinfo.styles
user_data.style_2 = playerinfo.styles_2
user_data.secret_music = playerinfo.secret_music
user_data.secret_chara = playerinfo.secret_chara
user_data.perfect = playerinfo.perfect
user_data.great = playerinfo.great
user_data.good = playerinfo.good
user_data.poor = playerinfo.poor
user_data.miss = playerinfo.miss
user_data.time = playerinfo.time
db.session.commit()
else:
raise Exception("This user doesn't exist")
# Save playdata
for idx, data in enumerate(self.player.playdata):
musicid = self.modedata.stages[idx].musicid
play_data = PlayData(
userid=user.userid,
no=data.no,
musicid=musicid,
seqmode=data.seqmode,
clear=data.clear,
auto_clear=data.auto_clear,
score=data.score,
flags=data.flags,
fullcombo=data.fullcombo,
excellent=data.excellent,
combo=data.combo,
skill_point=data.skill_point,
skill_perc=data.skill_perc,
result_rank=data.result_rank,
difficulty=data.difficulty,
combo_rate=data.combo_rate,
perfect_rate=data.perfect_rate,
)
db.session.add(play_data)
db.session.commit()
# Just send back a dummy object for now
now_time = datetime.now().strftime(self.DT_FMT)

View File

@ -4,8 +4,8 @@ from lxml import etree
from v8_server.eamuse.services.services import ServiceRequest
from v8_server.eamuse.utils.crc import calculate_crc8
from v8_server.eamuse.xml.utils import fill, get_xml_attrib, load_xml_template
from v8_server.model.user import User, UserData
from v8_server.eamuse.xml.utils import get_xml_attrib, load_xml_template
from v8_server.model.user import User
logger = logging.getLogger(__name__)
@ -77,14 +77,10 @@ class Get(object):
def response(self) -> etree:
# Grab user_data
user = User.from_refid(self.player.refid)
style = 2097152
style_2 = 0
if user is not None:
user_data = UserData.from_userid(user.userid)
if user is None:
raise Exception("User should not be none here")
if user_data is not None:
style = user_data.style
style_2 = user_data.style_2
user_data = user.user_data
# Generate history rounds (blank for now)
history_rounds = ""
@ -99,16 +95,14 @@ class Get(object):
load_xml_template("gametop", "get.music_hist.round")
).decode("UTF-8")
secret_music = fill(32)
secret_chara = 0
tag = calculate_crc8(
str(sum(int(x) for x in secret_music.split()) + secret_chara)
)
secret_music = user_data.secret_music
secret_chara = user_data.secret_chara
tag = calculate_crc8(str(sum(secret_music) + secret_chara))
args = {
"secret_music": secret_music,
"style": style,
"style_2": style_2,
"secret_music": " ".join(map(str, secret_music)),
"style": user_data.style,
"style_2": user_data.style_2,
"secret_chara": secret_chara,
"tag": tag,
"history_rounds": history_rounds,

View File

@ -3,11 +3,11 @@
<card no="1" state="{state}">
<kind __type="s8">0</kind>
<name __type="str">{name}</name>
<gdp __type="u32">0</gdp>
<skill __type="s32">0</skill>
<all_skill __type="s32">0</all_skill>
<gdp __type="u32">{gdp}</gdp>
<skill __type="s32">{skill}</skill>
<all_skill __type="s32">{all_skill}</all_skill>
<chara __type="u8">{chara}</chara>
<syogo __type="s16" __count="2">0 0</syogo>
<syogo __type="s16" __count="2">{syogo}</syogo>
<penalty __type="u8">0</penalty>
</card>
</cardutil>

24
v8_server/model/types.py Normal file
View File

@ -0,0 +1,24 @@
from typing import List
from sqlalchemy.types import String, TypeDecorator
class IntArray(TypeDecorator):
impl = String
def __init__(self, **kwargs) -> None:
super().__init__(None, **kwargs)
def process_literal_param(self, value, dialect) -> str:
# Value will be an int array
if value is None:
return ""
return " ".join(map(str, value))
process_bind_param = process_literal_param
def process_result_value(self, value, dialect) -> List[int]:
# Convert SQL String to Int List
if value is None:
return []
return [int(x) for x in value.split()]

View File

@ -9,6 +9,7 @@ from sqlalchemy.orm import relationship
from sqlalchemy.types import Boolean, Integer, String
from v8_server import db
from v8_server.model.types import IntArray
BaseModel: DefaultMeta = db.Model
@ -31,6 +32,8 @@ class User(BaseModel):
extids = relationship("ExtID", back_populates="user")
refids = relationship("RefID", back_populates="user")
user_account = relationship("UserAccount", uselist=False, back_populates="user")
user_data = relationship("UserData", uselist=False, back_populates="user")
play_data = relationship("PlayData", back_populates="user")
def __repr__(self) -> str:
return f'User<userid: {self.userid}, pin: "{self.pin}">'
@ -81,6 +84,16 @@ class UserData(BaseModel):
userid = Column(Integer, ForeignKey("users.userid"), primary_key=True)
style = Column(Integer, nullable=False)
style_2 = Column(Integer, nullable=False)
secret_music = Column(IntArray, nullable=False)
secret_chara = Column(Integer, nullable=False)
syogo = Column(IntArray, nullable=False)
perfect = Column(Integer, nullable=False)
great = Column(Integer, nullable=False)
good = Column(Integer, nullable=False)
poor = Column(Integer, nullable=False)
miss = Column(Integer, nullable=False)
time = Column(Integer, nullable=False)
user = relationship("User", back_populates="user_data")
@classmethod
def from_userid(cls, userid: int) -> Optional[UserData]:
@ -88,6 +101,34 @@ class UserData(BaseModel):
return q.one_or_none()
class PlayData(BaseModel):
"""
Store play data, every stage that a user has played
"""
__tablename__ = "play_data"
playid = Column(Integer, primary_key=True)
userid = Column(Integer, ForeignKey("users.userid"), nullable=False)
no = Column(Integer, nullable=False)
musicid = Column(Integer, nullable=False)
seqmode = Column(Integer, nullable=False)
clear = Column(Boolean, nullable=False)
auto_clear = Column(Boolean, nullable=False)
score = Column(Integer, nullable=False)
flags = Column(Integer, nullable=False)
fullcombo = Column(Boolean, nullable=False)
excellent = Column(Boolean, nullable=False)
combo = Column(Integer, nullable=False)
skill_point = Column(Integer, nullable=False)
skill_perc = Column(Integer, nullable=False)
result_rank = Column(Integer, nullable=False)
difficulty = Column(Integer, nullable=False)
combo_rate = Column(Integer, nullable=False)
perfect_rate = Column(Integer, nullable=False)
user = relationship("User", back_populates="play_data")
class Card(BaseModel):
"""
Table representing a card associated with a user. Users may have zero or more cards