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.
197 lines
5.2 KiB
197 lines
5.2 KiB
local stormlib = require 'ffi.stormlib'
|
|
local w2l = require 'w3x2lni'
|
|
local mapdump = require 'mapdump'
|
|
|
|
local mt = {}
|
|
mt.__index = mt
|
|
|
|
function mt:process_create(command_line, current_dir)
|
|
if self.h then
|
|
self.h:kill()
|
|
self.h = nil
|
|
end
|
|
|
|
local p = sys.process()
|
|
p:hide_window()
|
|
if not p:create(nil, command_line, current_dir) then
|
|
log.error('Executed failed: ', command_line)
|
|
return
|
|
end
|
|
log.trace('Executed: ', command_line)
|
|
self.h = p
|
|
end
|
|
|
|
function mt:__gc()
|
|
if self.h then
|
|
self.h:kill()
|
|
self.h = nil
|
|
end
|
|
end
|
|
|
|
local ydhost = setmetatable({}, mt)
|
|
|
|
local function getplayernum(mappath)
|
|
local ok, result = pcall(function()
|
|
local map = stormlib.open(mappath, true)
|
|
if not map then
|
|
return 0
|
|
end
|
|
local w3i = map:load_file('war3map.w3i')
|
|
local tbl = w2l:read_w3i(w3i)
|
|
local n = 0
|
|
if tbl['选项']['自定义玩家分组'] == 0 then
|
|
n = tbl['玩家']['玩家数量']
|
|
else
|
|
for i = 1, tbl['玩家']['玩家数量'] do
|
|
if tbl['玩家'..i]['类型'] == 1 then
|
|
n = n + 1
|
|
end
|
|
end
|
|
end
|
|
map:close()
|
|
return n
|
|
end)
|
|
if ok then return result end
|
|
return 0
|
|
end
|
|
|
|
|
|
local function single_test(commandline, mappath)
|
|
return '"' .. (fs.war3_path() / 'war3.exe'):string() .. '" -loadfile "' .. mappath:string() .. '"' .. commandline
|
|
end
|
|
|
|
local function path_sub(a, b)
|
|
local i = a
|
|
local r = fs.path('')
|
|
while i ~= '' and i ~= b do
|
|
r = i:filename() / r
|
|
i = i:parent_path()
|
|
end
|
|
return r
|
|
end
|
|
|
|
local function host_copy_dll(curdir)
|
|
pcall(fs.copy_file, fs.ydwe_path() / 'bin' / 'vcruntime140.dll', curdir / 'vcruntime140.dll', true)
|
|
pcall(fs.copy_file, fs.ydwe_path() / 'bin' / 'msvcp140.dll', curdir / 'msvcp140.dll', true)
|
|
end
|
|
|
|
local function get_war3_version()
|
|
if global_config["War3Patch"]["Option"] == "1" then
|
|
if global_config["MapSave"]["Option"] == "1" then
|
|
return sys.war3_version {
|
|
major = 1,
|
|
minor = 20,
|
|
revision = 4,
|
|
build = 6074,
|
|
}
|
|
else
|
|
return sys.war3_version {
|
|
major = 1,
|
|
minor = 24,
|
|
revision = 4,
|
|
build = 6387,
|
|
}
|
|
end
|
|
elseif global_config["War3Patch"]["Option"] == "2" then
|
|
return sys.war3_version {
|
|
file = fs.ydwe_path() / 'share' / 'patch' / global_config["War3Patch"]["DirName"] / 'Game.dll'
|
|
}
|
|
end
|
|
return war3_version
|
|
end
|
|
|
|
local function host_save_config(curdir, mappath, autostart)
|
|
local ver = get_war3_version()
|
|
local jasspath
|
|
if ver:is_new() then
|
|
jasspath = fs.ydwe_path() / "jass" / "system" / "ht"
|
|
else
|
|
jasspath = fs.ydwe_path() / "jass" / "system" / "rb"
|
|
end
|
|
local of = io.open(curdir / 'map.cfg', 'wb')
|
|
local ok, e = pcall(mapdump, mappath, jasspath,
|
|
function(s)
|
|
of:write(s .. '\n')
|
|
end
|
|
)
|
|
of:close()
|
|
if not ok then
|
|
log.error('')
|
|
end
|
|
local tbl = {
|
|
lan_war3version = ver.minor,
|
|
bot_defaultgamename = mappath:filename():string(),
|
|
bot_autostart = autostart,
|
|
bot_mappath = path_sub(mappath, fs.war3_path()):string(),
|
|
bot_mapcfgpath = 'map.cfg',
|
|
}
|
|
local str = ''
|
|
for k, v in pairs(tbl) do
|
|
str = str .. tostring(k) .. ' = ' .. tostring(v) .. '\n'
|
|
end
|
|
io.save(curdir / 'ydhost.cfg', str)
|
|
end
|
|
|
|
local function host_test(commandline, mappath)
|
|
local host_test = tonumber(global_config["HostTest"]["Option"])
|
|
local curdir = fs.ydwe_path() / 'plugin' / 'ydhost'
|
|
host_copy_dll(curdir)
|
|
host_save_config(curdir, mappath, host_test + 1)
|
|
ydhost:process_create(curdir / 'ydhost.exe', curdir)
|
|
local cmd = '"' .. (fs.war3_path() / 'war3.exe'):string() .. '"' .. commandline .. ' -auto'
|
|
if host_test == 0 then
|
|
return cmd, 1
|
|
end
|
|
return cmd, getplayernum(mappath)
|
|
end
|
|
|
|
-- 本函数在测试地图时使用
|
|
-- event_data - 事件参数,table,包含以下值
|
|
-- map_path - 保存的地图路径,字符串类型
|
|
-- application_name - 应用程序名,字符串对象
|
|
-- command_line - 命令行,字符串对象
|
|
-- 返回:非负表示成功,负数表示失败。如成功且无特殊情况原则上应该返回0
|
|
function event.EVENT_TEST_MAP(event_data)
|
|
log.debug("********************* on test start *********************")
|
|
|
|
-- 刷新配置数据
|
|
global_config_reload()
|
|
|
|
-- 获取当前测试的地图名
|
|
local mappath = fs.path(event_data.map_path)
|
|
log.debug("Testing " .. mappath:string())
|
|
log.debug("Testing " .. event_data.command_line)
|
|
|
|
-- 附加命令行
|
|
local commandline = ""
|
|
local n = 0
|
|
|
|
-- 是否OpenGL方式?
|
|
if global_config["MapTest"]["LaunchRenderingEngine"] == "OpenGL" then
|
|
commandline = commandline .. " -opengl"
|
|
end
|
|
|
|
-- 是否窗口方式?
|
|
if global_config["MapTest"]["LaunchWindowed"] ~= "0" then
|
|
commandline = commandline .. " -window"
|
|
end
|
|
|
|
commandline = commandline .. ' -ydwe "' .. fs.ydwe_path():string() .. '"'
|
|
|
|
log.debug("Testing " .. tostring(global_config["MapTest"]["EnableHost"]))
|
|
if global_config["MapTest"]["EnableHost"] == "1" then
|
|
commandline, n = host_test(commandline, mappath)
|
|
else
|
|
commandline, n = single_test(commandline, mappath), 1
|
|
end
|
|
|
|
local result = false
|
|
-- 启动魔兽开始测试...
|
|
for i = 1, n do
|
|
local war3_helper_dll = fs.ydwe_path() / "plugin" / "warcraft3" / "yd_loader.dll"
|
|
result = sys.spawn_inject(event_data.application_name, commandline, nil, war3_helper_dll)
|
|
end
|
|
|
|
log.debug("********************* on test end *********************")
|
|
if result then return 0 else return -1 end
|
|
end
|
|
|