AutoSave 1.2.0: autoload, /autosaver load <name>, new-server detection, watcher reinstall
This commit is contained in:
1 parent
b9d0eb6afd
commit
b037722432
1 file changed
+243
-36
+243
-36
@@ -36,6 +36,7 @@ static int gChangeAtStart = 0;
|
||||
static int gSavedCount = -1;
|
||||
static bool gReady = false;
|
||||
static bool gPreview = true;
|
||||
static bool gAutoLoad = false;
|
||||
|
||||
struct Row {
|
||||
ADDR obj;
|
||||
@@ -591,8 +592,9 @@ static void prefsToScript()
|
||||
"$Pref::Server::AutoSave::Interval = %d;"
|
||||
"$Pref::Server::AutoSave::Chunk = %d;"
|
||||
"$Pref::Server::AutoSave::Tick = %d;"
|
||||
"$Pref::Server::AutoSave::Preview = %d;",
|
||||
gEnabled ? 1 : 0, gInterval, gChunk, gTickMs, gPreview ? 1 : 0);
|
||||
"$Pref::Server::AutoSave::Preview = %d;"
|
||||
"$Pref::Server::AutoSave::AutoLoad = %d;",
|
||||
gEnabled ? 1 : 0, gInterval, gChunk, gTickMs, gPreview ? 1 : 0, gAutoLoad ? 1 : 0);
|
||||
tsf_Eval(code);
|
||||
}
|
||||
|
||||
@@ -614,6 +616,9 @@ static void prefsFromScript()
|
||||
value = varOf("$Pref::Server::AutoSave::Preview");
|
||||
if (!value.empty())
|
||||
gPreview = truthy(value);
|
||||
value = varOf("$Pref::Server::AutoSave::AutoLoad");
|
||||
if (!value.empty())
|
||||
gAutoLoad = truthy(value);
|
||||
clampPrefs();
|
||||
prefsToScript();
|
||||
}
|
||||
@@ -1592,12 +1597,12 @@ static int clampInterval()
|
||||
return gInterval;
|
||||
}
|
||||
|
||||
static bool gHostSeen = false;
|
||||
static int gServerId = 0;
|
||||
|
||||
static void reschedule()
|
||||
{
|
||||
char code[128];
|
||||
int delay = gHostSeen ? clampInterval() * 1000 : 5000;
|
||||
int delay = clampInterval() * 1000;
|
||||
std::snprintf(code, sizeof(code), "$AutoSave::Schedule = schedule(%d, 0, autoSaveTick);", delay);
|
||||
tsf_Eval(code);
|
||||
}
|
||||
@@ -1651,7 +1656,8 @@ function AutoSave_Help(%client)
|
||||
AutoSave_Tell(%client, "/autosaver tick <milliseconds, 1-1000>");
|
||||
AutoSave_Tell(%client, "/autosaver screenshot <on or off>");
|
||||
AutoSave_Tell(%client, "/autosaver save");
|
||||
AutoSave_Tell(%client, "/autosaver load");
|
||||
AutoSave_Tell(%client, "/autosaver load <optional autosave name>");
|
||||
AutoSave_Tell(%client, "/autosaver autoload <on or off>");
|
||||
}
|
||||
function AutoSave_Busy()
|
||||
{
|
||||
@@ -1697,18 +1703,73 @@ function AutoSave_ReloadTick()
|
||||
$AutoSave::ReloadFile = "";
|
||||
serverDirectSaveFileLoad(%file, 3, "", 1, 0);
|
||||
}
|
||||
function AutoSave_Reload(%client)
|
||||
function AutoSave_AutoLoadStart()
|
||||
{
|
||||
if (isEventPending($AutoSave::AutoLoadSchedule))
|
||||
cancel($AutoSave::AutoLoadSchedule);
|
||||
$AutoSave::AutoLoadTries = 0;
|
||||
AutoSave_AutoLoadWait();
|
||||
}
|
||||
function AutoSave_AutoLoadWait()
|
||||
{
|
||||
if (!$missionRunning || !isObject(mainBrickGroup))
|
||||
{
|
||||
if ($AutoSave::AutoLoadTries++ < 240)
|
||||
$AutoSave::AutoLoadSchedule = schedule(500, 0, AutoSave_AutoLoadWait);
|
||||
else
|
||||
echo("AutoSave: autoload gave up, the mission did not start");
|
||||
return;
|
||||
}
|
||||
if ($GameModeArg !$= "")
|
||||
{
|
||||
echo("AutoSave: autoload skipped, a game mode is running");
|
||||
return;
|
||||
}
|
||||
if ($SaveFileArg !$= "" || AutoSave_Busy() || getBrickCount() > 0)
|
||||
{
|
||||
echo("AutoSave: autoload skipped, the server already has bricks");
|
||||
return;
|
||||
}
|
||||
%file = AutoSave_NewestFile();
|
||||
if (%file $= "")
|
||||
{
|
||||
echo("AutoSave: autoload skipped, there is no autosave");
|
||||
return;
|
||||
}
|
||||
echo("AutoSave: autoload " @ %file);
|
||||
$AutoSave::AutoLoading = 1;
|
||||
serverDirectSaveFileLoad(%file, 3, "", 1, 0);
|
||||
}
|
||||
function AutoSave_Reload(%client, %wanted)
|
||||
{
|
||||
if ($Game::MissionCleaningUp || AutoSave_Busy() || $AutoSave::ReloadFile !$= "")
|
||||
{
|
||||
AutoSave_Tell(%client, "Bricks are still being cleared or loaded.");
|
||||
return;
|
||||
}
|
||||
%file = AutoSave_NewestFile();
|
||||
if (%file $= "")
|
||||
%wanted = trim(%wanted);
|
||||
if (%wanted $= "")
|
||||
{
|
||||
AutoSave_Tell(%client, "There is no autosave to load.");
|
||||
return;
|
||||
%file = AutoSave_NewestFile();
|
||||
if (%file $= "")
|
||||
{
|
||||
AutoSave_Tell(%client, "There is no autosave to load.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
%file = autoSaveFind(%wanted);
|
||||
if (getSubStr(%file, 0, 1) $= "*")
|
||||
{
|
||||
AutoSave_Tell(%client, "\c3" @ getSubStr(%file, 1, 10) @ "\c6 autosaves match \c3" @ %wanted @ "\c6. Type more of the name.");
|
||||
return;
|
||||
}
|
||||
if (%file $= "")
|
||||
{
|
||||
AutoSave_Tell(%client, "No autosave named \c3" @ %wanted @ "\c6 in saves/autosave/.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
%name = %client.getPlayerName();
|
||||
messageAll('', "\c6[\c3AutoSave\c6] \c3" @ %name @ "\c6 is loading \c3saves/autosave/" @ fileName(%file) @ "\c6.");
|
||||
@@ -1734,7 +1795,7 @@ function AutoSave_Command(%client, %cmd, %arg)
|
||||
}
|
||||
if (%cmd $= "status")
|
||||
{
|
||||
AutoSave_Tell(%client, "Enabled \c3" @ ($AutoSave::Enabled ? "on" : "off") @ "\c6, every \c3" @ $AutoSave::Interval @ "\c6 seconds, \c3" @ $AutoSave::Chunk @ "\c6 bricks per slice, \c3" @ $AutoSave::Tick @ "\c6 ms between slices, screenshots \c3" @ ($AutoSave::Preview ? "on" : "off") @ "\c6.");
|
||||
AutoSave_Tell(%client, "Enabled \c3" @ ($AutoSave::Enabled ? "on" : "off") @ "\c6, every \c3" @ $AutoSave::Interval @ "\c6 seconds, \c3" @ $AutoSave::Chunk @ "\c6 bricks per slice, \c3" @ $AutoSave::Tick @ "\c6 ms between slices, screenshots \c3" @ ($AutoSave::Preview ? "on" : "off") @ "\c6, autoload \c3" @ ($AutoSave::AutoLoad ? "on" : "off") @ "\c6.");
|
||||
return;
|
||||
}
|
||||
if (!AutoSave_Admin(%client))
|
||||
@@ -1772,7 +1833,24 @@ function AutoSave_Command(%client, %cmd, %arg)
|
||||
}
|
||||
if (%cmd $= "load" || %cmd $= "reload")
|
||||
{
|
||||
AutoSave_Reload(%client);
|
||||
AutoSave_Reload(%client, %arg);
|
||||
return;
|
||||
}
|
||||
if (%cmd $= "autoload")
|
||||
{
|
||||
%arg = strlwr(%arg);
|
||||
if (%arg $= "on" || %arg $= "1")
|
||||
%on = 1;
|
||||
else if (%arg $= "off" || %arg $= "0")
|
||||
%on = 0;
|
||||
else
|
||||
{
|
||||
AutoSave_Tell(%client, "Use \c3/autosaver autoload on\c6 or \c3/autosaver autoload off\c6.");
|
||||
return;
|
||||
}
|
||||
$AutoSave::AutoLoad = %on;
|
||||
autoSaveApply();
|
||||
messageAll('', "\c6[\c3AutoSave\c6] \c3" @ %name @ "\c6 turned autoload \c3" @ (%on ? "on" : "off") @ "\c6. " @ (%on ? "The newest autosave loads when the server starts." : ""));
|
||||
return;
|
||||
}
|
||||
if (%cmd $= "preview" || %cmd $= "screenshot" || %cmd $= "screenshots")
|
||||
@@ -1834,21 +1912,25 @@ function AutoSave_Command(%client, %cmd, %arg)
|
||||
}
|
||||
AutoSave_Tell(%client, "Unknown command. Type \c3/autosaver help\c6.");
|
||||
}
|
||||
function serverCmdautosaver(%client, %cmd, %arg)
|
||||
function AutoSave_Join(%a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10)
|
||||
{
|
||||
AutoSave_Command(%client, %cmd, %arg);
|
||||
return trim(%a1 SPC %a2 SPC %a3 SPC %a4 SPC %a5 SPC %a6 SPC %a7 SPC %a8 SPC %a9 SPC %a10);
|
||||
}
|
||||
function serverCmdAutosaver(%client, %cmd, %arg)
|
||||
function serverCmdautosaver(%client, %cmd, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10)
|
||||
{
|
||||
AutoSave_Command(%client, %cmd, %arg);
|
||||
AutoSave_Command(%client, %cmd, AutoSave_Join(%a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10));
|
||||
}
|
||||
function serverCmdAutoSaver(%client, %cmd, %arg)
|
||||
function serverCmdAutosaver(%client, %cmd, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10)
|
||||
{
|
||||
AutoSave_Command(%client, %cmd, %arg);
|
||||
AutoSave_Command(%client, %cmd, AutoSave_Join(%a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10));
|
||||
}
|
||||
function serverCmdAUTOSAVER(%client, %cmd, %arg)
|
||||
function serverCmdAutoSaver(%client, %cmd, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10)
|
||||
{
|
||||
AutoSave_Command(%client, %cmd, %arg);
|
||||
AutoSave_Command(%client, %cmd, AutoSave_Join(%a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10));
|
||||
}
|
||||
function serverCmdAUTOSAVER(%client, %cmd, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10)
|
||||
{
|
||||
AutoSave_Command(%client, %cmd, AutoSave_Join(%a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10));
|
||||
}
|
||||
$AutoSave::ChatInstalled = 1;
|
||||
)TS";
|
||||
@@ -1890,9 +1972,9 @@ package AutoSaveWatch
|
||||
{
|
||||
%client = findLocalClient();
|
||||
if (isObject(%client))
|
||||
AutoSave_Command(%client, getWord(%body, 1), getWord(%body, 2));
|
||||
AutoSave_Command(%client, getWord(%body, 1), getWords(%body, 2));
|
||||
else
|
||||
commandToServer('autosaver', getWord(%body, 1), getWord(%body, 2));
|
||||
commandToServer('autosaver', getWord(%body, 1), getWords(%body, 2));
|
||||
Canvas.popDialog(newMessageHud);
|
||||
return;
|
||||
}
|
||||
@@ -1918,6 +2000,11 @@ package AutoSaveWatch
|
||||
Parent::ServerLoadSaveFile_End();
|
||||
$AutoSave::Loading = 0;
|
||||
$AutoSave::Change++;
|
||||
if ($AutoSave::AutoLoading)
|
||||
{
|
||||
$AutoSave::AutoLoading = 0;
|
||||
autoSaveBaseline();
|
||||
}
|
||||
}
|
||||
function serverCmdCancelSaveFileUpload(%client)
|
||||
{
|
||||
@@ -1925,11 +2012,16 @@ package AutoSaveWatch
|
||||
if (!isObject($Server_LoadFileObj))
|
||||
$AutoSave::Loading = 0;
|
||||
$AutoSave::Change++;
|
||||
$AutoSave::AutoLoading = 0;
|
||||
}
|
||||
function destroyServer()
|
||||
{
|
||||
$AutoSave::Loading = 0;
|
||||
$AutoSave::AutoLoading = 0;
|
||||
if (isEventPending($AutoSave::AutoLoadSchedule))
|
||||
cancel($AutoSave::AutoLoadSchedule);
|
||||
Parent::destroyServer();
|
||||
autoSaveRewatch();
|
||||
}
|
||||
function serverCmdAddEvent(%client, %enabled, %inputEventIdx, %delay, %targetIdx, %NTNameIdx, %outputEventIdx, %par1, %par2, %par3, %par4)
|
||||
{
|
||||
@@ -2120,24 +2212,42 @@ static void autoSaveTick(ADDR obj, int argc, const char *argv[])
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
notePreview();
|
||||
if (!hosting()) {
|
||||
gHostSeen = false;
|
||||
reschedule();
|
||||
return;
|
||||
}
|
||||
if (!gHostSeen) {
|
||||
gHostSeen = true;
|
||||
prefsFromScript();
|
||||
BlPrintf("%s: $Pref::Server::AutoSave: %s, every %d seconds, %d bricks per slice, %d ms, preview %s", PROJECT_NAME,
|
||||
gEnabled ? "on" : "off", gInterval, gChunk, gTickMs, gPreview ? "on" : "off");
|
||||
reschedule();
|
||||
return;
|
||||
}
|
||||
if (gEnabled && gPhase == 0)
|
||||
if (gServerId != 0 && gEnabled && gPhase == 0 && hosting())
|
||||
beginSave();
|
||||
reschedule();
|
||||
}
|
||||
|
||||
static void scheduleHostCheck()
|
||||
{
|
||||
tsf_Eval("if (isEventPending($AutoSave::HostSchedule)) cancel($AutoSave::HostSchedule);"
|
||||
"$AutoSave::HostSchedule = schedule(5000, 0, autoSaveHostCheck);");
|
||||
}
|
||||
|
||||
/* Each mission creates a new MissionGroup, so its id tells servers apart even
|
||||
when one stops and the next starts between two save intervals. */
|
||||
static void autoSaveHostCheck(ADDR obj, int argc, const char *argv[])
|
||||
{
|
||||
(void)obj;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
ADDR missionGroup = hosting() ? tsf_FindObject("MissionGroup") : 0;
|
||||
int id = missionGroup != 0 ? *(int *)(missionGroup + 0x20) : 0;
|
||||
if (id != 0 && id != gServerId) {
|
||||
gServerId = id;
|
||||
gHaveBaseline = false;
|
||||
prefsFromScript();
|
||||
BlPrintf("%s: $Pref::Server::AutoSave: %s, every %d seconds, %d bricks per slice, %d ms, screenshots %s, autoload %s", PROJECT_NAME,
|
||||
gEnabled ? "on" : "off", gInterval, gChunk, gTickMs, gPreview ? "on" : "off", gAutoLoad ? "on" : "off");
|
||||
if (gAutoLoad && truthy(callFn1("isFunction", "AutoSave_AutoLoadStart")))
|
||||
tsf_Eval("AutoSave_AutoLoadStart();");
|
||||
tsf_Eval("if (isEventPending($AutoSave::Schedule)) cancel($AutoSave::Schedule);");
|
||||
reschedule();
|
||||
} else if (id == 0) {
|
||||
gServerId = 0;
|
||||
}
|
||||
scheduleHostCheck();
|
||||
}
|
||||
|
||||
static char gReturnText[32];
|
||||
|
||||
static const char *autoSaveNow(ADDR obj, int argc, const char *argv[])
|
||||
@@ -2161,6 +2271,72 @@ static const char *autoSaveNow(ADDR obj, int argc, const char *argv[])
|
||||
return gReturnText;
|
||||
}
|
||||
|
||||
static char gFoundPath[MAX_PATH];
|
||||
|
||||
/* Returns saves/autosave/<name>.bls for an exact name (with or without .bls,
|
||||
any case) or for the one file whose name contains the text. "*N" means N
|
||||
files contain it, "" means none. Names cannot leave the folder. */
|
||||
static const char *autoSaveFind(ADDR obj, int argc, const char *argv[])
|
||||
{
|
||||
(void)obj;
|
||||
(void)argc;
|
||||
std::string name = argv[1] != 0 ? argv[1] : "";
|
||||
char folder[MAX_PATH];
|
||||
WIN32_FIND_DATAA found;
|
||||
HANDLE handle;
|
||||
std::string match;
|
||||
std::string lowerName;
|
||||
int prefixCount = 0;
|
||||
|
||||
while (!name.empty() && name[0] == ' ')
|
||||
name.erase(0, 1);
|
||||
while (!name.empty() && name[name.size() - 1] == ' ')
|
||||
name.erase(name.size() - 1);
|
||||
if (_strnicmp(name.c_str(), "saves/autosave/", 15) == 0)
|
||||
name.erase(0, 15);
|
||||
if (name.size() >= 4 && _stricmp(name.c_str() + name.size() - 4, ".bls") == 0)
|
||||
name.erase(name.size() - 4);
|
||||
if (name.empty() || name.find_first_of("/\\:*?\"<>|") != std::string::npos || name.find("..") != std::string::npos)
|
||||
return "";
|
||||
if (!gameFile(folder, MAX_PATH, "autosave\\*.bls"))
|
||||
return "";
|
||||
handle = FindFirstFileA(folder, &found);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
return "";
|
||||
do {
|
||||
if (found.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
continue;
|
||||
std::string file = found.cFileName;
|
||||
if (file.size() < 4 || _stricmp(file.c_str() + file.size() - 4, ".bls") != 0)
|
||||
continue;
|
||||
std::string base = file.substr(0, file.size() - 4);
|
||||
if (_stricmp(base.c_str(), name.c_str()) == 0) {
|
||||
match = file;
|
||||
prefixCount = 1;
|
||||
break;
|
||||
}
|
||||
if (lowerName.empty()) {
|
||||
lowerName = name;
|
||||
std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), ::tolower);
|
||||
}
|
||||
std::transform(base.begin(), base.end(), base.begin(), ::tolower);
|
||||
if (base.find(lowerName) != std::string::npos) {
|
||||
if (prefixCount == 0)
|
||||
match = file;
|
||||
prefixCount++;
|
||||
}
|
||||
} while (FindNextFileA(handle, &found));
|
||||
FindClose(handle);
|
||||
if (prefixCount == 0)
|
||||
return "";
|
||||
if (prefixCount > 1) {
|
||||
std::snprintf(gFoundPath, sizeof(gFoundPath), "*%d", prefixCount);
|
||||
return gFoundPath;
|
||||
}
|
||||
std::snprintf(gFoundPath, sizeof(gFoundPath), "saves/autosave/%s", match.c_str());
|
||||
return gFoundPath;
|
||||
}
|
||||
|
||||
static char gNewestPath[MAX_PATH];
|
||||
|
||||
static const char *autoSaveNewest(ADDR obj, int argc, const char *argv[])
|
||||
@@ -2213,6 +2389,7 @@ static void deferredInstall()
|
||||
if (!gArmed) {
|
||||
gArmed = true;
|
||||
reschedule();
|
||||
scheduleHostCheck();
|
||||
}
|
||||
if (!gChat)
|
||||
installChat();
|
||||
@@ -2237,6 +2414,30 @@ static VOID CALLBACK installTimerProc(HWND hwnd, UINT message, UINT_PTR id, DWOR
|
||||
}
|
||||
}
|
||||
|
||||
/* destroyServer deactivates every package activated after the client
|
||||
add-ons, AutoSaveWatch included, so it is installed again afterwards. */
|
||||
static void autoSaveRewatch(ADDR obj, int argc, const char *argv[])
|
||||
{
|
||||
(void)obj;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
gWatching = false;
|
||||
tsf_Eval("$AutoSave::WatchInstalled = 0;");
|
||||
if (gInstallTimer == 0)
|
||||
gInstallTimer = SetTimer(0, 0, 500, installTimerProc);
|
||||
}
|
||||
|
||||
/* A build that was just loaded from a file matches that file. */
|
||||
static void autoSaveBaseline(ADDR obj, int argc, const char *argv[])
|
||||
{
|
||||
(void)obj;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
gSavedChange = gChange;
|
||||
gSavedCount = brickCount();
|
||||
gHaveBaseline = true;
|
||||
}
|
||||
|
||||
bool init()
|
||||
{
|
||||
if (!tsh_InitInternal())
|
||||
@@ -2252,14 +2453,19 @@ bool init()
|
||||
tsf_AddVar("AutoSave::Change", &gChange);
|
||||
tsf_AddVar("AutoSave::Loading", &gLoading);
|
||||
tsf_AddVar("AutoSave::Preview", &gPreview);
|
||||
tsf_AddVar("AutoSave::AutoLoad", &gAutoLoad);
|
||||
installPreview();
|
||||
tsf_AddConsoleFunc(0, 0, "autoSaveTick", autoSaveTick, "autoSaveTick() - timed brick save", 1, 1);
|
||||
tsf_AddConsoleFunc(0, 0, "autoSaveChunk", autoSaveChunk, "autoSaveChunk() - continue a brick save", 1, 1);
|
||||
tsf_AddConsoleFunc(0, 0, "autoSaveApply", autoSaveApply, "autoSaveApply() - clamp autosave prefs, write config/server/prefs.cs and reschedule", 1, 1);
|
||||
tsf_AddConsoleFunc(0, 0, "autoSave", autoSaveNow, "autoSave() - write a dated save in saves/autosave/", 1, 1);
|
||||
tsf_AddConsoleFunc(0, 0, "autoSaveNewest", autoSaveNewest, "autoSaveNewest() - newest file in saves/autosave/", 1, 1);
|
||||
tsf_AddConsoleFunc(0, 0, "autoSaveFind", autoSaveFind, "autoSaveFind(name) - saves/autosave/ file by name or unique start", 2, 2);
|
||||
tsf_AddConsoleFunc(0, 0, "autoSavePreviewPoll", autoSavePreviewPoll, "autoSavePreviewPoll() - report a finished save screenshot", 1, 1);
|
||||
tsf_AddConsoleFunc(0, 0, "autoSaveTraceStep", autoSaveTraceStep, "autoSaveTraceStep() - trace part of a save screenshot", 1, 1);
|
||||
tsf_AddConsoleFunc(0, 0, "autoSaveHostCheck", autoSaveHostCheck, "autoSaveHostCheck() - notice a new server", 1, 1);
|
||||
tsf_AddConsoleFunc(0, 0, "autoSaveRewatch", autoSaveRewatch, "autoSaveRewatch() - install the change watcher again", 1, 1);
|
||||
tsf_AddConsoleFunc(0, 0, "autoSaveBaseline", autoSaveBaseline, "autoSaveBaseline() - treat the current build as saved", 1, 1);
|
||||
gInstallTimer = SetTimer(0, 0, 500, installTimerProc);
|
||||
if (gInstallTimer == 0)
|
||||
BlPrintf("%s: could not start the install timer", PROJECT_NAME);
|
||||
@@ -2279,6 +2485,7 @@ bool deinit()
|
||||
tsf_Eval("if (isEventPending($AutoSave::ChunkSchedule)) cancel($AutoSave::ChunkSchedule);");
|
||||
tsf_Eval("if (isEventPending($AutoSave::PreviewSchedule)) cancel($AutoSave::PreviewSchedule);");
|
||||
tsf_Eval("if (isEventPending($AutoSave::TraceSchedule)) cancel($AutoSave::TraceSchedule);");
|
||||
tsf_Eval("if (isEventPending($AutoSave::HostSchedule)) cancel($AutoSave::HostSchedule);");
|
||||
if (gWatching)
|
||||
tsf_Eval("deactivatePackage(AutoSaveWatch);");
|
||||
clearSave();
|
||||
|
||||
Reference in new issue
Block a user