Files
smupdater-godtony/scripting/updater/download.sp
T
2020-08-19 20:37:30 +02:00

236 lines
5.3 KiB
SourcePawn

/* Download Manager */
#include "updater/download_curl.sp"
#include "updater/download_socket.sp"
#include "updater/download_steamtools.sp"
#include "updater/download_steamworks.sp"
DataPackPos QueuePack_URL;
void FinalizeDownload(int index)
{
/* Strip the temporary file extension from downloaded files. */
char newpath[PLATFORM_MAX_PATH];
char oldpath[PLATFORM_MAX_PATH];
Handle hFiles = Updater_GetFiles(index);
int maxFiles = GetArraySize(hFiles);
for (int i = 0; i < maxFiles; i++)
{
GetArrayString(hFiles, i, newpath, sizeof(newpath));
Format(oldpath, sizeof(oldpath), "%s.%s", newpath, TEMP_FILE_EXT);
// Rename doesn't overwrite on Windows. Make sure the path is clear.
if (FileExists(newpath))
{
DeleteFile(newpath);
}
RenameFile(newpath, oldpath);
}
ClearArray(hFiles);
}
void AbortDownload(int index)
{
/* Delete all downloaded temporary files. */
char path[PLATFORM_MAX_PATH];
Handle hFiles = Updater_GetFiles(index);
int maxFiles = GetArraySize(hFiles);
for (int i = 0; i < maxFiles; i++)
{
GetArrayString(hFiles, 0, path, sizeof(path));
Format(path, sizeof(path), "%s.%s", path, TEMP_FILE_EXT);
if (FileExists(path))
{
DeleteFile(path);
}
}
ClearArray(hFiles);
}
void ProcessDownloadQueue(bool force=false)
{
if (!force && (g_bDownloading || !GetArraySize(g_hDownloadQueue)))
{
return;
}
Handle hQueuePack = GetArrayCell(g_hDownloadQueue, 0);
SetPackPosition(hQueuePack, QueuePack_URL);
char url[MAX_URL_LENGTH];
char dest[PLATFORM_MAX_PATH];
ReadPackString(hQueuePack, url, sizeof(url));
ReadPackString(hQueuePack, dest, sizeof(dest));
if (!CURL_AVAILABLE() && !SOCKET_AVAILABLE() && !STEAMTOOLS_AVAILABLE() && !STEAMWORKS_AVAILABLE())
{
SetFailState(EXTENSION_ERROR);
}
#if defined DEBUG
Updater_DebugLog("Download started:");
Updater_DebugLog(" [0] URL: %s", url);
Updater_DebugLog(" [1] Destination: %s", dest);
#endif
g_bDownloading = true;
if (STEAMWORKS_AVAILABLE())
{
if (SteamWorks_IsLoaded())
{
Download_SteamWorks(url, dest);
}
else
{
CreateTimer(10.0, Timer_RetryQueue);
}
}
else if (STEAMTOOLS_AVAILABLE())
{
if (g_bSteamLoaded)
{
Download_SteamTools(url, dest);
}
else
{
CreateTimer(10.0, Timer_RetryQueue);
}
}
else if (CURL_AVAILABLE())
{
Download_cURL(url, dest);
}
else if (SOCKET_AVAILABLE())
{
Download_Socket(url, dest);
}
}
public Action Timer_RetryQueue(Handle timer)
{
ProcessDownloadQueue(true);
return Plugin_Stop;
}
void AddToDownloadQueue(int index, const char[] url, const char[] dest)
{
Handle hQueuePack = CreateDataPack();
WritePackCell(hQueuePack, index);
QueuePack_URL = GetPackPosition(hQueuePack);
WritePackString(hQueuePack, url);
WritePackString(hQueuePack, dest);
PushArrayCell(g_hDownloadQueue, hQueuePack);
ProcessDownloadQueue();
}
void DownloadEnded(bool successful, const char[] error="")
{
Handle hQueuePack = GetArrayCell(g_hDownloadQueue, 0);
ResetPack(hQueuePack);
char url[MAX_URL_LENGTH];
char dest[PLATFORM_MAX_PATH];
int index = ReadPackCell(hQueuePack);
ReadPackString(hQueuePack, url, sizeof(url));
ReadPackString(hQueuePack, dest, sizeof(dest));
// Remove from the queue.
CloseHandle(hQueuePack);
RemoveFromArray(g_hDownloadQueue, 0);
#if defined DEBUG
Updater_DebugLog(" [2] Successful: %s", successful ? "Yes" : "No");
#endif
switch (Updater_GetStatus(index))
{
case Status_Checking:
{
if (!successful || !ParseUpdateFile(index, dest))
{
Updater_SetStatus(index, Status_Idle);
#if defined DEBUG
if (error[0] != '\0')
{
Updater_DebugLog(" [2] %s", error);
}
#endif
}
}
case Status_Downloading:
{
if (successful)
{
// Check if this was the last file we needed.
char lastfile[PLATFORM_MAX_PATH];
Handle hFiles = Updater_GetFiles(index);
GetArrayString(hFiles, GetArraySize(hFiles) - 1, lastfile, sizeof(lastfile));
Format(lastfile, sizeof(lastfile), "%s.%s", lastfile, TEMP_FILE_EXT);
if (StrEqual(dest, lastfile))
{
Handle hPlugin = IndexToPlugin(index);
Fwd_OnPluginUpdating(hPlugin);
FinalizeDownload(index);
char sName[64];
if (!GetPluginInfo(hPlugin, PlInfo_Name, sName, sizeof(sName)))
{
strcopy(sName, sizeof(sName), "Null");
}
Updater_Log("Successfully updated and installed \"%s\".", sName);
Updater_SetStatus(index, Status_Updated);
Fwd_OnPluginUpdated(hPlugin);
}
}
else
{
// Failed during an update.
AbortDownload(index);
Updater_SetStatus(index, Status_Error);
char filename[64];
GetPluginFilename(IndexToPlugin(index), filename, sizeof(filename));
Updater_Log("Error downloading update for plugin: %s", filename);
Updater_Log(" [0] URL: %s", url);
Updater_Log(" [1] Destination: %s", dest);
if (error[0] != '\0')
{
Updater_Log(" [2] %s", error);
}
}
}
case Status_Error:
{
// Delete any additional files that this plugin had queued.
if (successful && FileExists(dest))
{
DeleteFile(dest);
}
}
}
g_bDownloading = false;
ProcessDownloadQueue();
}