mikunyan 3.9.8 → 3.9.10
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 +4 -4
- data/.rubocop.yml +42 -0
- data/README.md +2 -1
- data/Rakefile +2 -2
- data/exe/mikunyan-image +38 -18
- data/ext/decoders/crunch/extconf.rb +3 -0
- data/ext/decoders/native/extconf.rb +3 -0
- data/lib/mikunyan/asset.rb +27 -11
- data/lib/mikunyan/asset_bundle.rb +7 -4
- data/lib/mikunyan/binary_reader.rb +2 -0
- data/lib/mikunyan/constants.rb +85 -85
- data/lib/mikunyan/decoders/image_decoder.rb +17 -7
- data/lib/mikunyan/object_value.rb +3 -3
- data/lib/mikunyan/type_tree.rb +3 -1
- data/lib/mikunyan/typetrees/108/90536dd8f3f4fe3df5964930a9482336.json +1 -0
- data/lib/mikunyan/typetrees/137/2697e6f3893bf152ccfa6766c4c7f505.json +1 -0
- data/lib/mikunyan/typetrees/157/6a51273486ff0a7ab9f6df13917bc047.json +1 -0
- data/lib/mikunyan/typetrees/196/306f0c2739dc8ad54fb4a1a44d1a3880.json +1 -0
- data/lib/mikunyan/typetrees/198/4b5dc9892b939558afad44bc1c94cb95.json +1 -0
- data/lib/mikunyan/typetrees/199/5fa34208d6cf04d6ae190f096d624677.json +1 -0
- data/lib/mikunyan/typetrees/21/63d861fd9f999c93d61fe5659162061d.json +1 -0
- data/lib/mikunyan/typetrees/212/d1820f56f61b6f673e2f5301c4686d39.json +1 -0
- data/lib/mikunyan/typetrees/23/f19f7e20c325589c346554ef7d1cadc9.json +1 -0
- data/lib/mikunyan/typetrees/241/06c982971191fe245e5ebf10100d830b.json +1 -0
- data/lib/mikunyan/typetrees/28/0d08414cfd5bdb0d22792011bda9ab26.json +1 -0
- data/lib/mikunyan/typetrees/320/4edb00d2a9c65f6f25f5cdc31bb86380.json +1 -0
- data/lib/mikunyan/typetrees/328/2c5307574bfe212cbac3047511700fc5.json +1 -0
- data/lib/mikunyan/typetrees/328/f95fb25bc9075d2acd7b879adca49eda.json +1 -0
- data/lib/mikunyan/typetrees/329/093e4500a0a67d1ed84eb0116520fa2d.json +1 -0
- data/lib/mikunyan/typetrees/329/a7209c2a706f5ce5d5b6d405d08194d6.json +1 -0
- data/lib/mikunyan/typetrees/43/b5516dd9b9d6b7d5643b75df1847c5c9.json +1 -0
- data/lib/mikunyan/typetrees/48/a30e3dcf6c6d25153d6f64e5e41caf4e.json +1 -0
- data/lib/mikunyan/typetrees/50/6e8b670a26a77e98186711bb06946b54.json +1 -0
- data/lib/mikunyan/typetrees/61/30520d6e00d721084910face9f4161f1.json +1 -0
- data/lib/mikunyan/typetrees/64/80051ff78d79f99ebe47afb72cc66120.json +1 -0
- data/lib/mikunyan/typetrees/687078895/cae79c57c58bb3a331c1a3a78ff9cfef.json +1 -0
- data/lib/mikunyan/typetrees/83/57a6370a001d5449abd37c2184ec5138.json +1 -0
- data/lib/mikunyan/typetrees/84/78e42736c01cb0f007375d925e0eb8b0.json +1 -0
- data/lib/mikunyan/typetrees/850595691/5e9bfc993e74efde8bb9081817c5926a.json +1 -0
- data/lib/mikunyan/typetrees/89/3e37f1e0e678133aeabb230a8492e213.json +1 -0
- data/lib/mikunyan/typetrees/90/06fc117ca6d965140ccc18ca840cc1a1.json +1 -0
- data/lib/mikunyan/typetrees/96/32fa2c2b9d9e3f4a716af411fe635d29.json +1 -0
- data/lib/mikunyan/version.rb +1 -1
- data/mikunyan.gemspec +4 -4
- metadata +37 -22
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 307573d81cdf56b190cc886ee41d6f529a163dedd5821d8d0b752f13757f6bc1
|
|
4
|
+
data.tar.gz: 37e833380ead2464767773f06b31a72e4f53ea956d69d0b300a13e06f2b93b47
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 87d9749eebdedb468b7ef6d370775b7769a12b7930b4d3feddea462ef3a2a6611ad9417f5d11cb70e7fc5c2ef8174a967a6a3d480d6171685a4f33fc652ff63f
|
|
7
|
+
data.tar.gz: 9044ea58c2270b85c067ea3b80f9f737ae5d156c71284d7049125f511b389c52e0c10b67917add739fc6fce721a56cc790a5791988e64e1bf70da3e313ac684f
|
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
AllCops:
|
|
2
|
+
TargetRubyVersion: 2.6
|
|
3
|
+
|
|
4
|
+
Metrics/AbcSize:
|
|
5
|
+
Max: 170
|
|
6
|
+
|
|
7
|
+
Metrics/BlockLength:
|
|
8
|
+
Max: 250
|
|
9
|
+
|
|
10
|
+
Metrics/ClassLength:
|
|
11
|
+
Max: 1000
|
|
12
|
+
|
|
13
|
+
Metrics/CyclomaticComplexity:
|
|
14
|
+
Max: 70
|
|
15
|
+
|
|
16
|
+
Metrics/MethodLength:
|
|
17
|
+
Max: 100
|
|
18
|
+
|
|
19
|
+
Metrics/ModuleLength:
|
|
20
|
+
Max: 1000
|
|
21
|
+
|
|
22
|
+
Metrics/ParameterLists:
|
|
23
|
+
Max: 50
|
|
24
|
+
|
|
25
|
+
Metrics/PerceivedComplexity:
|
|
26
|
+
Max: 80
|
|
27
|
+
|
|
28
|
+
Layout/SpaceInsideBlockBraces:
|
|
29
|
+
EnforcedStyle: no_space
|
|
30
|
+
SpaceBeforeBlockParameters: false
|
|
31
|
+
|
|
32
|
+
Style/Documentation:
|
|
33
|
+
Enabled: false
|
|
34
|
+
|
|
35
|
+
Style/NumericPredicate:
|
|
36
|
+
EnforcedStyle: comparison
|
|
37
|
+
|
|
38
|
+
Style/MultilineBlockChain:
|
|
39
|
+
Enabled: false
|
|
40
|
+
|
|
41
|
+
Style/SpecialGlobalVars:
|
|
42
|
+
EnforcedStyle: use_perl_names
|
data/README.md
CHANGED
|
@@ -244,7 +244,8 @@ Available options:
|
|
|
244
244
|
|
|
245
245
|
- [json](https://rubygems.org/gems/json)
|
|
246
246
|
- [extlz4](https://rubygems.org/gems/extlz4)
|
|
247
|
-
- [
|
|
247
|
+
- [extlzma2](https://rubygems.org/gems/extlzma2)
|
|
248
|
+
- extlzma2 requires liblzma. You may need a `--with-liblzma-dir=` argument to install extlzma2.
|
|
248
249
|
- [bin_utils](https://rubygems.org/gems/bin_utils)
|
|
249
250
|
- [chunky_png](https://rubygems.org/gems/chunky_png)
|
|
250
251
|
|
data/Rakefile
CHANGED
|
@@ -13,10 +13,10 @@ ext_dirs = %w[decoders/native decoders/crunch]
|
|
|
13
13
|
|
|
14
14
|
ext_dirs.each do |dir|
|
|
15
15
|
Rake::ExtensionTask.new(dir) do |ext|
|
|
16
|
-
ext.lib_dir =
|
|
16
|
+
ext.lib_dir = "lib/mikunyan/#{File.dirname(dir)}"
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
task compile: ext_dirs.map{|e| "compile:#{e}".to_sym}
|
|
20
|
+
task compile: ext_dirs.map {|e| "compile:#{e}".to_sym}
|
|
21
21
|
|
|
22
22
|
task default: %i[clobber compile spec]
|
data/exe/mikunyan-image
CHANGED
|
@@ -44,51 +44,71 @@ unless File.file?(arg)
|
|
|
44
44
|
exit(1)
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
if opts[:as_asset]
|
|
48
|
+
assets = [Mikunyan::Asset.file(arg)]
|
|
49
|
+
else
|
|
50
|
+
bundle = Mikunyan::AssetBundle.file(arg)
|
|
51
|
+
assets = bundle.assets
|
|
52
|
+
end
|
|
48
53
|
|
|
49
54
|
outdir = opts[:outputdir] || File.basename(arg, '.*')
|
|
50
55
|
FileUtils.mkpath(outdir)
|
|
51
56
|
|
|
52
|
-
|
|
53
|
-
|
|
57
|
+
if opts[:sprite]
|
|
58
|
+
textures = {}
|
|
59
|
+
textures_meta = {}
|
|
60
|
+
assets.each do |asset|
|
|
54
61
|
json = {}
|
|
55
|
-
textures = {}
|
|
56
62
|
|
|
57
63
|
asset.each_object do |obj|
|
|
58
64
|
next unless obj.type == 'Sprite'
|
|
65
|
+
next unless obj.klass
|
|
59
66
|
obj = obj.parse
|
|
60
|
-
next unless obj
|
|
61
|
-
|
|
62
|
-
|
|
67
|
+
next unless obj&.m_RD&.texture
|
|
68
|
+
file_id = obj.m_RD.texture.m_FileID.value
|
|
69
|
+
texture_asset = file_id == 0 ? asset : bundle && bundle[asset.references[file_id - 1].file_path]
|
|
70
|
+
texture_id = obj.m_RD.texture.m_PathID.value
|
|
71
|
+
next unless texture_asset && texture_id
|
|
63
72
|
|
|
64
|
-
unless textures.
|
|
65
|
-
texture_obj =
|
|
73
|
+
unless textures.dig(texture_asset, texture_id)
|
|
74
|
+
texture_obj = texture_asset.parse_object(texture_id)
|
|
66
75
|
if texture_obj.is_a?(Mikunyan::CustomTypes::Texture2D)
|
|
67
|
-
textures[
|
|
68
|
-
|
|
76
|
+
textures[texture_asset] ||= {}
|
|
77
|
+
textures[texture_asset][texture_id] = texture_obj.generate_png
|
|
78
|
+
textures_meta[texture_asset] ||= {}
|
|
79
|
+
textures_meta[texture_asset][texture_id] = {
|
|
69
80
|
name: texture_obj.m_Name&.value, width: texture_obj.m_Width&.value, height: texture_obj.m_Height&.value,
|
|
70
|
-
format: texture_obj.m_TextureFormat&.value,
|
|
81
|
+
format: texture_obj.m_TextureFormat&.value, asset: texture_asset.name, path_id: texture_id
|
|
71
82
|
}
|
|
72
83
|
end
|
|
73
84
|
end
|
|
74
85
|
|
|
86
|
+
next unless textures_meta[texture_asset][texture_id]
|
|
87
|
+
|
|
88
|
+
unless json.key?([file_id, texture_id])
|
|
89
|
+
json[[file_id, texture_id]] = textures_meta[texture_asset][texture_id].dup
|
|
90
|
+
json[[file_id, texture_id]][:sprites] = []
|
|
91
|
+
end
|
|
92
|
+
|
|
75
93
|
x = obj.m_Rect&.x&.value
|
|
76
94
|
y = obj.m_Rect&.y&.value
|
|
77
95
|
width = obj.m_Rect&.width&.value
|
|
78
96
|
height = obj.m_Rect&.height&.value
|
|
79
97
|
|
|
80
|
-
json[texture_id][:sprites] << { name: obj.object_name, x: x, y: y, width: width, height: height, path_id: obj.path_id }
|
|
98
|
+
json[[file_id, texture_id]][:sprites] << { name: obj.object_name, x: x, y: y, width: width, height: height, path_id: obj.path_id }
|
|
81
99
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
).save("#{outdir}/#{obj.object_name}.png")
|
|
100
|
+
texture = textures[texture_asset][texture_id]
|
|
101
|
+
next unless texture && x && y && width && height
|
|
102
|
+
texture.crop(x.round, (texture.height - height - y).round, width.round, height.round).save("#{outdir}/#{obj.object_name}.png")
|
|
86
103
|
end
|
|
87
104
|
puts opts[:pretty] ? JSON.pretty_generate(json.values) : JSON.generate(json.values)
|
|
88
|
-
|
|
105
|
+
end
|
|
106
|
+
else
|
|
107
|
+
assets.each do |asset|
|
|
89
108
|
json = []
|
|
90
109
|
asset.each_object do |obj|
|
|
91
110
|
next unless obj.type == 'Texture2D'
|
|
111
|
+
next unless obj.klass
|
|
92
112
|
obj = obj.parse
|
|
93
113
|
next unless obj.is_a?(Mikunyan::CustomTypes::Texture2D)
|
|
94
114
|
json << {
|
data/lib/mikunyan/asset.rb
CHANGED
|
@@ -56,7 +56,7 @@ module Mikunyan
|
|
|
56
56
|
# Returns object type name string
|
|
57
57
|
# @return [String,nil] type name
|
|
58
58
|
def type
|
|
59
|
-
klass&.type_tree&.tree&.type || Mikunyan::Constants::CLASS_ID2NAME[class_id]
|
|
59
|
+
klass&.type_tree&.tree&.type || Mikunyan::Constants::CLASS_ID2NAME[class_id || klass&.class_id]
|
|
60
60
|
end
|
|
61
61
|
end
|
|
62
62
|
|
|
@@ -103,6 +103,12 @@ module Mikunyan
|
|
|
103
103
|
@objects.each(&block)
|
|
104
104
|
end
|
|
105
105
|
|
|
106
|
+
# Returns object with specified path ID
|
|
107
|
+
# @return [ObjectEntry,nil]
|
|
108
|
+
def path_id(id)
|
|
109
|
+
@path_id_table[id]
|
|
110
|
+
end
|
|
111
|
+
|
|
106
112
|
# Returns list of all path IDs
|
|
107
113
|
# @return [Array<Integer>] list of all path IDs
|
|
108
114
|
def path_ids
|
|
@@ -114,8 +120,10 @@ module Mikunyan
|
|
|
114
120
|
def containers
|
|
115
121
|
obj = @path_id_table[1]
|
|
116
122
|
return nil unless obj.klass&.type_tree&.tree&.type == 'AssetBundle'
|
|
123
|
+
|
|
117
124
|
parse_object(obj).m_Container.value.map do |e|
|
|
118
|
-
ContainerInfo.new(e.first.value, e.second.preloadIndex.value, e.second.preloadSize.value,
|
|
125
|
+
ContainerInfo.new(e.first.value, e.second.preloadIndex.value, e.second.preloadSize.value,
|
|
126
|
+
e.second.asset.m_FileID.value, e.second.asset.m_PathID.value)
|
|
119
127
|
end
|
|
120
128
|
end
|
|
121
129
|
|
|
@@ -123,8 +131,9 @@ module Mikunyan
|
|
|
123
131
|
# @param [Integer,ObjectEntry] obj path ID or object
|
|
124
132
|
# @return [Mikunyan::BaseObject,nil] parsed object
|
|
125
133
|
def parse_object(obj)
|
|
126
|
-
obj = @path_id_table[obj] if obj.
|
|
134
|
+
obj = @path_id_table[obj] if obj.instance_of?(Integer)
|
|
127
135
|
return nil unless obj.klass&.type_tree
|
|
136
|
+
|
|
128
137
|
value_klass = Mikunyan::CustomTypes.get_custom_type(obj.klass.type_tree.tree.type, obj.class_id)
|
|
129
138
|
ret = parse_object_private(BinaryReader.new(obj.data, @endian), obj.klass.type_tree.tree, value_klass)
|
|
130
139
|
ret.object_entry = obj
|
|
@@ -142,7 +151,7 @@ module Mikunyan
|
|
|
142
151
|
# @param [Integer,ObjectEntry] obj path ID or object
|
|
143
152
|
# @return [String,nil] type name
|
|
144
153
|
def object_type(obj)
|
|
145
|
-
obj = @path_id_table[obj] if obj.
|
|
154
|
+
obj = @path_id_table[obj] if obj.instance_of?(Integer)
|
|
146
155
|
obj&.type
|
|
147
156
|
end
|
|
148
157
|
|
|
@@ -177,8 +186,8 @@ module Mikunyan
|
|
|
177
186
|
end
|
|
178
187
|
|
|
179
188
|
if @format >= 22
|
|
180
|
-
|
|
181
|
-
|
|
189
|
+
_meta_size = br.i32u
|
|
190
|
+
_file_size = br.i64u
|
|
182
191
|
data_offset = br.i64u
|
|
183
192
|
br.adv(8)
|
|
184
193
|
end
|
|
@@ -220,7 +229,7 @@ module Mikunyan
|
|
|
220
229
|
end
|
|
221
230
|
end
|
|
222
231
|
|
|
223
|
-
@path_id_table = @objects.map{|e| [e.path_id, e]}.to_h
|
|
232
|
+
@path_id_table = @objects.map {|e| [e.path_id, e]}.to_h
|
|
224
233
|
|
|
225
234
|
if @format >= 11
|
|
226
235
|
add_id_count = br.i32u
|
|
@@ -232,7 +241,8 @@ module Mikunyan
|
|
|
232
241
|
|
|
233
242
|
reference_count = br.i32u
|
|
234
243
|
@references = Array.new(reference_count) do
|
|
235
|
-
Reference.new(@format >= 6 ? br.cstr : nil, @format >= 5 ? br.read(16) : nil, @format >= 5 ? br.i32s : nil,
|
|
244
|
+
Reference.new(@format >= 6 ? br.cstr : nil, @format >= 5 ? br.read(16) : nil, @format >= 5 ? br.i32s : nil,
|
|
245
|
+
br.cstr)
|
|
236
246
|
end
|
|
237
247
|
|
|
238
248
|
@comment = br.cstr if @format >= 5
|
|
@@ -241,7 +251,11 @@ module Mikunyan
|
|
|
241
251
|
@objects.each do |e|
|
|
242
252
|
br.jmp(data_offset + e.offset)
|
|
243
253
|
e.data = br.read(e.size)
|
|
244
|
-
e.klass =
|
|
254
|
+
e.klass = if e.class_idx
|
|
255
|
+
@klasses[e.class_idx]
|
|
256
|
+
else
|
|
257
|
+
@klasses.find {|e2| e2.class_id == e.class_id} || @klasses.find {|e2| e2.class_id == e.type_id}
|
|
258
|
+
end
|
|
245
259
|
end
|
|
246
260
|
end
|
|
247
261
|
|
|
@@ -284,6 +298,7 @@ module Mikunyan
|
|
|
284
298
|
elsif node.array?
|
|
285
299
|
children.each do |child|
|
|
286
300
|
next ret[child.name] = parse_object_private(br, child) unless child.name == 'data'
|
|
301
|
+
|
|
287
302
|
size = ret['size']&.value || raise('`size` node must appear before `data` node in array node')
|
|
288
303
|
ret.value =
|
|
289
304
|
if child.children.empty? && (!child.need_align? || br.pos % 4 == 0 && child.size % 4 == 0)
|
|
@@ -294,7 +309,7 @@ module Mikunyan
|
|
|
294
309
|
br.read(size * child.size).force_encoding('utf-8')
|
|
295
310
|
end
|
|
296
311
|
end
|
|
297
|
-
ret.value ||= Array.new(size){parse_object_private(br, child)}
|
|
312
|
+
ret.value ||= Array.new(size) {parse_object_private(br, child)}
|
|
298
313
|
ret['data'] = ret.value
|
|
299
314
|
end
|
|
300
315
|
elsif children.size == 1 && children[0].array? && children[0].type == 'Array' && children[0].name == 'Array'
|
|
@@ -302,7 +317,7 @@ module Mikunyan
|
|
|
302
317
|
ret.name = node.name
|
|
303
318
|
ret.type = node.type
|
|
304
319
|
else
|
|
305
|
-
ret.attr = children.map{|c| [c.name, parse_object_private(br, c)]}.to_h
|
|
320
|
+
ret.attr = children.map {|c| [c.name, parse_object_private(br, c)]}.to_h
|
|
306
321
|
if node.type == 'StreamingInfo'
|
|
307
322
|
ret.value = get_stream_blob(ret['path'].value, ret['offset'].value, ret['size'].value)
|
|
308
323
|
else
|
|
@@ -316,6 +331,7 @@ module Mikunyan
|
|
|
316
331
|
def get_stream_blob(path, offset, size)
|
|
317
332
|
return nil unless path && @bundle
|
|
318
333
|
return nil if path.empty?
|
|
334
|
+
|
|
319
335
|
path["archive:/#{@name}/"] = '' if path.start_with?("archive:/#{@name}/")
|
|
320
336
|
@bundle.blobs[path]&.byteslice(offset, size)
|
|
321
337
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'extlz4'
|
|
4
|
-
require '
|
|
4
|
+
require 'extlzma2'
|
|
5
5
|
require 'mikunyan/asset'
|
|
6
6
|
require 'mikunyan/binary_reader'
|
|
7
7
|
|
|
@@ -21,7 +21,7 @@ module Mikunyan
|
|
|
21
21
|
# @param [String,Integer] index
|
|
22
22
|
# @return [Mikunyan::Asset,nil]
|
|
23
23
|
def [](index)
|
|
24
|
-
index.is_a?(String) ? @assets.find{|e| e.name == index} : @assets[index]
|
|
24
|
+
index.is_a?(String) ? @assets.find {|e| e.name == index} : @assets[index]
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
# Same as assets.each
|
|
@@ -92,7 +92,10 @@ module Mikunyan
|
|
|
92
92
|
ui_block_size = br.i32u
|
|
93
93
|
flags = br.i32u
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
br.align(16) if @format >= 7
|
|
96
|
+
|
|
97
|
+
head_bin = flags & 0x80 == 0 ? br.read(ci_block_size) : br.read_abs(ci_block_size, file_size - ci_block_size)
|
|
98
|
+
head = BinaryReader.new(uncompress(head_bin, ui_block_size, flags))
|
|
96
99
|
@guid = head.read(16)
|
|
97
100
|
|
|
98
101
|
block_count = head.i32u
|
|
@@ -114,7 +117,7 @@ module Mikunyan
|
|
|
114
117
|
end
|
|
115
118
|
|
|
116
119
|
def process_asset_entries(asset_entries)
|
|
117
|
-
@blobs = asset_entries.select(&:blob?).map{|e| [e.name, e.data]}.to_h
|
|
120
|
+
@blobs = asset_entries.select(&:blob?).map {|e| [e.name, e.data]}.to_h
|
|
118
121
|
@assets = asset_entries.reject(&:blob?).map do |e|
|
|
119
122
|
Asset.load(e.data, e.name, self)
|
|
120
123
|
end
|
|
@@ -56,6 +56,7 @@ module Mikunyan
|
|
|
56
56
|
def read(size)
|
|
57
57
|
ret = @io.read(size)
|
|
58
58
|
raise EOFError if ret.nil? || size && ret.bytesize < size
|
|
59
|
+
|
|
59
60
|
ret
|
|
60
61
|
end
|
|
61
62
|
|
|
@@ -75,6 +76,7 @@ module Mikunyan
|
|
|
75
76
|
# @return [String] string
|
|
76
77
|
def cstr
|
|
77
78
|
raise EOFError if @io.eof?
|
|
79
|
+
|
|
78
80
|
@io.each_byte.take_while(&:nonzero?).pack('C*')
|
|
79
81
|
end
|
|
80
82
|
|
data/lib/mikunyan/constants.rb
CHANGED
|
@@ -416,91 +416,91 @@ module Mikunyan
|
|
|
416
416
|
[1126, 'PackedAssets'],
|
|
417
417
|
[1127, 'VideoClipImporter'],
|
|
418
418
|
[2000, 'ActivationLogComponent'],
|
|
419
|
-
[
|
|
420
|
-
[
|
|
421
|
-
[
|
|
422
|
-
[
|
|
423
|
-
[
|
|
424
|
-
[
|
|
425
|
-
[
|
|
426
|
-
[
|
|
427
|
-
[
|
|
428
|
-
[
|
|
429
|
-
[
|
|
430
|
-
[
|
|
431
|
-
[
|
|
432
|
-
[
|
|
433
|
-
[
|
|
434
|
-
[
|
|
435
|
-
[
|
|
436
|
-
[
|
|
437
|
-
[
|
|
438
|
-
[
|
|
439
|
-
[
|
|
440
|
-
[
|
|
441
|
-
[
|
|
442
|
-
[
|
|
443
|
-
[
|
|
444
|
-
[
|
|
445
|
-
[
|
|
446
|
-
[
|
|
447
|
-
[
|
|
448
|
-
[
|
|
449
|
-
[
|
|
450
|
-
[
|
|
451
|
-
[
|
|
452
|
-
[
|
|
453
|
-
[
|
|
454
|
-
[
|
|
455
|
-
[
|
|
456
|
-
[
|
|
457
|
-
[
|
|
458
|
-
[
|
|
459
|
-
[
|
|
460
|
-
[
|
|
461
|
-
[
|
|
462
|
-
[
|
|
463
|
-
[
|
|
464
|
-
[
|
|
465
|
-
[
|
|
466
|
-
[
|
|
467
|
-
[
|
|
468
|
-
[
|
|
469
|
-
[
|
|
470
|
-
[
|
|
471
|
-
[
|
|
472
|
-
[
|
|
473
|
-
[
|
|
474
|
-
[
|
|
475
|
-
[
|
|
476
|
-
[
|
|
477
|
-
[
|
|
478
|
-
[
|
|
479
|
-
[
|
|
480
|
-
[
|
|
481
|
-
[
|
|
482
|
-
[
|
|
483
|
-
[
|
|
484
|
-
[
|
|
485
|
-
[
|
|
486
|
-
[
|
|
487
|
-
[
|
|
488
|
-
[
|
|
489
|
-
[
|
|
490
|
-
[
|
|
491
|
-
[
|
|
492
|
-
[
|
|
493
|
-
[
|
|
494
|
-
[
|
|
495
|
-
[
|
|
496
|
-
[
|
|
497
|
-
[
|
|
498
|
-
[
|
|
499
|
-
[
|
|
500
|
-
[
|
|
501
|
-
[
|
|
502
|
-
[
|
|
503
|
-
[
|
|
419
|
+
[100_000, 'int'],
|
|
420
|
+
[100_001, 'bool'],
|
|
421
|
+
[100_002, 'float'],
|
|
422
|
+
[100_003, 'MonoObject'],
|
|
423
|
+
[100_004, 'Collision'],
|
|
424
|
+
[100_005, 'Vector3f'],
|
|
425
|
+
[100_006, 'RootMotionData'],
|
|
426
|
+
[100_007, 'Collision2D'],
|
|
427
|
+
[100_008, 'AudioMixerLiveUpdateFloat'],
|
|
428
|
+
[100_009, 'AudioMixerLiveUpdateBool'],
|
|
429
|
+
[100_010, 'Polygon2D'],
|
|
430
|
+
[100_011, 'void'],
|
|
431
|
+
[19_719_996, 'TilemapCollider2D'],
|
|
432
|
+
[41_386_430, 'AssetImporterLog'],
|
|
433
|
+
[73_398_921, 'VFXRenderer'],
|
|
434
|
+
[76_251_197, 'SerializableManagedRefTestClass'],
|
|
435
|
+
[156_049_354, 'Grid'],
|
|
436
|
+
[181_963_792, 'Preset'],
|
|
437
|
+
[277_625_683, 'EmptyObject'],
|
|
438
|
+
[285_090_594, 'IConstraint'],
|
|
439
|
+
[293_259_124, 'TestObjectWithSpecialLayoutOne'],
|
|
440
|
+
[294_290_339, 'AssemblyDefinitionReferenceImporter'],
|
|
441
|
+
[334_799_969, 'SiblingDerived'],
|
|
442
|
+
[342_846_651, 'TestObjectWithSerializedMapStringNonAlignedStruct'],
|
|
443
|
+
[367_388_927, 'SubDerived'],
|
|
444
|
+
[369_655_926, 'AssetImportInProgressProxy'],
|
|
445
|
+
[382_020_655, 'PluginBuildInfo'],
|
|
446
|
+
[426_301_858, 'EditorProjectAccess'],
|
|
447
|
+
[468_431_735, 'PrefabImporter'],
|
|
448
|
+
[478_637_458, 'TestObjectWithSerializedArray'],
|
|
449
|
+
[478_637_459, 'TestObjectWithSerializedAnimationCurve'],
|
|
450
|
+
[483_693_784, 'TilemapRenderer'],
|
|
451
|
+
[638_013_454, 'SpriteAtlasDatabase'],
|
|
452
|
+
[641_289_076, 'AudioBuildInfo'],
|
|
453
|
+
[644_342_135, 'CachedSpriteAtlasRuntimeData'],
|
|
454
|
+
[646_504_946, 'RendererFake'],
|
|
455
|
+
[662_584_278, 'AssemblyDefinitionReferenceAsset'],
|
|
456
|
+
[668_709_126, 'BuiltAssetBundleInfoSet'],
|
|
457
|
+
[687_078_895, 'SpriteAtlas'],
|
|
458
|
+
[877_146_078, 'PlatformModuleSetup'],
|
|
459
|
+
[895_512_359, 'AimConstraint'],
|
|
460
|
+
[937_362_698, 'VFXManager'],
|
|
461
|
+
[994_735_392, 'VisualEffectSubgraph'],
|
|
462
|
+
[994_735_403, 'VisualEffectSubgraphOperator'],
|
|
463
|
+
[994_735_404, 'VisualEffectSubgraphBlock'],
|
|
464
|
+
[1_001_480_554, 'Prefab'],
|
|
465
|
+
[1_027_052_791, 'LocalizationImporter'],
|
|
466
|
+
[1_091_556_383, 'Derived'],
|
|
467
|
+
[1_111_377_672, 'PropertyModificationsTargetTestObject'],
|
|
468
|
+
[1_114_811_875, 'ReferencesArtifactGenerator'],
|
|
469
|
+
[1_152_215_463, 'AssemblyDefinitionAsset'],
|
|
470
|
+
[1_154_873_562, 'SceneVisibilityState'],
|
|
471
|
+
[1_183_024_399, 'LookAtConstraint'],
|
|
472
|
+
[1_223_240_404, 'MultiArtifactTestImporter'],
|
|
473
|
+
[1_268_269_756, 'GameObjectRecorder'],
|
|
474
|
+
[1_325_145_578, 'LightingDataAssetParent'],
|
|
475
|
+
[1_386_491_679, 'PresetManager'],
|
|
476
|
+
[1_392_443_030, 'TestObjectWithSpecialLayoutTwo'],
|
|
477
|
+
[1_403_656_975, 'StreamingManager'],
|
|
478
|
+
[1_480_428_607, 'LowerResBlitTexture'],
|
|
479
|
+
[1_542_919_678, 'StreamingController'],
|
|
480
|
+
[1_571_458_007, 'RenderPassAttachment'],
|
|
481
|
+
[1_628_831_178, 'TestObjectVectorPairStringBool'],
|
|
482
|
+
[1_742_807_556, 'GridLayout'],
|
|
483
|
+
[1_766_753_193, 'AssemblyDefinitionImporter'],
|
|
484
|
+
[1_773_428_102, 'ParentConstraint'],
|
|
485
|
+
[1_803_986_026, 'FakeComponent'],
|
|
486
|
+
[1_818_360_608, 'PositionConstraint'],
|
|
487
|
+
[1_818_360_609, 'RotationConstraint'],
|
|
488
|
+
[1_818_360_610, 'ScaleConstraint'],
|
|
489
|
+
[1_839_735_485, 'Tilemap'],
|
|
490
|
+
[1_896_753_125, 'PackageManifest'],
|
|
491
|
+
[1_896_753_126, 'PackageManifestImporter'],
|
|
492
|
+
[1_953_259_897, 'TerrainLayer'],
|
|
493
|
+
[1_971_053_207, 'SpriteShapeRenderer'],
|
|
494
|
+
[1_977_754_360, 'NativeObjectType'],
|
|
495
|
+
[1_981_279_845, 'TestObjectWithSerializedMapStringBool'],
|
|
496
|
+
[1_995_898_324, 'SerializableManagedHost'],
|
|
497
|
+
[2_058_629_509, 'VisualEffectAsset'],
|
|
498
|
+
[2_058_629_510, 'VisualEffectImporter'],
|
|
499
|
+
[2_058_629_511, 'VisualEffectResource'],
|
|
500
|
+
[2_059_678_085, 'VisualEffectObject'],
|
|
501
|
+
[2_083_052_967, 'VisualEffect'],
|
|
502
|
+
[2_083_778_819, 'LocalizationAsset'],
|
|
503
|
+
[2_089_858_483, 'ScriptedImporter']
|
|
504
504
|
]
|
|
505
505
|
|
|
506
506
|
CLASS_ID2NAME = CLASS_ID_TABLE.to_h.freeze
|
|
@@ -187,7 +187,8 @@ module Mikunyan
|
|
|
187
187
|
# @param [Symbol] endian endianness of binary
|
|
188
188
|
# @return [ChunkyPNG::Image] decoded image
|
|
189
189
|
def self.decode_rgb565(width, height, bin, endian = :big)
|
|
190
|
-
ChunkyPNG::Image.from_rgb_stream(width, height,
|
|
190
|
+
ChunkyPNG::Image.from_rgb_stream(width, height,
|
|
191
|
+
DecodeHelper.decode_rgb565(bin, width * height, endian == :big)).flip
|
|
191
192
|
end
|
|
192
193
|
|
|
193
194
|
# Decode image from R16 binary
|
|
@@ -197,7 +198,8 @@ module Mikunyan
|
|
|
197
198
|
# @param [Symbol] endian endianness of binary
|
|
198
199
|
# @return [ChunkyPNG::Image] decoded image
|
|
199
200
|
def self.decode_r16(width, height, bin, endian = :big)
|
|
200
|
-
ChunkyPNG::Image.from_rgb_stream(width, height,
|
|
201
|
+
ChunkyPNG::Image.from_rgb_stream(width, height,
|
|
202
|
+
DecodeHelper.decode_r16(bin, width * height, endian == :big)).flip
|
|
201
203
|
end
|
|
202
204
|
|
|
203
205
|
# Decode image from RGBA4444 binary
|
|
@@ -270,7 +272,8 @@ module Mikunyan
|
|
|
270
272
|
# @param [Symbol] endian endianness of binary
|
|
271
273
|
# @return [ChunkyPNG::Image] decoded image
|
|
272
274
|
def self.decode_rhalf(width, height, bin, endian = :big)
|
|
273
|
-
ChunkyPNG::Image.from_rgb_stream(width, height,
|
|
275
|
+
ChunkyPNG::Image.from_rgb_stream(width, height,
|
|
276
|
+
DecodeHelper.decode_rhalf(bin, width * height, endian == :big)).flip
|
|
274
277
|
end
|
|
275
278
|
|
|
276
279
|
# Decode image from RG Half-float binary
|
|
@@ -280,7 +283,8 @@ module Mikunyan
|
|
|
280
283
|
# @param [Symbol] endian endianness of binary
|
|
281
284
|
# @return [ChunkyPNG::Image] decoded image
|
|
282
285
|
def self.decode_rghalf(width, height, bin, endian = :big)
|
|
283
|
-
ChunkyPNG::Image.from_rgb_stream(width, height,
|
|
286
|
+
ChunkyPNG::Image.from_rgb_stream(width, height,
|
|
287
|
+
DecodeHelper.decode_rghalf(bin, width * height, endian == :big)).flip
|
|
284
288
|
end
|
|
285
289
|
|
|
286
290
|
# Decode image from RGBA Half-float binary
|
|
@@ -290,7 +294,8 @@ module Mikunyan
|
|
|
290
294
|
# @param [Symbol] endian endianness of binary
|
|
291
295
|
# @return [ChunkyPNG::Image] decoded image
|
|
292
296
|
def self.decode_rgbahalf(width, height, bin, endian = :big)
|
|
293
|
-
ChunkyPNG::Image.from_rgba_stream(width, height,
|
|
297
|
+
ChunkyPNG::Image.from_rgba_stream(width, height,
|
|
298
|
+
DecodeHelper.decode_rgbahalf(bin, width * height, endian == :big)).flip
|
|
294
299
|
end
|
|
295
300
|
|
|
296
301
|
# Decode image from R float binary
|
|
@@ -366,7 +371,8 @@ module Mikunyan
|
|
|
366
371
|
# @param [Integer] bpp bit per pixel (2 or 4)
|
|
367
372
|
# @return [ChunkyPNG::Image] decoded image
|
|
368
373
|
def self.decode_pvrtc1(width, height, bin, bpp)
|
|
369
|
-
raise 'bpp of PVRTC1 must be 2 or 4' unless
|
|
374
|
+
raise 'bpp of PVRTC1 must be 2 or 4' unless [2, 4].include?(bpp)
|
|
375
|
+
|
|
370
376
|
ChunkyPNG::Image.from_rgba_stream(width, height, DecodeHelper.decode_pvrtc1(bin, width, height, bpp == 2))
|
|
371
377
|
end
|
|
372
378
|
|
|
@@ -449,7 +455,8 @@ module Mikunyan
|
|
|
449
455
|
# @param [String] bin binary to decode
|
|
450
456
|
# @return [ChunkyPNG::Image] decoded image
|
|
451
457
|
def self.decode_astc(width, height, blocksize, bin)
|
|
452
|
-
ChunkyPNG::Image.from_rgba_stream(width, height,
|
|
458
|
+
ChunkyPNG::Image.from_rgba_stream(width, height,
|
|
459
|
+
DecodeHelper.decode_astc(bin, width, height, blocksize, blocksize))
|
|
453
460
|
end
|
|
454
461
|
|
|
455
462
|
# Decode image from crunched texture binary
|
|
@@ -488,8 +495,10 @@ module Mikunyan
|
|
|
488
495
|
fmt = object['m_TextureFormat']&.value
|
|
489
496
|
bin = object['image data']&.value
|
|
490
497
|
return unless width && height && fmt && bin && astc_list[fmt]
|
|
498
|
+
|
|
491
499
|
bin = object['m_StreamData']&.value if bin.empty?
|
|
492
500
|
return unless bin
|
|
501
|
+
|
|
493
502
|
header = [0x13, 0xab, 0xa1, 0x5c, astc_list[fmt], astc_list[fmt], 1].pack('C*')
|
|
494
503
|
header << [width].pack('V').byteslice(0, 3)
|
|
495
504
|
header << [height].pack('V').byteslice(0, 3)
|
|
@@ -500,6 +509,7 @@ module Mikunyan
|
|
|
500
509
|
# [0.0,1.0] -> [0,255]
|
|
501
510
|
def self.f2i(val)
|
|
502
511
|
return 0 unless val.finite?
|
|
512
|
+
|
|
503
513
|
(val * 255).round.clamp(0, 255)
|
|
504
514
|
end
|
|
505
515
|
end
|
|
@@ -95,11 +95,11 @@ module Mikunyan
|
|
|
95
95
|
if @type == 'pair'
|
|
96
96
|
[@attr['first'].simplify, @attr['second'].simplify]
|
|
97
97
|
elsif @type == 'map' && @value.is_a?(Array)
|
|
98
|
-
@value.map{|e| [e['first'].simplify, e['second'].simplify]}.to_h
|
|
98
|
+
@value.map {|e| [e['first'].simplify, e['second'].simplify]}.to_h
|
|
99
99
|
elsif is_struct
|
|
100
|
-
@attr.
|
|
100
|
+
@attr.transform_values(&:simplify)
|
|
101
101
|
elsif @value.is_a?(Array)
|
|
102
|
-
@value.map{|e| e.is_a?(ObjectValue) ? e.simplify : e}
|
|
102
|
+
@value.map {|e| e.is_a?(ObjectValue) ? e.simplify : e}
|
|
103
103
|
elsif @value.is_a?(ObjectValue)
|
|
104
104
|
@value.simplify
|
|
105
105
|
else
|