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
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
|
|
|