Compare commits

...

5 Commits

Author SHA1 Message Date
Chee Yee 529d88af06 remove old hash from map 2023-08-30 13:37:17 -07:00
Chee Yee d26baf817e update readme 2023-08-30 08:34:22 -07:00
Chee Yee 01f2f44942 add ability to install via alldebrid 2023-08-30 02:30:26 -07:00
Chee Yee e28e562a10 add ability to install shared URL from web interface 2023-08-06 17:53:27 -07:00
Chee Yee 83661c7fcb add rclone http server support 2023-08-01 22:11:05 -07:00
38 changed files with 1288 additions and 177 deletions
+8
View File
@@ -40,6 +40,14 @@ add_executable(ezremote_client
source/clients/smbclient.cpp
source/clients/webdavclient.cpp
source/clients/sftpclient.cpp
source/clients/rclone.cpp
source/filehost/alldebrid.cpp
source/filehost/directhost.cpp
source/filehost/gdrive.cpp
source/filehost/filehost.cpp
source/filehost/1fichier.cpp
source/filehost/mediafire.cpp
source/filehost/pixeldrain.cpp
source/server/http_server.cpp
source/actions.cpp
source/config.cpp
+1
View File
@@ -114,6 +114,7 @@ Remote Package Installation with all Remote Server, even if they are password pr
- Upload files to the PS4
- Download files from the PS4
- Install packages on the PS4
- Install packages from shared links from mediafire, google and pixeldrain. For other filehost, they can installed via AllDebrid (See AllDebrid website for supported filehost).
## How to access the Web Interface ##
You need to launch the "ezRemote Client" app on the PS4. Then on any device(laptop, tablet, phone etc..) with web browser goto to http://<ip_address_of_ps4>:8080 . That's all.
+1
View File
@@ -41,6 +41,7 @@
permissionsUrl: '/__local__/permission',
installUrl: '/__local__/install',
uploadResumeSizeUrl: '__local__/uploadResumeSize',
installUrlUrl: '/__local__/install_url',
multipleDownloadFileName: 'ezremote-client.zip',
isExtractableFilePattern: /\.(7z|rar|zip)$/i,
pickCallback: function (item) {
+7 -1
View File
@@ -82,7 +82,7 @@ STR_ONETIME_URL=One Time Url
STR_NOT_A_VALID_PACKAGE=Not a valid Package
STR_WAIT_FOR_INSTALL_MSG=Waiting for Package to finish installing
STR_FAIL_INSTALL_TMP_PKG_MSG=Failed to install pkg file. Please delete the tmp pkg manually
STR_FAIL_TO_OBTAIN_GG_DL_MSG=Failed to obtain google download URL
STR_FAIL_TO_OBTAIN_GG_DL_MSG=Failed to obtain download URL
STR_AUTO_DELETE_TMP_PKG=Auto delete temporary downloaded pkg file after install
STR_PROTOCOL_NOT_SUPPORTED=Protocol not supported
STR_COULD_NOT_RESOLVE_HOST=Could not resolve hostname
@@ -150,3 +150,9 @@ STR_WEB_SERVER=Web Server
STR_ENABLE=Enable
STR_COMPRESSED_FILE_PATH=Compressed Files Location
STR_COMPRESSED_FILE_PATH_MSG=Location of where compressed files are stored on the web server
STR_ALLDEBRID=AllDebrid
STR_API_KEY=API Key
STR_CANT_EXTRACT_URL_MSG=Couldn't extract download url
STR_FAIL_INSTALL_FROM_URL_MSG=Failed to install from URL
STR_INVALID_URL=InValid URL
STR_ALLDEBRID_API_KEY_MISSING_MSG=To use this function, an API Key needs to be configured in the ezRemote Client settings
File diff suppressed because one or more lines are too long
+16 -84
View File
@@ -14,7 +14,9 @@
#include "clients/npxserve.h"
#include "clients/nfsclient.h"
#include "clients/iis.h"
#include "clients/rclone.h"
#include "clients/sftpclient.h"
#include "filehost/filehost.h"
#include "common.h"
#include "fs.h"
#include "config.h"
@@ -706,7 +708,8 @@ namespace Actions
}
else
{
if (INSTALLER::InstallRemotePkg(it->path, &header) == 0)
std::string url = INSTALLER::getRemoteUrl(it->path, true);
if (INSTALLER::InstallRemotePkg(url, &header, true) == 0)
failed++;
else
success++;
@@ -918,87 +921,6 @@ namespace Actions
}
}
std::string GetGoogleDownloadUrl(std::string &url)
{
size_t scheme_pos = url.find_first_of("://");
size_t path_pos = url.find_first_of("/", scheme_pos + 3);
std::string host = url.substr(0, path_pos);
std::string path = url.substr(path_pos);
std::string first_download_path;
size_t file_id_start_pos = path.find("/file/d/");
if (file_id_start_pos != std::string::npos)
{
file_id_start_pos = file_id_start_pos + 8;
std::string file_id = path.substr(file_id_start_pos);
size_t file_id_end_pos = file_id.find_first_of("/");
file_id = file_id.substr(0, file_id_end_pos);
first_download_path = "/uc?export=download&id=" + file_id;
}
else if (path.find("/uc?export=download") != std::string::npos)
{
first_download_path = path;
}
else
{
return "";
}
WebDAV::WebDavClient tmp_client;
tmp_client.Connect(host.c_str(), "", "", false);
WebDAV::dict_t headers;
tmp_client.GetHeaders(first_download_path.c_str(), &headers);
std::string content_type = WebDAV::get(headers, "content-type");
if (content_type.find("application/octet-stream") != std::string::npos)
{
return first_download_path;
}
else if (content_type.find("text/html") == std::string::npos)
{
return "";
}
char *buffer_ptr = nullptr;
unsigned long long buffer_size = 0;
tmp_client.GetClient()->download_to(first_download_path, buffer_ptr, buffer_size);
lxb_status_t status;
lxb_dom_element_t *element;
lxb_html_document_t *document;
lxb_dom_collection_t *collection;
lxb_dom_attr_t *attr;
document = lxb_html_document_create();
status = lxb_html_document_parse(document, (lxb_char_t *)buffer_ptr, buffer_size);
if (status != LXB_STATUS_OK)
return "";
collection = lxb_dom_collection_make(&document->dom_document, 128);
if (collection == NULL)
{
return "";
}
status = lxb_dom_elements_by_tag_name(lxb_dom_interface_element(document->body),
collection, (const lxb_char_t *)"form", 4);
if (status != LXB_STATUS_OK)
return "";
std::string download_url;
for (size_t i = 0; i < lxb_dom_collection_length(collection); i++)
{
element = lxb_dom_collection_element(collection, i);
std::string form_id((char *)element->attr_id->value->data, element->attr_id->value->length);
if (form_id == "download-form")
{
size_t value_len;
const lxb_char_t *value = lxb_dom_element_get_attribute(element, (const lxb_char_t *)"action", 6, &value_len);
download_url = std::string((char *)value, value_len);
break;
}
}
lxb_dom_collection_destroy(collection, true);
lxb_html_document_destroy(document);
return download_url;
}
void *InstallUrlPkgThread(void *argp)
{
bytes_transfered = 0;
@@ -1012,8 +934,16 @@ namespace Actions
sprintf(filename, "%s/%lu.pkg", DATA_PATH, tick.mytick);
std::string full_url = std::string(install_pkg_url.url);
if (full_url.find("https://drive.google.com") != std::string::npos)
full_url = GetGoogleDownloadUrl(full_url);
FileHost *filehost = FileHost::getFileHost(full_url);
if (!filehost->IsValidUrl())
{
sprintf(status_message, "%s", lang_strings[STR_FAIL_TO_OBTAIN_GG_DL_MSG]);
activity_inprogess = false;
Windows::SetModalMode(false);
return NULL;
}
full_url = filehost->GetDownloadUrl();
delete(filehost);
if (full_url.empty())
{
@@ -1133,6 +1063,8 @@ namespace Actions
remoteclient = new NginxClient();
else if (strcmp(remote_settings->http_server_type, HTTP_SERVER_NPX_SERVE) == 0)
remoteclient = new NpxServeClient();
else if (strcmp(remote_settings->http_server_type, HTTP_SERVER_RCLONE) == 0)
remoteclient = new RCloneClient();
}
else if (strncmp(remote_settings->server, "webdavs://", 10) == 0 || strncmp(remote_settings->server, "webdav://", 9) == 0)
{
+6 -2
View File
@@ -6,7 +6,7 @@
class Base64
{
public:
static int Encode(const std::string &input, std::string &out)
static int Encode(unsigned char *input, size_t in_len, std::string &out)
{
static constexpr char sEncodingTable[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
@@ -18,7 +18,6 @@ public:
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'};
size_t in_len = input.size();
size_t out_len = 4 * ((in_len + 2) / 3);
out.resize(out_len);
size_t i;
@@ -50,6 +49,11 @@ public:
return 1;
}
static int Encode(const std::string &input, std::string &out)
{
return Encode((unsigned char*)input.data(), input.size(), out);
}
static int Decode(const std::string &input, std::string &out)
{
static constexpr unsigned char kDecodingTable[] = {
+5 -25
View File
@@ -12,26 +12,6 @@ using httplib::Client;
using httplib::Headers;
using httplib::Result;
lxb_dom_node_t *nextChildElement(lxb_dom_element_t *element)
{
lxb_dom_node_t *node = element->node.first_child;
while (node != nullptr && node->type != LXB_DOM_NODE_TYPE_ELEMENT)
{
node = node->next;
}
return node;
}
lxb_dom_node_t *nextElement(lxb_dom_node_t *node)
{
lxb_dom_node_t *next = node->next;
while (next != nullptr && next->type != LXB_DOM_NODE_TYPE_ELEMENT)
{
next = next->next;
}
return next;
}
std::vector<DirEntry> ApacheClient::ListDir(const std::string &path)
{
std::vector<DirEntry> out;
@@ -101,7 +81,7 @@ std::vector<DirEntry> ApacheClient::ListDir(const std::string &path)
memset(&entry, 0, sizeof(DirEntry));
element = lxb_dom_collection_element(collection, i);
node = nextChildElement(element);
node = NextChildElement(element);
if (node == nullptr) continue;
value = lxb_dom_element_local_name(lxb_dom_interface_element(node), &value_len);
@@ -114,7 +94,7 @@ std::vector<DirEntry> ApacheClient::ListDir(const std::string &path)
if (tmp_string.compare("td") == 0)
{
// get the child img element
lxb_dom_node_t *img = nextChildElement(lxb_dom_interface_element(node));
lxb_dom_node_t *img = NextChildElement(lxb_dom_interface_element(node));
if (img == nullptr) continue;
value = lxb_dom_element_local_name(lxb_dom_interface_element(img), &value_len);
@@ -142,7 +122,7 @@ std::vector<DirEntry> ApacheClient::ListDir(const std::string &path)
else continue; // invalid record
// file/folder name
node = nextElement(node);
node = NextElement(node);
if (node == nullptr) continue;
value = lxb_dom_element_local_name(lxb_dom_interface_element(node), &value_len);
tmp_string = std::string((const char *)value, value_len);
@@ -165,7 +145,7 @@ std::vector<DirEntry> ApacheClient::ListDir(const std::string &path)
else continue; // not valid record
// datetime
node = nextElement(node);
node = NextElement(node);
if (node == nullptr) continue;
value = lxb_dom_element_local_name(lxb_dom_interface_element(node), &value_len);
tmp_string = std::string((const char *)value, value_len);
@@ -195,7 +175,7 @@ std::vector<DirEntry> ApacheClient::ListDir(const std::string &path)
else continue; // invalid record
// filesize
node = nextElement(node);
node = NextElement(node);
if (node == nullptr) continue;
value = lxb_dom_element_local_name(lxb_dom_interface_element(node), &value_len);
tmp_string = std::string((const char *)value, value_len);
-2
View File
@@ -1,5 +1,3 @@
#include <lexbor/html/parser.h>
#include <lexbor/dom/interfaces/element.h>
#include <fstream>
#include <curl/curl.h>
#include "common.h"
+2
View File
@@ -3,6 +3,8 @@
#include <string>
#include <vector>
#include <lexbor/html/parser.h>
#include <lexbor/dom/interfaces/element.h>
#include "http/httplib.h"
#include "clients/remote_client.h"
#include "http/httplib.h"
+225
View File
@@ -0,0 +1,225 @@
#include <lexbor/html/parser.h>
#include <lexbor/dom/interfaces/element.h>
#include <fstream>
#include "common.h"
#include "clients/remote_client.h"
#include "clients/rclone.h"
#include "lang.h"
#include "util.h"
#include "system.h"
#include "windows.h"
#include "dbglogger.h"
using httplib::Client;
using httplib::Headers;
using httplib::Result;
std::vector<DirEntry> RCloneClient::ListDir(const std::string &path)
{
std::vector<DirEntry> out;
DirEntry entry;
Util::SetupPreviousFolder(path, &entry);
out.push_back(entry);
std::string encoded_path = httplib::detail::encode_url(GetFullPath(path)+"/");
if (auto res = client->Get(encoded_path))
{
lxb_status_t status;
lxb_dom_attr_t *attr;
lxb_dom_element_t *tbody_element, *tr_element, *td_element;
lxb_html_document_t *document;
lxb_dom_collection_t *tbody_collection;
lxb_dom_collection_t *tr_collection;
lxb_dom_collection_t *td_collection;
document = lxb_html_document_create();
status = lxb_html_document_parse(document, (lxb_char_t *)res->body.c_str(), res->body.length());
if (status != LXB_STATUS_OK)
{
lxb_html_document_destroy(document);
goto finish;
}
tbody_collection = lxb_dom_collection_make(&document->dom_document, 1);
if (tbody_collection == NULL)
{
lxb_html_document_destroy(document);
goto finish;
}
tr_collection = lxb_dom_collection_make(&document->dom_document, 128);
if (tbody_collection == NULL)
{
lxb_html_document_destroy(document);
goto finish;
}
status = lxb_dom_elements_by_tag_name(lxb_dom_interface_element(document->body),
tbody_collection, (const lxb_char_t *)"tbody", 5);
if (status != LXB_STATUS_OK)
{
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(tbody_collection, true);
lxb_html_document_destroy(document);
goto finish;
}
if (lxb_dom_collection_length(tbody_collection) < 1)
{
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(tbody_collection, true);
lxb_html_document_destroy(document);
goto finish;
}
// Get the first tbody which should only be 1
tbody_element = lxb_dom_collection_element(tbody_collection, 0);
status = lxb_dom_elements_by_tag_name(tbody_element,
tr_collection, (const lxb_char_t *)"tr", 2);
if (status != LXB_STATUS_OK)
{
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(tbody_collection, true);
lxb_html_document_destroy(document);
goto finish;
}
// skip row 0 , since it has the previous folder header
for (size_t i = 1; i < lxb_dom_collection_length(tr_collection); i++)
{
DirEntry entry;
std::string title, aclass;
memset(&entry.modified, 0, sizeof(DateTime));
const lxb_char_t *value;
size_t value_len;
std::string tmp_string;
tr_element = lxb_dom_collection_element(tr_collection, i);
td_collection = lxb_dom_collection_make(&document->dom_document, 5);
status = lxb_dom_elements_by_tag_name(tr_element,
td_collection, (const lxb_char_t *)"td", 2);
if (status != LXB_STATUS_OK || lxb_dom_collection_length(td_collection) < 0)
{
lxb_dom_collection_destroy(td_collection, true);
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(tbody_collection, true);
lxb_html_document_destroy(document);
goto finish;
}
// td 0 is empty, td 1 is file or folder
td_element = lxb_dom_collection_element(td_collection, 1);
lxb_dom_node_t *use_node = NextChildElement(lxb_dom_interface_element(NextChildElement(td_element)));
value = lxb_dom_element_local_name(lxb_dom_interface_element(use_node), &value_len);
tmp_string = std::string((const char *)value, value_len);
if (tmp_string.compare("use") != 0)
{
lxb_dom_collection_destroy(td_collection, true);
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(tbody_collection, true);
lxb_html_document_destroy(document);
goto finish;
}
value = lxb_dom_element_get_attribute(lxb_dom_interface_element(use_node), (const lxb_char_t *)"xlink:href", 10, &value_len);
tmp_string = std::string((const char *)value, value_len);
if (tmp_string.compare("#folder") == 0)
{
entry.isDir = true;
entry.selectable = true;
entry.file_size = 0;
sprintf(entry.display_size, "%s", lang_strings[STR_FOLDER]);
}
else
{
entry.isDir = false;
entry.selectable = true;
}
// <a> element contains the file/folder name
lxb_dom_node_t *a_node = NextChildElement(lxb_dom_interface_element(NextElement(NextChildElement(td_element))));
value = lxb_dom_element_get_attribute(lxb_dom_interface_element(a_node), (const lxb_char_t *)"href", 4, &value_len);
tmp_string = std::string((const char *)value, value_len);
if (tmp_string[tmp_string.length()-1] == '/')
tmp_string = tmp_string.substr(0, tmp_string.length()-1);
tmp_string = BaseClient::DecodeUrl(tmp_string);
sprintf(entry.name, "%s", tmp_string.c_str());
sprintf(entry.directory, "%s", path.c_str());
if (path.length() > 0 && path[path.length() - 1] == '/')
{
sprintf(entry.path, "%s%s", path.c_str(), entry.name);
}
else
{
sprintf(entry.path, "%s/%s", path.c_str(), entry.name);
}
// td 3 - filesize
if (!entry.isDir)
{
td_element = lxb_dom_collection_element(td_collection, 2);
lxb_dom_node_t *size_node = NextChildElement(td_element);
value = lxb_dom_node_text_content(size_node->first_child, &value_len);
tmp_string = std::string((const char *)value, value_len);
entry.file_size = atoi(tmp_string.c_str());
DirEntry::SetDisplaySize(&entry);
}
// td 4 - datetime
td_element = lxb_dom_collection_element(td_collection, 3);
lxb_dom_node_t *date_node = NextChildElement(td_element);
value = lxb_dom_element_get_attribute(lxb_dom_interface_element(date_node), (const lxb_char_t *)"datetime", 8, &value_len);
tmp_string = std::string((const char *)value, value_len);
std::vector<std::string> date_time = Util::Split(tmp_string, " ");
OrbisDateTime gmt;
OrbisDateTime lt;
if (date_time.size() > 1)
{
std::vector<std::string> adate = Util::Split(date_time[0], "-");
if (adate.size() == 3)
{
gmt.year = atoi(adate[0].c_str());
gmt.month = atoi(adate[1].c_str());
gmt.day = atoi(adate[2].c_str());
}
std::vector<std::string> atime = Util::Split(date_time[1], ":");
if (atime.size() == 3)
{
gmt.hour = atoi(atime[0].c_str());
gmt.minute = atoi(atime[1].c_str());
std::vector<std::string> sec_msec = Util::Split(atime[2], ".");
if (sec_msec.size() > 0)
{
gmt.second = atoi(sec_msec[0].c_str());
}
}
}
convertUtcToLocalTime(&gmt, &lt);
entry.modified.day = lt.day;
entry.modified.month = lt.month;
entry.modified.year = lt.year;
entry.modified.hours = lt.hour;
entry.modified.minutes = lt.minute;
entry.modified.seconds = lt.second;
lxb_dom_collection_destroy(td_collection, true);
out.push_back(entry);
}
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(tbody_collection, true);
lxb_html_document_destroy(document);
}
else
{
sprintf(this->response, "%s", httplib::to_string(res.error()).c_str());
return out;
}
finish:
return out;
}
+17
View File
@@ -0,0 +1,17 @@
#ifndef RCLONE_H
#define RCLONE_H
#include <string>
#include <vector>
#include "http/httplib.h"
#include "clients/baseclient.h"
#include "clients/remote_client.h"
#include "common.h"
class RCloneClient : public BaseClient
{
public:
std::vector<DirEntry> ListDir(const std::string &path);
};
#endif
+42
View File
@@ -4,6 +4,8 @@
#include <string>
#include <vector>
#include <string.h>
#include <lexbor/html/parser.h>
#include <lexbor/dom/interfaces/element.h>
#define HTTP_SUCCESS(x) (x >= 200 && x < 300)
#define MIN(a,b) (((a)<(b))?(a):(b))
@@ -86,4 +88,44 @@ struct DirEntry
}
};
static lxb_dom_node_t *NextChildElement(lxb_dom_element_t *element)
{
lxb_dom_node_t *node = element->node.first_child;
while (node != nullptr && node->type != LXB_DOM_NODE_TYPE_ELEMENT)
{
node = node->next;
}
return node;
}
static lxb_dom_node_t *NextElement(lxb_dom_node_t *node)
{
lxb_dom_node_t *next = node->next;
while (next != nullptr && next->type != LXB_DOM_NODE_TYPE_ELEMENT)
{
next = next->next;
}
return next;
}
static lxb_dom_node_t *NextChildTextNode(lxb_dom_element_t *element)
{
lxb_dom_node_t *node = element->node.first_child;
while (node != nullptr && node->type != LXB_DOM_NODE_TYPE_TEXT)
{
node = node->next;
}
return node;
}
static lxb_dom_node_t *NextTextNode(lxb_dom_node_t *node)
{
lxb_dom_node_t *next = node->next;
while (next != nullptr && next->type != LXB_DOM_NODE_TYPE_TEXT)
{
next = next->next;
}
return next;
}
#endif
+26 -1
View File
@@ -37,6 +37,7 @@ bool auto_delete_tmp_pkg;
int max_edit_file_size;
GoogleAppInfo gg_app;
bool show_hidden_files;
char alldebrid_api_key[32];
unsigned char cipher_key[32] = {'s', '5', 'v', '8', 'y', '/', 'B', '?', 'E', '(', 'H', '+', 'M', 'b', 'Q', 'e', 'T', 'h', 'W', 'm', 'Z', 'q', '4', 't', '7', 'w', '9', 'z', '$', 'C', '&', 'F'};
unsigned char cipher_iv[16] = {'Y', 'p', '3', 's', '6', 'v', '9', 'y', '$', 'B', '&', 'E', ')', 'H', '@', 'M'};
@@ -151,7 +152,7 @@ namespace CONFIG
sites = {"Site 1", "Site 2", "Site 3", "Site 4", "Site 5", "Site 6", "Site 7", "Site 8", "Site 9", "Site 10",
"Site 11", "Site 12", "Site 13", "Site 14", "Site 15", "Site 16", "Site 17", "Site 18", "Site 19", "Site 20"};
http_servers = {HTTP_SERVER_APACHE, HTTP_SERVER_MS_IIS, HTTP_SERVER_NGINX, HTTP_SERVER_NPX_SERVE};
http_servers = {HTTP_SERVER_APACHE, HTTP_SERVER_MS_IIS, HTTP_SERVER_NGINX, HTTP_SERVER_NPX_SERVE, HTTP_SERVER_RCLONE};
text_file_extensions = { ".txt", ".ini", ".log", ".json", ".xml", ".html", ".xhtml", ".conf", ".config" };
image_file_extensions = { ".bmp", ".jpg", ".jpeg", ".png", ".webp" };
@@ -181,6 +182,22 @@ namespace CONFIG
show_hidden_files = ReadBool(CONFIG_GLOBAL, CONFIG_SHOW_HIDDEN_FILES, false);
WriteBool(CONFIG_GLOBAL, CONFIG_SHOW_HIDDEN_FILES, show_hidden_files);
// alldebrid api key
char tmp_api_key[512];
sprintf(tmp_api_key, "%s", ReadString(CONFIG_GLOBAL, CONFIG_ALLDEBRID_API_KEY, ""));
std::string encrypted_api_key;
if (strlen(tmp_api_key) > 0)
{
std::string decrypted__api_key;
int ret = Decrypt(tmp_api_key, decrypted__api_key);
if (ret == 0)
sprintf(alldebrid_api_key, "%s", tmp_api_key);
else
sprintf(alldebrid_api_key, "%s", decrypted__api_key.c_str());
Encrypt(alldebrid_api_key, encrypted_api_key);
}
WriteString(CONFIG_GLOBAL, CONFIG_ALLDEBRID_API_KEY, encrypted_api_key.c_str());
// Load Google Account Info
sprintf(gg_app.client_id, "%s", ReadString(CONFIG_GOOGLE, CONFIG_GOOGLE_CLIENT_ID, ""));
WriteString(CONFIG_GOOGLE, CONFIG_GOOGLE_CLIENT_ID, gg_app.client_id);
@@ -355,9 +372,17 @@ namespace CONFIG
Encrypt(gg_app.client_secret, encrypted_secret);
else
encrypted_secret = std::string(gg_app.client_secret);
std::string encrypted_api_key;
if (strlen(alldebrid_api_key) > 0)
Encrypt(alldebrid_api_key, encrypted_api_key);
else
encrypted_api_key = std::string(alldebrid_api_key);
WriteString(CONFIG_GOOGLE, CONFIG_GOOGLE_CLIENT_SECRET, encrypted_secret.c_str());
WriteString(CONFIG_GOOGLE, CONFIG_GOOGLE_CLIENT_ID, gg_app.client_id);
WriteString(CONFIG_GOOGLE, CONFIG_GOOGLE_PERMISSIONS, gg_app.permissions);
WriteString(CONFIG_GLOBAL, CONFIG_ALLDEBRID_API_KEY, encrypted_api_key.c_str());
WriteBool(CONFIG_GLOBAL, CONFIG_AUTO_DELETE_TMP_PKG, auto_delete_tmp_pkg);
WriteBool(CONFIG_GLOBAL, CONFIG_SHOW_HIDDEN_FILES, show_hidden_files);
WriteInt(CONFIG_HTTP_SERVER, CONFIG_HTTP_SERVER_PORT, http_server_port);
+4
View File
@@ -57,6 +57,8 @@
#define CONFIG_REMOTE_HTTP_SERVER_TYPE "remote_server_http_server_type"
#define CONFIG_REMOTE_DEFAULT_DIRECTORY "remote_server_default_directory"
#define CONFIG_ALLDEBRID_API_KEY "alldebrid_api_key"
#define CONFIG_VERSION "config_version"
#define CONFIG_VERSION_NUM 1
@@ -75,6 +77,7 @@
#define HTTP_SERVER_MS_IIS "Microsoft IIS"
#define HTTP_SERVER_NGINX "Nginx"
#define HTTP_SERVER_NPX_SERVE "Serve"
#define HTTP_SERVER_RCLONE "RClone"
#define MAX_EDIT_FILE_SIZE 32768
@@ -134,6 +137,7 @@ extern unsigned char cipher_key[32];
extern unsigned char cipher_iv[16];
extern GoogleAppInfo gg_app;
extern bool show_hidden_files;
extern char alldebrid_api_key[32];
namespace CONFIG
{
+142
View File
@@ -0,0 +1,142 @@
#include <regex>
#include <lexbor/html/parser.h>
#include <lexbor/dom/interfaces/element.h>
#include <http/httplib.h>
#include "common.h"
#include "1fichier.h"
#define VALIDATION_REGEX "https:\\/\\/1fichier\\.com\\/(.*)"
FichierHost::FichierHost(const std::string &url) : FileHost(url)
{
}
bool FichierHost::IsValidUrl()
{
std::regex regex(VALIDATION_REGEX);
if (std::regex_match(url, regex))
return true;
return false;
}
std::string FichierHost::GetDownloadUrl()
{
std::regex re("https:\\/\\/1fichier\\.com");
std::string path = std::regex_replace(url, re, "");
httplib::Client tmp_client("https://1fichier.com");
tmp_client.set_keep_alive(true);
tmp_client.set_follow_location(true);
tmp_client.set_connection_timeout(30);
tmp_client.set_read_timeout(30);
tmp_client.enable_server_certificate_verification(false);
auto res = tmp_client.Get(path);
if (HTTP_SUCCESS(res->status))
{
lxb_status_t status;
lxb_dom_element_t *element;
lxb_dom_node_t *node;
lxb_html_document_t *document;
lxb_dom_collection_t *collection;
lxb_dom_attr_t *attr;
const lxb_char_t *value;
size_t value_len;
std::string download_url = "";
document = lxb_html_document_create();
status = lxb_html_document_parse(document, (lxb_char_t *)res->body.c_str(), res->body.length());
if (status != LXB_STATUS_OK)
return "";
collection = lxb_dom_collection_make(&document->dom_document, 128);
if (collection == NULL)
{
lxb_html_document_destroy(document);
return "";
}
status = lxb_dom_elements_by_tag_name(lxb_dom_interface_element(document->body),
collection, (const lxb_char_t *)"input", 5);
if (status != LXB_STATUS_OK)
{
lxb_dom_collection_destroy(collection, true);
lxb_html_document_destroy(document);
return "";
}
std::string post_data;
for (size_t i = 0; i < lxb_dom_collection_length(collection); i++)
{
element = lxb_dom_collection_element(collection, i);
value = lxb_dom_element_get_attribute(element, (const lxb_char_t *)"name", 4, &value_len);
if (value != nullptr)
{
std::string name_attr((char *)value, value_len);
if (name_attr == "adz")
{
value = lxb_dom_element_get_attribute(element, (const lxb_char_t *)"value", 5, &value_len);
std::string adz_value((char *)value, value_len);
post_data = std::string("adz=") + adz_value + "&did=0&dl_no_ssl=off&dlinline=on";
break;
}
}
}
lxb_dom_collection_destroy(collection, true);
lxb_html_document_destroy(document);
if (auto res = tmp_client.Post(path, post_data.c_str(), post_data.length(), "application/x-www-form-urlencoded"))
{
if (HTTP_SUCCESS(res->status))
{
document = lxb_html_document_create();
status = lxb_html_document_parse(document, (lxb_char_t *)res->body.c_str(), res->body.length());
if (status != LXB_STATUS_OK)
return "";
collection = lxb_dom_collection_make(&document->dom_document, 128);
if (collection == NULL)
{
lxb_html_document_destroy(document);
return "";
}
status = lxb_dom_elements_by_tag_name(lxb_dom_interface_element(document->body),
collection, (const lxb_char_t *)"a", 1);
if (status != LXB_STATUS_OK)
{
lxb_dom_collection_destroy(collection, true);
lxb_html_document_destroy(document);
return "";
}
for (size_t i = 0; i < lxb_dom_collection_length(collection); i++)
{
element = lxb_dom_collection_element(collection, i);
value = lxb_dom_element_get_attribute(element, (const lxb_char_t *)"class", 5, &value_len);
if (value != nullptr)
{
std::string class_value((char*) value, value_len);
if (class_value == "ok btn-general btn-orange")
{
value = lxb_dom_element_get_attribute(element, (const lxb_char_t *)"href", 4, &value_len);
if (value != nullptr)
{
download_url = std::string((char*) value, value_len);
break;
}
}
}
}
lxb_dom_collection_destroy(collection, true);
lxb_html_document_destroy(document);
}
}
return download_url;
}
return "";
}
+14
View File
@@ -0,0 +1,14 @@
#ifndef FICHIER_HOST_H
#define FICHIER_HOST_H
#include "filehost.h"
class FichierHost : public FileHost
{
public:
FichierHost(const std::string &url);
bool IsValidUrl();
std::string GetDownloadUrl();
};
#endif
+64
View File
@@ -0,0 +1,64 @@
#include <http/httplib.h>
#include <json-c/json.h>
#include "config.h"
#include "common.h"
#include "alldebrid.h"
AllDebridHost::AllDebridHost(const std::string &url) : FileHost(url)
{
}
bool AllDebridHost::IsValidUrl()
{
httplib::Client tmp_client("https://api.alldebrid.com");
tmp_client.set_keep_alive(true);
tmp_client.set_follow_location(true);
tmp_client.set_connection_timeout(30);
tmp_client.set_read_timeout(30);
tmp_client.enable_server_certificate_verification(false);
std::string path = std::string("/v4/link/unlock?agent=ezRemoteClient&apikey=") + alldebrid_api_key + "&link=" + httplib::detail::encode_url(url);
auto res = tmp_client.Get(path);
if (HTTP_SUCCESS(res->status))
{
json_object *jobj = json_tokener_parse(res->body.c_str());
const char *status = json_object_get_string(json_object_object_get(jobj, "status"));
if (strcmp(status, "success") == 0)
return true;
}
return false;
}
std::string AllDebridHost::GetDownloadUrl()
{
httplib::Client tmp_client("https://api.alldebrid.com");
tmp_client.set_keep_alive(true);
tmp_client.set_follow_location(true);
tmp_client.set_connection_timeout(30);
tmp_client.set_read_timeout(30);
tmp_client.enable_server_certificate_verification(false);
std::string path = std::string("/v4/link/unlock?agent=ezRemoteClient&apikey=") + alldebrid_api_key + "&link=" + httplib::detail::encode_url(url);
auto res = tmp_client.Get(path);
if (HTTP_SUCCESS(res->status))
{
json_object *jobj = json_tokener_parse(res->body.c_str());
const char *status = json_object_get_string(json_object_object_get(jobj, "status"));
if (status != nullptr && strcmp(status, "success") == 0)
{
json_object *data = json_object_object_get(jobj, "data");
const char *link = json_object_get_string(json_object_object_get(data, "link"));
return std::string(link);
}
else
{
return "";
}
}
return "";
}
+14
View File
@@ -0,0 +1,14 @@
#ifndef ALLDEBRID_HOST_H
#define ALLDEBRID_HOST_H
#include "filehost.h"
class AllDebridHost : public FileHost
{
public:
AllDebridHost(const std::string &url);
bool IsValidUrl();
std::string GetDownloadUrl();
};
#endif
+28
View File
@@ -0,0 +1,28 @@
#include <regex>
#include <lexbor/html/parser.h>
#include <lexbor/dom/interfaces/element.h>
#include <http/httplib.h>
#include "common.h"
#include "directhost.h"
#define VALIDATION_REGEX "(.*)"
DirectHost::DirectHost(const std::string &url) : FileHost(url)
{
}
bool DirectHost::IsValidUrl()
{
std::regex regex_1(VALIDATION_REGEX);
if (std::regex_match(url, regex_1))
return true;
return false;
}
std::string DirectHost::GetDownloadUrl()
{
return url;
}
+14
View File
@@ -0,0 +1,14 @@
#ifndef DIRECT_HOST_H
#define DIRECT_HOST_H
#include "filehost.h"
class DirectHost : public FileHost
{
public:
DirectHost(const std::string &url);
bool IsValidUrl();
std::string GetDownloadUrl();
};
#endif
+67
View File
@@ -0,0 +1,67 @@
#include <regex>
#include <string>
#include <vector>
#include <map>
#include "openssl/md5.h"
#include "filehost.h"
#include "1fichier.h"
#include "filehost/alldebrid.h"
#include "filehost/directhost.h"
#include "filehost/gdrive.h"
#include "filehost/mediafire.h"
#include "filehost/pixeldrain.h"
#include "config.h"
#include "base64.h"
#include "util.h"
#define GDRIVE_REGEX "https:\\/\\/drive\\.google\\.com\\/(.*)"
#define MEDIAFIRE_REGEX "https:\\/\\/www\\.mediafire\\.com\\/(.*)"
#define PIXELDRAIN_REGEX "https:\\/\\/pixeldrain\\.com\\/(.*)"
#define FICHIER_REGEX "https:\\/\\/1fichier\\.com\\/(.*)"
static std::map<std::string, std::string> cache_downloal_urls;
std::string FileHost::Hash()
{
std::vector<unsigned char> res(16);
MD5((const unsigned char *)this->url.c_str(), this->url.length(), res.data());
std::string out;
Base64::Encode(res.data(), res.size(), out);
Util::ReplaceAll(out, "=", "_");
Util::ReplaceAll(out, "+", "_");
out = out + ".pkg";
return out;
}
FileHost *FileHost::getFileHost(const std::string &url, bool use_alldebrid)
{
std::regex google_re(GDRIVE_REGEX);
std::regex mediafire_re(MEDIAFIRE_REGEX);
std::regex pixeldrain_re(PIXELDRAIN_REGEX);
std::regex fichier_re(FICHIER_REGEX);
if (use_alldebrid)
return new AllDebridHost(url);
else if (std::regex_match(url, google_re))
return new GDriveHost(url);
else if (std::regex_match(url, mediafire_re))
return new MediaFireHost(url);
else if (std::regex_match(url, pixeldrain_re))
return new PixelDrainHost(url);
else
return new DirectHost(url);
}
std::string FileHost::GetCachedDownloadUrl(std::string &hash)
{
return cache_downloal_urls[hash];
}
void FileHost::AddCacheDownloadUrl(std::string &hash, std::string &url)
{
std::pair<std::string, std::string> pair = std::make_pair(hash, url);
cache_downloal_urls.erase(hash);
cache_downloal_urls.insert(pair);
}
+24
View File
@@ -0,0 +1,24 @@
#ifndef FILEHOST_H
#define FILEHOST_H
#include <string>
#include <vector>
class FileHost
{
public:
FileHost(const std::string &url) { this->url = url; };
virtual ~FileHost(){};
virtual bool IsValidUrl() = 0;
virtual std::string GetDownloadUrl() = 0;
std::string Hash();
static FileHost *getFileHost(const std::string &url, bool use_alldebrid = false);
static std::string GetCachedDownloadUrl(std::string &hash);
static void AddCacheDownloadUrl(std::string &hash, std::string &url);
protected:
std::string url;
};
#endif
+118
View File
@@ -0,0 +1,118 @@
#include <regex>
#include <lexbor/html/parser.h>
#include <lexbor/dom/interfaces/element.h>
#include <http/httplib.h>
#include "common.h"
#include "gdrive.h"
#define VALIDATION_REGEX_1 "https:\\/\\/drive\\.google\\.com\\/file\\/d\\/(.*)\\/(edit|view)\\?usp=(.*)"
#define VALIDATION_REGEX_2 "https:\\/\\/drive\\.google\\.com\\/(.*)uc\\?(id=|export=)(.*)&(id=|export=)(.*)"
GDriveHost::GDriveHost(const std::string &url) : FileHost(url)
{
}
bool GDriveHost::IsValidUrl()
{
std::regex regex_1(VALIDATION_REGEX_1);
std::regex regex_2(VALIDATION_REGEX_2);
if (std::regex_match(url, regex_1) || std::regex_match(url, regex_2))
return true;
return false;
}
std::string GDriveHost::GetDownloadUrl()
{
std::regex regex_1(VALIDATION_REGEX_1);
std::smatch matches;
std::string path;
if(std::regex_search(url, matches, regex_1))
{
path = std::string("/uc?export=download&id=") + matches[1].str();
}
else
{
std::regex re("https:\\/\\/drive\\.google\\.com");
path = std::regex_replace(url, re, "");
}
httplib::Client tmp_client("https://drive.google.com");
tmp_client.set_keep_alive(true);
tmp_client.set_follow_location(true);
tmp_client.set_connection_timeout(30);
tmp_client.set_read_timeout(30);
tmp_client.enable_server_certificate_verification(false);
auto res = tmp_client.Head(path);
if (HTTP_SUCCESS(res->status))
{
std::string content_type = res->get_header_value("Content-Type");
if (content_type == "application/octet-stream")
return url;
else if (content_type.find("text/html") == std::string::npos)
return "";
}
else
return "";
res = tmp_client.Get(path);
if (HTTP_SUCCESS(res->status))
{
lxb_status_t status;
lxb_dom_element_t *element;
lxb_html_document_t *document;
lxb_dom_collection_t *collection;
lxb_dom_attr_t *attr;
document = lxb_html_document_create();
status = lxb_html_document_parse(document, (lxb_char_t *)res->body.c_str(), res->body.length());
if (status != LXB_STATUS_OK)
{
lxb_html_document_destroy(document);
return "";
}
collection = lxb_dom_collection_make(&document->dom_document, 128);
if (collection == NULL)
{
lxb_html_document_destroy(document);
return "";
}
status = lxb_dom_elements_by_tag_name(lxb_dom_interface_element(document->body),
collection, (const lxb_char_t *)"form", 4);
if (status != LXB_STATUS_OK)
{
lxb_dom_collection_destroy(collection, true);
lxb_html_document_destroy(document);
return "";
}
std::string download_url;
for (size_t i = 0; i < lxb_dom_collection_length(collection); i++)
{
element = lxb_dom_collection_element(collection, i);
if (element->attr_id != nullptr)
{
std::string form_id((char *)element->attr_id->value->data, element->attr_id->value->length);
if (form_id == "download-form")
{
size_t value_len;
const lxb_char_t *value = lxb_dom_element_get_attribute(element, (const lxb_char_t *)"action", 6, &value_len);
download_url = std::string((char *)value, value_len);
break;
}
}
}
lxb_dom_collection_destroy(collection, true);
lxb_html_document_destroy(document);
return download_url;
}
return "";
}
+14
View File
@@ -0,0 +1,14 @@
#ifndef GDRIVE_HOST_H
#define GDRIVE_HOST_H
#include "filehost.h"
class GDriveHost : public FileHost
{
public:
GDriveHost(const std::string &url);
bool IsValidUrl();
std::string GetDownloadUrl();
};
#endif
+89
View File
@@ -0,0 +1,89 @@
#include <regex>
#include <lexbor/html/parser.h>
#include <lexbor/dom/interfaces/element.h>
#include <http/httplib.h>
#include "common.h"
#include "mediafire.h"
#define VALIDATION_REGEX "https:\\/\\/www\\.mediafire\\.com\\/file\\/(.*)\\/(.*)\\/file"
MediaFireHost::MediaFireHost(const std::string &url) : FileHost(url)
{
}
bool MediaFireHost::IsValidUrl()
{
std::regex regex(VALIDATION_REGEX);
if (std::regex_match(url, regex))
return true;
return false;
}
std::string MediaFireHost::GetDownloadUrl()
{
std::regex re("https:\\/\\/www\\.mediafire\\.com");
std::string path = std::regex_replace(url, re, "");
httplib::Client tmp_client("https://www.mediafire.com");
tmp_client.set_keep_alive(true);
tmp_client.set_follow_location(true);
tmp_client.set_connection_timeout(30);
tmp_client.set_read_timeout(30);
tmp_client.enable_server_certificate_verification(false);
auto res = tmp_client.Get(path);
if (HTTP_SUCCESS(res->status))
{
lxb_status_t status;
lxb_dom_element_t *element;
lxb_html_document_t *document;
lxb_dom_collection_t *collection;
lxb_dom_attr_t *attr;
document = lxb_html_document_create();
status = lxb_html_document_parse(document, (lxb_char_t *)res->body.c_str(), res->body.length());
if (status != LXB_STATUS_OK)
return "";
collection = lxb_dom_collection_make(&document->dom_document, 128);
if (collection == NULL)
{
lxb_html_document_destroy(document);
return "";
}
status = lxb_dom_elements_by_tag_name(lxb_dom_interface_element(document->body),
collection, (const lxb_char_t *)"a", 1);
if (status != LXB_STATUS_OK)
{
lxb_dom_collection_destroy(collection, true);
lxb_html_document_destroy(document);
return "";
}
std::string download_url;
for (size_t i = 0; i < lxb_dom_collection_length(collection); i++)
{
element = lxb_dom_collection_element(collection, i);
if (element->attr_id != nullptr)
{
std::string a_id((char *)element->attr_id->value->data, element->attr_id->value->length);
if (a_id == "downloadButton")
{
size_t value_len;
const lxb_char_t *value = lxb_dom_element_get_attribute(element, (const lxb_char_t *)"href", 4, &value_len);
download_url = std::string((char *)value, value_len);
break;
}
}
}
lxb_dom_collection_destroy(collection, true);
lxb_html_document_destroy(document);
return download_url;
}
return "";
}
+14
View File
@@ -0,0 +1,14 @@
#ifndef MEDIAFIRE_HOST_H
#define MEDIAFIRE_HOST_H
#include "filehost.h"
class MediaFireHost : public FileHost
{
public:
MediaFireHost(const std::string &url);
bool IsValidUrl();
std::string GetDownloadUrl();
};
#endif
+38
View File
@@ -0,0 +1,38 @@
#include <regex>
#include <lexbor/html/parser.h>
#include <lexbor/dom/interfaces/element.h>
#include <http/httplib.h>
#include "common.h"
#include "pixeldrain.h"
#define VALIDATION_REGEX "https:\\/\\/pixeldrain\\.com\\/u\\/(.*)"
PixelDrainHost::PixelDrainHost(const std::string &url) : FileHost(url)
{
}
bool PixelDrainHost::IsValidUrl()
{
std::regex re(VALIDATION_REGEX);
if (std::regex_match(url, re))
return true;
return false;
}
std::string PixelDrainHost::GetDownloadUrl()
{
std::regex re(VALIDATION_REGEX);
std::smatch matches;
if(std::regex_search(url, matches, re))
{
if (matches.size() > 1)
{
return std::string("https://pixeldrain.com/api/file/") + matches[1].str() + "?download=";
}
}
return "";
}
+14
View File
@@ -0,0 +1,14 @@
#ifndef PIXELDRAIN_HOST_H
#define PIXELDRAIN_HOST_H
#include "filehost.h"
class PixelDrainHost : public FileHost
{
public:
PixelDrainHost(const std::string &url);
bool IsValidUrl();
std::string GetDownloadUrl();
};
#endif
+1
View File
@@ -1900,6 +1900,7 @@ namespace detail {
std::string encode_query_param(const std::string &value);
std::string encode_url(const std::string &s);
std::string decode_url(const std::string &s, bool convert_plus_to_space);
void read_file(const std::string &path, std::string &out);
+41 -28
View File
@@ -125,11 +125,14 @@ namespace INSTALLER
else
{
std::string encoded_path = path;
std::string encoded_site_name = remote_settings->site_name;
Web::Urn::Path uri(encoded_path);
Web::Urn::Path site_name(encoded_site_name);
CURL *curl = curl_easy_init();
encoded_path = uri.quote(curl);
encoded_site_name = site_name.quote(curl);
curl_easy_cleanup(curl);
std::string full_url = std::string("http://localhost:") + std::to_string(http_server_port) + "/rmt_inst" + encoded_path;
std::string full_url = std::string("http://localhost:") + std::to_string(http_server_port) + "/rmt_inst" + encoded_site_name + encoded_path;
return full_url;
}
@@ -142,15 +145,12 @@ namespace INSTALLER
return true;
}
int InstallRemotePkg(const std::string &path, pkg_header *header)
int InstallRemotePkg(const std::string &url, pkg_header *header, bool prompt)
{
std::string url = getRemoteUrl(path, true);
if (url.empty())
return 0;
int ret;
std::string filename = path.substr(path.find_last_of("/")+1);
std::string cid = std::string((char *)header->pkg_content_id);
cid = cid.substr(cid.find_first_of("-") + 1, 9);
int user_id;
@@ -196,7 +196,7 @@ namespace INSTALLER
params.entitlementType = 5;
params.id = (char *)header->pkg_content_id;
params.contentUrl = url.c_str();
params.contentName = filename.c_str();
params.contentName = cid.c_str();
params.iconPath = "";
params.playgoScenarioId = "0";
params.option = ORBIS_BGFT_TASK_OPT_DISABLE_CDN_QUERY_PARAM;
@@ -213,18 +213,28 @@ namespace INSTALLER
ret = sceBgftServiceIntDebugDownloadRegisterPkg(&params, &task_id);
if (ret == 0x80990088 || ret == 0x80990015)
{
sprintf(confirm_message, "%s - %s?", path.c_str(), lang_strings[STR_REINSTALL_CONFIRM_MSG]);
confirm_state = CONFIRM_WAIT;
action_to_take = selected_action;
activity_inprogess = false;
while (confirm_state == CONFIRM_WAIT)
if (prompt)
{
sceKernelUsleep(100000);
}
activity_inprogess = true;
selected_action = action_to_take;
sprintf(confirm_message, "%s - %s?", cid.c_str(), lang_strings[STR_REINSTALL_CONFIRM_MSG]);
confirm_state = CONFIRM_WAIT;
action_to_take = selected_action;
activity_inprogess = false;
while (confirm_state == CONFIRM_WAIT)
{
sceKernelUsleep(100000);
}
activity_inprogess = true;
selected_action = action_to_take;
if (confirm_state == CONFIRM_YES)
if (confirm_state == CONFIRM_YES)
{
ret = sceAppInstUtilAppUnInstall(cid.c_str());
if (ret != 0)
goto err;
goto retry;
}
}
else
{
ret = sceAppInstUtilAppUnInstall(cid.c_str());
if (ret != 0)
@@ -241,19 +251,22 @@ namespace INSTALLER
goto err;
}
Util::Notify("%s queued", filename.c_str());
Util::Notify("%s queued", cid.c_str());
file_transfering = true;
bytes_to_download = 100;
bytes_transfered = 0;
while (bytes_transfered < 99)
if (prompt)
{
memset(&progress_info, 0, sizeof(progress_info));
ret = sceBgftServiceDownloadGetProgress(task_id, &progress_info);
if (ret || (progress_info.transferred > 0 && progress_info.errorResult != 0))
return 0;
bytes_transfered = (uint32_t)(((float)progress_info.transferred / progress_info.length) * 100.f);
sceSystemServicePowerTick();
file_transfering = true;
bytes_to_download = 100;
bytes_transfered = 0;
while (bytes_transfered < 99)
{
memset(&progress_info, 0, sizeof(progress_info));
ret = sceBgftServiceDownloadGetProgress(task_id, &progress_info);
if (ret || (progress_info.transferred > 0 && progress_info.errorResult != 0))
return 0;
bytes_transfered = (uint32_t)(((float)progress_info.transferred / progress_info.length) * 100.f);
sceSystemServicePowerTick();
}
}
return 1;
@@ -587,4 +600,4 @@ namespace INSTALLER
return true;
}
}
}
+1 -1
View File
@@ -121,7 +121,7 @@ namespace INSTALLER
bool canInstallRemotePkg(const std::string &url);
std::string getRemoteUrl(const std::string path, bool encodeUrl = false);
int InstallRemotePkg(const std::string &path, pkg_header *header);
int InstallRemotePkg(const std::string &path, pkg_header *header, bool prompt = false);
int InstallLocalPkg(const std::string &path);
int InstallLocalPkg(const std::string &path, pkg_header *header, bool remove_after_install = false);
bool ExtractLocalPkg(const std::string &path, const std::string sfo_path, const std::string icon_path);
+7 -1
View File
@@ -94,7 +94,7 @@ char lang_strings[LANG_STRINGS_NUM][LANG_STR_SIZE] = {
"Not a valid Package", // STR_NOT_A_VALID_PACKAGE
"Waiting for Package to finish installing", // STR_WAIT_FOR_INSTALL_MSG
"Failed to install pkg file. Please delete the tmp pkg manually", // STR_FAIL_INSTALL_TMP_PKG_MSG
"Failed to obtain google download URL", // STR_FAIL_TO_OBTAIN_GG_DL_MSG
"Failed to obtain download URL", // STR_FAIL_TO_OBTAIN_GG_DL_MSG
"Auto delete temporary downloaded pkg file after install", // STR_AUTO_DELETE_TMP_PKG
"Protocol not supported", // STR_PROTOCOL_NOT_SUPPORTED
"Could not resolve hostname", // STR_COULD_NOT_RESOLVE_HOST
@@ -162,6 +162,12 @@ char lang_strings[LANG_STRINGS_NUM][LANG_STR_SIZE] = {
"Enable", // STR_ENABLE
"Compressed Files Location", // STR_COMPRESSED_FILE_PATH
"Location of where compressed files are stored on the web server", // STR_COMPRESSED_FILE_PATH_MSG
"AllDebrid", // STR_ALLDEBRID
"API Key", // STR_API_KEY
"Couldn't extract download url", // STR_CANT_EXTRACT_URL_MSG
"Failed to install from URL", // STR_FAIL_INSTALL_FROM_URL_MSG
"InValid URL", // STR_INVALID_URL
"To use this function, an API Key needs to be configured in the ezRemote Client settings", // STR_ALLDEBRID_API_KEY_MISSING_MSG
};
bool needs_extended_font = false;
+9 -3
View File
@@ -153,9 +153,15 @@
FUNC(STR_FAIL_INIT_NFS_CONTEXT) \
FUNC(STR_FAIL_MOUNT_NFS_MSG) \
FUNC(STR_WEB_SERVER) \
FUNC(STR_ENABLE) \
FUNC(STR_ENABLE) \
FUNC(STR_COMPRESSED_FILE_PATH) \
FUNC(STR_COMPRESSED_FILE_PATH_MSG)
FUNC(STR_COMPRESSED_FILE_PATH_MSG) \
FUNC(STR_ALLDEBRID) \
FUNC(STR_API_KEY) \
FUNC(STR_CANT_EXTRACT_URL_MSG) \
FUNC(STR_FAIL_INSTALL_FROM_URL_MSG) \
FUNC(STR_INVALID_URL) \
FUNC(STR_ALLDEBRID_API_KEY_MISSING_MSG)
#define GET_VALUE(x) x,
#define GET_STRING(x) #x,
@@ -165,7 +171,7 @@ enum
FOREACH_STR(GET_VALUE)
};
#define LANG_STRINGS_NUM 152
#define LANG_STRINGS_NUM 158
#define LANG_ID_SIZE 64
#define LANG_STR_SIZE 384
extern char lang_identifiers[LANG_STRINGS_NUM][LANG_ID_SIZE];
+61
View File
@@ -2,9 +2,70 @@
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <sys/uio.h>
#include <orbis/libkernel.h>
#include <libjbc.h>
#define SYSCALL(nr, fn) __attribute__((naked)) fn\
{\
asm volatile("mov $" #nr ", %rax\nmov %rcx, %r10\nsyscall\nret");\
}
SYSCALL(22, static int unmount(const char* path, int flags))
SYSCALL(378, static int nmount(struct iovec* iov, unsigned int niov, int flags))
static void build_iovec(struct iovec** iov, int* iovlen, const char* name, const void* val, size_t len) {
int i;
if (*iovlen < 0)
return;
i = *iovlen;
*iov = (struct iovec*)realloc(*iov, sizeof **iov * (i + 2));
if (*iov == NULL) {
*iovlen = -1;
return;
}
(*iov)[i].iov_base = strdup(name);
(*iov)[i].iov_len = strlen(name) + 1;
++i;
(*iov)[i].iov_base = (void*)val;
if (len == (size_t)-1) {
if (val != NULL)
len = strlen((const char*)val) + 1;
else
len = 0;
}
(*iov)[i].iov_len = (int)len;
*iovlen = ++i;
}
int mount_large_fs(const char* device, const char* mountpoint, const char* fstype, const char* mode, unsigned int flags)
{
struct iovec* iov = NULL;
int iovlen = 0;
unmount(mountpoint, 0);
build_iovec(&iov, &iovlen, "fstype", fstype, -1);
build_iovec(&iov, &iovlen, "fspath", mountpoint, -1);
build_iovec(&iov, &iovlen, "from", device, -1);
build_iovec(&iov, &iovlen, "large", "yes", -1);
build_iovec(&iov, &iovlen, "timezone", "static", -1);
build_iovec(&iov, &iovlen, "async", "", -1);
build_iovec(&iov, &iovlen, "ignoreacl", "", -1);
if (mode) {
build_iovec(&iov, &iovlen, "dirmask", mode, -1);
build_iovec(&iov, &iovlen, "mask", mode, -1);
}
return nmount(iov, iovlen, flags);
}
// Variables for (un)jailbreaking
jbc_cred g_Cred;
jbc_cred g_RootCreds;
+3
View File
@@ -1,7 +1,10 @@
#ifndef __ORBIS_JBC_H__
#define __ORBIS_JBC_H__
#define MNT_UPDATE 0x0000000000010000ULL
int initialize_jbc();
void terminate_jbc();
int mount_large_fs(const char* device, const char* mountpoint, const char* fstype, const char* mode, unsigned int flags);
#endif
+121 -27
View File
@@ -8,6 +8,7 @@
#include "clients/smbclient.h"
#include "clients/ftpclient.h"
#include "clients/nfsclient.h"
#include "filehost/filehost.h"
#include "config.h"
#include "fs.h"
#include "windows.h"
@@ -920,34 +921,55 @@ namespace HttpServer
res.set_content(str.c_str(), "text/plain");
});
svr->Get("/rmt_inst/(.*)", [&](const Request & req, Response & res)
svr->Get("/rmt_inst/Site (\\d+)(/)(.*)", [&](const Request & req, Response & res)
{
RemoteClient *tmp_client;
auto path = std::string("/") + std::string(req.matches[1]);
RemoteSettings *tmp_settings;
auto site_idx = std::stoi(req.matches[1])-1;
std::string path;
if (remote_settings->type == CLIENT_TYPE_SFTP)
if (site_idx != 98)
{
tmp_client = new SFTPClient();
tmp_client->Connect(remote_settings->server, remote_settings->username, remote_settings->password);
}
else if (remote_settings->type == CLIENT_TYPE_SMB)
{
tmp_client = new SmbClient();
tmp_client->Connect(remote_settings->server, remote_settings->username, remote_settings->password);
}
else if (remote_settings->type == CLIENT_TYPE_FTP)
{
tmp_client = new FtpClient();
tmp_client->Connect(remote_settings->server, remote_settings->username, remote_settings->password);
}
else if (remote_settings->type == CLIENT_TYPE_NFS)
{
tmp_client = new NfsClient();
tmp_client->Connect(remote_settings->server, remote_settings->username, remote_settings->password);
path = std::string("/") + std::string(req.matches[3]);
tmp_settings = &site_settings[sites[site_idx]];
if (tmp_settings->type == CLIENT_TYPE_SFTP)
{
tmp_client = new SFTPClient();
tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password);
}
else if (tmp_settings->type == CLIENT_TYPE_SMB)
{
tmp_client = new SmbClient();
tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password);
}
else if (tmp_settings->type == CLIENT_TYPE_FTP)
{
tmp_client = new FtpClient();
tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password);
}
else if (tmp_settings->type == CLIENT_TYPE_NFS)
{
tmp_client = new NfsClient();
tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password);
}
else
{
tmp_client = remoteclient;
}
}
else
{
tmp_client = remoteclient;
std::string hash = std::string(req.matches[3]);
std::string url = FileHost::GetCachedDownloadUrl(hash);
size_t scheme_pos = url.find("://");
size_t root_pos = url.find("/", scheme_pos + 3);
std::string host = url.substr(0, root_pos);
path = url.substr(root_pos);
tmp_client = new BaseClient();
tmp_client->Connect(host, "", "");
}
if (tmp_client == nullptr || !tmp_client->IsConnected())
@@ -983,11 +1005,12 @@ namespace HttpServer
int ret = tmp_client->GetRange(path, sink, length, offset);
return (ret == 1);
},
[tmp_client, path](bool success) {
[tmp_client, path, site_idx](bool success) {
if (tmp_client != nullptr && (tmp_client->clientType() == CLIENT_TYPE_SFTP
|| tmp_client->clientType() == CLIENT_TYPE_SMB
|| tmp_client->clientType() == CLIENT_TYPE_FTP
|| tmp_client->clientType() == CLIENT_TYPE_NFS))
|| tmp_client->clientType() == CLIENT_TYPE_NFS
|| (tmp_client->clientType() == CLIENT_TYPE_HTTP_SERVER && site_idx == 98)))
{
tmp_client->Quit();
delete tmp_client;
@@ -1011,11 +1034,12 @@ namespace HttpServer
int ret = tmp_client->GetRange(path, sink, range_len, range.first);
return (ret == 1);
},
[tmp_client, path, range, range_len](bool success) {
[tmp_client, site_idx, path, range, range_len](bool success) {
if (tmp_client != nullptr && (tmp_client->clientType() == CLIENT_TYPE_SFTP
|| tmp_client->clientType() == CLIENT_TYPE_SMB
|| tmp_client->clientType() == CLIENT_TYPE_FTP
|| tmp_client->clientType() == CLIENT_TYPE_NFS))
|| tmp_client->clientType() == CLIENT_TYPE_NFS
|| (tmp_client->clientType() == CLIENT_TYPE_HTTP_SERVER && site_idx == 98)))
{
tmp_client->Quit();
delete tmp_client;
@@ -1024,6 +1048,76 @@ namespace HttpServer
}
});
svr->Post("/__local__/install_url", [&](const Request & req, Response & res)
{
std::string url;
const char *url_param;
bool use_alldebrid;
json_object *jobj = json_tokener_parse(req.body.c_str());
if (jobj != nullptr)
{
url_param = json_object_get_string(json_object_object_get(jobj, "url"));
use_alldebrid = json_object_get_boolean(json_object_object_get(jobj, "use_alldebrid"));
if (url_param == nullptr)
{
bad_request(res, "Required url_param, use_alldebrid parameter missing");
return;
}
}
else
{
bad_request(res, "Invalid payload");
return;
}
if (use_alldebrid && strlen(alldebrid_api_key) == 0)
{
failed(res, 200, lang_strings[STR_ALLDEBRID_API_KEY_MISSING_MSG]);
return;
}
url = std::string(url_param);
FileHost *filehost = FileHost::getFileHost(url, use_alldebrid);
if (!filehost->IsValidUrl())
{
failed(res, 200, lang_strings[STR_INVALID_URL]);
return;
}
std::string hash = filehost->Hash();
std::string download_url = filehost->GetDownloadUrl();
if (download_url.empty())
{
failed(res, 200, lang_strings[STR_CANT_EXTRACT_URL_MSG]);
return;
}
FileHost::AddCacheDownloadUrl(hash, download_url);
delete(filehost);
size_t scheme_pos = download_url.find("://");
size_t root_pos = download_url.find("/", scheme_pos + 3);
std::string host = download_url.substr(0, root_pos);
std::string path = download_url.substr(root_pos);
pkg_header header;
BaseClient *baseclient = new BaseClient();
baseclient->Connect(host, "", "");
baseclient->Head(path, &header, sizeof(pkg_header));
delete(baseclient);
std::string remote_install_url = std::string("http://localhost:") + std::to_string(http_server_port) + "/rmt_inst/Site%2099/" + hash;
int rc = INSTALLER::InstallRemotePkg(remote_install_url, &header);
if (rc == 0)
{
failed(res, 200, lang_strings[STR_FAIL_INSTALL_FROM_URL_MSG]);
return;
}
success(res);
});
svr->Get("/stop", [&](const Request & /*req*/, Response & /*res*/)
{
svr->stop();
@@ -1043,7 +1137,7 @@ namespace HttpServer
dbglogger_log("%s", log(req, res).c_str());
});
*/
svr->set_payload_max_length(1024 * 1024 * 12);
svr->set_tcp_nodelay(true);
svr->set_mount_point("/", "/");
@@ -1072,4 +1166,4 @@ namespace HttpServer
if (svr != nullptr)
svr->stop();
}
}
}
+29 -1
View File
@@ -1605,7 +1605,7 @@ namespace Windows
ImGui::OpenPopup(lang_strings[STR_SETTINGS]);
ImGui::SetNextWindowPos(ImVec2(1050, 80));
ImGui::SetNextWindowSizeConstraints(ImVec2(850, 80), ImVec2(850, 500), NULL, NULL);
ImGui::SetNextWindowSizeConstraints(ImVec2(850, 80), ImVec2(850, 650), NULL, NULL);
if (ImGui::BeginPopupModal(lang_strings[STR_SETTINGS], NULL, ImGuiWindowFlags_AlwaysAutoResize))
{
ImGui::TextColored(colors[ImGuiCol_ButtonHovered], "%s", lang_strings[STR_GLOBAL]);
@@ -1674,6 +1674,34 @@ namespace Windows
ImGui::PopStyleVar();
ImGui::Separator();
// Google settings
ImGui::TextColored(colors[ImGuiCol_ButtonHovered], "%s", lang_strings[STR_ALLDEBRID]);
ImGui::Separator();
field_size = ImGui::CalcTextSize(lang_strings[STR_API_KEY]);
width = field_size.x + 45;
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 15);
ImGui::Text("%s", lang_strings[STR_API_KEY]);
ImGui::SameLine();
ImGui::SetCursorPosX(width);
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 1.0f));
if (strlen(alldebrid_api_key) > 0)
sprintf(id, "%s", "*********************************************##alldebrid_api_key");
else
sprintf(id, "%s", "##client_secret_input");
if (ImGui::Button(id, ImVec2(835-width, 0)))
{
ResetImeCallbacks();
ime_single_field = alldebrid_api_key;
ime_field_size = 31;
ime_callback = SingleValueImeCallback;
Dialog::initImeDialog(lang_strings[STR_API_KEY], alldebrid_api_key, 31, ORBIS_TYPE_BASIC_LATIN, 1050, 80);
gui_mode = GUI_MODE_IME;
}
ImGui::PopStyleVar();
ImGui::Separator();
// Google settings
ImGui::TextColored(colors[ImGuiCol_ButtonHovered], "%s", lang_strings[STR_GOOGLE]);
ImGui::Separator();