Retire tpt.beginGetScript in favour of tpt.installScriptManager
There had never been a legit use of tpt.beginGetScript (or indeed, tpt.getscript) that didn't involve the exact parameters 1, "autorun.lua", 1. The most infamous alternative parametrization was 2, "autorun.lua", 1, which would install TPTMP where you'd normally install the script manager. Absolute madness. The callback parameter also goes away with this change, because no other script needs to know when the script manager is done being installed. I also fixed a problem where the function might be called from the wrong context and thus get delayed in handling the completion of the HTTP request. With the earlier removal of checking for existing destination files and bailing out if found, this function is now bullet-proof(tm). This restores the tpt.getscript(1, "autorun.lua", 1) usage pattern, albeit only from the console.
This commit is contained in:
parent
95b83ffd61
commit
3ecc1c6c6f
@ -366,7 +366,7 @@ LuaScriptInterface::LuaScriptInterface(GameController * c, GameModel * m):
|
|||||||
{"setfire", &luatpt_setfire},
|
{"setfire", &luatpt_setfire},
|
||||||
{"setdebug", &luatpt_setdebug},
|
{"setdebug", &luatpt_setdebug},
|
||||||
{"setfpscap",&luatpt_setfpscap},
|
{"setfpscap",&luatpt_setfpscap},
|
||||||
{"beginGetScript",&luatpt_getscript},
|
{"installScriptManager",&installScriptManager},
|
||||||
{"setwindowsize",&luatpt_setwindowsize},
|
{"setwindowsize",&luatpt_setwindowsize},
|
||||||
{"watertest",&luatpt_togglewater},
|
{"watertest",&luatpt_togglewater},
|
||||||
{"screenshot",&luatpt_screenshot},
|
{"screenshot",&luatpt_screenshot},
|
||||||
@ -4704,14 +4704,15 @@ bool LuaScriptInterface::HandleEvent(const GameControllerEvent &event)
|
|||||||
return cont;
|
return cont;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GetScriptStatus
|
void LuaScriptInterface::OnTick()
|
||||||
|
{
|
||||||
|
if (scriptManagerDownload && scriptManagerDownload->CheckDone())
|
||||||
|
{
|
||||||
|
struct Status
|
||||||
{
|
{
|
||||||
struct Ok
|
struct Ok
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
struct Cancelled
|
|
||||||
{
|
|
||||||
};
|
|
||||||
struct GetFailed
|
struct GetFailed
|
||||||
{
|
{
|
||||||
String error;
|
String error;
|
||||||
@ -4722,72 +4723,57 @@ struct GetScriptStatus
|
|||||||
};
|
};
|
||||||
using Value = std::variant<
|
using Value = std::variant<
|
||||||
Ok,
|
Ok,
|
||||||
Cancelled,
|
|
||||||
GetFailed,
|
GetFailed,
|
||||||
RunFailed
|
RunFailed
|
||||||
>;
|
>;
|
||||||
Value value;
|
Value value;
|
||||||
};
|
};
|
||||||
|
auto complete = [](Status status) {
|
||||||
void LuaScriptInterface::OnTick()
|
if (std::get_if<Status::Ok>(&status.value))
|
||||||
{
|
{
|
||||||
if (scriptDownload && scriptDownload->CheckDone())
|
new InformationMessage("Install script manager", "Script manager successfully installed", false);
|
||||||
{
|
|
||||||
auto ret = scriptDownload->StatusCode();
|
|
||||||
ByteString scriptData;
|
|
||||||
auto complete = [this](GetScriptStatus status) {
|
|
||||||
if (std::get_if<GetScriptStatus::Ok>(&status.value))
|
|
||||||
{
|
|
||||||
new InformationMessage("Script download", "Script successfully downloaded", false);
|
|
||||||
}
|
}
|
||||||
if (auto *requestFailed = std::get_if<GetScriptStatus::GetFailed>(&status.value))
|
if (auto *requestFailed = std::get_if<Status::GetFailed>(&status.value))
|
||||||
{
|
{
|
||||||
new ErrorMessage("Script download", "Failed to get script: " + requestFailed->error);
|
new ErrorMessage("Install script manager", "Failed to get script manager: " + requestFailed->error);
|
||||||
}
|
}
|
||||||
if (auto *runFailed = std::get_if<GetScriptStatus::RunFailed>(&status.value))
|
if (auto *runFailed = std::get_if<Status::RunFailed>(&status.value))
|
||||||
{
|
{
|
||||||
new ErrorMessage("Script download", "Failed to run script: " + runFailed->error);
|
new ErrorMessage("Install script manager", "Failed to run script manager: " + runFailed->error);
|
||||||
}
|
}
|
||||||
scriptDownloadComplete(status);
|
|
||||||
};
|
};
|
||||||
auto handleResponse = [this, &scriptData, &ret, &complete]() {
|
try
|
||||||
|
{
|
||||||
|
auto ret = scriptManagerDownload->StatusCode();
|
||||||
|
auto scriptData = scriptManagerDownload->Finish().second;
|
||||||
if (!scriptData.size())
|
if (!scriptData.size())
|
||||||
{
|
{
|
||||||
complete({ GetScriptStatus::GetFailed{ "Server did not return data" } });
|
complete({ Status::GetFailed{ "Server did not return data" } });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ret != 200)
|
if (ret != 200)
|
||||||
{
|
{
|
||||||
complete({ GetScriptStatus::GetFailed{ ByteString(http::StatusText(ret)).FromUtf8() } });
|
complete({ Status::GetFailed{ ByteString(http::StatusText(ret)).FromUtf8() } });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!Platform::WriteFile(std::vector<char>(scriptData.begin(), scriptData.end()), scriptDownloadFilename))
|
ByteString filename = "autorun.lua";
|
||||||
|
if (!Platform::WriteFile(std::vector<char>(scriptData.begin(), scriptData.end()), filename))
|
||||||
{
|
{
|
||||||
complete({ GetScriptStatus::GetFailed{ "Unable to write to file" } });
|
complete({ Status::GetFailed{ String::Build("Unable to write to ", filename.FromUtf8()) } });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (scriptDownloadRunScript)
|
if (tpt_lua_dostring(l, ByteString::Build("dofile('", filename, "')")))
|
||||||
{
|
{
|
||||||
if (tpt_lua_dostring(l, ByteString::Build("dofile('", scriptDownloadFilename, "')")))
|
complete({ Status::RunFailed{ luacon_geterror() } });
|
||||||
{
|
|
||||||
complete({ GetScriptStatus::RunFailed{ luacon_geterror() } });
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
complete({ Status::Ok{} });
|
||||||
complete({ GetScriptStatus::Ok{} });
|
|
||||||
};
|
|
||||||
try
|
|
||||||
{
|
|
||||||
scriptData = scriptDownload->Finish().second;
|
|
||||||
handleResponse();
|
|
||||||
}
|
}
|
||||||
catch (const http::RequestError &ex)
|
catch (const http::RequestError &ex)
|
||||||
{
|
{
|
||||||
complete({ GetScriptStatus::GetFailed{ ByteString(ex.what()).FromUtf8() } });
|
complete({ Status::GetFailed{ ByteString(ex.what()).FromUtf8() } });
|
||||||
}
|
}
|
||||||
scriptDownload.reset();
|
scriptManagerDownload.reset();
|
||||||
scriptDownloadComplete = nullptr;
|
|
||||||
scriptDownloadPending = false;
|
|
||||||
}
|
}
|
||||||
lua_getglobal(l, "simulation");
|
lua_getglobal(l, "simulation");
|
||||||
if (lua_istable(l, -1))
|
if (lua_istable(l, -1))
|
||||||
@ -5206,82 +5192,21 @@ CommandInterface *CommandInterface::Create(GameController * c, GameModel * m)
|
|||||||
return new LuaScriptInterface(c, m);
|
return new LuaScriptInterface(c, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
int LuaScriptInterface::luatpt_getscript(lua_State* l)
|
int LuaScriptInterface::installScriptManager(lua_State* l)
|
||||||
{
|
{
|
||||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||||
if (luacon_ci->scriptDownloadPending)
|
if (luacon_ci->scriptManagerDownload)
|
||||||
{
|
{
|
||||||
new ErrorMessage("Script download", "A script download is already pending");
|
new ErrorMessage("Script download", "A script download is already pending");
|
||||||
lua_pushnil(l);
|
return 0;
|
||||||
lua_pushliteral(l, "pending");
|
|
||||||
return 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int scriptID = luaL_checkinteger(l, 1);
|
|
||||||
auto filename = tpt_lua_checkByteString(l, 2);
|
|
||||||
auto runScript = PickIfType(l, 3, false);
|
|
||||||
|
|
||||||
auto cb = std::make_shared<LuaSmartRef>(); // * Bind to main lua state (might be different from l).
|
|
||||||
cb->Assign(l, lua_gettop(l));
|
|
||||||
luacon_ci->scriptDownloadComplete = [cb](const GetScriptStatus &status) {
|
|
||||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
|
||||||
auto l = luacon_ci->l;
|
|
||||||
cb->Push(l);
|
|
||||||
if (lua_isfunction(l, -1))
|
|
||||||
{
|
|
||||||
int nargs = 0;
|
|
||||||
if (std::get_if<GetScriptStatus::Ok>(&status.value))
|
|
||||||
{
|
|
||||||
lua_pushliteral(l, "ok");
|
|
||||||
nargs = 1;
|
|
||||||
}
|
|
||||||
if (std::get_if<GetScriptStatus::Cancelled>(&status.value))
|
|
||||||
{
|
|
||||||
lua_pushliteral(l, "cancelled");
|
|
||||||
nargs = 1;
|
|
||||||
}
|
|
||||||
if (auto *requestFailed = std::get_if<GetScriptStatus::GetFailed>(&status.value))
|
|
||||||
{
|
|
||||||
lua_pushliteral(l, "get_failed");
|
|
||||||
tpt_lua_pushString(l, requestFailed->error);
|
|
||||||
nargs = 2;
|
|
||||||
}
|
|
||||||
if (auto *runFailed = std::get_if<GetScriptStatus::RunFailed>(&status.value))
|
|
||||||
{
|
|
||||||
lua_pushliteral(l, "run_failed");
|
|
||||||
tpt_lua_pushString(l, runFailed->error);
|
|
||||||
nargs = 2;
|
|
||||||
}
|
|
||||||
if (tpt_lua_pcall(l, nargs, 0, 0, false))
|
|
||||||
{
|
|
||||||
luacon_ci->Log(CommandInterface::LogError, luacon_geterror());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lua_pop(l, 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ByteString url = ByteString::Build(SCHEME, "starcatcher.us/scripts/main.lua?get=", scriptID);
|
|
||||||
new ConfirmPrompt("Do you want to install this script?", url.FromUtf8(), {
|
|
||||||
[filename, runScript, url]() {
|
|
||||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
|
||||||
luacon_ci->scriptDownload = std::make_unique<http::Request>(url);
|
|
||||||
luacon_ci->scriptDownload->Start();
|
|
||||||
luacon_ci->scriptDownloadFilename = filename;
|
|
||||||
luacon_ci->scriptDownloadRunScript = runScript;
|
|
||||||
luacon_controller->HideConsole();
|
luacon_controller->HideConsole();
|
||||||
},
|
if (ui::Engine::Ref().GetWindow() != luacon_controller->GetView())
|
||||||
[]() {
|
{
|
||||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
new ErrorMessage("Script download", "You must run this function from the console");
|
||||||
luacon_ci->scriptDownloadComplete({ GetScriptStatus::Cancelled{} });
|
return 0;
|
||||||
luacon_ci->scriptDownloadComplete = nullptr;
|
}
|
||||||
luacon_ci->scriptDownloadPending = false;
|
luacon_ci->scriptManagerDownload = std::make_unique<http::Request>(ByteString::Build(SCHEME, "starcatcher.us/scripts/main.lua?get=1"));
|
||||||
},
|
luacon_ci->scriptManagerDownload->Start();
|
||||||
}, "Install");
|
return 0;
|
||||||
|
|
||||||
luacon_ci->scriptDownloadPending = true;
|
|
||||||
lua_pushboolean(l, 1);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
@ -26,15 +26,9 @@ class Tool;
|
|||||||
class Simulation;
|
class Simulation;
|
||||||
class LuaComponent;
|
class LuaComponent;
|
||||||
|
|
||||||
struct GetScriptStatus;
|
|
||||||
|
|
||||||
class LuaScriptInterface: public TPTScriptInterface
|
class LuaScriptInterface: public TPTScriptInterface
|
||||||
{
|
{
|
||||||
std::unique_ptr<http::Request> scriptDownload;
|
std::unique_ptr<http::Request> scriptManagerDownload;
|
||||||
ByteString scriptDownloadFilename;
|
|
||||||
bool scriptDownloadPending = false;
|
|
||||||
bool scriptDownloadRunScript;
|
|
||||||
std::function<void (GetScriptStatus)> scriptDownloadComplete;
|
|
||||||
|
|
||||||
int luacon_mousex, luacon_mousey, luacon_mousebutton;
|
int luacon_mousex, luacon_mousey, luacon_mousebutton;
|
||||||
ByteString luacon_selectedl, luacon_selectedr, luacon_selectedalt, luacon_selectedreplace;
|
ByteString luacon_selectedl, luacon_selectedr, luacon_selectedalt, luacon_selectedreplace;
|
||||||
@ -195,7 +189,7 @@ class LuaScriptInterface: public TPTScriptInterface
|
|||||||
static int event_unregister(lua_State * l);
|
static int event_unregister(lua_State * l);
|
||||||
static int event_getmodifiers(lua_State * l);
|
static int event_getmodifiers(lua_State * l);
|
||||||
|
|
||||||
static int luatpt_getscript(lua_State * l);
|
static int installScriptManager(lua_State * l);
|
||||||
|
|
||||||
void initHttpAPI();
|
void initHttpAPI();
|
||||||
void initSocketAPI();
|
void initSocketAPI();
|
||||||
|
@ -239,3 +239,10 @@ function tpt.graphics_func(f, element)
|
|||||||
if f == nil then f = false end
|
if f == nil then f = false end
|
||||||
elem.property(element, "Graphics", f)
|
elem.property(element, "Graphics", f)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function tpt.getscript(id, name, run)
|
||||||
|
if not (id == 1 and name == "autorun.lua" and run == 1) then
|
||||||
|
error("only use tpt.getscript to install the script manager")
|
||||||
|
end
|
||||||
|
tpt.installScriptManager()
|
||||||
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user