vpk

VPK(“Valve Pak”)は、Source Engine(Valve のゲームエンジン)で使われるアーカイブ形式です(Valve Developer Wiki の解説)。この vpk は、その VPK ファイルを Ruby で読み書きするライブラリで、VPK ファイルの展開と、ディレクトリを VPK にまとめる圧縮の両方ができます。

gem として公開していて、コマンドラインツールも同梱しています。

gem install vpk
require 'vpk'

# VPK ファイルを展開する
VPK::VPKFile.new("./path_to.vpk").extract_to("./")

# ディレクトリを VPK にまとめる
VPK::VPKFile.archive("./path_to_dir").write_to("./archive.vpk")

コマンドラインからはこう使います。-c はディレクトリと同名の .vpk を作り、-x はカレントディレクトリに展開します。

vpk -c some_dir       # some_dir を some_dir.vpk に圧縮
vpk -x some_file.vpk  # カレントディレクトリに展開

内部設計

実装しているのは VPK フォーマットのバージョン 1 です。ファイルは「12 バイトのヘッダ」「ファイル一覧を持つディレクトリ部」「中身を連結したデータ部」の三層でできています。

ヘッダ(12 バイト)のバイトレイアウト

ディレクトリ部の並び(例):
"vtf"                                ← 第 1 段: 拡張子
  "materials/vgui"                   ← 第 2 段: パス
    "logo" + エントリ情報(18 バイト)  ← 第 3 段: ファイル名
    ""                               ← ファイル名の終端
  ""                                 ← パスの終端
""                                   ← 拡張子の終端 = ディレクトリ部おわり

ディレクトリエントリ(18 バイト)のバイトレイアウト

読み書きの流れはこうなっています。

vpk の展開・圧縮処理の流れ図