Merge branch 'develop' into diva_handler_classes

This commit is contained in:
Kevin Trocolli
2023-03-13 02:27:12 -04:00
22 changed files with 221 additions and 202 deletions

View File

@@ -11,7 +11,7 @@ from Crypto.Util.Padding import pad
from os import path
from typing import Tuple
from core import CoreConfig
from core import CoreConfig, Utils
from titles.chuni.config import ChuniConfig
from titles.chuni.const import ChuniConstants
from titles.chuni.base import ChuniBase
@@ -111,6 +111,7 @@ class ChuniServlet:
encrtped = False
internal_ver = 0
endpoint = url_split[len(url_split) - 1]
client_ip = Utils.get_ip_addr(request)
if version < 105: # 1.0
internal_ver = ChuniConstants.VER_CHUNITHM
@@ -179,7 +180,7 @@ class ChuniServlet:
req_data = json.loads(unzip)
self.logger.info(
f"v{version} {endpoint} request from {request.getClientAddress().host}"
f"v{version} {endpoint} request from {client_ip}"
)
self.logger.debug(req_data)

View File

@@ -60,6 +60,9 @@ class ChuniNew(ChuniBase):
"isAou": "false",
}
def handle_remove_token_api_request(self, data: Dict) -> Dict:
return { "returnCode": "1" }
def handle_delete_token_api_request(self, data: Dict) -> Dict:
return {"returnCode": "1"}

View File

@@ -26,6 +26,8 @@ class CardMaker136(CardMakerBase):
ret["gameConnectList"][0]["titleUri"] = f"{uri}/SDHD/205/"
ret["gameConnectList"][1]["titleUri"] = f"{uri}/SDEZ/125/"
ret["gameConnectList"][2]["titleUri"] = f"{uri}/SDDT/135/"
return ret
def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
ret = super().handle_get_game_setting_api_request(data)

View File

@@ -98,11 +98,11 @@ class CxbServlet(resource.Resource):
).listen(server.Site(CxbServlet(self.core_cfg, self.cfg_dir)))
self.logger.info(
f"Crossbeats title server ready on port {self.game_cfg.server.port} & {self.game_cfg.server.port_secure}"
f"Ready on ports {self.game_cfg.server.port} & {self.game_cfg.server.port_secure}"
)
else:
self.logger.info(
f"Crossbeats title server ready on port {self.game_cfg.server.port}"
f"Ready on port {self.game_cfg.server.port}"
)
def render_POST(self, request: Request):

View File

@@ -298,6 +298,6 @@ class DivaReader(BaseReader):
tree[key] = (
value
if len(vector) == 1
else self.add_branch(tree[key] if key in tree else {}, vector[1:], value)
else self.add_branch(tree.get(key, {}), vector[1:], value)
)
return tree

View File

