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},
|
||||
{"setdebug", &luatpt_setdebug},
|
||||
{"setfpscap",&luatpt_setfpscap},
|
||||
{"beginGetScript",&luatpt_getscript},
|
||||
{"installScriptManager",&installScriptManager},
|
||||
{"setwindowsize",&luatpt_setwindowsize},
|
||||
{"watertest",&luatpt_togglewater},
|
||||
{"screenshot",&luatpt_screenshot},
|
||||
@ -4704,90 +4704,76 @@ bool LuaScriptInterface::HandleEvent(const GameControllerEvent &event)
|
||||
return cont;
|
||||
}
|
||||
|
||||
struct GetScriptStatus
|
||||
{
|
||||
struct Ok
|
||||
{
|
||||
};
|
||||
struct Cancelled
|
||||
{
|
||||
};
|
||||
struct GetFailed
|
||||
{
|
||||
String error;
|
||||
};
|
||||
struct RunFailed
|
||||
{
|
||||
String error;
|
||||
};
|
||||
using Value = std::variant<
|
||||
Ok,
|
||||
Cancelled,
|
||||
GetFailed,
|
||||
RunFailed
|
||||
>;
|
||||
Value value;
|
||||
};
|
||||
|
||||
void LuaScriptInterface::OnTick()
|
||||
{
|
||||
if (scriptDownload && scriptDownload->CheckDone())
|
||||
if (scriptManagerDownload && scriptManagerDownload->CheckDone())
|
||||
{
|
||||
auto ret = scriptDownload->StatusCode();
|
||||
ByteString scriptData;
|
||||
auto complete = [this](GetScriptStatus status) {
|
||||
if (std::get_if<GetScriptStatus::Ok>(&status.value))
|
||||
struct Status
|
||||
{
|
||||
struct Ok
|
||||
{
|
||||
new InformationMessage("Script download", "Script successfully downloaded", false);
|
||||
}
|
||||
if (auto *requestFailed = std::get_if<GetScriptStatus::GetFailed>(&status.value))
|
||||
};
|
||||
struct GetFailed
|
||||
{
|
||||
new ErrorMessage("Script download", "Failed to get script: " + requestFailed->error);
|
||||
}
|
||||
if (auto *runFailed = std::get_if<GetScriptStatus::RunFailed>(&status.value))
|
||||
String error;
|
||||
};
|
||||
struct RunFailed
|
||||
{
|
||||
new ErrorMessage("Script download", "Failed to run script: " + runFailed->error);
|
||||
}
|
||||
scriptDownloadComplete(status);
|
||||
String error;
|
||||
};
|
||||
using Value = std::variant<
|
||||
Ok,
|
||||
GetFailed,
|
||||
RunFailed
|
||||
>;
|
||||
Value value;
|
||||
};
|
||||
auto handleResponse = [this, &scriptData, &ret, &complete]() {
|
||||
auto complete = [](Status status) {
|
||||
if (std::get_if<Status::Ok>(&status.value))
|
||||
{
|
||||
new InformationMessage("Install script manager", "Script manager successfully installed", false);
|
||||
}
|
||||
if (auto *requestFailed = std::get_if<Status::GetFailed>(&status.value))
|
||||
{
|
||||
new ErrorMessage("Install script manager", "Failed to get script manager: " + requestFailed->error);
|
||||
}
|
||||
if (auto *runFailed = std::get_if<Status::RunFailed>(&status.value))
|
||||
{
|
||||
new ErrorMessage("Install script manager", "Failed to run script manager: " + runFailed->error);
|
||||
}
|
||||
};
|
||||
try
|
||||
{
|
||||
auto ret = scriptManagerDownload->StatusCode();
|
||||
auto scriptData = scriptManagerDownload->Finish().second;
|
||||
if (!scriptData.size())
|
||||
{
|
||||
complete({ GetScriptStatus::GetFailed{ "Server did not return data" } });
|
||||
complete({ Status::GetFailed{ "Server did not return data" } });
|
||||
return;
|
||||
}
|
||||
if (ret != 200)
|
||||
{
|
||||
complete({ GetScriptStatus::GetFailed{ ByteString(http::StatusText(ret)).FromUtf8() } });
|
||||
complete({ Status::GetFailed{ ByteString(http::StatusText(ret)).FromUtf8() } });
|
||||
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;
|
||||
}
|
||||
if (scriptDownloadRunScript)
|
||||
if (tpt_lua_dostring(l, ByteString::Build("dofile('", filename, "')")))
|
||||
{
|
||||
if (tpt_lua_dostring(l, ByteString::Build("dofile('", scriptDownloadFilename, "')")))
|
||||
{
|
||||
complete({ GetScriptStatus::RunFailed{ luacon_geterror() } });
|
||||
return;
|
||||
}
|
||||
complete({ Status::RunFailed{ luacon_geterror() } });
|
||||
return;
|
||||
}
|
||||
complete({ GetScriptStatus::Ok{} });
|
||||
};
|
||||
try
|
||||
{
|
||||
scriptData = scriptDownload->Finish().second;
|
||||
handleResponse();
|
||||
complete({ Status::Ok{} });
|
||||
}
|
||||
catch (const http::RequestError &ex)
|
||||
{
|
||||
complete({ GetScriptStatus::GetFailed{ ByteString(ex.what()).FromUtf8() } });
|
||||
complete({ Status::GetFailed{ ByteString(ex.what()).FromUtf8() } });
|
||||
}
|
||||
scriptDownload.reset();
|
||||
scriptDownloadComplete = nullptr;
|
||||
scriptDownloadPending = false;
|
||||
scriptManagerDownload.reset();
|
||||
}
|
||||
lua_getglobal(l, "simulation");
|
||||
if (lua_istable(l, -1))
|
||||
@ -5206,82 +5192,21 @@ CommandInterface *CommandInterface::Create(GameController * c, GameModel * 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);
|
||||
if (luacon_ci->scriptDownloadPending)
|
||||
if (luacon_ci->scriptManagerDownload)
|
||||
{
|
||||
new ErrorMessage("Script download", "A script download is already pending");
|
||||
lua_pushnil(l);
|
||||
lua_pushliteral(l, "pending");
|
||||
return 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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();
|
||||
},
|
||||
[]() {
|
||||
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
|
||||
luacon_ci->scriptDownloadComplete({ GetScriptStatus::Cancelled{} });
|
||||
luacon_ci->scriptDownloadComplete = nullptr;
|
||||
luacon_ci->scriptDownloadPending = false;
|
||||
},
|
||||
}, "Install");
|
||||
|
||||
luacon_ci->scriptDownloadPending = true;
|
||||
lua_pushboolean(l, 1);
|
||||
return 1;
|
||||
luacon_controller->HideConsole();
|
||||
if (ui::Engine::Ref().GetWindow() != luacon_controller->GetView())
|
||||
{
|
||||
new ErrorMessage("Script download", "You must run this function from the console");
|
||||
return 0;
|
||||
}
|
||||
luacon_ci->scriptManagerDownload = std::make_unique<http::Request>(ByteString::Build(SCHEME, "starcatcher.us/scripts/main.lua?get=1"));
|
||||
luacon_ci->scriptManagerDownload->Start();
|
||||
return 0;
|
||||
}
|
||||
|
@ -26,15 +26,9 @@ class Tool;
|
||||
class Simulation;
|
||||
class LuaComponent;
|
||||
|
||||
struct GetScriptStatus;
|
||||
|
||||
class LuaScriptInterface: public TPTScriptInterface
|
||||
{
|
||||
std::unique_ptr<http::Request> scriptDownload;
|
||||
ByteString scriptDownloadFilename;
|
||||
bool scriptDownloadPending = false;
|
||||
bool scriptDownloadRunScript;
|
||||
std::function<void (GetScriptStatus)> scriptDownloadComplete;
|
||||
std::unique_ptr<http::Request> scriptManagerDownload;
|
||||
|
||||
int luacon_mousex, luacon_mousey, luacon_mousebutton;
|
||||
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_getmodifiers(lua_State * l);
|
||||
|
||||
static int luatpt_getscript(lua_State * l);
|
||||
static int installScriptManager(lua_State * l);
|
||||
|
||||
void initHttpAPI();
|
||||
void initSocketAPI();
|
||||
|
@ -239,3 +239,10 @@ function tpt.graphics_func(f, element)
|
||||
if f == nil then f = false end
|
||||
elem.property(element, "Graphics", f)
|
||||
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