rbstarbound 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d05f85c2aa5f0cfb19c28e8d45f9c378da343273
4
- data.tar.gz: 2be0f43338decdda10062f93a5f0018e4db6f33e
3
+ metadata.gz: 598e73b703c140b4ae530217f71e8e18fb6d6b7f
4
+ data.tar.gz: 77208c31fee555eacacff7b493d80fc02fda2f61
5
5
  SHA512:
6
- metadata.gz: 9cc42be3a1e207957bac7e4252572e0b1a764f10c40959b1e0a6275291e3123ed0b3ca6b225fb54f629a6ffd43cb3e0fa4513f08320a053d0d5e85d05550e1dc
7
- data.tar.gz: 181f76077841725a6f27e916b7b7c8f4892bd4b7dfab3ae6cf2080ce54052930cd6294d20e97007d45e3cec60a51ce9fe20ae5e0e0c7b51b6ed2a9d69335a0a6
6
+ metadata.gz: 3732239fd5c8ed9be66cec4f717acbe0dd29d8cc3949c28ee475730beeb58620a2cbf0c84c6b3686ad28822951261e5b2cc6f90c1cbfa655a129ecb137514f51
7
+ data.tar.gz: e8d67c1fbc7d7d03370952cbcf469cb8fb0060ecf39adde40280bd78b232800cf557157cc832eda915dac957fbe5c6b6c2f7996dd71a97d42e6ed961d21544aa
data/lib/rbstarbound.rb CHANGED
@@ -5,6 +5,7 @@ require 'rbstarbound/exceptions'
5
5
  require 'rbstarbound/utils'
6
6
  require 'rbstarbound/sbvj01'
7
7
  require 'rbstarbound/sbon'
8
+ require 'rbstarbound/sbasset6'
8
9
  require 'rbstarbound/exit_codes'
9
10
  require 'rbstarbound/main_command'
10
11
 
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+
5
+ module RBStarbound
6
+ class ExportCommand < Clamp::Command
7
+ option ['-d', '--dir'], 'DIR', 'directory to extract the files to',
8
+ required: true
9
+ option ['-p', '--package'], 'PAK', 'the package file to extract from',
10
+ required: true
11
+ option ['-v', '--verbose'], :flag, 'be verbose', default: false
12
+
13
+ def execute
14
+ start = Time.now.to_i
15
+ extracted = 0
16
+ begin
17
+ File.open(package.to_s, 'rb') do |file|
18
+ RBStarbound::SBAsset6.verbose = true if verbose?
19
+ RBStarbound::SBAsset6.package(file)
20
+ if verbose?
21
+ puts "Extracting #{RBStarbound::SBAsset6.file_count} files..."
22
+ end
23
+ percentage = [RBStarbound::SBAsset6.file_count / 100, 1].max
24
+ RBStarbound::SBAsset6.index.each_key do |path|
25
+ dest_path = dir + path
26
+ dest_dir, = File.split(dest_path)
27
+ FileUtils.mkdir_p(dest_dir) unless Dir.exist?(dest_dir)
28
+ data = RBStarbound::SBAsset6.get(path)
29
+ File.open(dest_path, 'wb') { |f| f.write(data) }
30
+ extracted += 1
31
+ next unless verbose?
32
+ putc '.' if (extracted % percentage).zero?
33
+ end
34
+ end
35
+ return RBStarbound::EX_OK unless verbose?
36
+ puts
37
+ puts "Extracted #{extracted} files in #{Time.now.to_i - start} seconds."
38
+ return RBStarbound::EX_OK
39
+ rescue StandardError => e
40
+ RBStarbound.print_error(e)
41
+ return RBStarbound::EX_ERR
42
+ end
43
+ end
44
+ end
45
+ end
@@ -2,4 +2,5 @@ module RBStarbound
2
2
  class NotImplementedError < StandardError; end
3
3
  class SBVJ01Error < StandardError; end
4
4
  class ValueError < StandardError; end
5
+ class SBAsset6Error < StandardError; end
5
6
  end
@@ -4,6 +4,7 @@ require 'clamp'
4
4
  require 'rbstarbound/exit_codes'
5
5
  require 'rbstarbound/commands/dump'
6
6
  require 'rbstarbound/commands/serialize'
7
+ require 'rbstarbound/commands/export'
7
8
 
8
9
  module RBStarbound
9
10
  class MainCommand < Clamp::Command
@@ -18,5 +19,8 @@ module RBStarbound
18
19
  subcommand 'serialize',
19
20
  'serialize a player save file form a formatted file',
20
21
  RBStarbound::SerializeCommand
