pokken support

This commit is contained in:
Hay1tsme 2023-02-17 02:09:26 -05:00
parent 9ee155792e
commit abb25aa328
7 changed files with 390 additions and 0 deletions

View File

@ -0,0 +1,9 @@
server:
enable: True
loglevel: "info"
hostname: "localhost"
ssl_enable: False
port: 9000
port_matching: 9001
ssl_cert: cert/pokken.crt
ssl_key: cert/pokken.key

17
titles/pokken/__init__.py Normal file
View File

@ -0,0 +1,17 @@
from titles.pokken.index import PokkenServlet
from titles.pokken.const import PokkenConstants
index = PokkenServlet
use_default_title = True
include_protocol = True
title_secure = True
game_codes = [PokkenConstants.GAME_CODE]
trailing_slash = True
use_default_host = False
include_port = True
uri="https://$h:$p/"
host="$h:$p/"
current_schema_version = 1

103
titles/pokken/base.py Normal file
View File

@ -0,0 +1,103 @@
from datetime import datetime, timedelta
import json
from typing import Any
from core.config import CoreConfig
from titles.pokken.config import PokkenConfig
from titles.pokken.proto import jackal_pb2
class PokkenBase():
def __init__(self, core_cfg: CoreConfig, game_cfg: PokkenConfig) -> None:
self.core_cfg = core_cfg
self.game_cfg = game_cfg
self.version = 0
def handle_noop(self, request: Any) -> bytes:
res = jackal_pb2.Response()
res.result = 1
res.type = request.type
return res.SerializeToString()
def handle_ping(self, request: jackal_pb2.PingRequestData) -> 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:
res = jackal_pb2.Response()
res.result = 1
res.type = jackal_pb2.MessageType.REGISTER_PCB
regist_pcb = jackal_pb2.RegisterPcbResponseData()
regist_pcb.server_time = int(datetime.now().timestamp() / 1000)
biwa_setting = {
"MatchingServer": {
"host": f"https://{self.core_cfg.title.hostname}",
"port": 9000,
"url": "/matching"
},
"StunServer": {
"addr": self.core_cfg.title.hostname,
"port": 3333
},
"TurnServer": {
"addr": self.core_cfg.title.hostname,
"port": 4444
},
"AdmissionUrl": f"ws://{self.core_cfg.title.hostname}:1111",
"locationId": 123,
"logfilename": "JackalMatchingLibrary.log",
"biwalogfilename": "./biwa.log"
}
regist_pcb.bnp_baseuri = f"{self.core_cfg.title.hostname}/bna"
regist_pcb.biwa_setting = json.dumps(biwa_setting)
res.register_pcb.CopyFrom(regist_pcb)
return res.SerializeToString()
def handle_save_ads(self, request: jackal_pb2.SaveAdsRequestData) -> bytes:
res = jackal_pb2.Response()
res.result = 1
res.type = jackal_pb2.MessageType.SAVE_ADS
return res.SerializeToString()
def handle_save_client_log(self, request: jackal_pb2.SaveClientLogRequestData) -> bytes:
res = jackal_pb2.Response()
res.result = 1
res.type = jackal_pb2.MessageType.SAVE_CLIENT_LOG
return res.SerializeToString()
def handle_check_diagnosis(self, request: jackal_pb2.CheckDiagnosisRequestData) -> bytes:
res = jackal_pb2.Response()
res.result = 1
res.type = jackal_pb2.MessageType.CHECK_DIAGNOSIS
return res.SerializeToString()
def handle_load_client_settings(self, request: jackal_pb2.CheckDiagnosisRequestData) -> bytes:
res = jackal_pb2.Response()
res.result = 1
res.type = jackal_pb2.MessageType.LOAD_CLIENT_SETTINGS
settings = jackal_pb2.LoadClientSettingsResponseData()
settings.money_magnification = 0
settings.continue_bonus_exp = 100
settings.continue_fight_money = 100
settings.event_bonus_exp = 100
settings.level_cap = 999
settings.op_movie_flag = 0xFFFFFFFF
settings.lucky_bonus_rate = 1
settings.fail_support_num = 10
settings.chara_open_flag = 0xFFFFFFFF
settings.chara_open_date = int(datetime.now().timestamp() / 1000)
settings.chara_pre_open_date = int(datetime.now().timestamp() / 1000)
settings.search_id = 123
res.load_client_settings.CopyFrom(settings)
return res.SerializeToString()

