This commit is contained in:
Naruse
2025-04-15 19:36:05 +08:00
parent dd51fb491d
commit ec8972d5d6
121 changed files with 30598 additions and 0 deletions

44
sdk_server/__init__.py Normal file
View File

@@ -0,0 +1,44 @@
import logging
from flask import Flask
from sdk_server.controllers.config.agreement_controller import agreement_blueprint
from sdk_server.controllers.config.alert_ann_controller import alert_ann_blueprint
from sdk_server.controllers.config.alert_pict_controller import alert_pic_blueprint
from sdk_server.controllers.config.batch_upload_controller import batch_upload_blueprint
from sdk_server.controllers.config.combo_config_controller import combo_config_blueprint
from sdk_server.controllers.config.combo_controller import combo_blueprint
from sdk_server.controllers.config.compare_protocol_ver_controller import compare_protocol_ver_blueprint
from sdk_server.controllers.config.data_upload_controller import data_upload_blueprint
from sdk_server.controllers.config.risky_check_controller import risky_check_blueprint
from sdk_server.controllers.login.login_controller import login_blueprint
from sdk_server.controllers.login.login_v2_controller import login_v2_blueprint
from sdk_server.controllers.login.query_dispatch_controller import query_dispatch_blueprint
from sdk_server.controllers.login.query_gateway_controller import query_gateway_blueprint
from sdk_server.controllers.login.token_login_controller import token_login_blueprint
app = Flask(__name__)
log = logging.getLogger('werkzeug')
log.setLevel(logging.ERROR)
# CONFIG
app.register_blueprint(agreement_blueprint)
app.register_blueprint(alert_ann_blueprint)
app.register_blueprint(alert_pic_blueprint)
app.register_blueprint(batch_upload_blueprint)
app.register_blueprint(combo_config_blueprint)
app.register_blueprint(combo_blueprint)
app.register_blueprint(compare_protocol_ver_blueprint)
app.register_blueprint(data_upload_blueprint)
app.register_blueprint(risky_check_blueprint)
# LOGIN
app.register_blueprint(login_blueprint)
app.register_blueprint(login_v2_blueprint)
app.register_blueprint(query_dispatch_blueprint)
app.register_blueprint(query_gateway_blueprint)
app.register_blueprint(token_login_blueprint)
def run_http_server(host, port):
app.run(host=host, port=port, debug=False)

View File

@@ -0,0 +1,16 @@
from flask import Blueprint, jsonify
from sdk_server.models.config.agreement_data import AgreementInfoRsp
agreement_blueprint = Blueprint('agreement', __name__)
@agreement_blueprint.route('/hkrpg_cn/mdk/agreement/api/getAgreementInfos', methods=['GET'])
@agreement_blueprint.route('/hkrpg_global/mdk/agreement/api/getAgreementInfos', methods=['GET'])
def agreement():
response_data = AgreementInfoRsp(
retcode=0,
message="OK",
data=AgreementInfoRsp.Data(
marketing_agreements=[]
)
)
return jsonify(response_data.model_dump())

View File

@@ -0,0 +1,19 @@
from flask import Blueprint, jsonify
from sdk_server.models.config.alert_ann_data import AlertAnnRsp
alert_ann_blueprint = Blueprint('alert_ann', __name__)
@alert_ann_blueprint.route('/common/hkrpg_cn/announcement/api/getAlertAnn', methods=['GET'])
@alert_ann_blueprint.route('/common/hkrpg_global/announcement/api/getAlertAnn', methods=['GET'])
def alert_ann():
response_data = AlertAnnRsp(
retcode=0,
message="OK",
data=AlertAnnRsp.Data(
alert=False,
alert_id=0,
remind=True,
extra_remind=True
)
)
return jsonify(response_data.model_dump())

View File

@@ -0,0 +1,17 @@
from flask import Blueprint, jsonify
from sdk_server.models.config.alert_pic_data import AlertPicRsp
alert_pic_blueprint = Blueprint('alert_pic', __name__)
@alert_pic_blueprint.route('/common/hkrpg_cn/announcement/api/getAlertPic', methods=['GET'])
@alert_pic_blueprint.route('/common/hkrpg_global/announcement/api/getAlertPic', methods=['GET'])
def alert_pic():
response_data = AlertPicRsp(
retcode=0,
message="OK",
data=AlertPicRsp.Data(
total=0,
list=[]
)
)
return jsonify(response_data.model_dump())

