SoUI 0.5版本占坑
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

211 lines
7.0 KiB

require "compile.inject_code"
require "compile.wave"
require "compile.template"
require "compile.cjass"
require "compile.jasshelper"
require "compile.native"
require "mpq_util"
-- 确定应当把地图保存为适合老版本(< 1.24)还是新版本(>= 1.24)的
-- 对于保存为双份,按照当前魔兽版本处理
-- save_type - 保存类型,0到3的取值,意义同设置程序,从上到下依次为0到3
-- runtime_version - 魔兽版本
-- 返回值: 数,如果保存的目标版本和当前版本一致,返回当前版本,否则视情况返回1.20或者1.24(和当前版本不同)
local function determine_map_version(save_type, runtime_version)
-- 固定旧版本
if save_type == 1 then
return runtime_version:is_new() and runtime_version:old() or runtime_version
-- 固定新版本
elseif save_type == 2 then
return runtime_version:is_new() and runtime_version or runtime_version:new()
else
-- 按照当前版本或者双份
return runtime_version
end
end
-- 编译地图
-- map_path - 地图路径,string或者fs.path
-- option - 编译选项,table类型,支持的选项:
-- enable_preprocessor - 启用wave预处理器,true/false
-- enable_jasshelper - 启用JassHelper,true/false
-- enable_jasshelper_debug - 启用JassHelper的Debug,true/false
-- enable_jasshelper_optimization - 启用优化,true/false
-- enable_cjass - 启用cJass编译器,true/false
-- script_injection - 代码注入选项,整数,0表示智能注入,1表示不注入
-- runtime_version - 魔兽版本
-- 返回:true表示成功,false表示失败
local function compile_map(map_path, option)
-- 统一处理fs.path
if type(map_path) == "string" then map_path = fs.path(map_path) end
-- 结果
local result = nil
log.trace("Save version " .. tostring(option.runtime_version))
local compile_t = {
['option'] = option,
['map_path'] = map_path,
}
-- 如果JassHelper开启,执行正常编译
if option.enable_jasshelper then
result = mpq_util:update_file(map_path, "war3map.j",
-- 解压缩地图脚本,处理然后写回
function (map_handle, in_script_path)
-- 开始处理
log.trace("Processing " .. in_script_path:filename():string())
compile_t.input = in_script_path
compile_t.output = nil
compile_t.map_handle = map_handle
compile_t.inject_file = function (file_path, path_in_archive)
log.trace("[stormlib]import file", path_in_archive)
return map_handle:add_file(path_in_archive, file_path)
end
-- 未启用用cJass
if not option.enable_cjass then
-- 根据注入选项进行处理(由于Lua的closure,此处可以访问“父”函数的局部变量)
if option.script_injection == 0 then
if not inject_code:compile(compile_t) then
return nil
end
compile_t.input = compile_t.output
end
-- Wave预处理
if not wave:compile(compile_t) then
return nil
end
compile_t.input = compile_t.output
end
if not template:compile(compile_t) then
return nil
end
return compile_t.output
end
)
-- 开始调用编译工具编译
if result then
-- 调用cJass
if option.enable_cjass then
result = cjass:compile(map_path, option)
end
-- 调用jasshelepr
if result then
result = jasshelper:compile(map_path, option)
end
end
native:compile(compile_t)
else
-- 只做语法检查
result = jasshelper:compile(map_path, option)
end
return result
end
-- 本函数当保存地图时调用
-- event_data - 事件参数。table类型,包含了以下成员
-- map_path - 保存的地图路径,字符串类型
-- 返回值:0和正数表示保存成功,负数表示保存失败。如果成功编译,一般返回0
function event.EVENT_SAVE_MAP(event_data)
log.debug("********************* on save start *********************")
-- 刷新配置数据
global_config_reload()
-- 当前保存的地图路径
local map_path = fs.path(event_data.map_path)
log.trace("Saving " .. map_path:string())
-- 获取保存类型
local save_type = tonumber(global_config["MapSave"]["Option"])
-- 获取保存选项
local save_option = {
-- 是否启用JassHelper
enable_jasshelper = (global_config["ScriptCompiler"]["EnableJassHelper"] ~= "0"),
-- 是否使用脚本模式编译
enable_jasshelper_scriptonly = (global_config["ScriptCompiler"]["EnableJassHelperScriptOnly"] == "1"),
-- 是否是调试模式
enable_jasshelper_debug = (global_config["ScriptCompiler"]["EnableJassHelperDebug"] == "1"),
-- 是否优化地图
enable_jasshelper_optimization = (global_config["ScriptCompiler"]["EnableJassHelperOptimization"] ~= "0"),
-- 是否启用cJass
enable_cjass = (global_config["ScriptCompiler"]["EnableCJass"] == "1"),
-- 目标魔兽版本
runtime_version = determine_map_version(save_type, war3_version),
-- 代码注入选项
script_injection = tonumber(global_config["ScriptInjection"]["Option"]),
-- 是否启用YDTrigger
enable_yd_trigger = plugin.loaders['YDTrigger'] ~= nil,
-- pjass的版本
pjass = global_config["PJass"]["Option"],
}
-- cjass和脚本注入不能共存
if save_option.enable_cjass then
save_option.script_injection = false
end
-- 如果保存双份,需要预先拷贝
local map_path_aux = nil
if save_type == 3 then
-- 决定第二份的路径
if save_option.runtime_version:is_new() then
map_path_aux = fs.aux_filename(map_path, "hashtable")
else
map_path_aux = fs.aux_filename(map_path, "returnbug")
end
log.trace("Making copy of the original map.")
-- true代表覆盖现有文件。false不会覆盖
pcall(fs.copy_file, map_path, map_path_aux, true)
end
-- 编译地图
local result = compile_map(map_path, save_option)
-- 如果有第二份,此时处理第二份
if map_path_aux then
log.trace("Processing second map")
save_option.runtime_version = save_option.runtime_version:is_new() and save_option.runtime_version:old() or save_option.runtime_version:new()
compile_map(map_path_aux, save_option)
end
log.debug("Result " .. tostring(result))
log.debug("********************* on save end *********************")
if result then return 0 else return -1 end
end
-- 本函数当保存地图时调用
-- event_data - 事件参数。table类型,包含了以下成员
-- map_path - 保存的地图路径,字符串类型
function event.EVENT_PRE_SAVE_MAP(event_data)
log.debug("********************* on pre_save start *********************")
local map_path = fs.path(event_data.map_path)
log.trace("Saving " .. map_path:string())
-- 如果地图文件带有只读属性,则先询问是否去掉只读属性
-- 128 == 0200 S_IWUSR
if fs.exists(map_path) and 0 == (map_path:permissions() & 128) then
if gui.yesno_message(nil, _("Whether to remove the read-only attribute from \"%s\"?"), map_path:string()) then
log.trace("Remove the read-only attribute.")
map_path:add_permissions(128)
else
log.trace("Don't the remove read-only attribute.")
end
end
log.debug("********************* on pre_save end *********************")
return 0
end