rvpacker-txt 1.5.2 → 1.7.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.
data/lib/read.rb CHANGED
@@ -2,32 +2,33 @@
2
2
 
3
3
  require 'zlib'
4
4
 
5
- def self.insert_at_index(hash, index, key, value)
6
- return hash[key] = value if index >= hash.size
5
+ class Hash
6
+ def insert_at_index(index, key, value)
7
+ return self[key] = value if index >= size
7
8
 
8
- temp_hash = hash.to_a
9
- temp_hash.insert(index, [key, value])
10
- hash.clear
11
- hash.merge!(temp_hash.to_h)
9
+ temp_array = to_a
10
+ temp_array.insert(index, [key, value])
11
+ replace(temp_array.to_h)
12
+ end
12
13
  end
13
14
 
15
+ # @param [String] string A parsed scripts code string, containing raw Ruby code
16
+ # @return [IndexSet<String>] Hash of parsed from code strings and their start indices
14
17
  def self.extract_quoted_strings(string)
15
- # Hash of string-index key-value pairs
16
- result = {}
18
+ result = IndexSet.new
17
19
 
18
20
  skip_block = false
19
21
  in_quotes = false
20
22
  quote_type = nil
21
23
  buffer = []
22
24
 
23
- # I hope this calculates index correctly
24
- current_string_index = 0
25
25
  string.each_line do |line|
26
26
  stripped = line.strip
27
27
 
