赞 | 12 |
VIP | 0 |
好人卡 | 0 |
积分 | 17 |
经验 | 0 |
最后登录 | 2020-8-22 |
在线时间 | 91 小时 |
Lv3.寻梦者
- 梦石
- 0
- 星屑
- 1680
- 在线时间
- 91 小时
- 注册时间
- 2019-5-16
- 帖子
- 45
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
本帖最后由 Aephiex 于 2019-6-6 23:50 编辑
我不是很清楚每个脚本自带的那一串数字的功能。我已经用自己写的脚本管理模块多次导出导入,那一串谜之数字全部变成了nil,而游戏并未出现任何功能问题。所以我觉得可以发出来分享一下。
为避免可能的风险,建议每次执行脚本导入之前备份 "Data/Scripts.rvdata2" 。
此外,进行脚本导入期间,如果你的 RMVA 是开着的, "Data/Scripts.rvdata2" 的变化不会立刻反映到 RMVA 里,需要关掉 RMVA 再重新打开工程才能看到脚本的变化。否则的话,导入过的脚本可能会被 RMVA 的缓存覆盖。
- #!!! skip_if_destructive
- #==============================================================================
- # ◆ 脚本管理模块 by Aephiex
- #------------------------------------------------------------------------------
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- # http://www.apache.org/licenses/LICENSE-2.0
- #------------------------------------------------------------------------------
- #
- # 使用说明:
- # ◎ 创建 script_manager.txt ,在里面写入指令,再运行 Game.exe 来触发。
- # 脚本管理模块将会抢在游戏开始之前执行任务。
- # 该文件不能有任何多余字符!
- # ◎ 可用指令如下
- # export ->
- # • 导出脚本到 Scripts\ ,然后关闭游戏。
- # 脚本将以 002 [Vocab].rb 的格式决定文件名,并单独储存在每个文件中。
- # 不适宜出现在文件名中的特殊符号会被自动替换。
- # • 脚本的原本标题和排列顺序储存在 000 Mapping.txt 中,
- # 格式为:"Vocab->002 [Vocab].rb"
- # 没有指定文件名的行是一个只有标题、没有内容的脚本,
- # 而空行是一个既没有标题又没有内容的脚本。
- # • 000 Mapping.txt 是脚本导入的依据。
- # 可以通过调换行顺序来调换脚本顺序,也可以通过增删行来增删脚本。
- # 新文件名哪怕是 "新建 文本文档.txt" 都可以。
- # 不符合格式将会使这一行导入失败。
- # • 顺便一提,> 也是敏感字符之一,所以脚本标题不会影响到 000 Mapping.txt 的格式。
- # import ->
- # • 从 Scripts\ 导入脚本,然后关闭游戏。
- # blink ->
- # • 先执行导入,再执行导出以刷新 Scripts\ 的内容。然后关闭游戏。
- # destructive_import ->
- # • 执行破坏性的导入。然后关闭游戏。
- # 文件的开头写着 "#!!! skip_if_destructive" 的脚本会被跳过。
- # 符合特定格式的代码块会被移除。
- # 符合特定格式的代码块会被指定的其他代码块替换。
- # • Scripts\ 会被删除。
- # • 适合在制作发行包之前运行一次。由于是破坏性的,请勿在主分支中运行。
- # • 顺便一提,虽然此脚本是阿帕奇协议V2.0,
- # 但执行过破坏性导入以后,此脚本即消失,所以……
- # exit ->
- # • 什么也不做,直接关闭游戏。
- #
- #==============================================================================
- # * 特定格式
- #!!! remove_if_destructive
- # 我是要被删除的代码块
- #!!! end_remove_if_destructive
- #!!! replace_if_destructive
- # 我是要被取代的代码块
- #!!! with
- #~ # 我是要取代它的代码块
- #!!! end_replace_if_destructive
- module ScriptManager
- #--------------------------------------------------------------------------
- # ¤ 运行
- #--------------------------------------------------------------------------
- def self.run
- return if !File.exists?("script_manager.txt")
- mode = self.read("script_manager.txt")
- case mode
- when "export"
- self.export
- self.write("script_manager.txt", "watch")
- exit
- when "import"
- self.import
- self.write("script_manager.txt", "do nothing")
- exit
- when "blink"
- self.import
- self.export
- self.write("script_manager.txt", "watch")
- exit
- when "watch"
- t = File.mtime("Data/Scripts.rvdata2")
- flag = false
- if File.exist?("Scripts")
- Files.list("Scripts").each do |path|
- m = File.mtime(path)
- if m > t
- self.import
- self.export
- exit
- elsif m < t
- flag = true
- end
- end
- end
- if flag
- self.export
- exit
- end
- when "destructive_import"
- self.import(true)
- File.delete("script_manager.txt")
- self.deleteDirectory("Scripts")
- exit
- when "exit"
- exit
- end
- end
- #--------------------------------------------------------------------------
- # ¤ 导出
- #--------------------------------------------------------------------------
- def self.export
- self.deleteDirectory("Scripts")
- self.ensureDirectory("Scripts")
- p "extracting script..."
- script_mapper = []
- load_data("Data/Scripts.rvdata2").each_with_index do |(num, title, contents), i|
- contents = self.decrypt(contents)
- if contents.empty?
- script_mapper.push(title.empty? ? "" : "#{title}->")
- next
- end
- filename = sprintf("%03d [%s].rb", i, title)
- filename.gsub!("/", "/")
- filename.gsub!("\\", "﹨")
- filename.gsub!(":", ":")
- filename.gsub!("*", "﹡")
- filename.gsub!("\"", """)
- filename.gsub!("<", "<")
- filename.gsub!(">", ">")
- filename.gsub!("|", "|")
- filename.gsub!("?", "?")
- contents.gsub!(/\r\n/, "\n")
- self.write("Scripts/#{filename}", contents)
- script_mapper.push("#{title}->#{filename}")
- p filename
- end
- self.write("Scripts/000 Mapping.txt", script_mapper.join("\n"))
- t = Time.new
- File.utime(t, t, "Data/Scripts.rvdata2")
- File.utime(t, t, "Scripts/")
- p "extraction complete."
- end
- #--------------------------------------------------------------------------
- # ¤ 导入
- #--------------------------------------------------------------------------
- def self.import(destructively = false)
- self.ensureDirectory("Scripts")
- p "loading script..."
- scripts = []
- mapper_info = self.read("Scripts/000 Mapping.txt")
- script_mapper = mapper_info.split("\n")
- script_mapper.push("") if mapper_info.slice(-1, 1) == "\n"
- script_mapper.each do |entry|
- title = ""
- contents = ""
- if !entry.empty?
- if entry =~ /^(.*)->(.*)$/
- title = $1
- contents = $2.empty? ? "" : self.read("Scripts/#{$2}")
- if destructively
- next if contents =~ /^#!!! skip_if_destructive/
- contents.gsub!(/#!!! remove_if_destructive\n.*?#!!! end_remove_if_destructive\n?/m, "")
- contents.gsub!(/#!!! replace_if_destructive\n.*?#!!! with\n(.*?)#!!! end_replace_if_destructive\n?/m) { $1.gsub(/^#~/, "") }
- end
- p title
- else
- title = "<ERROR>"
- contents = "# Error loading this script:\n# #{entry}"
- end
- end
- scripts.push([nil, title, self.encrypt(contents)])
- end
- save_data(scripts, "Data/Scripts.rvdata2")
- p "script loaded."
- end
- #--------------------------------------------------------------------------
- # ¤ 读文件
- #--------------------------------------------------------------------------
- def self.read(path)
- File.open(path, 'r:utf-8') {|f| return f.read() }
- end
- #--------------------------------------------------------------------------
- # ¤ 写文件
- #--------------------------------------------------------------------------
- def self.write(path, contents)
- File.open(path, 'w:utf-8') {|f| f.write(contents) }
- end
- #--------------------------------------------------------------------------
- # ¤ 如果文件夹不存在则创建
- #--------------------------------------------------------------------------
- def self.ensureDirectory(path)
- Dir.mkdir(path) if !File.exist?(path)
- end
- #--------------------------------------------------------------------------
- # ¤ 删除文件夹和所有内容
- #--------------------------------------------------------------------------
- def self.deleteDirectory(path)
- return if !File.exist?(path)
- if File.directory?(path)
- self.list(path).each {|title| self.deleteDirectory(title) }
- Dir.rmdir(path)
- else
- File.delete(path)
- end
- end
- #--------------------------------------------------------------------------
- # ¤ 列出直属某文件夹的所有文件名
- #--------------------------------------------------------------------------
- def self.list(directory, filter = nil)
- directory += "/" if directory.slice(-1, 1) != "/"
- directory += "*"
- array = Dir.glob(directory)
- array.reject! {|str| !str =~ filter } if filter.is_a?(Regexp)
- return array
- end
- #--------------------------------------------------------------------------
- # ¤ 压缩文本
- #--------------------------------------------------------------------------
- def self.encrypt(string)
- return Zlib::Deflate.deflate(string)
- end
- #--------------------------------------------------------------------------
- # ¤ 解压文本
- #--------------------------------------------------------------------------
- def self.decrypt(string)
- return Zlib::Inflate.inflate(string).force_encoding("UTF-8")
- end
- end
- ScriptManager.run
复制代码
---------- 2019/6/6 ----------
• 增加了 watch 指令。会自动检查脚本的最后修改时间,如果有任何脚本文件的最后修改时间晚于 "Data/Scripts.rvdata2" 则自动 blink;否则,如果有任何脚本文件的最后修改时间早于 "Data/Scripts.rvdata2" 则自动导出。每次导出文件,都会将脚本文件和 "Data/Scripts.rvdata2" 的最后修改时间设为完全相同,且只在所有文件的最后修改时间都完全相同的情况下,watch 模式的脚本管理模块才会不进行任何动作。 |
|