22
+ subcommand 'export',
23
+ 'extract all the files from a .pak file',
24
+ RBStarbound::ExportCommand
21
25
  end
22
26
  end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBStarbound
4
+ module SBAsset6
5
+ @verbose = false
6
+
7
+ def self.package(io)
8
+ @package = io
9
+ raise SBAsset6Error, 'No package file given' if @package.nil?
10
+ read_header
11
+ read_index
12
+ end
13
+
14
+ def self.get(path)
15
+ raise SBAsset6Error, 'No package file given' if @package.nil?
16
+ offset, length = @index[path]
17
+ rewind_to(offset)
18
+ @package.read(length)
19
+ end
20
+
21
+ def self.read_header
22
+ rewind_to(0)
23
+ header, @metadata_offset = @package.read(16).unpack('A8Q>')
24
+ raise SBAsset6Error, 'Invalid header' unless header == 'SBAsset6'
25
+ read_metadata
26
+ end
27
+
28
+ def self.read_index
29
+ puts 'Loading index...' if @verbose
30
+ rewind_to(@index_offset)
31
+ @index = {}
32
+ @file_count.times do
33
+ path = RBStarbound::SBON.read_string(@package)
34
+ offset, length = @package.read(16).unpack('Q>Q>')
35
+ @index[path] = [offset, length]
36
+ end
37
+ puts 'Index loaded.' if @verbose
38
+ end
39
+
40
+ def self.read_metadata
41
+ rewind_to(@metadata_offset)
42
+ raise SBAsset6Error, 'Invalid index data' unless meta_header == 'INDEX'
43
+ @metadata = RBStarbound::SBON.read_map(@package)
44
+ @file_count = RBStarbound::SBON.read_varint(@package)
45
+ @index_offset = @package.pos
46
+ end
47
+
48
+ def self.rewind_to(pos)
49
+ @package.seek(pos, IO::SEEK_SET)
50
+ end
51
+
52
+ def self.meta_header
53
+ @package.read(5)
54
+ end
55
+
56
+ class << self
57
+ attr_accessor :verbose
58
+ attr_reader :metadata, :file_count, :metadata_offset, :index_offset,
59
+ :index
60
+ private :rewind_to, :read_header, :read_index, :read_metadata
61
+ end
62
+ end
63
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RBStarbound
4
- VERSION = '0.2.0'
4
+ VERSION = '0.3.0'
5
5
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class SBAsset6Test < Minitest::Test
6
+ def test_it_requires_package_file
7
+ assert_raises RBStarbound::SBAsset6Error do
8
+ ::RBStarbound::SBAsset6.package(nil)
9
+ ::RBStarbound::SBAsset6.get('path')
10
+ end
11
+ end
12
+
13
+ def test_it_raises_header_error
14
+ file = Tempfile.new('sbasset6_header_test_temp')
15
+ begin
16
+ file.write('NotAHeader')
17
+ error = assert_raises RBStarbound::SBAsset6Error do
18
+ ::RBStarbound::SBAsset6.package(file)
19
+ end
20
+ assert_match(/Invalid header/, error.message)
21
+ ensure
22
+ file.close
23
+ file.unlink
24
+ end
25
+ end
26
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbstarbound
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oleh Fedorenko
@@ -79,11 +79,13 @@ files:
79
79
  - bin/rbstarbound
80
80
  - lib/rbstarbound.rb
81
81
  - lib/rbstarbound/commands/dump.rb
82
+ - lib/rbstarbound/commands/export.rb
82
83
  - lib/rbstarbound/commands/serialize.rb
83
84
  - lib/rbstarbound/exceptions.rb
84
85
  - lib/rbstarbound/exit_codes.rb
85
86
  - lib/rbstarbound/main_command.rb
86
87
  - lib/rbstarbound/player.rb
88
+ - lib/rbstarbound/sbasset6.rb
87
89
  - lib/rbstarbound/sbon.rb
88
90
  - lib/rbstarbound/sbvj01.rb
89
91
  - lib/rbstarbound/utils.rb
@@ -94,6 +96,7 @@ files:
94
96
  - test/data/1.3.3/test.yaml
95
97
  - test/player_test.rb
96
98
  - test/rbstarbound_test.rb
99
+ - test/sbasset6_test.rb
97
100
  - test/sbvj01_test.rb
98
101
  - test/test_helper.rb
99
102
  homepage: https://github.com/JetPirate/rb-starbound
@@ -128,4 +131,5 @@ test_files:
128
131
  - test/rbstarbound_test.rb
129
132
  - test/commands/dump_test.rb
130
133
  - test/commands/serialize_test.rb
134
+ - test/sbasset6_test.rb
131
135
  - test/test_helper.rb