28
- if stripped[0] == '#' || stripped.start_with?(/(Win|Lose)|_Fanfare/)
29
- next
30
- end
28
+ next if stripped[0] == '#' ||
29
+ !stripped.match?(/["']/) ||
30
+ stripped.start_with?(/(Win|Lose)|_Fanfare/) ||
31
+ stripped.match?(/eval\(/)
31
32
 
32
33
  skip_block = true if stripped.start_with?('=begin')
33
34
  skip_block = false if stripped.start_with?('=end')
@@ -36,7 +37,7 @@ def self.extract_quoted_strings(string)
36
37
 
37
38
  buffer.push('\#') if in_quotes
38
39
 
39
- line.each_char.each_with_index do |char, index|
40
+ line.each_char do |char|
40
41
  if %w[' "].include?(char)
41
42
  unless quote_type.nil? || char == quote_type
42
43
  buffer.push(char)
@@ -45,72 +46,84 @@ def self.extract_quoted_strings(string)
45
46
 
46
47
  quote_type = char
47
48
  in_quotes = !in_quotes
48
- result[buffer.join] = current_string_index + index
49
+ result.add(buffer.join)
49
50
  buffer.clear
50
51
  next
51
52
  end
52
53
 
53
- if in_quotes
54
- buffer.push(char)
55
- end
54
+ buffer.push(char) if in_quotes
56
55
  end
57
-
58
- current_string_index += line.length
59
56
  end
60
57
 
61
58
  result
62
59
  end
63
60
 
61
+ # @param [Integer] code
62
+ # @param [String] parameter
63
+ # @param [String] game_type
64
+ # @return [String]
64
65
  def self.parse_parameter(code, parameter, game_type)
65
- case code
66
- when 401, 405
67
- case game_type
68
- when 'lisa'
69
- match = parameter.scan(/^(\\et\[[0-9]+\]|\\nbt)/)
70
- parameter = parameter.slice((match[0].length)..) if match
71
- else
72
- nil
73
- end
74
- when 102
75
- # Implement some custom parsing
76
- when 356
77
- # Implement some custom parsing
78
- else
79
- return nil
66
+ unless game_type.nil?
67
+ case code
68
+ when 401, 405
69
+ case game_type
70
+ when 'lisa'
71
+ match = parameter.scan(/^(\\et\[[0-9]+\]|\\nbt)/)
72
+ parameter = parameter.slice((match[0].length)..) unless match.empty?
73
+ else
74
+ nil
75
+ end
76
+ when 102
77
+ # Implement some custom parsing
78
+ when 356
79
+ # Implement some custom parsing
80
+ else
81
+ return nil
82
+ end
80
83
  end
81
84
 
82
85
  parameter
83
86
  end
84
87
 
88
+ # @param [String] variable
89
+ # @param [String] game_type
90
+ # @return [String]
85
91
  def self.parse_variable(variable, game_type)
86
- lines_count = variable.count("\n")
92
+ unless game_type.nil?
93
+ lines_count = variable.count("\n")
87
94
 
88
- if lines_count.positive?
89
- variable = variable.gsub(/\r?\n/, '\#')
95
+ if lines_count.positive?
96
+ variable = variable.gsub(/\r?\n/, '\#')
90
97
 
91
- case game_type
92
- when 'lisa'
93
- return nil unless variable.split('\#').all? { |line| line.match?(/^<.*>\.?$/) || line.empty? }
94
- else
95
- nil
98
+ case game_type
99
+ when 'lisa'
100
+ return nil unless variable.split('\#').all? { |line| line.match?(/^<.*>\.?$/) || line.empty? }
101
+ else
102
+ nil
103
+ end
96
104
  end
97
105
  end
98
106
 
99
107
  variable
100
108
  end
101
109
 
102
- def self.read_map(maps_files, output_path, logging, game_type, processing_type)
110
+ # @param [Array<String>] maps_files_paths
111
+ # @param [String] output_path
112
+ # @param [Boolean] logging
113
+ # @param [String] game_type
114
+ # @param [String] processing_type
115
+ def self.read_map(maps_files_paths, output_path, logging, game_type, processing_type)
103
116
  maps_output_path = File.join(output_path, 'maps.txt')
104
117
  names_output_path = File.join(output_path, 'names.txt')
105
118
  maps_trans_output_path = File.join(output_path, 'maps_trans.txt')
106
119
  names_trans_output_path = File.join(output_path, 'names_trans.txt')
107
120
 
108
- if processing_type == 'default' && (File.exist?(maps_trans_output_path) || File.exist?(names_trans_output_path))
121
+ if processing_type == :default && (File.exist?(maps_trans_output_path) || File.exist?(names_trans_output_path))
109
122
  puts 'maps_trans.txt or names_trans.txt file already exists. If you want to forcefully re-read all files, use --force flag, or --append if you want append new text to already existing files.'
110
123
  return
111
124
  end
112
125
 
113
- maps_object_map = Hash[maps_files.map do |filename|
126
+ maps_object_map = Hash[maps_files_paths.map do |filename|
114
127
  [File.basename(filename), Marshal.load(File.binread(filename))]
115
128
  end]
116
129
 
@@ -120,94 +133,107 @@ def self.read_map(maps_files, output_path, logging, game_type, processing_type)
120
133
  maps_translation_map = nil
121
134
  names_translation_map = nil
122
135
 
123
- if processing_type == 'append'
136
+ if processing_type == :append
124
137
  if File.exist?(maps_trans_output_path)
125
- maps_translation_map = Hash[File.readlines(maps_output_path, chomp: true).zip(File.readlines(maps_trans_output_path, chomp: true))]
126
- names_translation_map = Hash[File.readlines(names_output_path, chomp: true).zip(File.readlines(names_trans_output_path, chomp: true))]
138
+ maps_translation_map = Hash[File.readlines(maps_output_path, chomp: true)
139
+ .zip(File.readlines(maps_trans_output_path, chomp: true))]
140
+ names_translation_map = Hash[File.readlines(names_output_path, chomp: true)
141
+ .zip(File.readlines(names_trans_output_path, chomp: true))]
127
142
  else
128
143
  puts "Files aren't already parsed. Continuing as if --append flag was omitted."
129
- processing_type = 'default'
144
+ processing_type = :default
130
145
  end
131
146
  end
132
147
 
148
+ # 401 - dialogue lines
149
+ # 102 - dialogue choices array
150
+ # 402 - one of the dialogue choices from the array
151
+ # 356 - system lines/special texts (do they even exist before mv?)
152
+ allowed_codes = [401, 102, 402, 356].freeze
153
+
133
154
  maps_object_map.each do |filename, object|
134
- display_name = object.instance_variable_get(:@display_name)
155
+ display_name = object.display_name
135
156
 
136
- if display_name.is_a?(String) && !display_name.empty?
137
- if processing_type == 'append' && !names_translation_map.include?(display_name)
138
- insert_at_index(names_translation_map, names_lines.length, display_name, '')
139
- end
157
+ if display_name.is_a?(String)
158
+ display_name = display_name.strip
159
+
160
+ unless display_name.empty?
161
+ names_translation_map.insert_at_index(names_lines.length, display_name, '') if processing_type == :append &&
162
+ !names_translation_map.include?(display_name)
140
163
 
141
- names_lines.add(display_name)
164
+ names_lines.add(display_name)
165
+ end
142
166
  end
143
167
 
144
- events = object.instance_variable_get(:@events)
168
+ events = object.events
145
169
  next if events.nil?
146
170
 
147
171
  events.each_value do |event|
148
- pages = event.instance_variable_get(:@pages)
172
+ pages = event.pages
149
173
  next if pages.nil?
150
174
 
151
175
  pages.each do |page|
152
- list = page.instance_variable_get(:@list)
176
+ list = page.list
153
177
  next if list.nil?
154
178
 
155
179
  in_sequence = false
156
180
  line = []
157
181
 
158
182
  list.each do |item|
159
- code = item.instance_variable_get(:@code)
160
- parameters = item.instance_variable_get(:@parameters)
183
+ code = item.code
161
184
 
185
+ unless allowed_codes.include?(code)
186
+ if in_sequence
187
+ joined = line.join('\#').strip
188
+ parsed = parse_parameter(401, joined, game_type)
189
+
190
+ maps_translation_map.insert_at_index(maps_lines.length, parsed, '') if processing_type == :append &&
191
+ !maps_translation_map.include?(parsed)
192
+
193
+ maps_lines.add(parsed)
194
+
195
+ line.clear
196
+ in_sequence = false
197
+ end
198
+ next
199
+ end
200
+
201
+ parameters = item.parameters
162
202
  parameters.each do |parameter|
163
203
  if code == 401
164
- if parameter.is_a?(String) && !parameter.empty?
165
- in_sequence = true
204
+ next unless parameter.is_a?(String) && !parameter.empty?
166
205
 
167
- parsed = parse_parameter(code, parameter, game_type)
168
- line.push(parsed) unless parsed.nil?
169
- end
170
- else
171
- if in_sequence
172
- joined = line.join('\#')
206
+ in_sequence = true
207
+ line.push(parameter)
208
+ elsif code == 102 && parameter.is_a?(Array)
173
209
 
174
- if processing_type == 'append' && !maps_translation_map.include?(joined)
175
- insert_at_index(maps_translation_map, maps_lines.length, joined, '')
176
- end
210
+ parameter.each do |subparameter|
211
+ next unless subparameter.is_a?(String)
177
212
 
178
- maps_lines.add(joined)
213
+ subparameter = subparameter.strip
214
+ next if subparameter.empty?
179
215
 
180
- line.clear
181
- in_sequence = false
182
- end
216
+ parsed = parse_parameter(code, subparameter, game_type)
217
+ next if parsed.nil?
183
218
 
184
- if code == 102 && parameter.is_a?(Array)
185
- parameter.each do |subparameter|
186
- if subparameter.is_a?(String) && !subparameter.empty?
187
- parsed = parse_parameter(code, subparameter, game_type)
219
+ maps_translation_map.insert_at_index(maps_lines.length, parsed, '') if processing_type == :append &&
220
+ !maps_translation_map.include?(parsed)
188
221
 
189
- unless parsed.nil?
190
- if processing_type == 'append' && !maps_translation_map.include?(parsed)
191
- insert_at_index(maps_translation_map, maps_lines.length, parsed, '')
192
- end
222
+ maps_lines.add(parsed)
223
+ end
224
+ elsif code == 356 && parameter.is_a?(String)
225
+ parameter = parameter.strip
226
+ next if parameter.empty?
193
227
 
194
- maps_lines.add(parsed)
195
- end
196
- end
197
- end
198
- elsif code == 356 && parameter.is_a?(String) && !parameter.empty?
199
- parsed = parse_parameter(code, parameter, game_type)
228
+ parsed = parse_parameter(code, parameter, game_type)
229
+ next if parsed.nil?
200
230
 
201
- unless parsed.nil?
202
- subbed = parsed.gsub(/\r?\n/, '\#')
231
+ parsed = parsed.gsub(/\r?\n/, '\#')
203
232
 
204
- if processing_type == 'append' && !maps_translation_map.include?(parsed)
205
- insert_at_index(maps_translation_map, maps_lines.length, parsed, '')
206
- end
233
+ maps_translation_map.insert_at_index(maps_lines.length, parsed, '') if processing_type == :append &&
234
+ !maps_translation_map.include?(parsed)
207
235
 
208
- maps_lines.add(subbed)
209
- end
210
- end
236
+ maps_lines.add(parsed)
211
237
  end
212
238
  end
213
239
  end
@@ -220,7 +246,7 @@ def self.read_map(maps_files, output_path, logging, game_type, processing_type)
220
246
  maps_original_content,
221
247
  maps_translated_content,
222
248
  names_original_content,
223
- names_translated_content = if processing_type == 'append'
249
+ names_translated_content = if processing_type == :append
224
250
  [maps_translation_map.keys.join("\n"),
225
251
  maps_translation_map.values.join("\n"),
226
252
  names_translation_map.keys.join("\n"),
@@ -238,16 +264,23 @@ def self.read_map(maps_files, output_path, logging, game_type, processing_type)
238
264
  File.binwrite(names_trans_output_path, names_translated_content)
239
265
  end
240
266
 
241
- def self.read_other(other_files, output_path, logging, game_type, processing_type)
242
- other_object_array_map = Hash[other_files.map do |filename|
243
- basename = File.basename(filename)
244
- object = Marshal.load(File.binread(filename))
245
- object = merge_other(object).slice(1..) if basename.start_with?(/Common|Troops/)
246
-
247
- [basename, object]
267
+ # @param [Array<String>] other_files_paths
268
+ # @param [String] output_path
269
+ # @param [Boolean] logging
270
+ # @param [String] game_type
271
+ # @param [String] processing_type
272
+ def self.read_other(other_files_paths, output_path, logging, game_type, processing_type)
273
+ other_object_array_map = Hash[other_files_paths.map do |filename|
274
+ [File.basename(filename), Marshal.load(File.binread(filename))]
248
275
  end]
249
276
 
250
- internal_processing_type = processing_type
277
+ inner_processing_type = processing_type
278
+ # 401 - dialogue lines
279
+ # 405 - credits lines
280
+ # 102 - dialogue choices array
281
+ # 402 - one of the dialogue choices from the array
282
+ # 356 - system lines/special texts (do they even exist before mv?)
283
+ allowed_codes = [401, 405, 102, 402, 356].freeze
251
284
 
252
285
  other_object_array_map.each do |filename, other_object_array|
253
286
  processed_filename = File.basename(filename, '.*').downcase
@@ -255,7 +288,7 @@ def self.read_other(other_files, output_path, logging, game_type, processing_typ
255
288
  other_output_path = File.join(output_path, "#{processed_filename}.txt")
256
289
  other_trans_output_path = File.join(output_path, "#{processed_filename}_trans.txt")
257
290
 
258
- if processing_type == 'default' && File.exist?(other_trans_output_path)
291
+ if processing_type == :default && File.exist?(other_trans_output_path)
259
292
  puts "#{processed_filename}_trans.txt file already exists. If you want to forcefully re-read all files, use --force flag, or --append if you want append new text to already existing files."
260
293
  next
261
294
  end
@@ -263,94 +296,111 @@ def self.read_other(other_files, output_path, logging, game_type, processing_typ
263
296
  other_lines = IndexSet.new
264
297
  other_translation_map = nil
265
298
 
266
- if processing_type == 'append'
299
+ if processing_type == :append
267
300
  if File.exist?(other_trans_output_path)
268
- internal_processing_type == 'append'
269
- other_translation_map = Hash[File.readlines(other_output_path, chomp: true).zip(File.readlines(other_trans_output_path, chomp: true))]
301
+ inner_processing_type == :append
302
+ other_translation_map = Hash[File.readlines(other_output_path, chomp: true)
303
+ .zip(File.readlines(other_trans_output_path, chomp: true))]
270
304
  else
271
305
  puts "Files aren't already parsed. Continuing as if --append flag was omitted."
272
- internal_processing_type = 'default'
306
+ inner_processing_type = :default
273
307
  end
274
308
  end
275
309
 
276
310
  if !filename.start_with?(/Common|Troops/)
277
311
  other_object_array.each do |object|
278
- name = object.instance_variable_get(:@name)
279
- nickname = object.instance_variable_get(:@nickname)
280
- description = object.instance_variable_get(:@description)
281
- note = object.instance_variable_get(:@note)
312
+ next if object.nil?
313
+
314
+ name = object.name
315
+ nickname = object.nickname
316
+ description = object.description
317
+ note = object.note
282
318
 
283
319
  [name, nickname, description, note].each do |variable|
284
- if variable.is_a?(String) && !variable.empty?
285
- parsed = parse_variable(variable, game_type)
320
+ next unless variable.is_a?(String)
286
321
 
287
- unless parsed.nil?
288
- if internal_processing_type == 'append' && !other_translation_map.include?(parsed)
289
- insert_at_index(other_translation_map, other_lines.length, parsed, '')
290
- end
322
+ variable = variable.strip
323
+ next if variable.empty?
291
324
 
292
- other_lines.add(parsed)
293
- end
294
- end
325
+ parsed = parse_variable(variable, game_type)
326
+ next if parsed.nil?
327
+
328
+ parsed = parsed.gsub(/\r?\n/, '\#')
329
+
330
+ other_translation_map.insert_at_index(other_lines.length, parsed, '') if inner_processing_type == :append &&
331
+ !other_translation_map.include?(parsed)
332
+
333
+ other_lines.add(parsed)
295
334
  end
296
335
  end
297
336
  else
298
337
  other_object_array.each do |object|
299
- pages = object.instance_variable_get(:@pages)
338
+ next if object.nil?
339
+
340
+ pages = object.pages
300
341
  pages_length = pages.nil? ? 1 : pages.length
301
342
 
302
343
  (0..pages_length).each do |i|
303
- list = pages.nil? ? object.instance_variable_get(:@list) : pages[i].instance_variable_get(:@list)
344
+ list = pages.nil? ? object.list : pages[i].instance_variable_get(:@list)
304
345
  next if list.nil?
305
346
 
306
347
  in_sequence = false
307
348
  line = []
308
349
 
309
350
  list.each do |item|
310
- code = item.instance_variable_get(:@code)
311
- parameters = item.instance_variable_get(:@parameters)
351
+ code = item.code
352
+
353
+ unless allowed_codes.include?(code)
354
+ if in_sequence
355
+ joined = line.join('\#').strip
356
+
357
+ other_translation_map.insert_at_index(other_lines.length, joined, '') if inner_processing_type == :append &&
358
+ !other_translation_map.include?(joined)
359
+
360
+ other_lines.add(joined)
361
+
362
+ line.clear
363
+ in_sequence = false
364
+ end
365
+ next
366
+ end
312
367
 
368
+ parameters = item.parameters
313
369
  parameters.each do |parameter|
314
370
  if [401, 405].include?(code)
371
+ next unless parameter.is_a?(String) && !parameter.empty?
372
+
315
373
  in_sequence = true
316
- line.push(parameter.gsub(/\r?\n/, '\#')) if parameter.is_a?(String) && !parameter.empty?
374
+ line.push(parameter.gsub(/\r?\n/, '\#'))
317
375
  else
318
- if in_sequence
319
- joined = line.join('\#')
320
-
321
- if internal_processing_type == 'append' && !other_translation_map.include?(joined)
322
- insert_at_index(other_translation_map, other_lines.length, joined, '')
323
- end
324
-
325
- other_lines.add(joined)
326
-
327
- line.clear
328
- in_sequence = false
329
- end
330
376
 
331
377
  case code
332
378
  when 102
333
379
  if parameter.is_a?(Array)
334
380
  parameter.each do |subparameter|
335
- if subparameter.is_a?(String) && !subparameter.empty?
336
- if internal_processing_type == 'append' && !other_translation_map.include?(subparameter)
337
- insert_at_index(other_translation_map, other_lines.length, subparameter, '')
338
- end
381
+ next unless subparameter.is_a?(String)
382
+
383
+ subparameter = subparameter.strip
384
+ next if subparameter.empty?
385
+
386
+ other_translation_map.insert_at_index(other_lines.length, subparameter, '') if inner_processing_type == :append &&
387
+ !other_translation_map.include?(subparameter)
339
388
 
340
- other_lines.add(subparameter)
341
- end
389
+ other_lines.add(subparameter)
342
390
  end
343
391
  end
344
392
  when 356
345
- if parameter.is_a?(String) && !parameter.empty?
346
- subbed = parameter.gsub(/\r?\n/, '\#')
393
+ next unless parameter.is_a?(String)
347
394
 
348
- if internal_processing_type == 'append'
349
- insert_at_index(other_translation_map, other_lines.length, subbed, '')
350
- end
395
+ parameter = parameter.strip
396
+ next if parameter.empty?
351
397
 
352
- other_lines.add(subbed)
353
- end
398
+ parameter = parameter.gsub(/\r?\n/, '\#')
399
+
400
+ other_translation_map.insert_at_index(other_lines.length, parameter, '') if inner_processing_type == :append &&
401
+ !other_translation_map.include?(parameter)
402
+
403
+ other_lines.add(parameter)
354
404
  else
355
405
  nil
356
406
  end
@@ -363,10 +413,12 @@ def self.read_other(other_files, output_path, logging, game_type, processing_typ
363
413
 
364
414
  puts "Parsed #{filename}" if logging
365
415
 
366
- original_content, translated_content = if processing_type == 'append'
367
- [other_translation_map.keys.join("\n"), other_translation_map.values.join("\n")]
416
+ original_content, translated_content = if processing_type == :append
417
+ [other_translation_map.keys.join("\n"),
418
+ other_translation_map.values.join("\n")]
368
419
  else
369
- [other_lines.join("\n"), "\n" * (other_lines.empty? ? 0 : other_lines.length - 1)]
420
+ [other_lines.join("\n"),
421
+ "\n" * (other_lines.empty? ? 0 : other_lines.length - 1)]
370
422
  end
371
423
 
372
424
  File.binwrite(other_output_path, original_content)
@@ -374,24 +426,30 @@ def self.read_other(other_files, output_path, logging, game_type, processing_typ
374
426
  end
375
427
  end
376
428
 
377
- def self.read_system(system_file_path, ini_file_path, output_path, logging, processing_type)
378
- def self.read_ini_title(ini_file_path)
379
- file_lines = File.readlines(ini_file_path, chomp: true)
380
- file_lines.each do |line|
381
- if line.start_with?('title')
382
- parts = line.partition('=')
383
- break parts[2].strip
384
- end
429
+ # @param [String] ini_file_path
430
+ def self.read_ini_title(ini_file_path)
431
+ file_lines = File.readlines(ini_file_path, chomp: true)
432
+ file_lines.each do |line|
433
+ if line.downcase.start_with?('title')
434
+ parts = line.partition('=')
435
+ break parts[2].strip
385
436
  end
386
437
  end
438
+ end
387
439
 
440
+ # @param [String] system_file_path
441
+ # @param [String] ini_file_path
442
+ # @param [String] output_path
443
+ # @param [Boolean] logging
444
+ # @param [String] processing_type
445
+ def self.read_system(system_file_path, ini_file_path, output_path, logging, processing_type)
388
446
  system_filename = File.basename(system_file_path)
389
447
  system_basename = File.basename(system_file_path, '.*').downcase
390
448
 
391
449
  system_output_path = File.join(output_path, "#{system_basename}.txt")
392
450
  system_trans_output_path = File.join(output_path, "#{system_basename}_trans.txt")
393
451
 
394
- if processing_type == 'default' && File.exist?(system_trans_output_path)
452
+ if processing_type == :default && File.exist?(system_trans_output_path)
395
453
  puts 'system_trans.txt file already exists. If you want to forcefully re-read all files, use --force flag, or --append if you want append new text to already existing files.'
396
454
  return
397
455
  end
@@ -401,52 +459,60 @@ def self.read_system(system_file_path, ini_file_path, output_path, logging, proc
401
459
  system_lines = IndexSet.new
402
460
  system_translation_map = nil
403
461
 
404
- if processing_type == 'append'
462
+ if processing_type == :append
405
463
  if File.exist?(system_trans_output_path)
406
- system_translation_map = Hash[File.readlines(system_output_path, chomp: true).zip(File.readlines(system_trans_output_path, chomp: true))]
464
+ system_translation_map = Hash[File.readlines(system_output_path, chomp: true)
465
+ .zip(File.readlines(system_trans_output_path, chomp: true))]
407
466
  else
408
467
  puts "Files aren't already parsed. Continuing as if --append flag was omitted."
409
- processing_type = 'default'
468
+ processing_type = :default
410
469
  end
411
470
  end
412
471
 
413
- elements = system_object.instance_variable_get(:@elements)
414
- skill_types = system_object.instance_variable_get(:@skill_types)
415
- weapon_types = system_object.instance_variable_get(:@weapon_types)
416
- armor_types = system_object.instance_variable_get(:@armor_types)
417
- currency_unit = system_object.instance_variable_get(:@currency_unit)
418
- terms = system_object.instance_variable_get(:@terms) || system_object.instance_variable_get(:@words)
472
+ elements = system_object.elements
473
+ skill_types = system_object.skill_types
474
+ weapon_types = system_object.weapon_types
475
+ armor_types = system_object.armor_types
476
+ currency_unit = system_object.currency_unit
477
+ terms = system_object.terms || system_object.words
419
478
 
420
479
  [elements, skill_types, weapon_types, armor_types].each do |array|
421
480
  next if array.nil?
422
481
 
423
482
  array.each do |string|
424
- if string.is_a?(String) && !string.empty?
425
- if processing_type == 'append' && !system_translation_map.include?(string)
426
- insert_at_index(system_translation_map, system_lines.length, string, '')
427
- end
483
+ next unless string.is_a?(String)
428
484
 
429
- system_lines.add(string)
430
- end
485
+ string = string.strip
486
+
487
+ next if string.empty?
488
+
489
+ system_translation_map.insert_at_index(system_lines.length, string, '') if processing_type == :append &&
490
+ !system_translation_map.include?(string)
491
+
492
+ system_lines.add(string)
431
493
  end
432
494
  end
433
495
 
434
- if currency_unit.is_a?(String) && !currency_unit.empty?
435
- if processing_type == 'append' && !system_translation_map.include?(currency_unit)
436
- insert_at_index(system_translation_map, system_lines.length, currency_unit, '')
437
- end
496
+ if currency_unit.is_a?(String)
497
+ currency_unit = currency_unit.strip
498
+
499
+ unless currency_unit.empty?
500
+ system_translation_map.insert_at_index(system_lines.length, currency_unit, '') if processing_type == :append &&
501
+ !system_translation_map.include?(currency_unit)
438
502
 
439
- system_lines.add(currency_unit)
503
+ system_lines.add(currency_unit)
504
+ end
440
505
  end
441
506
 
442
507
  terms.instance_variables.each do |variable|
443
508
  value = terms.instance_variable_get(variable)
444
509
 
445
510
  if value.is_a?(String)
511
+ value = value.strip
512
+
446
513
  unless value.empty?
447
- if processing_type == 'append' && !system_translation_map.include?(value)
448
- insert_at_index(system_translation_map, system_lines.length, value, '')
449
- end
514
+ system_translation_map.insert_at_index(system_lines.length, value, '') if processing_type == :append &&
515
+ !system_translation_map.include?(value)
450
516
 
451
517
  system_lines.add(value)
452
518
  end
@@ -455,39 +521,46 @@ def self.read_system(system_file_path, ini_file_path, output_path, logging, proc
455
521
  end
456
522
 
457
523
  value.each do |string|
458
- if string.is_a?(String) && !string.empty?
459
- if processing_type == 'append' && !system_translation_map.include?(string)
460
- insert_at_index(system_translation_map, system_lines.length, string, '')
461
- end
524
+ next unless string.is_a?(String)
462
525
 
463
- system_lines.add(string)
464
- end
526
+ string = string.strip
527
+
528
+ next if string.empty?
529
+
530
+ system_translation_map.insert_at_index(system_lines.length, string, '') if processing_type == :append &&
531
+ !system_translation_map.include?(string)
532
+
533
+ system_lines.add(string)
465
534
  end
466
535
  end
467
536
 
468
537
  # Game title from System file and ini file may differ, but requesting user request to determine which line do they want is LAME
469
538
  # So just throw that ini ass and continue
470
- _game_title = system_object.instance_variable_get(:@game_title)
471
- ini_game_title = read_ini_title(ini_file_path)
539
+ ini_game_title = read_ini_title(ini_file_path).strip
472
540
 
473
- if processing_type == 'append' && !system_translation_map.include?(ini_game_title)
474
- insert_at_index(system_translation_map, system_lines.length, ini_game_title, '')
475
- end
541
+ system_translation_map.insert_at_index(system_lines.length, ini_game_title, '') if processing_type == :append &&
542
+ !system_translation_map.include?(ini_game_title)
476
543
 
477
544
  system_lines.add(ini_game_title)
478
545
 
479
546
  puts "Parsed #{system_filename}" if logging
480
547
 
481
- original_content, translated_content = if processing_type == 'append'
482
- [system_translation_map.keys.join("\n"), system_translation_map.values.join("\n")]
548
+ original_content, translated_content = if processing_type == :append
549
+ [system_translation_map.keys.join("\n"),
550
+ system_translation_map.values.join("\n")]
483
551
  else
484
- [system_lines.join("\n"), "\n" * (system_lines.empty? ? 0 : system_lines.length - 1)]
552
+ [system_lines.join("\n"),
553
+ "\n" * (system_lines.empty? ? 0 : system_lines.length - 1)]
485
554
  end
486
555
 
487
556
  File.binwrite(system_output_path, original_content)
488
557
  File.binwrite(system_trans_output_path, translated_content)
489
558
  end
490
559
 
560
+ # @param [String] scripts_file_path
561
+ # @param [String] output_path
562
+ # @param [Boolean] logging
563
+ # @param [String] processing_type
491
564
  def self.read_scripts(scripts_file_path, output_path, logging, processing_type)
492
565
  scripts_filename = File.basename(scripts_file_path)
493
566
  scripts_basename = File.basename(scripts_file_path, '.*').downcase
@@ -496,7 +569,7 @@ def self.read_scripts(scripts_file_path, output_path, logging, processing_type)
496
569
  scripts_output_path = File.join(output_path, "#{scripts_basename}.txt")
497
570
  scripts_trans_output_path = File.join(output_path, "#{scripts_basename}_trans.txt")
498
571
 
499
- if processing_type == 'default' && File.exist?(scripts_trans_output_path)
572
+ if processing_type == :default && File.exist?(scripts_trans_output_path)
500
573
  puts 'scripts_trans.txt file already exists. If you want to forcefully re-read all files, use --force flag, or --append if you want append new text to already existing files.'
501
574
  return
502
575
  end
@@ -506,58 +579,67 @@ def self.read_scripts(scripts_file_path, output_path, logging, processing_type)
506
579
  scripts_lines = IndexSet.new
507
580
  scripts_translation_map = nil
508
581
 
509
- if processing_type == 'append'
582
+ if processing_type == :append
510
583
  if File.exist?(scripts_trans_output_path)
511
- scripts_translation_map = Hash[File.readlines(scripts_output_path, chomp: true).zip(File.readlines(scripts_trans_output_path, chomp: true))]
584
+ scripts_translation_map = Hash[File.readlines(scripts_output_path, chomp: true)
585
+ .zip(File.readlines(scripts_trans_output_path, chomp: true))]
512
586
  else
513
587
  puts "Files aren't already parsed. Continuing as if --append flag was omitted."
514
- processing_type = 'default'
588
+ processing_type = :default
515
589
  end
516
590
  end
517
591
 
518
592
  codes_content = []
519
593
 
594
+ # This code was fun before `that` game used Windows-1252 degree symbol
520
595
  script_entries.each do |script|
521
596
  code = Zlib::Inflate.inflate(script[2]).force_encoding('UTF-8')
522
- codes_content.push(code)
597
+ # we're fucking cloning because of encoding issue
598
+ codes_content.push(code.clone)
599
+
600
+ unless code.valid_encoding?
601
+ # who the fuck uses the degree symbol from FUCKING WINDOWS-1252 and NOT UTF-8
602
+ # also, String#encode does NOT FUCKING WORK and for some reason raises on the
603
+ # fucking degree symbol from windows-1252 when trying to encode
604
+ code.force_encoding('Windows-1252')
605
+ end
523
606
 
524
- extract_quoted_strings(code).each_key do |string|
525
- string.strip!
607
+ raise unless code.valid_encoding?
526
608
 
609
+ extract_quoted_strings(code).each do |string|
527
610
  # Removes the U+3000 Japanese typographical space to check if string, when stripped, is truly empty
528
- next if string.empty? || string.gsub(' ', '').empty?
611
+ string = string.strip.delete(' ')
612
+
613
+ next if string.empty?
529
614
 
530
615
  # Maybe this mess will remove something that mustn't be removed, but it needs to be tested
531
616
  next if string.start_with?(/([#!?$@]|(\.\/)?(Graphics|Data|Audio|CG|Movies|Save)\/)/) ||
617
+ string.match(/^[^\p{L}]+$/) ||
532
618
  string.match?(/^\d+$/) ||
619
+ string.match?(/%.*(\d|\+|\*)d\]?:?$/) ||
620
+ string.match?(/^\[(ON|OFF)\]$/) ||
621
+ string.match?(/^\[\]$/) ||
533
622
  string.match?(/^(.)\1{2,}$/) ||
534
623
  string.match?(/^(false|true)$/) ||
535
624
  string.match?(/^[wr]b$/) ||
536
625
  string.match?(/^(?=.*\d)[A-Za-z0-9\-]+$/) ||
537
- string.match?(/^[A-Z\-()\/ +'&]*$/) ||
538
626
  string.match?(/^[a-z\-()\/ +'&]*$/) ||
539
627
  string.match?(/^[A-Za-z]+[+-]$/) ||
540
628
  string.match?(/^[.()+-:;\[\]^~%&!*\/→×??x%▼|]$/) ||
541
629
  string.match?(/^Tile.*[A-Z]$/) ||
542
- string.match?(/^:?%.*[ds][:%]*?$/) ||
543
- string.match?(/^[a-zA-Z]+([A-Z][a-z]*)+$/) ||
630
+ string.match?(/^[a-zA-Z][a-z]+([A-Z][a-z]*)+$/) ||
544
631
  string.match?(/^Cancel Action$|^Invert$|^End$|^Individual$|^Missed File$|^Bitmap$|^Audio$/) ||
545
- string.match?(/\.(mp3|ogg|jpg|png|ini)$/) ||
632
+ string.match?(/\.(mp3|ogg|jpg|png|ini|txt)$/i) ||
546
633
  string.match?(/\/(\d.*)?$/) ||
547
634
  string.match?(/FILE$/) ||
548
635
  string.match?(/#\{/) ||
549
- string.match?(/\\(?!#)/) ||
636
+ string.match?(/(?<!\\)\\(?![\\G#])/) ||
550
637
  string.match?(/\+?=?=/) ||
551
638
  string.match?(/[}{_<>]/) ||
552
639
  string.match?(/r[vx]data/) ||
553
640
  string.match?(/No such file or directory/) ||
554
641
  string.match?(/level \*\*/) ||
555
- string.match?(/Courier New/) ||
556
- string.match?(/Comic Sans/) ||
557
- string.match?(/Lucida/) ||
558
- string.match?(/Verdana/) ||
559
- string.match?(/Tahoma/) ||
560
- string.match?(/Arial/) ||
642
+ string.match?(/Courier New|Comic Sans|Lucida|Verdana|Tahoma|Arial|Times New Roman/) ||
561
643
  string.match?(/Player start location/) ||
562
644
  string.match?(/Common event call has exceeded/) ||
563
645
  string.match?(/se-/) ||
@@ -570,9 +652,8 @@ def self.read_scripts(scripts_file_path, output_path, logging, processing_type)
570
652
  string.match?(/Clear image/) ||
571
653
  string.match?(/Can Collapse/)
572
654
 
573
- if processing_type == 'append' && !scripts_translation_map.include?(string)
574
- insert_at_index(scripts_translation_map, scripts_lines.length, string, '')
575
- end
655
+ scripts_translation_map.insert_at_index(scripts_lines.length, string, '') if processing_type == :append &&
656
+ !scripts_translation_map.include?(string)
576
657
 
577
658
  scripts_lines.add(string)
578
659
  end
@@ -582,10 +663,12 @@ def self.read_scripts(scripts_file_path, output_path, logging, processing_type)
582
663
 
583
664
  File.binwrite(scripts_plain_output_path, codes_content.join("\n"))
584
665
 
585
- original_content, translated_content = if processing_type == 'append'
586
- [scripts_translation_map.keys.join("\n"), scripts_translation_map.values.join("\n")]
666
+ original_content, translated_content = if processing_type == :append
667
+ [scripts_translation_map.keys.join("\n"),
668
+ scripts_translation_map.values.join("\n")]
587
669
  else
588
- [scripts_lines.join("\n"), "\n" * (scripts_lines.empty? ? 0 : scripts_lines.length - 1)]
670
+ [scripts_lines.join("\n"),
671
+ "\n" * (scripts_lines.empty? ? 0 : scripts_lines.length - 1)]
589
672
  end
590
673
 
591
674
  File.binwrite(scripts_output_path, original_content)