View File

@@ -0,0 +1,13 @@
from flask import Blueprint, jsonify
from sdk_server.models.config.batch_upload_data import BatchUploadRsp
batch_upload_blueprint = Blueprint('batch_upload', __name__)
@batch_upload_blueprint.route('/common/h5log/log/batch', methods=['POST'])
def batch_upload():
response_data = BatchUploadRsp(
retcode=0,
message="success",
data=[]
)
return jsonify(response_data.model_dump())

View File

@@ -0,0 +1,35 @@
from flask import Blueprint, jsonify
from sdk_server.models.config.combo_config_data import ComboConfigRsp,QrEnabledApps,QrAppIcons
combo_config_blueprint = Blueprint('combo_config', __name__)
@combo_config_blueprint.route('/hkrpg_cn/combo/granter/api/getConfig', methods=['GET'])
@combo_config_blueprint.route('/hkrpg_global/combo/granter/api/getConfig', methods=['GET'])
def combo_config():
response_data = ComboConfigRsp(
retcode=0,
message="OK",
data=ComboConfigRsp.Data(
protocol = True,
qr_enabled = False,
log_level = "INFO",
announce_url = "",
push_alias_type = 0,
disable_ysdk_guard = True,
enable_announce_pic_popup = False,
app_name = "崩坏RPG",
qr_enabled_apps=QrEnabledApps(
bbs=False,
cloud=False
),
qr_app_icons=QrAppIcons(
app="",
bbs="",
cloud=""
),
qr_cloud_display_name="",
enable_user_center=False,
functional_switch_configs=[]
)
)
return jsonify(response_data.model_dump())

View File

@@ -0,0 +1,51 @@
from flask import Blueprint, jsonify
from sdk_server.models.config.combo_data import (
ComboRsp,
KibanaPc,
Report,
Telemetry,
LogFilter,
RenderMethod,
Function
)
combo_blueprint = Blueprint('combo', __name__)
@combo_blueprint.route('/combo/box/api/config/sdk/combo', methods=['GET'])
def combo():
response_data = ComboRsp(
vals=ComboRsp.Values(
kibana_pc_config=KibanaPc(
enable=1,
level="Info",
modules=["download"]
),
network_report_config=Report(
enable=1,
status_codes=[206],
url_paths=["dataUpload", "red_dot"]
),
modify_real_name_other_verify=True,
telemetry_config=Telemetry(
dataupload_enable=1
),
enable_web_dpi=True,
h5log_filter_config=LogFilter(
function=Function(
event_name=[
"info_get_cps",
"notice_close_notice",
"info_get_uapc",
"report_set_info",
"info_get_channel_id",
"info_get_sub_channel_id"
]
)
),
webview_rendermethod_config=RenderMethod(
use_legacy=True
),
list_price_tierv2_enable=True
)
)
return jsonify(response_data.model_dump())

View File

@@ -0,0 +1,17 @@
from flask import Blueprint, jsonify
from sdk_server.models.config.compare_protocol_ver_data import CompareProtocolVerRsp
compare_protocol_ver_blueprint = Blueprint('compare_protocol_ver', __name__)
@compare_protocol_ver_blueprint.route('/hkrpg_cn/combo/granter/api/compareProtocolVersion', methods=['POST'])
@compare_protocol_ver_blueprint.route('/hkrpg_global/combo/granter/api/compareProtocolVersion', methods=['POST'])
def compare_protocol_ver():
response_data = CompareProtocolVerRsp(
retcode=0,
message="OK",
data=CompareProtocolVerRsp.Data(
modified=False,
protocol=[]
)
)
return jsonify(response_data.model_dump())

View File

@@ -0,0 +1,12 @@
from flask import Blueprint, jsonify
from sdk_server.models.config.log_upload_data import LogUploadRsp
data_upload_blueprint = Blueprint('data_upload', __name__)
@data_upload_blueprint.route('/sdk/dataUpload', methods=['POST'])
@data_upload_blueprint.route('/loginsdk/dataUpload', methods=['POST'])
@data_upload_blueprint.route('/crashdump/dataUpload', methods=['POST'])
@data_upload_blueprint.route('/apm/dataUpload', methods=['POST'])
def data_upload():
response_data = LogUploadRsp(code=0)
return jsonify(response_data.model_dump())

View File

