2023-07-24 19:38:26 +00:00
|
|
|
#include <iostream>
|
2023-07-24 19:58:58 +00:00
|
|
|
#include <cstring>
|
2023-07-24 19:38:26 +00:00
|
|
|
#include <string>
|
|
|
|
#include <locale>
|
|
|
|
#include <curl/curl.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string>
|
|
|
|
#include <vitasdk.h>
|
|
|
|
#include <vitaGL.h>
|
|
|
|
#include "dialogs.h"
|
|
|
|
#include "network.h"
|
|
|
|
|
|
|
|
volatile char generic_url[512];
|
|
|
|
static CURL *curl_handle = NULL;
|
|
|
|
volatile uint64_t total_bytes = 0xFFFFFFFF;
|
|
|
|
volatile uint64_t downloaded_bytes = 0;
|
|
|
|
volatile uint8_t downloader_pass = 1;
|
|
|
|
uint8_t *generic_mem_buffer = nullptr;
|
|
|
|
static FILE *fh;
|
|
|
|
char *bytes_string;
|
|
|
|
|
|
|
|
static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *stream) {
|
|
|
|
if (total_bytes > MEM_BUFFER_SIZE || fh) {
|
|
|
|
if (!fh)
|
|
|
|
fh = fopen(TEMP_DOWNLOAD_NAME, "wb");
|
|
|
|
fwrite(ptr, 1, nmemb, fh);
|
|
|
|
} else {
|
|
|
|
uint8_t *dst = &generic_mem_buffer[downloaded_bytes];
|
|
|
|
sceClibMemcpy(dst, ptr, nmemb);
|
|
|
|
}
|
|
|
|
downloaded_bytes += nmemb;
|
|
|
|
if (total_bytes < downloaded_bytes) total_bytes = downloaded_bytes;
|
|
|
|
return nmemb;
|
|
|
|
}
|
|
|
|
|
|
|
|
static size_t header_cb(char *buffer, size_t size, size_t nitems, void *userdata) {
|
|
|
|
char *ptr = strcasestr(buffer, "Content-Length");
|
|
|
|
if (ptr != NULL) sscanf(ptr, "Content-Length: %llu", &total_bytes);
|
|
|
|
return nitems;
|
|
|
|
}
|
|
|
|
|
|
|
|
static size_t header_dummy_cb(char *buffer, size_t size, size_t nitems, void *userdata) {
|
|
|
|
return nitems;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void startDownload(const char *url) {
|
|
|
|
curl_easy_reset(curl_handle);
|
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_URL, url);
|
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_HTTPGET, 1L);
|
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36");
|
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L);
|
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L);
|
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
|
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_CONNECTTIMEOUT, 10L);
|
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L);
|
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1L);
|
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_cb);
|
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, bytes_string); // Dummy
|
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, downloaded_bytes ? header_dummy_cb : header_cb);
|
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_HEADERDATA, bytes_string); // Dummy
|
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_RESUME_FROM, downloaded_bytes);
|
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_BUFFERSIZE, 524288);
|
|
|
|
struct curl_slist *headerchunk = NULL;
|
|
|
|
headerchunk = curl_slist_append(headerchunk, "Accept: */*");
|
|
|
|
headerchunk = curl_slist_append(headerchunk, "Content-Type: application/json");
|
|
|
|
headerchunk = curl_slist_append(headerchunk, "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36");
|
|
|
|
headerchunk = curl_slist_append(headerchunk, "Content-Length: 0");
|
|
|
|
curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headerchunk);
|
|
|
|
curl_easy_perform(curl_handle);
|
|
|
|
}
|
|
|
|
|
|
|
|
int downloadThread(unsigned int args, void *arg) {
|
|
|
|
curl_handle = curl_easy_init();
|
|
|
|
//printf("downloading %s\n", generic_url);
|
|
|
|
char *url = (char *)generic_url;
|
|
|
|
char *space = strstr(url, " ");
|
|
|
|
char *s = url;
|
|
|
|
char final_url[512] = "";
|
|
|
|
fh = NULL;
|
|
|
|
while (space) {
|
|
|
|
space[0] = 0;
|
|
|
|
sprintf(final_url, "%s%s%%20", final_url, s);
|
|
|
|
space[0] = ' ';
|
|
|
|
s = space + 1;
|
|
|
|
space = strstr(s, " ");
|
|
|
|
}
|
|
|
|
sprintf(final_url, "%s%s", final_url, s);
|
|
|
|
//printf("starting download of %s\n", final_url);
|
|
|
|
downloader_pass = 1;
|
|
|
|
downloaded_bytes = 0;
|
|
|
|
total_bytes = 180;
|
|
|
|
startDownload(final_url);
|
|
|
|
while (downloaded_bytes < total_bytes) {
|
|
|
|
startDownload(final_url);
|
|
|
|
}
|
|
|
|
if (downloaded_bytes > 180 && total_bytes <= MEM_BUFFER_SIZE) {
|
|
|
|
fh = fopen(TEMP_DOWNLOAD_NAME, "wb");
|
|
|
|
fwrite(generic_mem_buffer, 1, downloaded_bytes, fh);
|
|
|
|
}
|
|
|
|
fclose(fh);
|
|
|
|
downloaded_bytes = total_bytes;
|
|
|
|
curl_easy_cleanup(curl_handle);
|
|
|
|
return sceKernelExitDeleteThread(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void download_file(char *url, char *text) {
|
|
|
|
SceKernelThreadInfo info;
|
|
|
|
info.size = sizeof(SceKernelThreadInfo);
|
|
|
|
int res = 0;
|
|
|
|
SceUID thd = sceKernelCreateThread("Generic Downloader", &downloadThread, 0x10000100, 0x100000, 0, 0, NULL);
|
|
|
|
sprintf(generic_url, url);
|
|
|
|
sceKernelStartThread(thd, 0, NULL);
|
|
|
|
do {
|
|
|
|
DrawDownloaderDialog(downloader_pass, downloaded_bytes, total_bytes, text, 1, true);
|
|
|
|
res = sceKernelGetThreadInfo(thd, &info);
|
|
|
|
} while (info.status <= SCE_THREAD_DORMANT && res >= 0);
|
|
|
|
}
|