记录一下BH3第一部的私服搭建以及功能完善过程

使用已有工具运行

直接运行一键启动.exe,然后开启phpstudy的nginx服务。

已进行的操作(注意点)

  • 修改nginx配置目录
  • 修改目录名字为纯英文
  • 安装mitmproxy,导入mitmproxy证书
  • 安装.Net工具
  • 第一次安装好后不要进入,重启游戏

问题解决

网络连接失败,请检查网络设置

进入游戏后发现无法连接网络

查看代理的terminal发现没有日志信息,发现是系统代理并没有开启。

开启后可以看到日志信息:

发现服务器拒绝连接,使用http://127.0.0.1访问发现为404,首先怀疑是安装mimtproxy的证书。

参考链接:mitmproxy的下载及证书配置

此处要注意现有工具设置的代理端口为8891

查看nginx的错误日志error.log文件发现问题,路径设置有误,找到路径定义位置进行修改:

更改后发现仍然报错,原来是www/127.0.0.1/目录下就没有这两个文件:

根据教程要修改BH3/BH3/config.json的内容HOST字段为127.0.0.1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"UseLocalCache": false,
"CreateAccountOnLoginAttempt": true,
"DatabaseUri": "mongodb://127.0.0.1:27017",
"Gameserver": {
"Port": 16100,
"RegionName": "BH3",
"Host": "127.0.0.1"
},
"Http": {
"HttpPort": 8081,
"HttpsPort": 443
},
"VerboseLevel": "Debug"
}

发现原来一键启动后只有两个终端,少了一个服务器的终端进程,怀疑是没有安装.NET工具

将这五个工具全部按顺序运行一遍,然后重新一键启动

成功弹出三个终端,并且游戏内网络错误报错消失

下载数值文件失败,请确认网络、读写权限以及存储空间后点击重试

报错如下:

重启游戏和服务器即可,或者也有可能是phpstudy的问题

重启后使用用户名1,密码1登录,就可以进入游戏了。

正常的服务端运行截图(供后续调试参考)

正常的mitmproxy日志信息(供参考)

使用已有服务器源码运行

服务器源码为C#编写

服务端运行

运行源码中的Program.cs文件,发现服务端成功启动,监听在80和443端口

为防止端口冲突,需要修改监听端口为8081,修改Program.cs文件内容即可

修改配置文件bin/Debug/net6.0/config.json内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"UseLocalCache": false,
"CreateAccountOnLoginAttempt": true,
"DatabaseUri": "mongodb://127.0.0.1:27017",
"Gameserver": {
"Port": 16100,
"RegionName": "BH3",
"Host": "127.0.0.1"
},
"Http": {
"HttpPort": 8081,
"HttpsPort": 443
},
"VerboseLevel": "Debug"
}

注意输出日志为硬编码的80端口, A lie!

修改为以下内容,让日志打印正确值:

1
c.Log($"HTTP server started on port {Global.config.Http.HttpPort} & {Global.config.Http.HttpsPort}"); // Truth

发现正常

代理运行

mitmproxy

首先开启系统代理8891端口,直接将以下脚本另存为switchProxy.bat,使用ANSI编码保存可以解决中文乱码问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@echo off
for /f "tokens=1,2,* " %%i in ('REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyEnable ^| find /i "ProxyEnable"') do (set /A ProxyEnableValue=%%k)

if %ProxyEnableValue% equ 0 (
echo 系统代理目前处于关闭状态,正在开启代理,请稍候...
echo=
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyEnable /t REG_DWORD /d 1 /f >nul 2>nul
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyServer /d "127.0.0.1:8891" /f >nul 2>nul
echo 系统代理已开启,请按任意键关闭本窗口...
) else if %ProxyEnableValue% equ 1 (
echo 系统代理目前处于开启状态,正在关闭代理,请稍候...
echo=
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyEnable /t REG_DWORD /d 0 /f >nul 2>nul
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyServer /d "" /f >nul 2>nul
echo 系统代理已关闭,请按任意键退出本窗口...
)
pause>nul

执行以下命令

1
2
3
4
.\switchProxy.bat
.\bin\mitmdump.exe -p 8891 -s .\proxy.py
# mitmweb方便调试
.\bin\mitmweb.exe -p 8891 -s .\proxy.py --web-port 8892

