mirror of
https://github.com/astronautlevel2/Anemone3DS.git
synced 2026-01-24 08:42:43 -05:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dc21e4d24b | ||
|
|
9a51667546 |
@@ -1,6 +1,6 @@
|
|||||||

|

|
||||||
|
|
||||||
A Theme and Splashscreen Manager for the Nintendo 3DS, written in C.
|
A Theme and Splashscreen Manager for the Nintendo 3DS, written in C.\
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
* devkitARM, which can be installed following the instructions [here](https://devkitpro.org/wiki/Getting_Started).
|
* devkitARM, which can be installed following the instructions [here](https://devkitpro.org/wiki/Getting_Started).
|
||||||
|
|||||||
@@ -46,10 +46,9 @@ typedef struct {
|
|||||||
u32 filesize;
|
u32 filesize;
|
||||||
|
|
||||||
volatile bool stop;
|
volatile bool stop;
|
||||||
Thread playing_thread;
|
Handle finished;
|
||||||
} audio_s;
|
} audio_s;
|
||||||
|
|
||||||
void play_audio(audio_s *);
|
void play_audio(audio_s *);
|
||||||
void stop_audio(audio_s**);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,88 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of Anemone3DS
|
|
||||||
* Copyright (C) 2016-2020 Contributors in CONTRIBUTORS.md
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
|
|
||||||
* * Requiring preservation of specified reasonable legal notices or
|
|
||||||
* author attributions in that material or in the Appropriate Legal
|
|
||||||
* Notices displayed by works containing it.
|
|
||||||
* * Prohibiting misrepresentation of the origin of that material,
|
|
||||||
* or requiring that modified versions of such material be marked in
|
|
||||||
* reasonable ways as different from the original version.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static char from_hex(char c)
|
|
||||||
{
|
|
||||||
return isdigit(c) ? c - '0' : tolower(c) - 'a' + 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char to_hex(char code)
|
|
||||||
{
|
|
||||||
static char hex[] = "0123456789abcdef";
|
|
||||||
return hex[code & 15];
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure caller frees
|
|
||||||
char * url_escape(char * url)
|
|
||||||
{
|
|
||||||
char * ptr = url;
|
|
||||||
char * buf = malloc(3 * strlen(url) + 1);
|
|
||||||
char * ptr_buf = buf;
|
|
||||||
|
|
||||||
while (*ptr)
|
|
||||||
{
|
|
||||||
if (isalnum((int)*ptr) || strchr("-_.~", *ptr))
|
|
||||||
*ptr_buf++ = *ptr;
|
|
||||||
else if (*ptr == ' ')
|
|
||||||
*ptr_buf++ = '+';
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*ptr_buf++ = '%';
|
|
||||||
*ptr_buf++ = to_hex(*ptr >> 4);
|
|
||||||
*ptr_buf++ = to_hex(*ptr & 15);
|
|
||||||
}
|
|
||||||
ptr++;
|
|
||||||
}
|
|
||||||
*ptr_buf = '\0';
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure caller frees
|
|
||||||
char * url_unescape(char * url)
|
|
||||||
{
|
|
||||||
char * ptr = url;
|
|
||||||
char * buf = malloc(strlen(url) + 1);
|
|
||||||
char * ptr_buf = buf;
|
|
||||||
|
|
||||||
while (*ptr)
|
|
||||||
{
|
|
||||||
if (*ptr == '%')
|
|
||||||
{
|
|
||||||
if (ptr[1] && ptr[2])
|
|
||||||
{
|
|
||||||
*ptr_buf++ = from_hex(ptr[1]) << 4 | from_hex(ptr[2]);
|
|
||||||
ptr += 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (*ptr == '+')
|
|
||||||
*ptr_buf++ = ' ';
|
|
||||||
else
|
|
||||||
*ptr_buf++ = *ptr;
|
|
||||||
ptr++;
|
|
||||||
}
|
|
||||||
*ptr_buf = '\0';
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
@@ -377,7 +377,7 @@ renamed:
|
|||||||
sprintf(path_to_file, "%s%s", main_paths[mode], filename);
|
sprintf(path_to_file, "%s%s", main_paths[mode], filename);
|
||||||
|
|
||||||
// filter out characters illegal in FAT32 filenames
|
// filter out characters illegal in FAT32 filenames
|
||||||
char * curr_filename = path_to_file + strlen(main_paths[mode]);
|
char * curr_filename = strrchr(path_to_file, '/') + 1;
|
||||||
char * illegal_char = curr_filename;
|
char * illegal_char = curr_filename;
|
||||||
while ((illegal_char = strpbrk(illegal_char, ILLEGAL_CHARS)))
|
while ((illegal_char = strpbrk(illegal_char, ILLEGAL_CHARS)))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -608,6 +608,7 @@ Result load_audio(Entry_s entry, audio_s *audio)
|
|||||||
}
|
}
|
||||||
|
|
||||||
audio->mix[0] = audio->mix[1] = 1.0f; // Determines volume for the 12 (?) different outputs. See http://smealum.github.io/ctrulib/channel_8h.html#a30eb26f1972cc3ec28370263796c0444
|
audio->mix[0] = audio->mix[1] = 1.0f; // Determines volume for the 12 (?) different outputs. See http://smealum.github.io/ctrulib/channel_8h.html#a30eb26f1972cc3ec28370263796c0444
|
||||||
|
svcCreateEvent(&audio->finished, RESET_STICKY);
|
||||||
|
|
||||||
ndspChnSetInterp(0, NDSP_INTERP_LINEAR);
|
ndspChnSetInterp(0, NDSP_INTERP_LINEAR);
|
||||||
ndspChnSetMix(0, audio->mix); // See mix comment above
|
ndspChnSetMix(0, audio->mix); // See mix comment above
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
bool quit = false;
|
bool quit = false;
|
||||||
bool dspfirm = false;
|
bool dspfirm = false;
|
||||||
static audio_s * audio = NULL;
|
audio_s * audio = NULL;
|
||||||
static bool homebrew = false;
|
static bool homebrew = false;
|
||||||
static bool installed_themes = false;
|
static bool installed_themes = false;
|
||||||
|
|
||||||
@@ -109,12 +109,6 @@ static void stop_install_check(void)
|
|||||||
{
|
{
|
||||||
installCheckThreads_arg[i].run_thread = false;
|
installCheckThreads_arg[i].run_thread = false;
|
||||||
}
|
}
|
||||||
for(int i = 0; i < MODE_AMOUNT; i++)
|
|
||||||
{
|
|
||||||
threadJoin(installCheckThreads[i], U64_MAX);
|
|
||||||
threadFree(installCheckThreads[i]);
|
|
||||||
installCheckThreads[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void exit_thread(void)
|
static void exit_thread(void)
|
||||||
@@ -127,7 +121,6 @@ static void exit_thread(void)
|
|||||||
svcWaitSynchronization(update_icons_mutex, U64_MAX);
|
svcWaitSynchronization(update_icons_mutex, U64_MAX);
|
||||||
threadJoin(iconLoadingThread, U64_MAX);
|
threadJoin(iconLoadingThread, U64_MAX);
|
||||||
threadFree(iconLoadingThread);
|
threadFree(iconLoadingThread);
|
||||||
iconLoadingThread = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +138,6 @@ static void free_icons(Entry_List_s * list)
|
|||||||
free(list->icons[i]);
|
free(list->icons[i]);
|
||||||
}
|
}
|
||||||
free(list->icons);
|
free(list->icons);
|
||||||
list->icons = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_lists(void)
|
void free_lists(void)
|
||||||
@@ -165,7 +157,8 @@ void exit_function(bool power_pressed)
|
|||||||
{
|
{
|
||||||
if(audio)
|
if(audio)
|
||||||
{
|
{
|
||||||
stop_audio(&audio);
|
audio->stop = true;
|
||||||
|
svcWaitSynchronization(audio->finished, U64_MAX);
|
||||||
}
|
}
|
||||||
free_lists();
|
free_lists();
|
||||||
svcCloseHandle(update_icons_mutex);
|
svcCloseHandle(update_icons_mutex);
|
||||||
@@ -237,7 +230,7 @@ static void load_lists(Entry_List_s * lists)
|
|||||||
|
|
||||||
if(install_check_function != NULL)
|
if(install_check_function != NULL)
|
||||||
{
|
{
|
||||||
installCheckThreads[i] = threadCreate(install_check_function, current_arg, __stacksize__, 0x3f, -2, false);
|
installCheckThreads[i] = threadCreate(install_check_function, current_arg, __stacksize__, 0x3f, -2, true);
|
||||||
svcSleepThread(1e8);
|
svcSleepThread(1e8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -511,7 +504,9 @@ int main(void)
|
|||||||
preview_mode = false;
|
preview_mode = false;
|
||||||
if(current_mode == MODE_THEMES && audio)
|
if(current_mode == MODE_THEMES && audio)
|
||||||
{
|
{
|
||||||
stop_audio(&audio);
|
audio->stop = true;
|
||||||
|
svcWaitSynchronization(audio->finished, U64_MAX);
|
||||||
|
audio = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@@ -521,7 +516,9 @@ int main(void)
|
|||||||
preview_mode = false;
|
preview_mode = false;
|
||||||
if(current_mode == MODE_THEMES && audio)
|
if(current_mode == MODE_THEMES && audio)
|
||||||
{
|
{
|
||||||
stop_audio(&audio);
|
audio->stop = true;
|
||||||
|
svcWaitSynchronization(audio->finished, U64_MAX);
|
||||||
|
audio = NULL;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,26 +69,17 @@ void thread_audio(void* data) {
|
|||||||
while(!audio->stop) {
|
while(!audio->stop) {
|
||||||
update_audio(audio);
|
update_audio(audio);
|
||||||
}
|
}
|
||||||
ndspChnWaveBufClear(0);
|
|
||||||
ndspChnReset(0);
|
|
||||||
ov_clear(&audio->vf);
|
|
||||||
free(audio->filebuf);
|
free(audio->filebuf);
|
||||||
|
ov_clear(&audio->vf);
|
||||||
linearFree((void*)audio->wave_buf[0].data_vaddr);
|
linearFree((void*)audio->wave_buf[0].data_vaddr);
|
||||||
linearFree((void*)audio->wave_buf[1].data_vaddr);
|
linearFree((void*)audio->wave_buf[1].data_vaddr);
|
||||||
|
while (audio->wave_buf[0].status != NDSP_WBUF_DONE || audio->wave_buf[1].status != NDSP_WBUF_DONE) svcSleepThread(1e7);
|
||||||
|
svcSignalEvent(audio->finished);
|
||||||
|
svcSleepThread(1e8);
|
||||||
|
svcCloseHandle(audio->finished);
|
||||||
|
free(audio);
|
||||||
}
|
}
|
||||||
|
|
||||||
void play_audio(audio_s *audio) {
|
void play_audio(audio_s *audio) {
|
||||||
audio->playing_thread = threadCreate(thread_audio, audio, 0x1000, 0x3F, 1, false);
|
threadCreate(thread_audio, audio, 0x1000, 0x3F, 1, true);
|
||||||
}
|
|
||||||
|
|
||||||
void stop_audio(audio_s** audio_ptr) {
|
|
||||||
audio_s* audio = *audio_ptr;
|
|
||||||
if(audio->playing_thread)
|
|
||||||
{
|
|
||||||
audio->stop = true;
|
|
||||||
threadJoin(audio->playing_thread, U64_MAX);
|
|
||||||
threadFree(audio->playing_thread);
|
|
||||||
}
|
|
||||||
free(audio);
|
|
||||||
*audio_ptr = NULL;
|
|
||||||
}
|
}
|
||||||
|
|||||||
121
source/remote.c
121
source/remote.c
@@ -31,11 +31,6 @@
|
|||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
#include "unicode.h"
|
#include "unicode.h"
|
||||||
#include "music.h"
|
#include "music.h"
|
||||||
#include "urls.h"
|
|
||||||
|
|
||||||
// forward declaration of special case used only here
|
|
||||||
// TODO: replace this travesty with a proper handler
|
|
||||||
static Result http_get_with_not_found_flag(const char * url, char ** filename, char ** buf, u32 * size, InstallType install_type, const char * acceptable_mime_types, bool not_found_is_error);
|
|
||||||
|
|
||||||
static Instructions_s browser_instructions[MODE_AMOUNT] = {
|
static Instructions_s browser_instructions[MODE_AMOUNT] = {
|
||||||
{
|
{
|
||||||
@@ -331,13 +326,10 @@ static void load_remote_bgm(Entry_s * entry)
|
|||||||
|
|
||||||
draw_install(INSTALL_LOADING_REMOTE_BGM);
|
draw_install(INSTALL_LOADING_REMOTE_BGM);
|
||||||
|
|
||||||
Result res = http_get_with_not_found_flag(bgm_url, NULL, &bgm_ogg, &bgm_size, INSTALL_LOADING_REMOTE_BGM, "application/ogg, audio/ogg", false);
|
Result res = http_get(bgm_url, NULL, &bgm_ogg, &bgm_size, INSTALL_LOADING_REMOTE_BGM, "application/ogg, audio/ogg");
|
||||||
free(bgm_url);
|
free(bgm_url);
|
||||||
if (R_FAILED(res))
|
if (R_FAILED(res))
|
||||||
return;
|
return;
|
||||||
// if bgm doesn't exist on the server
|
|
||||||
if (R_SUMMARY(res) == RS_NOTFOUND && R_MODULE(res) == RM_FILE_SERVER)
|
|
||||||
return;
|
|
||||||
|
|
||||||
u16 path[0x107] = { 0 };
|
u16 path[0x107] = { 0 };
|
||||||
strucat(path, entry->path);
|
strucat(path, entry->path);
|
||||||
@@ -444,12 +436,19 @@ static void search_menu(Entry_List_s * list)
|
|||||||
if (button == SWKBD_BUTTON_CONFIRM)
|
if (button == SWKBD_BUTTON_CONFIRM)
|
||||||
{
|
{
|
||||||
free(list->tp_search);
|
free(list->tp_search);
|
||||||
list->tp_search = url_escape(search);
|
for (unsigned int i = 0; i < strlen(search); i++)
|
||||||
DEBUG("Search escaped: %s -> %s\n", search, list->tp_search);
|
{
|
||||||
|
if (search[i] == ' ')
|
||||||
|
search[i] = '+';
|
||||||
|
}
|
||||||
|
list->tp_search = search;
|
||||||
load_remote_list(list, 1, list->mode, false);
|
load_remote_list(list, 1, list->mode, false);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
free(search);
|
free(search);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void change_selected(Entry_List_s * list, int change_value)
|
static void change_selected(Entry_List_s * list, int change_value)
|
||||||
{
|
{
|
||||||
@@ -490,7 +489,7 @@ bool themeplaza_browser(EntryMode mode)
|
|||||||
|
|
||||||
bool extra_mode = false;
|
bool extra_mode = false;
|
||||||
|
|
||||||
while (aptMainLoop() && !quit)
|
while (aptMainLoop())
|
||||||
{
|
{
|
||||||
if (current_list->entries == NULL)
|
if (current_list->entries == NULL)
|
||||||
break;
|
break;
|
||||||
@@ -518,6 +517,12 @@ bool themeplaza_browser(EntryMode mode)
|
|||||||
exit:
|
exit:
|
||||||
quit = true;
|
quit = true;
|
||||||
downloaded = false;
|
downloaded = false;
|
||||||
|
if (audio)
|
||||||
|
{
|
||||||
|
audio->stop = true;
|
||||||
|
svcWaitSynchronization(audio->finished, U64_MAX);
|
||||||
|
audio = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -576,7 +581,9 @@ bool themeplaza_browser(EntryMode mode)
|
|||||||
preview_mode = false;
|
preview_mode = false;
|
||||||
if (mode == MODE_THEMES && audio != NULL)
|
if (mode == MODE_THEMES && audio != NULL)
|
||||||
{
|
{
|
||||||
stop_audio(&audio);
|
audio->stop = true;
|
||||||
|
svcWaitSynchronization(audio->finished, U64_MAX);
|
||||||
|
audio = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -587,7 +594,9 @@ bool themeplaza_browser(EntryMode mode)
|
|||||||
preview_mode = false;
|
preview_mode = false;
|
||||||
if (mode == MODE_THEMES && audio != NULL)
|
if (mode == MODE_THEMES && audio != NULL)
|
||||||
{
|
{
|
||||||
stop_audio(&audio);
|
audio->stop = true;
|
||||||
|
svcWaitSynchronization(audio->finished, U64_MAX);
|
||||||
|
audio = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -653,7 +662,9 @@ bool themeplaza_browser(EntryMode mode)
|
|||||||
preview_mode = false;
|
preview_mode = false;
|
||||||
if (mode == MODE_THEMES && audio)
|
if (mode == MODE_THEMES && audio)
|
||||||
{
|
{
|
||||||
stop_audio(&audio);
|
audio->stop = true;
|
||||||
|
svcWaitSynchronization(audio->finished, U64_MAX);
|
||||||
|
audio = NULL;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -720,11 +731,6 @@ bool themeplaza_browser(EntryMode mode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (audio)
|
|
||||||
{
|
|
||||||
stop_audio(&audio);
|
|
||||||
}
|
|
||||||
|
|
||||||
free_preview(preview);
|
free_preview(preview);
|
||||||
|
|
||||||
free_icons(current_list);
|
free_icons(current_list);
|
||||||
@@ -764,19 +770,46 @@ typedef enum ParseResult
|
|||||||
HTTP_GATEWAY_TIMEOUT = 504,
|
HTTP_GATEWAY_TIMEOUT = 504,
|
||||||
} ParseResult;
|
} ParseResult;
|
||||||
|
|
||||||
/*static SwkbdCallbackResult fat32filter(void *user, const char **ppMessage, const char *text, size_t textlen)
|
// unescapes URL-encoded string non-destructively
|
||||||
|
static char * unescape(const char * url)
|
||||||
{
|
{
|
||||||
(void)textlen;
|
char * unescaped = malloc(strlen(url) + 1);
|
||||||
(void)user;
|
// source shamelessly ripped from https://stackoverflow.com/a/14530993/4073959
|
||||||
*ppMessage = "Input must not contain:\n><\"?;:/\\+,.|[=]";
|
char a;
|
||||||
if(strpbrk(text, "><\"?;:/\\+,.|[=]"))
|
char b;
|
||||||
|
while (*url)
|
||||||
{
|
{
|
||||||
DEBUG("illegal filename: %s\n", text);
|
if ((*url == '%') &&
|
||||||
return SWKBD_CALLBACK_CONTINUE;
|
((a = url[1]) && (b = url[2])) &&
|
||||||
|
(isxdigit(a) && isxdigit(b))) {
|
||||||
|
if (a >= 'a')
|
||||||
|
a -= 'a' - 'A';
|
||||||
|
if (a >= 'A')
|
||||||
|
a -= ('A' - 10);
|
||||||
|
else
|
||||||
|
a -= '0';
|
||||||
|
if (b >= 'a')
|
||||||
|
b -= 'a' - 'A';
|
||||||
|
if (b >= 'A')
|
||||||
|
b -= ('A' - 10);
|
||||||
|
else
|
||||||
|
b -= '0';
|
||||||
|
*unescaped++ = 16 * a + b;
|
||||||
|
url += 3;
|
||||||
|
}
|
||||||
|
else if (*url == '+')
|
||||||
|
{
|
||||||
|
*unescaped++ = ' ';
|
||||||
|
url++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*unescaped++ = *url++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*unescaped++ = '\0';
|
||||||
|
return unescaped;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SWKBD_CALLBACK_OK;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// the good paths for this function return SUCCESS, ABORTED, or REDIRECT;
|
// the good paths for this function return SUCCESS, ABORTED, or REDIRECT;
|
||||||
// all other paths are failures
|
// all other paths are failures
|
||||||
@@ -894,11 +927,6 @@ static ParseResult parse_header(struct header * out, httpcContext * context, con
|
|||||||
* call example: written = http_get("url", &filename, &buffer_to_download_to, &filesize, INSTALL_DOWNLOAD, "application/json");
|
* call example: written = http_get("url", &filename, &buffer_to_download_to, &filesize, INSTALL_DOWNLOAD, "application/json");
|
||||||
*/
|
*/
|
||||||
Result http_get(const char * url, char ** filename, char ** buf, u32 * size, InstallType install_type, const char * acceptable_mime_types)
|
Result http_get(const char * url, char ** filename, char ** buf, u32 * size, InstallType install_type, const char * acceptable_mime_types)
|
||||||
{
|
|
||||||
return http_get_with_not_found_flag(url, filename, buf, size, install_type, acceptable_mime_types, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Result http_get_with_not_found_flag(const char * url, char ** filename, char ** buf, u32 * size, InstallType install_type, const char * acceptable_mime_types, bool not_found_is_error)
|
|
||||||
{
|
{
|
||||||
Result ret;
|
Result ret;
|
||||||
httpcContext context;
|
httpcContext context;
|
||||||
@@ -935,7 +963,6 @@ redirect: // goto here if we need to redirect
|
|||||||
|
|
||||||
#define ERROR_BUFFER_SIZE 0x80
|
#define ERROR_BUFFER_SIZE 0x80
|
||||||
char err_buf[ERROR_BUFFER_SIZE];
|
char err_buf[ERROR_BUFFER_SIZE];
|
||||||
Result res;
|
|
||||||
ParseResult parse = parse_header(&_header, &context, acceptable_mime_types);
|
ParseResult parse = parse_header(&_header, &context, acceptable_mime_types);
|
||||||
switch (parse)
|
switch (parse)
|
||||||
{
|
{
|
||||||
@@ -981,10 +1008,7 @@ redirect: // goto here if we need to redirect
|
|||||||
snprintf(err_buf, ERROR_BUFFER_SIZE, ZIP_NOT_AVAILABLE);
|
snprintf(err_buf, ERROR_BUFFER_SIZE, ZIP_NOT_AVAILABLE);
|
||||||
goto error;
|
goto error;
|
||||||
case HTTP_NOT_FOUND:
|
case HTTP_NOT_FOUND:
|
||||||
if (!not_found_is_error)
|
case HTTP_GONE: ;
|
||||||
goto not_found_non_error;
|
|
||||||
[[fallthrough]];
|
|
||||||
case HTTP_GONE:
|
|
||||||
const char * http_error = parse == HTTP_NOT_FOUND ? "404 Not Found" : "410 Gone";
|
const char * http_error = parse == HTTP_NOT_FOUND ? "404 Not Found" : "410 Gone";
|
||||||
DEBUG("HTTP %s; URL: %s\n", http_error, url);
|
DEBUG("HTTP %s; URL: %s\n", http_error, url);
|
||||||
if (strstr(url, THEMEPLAZA_BASE_URL) && parse == HTTP_NOT_FOUND)
|
if (strstr(url, THEMEPLAZA_BASE_URL) && parse == HTTP_NOT_FOUND)
|
||||||
@@ -1047,13 +1071,9 @@ redirect: // goto here if we need to redirect
|
|||||||
goto no_error;
|
goto no_error;
|
||||||
error:
|
error:
|
||||||
throw_error(err_buf, ERROR_LEVEL_WARNING);
|
throw_error(err_buf, ERROR_LEVEL_WARNING);
|
||||||
res = httpcCloseContext(&context);
|
Result res = httpcCloseContext(&context);
|
||||||
if (R_FAILED(res)) return res;
|
if (R_FAILED(res)) return res;
|
||||||
return MAKERESULT(RL_TEMPORARY, RS_CANCELED, RM_APPLICATION, RD_NO_DATA);
|
return MAKERESULT(RL_TEMPORARY, RS_CANCELED, RM_APPLICATION, RD_NO_DATA);
|
||||||
not_found_non_error:
|
|
||||||
res = httpcCloseContext(&context);
|
|
||||||
if (R_FAILED(res)) return res;
|
|
||||||
return MAKERESULT(RL_SUCCESS, RS_NOTFOUND, RM_FILE_SERVER, RD_NO_DATA);
|
|
||||||
no_error:;
|
no_error:;
|
||||||
u32 chunk_size;
|
u32 chunk_size;
|
||||||
if (_header.file_size)
|
if (_header.file_size)
|
||||||
@@ -1112,6 +1132,15 @@ no_error:;
|
|||||||
*buf = new_buf;
|
*buf = new_buf;
|
||||||
|
|
||||||
DEBUG("size: %lu\n", *size);
|
DEBUG("size: %lu\n", *size);
|
||||||
if (filename) { DEBUG("filename: %s\n", *filename); }
|
if (filename) {
|
||||||
|
if (*filename == NULL)
|
||||||
|
{
|
||||||
|
// Content-Disposition extraction failed somehow
|
||||||
|
char * tmp = unescape(url);
|
||||||
|
*filename = strdup(basename(tmp));
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
DEBUG("filename: %s\n", *filename);
|
||||||
|
}
|
||||||
return MAKERESULT(RL_SUCCESS, RS_SUCCESS, RM_APPLICATION, RD_SUCCESS);
|
return MAKERESULT(RL_SUCCESS, RS_SUCCESS, RM_APPLICATION, RD_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -505,7 +505,6 @@ Result dump_all_themes(void)
|
|||||||
res = AMAPP_ListDLCContentInfos(&readcount, MEDIATYPE_SD, titleId, count, 0, contentInfos);
|
res = AMAPP_ListDLCContentInfos(&readcount, MEDIATYPE_SD, titleId, count, 0, contentInfos);
|
||||||
if(R_FAILED(res))
|
if(R_FAILED(res))
|
||||||
{
|
{
|
||||||
free(contentInfos);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -552,8 +551,6 @@ Result dump_all_themes(void)
|
|||||||
|
|
||||||
FILE* fh = fopen(contentinfoarchive_path, "rb");
|
FILE* fh = fopen(contentinfoarchive_path, "rb");
|
||||||
|
|
||||||
if(fh != NULL)
|
|
||||||
{
|
|
||||||
for(u32 i = 0; i < readcount; ++i)
|
for(u32 i = 0; i < readcount; ++i)
|
||||||
{
|
{
|
||||||
if(i == 0) continue;
|
if(i == 0) continue;
|
||||||
@@ -574,6 +571,11 @@ Result dump_all_themes(void)
|
|||||||
if(R_FAILED(res))
|
if(R_FAILED(res))
|
||||||
{
|
{
|
||||||
DEBUG("theme open romfs error: %08lx\n", res);
|
DEBUG("theme open romfs error: %08lx\n", res);
|
||||||
|
fclose(fh);
|
||||||
|
free(contentInfos);
|
||||||
|
romfsUnmount("meta");
|
||||||
|
FSUSER_CloseArchive(ncch_archive);
|
||||||
|
free(contentInfos);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -600,7 +602,7 @@ Result dump_all_themes(void)
|
|||||||
{
|
{
|
||||||
fseek(theme_file, 0, SEEK_END);
|
fseek(theme_file, 0, SEEK_END);
|
||||||
long theme_size = ftell(theme_file);
|
long theme_size = ftell(theme_file);
|
||||||
fseek(theme_file, 0, SEEK_SET);
|
fseek(theme_file, 0, SEEK_CUR);
|
||||||
char* theme_data = malloc(theme_size);
|
char* theme_data = malloc(theme_size);
|
||||||
fread(theme_data, 1, theme_size, theme_file);
|
fread(theme_data, 1, theme_size, theme_file);
|
||||||
fclose(theme_file);
|
fclose(theme_file);
|
||||||
@@ -617,7 +619,7 @@ Result dump_all_themes(void)
|
|||||||
{
|
{
|
||||||
fseek(bgm_file, 0, SEEK_END);
|
fseek(bgm_file, 0, SEEK_END);
|
||||||
long bgm_size = ftell(bgm_file);
|
long bgm_size = ftell(bgm_file);
|
||||||
fseek(bgm_file, 0, SEEK_SET);
|
fseek(bgm_file, 0, SEEK_CUR);
|
||||||
char* bgm_data = malloc(bgm_size);
|
char* bgm_data = malloc(bgm_size);
|
||||||
fread(bgm_data, 1, bgm_size, bgm_file);
|
fread(bgm_data, 1, bgm_size, bgm_file);
|
||||||
fclose(bgm_file);
|
fclose(bgm_file);
|
||||||
@@ -644,7 +646,6 @@ Result dump_all_themes(void)
|
|||||||
|
|
||||||
fclose(fh);
|
fclose(fh);
|
||||||
fh = NULL;
|
fh = NULL;
|
||||||
}
|
|
||||||
free(contentInfos);
|
free(contentInfos);
|
||||||
contentInfos = NULL;
|
contentInfos = NULL;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user