dsp_blueprint_parser 0.1.1 → 0.1.2

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.
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DspBlueprintParser
4
+ # Data Sections
5
+ #
6
+ # Given a raw DSP Blueprint sting this returns readability
7
+ # usable data on the string
8
+ class DataSections
9
+ # @param str_blueprint [String]
10
+ def initialize(str_blueprint)
11
+ @str_blueprint = str_blueprint
12
+ @first_quote_loc = @str_blueprint.index('"')
13
+ @second_quote_loc = @str_blueprint[(@first_quote_loc + 1)..].index('"') + @first_quote_loc
14
+ end
15
+
16
+ # @return [Array<String>]
17
+ def header_segments
18
+ @header_segments ||= @str_blueprint[10..@first_quote_loc - 1].split(',')
19
+ end
20
+
21
+ def hashed_string
22
+ @str_blueprint[..@second_quote_loc]
23
+ end
24
+
25
+ def hash
26
+ @str_blueprint[@second_quote_loc + 2..-1]
27
+ end
28
+
29
+ # @return [Array<Integer>] array of bytes, 0..255
30
+ def decompressed_body
31
+ @decompressed_body ||=
32
+ @str_blueprint[@first_quote_loc + 1..@second_quote_loc]
33
+ .then(&Base64.method(:decode64))
34
+ .then(&StringIO.method(:new))
35
+ .then(&Zlib::GzipReader.method(:new))
36
+ .each_byte
37
+ .to_a
38
+ end
39
+ end
40
+ end
@@ -1,23 +1,23 @@
1
- # frozen_string_literal: true
2
-
3
- module DspBlueprintParser
4
- module IconLayout
5
- NONE = 0
6
- NO_ICON = 1
7
- ONE_ICON = 10
8
- ONE_ICON_SMALL = 11
9
- TWO_ICON_46 = 20
10
- TWO_ICON_53 = 21
11
- TWO_ICON_59 = 22
12
- TWO_ICON_57 = 23
13
- TWO_ICON_51 = 24
14
- THREE_ICON_813 = 30
15
- THREE_ICON_279 = 31
16
- THREE_ICON_573 = 32
17
- THREE_ICON_591 = 33
18
- FOUR_ICON_7913 = 40
19
- FOUR_ICON_8462 = 41
20
- FIVE_ICON_57913 = 50
21
- FIVE_ICON_PENTA = 51
22
- end
23
- end
1
+ # frozen_string_literal: true
2
+
3
+ module DspBlueprintParser
4
+ module IconLayout
5
+ NONE = 0
6
+ NO_ICON = 1
7
+ ONE_ICON = 10
8
+ ONE_ICON_SMALL = 11
9
+ TWO_ICON_46 = 20
10
+ TWO_ICON_53 = 21
11
+ TWO_ICON_59 = 22
12
+ TWO_ICON_57 = 23
13
+ TWO_ICON_51 = 24
14
+ THREE_ICON_813 = 30
15
+ THREE_ICON_279 = 31
16
+ THREE_ICON_573 = 32
17
+ THREE_ICON_591 = 33
18
+ FOUR_ICON_7913 = 40
19
+ FOUR_ICON_8462 = 41
20
+ FIVE_ICON_57913 = 50
21
+ FIVE_ICON_PENTA = 51
22
+ end
23
+ end
@@ -1,144 +1,119 @@
1
- # frozen_string_literal: true
2
-
3
- module DspBlueprintParser
4
- # class to orchestrate parsing
5
- class Parser
6
- SECONDS_AT_EPOC = 62_135_596_800
7
-
8
- # @param [String] str_blueprint
9
- def initialize(str_blueprint)
10
- @str_blueprint = str_blueprint
11
- end
12
-
13
- # @return [BlueprintData]
14
- def parse
15
- blueprint = BlueprintData.new
16
- reader = get_reader(@str_blueprint)
17
-
18
- parse_metadata(blueprint, @str_blueprint, reader)
19
- parse_areas(blueprint, reader)
20
- parse_buildings(blueprint, reader)
21
-
22
- blueprint
23
- end
24
-
25
- private
26
-
27
- # @param ticks [Integer]
28
- # @return [Time]
29
- def ticks_to_epoch(ticks)
30
- # 10mil ticks per second
31
- seconds = ticks / 10_000_000
32
-
33
- Time.at(seconds - SECONDS_AT_EPOC)
34
- end
35
-
36
- # @param str_blueprint [String]
37
- # @return [Array<String>]
38
- def get_header_segments(str_blueprint)
39
- header_end = str_blueprint.index('"')
40
- header = str_blueprint[10..header_end - 1]
41
- header.split(',')
42
- end
43
-
44
- # @param str_blueprint [String]
45
- # @return [BinaryReader]
46
- def get_reader(str_blueprint)
47
- header_end = str_blueprint.index('"')
48
- blueprint_end = str_blueprint[header_end + 1..].index('"') + header_end
49
- blueprint_compressed = str_blueprint[header_end + 1..blueprint_end]
50
-
51
- gz = Zlib::GzipReader.new(StringIO.new(Base64.decode64(blueprint_compressed)))
52
- blueprint_decompressed = gz.each_byte.to_a
53
-
54
- BinaryReader.new(blueprint_decompressed)
55
- end
56
-
57
- # @param [BlueprintData] blueprint
58
- # @param [BinaryReader] reader
59
- def parse_areas(blueprint, reader)
60
- reader.read_i8.times do
61
- area = Area.new
62
- area.index = reader.read_i8
63
- area.parent_index = reader.read_i8
64
- area.tropic_anchor = reader.read_i16
65
- area.area_segments = reader.read_i16
66
- area.anchor_local_offset_x = reader.read_i16
67
- area.anchor_local_offset_y = reader.read_i16
68
- area.width = reader.read_i16
69
- area.height = reader.read_i16
70
-
71
- blueprint.areas << area
72
- end
73
- end
74
-
75
- # @param [BlueprintData] blueprint
76
- # @param [BinaryReader] reader
77
- def parse_buildings(blueprint, reader)
78
- reader.read_i32.times do
79
- building = Building.new
80
- building.index = reader.read_i32
81
- building.area_index = reader.read_i8
82
- building.local_offset_x = reader.read_single
83
- building.local_offset_y = reader.read_single
84
- building.local_offset_z = reader.read_single
85
- building.local_offset_x2 = reader.read_single
86
- building.local_offset_y2 = reader.read_single
87
- building.local_offset_z2 = reader.read_single
88
- building.yaw = reader.read_single
89
- building.yaw2 = reader.read_single
90
- building.item_id = reader.read_i16
91
- building.model_index = reader.read_i16
92
- building.temp_output_obj_idx = reader.read_i32
93
- building.temp_input_obj_idx = reader.read_i32
94
- building.output_to_slot = reader.read_i8
95
- building.input_from_slot = reader.read_i8
96
- building.output_from_slot = reader.read_i8
97
- building.input_to_slot = reader.read_i8
98
- building.output_offset = reader.read_i8
99
- building.input_offset = reader.read_i8
100
- building.recipe_id = reader.read_i16
101
- building.filter_fd = reader.read_i16
102
-
103
- reader.read_i16.times do
104
- building.parameters << reader.read_i32
105
- end
106
-
107
- blueprint.buildings << building
108
- end
109
- end
110
-
111
- # @param [BlueprintData] blueprint
112
- # @param [String] str_blueprint
113
- # @param [BinaryReader] reader
114
- def parse_metadata(blueprint, str_blueprint, reader)
115
- header_segments = get_header_segments(str_blueprint)
116
-
117
- blueprint.icon_layout = header_segments[1].to_i
118
- blueprint.icon0 = header_segments[2].to_i
119
- blueprint.icon1 = header_segments[3].to_i
120
- blueprint.icon2 = header_segments[4].to_i
121
- blueprint.icon3 = header_segments[5].to_i
122
- blueprint.icon4 = header_segments[6].to_i
123
-
124
- blueprint.time = ticks_to_epoch(header_segments[8].to_i)
125
- blueprint.game_version = header_segments[9]
126
-
127
- if header_segments[10]
128
- blueprint.short_description = CGI.unescape(header_segments[10])
129
- end
130
-
131
- if header_segments[11]
132
- blueprint.description = CGI.unescape(header_segments[11])
133
- end
134
-
135
- blueprint.version = reader.read_i32
136
- blueprint.cursor_offset_x = reader.read_i32
137
- blueprint.cursor_offset_y = reader.read_i32
138
- blueprint.cursor_target_area = reader.read_i32
139
- blueprint.drag_box_size_x = reader.read_i32
140
- blueprint.drag_box_size_y = reader.read_i32
141
- blueprint.primary_area_idx = reader.read_i32
142
- end
143
- end
144
- end
1
+ # frozen_string_literal: true
2
+
3
+ module DspBlueprintParser
4
+ # class to orchestrate parsing
5
+ class Parser
6
+ SECONDS_AT_EPOC = 62_135_596_800
7
+
8
+ # @param [String] str_blueprint
9
+ def initialize(str_blueprint)
10
+ @data_sections = DataSections.new(str_blueprint)
11
+ end
12
+
13
+ # @return [BlueprintData]
14
+ def blueprint
15
+ @blueprint ||= BlueprintData.new.tap do |blueprint|
16
+ parse_metadata(blueprint)
17
+ parse_areas(blueprint)
18
+ parse_buildings(blueprint)
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ # @return [Array<String>]
25
+ def header_segments
26
+ @header_segments ||= @data_sections.header_segments
27
+ end
28
+
29
+ # @return [BinaryReader]
30
+ def reader
31
+ @reader ||= BinaryReader.new(@data_sections.decompressed_body)
32
+ end
33
+
34
+ # @param ticks [Integer]
35
+ # @return [Time]
36
+ def ticks_to_epoch(ticks)
37
+ # 10mil ticks per second
38
+ seconds = ticks / 10_000_000
39
+
40
+ Time.at(seconds - SECONDS_AT_EPOC)
41
+ end
42
+
43
+ # @param [BlueprintData] blueprint
44
+ def parse_areas(blueprint)
45
+ reader.read_i8.times do
46
+ area = Area.new
47
+ area.index = reader.read_i8
48
+ area.parent_index = reader.read_i8
49
+ area.tropic_anchor = reader.read_i16
50
+ area.area_segments = reader.read_i16
51
+ area.anchor_local_offset_x = reader.read_i16
52
+ area.anchor_local_offset_y = reader.read_i16
53
+ area.width = reader.read_i16
54
+ area.height = reader.read_i16
55
+
56
+ blueprint.areas << area
57
+ end
58
+ end
59
+
60
+ # @param [BlueprintData] blueprint
61
+ def parse_buildings(blueprint)
62
+ reader.read_i32.times do
63
+ building = Building.new
64
+ building.index = reader.read_i32
65
+ building.area_index = reader.read_i8
66
+ building.local_offset_x = reader.read_single
67
+ building.local_offset_y = reader.read_single
68
+ building.local_offset_z = reader.read_single
69
+ building.local_offset_x2 = reader.read_single
70
+ building.local_offset_y2 = reader.read_single
71
+ building.local_offset_z2 = reader.read_single
72
+ building.yaw = reader.read_single
73
+ building.yaw2 = reader.read_single
74
+ building.item_id = reader.read_i16
75
+ building.model_index = reader.read_i16
76
+ building.temp_output_obj_idx = reader.read_i32
77
+ building.temp_input_obj_idx = reader.read_i32
78
+ building.output_to_slot = reader.read_i8
79
+ building.input_from_slot = reader.read_i8
80
+ building.output_from_slot = reader.read_i8
81
+ building.input_to_slot = reader.read_i8
82
+ building.output_offset = reader.read_i8
83
+ building.input_offset = reader.read_i8
84
+ building.recipe_id = reader.read_i16
85
+ building.filter_fd = reader.read_i16
86
+
87
+ reader.read_i16.times do
88
+ building.parameters << reader.read_i32
89
+ end
90
+
91
+ blueprint.buildings << building
92
+ end
93
+ end
94
+
95
+ # @param [BlueprintData] blueprint
96
+ def parse_metadata(blueprint)
97
+ blueprint.icon_layout = header_segments[1].to_i
98
+ blueprint.icon0 = header_segments[2].to_i
99
+ blueprint.icon1 = header_segments[3].to_i
100
+ blueprint.icon2 = header_segments[4].to_i
101
+ blueprint.icon3 = header_segments[5].to_i
102
+ blueprint.icon4 = header_segments[6].to_i
103
+
104
+ blueprint.time = ticks_to_epoch(header_segments[8].to_i)
105
+ blueprint.game_version = header_segments[9]
106
+
107
+ blueprint.short_description = CGI.unescape(header_segments[10]) if header_segments[10]
108
+ blueprint.description = CGI.unescape(header_segments[11]) if header_segments[11]
109
+
110
+ blueprint.version = reader.read_i32
111
+ blueprint.cursor_offset_x = reader.read_i32
112
+ blueprint.cursor_offset_y = reader.read_i32
113
+ blueprint.cursor_target_area = reader.read_i32
114
+ blueprint.drag_box_size_x = reader.read_i32
115
+ blueprint.drag_box_size_y = reader.read_i32
116
+ blueprint.primary_area_idx = reader.read_i32
117
+ end
118
+ end
119
+ end
@@ -1,5 +1,5 @@
1
- # frozen_string_literal: true
2
-
3
- module DspBlueprintParser
4
- VERSION = '0.1.1'
5
- end
1
+ # frozen_string_literal: true
2
+
3
+ module DspBlueprintParser
4
+ VERSION = '0.1.2'
5
+ end
data/lib/md5f.so ADDED
Binary file
metadata CHANGED
@@ -1,20 +1,21 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dsp_blueprint_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lucas Falk
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-08-02 00:00:00.000000000 Z
11
+ date: 2021-08-07 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Parse Dyson Sphere Program blueprint string
14
14
  email:
