module RGSS
Constants
- ACE_DATA_EXT
- FLOW_CLASSES
- RUBY_EXT
- SCRIPTS_BASE
- VX_DATA_EXT
- XP_DATA_EXT
- YAML_EXT
Public Class Methods
array_to_hash(arr, &block)
click to toggle source
# File lib/RGSS.rb, line 131 def self.array_to_hash(arr, &block) h = {} arr.each_with_index do |val, index| r = block_given? ? block.call(val) : val h[index] = r unless r.nil? end if arr.length > 0 last = arr.length - 1 h[last] = nil unless h.has_key?(last) end return h end
change_extension(file, new_ext)
click to toggle source
# File lib/RGSS/serialize.rb, line 28 def self.change_extension(file, new_ext) return File.basename(file, '.*') + new_ext end
convert(src, dest, options)
click to toggle source
# File lib/RGSS/serialize.rb, line 257 def self.convert(src, dest, options) files = files_with_extension(src[:directory], src[:ext]) files -= src[:exclude] files.each do |file| src_file = File.join(src[:directory], file) dest_file = File.join(dest[:directory], change_extension(file, dest[:ext])) process_file(file, src_file, dest_file, dest[:ext], src[:load_file], dest[:dump_file], options) end end
convert_saves(base, src, dest, options)
click to toggle source
# File lib/RGSS/serialize.rb, line 270 def self.convert_saves(base, src, dest, options) save_files = files_with_extension(base, src[:ext]) save_files.each do |file| src_file = File.join(base, file) dest_file = File.join(base, change_extension(file, dest[:ext])) process_file(file, src_file, dest_file, dest[:ext], src[:load_save], dest[:dump_save], options) end end
deflate(str)
click to toggle source
# File lib/RGSS/serialize.rb, line 45 def self.deflate(str) return Zlib::Deflate.deflate(str, Zlib::BEST_COMPRESSION) end
dump(dumper, file, data, time, options)
click to toggle source
# File lib/RGSS/serialize.rb, line 80 def self.dump(dumper, file, data, time, options) self.method(dumper).call(file, data, time, options) rescue warn "Exception dumping #{file}" raise end
dump_data_file(file, data, time, options)
click to toggle source
# File lib/RGSS/serialize.rb, line 50 def self.dump_data_file(file, data, time, options) File.open(file, "wb") do |f| Marshal.dump(data, f) end File.utime(time, time, file) end
dump_raw_file(file, data, time, options)
click to toggle source
# File lib/RGSS/serialize.rb, line 73 def self.dump_raw_file(file, data, time, options) File.open(file, "wb") do |f| f.write(data) end File.utime(time, time, file) end
dump_save(file, data, time, options)
click to toggle source
# File lib/RGSS/serialize.rb, line 64 def self.dump_save(file, data, time, options) File.open(file, "wb") do |f| data.each do |chunk| Marshal.dump(chunk, f) end end File.utime(time, time, file) end
dump_yaml_file(file, data, time, options)
click to toggle source
# File lib/RGSS/serialize.rb, line 57 def self.dump_yaml_file(file, data, time, options) File.open(file, "wb") do |f| Psych::dump(data, f, options) end File.utime(time, time, file) end
files_with_extension(directory, extension)
click to toggle source
# File lib/RGSS/serialize.rb, line 36 def self.files_with_extension(directory, extension) return Dir.entries(directory).select{|file| File.extname(file) == extension} end
get_data_directory(base)
click to toggle source
# File lib/RGSS.rb, line 253 def self.get_data_directory(base) return File.join(base, 'Data') end
get_script_directory(base)
click to toggle source
# File lib/RGSS.rb, line 261 def self.get_script_directory(base) return File.join(base, 'Scripts') end
get_yaml_directory(base)
click to toggle source
# File lib/RGSS.rb, line 257 def self.get_yaml_directory(base) return File.join(base, 'YAML') end
hash_to_array(hash)
click to toggle source
# File lib/RGSS.rb, line 144 def self.hash_to_array(hash) arr = [] hash.each do |k, v| arr[k] = v end return arr end
inflate(str)
click to toggle source
# File lib/RGSS/serialize.rb, line 40 def self.inflate(str) text = Zlib::Inflate.inflate(str) return text.force_encoding("UTF-8") end
load(loader, file)
click to toggle source
# File lib/RGSS/serialize.rb, line 163 def self.load(loader, file) return self.method(loader).call(file) rescue warn "Exception loading #{file}" raise end
load_data_file(file)
click to toggle source
# File lib/RGSS/serialize.rb, line 88 def self.load_data_file(file) File.open(file, "rb") do |f| return Marshal.load(f) end end
load_raw_file(file)
click to toggle source
# File lib/RGSS/serialize.rb, line 146 def self.load_raw_file(file) File.open(file, "rb") do |f| return f.read end end
load_save(file)
click to toggle source
# File lib/RGSS/serialize.rb, line 152 def self.load_save(file) File.open(file, "rb") do |f| data = [] while not f.eof? o = Marshal.load(f) data.push(o) end return data end end
load_yaml_file(file)
click to toggle source
# File lib/RGSS/serialize.rb, line 94 def self.load_yaml_file(file) formatador = Formatador.new obj = nil File.open(file, "rb") do |f| obj = Psych::load(f) end max = 0 return obj unless obj.kind_of?(Array) seen = {} idx = obj.each do |elem| next if elem.nil? if elem.instance_variable_defined?("@id") id = elem.instance_variable_get("@id") else id = nil elem.instance_variable_set("@id", nil) end next if id.nil? if seen.has_key?(id) formatador.display_line("[red]#{file}: Duplicate ID #{id}[/]") formatador.indent { formatador.indent { elem.pretty_inspect.split(/\n/).each do |line| formatador.display_line("[red]#{line}[/]") end } formatador.display_line formatador.display_line("[red]Last seen at:\n[/]") formatador.indent { elem.pretty_inspect.split(/\n/).each do |line| formatador.display_line("[red]#{line}[/]") end } } exit end seen[id] = elem max = ((id + 1) unless id < max) end obj.each do |elem| next if elem.nil? id = elem.instance_variable_get("@id") if id.nil? elem.instance_variable_set("@id", max) max += 1 end end return obj end
process(root, name, *args)
click to toggle source
creates an empty class in a potentially nested scope
# File lib/RGSS.rb, line 156 def self.process(root, name, *args) if args.length > 0 process(root.const_get(name), *args) else root.const_set(name, Class.new) unless root.const_defined?(name, false) end end
process_file(file, src_file, dest_file, dest_ext, loader, dumper, options)
click to toggle source
# File lib/RGSS/serialize.rb, line 243 def self.process_file(file, src_file, dest_file, dest_ext, loader, dumper, options) formatador = Formatador.new fbase = File.basename(file, File.extname(file)) return if (! options[:database].nil? ) and (options[:database].downcase != fbase.downcase) src_time = File.mtime(src_file) if !options[:force] && File.exists?(dest_file) && (src_time - 1) < File.mtime(dest_file) formatador.display_line("[yellow]Skipping #{file}[/]") if $VERBOSE else formatador.display_line("[green]Converting #{file} to #{dest_ext}[/]") if $VERBOSE data = load(loader, src_file) dump(dumper, dest_file, data, src_time, options) end end
remove_defined_method(scope, name)
click to toggle source
# File lib/RGSS.rb, line 117 def self.remove_defined_method(scope, name) scope.send(:remove_method, name) if scope.instance_methods(false).include?(name) end
reset_const(scope, sym, value)
click to toggle source
# File lib/RGSS.rb, line 126 def self.reset_const(scope, sym, value) scope.send(:remove_const, sym) if scope.const_defined?(sym) scope.send(:const_set, sym, value) end
reset_method(scope, name, method)
click to toggle source
# File lib/RGSS.rb, line 121 def self.reset_method(scope, name, method) remove_defined_method(scope, name) scope.send(:define_method, name, method) end
sanitize_filename(filename)
click to toggle source
# File lib/RGSS/serialize.rb, line 32 def self.sanitize_filename(filename) return filename.gsub(/[^0-9A-Za-z]+/, '_') end
scripts_to_binary(dirs, src, dest, options)
click to toggle source
# File lib/RGSS/serialize.rb, line 214 def self.scripts_to_binary(dirs, src, dest, options) formatador = Formatador.new src_file = File.join(dirs[:yaml], src) dest_file = File.join(dirs[:data], dest) raise "Missing #{src}" unless File.exists?(src_file) check_time = !options[:force] && File.exists?(dest_file) newest_time = File.mtime(src_file) if check_time index = load(:load_yaml_file, src_file) script_entries = [] index.each do |entry| magic_number, script_name, filename = entry code = '' if filename full_filename = File.join(dirs[:script], filename) raise "Missing script file #{filename}" unless File.exists?(full_filename) newest_time = [File.mtime(full_filename), newest_time].max if check_time code = load(:load_raw_file, full_filename) end script_entries.push([magic_number, script_name, deflate(code)]) end if check_time && (newest_time - 1) < File.mtime(dest_file) formatador.display_line("[yellow]Skipping scripts to binary[/]") if $VERBOSE else formatador.display_line("[green]Converting scripts to binary[/]") if $VERBOSE dump(:dump_data_file, dest_file, script_entries, newest_time, options) end end
scripts_to_text(dirs, src, dest, options)
click to toggle source
# File lib/RGSS/serialize.rb, line 171 def self.scripts_to_text(dirs, src, dest, options) formatador = Formatador.new src_file = File.join(dirs[:data], src) dest_file = File.join(dirs[:yaml], dest) raise "Missing #{src}" unless File.exists?(src_file) script_entries = load(:load_data_file, src_file) check_time = !options[:force] && File.exists?(dest_file) oldest_time = File.mtime(dest_file) if check_time file_map, script_index, script_code = Hash.new(-1), [], {} idx=0 script_entries.each do |script| idx += 1 magic_number, script_name, code = idx, script[1], inflate(script[2]) script_name.force_encoding("UTF-8") if code.length > 0 filename = script_name.empty? ? 'blank' : sanitize_filename(script_name) key = filename.upcase value = (file_map[key] += 1) actual_filename = filename + (value == 0 ? "" : ".#{value}") + RUBY_EXT script_index.push([magic_number, script_name, actual_filename]) full_filename = File.join(dirs[:script], actual_filename) script_code[full_filename] = code check_time = false unless File.exists?(full_filename) oldest_time = [File.mtime(full_filename), oldest_time].min if check_time else script_index.push([magic_number, script_name, nil]) end end src_time = File.mtime(src_file) if check_time && (src_time - 1) < oldest_time formatador.display_line("[yellow]Skipping scripts to text[/]") if $VERBOSE else formatador.display_line("[green]Converting scripts to text[/]") if $VERBOSE dump(:dump_yaml_file, dest_file, script_index, src_time, options) script_code.each {|file, code| dump(:dump_raw_file, file, code, src_time, options)} end end
serialize(version, direction, directory, options = {})
click to toggle source
- version
-
one of :ace, :vx, :xp
- direction
-
one of :data_bin_to_text, :data_text_to_bin, :save_bin_to_text, :save_text_to_bin, :scripts_bin_to_text, :scripts_text_to_bin, :all_text_to_bin, :all_bin_to_text
- directory
-
directory that project file is in
- options
-
:force - ignores file dates when converting (default false) :round_trip - create yaml data that matches original marshalled data skips
data cleanup operations (default false)
:line_width - line width form YAML files, -1 for no line width limit
(default 130)
:table_width - maximum number of entries per row for table data, -1 for no
table row limit (default 20)
# File lib/RGSS/serialize.rb, line 293 def self.serialize(version, direction, directory, options = {}) raise "#{directory} not found" unless File.exist?(directory) setup_classes(version, options) options = options.clone() options[:sort] = true if [:vx, :xp].include?(version) options[:flow_classes] = FLOW_CLASSES options[:line_width] ||= 130 table_width = options[:table_width] RGSS::reset_const(Table, :MAX_ROW_LENGTH, table_width ? table_width : 20) base = File.realpath(directory) dirs = { :base => base, :data => get_data_directory(base), :yaml => get_yaml_directory(base), :script => get_script_directory(base) } dirs.values.each do |d| FileUtils.mkdir(d) unless File.exists?(d) end exts = { :ace => ACE_DATA_EXT, :vx => VX_DATA_EXT, :xp => XP_DATA_EXT } yaml_scripts = SCRIPTS_BASE + YAML_EXT yaml = { :directory => dirs[:yaml], :exclude => [yaml_scripts], :ext => YAML_EXT, :load_file => :load_yaml_file, :dump_file => :dump_yaml_file, :load_save => :load_yaml_file, :dump_save => :dump_yaml_file } scripts = SCRIPTS_BASE + exts[version] data = { :directory => dirs[:data], :exclude => [scripts], :ext => exts[version], :load_file => :load_data_file, :dump_file => :dump_data_file, :load_save => :load_save, :dump_save => :dump_save } if options[:database].nil? or options[:database].downcase == 'scripts' convert_scripts = true else convert_scripts = false end if options[:database].nil? or options[:database].downcase == 'saves' convert_saves = true else convert_saves = false end case direction when :data_bin_to_text convert(data, yaml, options) scripts_to_text(dirs, scripts, yaml_scripts, options) if convert_scripts when :data_text_to_bin convert(yaml, data, options) scripts_to_binary(dirs, yaml_scripts, scripts, options) if convert_scripts when :save_bin_to_text convert_saves(base, data, yaml, options) if convert_saves when :save_text_to_bin convert_saves(base, yaml, data, options) if convert_saves when :scripts_bin_to_text scripts_to_text(dirs, scripts, yaml_scripts, options) if convert_scripts when :scripts_text_to_bin scripts_to_binary(dirs, yaml_scripts, scripts, options) if convert_scripts when :all_bin_to_text convert(data, yaml, options) scripts_to_text(dirs, scripts, yaml_scripts, options) if convert_scripts convert_saves(base, data, yaml, options) if convert_saves when :all_text_to_bin convert(yaml, data, options) scripts_to_binary(dirs, yaml_scripts, scripts, options) if convert_scripts convert_saves(base, yaml, data, options) if convert_saves else raise "Unrecognized direction :#{direction}" end end
setup_classes(version, options)
click to toggle source
# File lib/RGSS.rb, line 236 def self.setup_classes(version, options) setup_system(version, options) setup_interpreter(version) setup_event_command(version, options) BasicCoder.set_ivars_methods(version) end
setup_event_command(version, options)
click to toggle source
# File lib/RGSS.rb, line 224 def self.setup_event_command(version, options) # format event commands to flow style for the event codes that aren't move commands if options[:round_trip] reset_method(RPG::EventCommand, :clean, ->{}) else reset_method(RPG::EventCommand, :clean, ->{ @parameters[0].rstrip! if @code == 401 }) end reset_const(RPG::EventCommand, :MOVE_LIST_CODE, version == :xp ? 209 : 205) end
setup_interpreter(version)
click to toggle source
# File lib/RGSS.rb, line 209 def self.setup_interpreter(version) # Game_Interpreter is marshalled differently in VX Ace if version == :ace reset_method(Game_Interpreter, :marshal_dump, ->{ return @data }) reset_method(Game_Interpreter, :marshal_load, ->(obj) { @data = obj }) else remove_defined_method(Game_Interpreter, :marshal_dump) remove_defined_method(Game_Interpreter, :marshal_load) end end
setup_system(version, options)
click to toggle source
# File lib/RGSS.rb, line 188 def self.setup_system(version, options) # convert variable and switch name arrays to a hash when serialized # if round_trip isn't set change version_id to fixed number if options[:round_trip] iso = ->(val) { return val } reset_method(RPG::System, :reduce_string, iso) reset_method(RPG::System, :map_version, iso) reset_method(Game_System, :map_version, iso) else reset_method(RPG::System, :reduce_string, ->(str) { return nil if str.nil? stripped = str.strip return stripped.empty? ? nil : stripped }) # These magic numbers should be different. If they are the same, the saved version # of the map in save files will be used instead of any updated version of the map reset_method(RPG::System, :map_version, ->(ignored) { return 12345678 }) reset_method(Game_System, :map_version, ->(ignored) { return 87654321 }) end end