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