From a46b0210ebc0b5ccd1a1686b7760f2828cffe6ee Mon Sep 17 00:00:00 2001
From: 573dev <>
Date: Wed, 11 Nov 2020 19:59:42 -0600
Subject: [PATCH] Classes for all requests data
- A more generic class loader depending on request url, baed on method
and module to avoid big if trees. Better separation of data classes as
well imo.
---
v8_server/eamuse/services/__init__.py | 22 +-
v8_server/eamuse/services/cardmng.py | 165 +++++---
v8_server/eamuse/services/cardutil.py | 161 ++++++++
v8_server/eamuse/services/customize.py | 82 ++++
v8_server/eamuse/services/demodata.py | 72 ++++
v8_server/eamuse/services/dlstatus.py | 23 +-
v8_server/eamuse/services/facility.py | 31 +-
v8_server/eamuse/services/gameend.py | 476 ++++++++++++++++++++++++
v8_server/eamuse/services/gameinfo.py | 57 +++
v8_server/eamuse/services/gametop.py | 122 ++++++
v8_server/eamuse/services/lobby.py | 1 -
v8_server/eamuse/services/local.py | 302 ---------------
v8_server/eamuse/services/message.py | 24 +-
v8_server/eamuse/services/package.py | 29 +-
v8_server/eamuse/services/pcbevent.py | 69 ++--
v8_server/eamuse/services/pcbtracker.py | 40 +-
v8_server/eamuse/services/shopinfo.py | 208 +++++++++++
v8_server/utils/convert.py | 9 +
v8_server/view/index.py | 96 ++---
19 files changed, 1437 insertions(+), 552 deletions(-)
create mode 100644 v8_server/eamuse/services/cardutil.py
create mode 100644 v8_server/eamuse/services/customize.py
create mode 100644 v8_server/eamuse/services/demodata.py
create mode 100644 v8_server/eamuse/services/gameend.py
create mode 100644 v8_server/eamuse/services/gameinfo.py
create mode 100644 v8_server/eamuse/services/gametop.py
delete mode 100644 v8_server/eamuse/services/lobby.py
delete mode 100644 v8_server/eamuse/services/local.py
create mode 100644 v8_server/eamuse/services/shopinfo.py
diff --git a/v8_server/eamuse/services/__init__.py b/v8_server/eamuse/services/__init__.py
index 0941157..9779816 100644
--- a/v8_server/eamuse/services/__init__.py
+++ b/v8_server/eamuse/services/__init__.py
@@ -1,24 +1,4 @@
-from v8_server.eamuse.services.cardmng import CardMng
-from v8_server.eamuse.services.dlstatus import DLStatus
-from v8_server.eamuse.services.facility import Facility
-from v8_server.eamuse.services.local import Local
-from v8_server.eamuse.services.message import Message
-from v8_server.eamuse.services.package import Package
-from v8_server.eamuse.services.pcbevent import PCBEvent
-from v8_server.eamuse.services.pcbtracker import PCBTracker
from v8_server.eamuse.services.services import ServiceRequest, Services, ServiceType
-__all__ = [
- "CardMng",
- "DLStatus",
- "Facility",
- "Local",
- "Message",
- "PCBEvent",
- "PCBTracker",
- "Package",
- "ServiceRequest",
- "ServiceType",
- "Services",
-]
+__all__ = ["ServiceRequest", "ServiceType", "Services"]
diff --git a/v8_server/eamuse/services/cardmng.py b/v8_server/eamuse/services/cardmng.py
index 1e6bf11..dfc9405 100644
--- a/v8_server/eamuse/services/cardmng.py
+++ b/v8_server/eamuse/services/cardmng.py
@@ -1,10 +1,12 @@
from typing import Any, Dict, List, Optional
+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 Card, Profile, RefID, User, UserAccount
-from v8_server.utils.convert import bool_to_int as btoi
+from v8_server.model.user import Card, RefID, User, UserAccount
+from v8_server.utils.convert import bool_to_int as btoi, int_to_bool as itob
class CardStatus(object):
@@ -19,38 +21,40 @@ class CardStatus(object):
INVALID_PIN = 116
-class CardMng(object):
+class Inquire(object):
"""
- Handle the CardMng (Card Manage) request.
+ Handle the CardMng Inquire request.
- This is for supporting eAmuse card interaction.
+ Given the Card ID, determine if we have a brand new user or a returning one.
+
+
+
+
"""
- # Methods
- INQUIRE = "inquire"
- GETREFID = "getrefid"
- AUTHPASS = "authpass"
- BINDMODEL = "bindmodel"
- GETKEEPSPAN = "getkeepspan"
- GETDATALIST = "getdatalist"
+ def __init__(self, req: ServiceRequest) -> None:
+ self.cardid = get_xml_attrib(req.xml[0], "cardid")
+ self.cardtype = int(get_xml_attrib(req.xml[0], "cardtype"))
+ self.update = int(get_xml_attrib(req.xml[0], "update"))
- @classmethod
- def inquire(cls, req: ServiceRequest):
+ # Model doesn't always exist in the request, unsure what it's used for
+ model_value = get_xml_attrib(req.xml[0], "model")
+ self.model = model_value if model_value != "None" else None
+
+ def response(self) -> etree:
"""
- Handle a Card Manage Inquire Request
-
- Either the given card id is a brand new user, or a returning user.
-
Modifyable XML Text Replacements:
refid: The RefID.refid value for an existing user
newflag: Set to true for a new user, else 0
binded: Set to true if the user has a profile/account, else 0
status: See CardMng status consts at the top of this class
"""
-
- # Grab the card id
- cardid = get_xml_attrib(req.xml[0], "cardid")
-
# New unregistered user
args: Dict[str, Any] = {
"newflag": 1,
@@ -69,7 +73,7 @@ class CardMng(object):
}
# We have a returning user
- if (user := User.from_cardid(cardid)) is not None:
+ if (user := User.from_cardid(self.cardid)) is not None:
refid = RefID.from_userid(user.userid)
bound = UserAccount.from_userid(user.userid) is not None
@@ -89,19 +93,44 @@ class CardMng(object):
"cardmng", "inquire", args, drop_attributes=drop_attributes
)
- @classmethod
- def getrefid(cls, req: ServiceRequest):
- # Grab the card id and pin
- cardid = get_xml_attrib(req.xml[0], "cardid")
- pin = get_xml_attrib(req.xml[0], "passwd")
+ def __repr__(self) -> str:
+ return (
+ f'CardMng.Inquire'
+ )
+
+class Getrefid(object):
+ """
+ Handle the CardMng Getrefid request.
+
+ Given the Card ID, password, etc, generate a new RefID for the user and return it
+
+
+
+
+ """
+
+ def __init__(self, req: ServiceRequest) -> None:
+ self.cardid = get_xml_attrib(req.xml[0], "cardid")
+ self.cardtype = int(get_xml_attrib(req.xml[0], "cardtype"))
+ self.newflag = itob(int(get_xml_attrib(req.xml[0], "newflag")))
+ self.passwd = get_xml_attrib(req.xml[0], "passwd")
+
+ def response(self) -> etree:
# Create a new user object with the given pin
- user = User(pin=pin)
+ user = User(pin=self.passwd)
db.session.add(user)
db.session.commit()
# Create the card, tie it to the user account
- card = Card(cardid=cardid, userid=user.userid)
+ card = Card(cardid=self.cardid, userid=user.userid)
db.session.add(card)
db.session.commit()
@@ -110,42 +139,79 @@ class CardMng(object):
return load_xml_template("cardmng", "getrefid", {"refid": refid.refid})
- @classmethod
- def authpass(cls, req: ServiceRequest):
- """"""
- # Grab the refid and pin
- refid_str = get_xml_attrib(req.xml[0], "refid")
- pin = get_xml_attrib(req.xml[0], "pass")
+ def __repr__(self) -> str:
+ return (
+ f'CardMng.Getrefid'
+ )
+
+class Authpass(object):
+ """
+ Handle the CardMng Authpass request.
+
+ Given the RefID, and password, verify that the password given is correct for that
+ user
+
+
+
+
+ """
+
+ def __init__(self, req: ServiceRequest) -> None:
+ self.passwd = get_xml_attrib(req.xml[0], "pass")
+ self.refid = get_xml_attrib(req.xml[0], "refid")
+
+ def response(self) -> etree:
# Grab the refid
- refid = db.session.query(RefID).filter(RefID.refid == refid_str).one_or_none()
+ refid = db.session.query(RefID).filter(RefID.refid == self.refid).one_or_none()
if refid is None:
raise Exception("RefID Is None Here!")
# Check if the pin is valid for the user
user = refid.user
- status = CardStatus.SUCCESS if user.pin == pin else CardStatus.INVALID_PIN
+ status = (
+ CardStatus.SUCCESS if user.pin == self.passwd else CardStatus.INVALID_PIN
+ )
return load_xml_template("cardmng", "authpass", {"status": status})
- @classmethod
- def bindmodel(cls, req: ServiceRequest):
- """"""
- # Grab the refid
- refid_str = get_xml_attrib(req.xml[0], "refid")
- refid = db.session.query(RefID).filter(RefID.refid == refid_str).one_or_none()
+ def __repr__(self) -> str:
+ return f'CardMng.Authpass'
+
+
+class Bindmodel(object):
+ """
+ Handle the CardMng Bindmodel request.
+
+ Given the RefID, and a newflag, bind the user to the current game.
+
+ XXX: Partially unsure what this actually needs to do
+
+
+
+
+ """
+
+ def __init__(self, req: ServiceRequest) -> None:
+ self.refid = get_xml_attrib(req.xml[0], "refid")
+ self.newflag = itob(int(get_xml_attrib(req.xml[0], "newflag")))
+
+ def response(self) -> etree:
+ refid = db.session.query(RefID).filter(RefID.refid == self.refid).one_or_none()
if refid is None:
raise Exception("RefID is None Here!")
- # Just bind some garbage here for now
- profile = Profile(refid=refid.refid, data={"data": "something"})
- db.session.add(profile)
- db.session.commit()
-
return load_xml_template("cardmng", "bindmodel", {"refid": refid.refid})
+ def __repr__(self) -> str:
+ return f'CardMng.Bindmodel'
+
+
+# TODO: figure out if these are actually used or not
+'''
@classmethod
def getkeepspan(cls):
"""
@@ -161,3 +227,4 @@ class CardMng(object):
Unclear what this method does, return a dummy response
"""
return load_xml_template("cardmng", "cardmng")
+'''
diff --git a/v8_server/eamuse/services/cardutil.py b/v8_server/eamuse/services/cardutil.py
new file mode 100644
index 0000000..76417c9
--- /dev/null
+++ b/v8_server/eamuse/services/cardutil.py
@@ -0,0 +1,161 @@
+import logging
+from typing import Any, Dict, List, Optional
+
+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.utils.convert import int_to_bool as itob
+
+
+logger = logging.getLogger(__name__)
+
+
+class Card(object):
+ """
+ Cardutil.Check.Card object
+ """
+
+ def __init__(self, root: etree) -> None:
+ self.no = int(get_xml_attrib(root, "no"))
+ self.refid = root.find("refid").text
+ self.uid = root.find("uid").text
+
+ def __repr__(self) -> str:
+ return f'Card'
+
+
+class CheckStatus(object):
+ """
+ Status values for the Cardutil.Check response
+ """
+
+ NEW_USER = 0
+ UNKNOWN = 1 # XXX: Unsure if this is used anywhere for anything
+ EXISTING_USER = 2
+
+
+class Check(object):
+ """
+ Handle the Cardutil.Check request.
+
+ Checks to see if the card belongs to a new user or an existing registered user.
+
+
+
+
+ E9D2DD02072F05C5
+ E00401007F7AD7A4
+
+
+
+ """
+
+ def __init__(self, req: ServiceRequest) -> None:
+ self.card = Card(req.xml[0].find("card"))
+
+ def __repr__(self) -> str:
+ return f"Cardutil.Check"
+
+ def response(self) -> etree:
+ user = User.from_refid(self.card.refid)
+
+ new_user = (
+ user is None or (account := UserAccount.from_userid(user.userid)) is None
+ )
+
+ # New User
+ args: Dict[str, Any] = {"state": CheckStatus.NEW_USER}
+ drop_children: Optional[Dict[str, List[str]]] = {
+ "cardutil/card": [
+ "name",
+ "gdp",
+ "skill",
+ "all_skill",
+ "chara",
+ "syogo",
+ "penalty",
+ ],
+ }
+
+ # Existing User
+ if not new_user and account is not None:
+ args = {
+ "state": CheckStatus.EXISTING_USER,
+ "name": account.name,
+ "chara": account.chara,
+ }
+ drop_children = None
+
+ return load_xml_template("cardutil", "check", args, drop_children=drop_children)
+
+
+class Data(object):
+ """
+ Cardutil.Regist.Data object
+ """
+
+ def __init__(self, root: etree) -> None:
+ self.no = int(get_xml_attrib(root, "no"))
+ self.refid = root.find("refid").text
+ self.name = root.find("name").text
+ self.chara = int(root.find("chara").text)
+ self.uid = root.find("uid").text
+ self.cabid = int(root.find("cabid").text)
+ self.is_succession = itob(int(root.find("is_succession")))
+
+ def __repr__(self) -> str:
+ return (
+ f'Data"
+ )
+
+
+class Regist(object):
+ """
+ Handle the Cardutil Regist request.
+
+ Register the data for a new user.
+
+
+
+
+ E9D2DD02072F05C5
+ AAAA
+ 0
+ E00401007F7AD7A4
+ 1
+ 0
+
+
+
+ """
+
+ def __init__(self, req: ServiceRequest) -> None:
+ self.data = Data(req.xml[0].find("data"))
+
+ def __repr__(self) -> str:
+ return f"Cardutil.Regist"
+
+ def response(self) -> etree:
+ user = User.from_refid(self.data.refid)
+ if user is None:
+ raise Exception("This user should theoretically exist here")
+ if user.card.cardid != self.data.uid:
+ raise Exception(
+ f"Card ID is incorrect: {user.card.cardid} != {self.data.uid}"
+ )
+
+ user_account = UserAccount(
+ userid=user.userid,
+ name=self.data.name,
+ chara=self.data.chara,
+ is_succession=self.data.is_succession,
+ )
+ db.session.add(user_account)
+ db.session.commit()
+
+ return load_xml_template("cardutil", "regist")
diff --git a/v8_server/eamuse/services/customize.py b/v8_server/eamuse/services/customize.py
new file mode 100644
index 0000000..5a5bcbc
--- /dev/null
+++ b/v8_server/eamuse/services/customize.py
@@ -0,0 +1,82 @@
+import logging
+
+from lxml import etree
+
+from v8_server.eamuse.services.services import ServiceRequest
+from v8_server.eamuse.xml.utils import get_xml_attrib, load_xml_template
+
+
+logger = logging.getLogger(__name__)
+
+
+class Get(object):
+ """
+ Customize.Regist.Player.Syogodata.Get object
+ """
+
+ def __init__(self, root: etree) -> None:
+ self.syogo = [int(x.text) for x in root.findall("syogo")]
+
+ def __repr__(self) -> str:
+ return f"Get"
+
+
+class Syogodata(object):
+ """
+ Customize.Regist.Player.Syogodata object
+ """
+
+ def __init__(self, root: etree) -> None:
+ self.get = Get(root.find("get"))
+
+ def __repr__(self) -> str:
+ return f"Syogodata"
+
+
+class Player(object):
+ """
+ Customize.Regist.Player object
+ """
+
+ def __init__(self, root: etree) -> None:
+ self.no = int(get_xml_attrib(root, "no"))
+ self.refid = root.find("refid").text
+ self.syogodata = Syogodata(root.find("syogodata"))
+
+ def __repr__(self) -> str:
+ return (
+ f'Player"
+ )
+
+
+class Regist(object):
+ """
+ Handle the Customize Regist request.
+
+ Possibly just used to save some customizations for the user after the game ends.
+ Such as giving the user a new title.
+
+
+
+
+ E9D2DD02072F05C5
+
+
+ 4
+ 0
+
+
+
+
+
+ """
+
+ def __init__(self, req: ServiceRequest) -> None:
+ self.players = [Player(x) for x in req.xml[0].findall("player")]
+
+ def __repr__(self) -> str:
+ return f"Customize.Regist"
+
+ def response(self) -> etree:
+ return load_xml_template("customize", "regist")
diff --git a/v8_server/eamuse/services/demodata.py b/v8_server/eamuse/services/demodata.py
new file mode 100644
index 0000000..66bb121
--- /dev/null
+++ b/v8_server/eamuse/services/demodata.py
@@ -0,0 +1,72 @@
+import logging
+from datetime import datetime
+
+from lxml import etree
+
+from v8_server.eamuse.services.services import ServiceRequest
+from v8_server.eamuse.xml.utils import load_xml_template
+from v8_server.model.song import HitChart
+
+
+logger = logging.getLogger(__name__)
+
+
+class Shop(object):
+ """
+ Demodata.Get.Shop object
+ """
+
+ def __init__(self, root: etree) -> None:
+ self.locationid = root.find("locationid").text
+
+ def __repr__(self) -> str:
+ return f'Shop'
+
+
+class Get(object):
+ """
+ Handle the Demodata Get request.
+
+ Return demo data for the hitchart, etc.
+
+
+
+
+ CA-123
+
+ 100
+
+
+ """
+
+ DT_FMT = "%Y-%m-%d %H:%M:%S%z"
+
+ def __init__(self, req: ServiceRequest) -> None:
+ self.shop = Shop(req.xml[0].find("shop"))
+ self.hitchart_nr = int(req.xml[0].find("hitchart_nr").text)
+
+ def __repr__(self) -> str:
+ return f"Demodata.Get"
+
+ def response(self) -> etree:
+ rank_items = HitChart.get_ranking(self.hitchart_nr)
+
+ # Generate all hitchart data xml
+ hitchart_xml_str = ""
+ for rank_item in rank_items:
+ hitchart_xml_str += etree.tostring(
+ load_xml_template(
+ "demodata", "get.data", {"musicid": rank_item, "last1": 0}
+ )
+ ).decode("UTF-8")
+
+ args = {
+ "hitchart_nr": self.hitchart_nr,
+ "start": datetime.now().strftime(self.DT_FMT),
+ "end": datetime.now().strftime(self.DT_FMT),
+ "hitchart_data": hitchart_xml_str,
+ "division": 14,
+ "message": "SenPi's Kickass DrumMania V8 Machine",
+ }
+
+ return load_xml_template("demodata", "get", args)
diff --git a/v8_server/eamuse/services/dlstatus.py b/v8_server/eamuse/services/dlstatus.py
index c2c7535..fb99534 100644
--- a/v8_server/eamuse/services/dlstatus.py
+++ b/v8_server/eamuse/services/dlstatus.py
@@ -1,16 +1,27 @@
+from lxml import etree
+
+from v8_server.eamuse.services.services import ServiceRequest
from v8_server.eamuse.xml.utils import load_xml_template
-class DLStatus(object):
+class Progress(object):
"""
- Handle the DLStatus request.
+ Handle the DLStatus Progress request.
It is unknown as to what this does.
+
+
+
+
+
+
"""
- # Methods
- PROGRESS = "progress"
+ def __init__(self, req: ServiceRequest) -> None:
+ self.progress_value = int(req.xml[0].find("progress").text)
- @classmethod
- def progress(cls):
+ def progress(self) -> etree:
return load_xml_template("dlstatus", "progress")
+
+ def __repr__(self) -> str:
+ return f"DLStatus.Progress