-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathvalve_vpk.bms
161 lines (160 loc) · 4.28 KB
/
valve_vpk.bms
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# Valve - vpk
# ---
# also used in some Source engine games made not only by Valve itself
# but also by people outside Valve, see this Wikipedia article for a "entire" list of them:
# https://en.wikipedia.org/wiki/Source_(game_engine)
# there's also this Steam group who collects Steam games that use said engine
# https://steamcommunity.com/groups/sourceenginegames
get dir_file filename
set base_file string dir_file
string base_file - "_dir.vpk"
get sign_01 long
if sign_01 != 0x55aa1234
cleanexit
endif
get sign_02 long
xmath major_version "sign_02 & 0xffff"
if major_version != 2
cleanexit
endif
xmath minor_version "(sign_02 >> 16) & 0xffff"
string version_display p "%01d.%01d" major_version minor_version
print " Valve VPK filesystem version %version_display% "
get dir_size long
if major_version == 1
print " VPK version 1 not supported, contact me to request support for your file within this script. "
cleanexit
endif
if major_version == 2
get vpk_03 long
endif
if minor_version == 0
# everything else
get md5_size_01 long
get md5_size_02 long
get sig_size long
endif
if minor_version == 3
# Titanfall (2014)
# Titanfall 2 (2016)
putarray 0 0 "none"
putarray 0 1 "english"
putarray 0 2 "german"
putarray 0 3 "french"
putarray 0 4 "italian"
putarray 0 5 "korean"
putarray 0 6 "spanish"
putarray 0 7 "schinese"
putarray 0 8 "tchinese"
putarray 0 9 "russian"
putarray 0 10 "thai"
putarray 0 11 "japanese"
putarray 0 12 "portuguese"
putarray 0 13 "polish"
putarray 0 14 "danish"
putarray 0 15 "dutch"
putarray 0 16 "finnish"
putarray 0 17 "norwegian"
putarray 0 18 "swedish"
putarray 0 19 "czech"
putarray 0 20 "hungarian"
putarray 0 21 "romanian"
putarray 0 22 "turkish"
math folders = 0
math files = 0
math chunks_per_file = 0
set sc1 string ""
set sc2 string ""
for i = 0 < 1
if i = 0
for j = 0 < 23
getarray language_name 0 j
string base_file - language_name
next j
endif
next i
endif
for i = 0
get extension string
if extension == ""
break
else
math folders = 1
for j = 0 < folders
get path string
if path == ""
break
else
math files = 1
for k = 0 < files
get name string
get file_01 long
get file_02 short
if name != ""
string file_name p "%s/%s.%s" path name extension
print "%file_name%"
if minor_version == 0
get pak_number short
if pak_number != 0x7fff
string pak_name p "%s_%03d.vpk" base_file pak_number
open FDSE pak_name 1
endif
get file_offset long
get file_size long
if pak_number != 0x7fff
log file_name file_offset file_size 1
else
math file_offset + 0x1c
math file_offset + dir_size
log file_name file_offset file_size
endif
endif
if minor_version == 3
math chunks_per_file = 1
append
for l = 0 < chunks_per_file
get pak_number short
if pak_number == 0xffff
# wonky work-around for some Titanfall 2 vpk files
goto -2 0 SEEK_CUR
break
endif
string pak_name p "%s_%03d.vpk" base_file pak_number
open FDSE pak_name 1
get file_04 byte
get file_05 byte
get file_06 long
get file_offset_from_pak_number longlong
get compressed_chunk_size longlong
get original_chunk_size longlong
if original_chunk_size = 0x100000
math chunks_per_file + 1
endif
if compressed_chunk_size == original_chunk_size
log file_name file_offset_from_pak_number original_chunk_size 1
else
# (todo) Titanfall uses a (to the best of my knowledge)
# proprietary compression algorithm, not lzham.
#clog file_name file_offset_from_pak_number compressed_chunk_size original_chunk_size 1
#log file_name file_offset_from_pak_number compressed_chunk_size 1
endif
next l
append
endif
get delimiter short
if delimiter != 0xffff
break
endif
endif
get extra byte
if extra == 0
math folders + 1
else
goto -1 0 SEEK_CUR
math files + 1
endif
next k
endif
next j
endif
next i