module RMXPExtractor
Constants
- VERSION
Public Class Methods
export()
click to toggle source
# File lib/rmxp_extractor/data_export.rb, line 2 def self.export STDERR.puts "No Data Directory!" unless Dir.exists? "./Data" exit 1 unless Dir.exists? "./Data" require "json" require "ruby-progressbar" require "fileutils" require "pathname" require "readline" require_relative "classnames" require_relative "script_handler" window_size = (Readline.get_screen_size[1] - 1).clamp(0, 500) progress = ProgressBar.create( format: "%a /%e |%B| %p%% %c/%C %r files/sec %t", starting_at: 0, total: nil, output: $stderr, length: window_size, title: "Exported", remainder_mark: "\e[0;30mâ–ˆ\e[0m", progress_mark: "â–ˆ", unknown_progress_animation_steps: ["==>", ">==", "=>="], ) Dir.mkdir "./Data_JSON" unless Dir.exists? "./Data_JSON" paths = Pathname.glob(("./Data/" + ("*" + ".rxdata"))) count = paths.size progress.total = count paths.each_with_index do |path, i| content = Hash.new name = path.basename(".rxdata") rxdata = Marshal.load(path.read(mode: "rb")) #puts name.to_s case name.to_s when "xScripts" RMXPExtractor.rpgscript("./", "./Scripts", true) content[:version] = VERSION when "Scripts" content[:version] = VERSION when "System" content = rxdata.hash content[:version] = VERSION when "MapInfos" content = { mapinfos: {} } mapinfos = rxdata.sort_by { |key, value| value.order }.to_h mapinfos.each do |key, value| content[:mapinfos][key] = value.hash end content[:version] = VERSION when /^Map\d+$/ content = rxdata.hash content[:version] = VERSION else content[name.to_s.downcase] = [] rxdata.each_with_index do |value| content[name.to_s.downcase] << value.hash unless value == nil end content[:version] = VERSION end json = File.open("./Data_JSON/" + name.sub_ext(".json").to_s, "wb") #puts content json.puts JSON.pretty_generate(content) progress.increment end end
import()
click to toggle source
# File lib/rmxp_extractor/data_import.rb, line 2 def self.import STDERR.puts "No Data_JSON Directory!" unless Dir.exists? "./Data_JSON" exit 1 unless Dir.exists? "./Data_JSON" require "oj" require "ruby-progressbar" require "fileutils" require "pathname" require "readline" require_relative "classnames" require_relative "script_handler" window_size = (Readline.get_screen_size[1] - 1).clamp(0, 500) progress = ProgressBar.create( format: "%a /%e |%B| %p%% %c/%C %r files/sec %t", starting_at: 0, total: nil, output: $stderr, length: window_size, title: "Imported", remainder_mark: "\e[0;30mâ–ˆ\e[0m", progress_mark: "â–ˆ", unknown_progress_animation_steps: ["==>", ">==", "=>="], ) Dir.mkdir "./Data" unless Dir.exists? "./Data" paths = Pathname.glob(("./Data_JSON/" + ("*" + ".json"))) count = paths.size progress.total = count paths.each_with_index do |path, i| content = Hash.new name = path.basename(".json") json = Oj.load path.read(mode: "rb") puts "\n\e[33;1mWARNING: Incompatible version format in #{name.to_s}!\e[0m\n" if json["version"] != VERSION case name.to_s when "xScripts" RMXPExtractor.rpgscript("./", "./Scripts") progress.increment return when "Scripts" when "System" content = RPG::System.new(json) when "MapInfos" content = {} json["mapinfos"].each do |key, value| content[key.to_i] = RPG::MapInfo.new(value) unless key == "version" end #when "CommonEvents" when /^Map\d+$/ content = RPG::Map.new json #! All files that contain an array of subclasses start with nil since they start from 1, not 0 else content = [nil] json[name.to_s.downcase].each_with_index do |value, index| eval("content << RPG::#{RMXPExtractor.singularize(name.to_s)}.new(value)") end end rxdata = File.open("./Data/" + name.sub_ext(".rxdata").to_s, "wb") rxdata.puts Marshal.dump(content) progress.increment end end
process(type)
click to toggle source
# File lib/rmxp_extractor.rb, line 12 def self.process(type) RMXPExtractor.usage if type.length < 1 if type[0] == "import" RMXPExtractor.import elsif type[0] == "export" RMXPExtractor.export elsif type[0] == "scripts" if type[3] == "x" RMXPExtractor.rpgscript(type[2], type[1], true) elsif type.length < 3 || type.length > 4 STDERR.puts "usage: rmxp_extractor scripts scripts_dir game_dir [x]" exit 1 elsif type[3] == nil RMXPExtractor.rpgscript(type[2], type[1], false) end else RMXPExtractor.usage end end
rpgscript(game_dir, scripts_dir, extract = false)
click to toggle source
# File lib/rmxp_extractor/script_handler.rb, line 5 def self.rpgscript(game_dir, scripts_dir, extract = false) # 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 end
singularize(string)
click to toggle source
# File lib/rmxp_extractor/data_import.rb, line 69 def self.singularize(string) if string.end_with? "ies" string.delete_suffix("ies") + "y" elsif string.end_with? "tes" string.delete_suffix("s") elsif string.end_with? "es" string.delete_suffix("es") elsif string.end_with? "s" string.delete_suffix("s") else string end end
usage()
click to toggle source
# File lib/rmxp_extractor.rb, line 7 def self.usage STDERR.puts "usage: rmxp_extractor import|export|scripts" exit 1 end