wolftrans 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c841512ed31767357a132f115dd9c9d5d4d85ae3
4
- data.tar.gz: 13b81d6e79ce6e6e7a3ca202073dd4b8c2a22dd8
3
+ metadata.gz: 04ff8773a7b8a4af514f481410befe41e922aaf2
4
+ data.tar.gz: 80e7cb14b2a9337ef34b687df85cbff1e4cf60a6
5
5
  SHA512:
6
- metadata.gz: 4b63ce1e61df8e456faf61ae7064c8732dfc8626b75262641a9afe76b5f271c5e813daa97042435ea237fedf923e7129b74e363c6fbac6b5322f41a6316a5901
7
- data.tar.gz: faea22c7bbf27d5e4171fa3056306014e869e4c57e4ea9c5697c6359a0a84255ae1b0ccf5ea14ee9d474d2fb00b8f4328790a96e93bbff84443b408d687ea7bc
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
@@ -5,6 +5,7 @@ require 'wolftrans'
5
5
 
6
6
  if ARGV.size != 3
7
7
  STDERR.puts "usage: wolftrans game_dir patch_dir out_dir"
8
+ STDERR.puts "WARNING: out_dir will be DELETED. Use caution."
8
9
  exit 1
9
10
  end
10
11
 
@@ -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
@@ -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
- def dump(project_filename, dat_filename)
38
- FileCoder.open(project_filename, :write) do |coder|
39
- coder.write_int(@types.size)
40
- @types.each do |type|
41
- type.dump_project(coder)
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
- FileCoder.open(dat_filename, :write, DAT_SEED_INDICES, @crypt_header) do |coder|
45
- if encrypted?
46
- coder.write_byte(@unknown_encrypted_1)
47
- else
48
- coder.write(DAT_MAGIC_NUMBER)
49
- end
50
- coder.write_int(@types.size)
51
- @types.each do |type|
52
- type.dump_dat(coder)
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
- def grep(needle)
59
- @types.each_with_index do |type, type_index|
60
- type.data.each_with_index do |datum, datum_index|
61
- datum.each_translatable do |value, field|
62
- next unless value =~ needle
63
- puts "DB:[#{type_index}]#{type.name}/[#{datum_index}]#{datum.name}/[#{field.index}]#{field.name}"
64
- puts "\t" + value
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 = [
@@ -80,6 +80,10 @@ module WolfRpg
80
80
  end
81
81
  end
82
82
 
83
+ def each_filename
84
+ yield @default_pc_graphic.gsub('\\', '/') unless @default_pc_graphic.empty?
85
+ end
86
+
83
87
  private
84
88
  MAGIC_NUMBER = [
85
89
  0x57, 0x00, 0x00, 0x4f, 0x4c, 0x00, 0x46, 0x4d, 0x00
@@ -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*')
@@ -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 data folder in '#{@game_dir}'"
19
+ raise "could not find Data folder in '#{@game_dir}'"
19
20
  end
20
21
 
21
- @maps = {}
22
+ # Load databases, Game.dat, and common events
22
23
  @databases = {}
23
-
24
- # Find and read all necessary data
25
- Dir.entries(@game_data_dir).each do |parent_name|
26
- parent_name_downcase = parent_name.downcase
27
- next unless ['basicdata', 'mapdata'].include? parent_name_downcase
28
- parent_path = "#{@game_data_dir}/#{parent_name}"
29
- Dir.entries(parent_path).each do |basename|
30
- basename_downcase = basename.downcase
31
- extension = File.extname(basename_downcase)
32
- basename_noext = File.basename(basename_downcase, '.*')
33
- filename = "#{parent_path}/#{basename}"
34
- case parent_name_downcase
35
- when 'mapdata'
36
- load_map(filename) if extension == '.mps'
37
- when 'basicdata'
38
- if basename_downcase == 'game.dat'
39
- @game_dat_filename = 'Data/BasicData/Game.dat'
40
- load_game_dat(filename)
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
- # Patch all the maps and dump them
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
- # Copy image/sound/music files
124
- Dir.entries(@game_data_dir).each do |entry|
125
- # Skip dot and dot-dot and non-directories
126
- next if entry == '.' || entry == '..'
127
- path = "#{@game_data_dir}/#{entry}"
128
- next unless FileTest.directory? path
129
-
130
- # Find the corresponding folder in the out dir
131
- unless (out_path = Util.join_path_nocase(out_data_dir, entry))
132
- out_path = "#{out_data_dir}/#{entry}"
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
- # Find the corresponding folder in the patch
137
- if @patch_data_dir && (asset_entry = Util.join_path_nocase(@patch_data_dir, entry))
138
- copy_data_files("#{@patch_data_dir}/#{asset_entry}", DATA_FILE_EXTENSIONS, out_path)
139
- end
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
- # Copy the original game files
142
- copy_data_files(path, DATA_FILE_EXTENSIONS, out_path)
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
@@ -1,3 +1,3 @@
1
1
  module WolfTrans
2
- VERSION = '0.2.0'
2
+ VERSION = '0.2.1'
3
3
  end
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.0
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: 2015-12-01 00:00:00.000000000 Z
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.4.5.1
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