兼容XP/VX/VA的文件缺失容错及使用情况跟踪脚本

=begin
  RMzas RPG Maker Game Resources Tracker
  此脚本适用于RPG Maker XP、RPG Maker VX、RPG Maker VX Ace
  
  功能说明:
      从零开始记录游戏中使用过的所有素材文件的相对路径与文件名,
      同名文件也只记录1次,能够同时记录(首次)调用时的地图ID,
      逐条录入本地txt文件,可作为发布游戏前转移RTP数据的参考。
      在您正式发布游戏后,仍然可以起到文件缺失容错的保险作用。
  
  其他说明:
      但凡调用时,未能在游戏目录(YES)及RTP路径(RTP)里找到的文件,就会以[404]开头,
      在确认素材全部准备妥当后,请删除本脚本的最后1行,再删除Resources.txt即可,
      之后本脚本就会只履行文件缺失容错的机能,不再追踪记录、读取写入。
  
  如有任何问题,您可以在这里向我们提出:http://rmzas.sinaapp.com/?p=351
  by RMzas! ML4455739  2017.09.13  V1 使用和转载请保留以上信息
=end

class RMzas_Resources_Tracker
  
  FILENAME = "Resources.txt" # 导出列表的文件名,确保有读写权限
  NEED_MAPID = true # 若您不希望txt文件中出现地图ID,请将左边的true修改为false
  # 为用于区分RPG Maker程序版本的常量赋值
  RGSS_VER = ($TEST.nil? ? :XP : (RUBY_VERSION == '1.9.2' ? :VXAce : :VX))
  
  def initialize
    # 当导出列表文件不存在时创建它
    if !FileTest.exist?(FILENAME) and $TEST
      File.open(FILENAME, 'w', '0200'){|i|
        i.write("RMzas Game Resources Tracker(V1) [#{RGSS_VER}]\n\n")
      }
    end
    # 生成Win32API实例
    regopenkeyex = Win32API.new('advapi32', 'RegOpenKeyEx', 'lpiip', 'l')
    regqueryvalueex = Win32API.new('advapi32', 'RegQueryValueEx', 'lppppp', 'l')
    # 准备相应RPG Maker版本的注册表地址与键名信息
    case RGSS_VER
    when :XP
      path = ['SOFTWARE\Enterbrain\RGSS\RTP',  'Standard']
    when :VX
      path = ['SOFTWARE\Enterbrain\RGSS2\RTP', 'RPGVX']
    when :VXAce
      path = ['SOFTWARE\Enterbrain\RGSS3\RTP', 'RPGVXAce']
    end
    # 准备获取开发环境中的RTP绝对路径
    hKey, rtp_path, cbData = '    ', '    ' * 32, [128].pack('l')
    regopenkeyex.call(-2147483646, path[0], 0, 0x20019, hKey)
    hKey = hKey.unpack('l')[0]
    regqueryvalueex.call(hKey, path[1], 0, 0, rtp_path, cbData)
    Win32API.new('advapi32', 'RegCloseKey', 'l', 'l').call(hKey)
    # 准备系统编码转 UTF-8 的相关API
    multibt2wc = Win32API.new('kernel32', 'MultiByteToWideChar', 'ilpipi', 'i')
    wc2multibt = Win32API.new('kernel32', 'WideCharToMultiByte', 'ilpipipp', 'i')
    i = multibt2wc.call(0, 0, rtp_path, -1, nil, 0)
    buffer = "\0" * (i*2)
    multibt2wc.call(0, 0, rtp_path, -1, buffer, buffer.size / 2)
    i = wc2multibt.call(65001, 0, buffer, -1, nil, 0, nil, nil)
    result = "\0" * i
    wc2multibt.call(65001, 0, buffer, -1, result, result.size, nil, nil)
    # 将开发软件的RTP绝对路径写入类变量,用斜杠代替双反斜杠
    @@rtp_path = result.chop.gsub(/\\/) { "/" }
    @@rtp_path += "/"
  end
  
  def self.give_msgbox(message = "")
    @already_alert ||= []
    message = message[0] if !message.is_a?(String)
    if !@already_alert.include?(message)
      msg1 = "没有找到文件:#{message} ,"
      if RGSS_VER == :VX or RGSS_VER == :VXAce
        msg2 = ($TEST ? "请检查并修正." : "请您报告给作者,按Ctrl+C可复制文本信息.")
      else
        msg2 = ($DEBUG ? "请检查并修正." : "请您报告给作者,按Ctrl+C可复制文本信息.")
      end
      @already_alert << message
      RGSS_VER == :VXAce ? msgbox_p(msg1, msg2) : print(msg1, msg2)
    end
  end
  
  def self.insert_info(file = "")
    return if !FileTest.exist?(FILENAME)
    file = file[0] if !file.is_a?(String)
    # 取得文件是否存在的判断结果
    result = RMzas_Resources_Tracker.local_file_exist?(file)
    case result
    when 1;      file = "[YES]" + file
    when 2;      file = "[RTP]" + file
    when 0;      file = "[404]" + file
    end
    # 判断是否写入地图ID,若是VXAce,则可能追加 $game_map.display_name
    if NEED_MAPID
      mapinfo = sprintf("%03d", $game_map.map_id)
      info = "[MapID:#{mapinfo}]" + file
      if RGSS_VER == :VXAce and $game_map.map_id != 0
        display_name = $game_map.display_name
        info += "【地图名:#{display_name}】" if display_name != ""
      end
    else
      info = file
    end
    # 向导出列表文件写入文本内容
    File.open(FILENAME, 'a+', '0700'){|i| 
      i.write(info + "\n") if !i.read.to_s.include?(file)
    }
  end
  
  def self.local_file_exist?(filename = "")
    # 通过分割带相对路径的文件名,获取媒体文件的类型
    type = filename.split(/\//)[0]
    # 列出RPG Maker软件支持的媒体文件格式
    if type == "Graphics"
      sufarr = ['png', 'jpg', 'bmp', 'jpeg']
    elsif type == "Audio"
      sufarr = ['ogg', 'mp3', 'wma', 'mid', 'wav']
    end
    # 如果游戏目录下和开发软件RTP路径中存在同名文件,默认是优先游戏目录下的
    # 返回1表示在相对路径的游戏目录内判断存在,返回2表示在绝对路径的开发软
    # 件RTP路径内判断存在,返回0表示在以上两个位置中均未找到指定名称的文件。
    for sx in sufarr
      return 1 if FileTest.exist?(filename + ".#{sx}")
      return 2 if FileTest.exist?(@@rtp_path + filename + ".#{sx}")
    end
    return 0
  end

end


class Bitmap
  
  alias rmzas_resources_initialize initialize unless $@
  def initialize(*arg)
    RMzas_Resources_Tracker.insert_info(arg) if arg[0].is_a?(String)
    begin
      rmzas_resources_initialize(*arg)
    rescue Errno::ENOENT
      RMzas_Resources_Tracker.give_msgbox(arg)
      rmzas_resources_initialize(1, 1)
    end
  end
  
end

module Audio
  
  class << self
    alias_method :rmzas_rstk_bgm_play, :bgm_play unless $@
    alias_method :rmzas_rstk_bgs_play, :bgs_play unless $@
    alias_method :rmzas_rstk_me_play, :me_play unless $@
    alias_method :rmzas_rstk_se_play, :se_play unless $@
  end
  
  def self.bgm_play(*arg)
    RMzas_Resources_Tracker.insert_info(arg)
    begin
      rmzas_rstk_bgm_play(*arg)
    rescue Errno::ENOENT
      RMzas_Resources_Tracker.give_msgbox(arg)
    end
  end
  
  def self.bgs_play(*arg)
    RMzas_Resources_Tracker.insert_info(arg)
    begin
      rmzas_rstk_bgs_play(*arg)
    rescue Errno::ENOENT
      RMzas_Resources_Tracker.give_msgbox(arg)
    end
  end
  
  def self.me_play(*arg)
    RMzas_Resources_Tracker.insert_info(arg)
    begin
      rmzas_rstk_me_play(*arg)
    rescue Errno::ENOENT
      RMzas_Resources_Tracker.give_msgbox(arg)
    end
  end
  
  def self.se_play(*arg)
    RMzas_Resources_Tracker.insert_info(arg)
    begin
      rmzas_rstk_se_play(*arg)
    rescue Errno::ENOENT
      RMzas_Resources_Tracker.give_msgbox(arg)
    end
  end

end

RMzas_Resources_Tracker.new

插入至脚本编辑器中Main的上方即可正常运行,可能不兼容其他实现方式的文件容错脚本,如果您使用了音量调整一类的脚本,可能会需要作针对性调整。该脚本目前处于尚待完善的状态。

在RPG Maker VX Ace上的使用效果示例,Resources.txt:

RMzas Game Resources Tracker(V1) [VXAce]
[MapID:000][RTP]Graphics/Titles1/Plain
[MapID:000][RTP]Graphics/Titles2/Forest
[MapID:000][RTP]Graphics/System/Window
[MapID:000][YES]Audio/BGM/Title
[MapID:000][RTP]Audio/SE/Decision3
[MapID:003][RTP]Graphics/Tilesets/Dungeon_A1
[MapID:003][RTP]Graphics/Tilesets/Dungeon_A2
[MapID:003][RTP]Graphics/Tilesets/Dungeon_A4
[MapID:003][RTP]Graphics/Tilesets/Dungeon_A5
[MapID:003][RTP]Graphics/Tilesets/Dungeon_B
[MapID:003][RTP]Graphics/Tilesets/Inside_B
[MapID:003][RTP]Graphics/Tilesets/Dungeon_C
[MapID:003][RTP]Graphics/Characters/Vehicle
[MapID:003][RTP]Graphics/System/Shadow
[MapID:003][RTP]Audio/SE/Cancel2

可以根据这份列表转移RTP素材,应该是有一些的实用性的,欢迎反馈

发布者

ML4455739

宣传站维护团队

发表评论

电子邮件地址不会被公开。