mirror of
https://gitea.tendokyu.moe/Hay1tsme/artemis.git
synced 2026-02-09 09:17:29 +08:00
Merge branch 'develop' into diva_handler_classes
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
@@ -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"}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {}
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user