Tra cứu
Năm URL launcher gọi
Phần tiêu đề “Năm URL launcher gọi”Tất cả đều là {RemoteURL} cộng đường dẫn. RemoteURL bắt buộc kết thúc bằng /, vì launcher
ghép chuỗi trần ("%sGameUpdate/update.xml") chứ không tự chèn dấu phân cách.
GameUpdate/update.xml manifest của game, cái quan trọng nhấtLuncherUpdate/update.xml manifest của chính launcherServerList/list.xml danh sách server (danh sách thật đến từ login reply)ServerList/recommend.xml gọi khi bấm LOGINUpdate/Luncher/asup.exe chính file updaterThời điểm gọi
Phần tiêu đề “Thời điểm gọi”| Thao tác | Launcher tải gì |
|---|---|
| launcher mở lên | không gì cả |
| bấm LOGIN | ServerList/recommend.xml (×2) |
| bấm ENTER ở chọn server | GameUpdate/update.xml (×4), rồi từng <Url>, rồi update.xml lần nữa |
Payload bị tải hai lần. Cứ tính gấp đôi băng thông.
Field trong update.xml
Phần tiêu đề “Field trong update.xml”Manifest không có root element. CurVersion và UpdateVersion là hai node ngang hàng ở cấp cao
nhất. Đừng bọc chúng lại cho gọn, code parse gọi FirstChildElement thẳng trên document.
| Field | Ý nghĩa |
|---|---|
CurVersion (text) |
version kênh này đang rao. Update chỉ chạy khi CurVersion > local. Đây là thứ làm update dừng lại. |
SrcVer |
version mà block này nâng cấp từ, so bằng nhau với version dưới máy. * là wildcard, khớp mọi client. |
DstVer |
version block nâng cấp lên. Không phải cổng gì cả. |
<Url> text |
đường dẫn dưới {RemoteURL} để tải. Thiếu text thì tải về 0 byte và báo thành công. |
PatchName |
tên file lúc staging |
FileName |
đường dẫn đích, tính từ thư mục client. Dùng \ được. Ở mode Patch thì để rỗng. |
PatchMode |
Replace cho cả file, Patch để chèn file vào .pde |
Chuỗi version phải có đúng bốn phần cách nhau bằng dấu chấm. Ba hay năm phần thì parse hỏng mà không báo, cả block bị bỏ qua.
Wildcard chỉ ăn ở chỗ caller bật cờ cho phép. Version dưới máy được parse với cờ tắt, nên * không
bao giờ thay được nó.
Ma trận SrcVer
Phần tiêu đề “Ma trận SrcVer”Đo qua bốn lần chạy, DstVer và CurVersion đều là 1.4.0.64566:
SrcVer published |
client.exe version |
Kết quả |
|---|---|---|
* |
1.4.0.64564 | tải |
| 1.4.0.64564 | 1.4.0.64564 | tải |
| 1.4.0.64560 | 1.4.0.64564 | không rao, dù 64564 < DstVer |
| 1.4.0.64564 | 1.4.0.64566 | không rao |
Release bình thường thì dùng --src-version '*' và ship kèm client.exe đã stamp. Chỉ pin SrcVer
cụ thể khi cố ý loại bớt máy.
Dấu * phải sống sót qua shell. Câu ssh asbox "wsl python3 … --src-version *" sẽ bị glob-expand
theo home directory của máy từ xa. Viết thành
ssh asbox "wsl sh -c \"set -f; python3 … --src-version * …\"".
Opcode trong patch.lst
Phần tiêu đề “Opcode trong patch.lst”Mỗi dòng: chữ opcode ở byte đầu, đường dẫn bắt đầu từ offset 2.
| Op | Ý nghĩa |
|---|---|
P <archive> |
mở archive ra làm mục tiêu. Op nào sau đó có đường dẫn bắt đầu bằng <archive>\ thì áp bên trong archive đó |
A <relpath> |
thêm, tự tạo thư mục nếu thiếu |
U <relpath> |
ghi đè, không tạo thư mục |
D <relpath> |
xóa |
S <number> |
ghi vào một biến global đếm tiến độ |
B, C, E tới O, Q, R, T, và mọi thứ ngoài khoảng A–U đều rơi vào nhánh default rồi
bị bỏ qua, không báo gì. Gõ nhầm một chữ opcode là mất nguyên dòng đó.
Client định tuyến bằng cách tra đường dẫn chứ không theo P gần nhất. Op nào có thành phần đầu của
đường dẫn trùng một archive đã đăng ký thì rơi vào archive đó, còn lại ghi file ra thư mục client.
U lên một path đã có để lại đúng một entry, nó thay tại chỗ chứ không tạo bản trùng.
D trên một thư mục thì chưa ai thử. diff_pde.py chỉ sinh op cho file, thư mục mất hết file thì
nó báo lại rồi để nguyên.
Mã lỗi
Phần tiêu đề “Mã lỗi”Con số trong Error Code=0x... là id của chính câu thông báo đang hiện, không phải status code.
Nhánh hiện nó truyền hằng 0 vào tham số format.
| Code | Thông báo | Chỗ bắn ra |
|---|---|---|
-1 |
0x40000059 update game failed |
fallthrough, có kèm tham số |
-2 |
0x40000056 download timeout |
hàm download |
-3 |
0x40000057 file not exist |
hàm download |
-4 |
0x40000058 size error |
hàm download |
-5 |
(không hiện dialog) | bị hủy |
-6 |
0x4000005a “Auto patch” / unpack |
applier |
-7 |
(không hiện dialog) | — |
0x4000005a nghĩa là tải về thì xong, CopyFileW đè lên file đang sống thì chết. Gần như luôn
là do game vẫn đang chạy.
Chuỗi thông báo nằm trong LanguageDll.dll dưới dạng RT_MESSAGETABLE (type 11), 104 message × 5
thứ tiếng. Grep file EXE không ra gì. Bản tiếng Anh cẩu thả nhất trong năm bản, đọc bản tiếng Trung.
Version dưới máy nằm ở đâu
Phần tiêu đề “Version dưới máy nằm ở đâu”| Nơi | Có phải cổng update không |
|---|---|
client.exe VS_FIXEDFILEINFO |
Có. Launcher tự mở file rồi tự parse |
launch.ini [Ver] game |
Không. asup.exe có ghi, nhưng launcher không đọc để quyết định |
avital\launch.ini [Ver] game |
Không. Không bao giờ được đọc |
/version trong mỗi .pde |
Không. Chưa thấy nó ảnh hưởng gì |
Số version hiện ở màn hình chọn nhân vật nằm bên trong image client.exe, không file nào trên đĩa
đổi được nó. Sau bản release 1.4.0.64567, chuỗi 1.4.0.64564 không còn ở đâu trên bản cài nữa mà
màn hình vẫn hiện 64564. Muốn đổi thì client/set_client_version.py --label sửa cái được in ra,
thông qua UI_common_Version trong game_text.lua của từng pack.
Công cụ
Phần tiêu đề “Công cụ”| Script | Làm gì |
|---|---|
research/69_patch_channel/diff_pde.py |
so hai bản build, in danh sách op và trích payload |
research/69_patch_channel/make_delta.py |
đóng gói delta.dat từ danh sách op. Nhớ --check |
research/69_patch_channel/publish.py |
ghi payload và thêm block vào manifest. Chưa emit được block delta |
server/patch/publish.py |
như trên, phía server |
server/patch/stamp_version.py |
đóng dấu version resource của client.exe |
server/patch/patchsrv.py |
patch server. Log mọi request kể cả 404, kèm SENT <path> <bytes> |
research/01_pde_archive/pde_pack.py |
đóng gói một cây thư mục thành .pde |
research/16_add_content/fix_idhash_pde.py |
sửa idHash trong một archive |
Hai script publish.py hiện chỉ nhận một --mode chung cho cả block và luôn ghi
FileName=<PatchName>. Bản delta cần FileName="" và cần chọn mode riêng cho từng <Url>, nên
manifest delta phải gõ tay.
Mấy cái bẫy đã có người dính
Phần tiêu đề “Mấy cái bẫy đã có người dính”- Xài chung
--out-dirgiữa các archive làm file trùng đường dẫn tương đối đè lên nhau. Mỗi archive một thư mục riêng. - File op phân tách bằng TAB. Có một file đang ship tên là
/ui/skinf/skin_chuancheng_button3_disabled copy.tga.cache, trong tên có dấu cách. Tách theo whitespace thì một op thành năm field vàmake_delta.pychết vớiFileNotFoundError: 'copy.tga.cache'. --checkbỏ qua.physx.cache, và bắt buộc phải bỏ qua. Đó là họ file duy nhất chưa giải được công thức idHash. Vô hại khi copy nguyên xi byte của nhà phát hành, không vô hại với file.physxtự tạo.- idHash phân biệt hoa thường mà archive dùng chữ thường.
/ui/skinf/...đúng,/ui/skinF/...sai. - Đường dẫn đem đi băm phải có dấu gạch chéo mở đầu.
- Xác minh bằng hash và bằng màn hình game. Dòng 200 trong access log chỉ chứng minh file đã được gửi, không chứng minh nó đã cài.
patchsrv.pyphải chạy đa luồng. Launcher là hai HTTP client trong cùng một process, updater và browser control, mà browser thì giữ socket mở sau khi tải xong trang. TrênTCPServerđơn luồng, một kết nối rảnh như vậy chặn mọi request phía sau, làm ENTER hỏng vớiCURLE_OPERATION_TIMEDOUTtrong khi port vẫn nhận kết nối và curl vẫn lấy được manifest.- Đừng bao giờ trỏ
RemoteURLvào host của nhà phát hành cũ. Manifest bên đó liệt kêclient.exeở modeReplace, và host đó vẫn phân giải được. Nó mà trả lời thì launcher ghi đè binary của mình.
Bản nháp đang review. Nội dung nội bộ, đừng chia sẻ ra ngoài nhóm.