@@ -1,6 +1,6 @@
from datetime import datetime, timedelta
import json
from typing import Any
import json, logging
from typing import Any, Dict
from core.config import CoreConfig
from titles.pokken.config import PokkenConfig
@@ -12,6 +12,7 @@ class PokkenBase:
self.core_cfg = core_cfg
self.game_cfg = game_cfg
self.version = 0
self.logger = logging.getLogger("pokken")
def handle_noop(self, request: Any) -> bytes:
res = jackal_pb2.Response()
@@ -20,25 +21,26 @@ class PokkenBase:
return res.SerializeToString()
def handle_ping(self, request: jackal_pb2.PingRequestData) -> bytes:
def handle_ping(self, request: jackal_pb2.Request) -> bytes:
res = jackal_pb2.Response()
res.result = 1
res.type = jackal_pb2.MessageType.PING
return res.SerializeToString()
def handle_register_pcb(self, request: jackal_pb2.RegisterPcbRequestData) -> bytes:
def handle_register_pcb(self, request: jackal_pb2.Request) -> bytes:
res = jackal_pb2.Response()
res.result = 1
res.type = jackal_pb2.MessageType.REGISTER_PCB
self.logger.info(f"Register PCB {request.register_pcb.pcb_id}")
regist_pcb = jackal_pb2.RegisterPcbResponseData()
regist_pcb.server_time = int(datetime.now().timestamp() / 1000)
regist_pcb.server_time = int(datetime.now().timestamp())
biwa_setting = {
"MatchingServer": {
"host": f"https://{self.game_cfg.server.hostname}",
"port": self.game_cfg.server.port_matching,
"url": "/matching",
"port": self.game_cfg.server.port,
"url": "/SDAK/100/matching",
},
"StunServer": {
"addr": self.game_cfg.server.hostname,
@@ -60,7 +62,7 @@ class PokkenBase:
return res.SerializeToString()
def handle_save_ads(self, request: jackal_pb2.SaveAdsRequestData) -> bytes:
def handle_save_ads(self, request: jackal_pb2.Request) -> bytes:
res = jackal_pb2.Response()
res.result = 1
res.type = jackal_pb2.MessageType.SAVE_ADS
@@ -68,7 +70,7 @@ class PokkenBase:
return res.SerializeToString()
def handle_save_client_log(
self, request: jackal_pb2.SaveClientLogRequestData
self, request: jackal_pb2.Request
) -> bytes:
res = jackal_pb2.Response()
res.result = 1
@@ -77,7 +79,7 @@ class PokkenBase:
return res.SerializeToString()
def handle_check_diagnosis(
self, request: jackal_pb2.CheckDiagnosisRequestData
self, request: jackal_pb2.Request
) -> bytes:
res = jackal_pb2.Response()
res.result = 1
@@ -86,7 +88,7 @@ class PokkenBase:
return res.SerializeToString()
def handle_load_client_settings(
self, request: jackal_pb2.CheckDiagnosisRequestData
self, request: jackal_pb2.Request
) -> bytes:
res = jackal_pb2.Response()
res.result = 1
@@ -108,3 +110,36 @@ class PokkenBase:
res.load_client_settings.CopyFrom(settings)
return res.SerializeToString()
def handle_load_ranking(self, request: jackal_pb2.Request) -> bytes:
res = jackal_pb2.Response()
res.result = 1
res.type = jackal_pb2.MessageType.LOAD_RANKING
ranking = jackal_pb2.LoadRankingResponseData()
ranking.ranking_id = 1
ranking.ranking_start = 0
ranking.ranking_end = 1
ranking.event_end = True
ranking.modify_date = int(datetime.now().timestamp() / 1000)
res.load_ranking.CopyFrom(ranking)
def handle_matching_noop(self, data: Dict = {}, client_ip: str = "127.0.0.1") -> Dict:
return {}
def handle_matching_start_matching(self, data: Dict = {}, client_ip: str = "127.0.0.1") -> Dict:
return {}
def handle_matching_is_matching(self, data: Dict = {}, client_ip: str = "127.0.0.1") -> Dict:
"""
"sessionId":"12345678",
"A":{
"pcb_id": data["data"]["must"]["pcb_id"],
"gip": client_ip
},
"list":[]
"""
return {}
def handle_matching_stop_matching(self, data: Dict = {}, client_ip: str = "127.0.0.1") -> Dict:
return {}

View File

@@ -31,43 +31,24 @@ class PokkenServerConfig:
self.__config, "pokken", "server", "port", default=9000
)
@property
def port_matching(self) -> int:
return CoreConfig.get_config_field(
self.__config, "pokken", "server", "port_matching", default=9001
)
@property
def port_stun(self) -> int:
return CoreConfig.get_config_field(
self.__config, "pokken", "server", "port_stun", default=9002
self.__config, "pokken", "server", "port_stun", default=9001
)
@property
def port_turn(self) -> int:
return CoreConfig.get_config_field(
self.__config, "pokken", "server", "port_turn", default=9003
self.__config, "pokken", "server", "port_turn", default=9002
)
@property
def port_admission(self) -> int:
return CoreConfig.get_config_field(
self.__config, "pokken", "server", "port_admission", default=9004
self.__config, "pokken", "server", "port_admission", default=9003
)
@property
def ssl_cert(self) -> str:
return CoreConfig.get_config_field(
self.__config, "pokken", "server", "ssl_cert", default="cert/pokken.crt"
)
@property
def ssl_key(self) -> str:
return CoreConfig.get_config_field(
self.__config, "pokken", "server", "ssl_key", default="cert/pokken.key"
)
class PokkenConfig(dict):
def __init__(self) -> None:
self.server = PokkenServerConfig(self)

View File

@@ -1,18 +1,20 @@
from typing import Tuple
from twisted.web.http import Request
from twisted.web import resource, server
from twisted.internet import reactor, endpoints
from twisted.web import resource
import json, ast
from datetime import datetime
import yaml
import logging, coloredlogs
from logging.handlers import TimedRotatingFileHandler
from titles.pokken.proto import jackal_pb2
import inflection
from os import path
from google.protobuf.message import DecodeError
from core.config import CoreConfig
from core import CoreConfig, Utils
from titles.pokken.config import PokkenConfig
from titles.pokken.base import PokkenBase
from titles.pokken.const import PokkenConstants
from titles.pokken.proto import jackal_pb2
class PokkenServlet(resource.Resource):
@@ -65,17 +67,10 @@ class PokkenServlet(resource.Resource):
if not game_cfg.server.enable:
return (False, "", "")
if core_cfg.server.is_develop:
return (
True,
f"https://{game_cfg.server.hostname}:{game_cfg.server.port}/{game_code}/$v/",
f"{game_cfg.server.hostname}:{game_cfg.server.port}/",
)
return (
True,
f"https://{game_cfg.server.hostname}/{game_code}/$v/",
f"{game_cfg.server.hostname}/",
f"https://{game_cfg.server.hostname}:{game_cfg.server.port}/{game_code}/$v/",
f"{game_cfg.server.hostname}/SDAK/$v/",
)
@classmethod
@@ -90,46 +85,19 @@ class PokkenServlet(resource.Resource):
)
if not game_cfg.server.enable:
return (False, "", "")
return (False, "")
return (True, "PKFN")
return (True, "PKF2")
def setup(self):
"""
There's currently no point in having this server on because Twisted
won't play ball with both the fact that it's TLSv1.1, and because the
types of certs that pokken will accept are too flimsy for Twisted
so it will throw a fit. Currently leaving this here in case a bypass
is discovered in the future, but it's unlikly. For now, just use NGINX.
"""
if self.game_cfg.server.enable and self.core_cfg.server.is_develop:
key_exists = path.exists(self.game_cfg.server.ssl_key)
cert_exists = path.exists(self.game_cfg.server.ssl_cert)
if key_exists and cert_exists:
endpoints.serverFromString(
reactor,
f"ssl:{self.game_cfg.server.port}"
f":interface={self.core_cfg.server.listen_address}:privateKey={self.game_cfg.server.ssl_key}:"
f"certKey={self.game_cfg.server.ssl_cert}",
).listen(server.Site(self))
self.logger.info(
f"Pokken title server ready on port {self.game_cfg.server.port}"
)
else:
self.logger.error(
f"Could not find cert at {self.game_cfg.server.ssl_key} or key at {self.game_cfg.server.ssl_cert}, Pokken not running."
)
def setup(self) -> None:
# TODO: Setup stun, turn (UDP) and admission (WSS) servers
pass
def render_POST(
self, request: Request, version: int = 0, endpoints: str = ""
) -> bytes:
if endpoints == "":
endpoints = request.uri.decode()
if endpoints.startswith("/matching"):
self.logger.info("Matching request")
if endpoints == "matching":
return self.handle_matching(request)
content = request.content.getvalue()
if content == b"":
@@ -143,12 +111,50 @@ class PokkenServlet(resource.Resource):
self.logger.warn(f"{e} {content}")
return b""
endpoint = jackal_pb2.MessageType(pokken_request.type).name.lower()
self.logger.info(f"{endpoint} request")
endpoint = jackal_pb2.MessageType.DESCRIPTOR.values_by_number[
pokken_request.type
].name.lower()
handler = getattr(self.base, f"handle_{endpoint}", None)
if handler is None:
self.logger.warn(f"No handler found for message type {endpoint}")
return self.base.handle_noop(pokken_request)
return handler(pokken_request)
self.logger.info(f"{endpoint} request from {Utils.get_ip_addr(request)}")
self.logger.debug(pokken_request)
ret = handler(pokken_request)
self.logger.debug(f"Response: {ret}")
return ret
def handle_matching(self, request: Request) -> bytes:
content = request.content.getvalue()
client_ip = Utils.get_ip_addr(request)
if content is None or content == b"":
self.logger.info("Empty matching request")
return json.dumps(self.base.handle_matching_noop()).encode()
json_content = ast.literal_eval(content.decode().replace('null', 'None').replace('true', 'True').replace('false', 'False'))
self.logger.info(f"Matching {json_content['call']} request")
self.logger.debug(json_content)
handler = getattr(self.base, f"handle_matching_{inflection.underscore(json_content['call'])}", None)
if handler is None:
self.logger.warn(f"No handler found for message type {json_content['call']}")
return json.dumps(self.base.handle_matching_noop()).encode()
ret = handler(json_content, client_ip)
if ret is None:
ret = {}
if "result" not in ret:
ret["result"] = "true"
if "data" not in ret:
ret["data"] = {}
if "timestamp" not in ret:
ret["timestamp"] = int(datetime.now().timestamp() * 1000)
self.logger.debug(f"Response {ret}")
return json.dumps(ret).encode()