37
titles/pokken/config.py Normal file
View File

@ -0,0 +1,37 @@
from core.config import CoreConfig
class PokkenServerConfig():
def __init__(self, parent_config: "PokkenConfig"):
self.__config = parent_config
@property
def enable(self) -> bool:
return CoreConfig.get_config_field(self.__config, 'pokken', 'server', 'enable', default=True)
@property
def loglevel(self) -> int:
return CoreConfig.str_to_loglevel(CoreConfig.get_config_field(self.__config, 'pokken', 'server', 'loglevel', default="info"))
@property
def hostname(self) -> str:
return CoreConfig.get_config_field(self.__config, 'pokken', 'server', 'hostname', default="localhost")
@property
def port(self) -> int:
return CoreConfig.get_config_field(self.__config, 'pokken', 'server', 'port', default=9000)
@property
def port_matching(self) -> int:
return CoreConfig.get_config_field(self.__config, 'pokken', 'server', 'port', default=9001)
@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)

12
titles/pokken/const.py Normal file
View File

@ -0,0 +1,12 @@
class PokkenConstants():
GAME_CODE = "SDAK"
CONFIG_NAME = "pokken.yaml"
VER_POKKEN = 0
VERSION_NAMES = ("Pokken Tournament")
@classmethod
def game_ver_to_string(cls, ver: int):
return cls.VERSION_NAMES[ver]

73
titles/pokken/index.py Normal file
View File

@ -0,0 +1,73 @@
from twisted.web.http import Request
from twisted.web import resource, server
from twisted.internet import reactor, endpoints
import yaml
import logging, coloredlogs
from logging.handlers import TimedRotatingFileHandler
from titles.pokken.proto import jackal_pb2
from google.protobuf import text_format
from core.config import CoreConfig
from titles.pokken.config import PokkenConfig
from titles.pokken.base import PokkenBase
class PokkenServlet(resource.Resource):
def __init__(self, core_cfg: CoreConfig, cfg_dir: str) -> None:
self.isLeaf = True
self.core_cfg = core_cfg
self.config_dir = cfg_dir
self.game_cfg = PokkenConfig()
self.game_cfg.update(yaml.safe_load(open(f"{cfg_dir}/pokken.yaml")))
self.logger = logging.getLogger("pokken")
if not hasattr(self.logger, "inited"):
log_fmt_str = "[%(asctime)s] Pokken | %(levelname)s | %(message)s"
log_fmt = logging.Formatter(log_fmt_str)
fileHandler = TimedRotatingFileHandler("{0}/{1}.log".format(self.core_cfg.server.log_dir, "pokken"), encoding='utf8',
when="d", backupCount=10)
fileHandler.setFormatter(log_fmt)
consoleHandler = logging.StreamHandler()
consoleHandler.setFormatter(log_fmt)
self.logger.addHandler(fileHandler)
self.logger.addHandler(consoleHandler)
self.logger.setLevel(self.game_cfg.server.loglevel)
coloredlogs.install(level=self.game_cfg.server.loglevel, logger=self.logger, fmt=log_fmt_str)
self.logger.inited = True
self.base = PokkenBase(core_cfg, self.game_cfg)
def setup(self):
if self.game_cfg.server.enable:
if self.core_cfg.server.is_develop:
endpoints.serverFromString(reactor, f"ssl:{self.game_cfg.server.port}"\
f":interface={self.game_cfg.server.hostname}:privateKey={self.game_cfg.server.ssl_key}:"\
f"certKey={self.game_cfg.server.ssl_cert}")\
.listen(server.Site(PokkenServlet(self.core_cfg, self.config_dir)))
else:
endpoints.serverFromString(reactor, f"tcp:{self.game_cfg.server.port}"\
f":interface={self.game_cfg.server.hostname}")\
.listen(server.Site(PokkenServlet(self.core_cfg, self.config_dir)))
self.logger.info(f"Pokken title server ready on port {self.game_cfg.server.port}")
def render_POST(self, request: Request, version: int, endpoints: str) -> bytes:
req_url = request.uri.decode()
if req_url == "/matching":
self.logger.info("Matching request")
pokken_request = jackal_pb2.Request()
pokken_request.ParseFromString(request.content.getvalue())
endpoint = jackal_pb2.MessageType(pokken_request.type).name.lower()
self.logger.info(f"{endpoint} request")
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)

File diff suppressed because one or more lines are too long