Add updater
This commit is contained in:
parent
c16ef8ff83
commit
43f5603aa4
@ -26,39 +26,15 @@ function string:truncate(length)
|
||||
return self:sub(1, length - 3) .. "..."
|
||||
end
|
||||
|
||||
local maincampaign = LUI.MenuBuilder.m_types_build["main_campaign"]
|
||||
LUI.MenuBuilder.m_types_build["main_campaign"] = function(a1, a2)
|
||||
local menu = maincampaign(a1, a2)
|
||||
local buttonlist = menu:getChildById("main_campaign_list")
|
||||
|
||||
local button = menu:AddButton("$_MODS", function()
|
||||
LUI.addmenubutton("main_campaign", {
|
||||
index = 6,
|
||||
id = "mods_menu-button",
|
||||
text = "$_MODS",
|
||||
description = "Load installed mods.",
|
||||
callback = function()
|
||||
LUI.FlowManager.RequestAddMenu(nil, "mods_menu")
|
||||
end, nil, true, nil, {
|
||||
desc_text = "Open mods menu"
|
||||
})
|
||||
|
||||
buttonlist:removeElement(button)
|
||||
buttonlist:insertElement(button, 6)
|
||||
button.id = "mods_menu-button"
|
||||
|
||||
local hintbox = menu.optionTextInfo
|
||||
local firstbutton = buttonlist:getFirstChild()
|
||||
hintbox:dispatchEventToRoot({
|
||||
name = "set_button_info_text",
|
||||
text = firstbutton.properties.desc_text,
|
||||
immediate = true
|
||||
})
|
||||
|
||||
menu:CreateBottomDivider()
|
||||
menu:AddBottomDividerToList(buttonlist:getLastChild())
|
||||
menu:removeElement(menu.optionTextInfo)
|
||||
|
||||
LUI.Options.InitScrollingList(menu.list, nil)
|
||||
menu:CreateBottomDivider()
|
||||
menu.optionTextInfo = LUI.Options.AddOptionTextInfo(menu)
|
||||
|
||||
return menu
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
LUI.MenuBuilder.m_types_build["mods_menu"] = function(a1)
|
||||
local menu = LUI.MenuTemplate.new(a1, {
|
||||
@ -70,9 +46,11 @@ LUI.MenuBuilder.m_types_build["mods_menu"] = function(a1)
|
||||
})
|
||||
|
||||
menu:AddButton("$_OPEN STORE", function()
|
||||
LUI.FlowManager.RequestAddMenu(nil, "mod_store_menu")
|
||||
if (LUI.MenuBuilder.m_types_build["mod_store_menu"]) then
|
||||
LUI.FlowManager.RequestAddMenu(nil, "mod_store_menu")
|
||||
end
|
||||
end, nil, true, nil, {
|
||||
desc_text = "Open the menu store"
|
||||
desc_text = "Download and install mods."
|
||||
})
|
||||
|
||||
local modfolder = game:getloadedmod()
|
@ -1119,11 +1119,11 @@ namespace ui_scripting::lua
|
||||
event.name = "http_request_done";
|
||||
if (result.has_value())
|
||||
{
|
||||
event.arguments = { id, true, result.value() };
|
||||
event.arguments = {id, true, result.value()};
|
||||
}
|
||||
else
|
||||
{
|
||||
event.arguments = { id, false };
|
||||
event.arguments = {id, false};
|
||||
}
|
||||
|
||||
notify(event);
|
||||
@ -1134,7 +1134,7 @@ namespace ui_scripting::lua
|
||||
|
||||
game_type["sha"] = [](const game&, const std::string& data)
|
||||
{
|
||||
return utils::cryptography::sha1::compute(data, true);
|
||||
return utils::string::to_upper(utils::cryptography::sha1::compute(data, true));
|
||||
};
|
||||
|
||||
game_type["environment"] = [](const game&)
|
||||
@ -1142,6 +1142,13 @@ namespace ui_scripting::lua
|
||||
return GIT_BRANCH;
|
||||
};
|
||||
|
||||
game_type["binaryname"] = [](const game&)
|
||||
{
|
||||
char name[MAX_PATH] = {0};
|
||||
GetModuleBaseName(GetCurrentProcess(), GetModuleHandle(NULL), name, MAX_PATH);
|
||||
return std::string(name);
|
||||
};
|
||||
|
||||
struct player
|
||||
{
|
||||
};
|
||||
|
@ -13,7 +13,7 @@ namespace ui_scripting::lua::engine
|
||||
{
|
||||
namespace
|
||||
{
|
||||
const auto mods_menu_script = utils::nt::load_resource(LUI_MODS_MENU);
|
||||
const auto updater_script = utils::nt::load_resource(LUI_UPDATER_MENU);
|
||||
|
||||
float screen_max[2];
|
||||
|
||||
@ -413,7 +413,7 @@ namespace ui_scripting::lua::engine
|
||||
get_scripts().clear();
|
||||
clear_menus();
|
||||
|
||||
//load_code(mods_menu_script);
|
||||
load_code(updater_script);
|
||||
|
||||
load_scripts("ui_scripts/");
|
||||
load_scripts("h2-mod/ui_scripts/");
|
||||
|
@ -23,4 +23,4 @@
|
||||
|
||||
#define LUA_ANIMATION_SCRIPT 314
|
||||
#define LUA_JSON_SCRIPT 315
|
||||
#define LUI_MODS_MENU 316
|
||||
#define LUI_UPDATER_MENU 316
|
||||
|
@ -100,7 +100,7 @@ MENU_MAIN RCDATA "resources/main.html"
|
||||
LUA_ANIMATION_SCRIPT RCDATA "resources/animation.lua"
|
||||
LUA_JSON_SCRIPT RCDATA "resources/json.lua"
|
||||
|
||||
LUI_MODS_MENU RCDATA "resources/mods_menu.lua"
|
||||
LUI_UPDATER_MENU RCDATA "resources/updater.lua"
|
||||
|
||||
#ifdef _DEBUG
|
||||
TLS_DLL RCDATA "../../build/bin/x64/Debug/tlsdll.dll"
|
||||
|
@ -1,121 +0,0 @@
|
||||
function createdivider(menu, text)
|
||||
local element = LUI.UIElement.new( {
|
||||
leftAnchor = true,
|
||||
rightAnchor = true,
|
||||
left = 0,
|
||||
right = 0,
|
||||
topAnchor = true,
|
||||
bottomAnchor = false,
|
||||
top = 0,
|
||||
bottom = 33.33
|
||||
})
|
||||
|
||||
element.scrollingToNext = true
|
||||
element:addElement(LUI.MenuBuilder.BuildRegisteredType("h1_option_menu_titlebar", {
|
||||
title_bar_text = Engine.ToUpperCase(Engine.Localize(text))
|
||||
}))
|
||||
|
||||
menu.list:addElement(element)
|
||||
end
|
||||
|
||||
local maincampaign = LUI.MenuBuilder.m_types_build["main_campaign"]
|
||||
LUI.MenuBuilder.m_types_build["main_campaign"] = function(a1, a2)
|
||||
local menu = maincampaign(a1, a2)
|
||||
local buttonlist = menu:getChildById("main_campaign_list")
|
||||
|
||||
local button = menu:AddButton("$_MODS", function()
|
||||
LUI.FlowManager.RequestAddMenu(nil, "mods_menu")
|
||||
end, nil, true, nil, {
|
||||
desc_text = "Open mods menu"
|
||||
})
|
||||
|
||||
buttonlist:removeElement(button)
|
||||
buttonlist:insertElement(button, 6)
|
||||
button.id = "mods_menu-button"
|
||||
|
||||
local hintbox = menu.optionTextInfo
|
||||
local firstbutton = buttonlist:getFirstChild()
|
||||
hintbox:dispatchEventToRoot({
|
||||
name = "set_button_info_text",
|
||||
text = firstbutton.properties.desc_text,
|
||||
immediate = true
|
||||
})
|
||||
|
||||
menu:CreateBottomDivider()
|
||||
menu:AddBottomDividerToList(buttonlist:getLastChild())
|
||||
menu:removeElement(menu.optionTextInfo)
|
||||
|
||||
LUI.Options.InitScrollingList(menu.list, nil)
|
||||
menu:CreateBottomDivider()
|
||||
menu.optionTextInfo = LUI.Options.AddOptionTextInfo(menu)
|
||||
|
||||
return menu
|
||||
end
|
||||
|
||||
function modsmenu(a1)
|
||||
local menu = LUI.MenuTemplate.new(a1, {
|
||||
menu_title = "$_MODS",
|
||||
exclusiveController = 0,
|
||||
menu_width = 400,
|
||||
menu_top_indent = LUI.MenuTemplate.spMenuOffset,
|
||||
showTopRightSmallBar = true
|
||||
})
|
||||
|
||||
local modfolder = game:getloadedmod()
|
||||
if (modfolder ~= "") then
|
||||
createdivider(menu, "$_Loaded mod: " .. modfolder)
|
||||
|
||||
menu:AddButton("$_UNLOAD", function()
|
||||
game:executecommand("unloadmod")
|
||||
end, nil, true, nil, {
|
||||
desc_text = "Unload the currently loaded mod"
|
||||
})
|
||||
end
|
||||
|
||||
createdivider(menu, "$_Available mods")
|
||||
|
||||
if (io.directoryexists("mods")) then
|
||||
local mods = io.listfiles("mods/")
|
||||
for i = 1, #mods do
|
||||
local desc = "Load " .. mods[i]
|
||||
local infofile = mods[i] .. "/mod.txt"
|
||||
local exists = io.fileexists(infofile)
|
||||
|
||||
if (exists) then
|
||||
desc = io.readfile(infofile)
|
||||
end
|
||||
|
||||
if (mods[i] ~= modfolder) then
|
||||
menu:AddButton("$_" .. mods[i], function()
|
||||
game:executecommand("loadmod " .. mods[i])
|
||||
end, nil, true, nil, {
|
||||
desc_text = desc
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
menu:AddBackButton(function(a1)
|
||||
Engine.PlaySound(CoD.SFX.MenuBack)
|
||||
LUI.FlowManager.RequestLeaveMenu(a1)
|
||||
end)
|
||||
|
||||
LUI.Options.InitScrollingList(menu.list, nil)
|
||||
menu:CreateBottomDivider()
|
||||
menu.optionTextInfo = LUI.Options.AddOptionTextInfo(menu)
|
||||
|
||||
return menu
|
||||
end
|
||||
|
||||
LUI.MenuBuilder.m_types_build["mods_menu"] = modsmenu
|
||||
|
||||
local localize = Engine.Localize
|
||||
Engine.Localize = function(...)
|
||||
local args = {...}
|
||||
|
||||
if (type(args[1]) == "string" and args[1]:sub(1, 2) == "$_") then
|
||||
return args[1]:sub(3, -1)
|
||||
end
|
||||
|
||||
return localize(table.unpack(args))
|
||||
end
|
339
src/client/resources/updater.lua
Normal file
339
src/client/resources/updater.lua
Normal file
@ -0,0 +1,339 @@
|
||||
LUI.menucallbacks = {}
|
||||
LUI.originalmenus = {}
|
||||
|
||||
LUI.onmenuopen = function(name, callback)
|
||||
if (not LUI.MenuBuilder.m_types_build[name]) then
|
||||
return
|
||||
end
|
||||
|
||||
if (not LUI.menucallbacks[name]) then
|
||||
LUI.menucallbacks[name] = {}
|
||||
end
|
||||
|
||||
luiglobals.table.insert(LUI.menucallbacks[name], callback)
|
||||
|
||||
if (not LUI.originalmenus[name]) then
|
||||
LUI.originalmenus[name] = LUI.MenuBuilder.m_types_build[name]
|
||||
LUI.MenuBuilder.m_types_build[name] = function(...)
|
||||
local args = {...}
|
||||
local menu = LUI.originalmenus[name](table.unpack(args))
|
||||
|
||||
for k, v in luiglobals.next, LUI.menucallbacks[name] do
|
||||
v(menu, table.unpack(args))
|
||||
end
|
||||
|
||||
return menu
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local addoptionstextinfo = LUI.Options.AddOptionTextInfo
|
||||
LUI.Options.AddOptionTextInfo = function(menu)
|
||||
local result = addoptionstextinfo(menu)
|
||||
menu.optionTextInfo = result
|
||||
return result
|
||||
end
|
||||
|
||||
LUI.addmenubutton = function(name, data)
|
||||
LUI.onmenuopen(name, function(menu)
|
||||
if (not menu.list) then
|
||||
return
|
||||
end
|
||||
|
||||
local button = menu:AddButton(data.text, data.callback, nil, true, nil, {
|
||||
desc_text = data.description
|
||||
})
|
||||
|
||||
local buttonlist = menu:getChildById(menu.type .. "_list")
|
||||
|
||||
if (data.id) then
|
||||
button.id = data.id
|
||||
end
|
||||
|
||||
if (data.index) then
|
||||
buttonlist:removeElement(button)
|
||||
buttonlist:insertElement(button, data.index)
|
||||
end
|
||||
|
||||
local hintbox = menu.optionTextInfo
|
||||
menu:removeElement(hintbox)
|
||||
|
||||
LUI.Options.InitScrollingList(menu.list, nil)
|
||||
menu.optionTextInfo = LUI.Options.AddOptionTextInfo(menu)
|
||||
end)
|
||||
end
|
||||
|
||||
stack = {}
|
||||
LUI.openmenu = function(menu, args)
|
||||
stack = args
|
||||
LUI.FlowManager.RequestAddMenu(nil, menu)
|
||||
return stack.ret
|
||||
end
|
||||
|
||||
LUI.openpopupmenu = function(menu, args)
|
||||
stack = args
|
||||
LUI.FlowManager.RequestPopupMenu(nil, menu)
|
||||
return stack.ret
|
||||
end
|
||||
|
||||
LUI.onmenuopen("main_lockout", function()
|
||||
if (game:sharedget("has_tried_updating") == "") then
|
||||
game:ontimeout(function()
|
||||
game:sharedset("has_tried_updating", "1")
|
||||
tryupdate(true)
|
||||
end, 0)
|
||||
end
|
||||
end)
|
||||
|
||||
LUI.addmenubutton("pc_controls", {
|
||||
text = "$_CHECK FOR UPDATES",
|
||||
description = "Check for updates.",
|
||||
callback = function()
|
||||
tryupdate(false)
|
||||
end
|
||||
})
|
||||
|
||||
stack = {}
|
||||
LUI.MenuBuilder.m_types_build["generic_waiting_popup_"] = function (menu, event)
|
||||
local oncancel = stack.oncancel
|
||||
|
||||
local popup = LUI.MenuBuilder.BuildRegisteredType("waiting_popup", {
|
||||
message_text = stack.text,
|
||||
isLiveWithCancel = true,
|
||||
cancel_func = function(...)
|
||||
local args = {...}
|
||||
oncancel()
|
||||
LUI.common_menus.CommonPopups.CancelCSSDownload(table.unpack(args))
|
||||
end
|
||||
})
|
||||
|
||||
stack = {
|
||||
ret = popup
|
||||
}
|
||||
|
||||
return popup
|
||||
end
|
||||
|
||||
LUI.MenuBuilder.m_types_build["generic_yes_no_popup_"] = function()
|
||||
local title = stack.title
|
||||
local text = stack.text
|
||||
local callback = stack.callback
|
||||
|
||||
local popup = LUI.MenuBuilder.BuildRegisteredType("generic_yesno_popup", {
|
||||
popup_title = title,
|
||||
message_text = text,
|
||||
yes_action = function()
|
||||
callback(true)
|
||||
end,
|
||||
no_action = function()
|
||||
callback(false)
|
||||
end
|
||||
})
|
||||
|
||||
stack = {
|
||||
ret = popup
|
||||
}
|
||||
|
||||
return popup
|
||||
end
|
||||
|
||||
LUI.yesnopopup = function(data)
|
||||
for k, v in luiglobals.next, data do
|
||||
stack[k] = v
|
||||
end
|
||||
LUI.FlowManager.RequestPopupMenu(nil, "generic_yes_no_popup_")
|
||||
return stack.ret
|
||||
end
|
||||
|
||||
function updaterpopup(oncancel)
|
||||
return LUI.openpopupmenu("generic_waiting_popup_", {
|
||||
oncancel = oncancel,
|
||||
withcancel = true,
|
||||
text = "Checking for updates..."
|
||||
})
|
||||
end
|
||||
|
||||
function verifyfiles(files)
|
||||
local needed = {}
|
||||
local binaryname = game:binaryname()
|
||||
|
||||
for i = 1, #files do
|
||||
local name = files[i][1]
|
||||
if (name ~= binaryname and (not io.fileexists(files[i][1]) or game:sha(io.readfile(files[i][1])) ~= files[i][3])) then
|
||||
table.insert(needed, files[i])
|
||||
end
|
||||
end
|
||||
|
||||
return needed
|
||||
end
|
||||
|
||||
local canceled = false
|
||||
|
||||
function downloadfiles(popup, files, callback)
|
||||
local text = popup:getchildren()[7]
|
||||
local folder = game:environment() == "develop" and "data-dev" or "data"
|
||||
|
||||
if (#files == 0) then
|
||||
callback(true)
|
||||
return
|
||||
end
|
||||
|
||||
local total = 0
|
||||
local filedownloaded = function()
|
||||
total = total + 1
|
||||
if (total == #files) then
|
||||
callback(true)
|
||||
end
|
||||
end
|
||||
|
||||
local download = nil
|
||||
local stop = false
|
||||
download = function(index)
|
||||
if (canceled or stop) then
|
||||
return
|
||||
end
|
||||
|
||||
local url = "https://master.fed0001.xyz/" .. folder .. "/" .. files[index][1]
|
||||
text:setText(string.format("Downloading file [%i/%i]\n%s", index, #files, files[index][1]))
|
||||
|
||||
httprequest(url, function(valid, data)
|
||||
if (not valid) then
|
||||
callback(false, "Invalid server response")
|
||||
stop = true
|
||||
return
|
||||
end
|
||||
|
||||
if (not io.writefile(files[index][1], data, false)) then
|
||||
callback(false, "Failed to write file " .. files[index][1])
|
||||
stop = true
|
||||
return
|
||||
end
|
||||
|
||||
filedownloaded()
|
||||
|
||||
if (files[index + 1]) then
|
||||
download(index + 1)
|
||||
else
|
||||
callback(true)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
download(1)
|
||||
end
|
||||
|
||||
function userdata_:getchildren()
|
||||
local children = {}
|
||||
local first = self:getFirstChild()
|
||||
|
||||
while (first) do
|
||||
table.insert(children, first)
|
||||
first = first:getNextSibling()
|
||||
end
|
||||
|
||||
return children
|
||||
end
|
||||
|
||||
function tryupdate(autoclose)
|
||||
canceled = false
|
||||
local popup = updaterpopup(function()
|
||||
canceled = true
|
||||
end)
|
||||
|
||||
local text = popup:getchildren()[7]
|
||||
local file = game:environment() == "develop" and "files-dev.json" or "files.json"
|
||||
|
||||
httprequest("https://master.fed0001.xyz/" .. file, function(valid, data)
|
||||
if (not valid) then
|
||||
text:setText("Update check failed: Invalid server response")
|
||||
return
|
||||
end
|
||||
|
||||
local valid = pcall(function()
|
||||
local files = json.decode(data)
|
||||
local needed = verifyfiles(files)
|
||||
|
||||
if (#needed == 0) then
|
||||
text:setText("No updates available")
|
||||
if (autoclose) then
|
||||
LUI.common_menus.CommonPopups.CancelCSSDownload(popup, {})
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local download = function()
|
||||
local gotresult = false
|
||||
downloadfiles(popup, needed, function(result, error)
|
||||
if (gotresult or canceled) then
|
||||
return
|
||||
end
|
||||
|
||||
gotresult = true
|
||||
|
||||
if (result and #needed > 0) then
|
||||
game:executecommand("lui_restart")
|
||||
end
|
||||
|
||||
if (not result) then
|
||||
text:setText("Update failed: " .. error)
|
||||
return
|
||||
end
|
||||
|
||||
text:setText("Update successful!")
|
||||
|
||||
if (autoclose) then
|
||||
LUI.common_menus.CommonPopups.CancelCSSDownload(popup, {})
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
if (autoclose) then
|
||||
download()
|
||||
else
|
||||
LUI.yesnopopup({
|
||||
title = "NOTICE",
|
||||
text = "An update is available, proceed with installation?",
|
||||
callback = function(result)
|
||||
if (not result) then
|
||||
LUI.common_menus.CommonPopups.CancelCSSDownload(popup, {})
|
||||
else
|
||||
download()
|
||||
end
|
||||
end
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
if (not valid) then
|
||||
text:setText("Update failed: unknown error")
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
LUI.tryupdating = function(autoclose)
|
||||
tryupdate(autoclose)
|
||||
end
|
||||
|
||||
function httprequest(url, callback)
|
||||
local request = game:httpget(url)
|
||||
local listener = nil
|
||||
listener = game:onnotify("http_request_done", function(id, valid, data)
|
||||
if (id ~= request) then
|
||||
return
|
||||
end
|
||||
|
||||
listener:clear()
|
||||
callback(valid, data)
|
||||
end)
|
||||
end
|
||||
|
||||
local localize = Engine.Localize
|
||||
Engine.Localize = function(...)
|
||||
local args = {...}
|
||||
|
||||
if (type(args[1]) == "string" and args[1]:sub(1, 2) == "$_") then
|
||||
return args[1]:sub(3, -1)
|
||||
end
|
||||
|
||||
return localize(table.unpack(args))
|
||||
end
|
Loading…
Reference in New Issue
Block a user