View File

@@ -1,6 +1,7 @@
import yaml
import jinja2
from twisted.web.http import Request
from os import path
from core.frontend import FE_Base
from core.config import CoreConfig
@@ -16,7 +17,10 @@ class WaccaFrontend(FE_Base):
super().__init__(cfg, environment)
self.data = WaccaData(cfg)
self.game_cfg = WaccaConfig()
self.game_cfg.update(yaml.safe_load(open(f"{cfg_dir}/wacca.yaml")))
if path.exists(f"{cfg_dir}/{WaccaConstants.CONFIG_NAME}"):
self.game_cfg.update(
yaml.safe_load(open(f"{cfg_dir}/{WaccaConstants.CONFIG_NAME}"))
)
self.nav_name = "Wacca"
def render_GET(self, request: Request) -> bytes:

View File

@@ -8,7 +8,7 @@ from twisted.web.http import Request
from typing import Dict, Tuple
from os import path
from core.config import CoreConfig
from core import CoreConfig, Utils
from titles.wacca.config import WaccaConfig
from titles.wacca.config import WaccaConfig
from titles.wacca.const import WaccaConstants
@@ -89,25 +89,30 @@ class WaccaServlet:
request.responseHeaders.addRawHeader(b"X-Wacca-Hash", hash.hex().encode())
return json.dumps(resp).encode()
client_ip = Utils.get_ip_addr(request)
try:
req_json = json.loads(request.content.getvalue())
version_full = Version(req_json["appVersion"])
except:
self.logger.error(
f"Failed to parse request toi {request.uri} -> {request.content.getvalue()}"
f"Failed to parse request to {url_path} -> {request.content.getvalue()}"
)
resp = BaseResponse()
resp.status = 1
resp.message = "不正なリクエスト エラーです"
return end(resp.make())
url_split = url_path.split("/")
start_req_idx = url_split.index("api") + 1
if "/api/" in url_path:
func_to_find = (
"handle_" + url_path.partition("api/")[2].replace("/", "_") + "_request"
)
func_to_find = "handle_"
for x in range(len(url_split) - start_req_idx):
func_to_find += f"{url_split[x + start_req_idx]}_"
func_to_find += "request"
else:
self.logger.error(f"Malformed url {url_path}")
resp = BaseResponse()
resp.status = 1
resp.message = "Bad URL"
return end(resp.make())
ver_search = int(version_full)
@@ -136,7 +141,7 @@ class WaccaServlet:
return end(resp.make())
self.logger.info(
f"v{req_json['appVersion']} {url_path} request from {request.getClientAddress().host} with chipId {req_json['chipId']}"
f"v{req_json['appVersion']} {url_path} request from {client_ip} with chipId {req_json['chipId']}"
)
self.logger.debug(req_json)