11#! /bin/bash
22
3+ # Use C locale for consistent sorting and string operations
34export LC_ALL=C
45
6+ # Resolve the directory where this script lives
57ROOT_DIR=" $( dirname " $( realpath -s " ${BASH_SOURCE[0]} " ) " ) "
68
9+ # Append .exe suffix on Windows
710EXE_SUFFIX=" "
811if [[ " $( uname -s) " == MINGW* ]] || [[ " $( uname -s) " == MSYS* ]]; then
912 EXE_SUFFIX=" .exe"
1013fi
1114
15+ # Tool paths
1216VRF_PATH=" $ROOT_DIR /tools/exe/Source2Viewer/Source2Viewer-CLI${EXE_SUFFIX} "
1317PROTOBUF_DUMPER_PATH=" $ROOT_DIR /tools/exe/ProtobufDumper/ProtobufDumper${EXE_SUFFIX} "
1418DUMP_STRINGS_PATH=" $ROOT_DIR /tools/exe/DumpStrings${EXE_SUFFIX} "
1519STEAM_FILE_DOWNLOADER_PATH=" $ROOT_DIR /tools/exe/SteamFileDownloader/SteamFileDownloader${EXE_SUFFIX} "
1620FIX_ENCODING_PATH=" $ROOT_DIR /tools/exe/FixEncoding${EXE_SUFFIX} "
21+
22+ # Allow disabling git operations by passing "no-git" as the first or second argument
1723DO_GIT=1
1824
1925if [[ $# -gt 0 ]]; then
@@ -22,26 +28,30 @@ if [[ $# -gt 0 ]]; then
2228 fi
2329fi
2430
31+ # ProcessDepot - Processes binary files of a given type by dumping protobufs and extracting strings.
32+ # @param $1 - File extension to process (e.g. .dll, .so, .dylib, .exe)
2533ProcessDepot ()
2634{
2735 echo " > Processing binaries"
2836
2937# rm -r "Protobufs"
3038 mkdir -p " Protobufs"
3139
40+ # Find all files matching the given extension and process each one
3241 while IFS= read -r -d ' ' file
3342 do
43+ # Skip common not game-specific binaries
3444 if [[ " $( basename " $file " " $1 " ) " = " steamclient" ]] || [[ " $( basename " $file " " $1 " ) " = " libcef" ]]
3545 then
3646 continue
3747 fi
3848
3949 echo " > $file "
4050
41- # Dump protobufs
51+ # Extract protobuf definitions from the binary
4252 " $PROTOBUF_DUMPER_PATH " " $file " " Protobufs/" > /dev/null
4353
44- # Dump strings
54+ # Map the file extension to the binary format type for the strings dumper
4555 file_type=" "
4656 case " $1 " in
4757 .dylib)
@@ -61,35 +71,45 @@ ProcessDepot ()
6171 continue
6272 esac
6373
74+ # Derive the output strings filename by replacing the extension with _strings.txt
6475 if [[ " $1 " == " .exe" ]]; then
6576 strings_file=" ${file} _strings.txt"
6677 else
6778 strings_file=" $( echo " $file " | sed -e " s/$( echo " $1 " | sed ' s/\./\\./g' ) $/_strings.txt/g" ) "
6879 fi
6980
81+ # Extract readable strings from the binary, sort and deduplicate them
7082 " $DUMP_STRINGS_PATH " -binary " $file " -target " $file_type " | sort --unique > " $strings_file "
7183 done < <( find . -type f -name " *$1 " -print0)
7284}
7385
86+ # ProcessVPK - Lists contents of VPK directory files and writes them to corresponding .txt files.
7487ProcessVPK ()
7588{
7689 echo " > Processing VPKs"
7790
91+ # Find all VPK directory files and dump their file listings to .txt
7892 while IFS= read -r -d ' ' file
7993 do
8094 echo " > $file "
8195
96+ # Write the VPK's file list to a .txt file with the same name
8297 " $VRF_PATH " --input " $file " --vpk_list > " $( echo " $file " | sed -e ' s/\.vpk$/\.txt/g' ) "
8398 done < <( find . -type f -name " *_dir.vpk" -print0)
8499}
85100
101+ # DeduplicateStringsFrom - Removes duplicate string lines from extracted strings files
102+ # by filtering out lines that appear in the provided dedupe reference files.
103+ # @param $1 - File suffix to match binaries (e.g. .dll, .so)
104+ # @param $@ - One or more reference files whose lines will be subtracted from other strings files
86105DeduplicateStringsFrom ()
87106{
88107 suffix=" $1 "
89108 shift
90109
91110 echo " > Deduplicating strings ($suffix )"
92111
112+ # Resolve all dedupe reference files to absolute paths, warn if missing
93113 dedupe_files=()
94114 for file in " $@ " ; do
95115 resolved=" $( realpath " $file " ) "
@@ -100,6 +120,7 @@ DeduplicateStringsFrom ()
100120 fi
101121 done
102122
123+ # Build grep arguments to filter out lines found in any of the reference files
103124 grep_args=(
104125 --fixed-strings
105126 --line-regexp
@@ -110,60 +131,78 @@ DeduplicateStringsFrom ()
110131 grep_args+=(--file " $dedupe_file " )
111132 done
112133
134+ # Iterate over all binaries matching the suffix and process their strings files
113135 while IFS= read -r -d ' ' file
114136 do
137+ # Derive the corresponding _strings.txt path from the binary path
115138 target_file=" $( realpath " $file " | sed -e " s/$( echo " $suffix " | sed ' s/\./\\./g' ) $/_strings.txt/g" ) "
116139
140+ # Skip if no strings file exists for this binary
117141 if ! [[ -f " $target_file " ]]; then
118142 continue
119143 fi
120144
145+ # Don't deduplicate a file against itself
121146 for dedupe_file in " ${dedupe_files[@]} " ; do
122147 if [[ " $dedupe_file " = " $target_file " ]]; then
123148 continue 2
124149 fi
125150 done
126151
152+ # Remove lines present in reference files and replace the original
127153 grep " ${grep_args[@]} " " $target_file " > " $target_file .tmp" || true
128154 mv " $target_file .tmp" " $target_file "
129155 done < <( find . -type f -name " *$suffix " -print0)
130156}
131157
158+ # ProcessToolAssetInfo - Converts binary tools asset info files (*asset_info.bin) to readable .txt format.
132159ProcessToolAssetInfo ()
133160{
134161 echo " > Processing tools asset info"
135162
163+ # Find all tools asset info binaries and convert them to text
136164 while IFS= read -r -d ' ' file
137165 do
138166 echo " > $file "
139167
168+ # Dump asset info in short format, replacing .bin extension with .txt
140169 " $VRF_PATH " --input " $file " --output " $( echo " $file " | sed -e ' s/\.bin$/\.txt/g' ) " --tools_asset_info_short || echo " S2V failed to dump tools asset info"
141170 done < <( find . -type f -name " *asset_info.bin" -print0)
142171}
143172
173+ # FixUCS2 - Converts UCS-2 encoded .txt files to UTF-8 using the FixEncoding tool.
144174FixUCS2 ()
145175{
146176 echo " > Fixing UCS-2"
147177
178+ # Run FixEncoding on all .txt files in parallel (up to 3 at a time)
148179 find . -type f -name " *.txt" -print0 | xargs --null --max-lines=1 --max-procs=3 " $FIX_ENCODING_PATH "
149180}
150181
182+ # CreateCommit - Stages all changes, creates a git commit with a summary message, and pushes.
183+ # @param $1 - Commit message prefix (e.g. game/app name)
184+ # @param $2 - (optional) Patch notes ID appended as a SteamDB URL in the commit body
151185CreateCommit ()
152186{
187+ # Skip if git operations were disabled via "no-git" argument
153188 if ! [[ $DO_GIT == 1 ]]; then
154189 echo " Not performing git commit"
155190 return
156191 fi
157192
193+ # Stage all changes including untracked files
158194 git add --all
159195
196+ # Build commit message: "<prefix> | <file count> files | <comma-separated change list truncated to 1024 chars>"
160197 message=" $1 | $( git diff --cached --numstat | wc -l) files | $( git diff --cached --name-status | sed ' {:q;N;s/\n/, /g;t q}' | cut -c 1-1024) "
161198
199+ # Append a SteamDB patchnotes link if a patch notes ID was provided
162200 if [[ -n " $2 " ]]; then
163201 bashpls=$' \n\n '
164202 message=" ${message}${bashpls} https://steamdb.info/patchnotes/$2 /"
165203 fi
166204
205+ # Commit (allow failure if there are no changes) and push
167206 git commit --message " $message " || true
168207 git push
169208}
0 commit comments