R3EXS 1.0.4 → 1.1.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/CHANGELOG.md +12 -0
- data/README.md +260 -260
- data/README_EN.md +260 -260
- data/bin/R3EXS +10 -16
- data/ext/rgss3a_rvdata2/rgss3a_rvdata2.c +616 -616
- data/lib/R3EXS/RGSS3.rb +1456 -1456
- data/lib/R3EXS/RGSS3_R3EXS.rb +18 -11
- data/lib/R3EXS/ast.rb +12 -17
- data/lib/R3EXS/error.rb +1 -18
- data/lib/R3EXS/extract_strings.rb +76 -79
- data/lib/R3EXS/inject_strings.rb +37 -36
- data/lib/R3EXS/json_rvdata2.rb +115 -104
- data/lib/R3EXS/rvdata2_json.rb +47 -17
- data/lib/R3EXS/utils.rb +1080 -970
- data/lib/R3EXS/version.rb +1 -1
- metadata +5 -5
data/lib/R3EXS/RGSS3_R3EXS.rb
CHANGED
@@ -583,13 +583,14 @@ module R3EXS
|
|
583
583
|
@index = -1
|
584
584
|
end
|
585
585
|
when 205 # SetMoveRoute
|
586
|
-
@index = index
|
587
|
-
@code = 205
|
588
|
-
@usage = Utils::EVENT_COMMANDS[205]
|
589
586
|
moveroute_r3exs = R3EXS::MoveRoute.new(eventcommand.parameters[1])
|
590
|
-
|
591
|
-
|
592
|
-
|
587
|
+
if moveroute_r3exs.empty?
|
588
|
+
@index = -1 # 如果 MoveRoute 里面没有可提取的 MoveCommand ,就将索引设为-1,empty? 将据此判断是否为空
|
589
|
+
else
|
590
|
+
@index = index
|
591
|
+
@code = 205
|
592
|
+
@usage = Utils::EVENT_COMMANDS[205]
|
593
|
+
@parameter = moveroute_r3exs
|
593
594
|
end
|
594
595
|
when 320 # ChangeActorName
|
595
596
|
@index = index
|
@@ -627,13 +628,14 @@ module R3EXS
|
|
627
628
|
@usage = Utils::EVENT_COMMANDS[408]
|
628
629
|
@parameter = eventcommand.parameters[0]
|
629
630
|
when 505 # MoveRoute
|
630
|
-
|
631
|
+
movecommand_r3exs = R3EXS::MoveCommand.new(eventcommand.parameters[0], 0)
|
632
|
+
if movecommand_r3exs.empty?
|
633
|
+
@index = -1
|
634
|
+
else
|
631
635
|
@index = index
|
632
636
|
@code = 505
|
633
637
|
@usage = Utils::EVENT_COMMANDS[505]
|
634
|
-
@parameter =
|
635
|
-
else
|
636
|
-
@index = -1
|
638
|
+
@parameter = movecommand_r3exs
|
637
639
|
end
|
638
640
|
when 655 # ScriptMore
|
639
641
|
@index = index
|
@@ -684,7 +686,7 @@ module R3EXS
|
|
684
686
|
when 408 # CommentMore
|
685
687
|
eventcommand.parameters[0] = @parameter
|
686
688
|
when 505 # MoveRoute
|
687
|
-
eventcommand.parameters[0]
|
689
|
+
@parameter.inject_to(eventcommand.parameters[0])
|
688
690
|
when 655 # ScriptMore
|
689
691
|
eventcommand.parameters[0] = @parameter
|
690
692
|
else
|
@@ -703,6 +705,8 @@ module R3EXS
|
|
703
705
|
[@parameter]
|
704
706
|
when 205
|
705
707
|
@parameter.ex_strings
|
708
|
+
when 505
|
709
|
+
@parameter.ex_strings
|
706
710
|
else
|
707
711
|
puts "Unknown code: #{@code}"
|
708
712
|
[]
|
@@ -721,6 +725,8 @@ module R3EXS
|
|
721
725
|
@parameter = hash[@parameter] || @parameter
|
722
726
|
when 205
|
723
727
|
@parameter.in_strings(hash)
|
728
|
+
when 505
|
729
|
+
@parameter.in_strings(hash)
|
724
730
|
else
|
725
731
|
puts "Unknown code: #{@code}"
|
726
732
|
end
|
@@ -751,6 +757,7 @@ module R3EXS
|
|
751
757
|
# 事件指令参数
|
752
758
|
#
|
753
759
|
# @note 当 '@code' 为 102 时, parameter 是一个字符串数组
|
760
|
+
#
|
754
761
|
# @return [String] if @code != 102
|
755
762
|
# @return [Array<String>] if @code == 102
|
756
763
|
attr_accessor :parameter
|
data/lib/R3EXS/ast.rb
CHANGED
@@ -95,8 +95,8 @@ module R3EXS
|
|
95
95
|
def visit_string_node(node)
|
96
96
|
location = node.content_loc
|
97
97
|
value = location.slice
|
98
|
-
if @strings_hash.has_key?(value)
|
99
|
-
@content_loc << Location.new(location.start_offset, location.length,
|
98
|
+
if @strings_hash.has_key?(value) && @strings_hash[value].to_s != ''
|
99
|
+
@content_loc << Location.new(location.start_offset, location.length, value)
|
100
100
|
end
|
101
101
|
super
|
102
102
|
end
|
@@ -110,24 +110,19 @@ module R3EXS
|
|
110
110
|
# 如果 location 不为 nil,说明这个符号是一个字符串
|
111
111
|
if location
|
112
112
|
value = location.slice
|
113
|
-
if @strings_hash.has_key?(value)
|
114
|
-
@content_loc << Location.new(location.start_offset, location.length,
|
113
|
+
if @strings_hash.has_key?(value) && @strings_hash[value].to_s != ''
|
114
|
+
@content_loc << Location.new(location.start_offset, location.length, value)
|
115
115
|
end
|
116
116
|
end
|
117
117
|
super
|
118
118
|
end
|
119
119
|
|
120
|
-
# 将
|
120
|
+
# 将 script 源码中的字符串替换成 @strings_hash 翻译后的字符串
|
121
121
|
#
|
122
|
-
# @param
|
122
|
+
# @param script [String] Ruby 源码,以二进制编码打开
|
123
123
|
# @param ast_root [Prism::ProgramNode] AST 树根节点
|
124
124
|
# @return [String]
|
125
|
-
def rewrite(
|
126
|
-
# 读取文件内容
|
127
|
-
# 这里必须使用 rb 模式,因为 Prism 定位的位置是二进制下的位置
|
128
|
-
# 也就是说没有考虑换行符的问题,所以必须使用二进制模式读取文件
|
129
|
-
code = File.read(file_path, mode: 'rb')
|
130
|
-
|
125
|
+
def rewrite(script, ast_root)
|
131
126
|
# 首先遍历一遍,找到所有需要替换的字符串的位置
|
132
127
|
visit(ast_root)
|
133
128
|
|
@@ -138,14 +133,14 @@ module R3EXS
|
|
138
133
|
# 然后将 code 切片,将字符串替换成新的字符串
|
139
134
|
start_offset = 0
|
140
135
|
@content_loc.each do |loc|
|
141
|
-
@code <<
|
142
|
-
@code << loc.content
|
136
|
+
@code << script[start_offset...loc.start_offset]
|
137
|
+
@code << @strings_hash[loc.content]
|
143
138
|
start_offset = loc.start_offset + loc.length
|
144
139
|
end
|
145
|
-
@code <<
|
140
|
+
@code << script[start_offset..-1]
|
146
141
|
|
147
|
-
# 将 @code
|
148
|
-
@code.map! { |str| str.force_encoding('
|
142
|
+
# 将 @code 里面的字符串全部改为二进制编码
|
143
|
+
@code.map! { |str| str.force_encoding('ASCII-8BIT') unless str.nil? }
|
149
144
|
@code.join
|
150
145
|
end
|
151
146
|
|
data/lib/R3EXS/error.rb
CHANGED
@@ -101,7 +101,7 @@ module R3EXS
|
|
101
101
|
# 引发异常的 json 文件路径
|
102
102
|
#
|
103
103
|
# @return [String]
|
104
|
-
attr_reader :
|
104
|
+
attr_reader :json_path
|
105
105
|
end
|
106
106
|
|
107
107
|
# 用来处理模块名错误的异常
|
@@ -172,23 +172,6 @@ module R3EXS
|
|
172
172
|
attr_reader :json_dir
|
173
173
|
end
|
174
174
|
|
175
|
-
# 用来处理 *.rb 文件目录不存在的异常
|
176
|
-
class ScriptsDirError < IOError
|
177
|
-
|
178
|
-
# @param msg [String] 异常信息
|
179
|
-
# @param scripts_dir [String] 引发异常的 *.rb 文件目录
|
180
|
-
# @return [ScriptsDirError]
|
181
|
-
def initialize(msg = '', scripts_dir)
|
182
|
-
super(msg)
|
183
|
-
@scripts_dir = scripts_dir
|
184
|
-
end
|
185
|
-
|
186
|
-
# 引发异常的 *.rb 文件目录
|
187
|
-
#
|
188
|
-
# @return [String]
|
189
|
-
attr_reader :scripts_dir
|
190
|
-
end
|
191
|
-
|
192
175
|
# 用来处理 Scripts_info.json 文件不存在的异常
|
193
176
|
class ScriptsInfoPathError < IOError
|
194
177
|
|
@@ -1,80 +1,77 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'zlib'
|
4
|
-
require_relative 'ast'
|
5
|
-
require_relative 'utils'
|
6
|
-
require_relative 'RGSS3_R3EXS'
|
7
|
-
|
8
|
-
module R3EXS
|
9
|
-
|
10
|
-
#
|
11
|
-
#
|
12
|
-
# @param target_dir [
|
13
|
-
# @param
|
14
|
-
#
|
15
|
-
# @
|
16
|
-
#
|
17
|
-
#
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
-
Utils.object_json(all_ex_strings.each_with_object({}) { |item, h| h[item] = item }, File.join(output_dir, "ManualTransFile.json"))
|
78
|
-
end
|
79
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'zlib'
|
4
|
+
require_relative 'ast'
|
5
|
+
require_relative 'utils'
|
6
|
+
require_relative 'RGSS3_R3EXS'
|
7
|
+
|
8
|
+
module R3EXS
|
9
|
+
|
10
|
+
# 将指定目录下的所有已经序列化为 R3EXS 后的 JOSN 文件中的字符串提取出来
|
11
|
+
#
|
12
|
+
# @param target_dir [Pathname] 目标目录
|
13
|
+
# @param output_dir [Pathname] 输出目录
|
14
|
+
# @param with_scripts [Boolean] 是否包含脚本
|
15
|
+
# @param with_symbol [Boolean] 是否包含脚本中的符号
|
16
|
+
# @param with_scripts_separate [Boolean] 是否将脚本提取的字符串单独存放
|
17
|
+
#
|
18
|
+
# @raise [R3EXSJsonFileError] json 文件不是 R3EXS 模块中的对象
|
19
|
+
# @raise [JsonDirError] target_dir 不存在
|
20
|
+
#
|
21
|
+
# @return [void]
|
22
|
+
def R3EXS.ex_strings(target_dir, output_dir, with_scripts, with_symbol, with_scripts_separate)
|
23
|
+
all_ex_strings = []
|
24
|
+
|
25
|
+
# 处理常规的 JSON 文件
|
26
|
+
Utils.all_json_files(target_dir, :R3EXS) do |object, file_basename, parent_relative_dir|
|
27
|
+
file_path = target_dir.join(parent_relative_dir, "#{file_basename}.json")
|
28
|
+
print "#{Utils::ESCAPE}#{Utils::MAGENTA_COLOR}Extracting from #{Utils::RESET_COLOR}#{file_path}...\r" if $global_options[:verbose]
|
29
|
+
if object.is_a?(Array)
|
30
|
+
object.each do |obj|
|
31
|
+
all_ex_strings.concat(obj.ex_strings)
|
32
|
+
end
|
33
|
+
else
|
34
|
+
all_ex_strings.concat(object.ex_strings)
|
35
|
+
end
|
36
|
+
print "#{Utils::ESCAPE}#{Utils::GREEN_COLOR}Extracted #{Utils::RESET_COLOR}#{file_path}\n" if $global_options[:verbose]
|
37
|
+
end
|
38
|
+
|
39
|
+
# 处理 CommonEvent_\d{5}.json 文件
|
40
|
+
Utils.all_commonevent_json_files(target_dir, :R3EXS) do |commonevents, commonevents_basenames, parent_relative_dir|
|
41
|
+
commonevents.zip(commonevents_basenames).each do |commonevent, commonevent_basename|
|
42
|
+
file_path = target_dir.join(parent_relative_dir, "#{commonevent_basename}.json")
|
43
|
+
print "#{Utils::ESCAPE}#{Utils::MAGENTA_COLOR}Extracting from #{Utils::RESET_COLOR}#{file_path}...\r" if $global_options[:verbose]
|
44
|
+
all_ex_strings.concat(commonevent.ex_strings)
|
45
|
+
print "#{Utils::ESCAPE}#{Utils::GREEN_COLOR}Extracted #{Utils::RESET_COLOR}#{file_path}\n" if $global_options[:verbose]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# 处理 \d{5}.rb 文件
|
50
|
+
if with_scripts
|
51
|
+
all_rb_strings = []
|
52
|
+
strings_extractor = StringsExtractor.new(all_rb_strings, with_symbol)
|
53
|
+
|
54
|
+
Utils.all_rb_files(target_dir) do |scripts, scripts_basenames, parent_relative_dir|
|
55
|
+
scripts.zip(scripts_basenames).each do |script, script_basename|
|
56
|
+
file_path = target_dir.join(parent_relative_dir, "#{script_basename}.rb")
|
57
|
+
print "#{Utils::ESCAPE}#{Utils::MAGENTA_COLOR}Extracting from #{Utils::RESET_COLOR}#{file_path}...\r" if $global_options[:verbose]
|
58
|
+
strings_extractor.visit(Prism.parse(script).value)
|
59
|
+
print "#{Utils::ESCAPE}#{Utils::GREEN_COLOR}Extracted #{Utils::RESET_COLOR}#{file_path}\n" if $global_options[:verbose]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
if with_scripts_separate
|
64
|
+
# 去除 nil 元素
|
65
|
+
all_rb_strings.compact!
|
66
|
+
Utils.object_json(all_rb_strings.each_with_object({}) { |item, h| h[item] = item }, output_dir.join('ManualTransFile_scripts.json'))
|
67
|
+
else
|
68
|
+
all_ex_strings.concat(all_rb_strings)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# 去除 nil 元素
|
73
|
+
all_ex_strings.compact!
|
74
|
+
Utils.object_json(all_ex_strings.each_with_object({}) { |item, h| h[item] = item }, output_dir.join('ManualTransFile.json'))
|
75
|
+
end
|
76
|
+
|
80
77
|
end
|
data/lib/R3EXS/inject_strings.rb
CHANGED
@@ -7,52 +7,27 @@ require_relative 'RGSS3_R3EXS'
|
|
7
7
|
|
8
8
|
module R3EXS
|
9
9
|
|
10
|
-
# 将 Ruby 源码中的字符串和符号替换为指定的字符串
|
11
|
-
#
|
12
|
-
# @param target_dir [String] 目标目录
|
13
|
-
# @param output_dir [String] 输出目录
|
14
|
-
# @param hash [Hash]
|
15
|
-
#
|
16
|
-
# @raise [ScriptsDirError] Scripts 目录不存在
|
17
|
-
#
|
18
|
-
# @return [void]
|
19
|
-
def R3EXS.rb_in_strings(target_dir, output_dir, hash)
|
20
|
-
target_full_dir = File.join(target_dir, 'Scripts')
|
21
|
-
output_full_dir = File.join(output_dir, 'Scripts')
|
22
|
-
FileUtils.mkdir(output_full_dir) unless Dir.exist?(output_full_dir)
|
23
|
-
Dir.exist?(target_full_dir) or raise ScriptsDirError.new(target_full_dir), "Scripts directory not found: #{target_full_dir}"
|
24
|
-
|
25
|
-
Dir.glob(File.join(target_full_dir, "*.rb")).each do |script_file_path|
|
26
|
-
output_script_file_dir = File.join(output_full_dir, File.basename(script_file_path))
|
27
|
-
print "#{Utils::ESCAPE}#{Utils::MAGENTA_COLOR}Injecting to #{Utils::RESET_COLOR}#{output_script_file_dir}...\r" if $global_options[:verbose]
|
28
|
-
|
29
|
-
File.write(output_script_file_dir, StringsInjector.new(hash).rewrite(script_file_path, Prism.parse_file(script_file_path).value), mode: 'w')
|
30
|
-
|
31
|
-
print "#{Utils::ESCAPE}#{Utils::GREEN_COLOR}Injected #{Utils::RESET_COLOR}#{output_script_file_dir}\n" if $global_options[:verbose]
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
10
|
# 将指定目录下的所有已经序列化为 R3EXS 后的 JOSN 文件按照 ManualTransFile.json 翻译注入
|
36
11
|
#
|
37
|
-
# @param target_dir [
|
38
|
-
# @param output_dir [
|
39
|
-
# @param manualtransfile_path [
|
12
|
+
# @param target_dir [Pathname] 目标目录
|
13
|
+
# @param output_dir [Pathname] 输出目录
|
14
|
+
# @param manualtransfile_path [Pathname] ManualTransFile.json 文件路径
|
40
15
|
# @param with_scripts [Boolean] 是否包含脚本
|
41
16
|
#
|
42
17
|
# @raise [R3EXSJsonFileError] json 文件不是 R3EXS 模块中的对象
|
43
18
|
# @raise [JsonDirError] target_dir 不存在
|
44
|
-
# @raise [
|
19
|
+
# @raise [ScriptsInfoPathError] Scripts_info.json 文件不存在
|
45
20
|
# @raise [ManualTransFilePath] ManualTransFile.json 不存在
|
46
21
|
#
|
47
22
|
# @return [void]
|
48
23
|
def R3EXS.in_strings(target_dir, output_dir, manualtransfile_path, with_scripts)
|
49
|
-
|
50
|
-
File.exist?(manualtransfile_path) or raise ManualTransFilePathError.new(manualtransfile_path), "ManualTransFile.json not found: #{manualtransfile_path}"
|
24
|
+
manualtransfile_path.exist? or raise ManualTransFilePathError.new(manualtransfile_path.to_s), "ManualTransFile.json not found: #{manualtransfile_path}"
|
51
25
|
|
52
|
-
manual_trans_hash = Oj.load_file(manualtransfile_path)
|
26
|
+
manual_trans_hash = Oj.load_file(manualtransfile_path.to_s)
|
53
27
|
|
54
|
-
|
55
|
-
|
28
|
+
# 处理常规的 JSON 文件
|
29
|
+
Utils.all_json_files(target_dir, :R3EXS) do |object, file_basename, parent_relative_dir|
|
30
|
+
file_path = output_dir.join(parent_relative_dir, "#{file_basename}.json")
|
56
31
|
print "#{Utils::ESCAPE}#{Utils::MAGENTA_COLOR}Injecting to #{Utils::RESET_COLOR}#{file_path}...\r" if $global_options[:verbose]
|
57
32
|
if object.is_a?(Array)
|
58
33
|
object.each do |obj|
|
@@ -62,11 +37,37 @@ module R3EXS
|
|
62
37
|
object.in_strings(manual_trans_hash)
|
63
38
|
end
|
64
39
|
Utils.object_json(object, file_path)
|
65
|
-
print "#{Utils::ESCAPE}#{Utils::GREEN_COLOR}Injected #{Utils::RESET_COLOR}#{
|
40
|
+
print "#{Utils::ESCAPE}#{Utils::GREEN_COLOR}Injected #{Utils::RESET_COLOR}#{file_path}\n" if $global_options[:verbose]
|
41
|
+
end
|
42
|
+
|
43
|
+
# 处理 CommonEvent_\d{5}.json 文件
|
44
|
+
Utils.all_commonevent_json_files(target_dir, :R3EXS) do |commonevents, commonevents_basenames, parent_relative_dir|
|
45
|
+
commonevents.zip(commonevents_basenames).each do |commonevent, commonevent_basename|
|
46
|
+
file_path = output_dir.join(parent_relative_dir, "#{commonevent_basename}.json")
|
47
|
+
print "#{Utils::ESCAPE}#{Utils::MAGENTA_COLOR}Injecting to #{Utils::RESET_COLOR}#{file_path}...\r" if $global_options[:verbose]
|
48
|
+
commonevent.in_strings(manual_trans_hash)
|
49
|
+
Utils.object_json(commonevent, file_path)
|
50
|
+
print "#{Utils::ESCAPE}#{Utils::GREEN_COLOR}Injected #{Utils::RESET_COLOR}#{file_path}\n" if $global_options[:verbose]
|
51
|
+
end
|
66
52
|
end
|
67
53
|
|
54
|
+
# 处理 \d{5}.rb 文件
|
68
55
|
if with_scripts
|
69
|
-
|
56
|
+
Utils.all_rb_files(target_dir) do |scripts, scripts_basenames, parent_relative_dir|
|
57
|
+
full_output_dir = output_dir.join(parent_relative_dir)
|
58
|
+
full_output_dir.mkdir unless full_output_dir.exist?
|
59
|
+
|
60
|
+
script_info_file_path = target_dir.join(parent_relative_dir, 'Scripts_info.json')
|
61
|
+
script_info_file_path.exist? or raise ScriptsInfoPathError.new(script_info_file_path.to_s), "Scripts_info.json not found: #{script_info_file_path}"
|
62
|
+
# 记得把 Scripts_info.json 也复制过去
|
63
|
+
FileUtils.cp(script_info_file_path, full_output_dir)
|
64
|
+
|
65
|
+
scripts.zip(scripts_basenames).each do |script, script_basename|
|
66
|
+
output_file_path = full_output_dir.join("#{script_basename}.rb")
|
67
|
+
output_file_path.binwrite(StringsInjector.new(manual_trans_hash).rewrite(script, Prism.parse(script).value))
|
68
|
+
print "#{Utils::ESCAPE}#{Utils::GREEN_COLOR}Injected #{Utils::RESET_COLOR}#{output_file_path}\n" if $global_options[:verbose]
|
69
|
+
end
|
70
|
+
end
|
70
71
|
end
|
71
72
|
end
|
72
73
|
|