sso-elements-fmk 0.1.2 → 0.1.4
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/CODE_OF_CONDUCT.md +132 -132
- data/README.md +73 -73
- data/Rakefile +8 -8
- data/lib/sso/elements/collection.rb +264 -247
- data/lib/sso/elements/config.rb +92 -90
- data/lib/sso/elements/fmk/version.rb +9 -9
- data/lib/sso/elements/fmk.rb +12 -12
- data/sig/sso/elements/fmk.rbs +8 -8
- metadata +2 -6
- data/.idea/.gitignore +0 -8
- data/.idea/modules.xml +0 -8
- data/.idea/sso-elements-fmk.iml +0 -59
- data/.idea/vcs.xml +0 -6
@@ -1,248 +1,265 @@
|
|
1
|
-
require_relative 'config'
|
2
|
-
|
3
|
-
module SSO
|
4
|
-
module Elements
|
5
|
-
class Collection
|
6
|
-
attr_accessor :version,
|
7
|
-
:signature,
|
8
|
-
:index,
|
9
|
-
:configs
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
@
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
def
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
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
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
result
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
end
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
file.
|
206
|
-
elsif type
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
file.
|
212
|
-
elsif type
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
1
|
+
require_relative 'config'
|
2
|
+
|
3
|
+
module SSO
|
4
|
+
module Elements
|
5
|
+
class Collection
|
6
|
+
attr_accessor :version,
|
7
|
+
:signature,
|
8
|
+
:index,
|
9
|
+
:configs,
|
10
|
+
:id_set
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@addon_index = {}
|
14
|
+
@lists = []
|
15
|
+
@id_set = Set.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def gen_id
|
19
|
+
id = 1
|
20
|
+
|
21
|
+
while id_set.include?(id)
|
22
|
+
id += 1
|
23
|
+
end
|
24
|
+
|
25
|
+
id
|
26
|
+
end
|
27
|
+
|
28
|
+
def table(name)
|
29
|
+
index[name]
|
30
|
+
end
|
31
|
+
|
32
|
+
def build_index!
|
33
|
+
puts '[INFO] Building collections'
|
34
|
+
@index = {}
|
35
|
+
@configs.each do |config|
|
36
|
+
config_name = config.name.split(' - ').last.downcase.split('_').map(&:capitalize).join('')
|
37
|
+
@index[config_name] = config
|
38
|
+
puts "[INFO] Building collection #{config_name}"
|
39
|
+
config.elements.each do |element|
|
40
|
+
id_set << element.id
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def load_elements!(path)
|
46
|
+
sstat = [ 0, 0, 0, 0, 0 ]
|
47
|
+
|
48
|
+
file = File.open(path, 'rb')
|
49
|
+
|
50
|
+
@version = file.read(2).unpack('s<').first
|
51
|
+
|
52
|
+
if @configs.nil?
|
53
|
+
puts '[INFO] No config provided. Searching in default CFG files'
|
54
|
+
if SSO::Elements::Config::CFG_AVAIL.keys.include?(@version)
|
55
|
+
puts "[INFO] Using #{SSO::Elements::Config::CFG_AVAIL[@version]}!"
|
56
|
+
load_config!(@version)
|
57
|
+
else
|
58
|
+
raise "[ERROR] No config provided and no default cfg file to match with elements version #{@version}!"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
@signature = file.read(2).unpack('s<').first
|
63
|
+
|
64
|
+
@configs.each_with_index do |config, i|
|
65
|
+
puts "[INFO] (#{i+1}/#{@configs.size}) Reading #{config.name} ... "
|
66
|
+
sstat[0] = i
|
67
|
+
|
68
|
+
if config.offset.size > 0
|
69
|
+
config.offset = file.read(config.offset.size).bytes
|
70
|
+
else
|
71
|
+
puts 'CRITICAL: NO OFFSET FOUND!'
|
72
|
+
return false
|
73
|
+
end
|
74
|
+
|
75
|
+
config.values = Array.new(read_value(file, 'int32'))
|
76
|
+
sstat[1] = config.values.size
|
77
|
+
|
78
|
+
(0...config.values.size).each do |e|
|
79
|
+
config.values[e] = Array.new(config.types.size)
|
80
|
+
|
81
|
+
(0...config.values[e].size).each do |f|
|
82
|
+
config.values[e][f] = read_value(file, config.types[f])
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
file.close
|
88
|
+
|
89
|
+
build_index!
|
90
|
+
|
91
|
+
true
|
92
|
+
end
|
93
|
+
|
94
|
+
def load_config!(path)
|
95
|
+
if path.is_a?(Integer)
|
96
|
+
cfg = Config::CFG_AVAIL[path]
|
97
|
+
raise "Incompatible version #{path}!" unless cfg
|
98
|
+
dir = File.dirname(__FILE__)
|
99
|
+
path = File.expand_path("./configs/#{cfg}", dir)
|
100
|
+
end
|
101
|
+
|
102
|
+
buffer = File.readlines(path, chomp: true)
|
103
|
+
|
104
|
+
lists_size = buffer.shift.to_i
|
105
|
+
|
106
|
+
lists = []
|
107
|
+
@conversation_list_index = buffer.shift.to_i
|
108
|
+
@conversation_list_index = 58 if @conversation_list_index == 0
|
109
|
+
|
110
|
+
lists_size.times do
|
111
|
+
line = ''
|
112
|
+
|
113
|
+
loop do
|
114
|
+
line = buffer.shift
|
115
|
+
break unless line == ''
|
116
|
+
end
|
117
|
+
|
118
|
+
offset = buffer.shift
|
119
|
+
|
120
|
+
list = Config.new(self)
|
121
|
+
list.name = line
|
122
|
+
list.offset = Array.new(offset.to_i) if offset != 'AUTO'
|
123
|
+
list.fields = buffer.shift.split(';')
|
124
|
+
list.types = buffer.shift.split(';')
|
125
|
+
lists << list
|
126
|
+
end
|
127
|
+
|
128
|
+
@configs = lists
|
129
|
+
true
|
130
|
+
end
|
131
|
+
|
132
|
+
def load_rules(path)
|
133
|
+
buffer = File.readlines(path, chomp: true)
|
134
|
+
|
135
|
+
result = {}
|
136
|
+
|
137
|
+
buffer.each do |line|
|
138
|
+
next if line.empty? || line[0] == '#'
|
139
|
+
|
140
|
+
if line.include?('|')
|
141
|
+
key, value = line.split('|')
|
142
|
+
else
|
143
|
+
key = line
|
144
|
+
value = ''
|
145
|
+
end
|
146
|
+
|
147
|
+
result[key] = value
|
148
|
+
end
|
149
|
+
|
150
|
+
result['SETCONVERSATIONLISTINDEX'] ||= 58
|
151
|
+
|
152
|
+
result
|
153
|
+
end
|
154
|
+
|
155
|
+
def save!(path)
|
156
|
+
File.delete(path) if File.exist?(path)
|
157
|
+
file = File.open(path, 'wb')
|
158
|
+
|
159
|
+
file.write([@version].pack('s<'))
|
160
|
+
file.write([@signature].pack('s<'))
|
161
|
+
|
162
|
+
@configs.each_with_index do |config, index|
|
163
|
+
puts "[INFO] (#{index+1}/#{@configs.size}) Saving #{config.name} ... "
|
164
|
+
file.write(config.offset.pack("C*")) if config.offset.size > 0
|
165
|
+
|
166
|
+
if @conversation_list_index != index
|
167
|
+
file.write([config.values.size].pack('l<'))
|
168
|
+
end
|
169
|
+
|
170
|
+
if config.elements_loaded?
|
171
|
+
(0...config.values.size).each do |config_values_index|
|
172
|
+
config.values[config_values_index] = config.elements[config_values_index].to_value
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
config.values.each do |values|
|
177
|
+
values.each_with_index do |value, value_index|
|
178
|
+
begin
|
179
|
+
write_value(file, value, config.types[value_index])
|
180
|
+
rescue => e
|
181
|
+
pp values
|
182
|
+
raise e
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
file.close
|
189
|
+
true
|
190
|
+
rescue => e
|
191
|
+
p e
|
192
|
+
false
|
193
|
+
end
|
194
|
+
|
195
|
+
def read_value(file, type)
|
196
|
+
if type == 'int16'
|
197
|
+
file.read(2).unpack('s<')[0]
|
198
|
+
elsif type == 'int32'
|
199
|
+
file.read(4).unpack("l<")[0]
|
200
|
+
elsif type == 'int64'
|
201
|
+
file.read(8).unpack('q<')[0]
|
202
|
+
elsif type == 'float'
|
203
|
+
file.read(4).unpack('f')[0]
|
204
|
+
elsif type == 'double'
|
205
|
+
file.read(8).unpack('d')[0]
|
206
|
+
elsif type.start_with?('byte:')
|
207
|
+
byte_count = type[5..-1].to_i
|
208
|
+
file.read(byte_count)
|
209
|
+
elsif type.start_with?('wstring:')
|
210
|
+
byte_count = type[8..-1].to_i
|
211
|
+
Collection.compact_string(file.read(byte_count).force_encoding('UTF-16LE').encode('UTF-8'))
|
212
|
+
elsif type.start_with?('string:')
|
213
|
+
byte_count = type[7..-1].to_i
|
214
|
+
Collection.compact_string(file.read(byte_count).force_encoding('UTF-8'))
|
215
|
+
else
|
216
|
+
nil
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
def write_value(file, value, type)
|
221
|
+
if type == 'int16'
|
222
|
+
file.write([value.to_i].pack('s<'))
|
223
|
+
elsif type == 'int32'
|
224
|
+
file.write([value.to_i].pack('l<'))
|
225
|
+
elsif type == 'int64'
|
226
|
+
file.write([value.to_f].pack('q<'))
|
227
|
+
elsif type == 'float'
|
228
|
+
file.write([value.to_f].pack('f'))
|
229
|
+
elsif type == 'double'
|
230
|
+
file.write([value.to_f].pack('d'))
|
231
|
+
elsif type.start_with?('byte:')
|
232
|
+
file.write(value)
|
233
|
+
elsif type.start_with?('wstring:')
|
234
|
+
file.write(Collection.expand_string_utf16((value || 'BUG').encode('UTF-16LE'), type))
|
235
|
+
elsif type.start_with?('string:')
|
236
|
+
file.write(Collection.expand_string_utf8((value || 'BUG'), type))
|
237
|
+
else
|
238
|
+
nil
|
239
|
+
end
|
240
|
+
rescue => e
|
241
|
+
pp value
|
242
|
+
pp type
|
243
|
+
raise e
|
244
|
+
end
|
245
|
+
|
246
|
+
def self.compact_string(s)
|
247
|
+
s.gsub("\u0000", '')
|
248
|
+
end
|
249
|
+
|
250
|
+
def self.expand_string_utf16(base, type)
|
251
|
+
sz = type.split(':').last.to_i
|
252
|
+
s = base
|
253
|
+
s += "\u0000".encode('UTF-16LE') while s.bytes.size < sz
|
254
|
+
s
|
255
|
+
end
|
256
|
+
|
257
|
+
def self.expand_string_utf8(base, type)
|
258
|
+
sz = type.split(':').last.to_i
|
259
|
+
s = base
|
260
|
+
s += "\u0000" while s.bytes.size < sz
|
261
|
+
s
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
248
265
|
end
|