proxy.py脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from mitmproxy import http
from mitmproxy import ctx
from mitmproxy.proxy import layer, layers

def load(loader):
# ctx.options.web_open_browser = False
# We change the connection strategy to lazy so that next_layer happens before we actually connect upstream.
ctx.options.connection_strategy = "lazy"
ctx.options.upstream_cert = False
ctx.options.ssl_insecure = True

def next_layer(nextlayer: layer.NextLayer):
# ctx.log(
# f"{nextlayer.context=}\n"
# f"{nextlayer.data_client()[:70]=}\n"
# )
sni = nextlayer.context.client.sni
if sni and (sni.endswith("yuanshen.com") or sni.endswith("mihoyo.com") or sni.endswith("hoyoverse.com") or sni.endswith("starrails.com") or sni.endswith("bhsr.com") or sni.endswith("kurogame.com") or sni.endswith("zenlesszonezero.com") or sni.endswith("api.g3.proletariat.com") or sni.endswith("global01.os.honkaiimpact3.com") or sni.endswith("overseas01-appsflyer-report.honkaiimpact3.com") or sni.endswith("westglobal01.honkaiimpact3.com") or sni.endswith("bh3.com") and not (sni.endswith("bundle.bh3.com") or sni.endswith("qcloud.bh3.com") or sni.endswith("bh3rd-beta.bh3.com"))):
ctx.log('sni:' + sni)
nextlayer.context.server.address = ("127.0.0.1", 443)

def request(flow: http.HTTPFlow) -> None:
# flow.request.scheme = "http"

# pretty_host takes the "Host" header of the request into account
if flow.request.pretty_url.startswith('http://global01.west.honkaiimpact3.com'):
flow.request.host = "127.0.0.1"
flow.request.headers["Host"] = "127.0.0.1"
if flow.request.pretty_url.startswith('http://log-upload-os.mihoyo.com') or flow.request.pretty_url.startswith('http://client-report.bh3.com'):
flow.response = http.Response.make(
200, # (optional) status code
b"404 not found", # (optional) content
{"Content-Type": "text/html"} # (optional) headers
)
return

数据库代理运行

1
.\mongod.exe --dbpath .\data\

解决以下问题后,可以成功进入游戏

问题解决

网络连接失败,请检查网络设置

这一问题很普遍,请先检查是否已正常打开系统代理,服务端,然后可以多参考mitmproxy的输出日志信息

查看mitmproxy日志信息与正常的进行比较发现缺少query_gateway url访问

分析后得知是query_dispatch的url访问问题

对比发现正常响应没有设定端口

修改服务器端query_dispatch的响应

成功解决该问题

下载数值文件失败

