Also update binary with updater
This commit is contained in:
parent
b2247f7ae3
commit
d910ea5df5
@ -1150,7 +1150,7 @@ namespace ui_scripting::lua
|
|||||||
if (result.has_value())
|
if (result.has_value())
|
||||||
{
|
{
|
||||||
const auto write = utils::io::write_file(dest, result.value(), false);
|
const auto write = utils::io::write_file(dest, result.value(), false);
|
||||||
event.arguments = {id, write};
|
event.arguments = {id, true, write};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1179,6 +1179,12 @@ namespace ui_scripting::lua
|
|||||||
return self.get_name();
|
return self.get_name();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
game_type["relaunch"] = [](const game&)
|
||||||
|
{
|
||||||
|
utils::nt::relaunch_self("-singleplayer");
|
||||||
|
utils::nt::terminate();
|
||||||
|
};
|
||||||
|
|
||||||
struct player
|
struct player
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
@ -62,14 +62,27 @@ namespace ui_scripting
|
|||||||
const auto state = *game::hks::lua_state;
|
const auto state = *game::hks::lua_state;
|
||||||
state->m_apistack.top = state->m_apistack.base;
|
state->m_apistack.top = state->m_apistack.base;
|
||||||
|
|
||||||
game::hks::hksi_lua_pushlstring(state, value, (unsigned int)strlen(value));
|
game::hks::hksi_lua_pushlstring(state, value, static_cast<unsigned int>(strlen(value)));
|
||||||
|
obj = state->m_apistack.top[-1];
|
||||||
|
|
||||||
|
this->value_ = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
script_value::script_value(const char* value, unsigned int len)
|
||||||
|
{
|
||||||
|
game::hks::HksObject obj{};
|
||||||
|
|
||||||
|
const auto state = *game::hks::lua_state;
|
||||||
|
state->m_apistack.top = state->m_apistack.base;
|
||||||
|
|
||||||
|
game::hks::hksi_lua_pushlstring(state, value, len);
|
||||||
obj = state->m_apistack.top[-1];
|
obj = state->m_apistack.top[-1];
|
||||||
|
|
||||||
this->value_ = obj;
|
this->value_ = obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
script_value::script_value(const std::string& value)
|
script_value::script_value(const std::string& value)
|
||||||
: script_value(value.data())
|
: script_value(value.data(), static_cast<unsigned int>(value.size()))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ namespace ui_scripting
|
|||||||
script_value(double value);
|
script_value(double value);
|
||||||
|
|
||||||
script_value(const char* value);
|
script_value(const char* value);
|
||||||
|
script_value(const char* value, unsigned int len);
|
||||||
script_value(const std::string& value);
|
script_value(const std::string& value);
|
||||||
|
|
||||||
script_value(const lightuserdata& value);
|
script_value(const lightuserdata& value);
|
||||||
|
@ -96,7 +96,6 @@ LUI.addmenubutton("pc_controls", {
|
|||||||
stack = {}
|
stack = {}
|
||||||
LUI.MenuBuilder.m_types_build["generic_waiting_popup_"] = function (menu, event)
|
LUI.MenuBuilder.m_types_build["generic_waiting_popup_"] = function (menu, event)
|
||||||
local oncancel = stack.oncancel
|
local oncancel = stack.oncancel
|
||||||
|
|
||||||
local popup = LUI.MenuBuilder.BuildRegisteredType("waiting_popup", {
|
local popup = LUI.MenuBuilder.BuildRegisteredType("waiting_popup", {
|
||||||
message_text = stack.text,
|
message_text = stack.text,
|
||||||
isLiveWithCancel = true,
|
isLiveWithCancel = true,
|
||||||
@ -115,13 +114,10 @@ LUI.MenuBuilder.m_types_build["generic_waiting_popup_"] = function (menu, event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
LUI.MenuBuilder.m_types_build["generic_yes_no_popup_"] = function()
|
LUI.MenuBuilder.m_types_build["generic_yes_no_popup_"] = function()
|
||||||
local title = stack.title
|
|
||||||
local text = stack.text
|
|
||||||
local callback = stack.callback
|
local callback = stack.callback
|
||||||
|
|
||||||
local popup = LUI.MenuBuilder.BuildRegisteredType("generic_yesno_popup", {
|
local popup = LUI.MenuBuilder.BuildRegisteredType("generic_yesno_popup", {
|
||||||
popup_title = title,
|
popup_title = stack.title,
|
||||||
message_text = text,
|
message_text = stack.text,
|
||||||
yes_action = function()
|
yes_action = function()
|
||||||
callback(true)
|
callback(true)
|
||||||
end,
|
end,
|
||||||
@ -137,6 +133,22 @@ LUI.MenuBuilder.m_types_build["generic_yes_no_popup_"] = function()
|
|||||||
return popup
|
return popup
|
||||||
end
|
end
|
||||||
|
|
||||||
|
LUI.MenuBuilder.m_types_build["generic_confirmation_popup_"] = function()
|
||||||
|
local popup = LUI.MenuBuilder.BuildRegisteredType( "generic_confirmation_popup", {
|
||||||
|
cancel_will_close = false,
|
||||||
|
popup_title = stack.title,
|
||||||
|
message_text = stack.text,
|
||||||
|
button_text = stack.buttontext,
|
||||||
|
confirmation_action = stack.callback
|
||||||
|
})
|
||||||
|
|
||||||
|
stack = {
|
||||||
|
ret = popup
|
||||||
|
}
|
||||||
|
|
||||||
|
return stack.ret
|
||||||
|
end
|
||||||
|
|
||||||
LUI.yesnopopup = function(data)
|
LUI.yesnopopup = function(data)
|
||||||
for k, v in luiglobals.next, data do
|
for k, v in luiglobals.next, data do
|
||||||
stack[k] = v
|
stack[k] = v
|
||||||
@ -145,6 +157,14 @@ LUI.yesnopopup = function(data)
|
|||||||
return stack.ret
|
return stack.ret
|
||||||
end
|
end
|
||||||
|
|
||||||
|
LUI.confirmationpopup = function(data)
|
||||||
|
for k, v in luiglobals.next, data do
|
||||||
|
stack[k] = v
|
||||||
|
end
|
||||||
|
LUI.FlowManager.RequestPopupMenu(nil, "generic_confirmation_popup_")
|
||||||
|
return stack.ret
|
||||||
|
end
|
||||||
|
|
||||||
function updaterpopup(oncancel)
|
function updaterpopup(oncancel)
|
||||||
return LUI.openpopupmenu("generic_waiting_popup_", {
|
return LUI.openpopupmenu("generic_waiting_popup_", {
|
||||||
oncancel = oncancel,
|
oncancel = oncancel,
|
||||||
@ -155,16 +175,22 @@ end
|
|||||||
|
|
||||||
function verifyfiles(files)
|
function verifyfiles(files)
|
||||||
local needed = {}
|
local needed = {}
|
||||||
|
local needtoupdatebinary = false
|
||||||
local binaryname = game:binaryname()
|
local binaryname = game:binaryname()
|
||||||
|
|
||||||
for i = 1, #files do
|
for i = 1, #files do
|
||||||
local name = files[i][1]
|
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
|
|
||||||
|
if (not io.fileexists(name) or game:sha(io.readfile(name)) ~= files[i][3]) then
|
||||||
|
if (name == game:binaryname()) then
|
||||||
|
needtoupdatebinary = true
|
||||||
|
end
|
||||||
|
|
||||||
table.insert(needed, files[i])
|
table.insert(needed, files[i])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return needed
|
return needed, needtoupdatebinary
|
||||||
end
|
end
|
||||||
|
|
||||||
local canceled = false
|
local canceled = false
|
||||||
@ -193,18 +219,24 @@ function downloadfiles(popup, files, callback)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local url = "https://master.fed0001.xyz/" .. folder .. "/" .. files[index][1]
|
local filename = files[index][1]
|
||||||
text:setText(string.format("Downloading file [%i/%i]\n%s", index, #files, files[index][1]))
|
|
||||||
|
|
||||||
httprequest(url, function(valid, data)
|
local url = "https://master.fed0001.xyz/" .. folder .. "/" .. filename
|
||||||
|
text:setText(string.format("Downloading file [%i/%i]\n%s", index, #files, filename))
|
||||||
|
|
||||||
|
if (filename == game:binaryname()) then
|
||||||
|
io.movefile(filename, filename .. ".old")
|
||||||
|
end
|
||||||
|
|
||||||
|
httprequesttofile(url, filename, function(valid, success)
|
||||||
if (not valid) then
|
if (not valid) then
|
||||||
callback(false, "Invalid server response")
|
callback(false, "Invalid server response")
|
||||||
stop = true
|
stop = true
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if (not io.writefile(files[index][1], data, false)) then
|
if (not success) then
|
||||||
callback(false, "Failed to write file " .. files[index][1])
|
callback(false, "Failed to write file " .. filename)
|
||||||
stop = true
|
stop = true
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -251,7 +283,7 @@ function tryupdate(autoclose)
|
|||||||
|
|
||||||
local valid = pcall(function()
|
local valid = pcall(function()
|
||||||
local files = json.decode(data)
|
local files = json.decode(data)
|
||||||
local needed = verifyfiles(files)
|
local needed, updatebinary = verifyfiles(files)
|
||||||
|
|
||||||
if (#needed == 0) then
|
if (#needed == 0) then
|
||||||
text:setText("No updates available")
|
text:setText("No updates available")
|
||||||
@ -270,15 +302,28 @@ function tryupdate(autoclose)
|
|||||||
|
|
||||||
gotresult = true
|
gotresult = true
|
||||||
|
|
||||||
if (result and #needed > 0) then
|
|
||||||
game:executecommand("lui_restart")
|
|
||||||
end
|
|
||||||
|
|
||||||
if (not result) then
|
if (not result) then
|
||||||
text:setText("Update failed: " .. error)
|
text:setText("Update failed: " .. error)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if (updatebinary) then
|
||||||
|
LUI.confirmationpopup({
|
||||||
|
title = "RESTART REQUIRED",
|
||||||
|
text = "Update requires restart, relaunch now?",
|
||||||
|
buttontext = "RESTART",
|
||||||
|
callback = function()
|
||||||
|
game:relaunch()
|
||||||
|
end
|
||||||
|
})
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if (result and #needed > 0) then
|
||||||
|
game:executecommand("lui_restart")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
text:setText("Update successful!")
|
text:setText("Update successful!")
|
||||||
|
|
||||||
if (autoclose) then
|
if (autoclose) then
|
||||||
@ -327,6 +372,19 @@ function httprequest(url, callback)
|
|||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function httprequesttofile(url, dest, callback)
|
||||||
|
local request = game:httpgettofile(url, dest)
|
||||||
|
local listener = nil
|
||||||
|
listener = game:onnotify("http_request_done", function(id, valid, success)
|
||||||
|
if (id ~= request) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
listener:clear()
|
||||||
|
callback(valid, success)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
local localize = Engine.Localize
|
local localize = Engine.Localize
|
||||||
Engine.Localize = function(...)
|
Engine.Localize = function(...)
|
||||||
local args = {...}
|
local args = {...}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "nt.hpp"
|
#include "nt.hpp"
|
||||||
|
#include "string.hpp"
|
||||||
|
|
||||||
namespace utils::nt
|
namespace utils::nt
|
||||||
{
|
{
|
||||||
@ -225,7 +226,7 @@ namespace utils::nt
|
|||||||
return std::string(LPSTR(LockResource(handle)), SizeofResource(nullptr, res));
|
return std::string(LPSTR(LockResource(handle)), SizeofResource(nullptr, res));
|
||||||
}
|
}
|
||||||
|
|
||||||
void relaunch_self()
|
void relaunch_self(const std::string& extra_command_line)
|
||||||
{
|
{
|
||||||
const utils::nt::library self;
|
const utils::nt::library self;
|
||||||
|
|
||||||
@ -238,9 +239,14 @@ namespace utils::nt
|
|||||||
|
|
||||||
char current_dir[MAX_PATH];
|
char current_dir[MAX_PATH];
|
||||||
GetCurrentDirectoryA(sizeof(current_dir), current_dir);
|
GetCurrentDirectoryA(sizeof(current_dir), current_dir);
|
||||||
auto* const command_line = GetCommandLineA();
|
|
||||||
|
|
||||||
CreateProcessA(self.get_path().data(), command_line, nullptr, nullptr, false, NULL, nullptr, current_dir,
|
std::string command_line = GetCommandLineA();
|
||||||
|
if (!extra_command_line.empty())
|
||||||
|
{
|
||||||
|
command_line += " " + extra_command_line;
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateProcessA(self.get_path().data(), command_line.data(), nullptr, nullptr, false, NULL, nullptr, current_dir,
|
||||||
&startup_info, &process_info);
|
&startup_info, &process_info);
|
||||||
|
|
||||||
if (process_info.hThread && process_info.hThread != INVALID_HANDLE_VALUE) CloseHandle(process_info.hThread);
|
if (process_info.hThread && process_info.hThread != INVALID_HANDLE_VALUE) CloseHandle(process_info.hThread);
|
||||||
|
@ -105,6 +105,6 @@ namespace utils::nt
|
|||||||
__declspec(noreturn) void raise_hard_exception();
|
__declspec(noreturn) void raise_hard_exception();
|
||||||
std::string load_resource(int id);
|
std::string load_resource(int id);
|
||||||
|
|
||||||
void relaunch_self();
|
void relaunch_self(const std::string& extra_command_line = "");
|
||||||
__declspec(noreturn) void terminate(uint32_t code = 0);
|
__declspec(noreturn) void terminate(uint32_t code = 0);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user