15
15
  - LRFalk01@gmail.com
16
16
  executables: []
17
- extensions: []
17
+ extensions:
18
+ - ext/md5f/extconf.rb
18
19
  extra_rdoc_files: []
19
20
  files:
20
21
  - ".gitignore"
@@ -29,21 +30,25 @@ files:
29
30
  - bin/console
30
31
  - bin/setup
31
32
  - dsp_blueprint_parser.gemspec
33
+ - ext/md5f/extconf.rb
34
+ - ext/md5f/md5f.c
32
35
  - lib/dsp_blueprint_parser.rb
33
36
  - lib/dsp_blueprint_parser/area.rb
34
37
  - lib/dsp_blueprint_parser/binary_reader.rb
35
38
  - lib/dsp_blueprint_parser/blueprint_data.rb
36
39
  - lib/dsp_blueprint_parser/building.rb
40
+ - lib/dsp_blueprint_parser/data_sections.rb
37
41
  - lib/dsp_blueprint_parser/icon_layout.rb
38
42
  - lib/dsp_blueprint_parser/parser.rb
39
43
  - lib/dsp_blueprint_parser/version.rb
44
+ - lib/md5f.so
40
45
  homepage: https://github.com/LRFalk01/DSP-Blueprint-Parser
41
46
  licenses:
42
47
  - MIT
43
48
  metadata:
44
49
  homepage_uri: https://github.com/LRFalk01/DSP-Blueprint-Parser
45
50
  source_code_uri: https://github.com/LRFalk01/DSP-Blueprint-Parser
46
- post_install_message:
51
+ post_install_message:
47
52
  rdoc_options: []
48
53
  require_paths:
49
54
  - lib
@@ -58,8 +63,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
58
63
  - !ruby/object:Gem::Version
59
64
  version: '0'
60
65
  requirements: []
61
- rubygems_version: 3.2.22
62
- signing_key:
66
+ rubygems_version: 3.1.2
67
+ signing_key:
63
68
  specification_version: 4
64
69
  summary: Parse Dyson Sphere Program blueprint string
65
70
  test_files: []