sso-elements-fmk 0.1.1

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