forked from elizagamedev/mkxp-oneshot
-
Notifications
You must be signed in to change notification settings - Fork 6
/
rpgscript.rb
executable file
·108 lines (91 loc) · 2.54 KB
/
rpgscript.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#!/usr/bin/ruby
require 'zlib'
def usage
STDERR.puts "usage: rpgscript.rb scripts_dir game_dir [x]"
exit 1
end
usage if ARGV.length < 2
scripts_dir = ARGV[0]
game_dir = ARGV[1]
if ARGV.length >= 3
usage if ARGV[2] != 'x'
extract = true
else
extract = false
end
# Determine version of game engine
game_data_dir = File.join(game_dir, 'Data')
unless Dir.exist? game_data_dir
STDERR.puts "error: #{game_dir} does not have a Data subdirectory"
exit 1
end
target_path = nil
Dir.entries(game_data_dir).each do |e|
ext = File.extname(e)
if ext =~ /\.r[xv]data2?/
target_path = File.join(game_data_dir, 'xScripts' + ext)
break
end
end
unless target_path
STDERR.puts "warning: could not determine game engine version, assuming XP"
target_path = File.join(game_data_dir, 'xScripts.rxdata')
end
# Generate path of script list
list_path = File.join(scripts_dir, '_scripts.txt')
if extract
# Make sure the script directory exists
Dir.mkdir(scripts_dir) unless Dir.exists? scripts_dir
# Keep track of names of scripts extracted so we can warn about duplicates
names = Hash.new(0)
# Read scripts
File.open(target_path, 'rb') do |fin|
File.open(list_path, 'w') do |flist|
Marshal.load(fin).each_with_index do |script, index|
name = script[1].strip
data = Zlib::Inflate.inflate(script[2]).rstrip
.gsub(/[ \t]*(?:$|\r\n?)/, "\n")
# Make sure this file doesn't already exist
if name.empty?
if data.empty? || data == "\n"
flist.puts
next
else
name = 'UNTITLED'
end
end
names[name] += 1
if names[name] > 1
name << " (#{names[name]})"
end
if data.empty? || data == "\n"
# Treat this like a comment
flist.puts('# ' + name)
else
# Write to file order list
flist.puts(name)
# Write script file
File.open(File.join(scripts_dir, name + '.rb'), 'wb') do |fout|
fout.write(data)
end
end
end
end
end
puts "#{target_path} extracted."
else
# Write scripts
scripts = []
IO.foreach(list_path) do |name|
name.strip!
next if name.empty? || name.start_with?('#')
data = File.read(File.join(scripts_dir, name + '.rb')).rstrip.gsub("\n", "\r\n")
script = Array.new(3)
script[0] = 0
script[1] = name
script[2] = Zlib.deflate(data)
scripts << script
end
File.open(target_path, 'wb') { |f| f.write(Marshal.dump(scripts)) }
puts "#{target_path} written."
end