@@ -0,0 +1,17 @@
from flask import Blueprint, jsonify
from sdk_server.models.config.risky_check_data import RiskyCheckRsp
risky_check_blueprint = Blueprint('risky_check', __name__)
@risky_check_blueprint.route('/account/risky/api/check', methods=['POST'])
def risky_check():
response_data = RiskyCheckRsp(
retcode=0,
message="OK",
data=RiskyCheckRsp.Data(
id="none",
action="ACTION_NONE",
geetest={}
)
)
return jsonify(response_data.model_dump())

View File

@@ -0,0 +1,42 @@
from flask import Blueprint, jsonify, request
from database.account.account_data import create_new_account
from sdk_server.models.login.login_data import LoginReq,LoginRsp,Account
from database.account.account_data import find_account_by_name
login_blueprint = Blueprint('login', __name__)
@login_blueprint.route('/hkrpg_cn/mdk/shield/api/login', methods=['POST'])
@login_blueprint.route('/hkrpg_global/mdk/shield/api/login', methods=['POST'])
@login_blueprint.route('/account/ma-cn-passport/app/loginByPassword', methods=['POST'])
def login():
body=request.get_json()
try:
login_req = LoginReq(**body)
except Exception as e:
return jsonify({"error": "Invalid input", "details": str(e)}), 400
account_data=find_account_by_name(login_req.account)
if not account_data:
create_new_account(login_req.account)
account_data=find_account_by_name(login_req.account)
rsp=LoginRsp(
retcode=0,
message="success",
data=LoginRsp.Data(
account=Account(
uid=str(account_data.id),
name=account_data.username + "@MikuMiku",
token=account_data.token,
is_email_verify=0,
realname="Miku",
identity_card="114514",
country="OS",
area_code="OS",
),
device_grant_required=False,
realname_operation="NONE",
realperson_required=False,
safe_mobile_required=False
)
)
return jsonify(rsp.model_dump())

View File

@@ -0,0 +1,36 @@
import json
from flask import Blueprint, jsonify, request
from utils.crypto import generate_combo_token
from sdk_server.models.login.login_v2_data import LoginV2Req,LoginV2Rsp
from database.account.account_data import find_account_by_uid
login_v2_blueprint = Blueprint('login_v2', __name__)
@login_v2_blueprint.route('/hkrpg_cn/combo/granter/login/v2/login', methods=['POST'])
@login_v2_blueprint.route('/hkrpg_global/combo/granter/login/v2/login', methods=['POST'])
def login_v2():
res=LoginV2Rsp()
body=request.json
login_v2_req=LoginV2Req(**body)
data_dict = json.loads(login_v2_req.data)
token_data = LoginV2Req.Data(**data_dict)
if not token_data:
res.retcode=0
res.message="Invalid login data"
return jsonify(res.model_dump())
account_data=find_account_by_uid(int(token_data.uid))
if not account_data:
res.retcode=-201
res.message="Game account cache information error"
return jsonify(res.model_dump())
res.message="OK"
res.data=LoginV2Rsp.Data(
account_type=1,
open_id=str(account_data.id),
combo_token=generate_combo_token(str(account_data.id)),
data="{\"guest\":false}"
)
return jsonify(res.model_dump())

View File

@@ -0,0 +1,20 @@
import base64
from flask import Blueprint
from rail_proto.lib import Dispatch,RegionInfo
query_dispatch_blueprint = Blueprint('query_dispatch', __name__)
@query_dispatch_blueprint.route("/query_dispatch", methods=["GET"])
def query_dispatch():
rsp = Dispatch(
retcode=0,
region_list=[
RegionInfo(
name="NeonSR",
title="NeonSR",
env_type="21",
dispatch_url="http://127.0.0.1:21000/query_gateway",
)
]
)
return base64.b64encode(rsp.SerializeToString()).decode()

View File

