pokken support
This commit is contained in:
parent
9ee155792e
commit
abb25aa328
9
example_config/pokken.yaml
Normal file
9
example_config/pokken.yaml
Normal 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
17
titles/pokken/__init__.py
Normal 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
103
titles/pokken/base.py
Normal 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
37
titles/pokken/config.py
Normal 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
12
titles/pokken/const.py
Normal 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
73
titles/pokken/index.py
Normal 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)
|
139
titles/pokken/proto/jackal_pb2.py
Normal file
139
titles/pokken/proto/jackal_pb2.py
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user