rbstarbound 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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