查看服务端正常输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
20:11:18 <HTTP> 200 GET /query_dispatch
20:11:18 <HTTP> 200 GET /query_gateway
20:11:18 <HTTP> 404 POST /crashdump/dataUpload
20:11:18 <HTTP> 404 POST /crashdump/dataUpload
20:11:18 <HTTP> 404 POST /crashdump/dataUpload
20:11:18 <HTTP> 200 GET /admin/mi18n/plat_oversea/m2020030410/m2020030410-version.json
20:11:18 <HTTP> 200 GET /admin/mi18n/plat_os/m09291531181441/m09291531181441-version.json
20:11:18 <HTTP> 200 POST /sdk/dataUpload
20:11:18 <HTTP> 200 POST /sdk/dataUpload
20:11:18 <HTTP> 200 GET /bh3_os/combo/granter/api/getConfig
20:11:18 <HTTP> 200 GET /device-fp/api/getExtList
20:11:18 <HTTP> 200 GET /combo/box/api/config/sdk/combo
20:11:18 <HTTP> 200 GET /bh3_os/mdk/shield/api/loadConfig
20:11:18 <HTTP> 200 POST /bh3_os/combo/granter/api/compareProtocolVersion
20:11:18 <HTTP> 200 POST /sdk/dataUpload
20:11:18 <HTTP> 200 POST /sdk/dataUpload
20:11:18 <HTTP> 200 POST /device-fp/api/getFp
20:11:18 <HTTP> 200 POST /sdk/dataUpload
20:11:19 <HTTP> 200 POST /sdk/dataUpload
20:11:19 <HTTP> 200 POST /sdk/dataUpload
20:11:23 <HTTP> 200 POST /sdk/dataUpload
20:11:23 <HTTP> 200 GET /combo/box/api/config/sw/precache
20:11:23 <HTTP> 200 POST /sdk/dataUpload
20:11:23 <HTTP> 200 GET /sw.html
20:11:24 <HTTP> 404 POST /apm/dataUpload
20:11:24 <HTTP> 200 POST /common/h5log/log/batch
20:11:27 <HTTP> 200 POST /sdk/dataUpload
20:11:27 <HTTP> 200 POST /sdk/dataUpload
20:11:27 <HTTP> 200 POST /sdk/dataUpload
20:11:27 <HTTP> 200 POST /sdk/dataUpload
20:11:27 <HTTP> 200 POST /sdk/dataUpload
20:11:27 <HTTP> 200 POST /bh3_os/mdk/shield/api/verify
20:11:27 <HTTP20:11:27 > 200 POST /sdk/dataUpload
<HTTP> 200 POST /account/device/api/listNewerDevices
20:11:27 <HTTP> 200 POST /sdk/dataUpload
20:11:27 <HTTP> 200 POST /sdk/dataUpload
20:11:27 <HTTP> 200 POST /data_abtest_api/config/experiment/list
20:11:27 <HTTP> 200 POST /bh3_os/combo/granter/login/v2/login
20:11:28 <HTTP> 200 POST /sdk/dataUpload
20:11:28 <HTTP> 200 GET /bh3_os/mdk/agreement/api/getAgreementInfos
20:11:28 <HTTP> 200 POST /sdk/dataUpload
20:11:30 <HTTP> 404 POST /apm/dataUpload
20:11:30 <HTTP> 200 POST /common/h5log/log/batch

应该是query_gateway的响应url有问题,没有加端口:

在所有Global.config.Gameserver.Host后全部加上端口号(无果)。

怀疑是phpstudy与服务器的配置有误

正常情况下phpstudy日志信息

而使用源码运行并没有产生新的日志,说明服务器端并没有向phpstudy发送请求

确定为DispatchController.cs文件的GetAssetBundleUrlList存在问题

修改返回值为正确值

然后发现服务器端成功出现对/combo/box/api/config/sw/precache的url请求,说明CS进行了进一步交互。

下载活动资源失败,请确定读写权限以及存储空间后点击重试

重启游戏继续报错,查看详细信息发现是声音映射文件出错

对比query_gateway后发现缺少”manifest”字段

1
2
3
4
5
6
7
8
"manifest": {
"Audio": {
"platform": {
"Windows": "manifest_0b6ab335.m" //固定值
},
"revision": 650645 // 固定值
}
},

服务器使用

GM指令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
------------------------------【GM 命令】----------------------------
进入游戏在游戏内聊天窗口输入
以下是可用的命令:
-----------------
level <number>
设置玩家等级(人物88级,数字改多少就是多少级。最高应该是89)
例如:
level 88
-----------------
avatar <add|modify> <avatarId> <...>
将角色添加到用户帐户或修改角色信息
例如:
avatar add 713
avatar modify 713 Level 80
请注意 字母L是大写的
-----------------
avatar modify -1 level 80(一键角色80级)
avatar modify -1 Star 5(全部SSS级)
-----------------
give <avatars|weapons|stigmata|materials|dress>.
获取所有角色, 、武器、徽章、材料或服装
例如:
give avatars(全部角色)
give weapons(全部武器)
give stigmata(全部圣痕)
give materials(全部材料)危险操作
give dress(全部衣服)
give material-id 100 5(给id为5的物品加100个)
give gold 999999(加金币)
-----------------
give avatars weapons stigmata dress materials
获取所有 角色 武器 徽章 服装 材料(可能会炸存档,不建议使用)
-----------------

删库重开

删除mongod的data目录中所有内容即可。

更新cg动画为中文

找国服的Video重命名后替换即可

解包图片等资源

使用AssetStudio工具来提取./StreamingAssets/Asb/pc中的wmv数据。