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.
182 lines
5.6 KiB
182 lines
5.6 KiB
3 years ago
|
require "sys"
|
||
|
require "filesystem"
|
||
|
require "util"
|
||
|
require "mpq_util"
|
||
|
local storm = require 'ffi.storm'
|
||
|
local stormlib = require 'ffi.stormlib'
|
||
|
|
||
|
jasshelper = {}
|
||
|
|
||
|
jasshelper.path = fs.ydwe_path() / "plugin" / "jasshelper"
|
||
|
jasshelper.exe_path = jasshelper.path / "jasshelper.exe"
|
||
|
|
||
|
local config = [[
|
||
|
[jasscompiler]
|
||
|
%q
|
||
|
"%s$COMMONJ $BLIZZARDJ $WAR3MAPJ"
|
||
|
]]
|
||
|
|
||
|
|
||
|
-- 根据版本获取YDWE自带的Jass库函数(bj和cj)路径
|
||
|
-- version - 魔兽版本,数
|
||
|
-- 返回:cj路径,bj路径,都是fs.path
|
||
|
function jasshelper.default_jass_libs(self, version)
|
||
|
if version:is_new() then
|
||
|
return (fs.ydwe_path() / "jass" / "system" / "ht" / "common.j"),
|
||
|
(fs.ydwe_path() / "jass" / "system" / "ht" / "blizzard.j")
|
||
|
else
|
||
|
return (fs.ydwe_path() / "jass" / "system" / "rb" / "common.j"),
|
||
|
(fs.ydwe_path() / "jass" / "system" / "rb" / "blizzard.j")
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- 准备魔兽争霸3的Jass库函数(common.j和blizzard.j)供语法检查用
|
||
|
-- 如果地图中有,则优先使用地图的,否则使用自带的
|
||
|
-- map_path - 地图路径,fs.path对象
|
||
|
-- 返回2个值:cj路径,bj路径,都是fs.path。
|
||
|
function jasshelper.prepare_jass_libs(self, map_path, version)
|
||
|
local common_j_path = self.path / "common.j"
|
||
|
local blizzard_j_path = self.path / "blizzard.j"
|
||
|
local map_has_cj = false
|
||
|
local map_has_bj = false
|
||
|
|
||
|
-- 从地图中解压缩两个重要文件到jasshelper目录(供语法检查用)
|
||
|
local mpq = stormlib.open(map_path, true)
|
||
|
if mpq then
|
||
|
-- 如果地图中导入了,优先使用地图的
|
||
|
if mpq:has_file("common.j") then
|
||
|
mpq:extract("common.j", common_j_path)
|
||
|
map_has_cj = true
|
||
|
elseif mpq:has_file("scripts\\common.j") then
|
||
|
mpq:extract("scripts\\common.j", common_j_path)
|
||
|
map_has_cj = true
|
||
|
end
|
||
|
|
||
|
if mpq:has_file("blizzard.j") then
|
||
|
mpq:extract("blizzard.j", blizzard_j_path)
|
||
|
map_has_bj = true
|
||
|
elseif mpq:has_file("scripts\\blizzard.j") then
|
||
|
mpq:extract("scripts\\blizzard.j", blizzard_j_path)
|
||
|
map_has_bj = true
|
||
|
end
|
||
|
mpq:close()
|
||
|
else
|
||
|
log.warn("Cannot open map archive, using default bj and cj instead.")
|
||
|
end
|
||
|
|
||
|
-- 是否和当前版本一致?
|
||
|
local use_default = (war3_version:is_new() == version:is_new())
|
||
|
local default_common_j_path, default_blizzard_j_path = self:default_jass_libs(version)
|
||
|
if not map_has_cj then
|
||
|
if use_default then
|
||
|
if storm.has_file("common.j") then
|
||
|
storm.extract_file(common_j_path, "common.j")
|
||
|
elseif storm.has_file("scripts\\common.j") then
|
||
|
storm.extract_file(common_j_path, "scripts\\common.j")
|
||
|
else
|
||
|
common_j_path = default_common_j_path
|
||
|
end
|
||
|
else
|
||
|
common_j_path = default_common_j_path
|
||
|
end
|
||
|
end
|
||
|
if not map_has_bj then
|
||
|
if use_default then
|
||
|
if storm.has_file("blizzard.j") then
|
||
|
storm.extract_file(blizzard_j_path, "blizzard.j")
|
||
|
elseif storm.has_file("scripts\\blizzard.j") then
|
||
|
storm.extract_file(blizzard_j_path, "scripts\\blizzard.j")
|
||
|
else
|
||
|
blizzard_j_path = default_blizzard_j_path
|
||
|
end
|
||
|
else
|
||
|
blizzard_j_path = default_blizzard_j_path
|
||
|
end
|
||
|
end
|
||
|
|
||
|
return common_j_path, blizzard_j_path
|
||
|
end
|
||
|
|
||
|
|
||
|
-- 使用JassHelper编译地图
|
||
|
-- map_path - 地图路径,fs.path对象
|
||
|
-- common_j_path - common.j路径,fs.path对象
|
||
|
-- blizzard_j_path - blizzard.j路径,fs.path对象
|
||
|
-- option - 编译选项, table,目前支持参数:
|
||
|
-- enable_jasshelper - 启用JassHelper,true/false
|
||
|
-- enable_jasshelper_debug - 启用JassHelper的Debug,true/false
|
||
|
-- enable_jasshelper_optimization - 启用优化,true/false
|
||
|
-- 返回:true编译成功,false编译失败
|
||
|
function jasshelper.do_compile(self, map_path, common_j_path, blizzard_j_path, option)
|
||
|
local parameter = ""
|
||
|
|
||
|
-- 需要做vJass编译?
|
||
|
if option.enable_jasshelper then
|
||
|
-- debug选项(--debug)
|
||
|
if option.enable_jasshelper_debug then
|
||
|
parameter = parameter .. " --debug"
|
||
|
end
|
||
|
-- (关闭)优化选项(--nooptimize)
|
||
|
if not option.enable_jasshelper_optimization then
|
||
|
parameter = parameter .. " --nooptimize"
|
||
|
end
|
||
|
else
|
||
|
-- 不编译vJass选项(--nopreprocessor)
|
||
|
parameter = parameter .. " --nopreprocessor"
|
||
|
end
|
||
|
|
||
|
if option.enable_jasshelper_scriptonly then
|
||
|
return mpq_util:update_file(map_path, 'war3map.j',
|
||
|
function (map_handle, in_script_path)
|
||
|
local out_script_path = fs.ydwe_path() / "logs" / "jasshelper.j"
|
||
|
|
||
|
-- 生成命令行
|
||
|
local command_line = string.format('"%s"%s --scriptonly "%s" "%s" "%s" "%s"',
|
||
|
self.exe_path:string(),
|
||
|
parameter,
|
||
|
common_j_path:string(),
|
||
|
blizzard_j_path:string(),
|
||
|
in_script_path:string(),
|
||
|
out_script_path:string()
|
||
|
)
|
||
|
-- 执行并获取结果
|
||
|
if not sys.spawn(command_line, fs.ydwe_path(), true) then
|
||
|
return nil
|
||
|
end
|
||
|
|
||
|
return out_script_path
|
||
|
end
|
||
|
)
|
||
|
else
|
||
|
-- 生成命令行
|
||
|
local command_line = string.format('"%s"%s "%s" "%s" "%s"',
|
||
|
self.exe_path:string(),
|
||
|
parameter,
|
||
|
common_j_path:string(),
|
||
|
blizzard_j_path:string(),
|
||
|
map_path:string()
|
||
|
)
|
||
|
|
||
|
-- 执行并获取结果
|
||
|
return sys.spawn(command_line, fs.ydwe_path(), true)
|
||
|
end
|
||
|
|
||
|
end
|
||
|
|
||
|
function jasshelper.compile(self, map_path, option)
|
||
|
log.trace("JassHelper compilation start.")
|
||
|
local common_j_path, blizzard_j_path = self:prepare_jass_libs(map_path, option.runtime_version)
|
||
|
if option.pjass == '1' then
|
||
|
io.save(fs.ydwe_path() / 'jasshelper.conf', config:format('../pjass/pjass-classic.exe', ''))
|
||
|
else
|
||
|
if option.runtime_version:is_new() then
|
||
|
io.save(fs.ydwe_path() / 'jasshelper.conf', config:format('../pjass/pjass-latest.exe', ''))
|
||
|
else
|
||
|
io.save(fs.ydwe_path() / 'jasshelper.conf', config:format('../pjass/pjass-latest.exe', '+rb '))
|
||
|
end
|
||
|
end
|
||
|
local res = self:do_compile(map_path, common_j_path, blizzard_j_path, option)
|
||
|
fs.remove(fs.ydwe_path() / 'jasshelper.conf')
|
||
|
return res
|
||
|
end
|