Class: PAKFile
- Inherits:
-
Object
- Object
- PAKFile
- Defined in:
- lib/pakspy.rb
Overview
Class handles Quake style PAK files
Defined Under Namespace
Classes: FileEntry, FileEntryPAK, FileEntrySystem, Header
Instance Attribute Summary collapse
-
#pak_file ⇒ Object
readonly
Returns the value of attribute pak_file.
Instance Method Summary collapse
-
#extract(name, path) ⇒ Object
Extracts a file
name
from this PAKFile topath
on system. -
#extract_all(dir) ⇒ Object
Extracts all files in PAK to
dir
directory. - #finalize ⇒ Object
-
#initialize(path = nil) ⇒ PAKFile
constructor
Opens an existing PAK file at
path
or if not specified creates a virtual PAK. -
#insert(path, name) ⇒ Object
Inserts a system file at
path
asname
. -
#insert_all(dir) ⇒ Object
Inserts a directory
dir
recursively contents as their names. -
#list ⇒ Object
Lists all files in PAK to an array.
-
#save(path) ⇒ Object
Saves all the changes to
path
.
Constructor Details
#initialize(path = nil) ⇒ PAKFile
Opens an existing PAK file at path
or if not specified creates a virtual PAK
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/pakspy.rb', line 6 def initialize(path = nil) @file_hash = Hash.new @pak_file = nil unless path.nil? @pak_file = File.open path, "rb" header = Header.new @pak_file.read 12 puts "Warning: Might not be a real PAK" unless header.magic == "PACK" file_count = header.size / 64 @pak_file.seek header.offset file_count.times do entry = FileEntryPAK.new self, @pak_file.read(64) file_add entry end end end |
Instance Attribute Details
#pak_file ⇒ Object (readonly)
Returns the value of attribute pak_file.
120 121 122 |
# File 'lib/pakspy.rb', line 120 def pak_file @pak_file end |
Instance Method Details
#extract(name, path) ⇒ Object
Extracts a file name
from this PAKFile to path
on system
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/pakspy.rb', line 31 def extract(name, path) file_entry = file_find(name) raise ArgumentError, "No such file #{name} in this PAK." if file_entry.nil? # Create the necessary directories path_current = "" File.dirname(path).split(/[\/\\]/).each do |dir| path_current += dir Dir.mkdir path_current unless Dir.exists?(path_current) path_current += "/" end # Transfer contents file = File.open path, "wb" file.write file_entry.read file.close end |
#extract_all(dir) ⇒ Object
Extracts all files in PAK to dir
directory
52 53 54 55 56 |
# File 'lib/pakspy.rb', line 52 def extract_all(dir) files_list.each do |file_name| extract file_name, dir + "/" + file_name end end |
#finalize ⇒ Object
25 26 27 |
# File 'lib/pakspy.rb', line 25 def finalize @pak_file.close unless @pak_file.nil? end |
#insert(path, name) ⇒ Object
Inserts a system file at path
as name
60 61 62 |
# File 'lib/pakspy.rb', line 60 def insert(path, name) file_add FileEntrySystem.new self, path, name end |
#insert_all(dir) ⇒ Object
Inserts a directory dir
recursively contents as their names
66 67 68 |
# File 'lib/pakspy.rb', line 66 def insert_all(dir) insert_all_helper(dir, "") end |
#list ⇒ Object
Lists all files in PAK to an array
116 117 118 |
# File 'lib/pakspy.rb', line 116 def list files_list end |
#save(path) ⇒ Object
Saves all the changes to path
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 |
# File 'lib/pakspy.rb', line 72 def save(path) tmp_path = "#{path}.tmp_" file = File.open tmp_path, "wb" file_entries = Array.new # Will finish header later when we know where the file entries will be file.write "PACK" file.seek 12 # Insert all of the files files_list.each do |name| entry = file_find name file_entry = Hash.new file_entry[:name] = entry.name file_entry[:offset] = file.pos file.write entry.read file_entry[:size] = file.pos - file_entry[:offset] file_entries.push file_entry end # Now we know the rest of the info needed for the header file_entry_pos = file.pos file.seek 4 file.write [file_entry_pos, file_entries.length * 64].pack("VV") # And finally add the file entries file.seek file_entry_pos file_entries.each do |file_entry| file.write [file_entry[:name], file_entry[:offset], file_entry[:size]].pack("a56VV") end # close so we can open it again file.close # And finally move it to the correct place File.rename tmp_path, path end |