@@ -0,0 +1,45 @@
import base64
import json
from flask import Blueprint,request
from rail_proto.lib import GateServer
query_gateway_blueprint = Blueprint('query_gateway', __name__)
@query_gateway_blueprint.route("/query_gateway", methods=["GET"])
def query_gateway():
version = request.args.get('version')
with open('version.json', 'r') as f:
reader = json.load(f)
config = reader.get(version)
if config:
rsp = GateServer(
retcode=0,
ip="127.0.0.1",
port=23301,
asset_bundle_url="",
lua_url="",
ex_resource_url="",
mdk_res_version="",
enable_version_update=True,
enable_design_data_version_update=True,
enable_save_replay_file=True,
enable_upload_battle_log=True,
enable_watermark=True,
event_tracking_open=True,
)
else:
rsp = GateServer(
retcode=0,
ip="127.0.0.1",
port=23301,
asset_bundle_url="",
lua_url="",
ex_resource_url="",
enable_version_update=True,
enable_design_data_version_update=True,
enable_save_replay_file=True,
enable_upload_battle_log=True,
enable_watermark=True,
event_tracking_open=True,
)
return base64.b64encode(rsp.SerializeToString()).decode()

View File

@@ -0,0 +1,40 @@
from flask import Blueprint, jsonify, request
from sdk_server.models.login.token_login_data import TokenLoginReq
from sdk_server.models.login.login_data import LoginRsp,Account
from database.account.account_data import find_account_by_uid
token_login_blueprint = Blueprint('token_login', __name__)
@token_login_blueprint.route('/hkrpg_cn/mdk/shield/api/verify', methods=['POST'])
@token_login_blueprint.route('/hkrpg_global/mdk/shield/api/verify', methods=['POST'])
@token_login_blueprint.route('/account/ma-cn-session/app/verify', methods=['POST'])
def token_login():
res=LoginRsp()
body=request.json
req=TokenLoginReq(**body)
account_data=find_account_by_uid(int(req.uid))
if not account_data or account_data.token != req.token:
res.retcode=0
res.message="Game account cache information error"
else:
res.retcode=0
res.message="OK"
res.data=LoginRsp.Data(
account=Account(
uid=str(account_data.id),
name=account_data.username + "@MikuMiku",
token=account_data.token,
is_email_verify=0,
realname="Miku",
identity_card="114514",
country="OS",
area_code="OS",
),
device_grant_required=False,
realname_operation="NONE",
realperson_required=False,
safe_mobile_required=False
)
return jsonify(res.model_dump())

View File

@@ -0,0 +1,9 @@
from pydantic import BaseModel
from typing import List, Optional
from sdk_server.models.config.response_base import ResponseBase
class AgreementInfoRsp(ResponseBase):
class Data(BaseModel):
marketing_agreements: Optional[List[str]] = []
data: Optional[Data] = None

View File

@@ -0,0 +1,12 @@
from pydantic import BaseModel
from typing import Optional
from sdk_server.models.config.response_base import ResponseBase
class AlertAnnRsp(ResponseBase):
class Data(BaseModel):
alert : bool
alert_id: int
remind: bool
extra_remind: bool
data: Optional[Data] = None

View File

@@ -0,0 +1,10 @@
from pydantic import BaseModel
from typing import Optional,List
from sdk_server.models.config.response_base import ResponseBase
class AlertPicRsp(ResponseBase):
class Data(BaseModel):
total : bool
list: Optional[List[str]] = []
data: Optional[Data] = None

View File

@@ -0,0 +1,6 @@
from pydantic import BaseModel
from typing import List, Optional
from sdk_server.models.config.response_base import ResponseBase
class BatchUploadRsp(ResponseBase):
data:Optional[List] = []

View File

@@ -0,0 +1,32 @@
from pydantic import BaseModel
from typing import Optional,List
from sdk_server.models.config.response_base import ResponseBase
class QrEnabledApps(BaseModel):
bbs: bool
cloud: bool
class QrAppIcons(BaseModel):
app: Optional[str] = None
bbs: Optional[str] = None
cloud: Optional[str] = None
class ComboConfigRsp(ResponseBase):
class Data(BaseModel):
protocol: bool
qr_enabled: bool
log_level: Optional[str] = None
announce_url: Optional[str] = None
push_alias_type: int
disable_ysdk_guard: bool
enable_announce_pic_popup: bool
app_name: Optional[str] = None
qr_enabled_apps: Optional[QrEnabledApps] = None
qr_app_icons: Optional[QrAppIcons] = None
qr_cloud_display_name: Optional[str] = None
enable_user_center: bool
functional_switch_configs: Optional[List[str]] = None
data: Optional[Data] = None

View File

