wolftrans 0.2.0 → 0.2.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.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/bin/wolftrans +1 -0
- data/lib/wolfrpg/command.rb +8 -0
- data/lib/wolfrpg/common_events.rb +16 -0
- data/lib/wolfrpg/database.rb +43 -24
- data/lib/wolfrpg/game_dat.rb +4 -0
- data/lib/wolfrpg/map.rb +25 -0
- data/lib/wolftrans/patch_data.rb +117 -63
- data/lib/wolftrans/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 04ff8773a7b8a4af514f481410befe41e922aaf2
|
4
|
+
data.tar.gz: 80e7cb14b2a9337ef34b687df85cbff1e4cf60a6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 95a928ce6271aa3bfa37c8f842e92a9fee8c117c06849a52545f49fd2abd33ef64a7277b01342bcd188b1abcb7f36a78213161bd90411c1b42558fab05c0c03a
|
7
|
+
data.tar.gz: 7f3ed861199acd6c26fe2ac173892470ab061886b75332fe89d280e59fcf251df47be4a2eab4903670dcc6af2f869249fab874ae416e5981db19a786ca96ba69
|
data/README.md
CHANGED
@@ -36,6 +36,8 @@ Currently, Wolf Trans can be invoked with the command line:
|
|
36
36
|
|
37
37
|
If `patch_dir` does not exist, it will be automatically generated with the text contained in the data files of the game in `game_dir`. `out_dir` will contain the patched game.
|
38
38
|
|
39
|
+
**WARNING: OUT_DIR WILL BE *DELETED* IF IT EXISTS. USE CAUTION.**
|
40
|
+
|
39
41
|
The behavior of the command line arguments will almost certainly be revised in a future version.
|
40
42
|
|
41
43
|
## Todo
|
data/bin/wolftrans
CHANGED
data/lib/wolfrpg/command.rb
CHANGED
@@ -413,6 +413,14 @@ module WolfRpg
|
|
413
413
|
dump_terminator(coder)
|
414
414
|
end
|
415
415
|
|
416
|
+
def each_filename
|
417
|
+
@string_args.each do |str|
|
418
|
+
str.scan(/^[^ ]*?[\/\\].*?\.[a-zA-Z0-9]+$/).each do |filename|
|
419
|
+
yield filename.gsub('\\', '/')
|
420
|
+
end
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
416
424
|
private
|
417
425
|
def initialize(cid, args, string_args, indent)
|
418
426
|
@cid = cid
|
@@ -27,6 +27,14 @@ module WolfRpg
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
+
def each_filename
|
31
|
+
@events.each do |event|
|
32
|
+
event.each_filename do |fn|
|
33
|
+
yield fn
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
30
38
|
def grep(needle)
|
31
39
|
end
|
32
40
|
|
@@ -149,6 +157,14 @@ module WolfRpg
|
|
149
157
|
end
|
150
158
|
end
|
151
159
|
|
160
|
+
def each_filename
|
161
|
+
@commands.each do |command|
|
162
|
+
command.each_filename do |fn|
|
163
|
+
yield fn
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
152
168
|
private
|
153
169
|
MAGIC_NUMBER = [
|
154
170
|
0x0A, 0x00, 0x00, 0x00
|
data/lib/wolfrpg/database.rb
CHANGED
@@ -33,36 +33,46 @@ module WolfRpg
|
|
33
33
|
STDERR.puts "warning: no C1 terminator at the end of '#{dat_filename}'"
|
34
34
|
end
|
35
35
|
end
|
36
|
+
end
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
end
|
38
|
+
def dump(project_filename, dat_filename)
|
39
|
+
FileCoder.open(project_filename, :write) do |coder|
|
40
|
+
coder.write_int(@types.size)
|
41
|
+
@types.each do |type|
|
42
|
+
type.dump_project(coder)
|
43
43
|
end
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
44
|
+
end
|
45
|
+
FileCoder.open(dat_filename, :write, DAT_SEED_INDICES, @crypt_header) do |coder|
|
46
|
+
if encrypted?
|
47
|
+
coder.write_byte(@unknown_encrypted_1)
|
48
|
+
else
|
49
|
+
coder.write(DAT_MAGIC_NUMBER)
|
50
|
+
end
|
51
|
+
coder.write_int(@types.size)
|
52
|
+
@types.each do |type|
|
53
|
+
type.dump_dat(coder)
|
54
|
+
end
|
55
|
+
coder.write_byte(0xC1)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def each_filename
|
60
|
+
@types.each do |type|
|
61
|
+
type.data.each do |datum|
|
62
|
+
datum.each_filename do |fn|
|
63
|
+
yield fn
|
53
64
|
end
|
54
|
-
coder.write_byte(0xC1)
|
55
65
|
end
|
56
66
|
end
|
67
|
+
end
|
57
68
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
end
|
69
|
+
def grep(needle)
|
70
|
+
@types.each_with_index do |type, type_index|
|
71
|
+
type.data.each_with_index do |datum, datum_index|
|
72
|
+
datum.each_translatable do |value, field|
|
73
|
+
next unless value =~ needle
|
74
|
+
puts "DB:[#{type_index}]#{type.name}/[#{datum_index}]#{datum.name}/[#{field.index}]#{field.name}"
|
75
|
+
puts "\t" + value
|
66
76
|
end
|
67
77
|
end
|
68
78
|
end
|
@@ -312,6 +322,15 @@ module WolfRpg
|
|
312
322
|
yield [value, field] unless value.empty? || value.include?("\n")
|
313
323
|
end
|
314
324
|
end
|
325
|
+
|
326
|
+
def each_filename
|
327
|
+
@fields.each do |field|
|
328
|
+
next unless field.string?
|
329
|
+
self[field].scan(/^[^ ]*?[\/\\].*?\.[a-zA-Z0-9]+$/).each do |filename|
|
330
|
+
yield filename.gsub('\\', '/')
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
315
334
|
end
|
316
335
|
|
317
336
|
DAT_MAGIC_NUMBER = [
|
data/lib/wolfrpg/game_dat.rb
CHANGED
data/lib/wolfrpg/map.rb
CHANGED
@@ -55,6 +55,14 @@ module WolfRpg
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
+
def each_filename
|
59
|
+
@events.each do |event|
|
60
|
+
event.each_filename do |fn|
|
61
|
+
yield fn
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
58
66
|
#DEBUG method that searches for a string somewhere in the map
|
59
67
|
def grep(needle)
|
60
68
|
@events.each do |event|
|
@@ -128,6 +136,14 @@ module WolfRpg
|
|
128
136
|
coder.write_byte(0x70)
|
129
137
|
end
|
130
138
|
|
139
|
+
def each_filename
|
140
|
+
@pages.each do |page|
|
141
|
+
page.each_filename do |fn|
|
142
|
+
yield fn
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
131
147
|
class Page
|
132
148
|
attr_accessor :id
|
133
149
|
attr_accessor :unknown1
|
@@ -219,6 +235,15 @@ module WolfRpg
|
|
219
235
|
coder.write_byte(0x7A)
|
220
236
|
end
|
221
237
|
|
238
|
+
def each_filename
|
239
|
+
yield @graphic_name.gsub('\\', '/') unless @graphic_name.empty?
|
240
|
+
@commands.each do |command|
|
241
|
+
command.each_filename do |fn|
|
242
|
+
yield fn
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
222
247
|
COMMANDS_TERMINATOR = [
|
223
248
|
0x03, 0x00, 0x00, 0x00,
|
224
249
|
].pack('C*')
|
data/lib/wolftrans/patch_data.rb
CHANGED
@@ -3,6 +3,7 @@ require 'wolfrpg'
|
|
3
3
|
|
4
4
|
require 'fileutils'
|
5
5
|
require 'find'
|
6
|
+
require 'set'
|
6
7
|
|
7
8
|
#####################
|
8
9
|
# Loading Game data #
|
@@ -15,38 +16,29 @@ module WolfTrans
|
|
15
16
|
end
|
16
17
|
@game_data_dir = Util.join_path_nocase(@game_dir, 'data')
|
17
18
|
if @game_data_dir == nil
|
18
|
-
raise "could not find
|
19
|
+
raise "could not find Data folder in '#{@game_dir}'"
|
19
20
|
end
|
20
21
|
|
21
|
-
|
22
|
+
# Load databases, Game.dat, and common events
|
22
23
|
@databases = {}
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
elsif extension == '.project'
|
42
|
-
next if basename_downcase == 'sysdatabasebasic.project'
|
43
|
-
dat_filename = Util.join_path_nocase(parent_path, "#{basename_noext}.dat")
|
44
|
-
next if dat_filename == nil
|
45
|
-
load_game_database(filename, dat_filename)
|
46
|
-
elsif basename_downcase == 'commonevent.dat'
|
47
|
-
load_common_events(filename)
|
48
|
-
end
|
49
|
-
end
|
24
|
+
basicdata_dir = Util.join_path_nocase(@game_data_dir, 'basicdata')
|
25
|
+
if basicdata_dir == nil
|
26
|
+
raise "could not find BasicData folder in '#{@game_data_dir}'"
|
27
|
+
end
|
28
|
+
Dir.entries(basicdata_dir).each do |entry|
|
29
|
+
entry_downcase = entry.downcase
|
30
|
+
filename = "#{basicdata_dir}/#{entry}"
|
31
|
+
if entry_downcase == 'game.dat'
|
32
|
+
@game_dat_filename = 'Data/BasicData/Game.dat'
|
33
|
+
load_game_dat(filename)
|
34
|
+
elsif entry_downcase.end_with?('.project')
|
35
|
+
next if entry_downcase == 'sysdatabasebasic.project'
|
36
|
+
basename = File.basename(entry_downcase, '.*')
|
37
|
+
dat_filename = Util.join_path_nocase(basicdata_dir, "#{basename}.dat")
|
38
|
+
next if dat_filename == nil
|
39
|
+
load_game_database(filename, dat_filename)
|
40
|
+
elsif entry_downcase == 'commonevent.dat'
|
41
|
+
load_common_events(filename)
|
50
42
|
end
|
51
43
|
end
|
52
44
|
|
@@ -60,13 +52,62 @@ module WolfTrans
|
|
60
52
|
end
|
61
53
|
end
|
62
54
|
end
|
55
|
+
|
56
|
+
# Gather list of asset and map filenames
|
57
|
+
map_names = Set.new
|
58
|
+
@assets = {}
|
59
|
+
@databases.each_value do |db|
|
60
|
+
db.each_filename do |fn|
|
61
|
+
fn_downcase = fn.downcase
|
62
|
+
@assets[fn_downcase] = fn
|
63
|
+
if fn_downcase.end_with?('.mps')
|
64
|
+
map_names.add(File.basename(fn_downcase, '.*'))
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
@game_dat.each_filename do |fn|
|
69
|
+
@assets[fn.downcase] = fn
|
70
|
+
end
|
71
|
+
@common_events.each_filename do |fn|
|
72
|
+
@assets[fn.downcase] = fn
|
73
|
+
end
|
74
|
+
|
75
|
+
# Load maps
|
76
|
+
maps_path = Util.join_path_nocase(@game_data_dir, 'mapdata')
|
77
|
+
if maps_path == nil
|
78
|
+
raise "could not find MapData folder in '#{@game_data_dir}'"
|
79
|
+
end
|
80
|
+
@maps = {}
|
81
|
+
map_names.each do |name|
|
82
|
+
map_path = Util.join_path_nocase(maps_path, name + '.mps')
|
83
|
+
if map_path == nil
|
84
|
+
STDERR.puts "warn: could not find map '#{name}'"
|
85
|
+
next
|
86
|
+
end
|
87
|
+
load_map(map_path)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Gather remaining asset filenames
|
91
|
+
@maps.each_value do |map|
|
92
|
+
map.each_filename do |fn|
|
93
|
+
@assets[fn.downcase] = fn
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Make sure not to treat certain kinds of filenames as assets
|
98
|
+
@assets.reject! { |k, v| k.start_with?('save/') }
|
99
|
+
|
100
|
+
# Rewrite asset filenames
|
101
|
+
extcounts = Hash.new(0)
|
102
|
+
@assets.keys.sort.each do |fn|
|
103
|
+
ext = File.extname(fn)[1..-1]
|
104
|
+
@assets[fn] = '%04d.%s' % [extcounts[ext], ext]
|
105
|
+
extcounts[ext] += 1
|
106
|
+
end
|
63
107
|
end
|
64
108
|
|
65
109
|
# Apply the patch to the files in the game path and write them to the
|
66
110
|
# output directory
|
67
|
-
DATA_FILE_EXTENSIONS = ['png','jpg','jpeg','bmp','ogg',
|
68
|
-
'mp3','wav','mid','midi',
|
69
|
-
'dat','project','xxxxx']
|
70
111
|
def apply(out_dir)
|
71
112
|
out_dir = Util.sanitize_path(out_dir)
|
72
113
|
out_data_dir = "#{out_dir}/Data"
|
@@ -74,21 +115,8 @@ module WolfTrans
|
|
74
115
|
# Clear out directory
|
75
116
|
FileUtils.rm_rf(out_dir)
|
76
117
|
FileUtils.mkdir_p("#{out_data_dir}/BasicData")
|
77
|
-
FileUtils.mkdir_p("#{out_data_dir}/MapData")
|
78
118
|
|
79
|
-
#
|
80
|
-
@maps.each do |map_name, map|
|
81
|
-
map.events.each do |event|
|
82
|
-
next unless event
|
83
|
-
event.pages.each do |page|
|
84
|
-
page.commands.each_with_index do |command, cmd_index|
|
85
|
-
context = Context::MapEvent.from_data(map_name, event, page, cmd_index, command)
|
86
|
-
patch_command(command, context)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
map.dump("#{out_data_dir}/MapData/#{map_name}.mps")
|
91
|
-
end
|
119
|
+
#TODO create directories for each asset
|
92
120
|
|
93
121
|
# Patch the databases
|
94
122
|
@databases.each do |db_name, db|
|
@@ -120,26 +148,33 @@ module WolfTrans
|
|
120
148
|
patch_game_dat
|
121
149
|
@game_dat.dump("#{out_dir}/#{@game_dat_filename}")
|
122
150
|
|
123
|
-
#
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
FileUtils.mkdir_p(out_path)
|
151
|
+
# Patch all the maps
|
152
|
+
@maps.each do |map_name, map|
|
153
|
+
map.events.each do |event|
|
154
|
+
next unless event
|
155
|
+
event.pages.each do |page|
|
156
|
+
page.commands.each_with_index do |command, cmd_index|
|
157
|
+
context = Context::MapEvent.from_data(map_name, event, page, cmd_index, command)
|
158
|
+
patch_command(command, context)
|
159
|
+
end
|
160
|
+
end
|
134
161
|
end
|
162
|
+
# Translate path
|
163
|
+
assetpath = @assets["mapdata/#{map_name.downcase}.mps"]
|
164
|
+
fullpath = "#{out_data_dir}/#{assetpath}"
|
165
|
+
map.dump(fullpath)
|
166
|
+
end
|
135
167
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
168
|
+
# Copy remaining BasicData files
|
169
|
+
copy_data_files(Util.join_path_nocase(@game_data_dir, 'basicdata'),
|
170
|
+
['xxxxx', 'dat', 'project', 'png'],
|
171
|
+
"#{out_data_dir}/BasicData")
|
140
172
|
|
141
|
-
|
142
|
-
|
173
|
+
# Copy remaining assets
|
174
|
+
@assets.each_pair do |fn, newfn|
|
175
|
+
filename = get_asset_filename(fn)
|
176
|
+
next unless filename
|
177
|
+
FileUtils.cp(filename, "#{out_data_dir}/#{newfn}")
|
143
178
|
end
|
144
179
|
|
145
180
|
# Copy fonts
|
@@ -345,5 +380,24 @@ module WolfTrans
|
|
345
380
|
FileUtils.cp(path, "#{out_dir}/#{entry}")
|
346
381
|
end
|
347
382
|
end
|
383
|
+
|
384
|
+
# Get a full filename based on a short asset filename
|
385
|
+
def get_asset_filename(fn)
|
386
|
+
# Find the correct filename case
|
387
|
+
dirname, basename = fn.split('/')
|
388
|
+
if @patch_data_dir
|
389
|
+
path = Util.join_path_nocase(@patch_data_dir, dirname)
|
390
|
+
if path
|
391
|
+
path = Util.join_path_nocase(path, basename)
|
392
|
+
return path if path
|
393
|
+
end
|
394
|
+
end
|
395
|
+
path = Util.join_path_nocase(@game_data_dir, dirname)
|
396
|
+
if path
|
397
|
+
path = Util.join_path_nocase(path, basename)
|
398
|
+
return path if path
|
399
|
+
end
|
400
|
+
return nil
|
401
|
+
end
|
348
402
|
end
|
349
403
|
end
|
data/lib/wolftrans/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wolftrans
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mathew Velasquez
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-11-30 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A utility to translate Wolf RPG Editor games
|
14
14
|
email: mathewvq@gmail.com
|
@@ -60,7 +60,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
60
60
|
version: '0'
|
61
61
|
requirements: []
|
62
62
|
rubyforge_project:
|
63
|
-
rubygems_version: 2.
|
63
|
+
rubygems_version: 2.6.13
|
64
64
|
signing_key:
|
65
65
|
specification_version: 4
|
66
66
|
summary: A utility to translate Wolf RPG Editor games
|