@@ -0,0 +1,44 @@
from pydantic import BaseModel
from typing import Optional, List
from sdk_server.models.config.response_base import ResponseBase
class KibanaPc(BaseModel):
enable: int
level: Optional[str] = None
modules: Optional[List[str]] = None
class Report(BaseModel):
enable: int
status_codes: Optional[List[int]] = None
url_paths: Optional[List[str]] = None
class Telemetry(BaseModel):
dataupload_enable: int
class Function(BaseModel):
event_name: Optional[List[str]] = None
class LogFilter(BaseModel):
function: Optional[Function] = None
class RenderMethod(BaseModel):
use_legacy: bool
class ComboRsp(BaseModel):
class Values(BaseModel):
kibana_pc_config: Optional[KibanaPc] = None
network_report_config: Optional[Report] = None
modify_real_name_other_verify: bool
telemetry_config: Optional[Telemetry] = None
enable_web_dpi: bool
h5log_filter_config: Optional[LogFilter] = None
webview_rendermethod_config: Optional[RenderMethod] = None
list_price_tierv2_enable: bool
vals: Optional[Values] = None

View File

@@ -0,0 +1,10 @@
from pydantic import BaseModel
from typing import List, Optional
from sdk_server.models.config.response_base import ResponseBase
class CompareProtocolVerRsp(ResponseBase):
class Data(BaseModel):
modified: bool
protocol: Optional[List[str]] = []
data: Optional[Data] = None

View File

@@ -0,0 +1,13 @@
from pydantic import BaseModel
from typing import Optional
from sdk_server.models.config.response_base import ResponseBase
class FingerprintRsp(ResponseBase):
class Data(BaseModel):
device_fp: Optional[str] = None
msg: Optional[str] = None
code: int
data: Optional[Data] = None

View File

@@ -0,0 +1,4 @@
from pydantic import BaseModel
class LogUploadRsp(BaseModel):
code: int

View File

@@ -0,0 +1,6 @@
from pydantic import BaseModel
from typing import Optional
class ResponseBase(BaseModel):
retcode: int = 0
message: Optional[str] = None

View File

@@ -0,0 +1,12 @@
from pydantic import BaseModel
from typing import Optional, Any
from sdk_server.models.config.response_base import ResponseBase
class RiskyCheckRsp(ResponseBase):
data: Optional["Data"] = None
class Data(BaseModel):
id: Optional[str] = None
action: Optional[str] = None
geetest: Optional[Any] = None

View File

@@ -0,0 +1,44 @@
from pydantic import BaseModel
from typing import Optional
from sdk_server.models.config.response_base import ResponseBase
class Account(BaseModel):
uid: Optional[str] = None
name: Optional[str] = None
email: Optional[str] = None
mobile: Optional[str] = None
is_email_verify: int
realname: Optional[str] = None
identity_card: Optional[str] = None
token: Optional[str] = None
safe_mobile: Optional[str] = None
facebook_name: Optional[str] = None
twitter_name: Optional[str] = None
game_center_name: Optional[str] = None
google_name: Optional[str] = None
apple_name: Optional[str] = None
sony_name: Optional[str] = None
tap_name: Optional[str] = None
country: Optional[str] = None
reactivate_ticket: Optional[str] = None
area_code: Optional[str] = None
device_grant_ticket: Optional[str] = None
class LoginReq(BaseModel):
account: Optional[str] = None
password: Optional[str] = None
is_crypto: bool
class LoginRsp(ResponseBase):
class Data(BaseModel):
account: Optional[Account] = None
device_grant_required: bool
realname_operation: Optional[str] = None
realperson_required: bool
safe_mobile_required: bool
data: Optional[Data] = None

View File

@@ -0,0 +1,29 @@
from pydantic import BaseModel
from typing import Optional
from sdk_server.models.config.response_base import ResponseBase
class LoginV2Req(BaseModel):
app_id: int
channel_id: int
data: Optional[str] = None
device: Optional[str] = None
sign: Optional[str] = None
class Data(BaseModel):
uid: Optional[str] = None
token: Optional[str] = None
guest: bool
class LoginV2Rsp(ResponseBase):
data: Optional["Data"] = None
class Data(BaseModel):
account_type: int
heartbeat: Optional[bool] = False
combo_id: Optional[str] = None
combo_token: Optional[str] = None
open_id: Optional[str] = None
data: Optional[str] = None
fatigue_remind: Optional[str] = None

View File

@@ -0,0 +1,6 @@
from pydantic import BaseModel
from typing import Optional
class TokenLoginReq(BaseModel):
uid: Optional[str] = None
token: Optional[str] = None