Initial Commit
This commit is contained in:
199
source/main.c
Normal file
199
source/main.c
Normal file
@@ -0,0 +1,199 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <switch.h>
|
||||
#include <minizip/unzip.h>
|
||||
|
||||
#define PATCHES_ZIP "sdmc:/SaltySD/plugins/FPSLocker/patches.zip"
|
||||
#define EXTRACT_DIR "sdmc:/SaltySD/plugins/FPSLocker/"
|
||||
#define SELF_NRO "sdmc:/switch/PatchExtractor.nro"
|
||||
#define READ_BUF_SIZE 8192
|
||||
|
||||
#define STATUS_ROW 11
|
||||
|
||||
static PrintConsole *con;
|
||||
|
||||
static void status(const char *fmt, ...) {
|
||||
printf("\x1b[%d;0H\x1b[2K", STATUS_ROW);
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static int mkdirs(const char *path) {
|
||||
char tmp[512];
|
||||
snprintf(tmp, sizeof(tmp), "%s", path);
|
||||
size_t len = strlen(tmp);
|
||||
if (len == 0) return 0;
|
||||
if (tmp[len - 1] == '/') tmp[len - 1] = '\0';
|
||||
|
||||
for (char *p = tmp + 1; *p; p++) {
|
||||
if (*p == '/') {
|
||||
*p = '\0';
|
||||
mkdir(tmp, 0755);
|
||||
*p = '/';
|
||||
}
|
||||
}
|
||||
return mkdir(tmp, 0755);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
con = consoleInit(NULL);
|
||||
|
||||
padConfigureInput(1, HidNpadStyleSet_NpadStandard);
|
||||
PadState pad;
|
||||
padInitializeDefault(&pad);
|
||||
|
||||
printf("\n");
|
||||
printf(" ========================================\n");
|
||||
printf(" PatchExtractor - OmniNX OC\n");
|
||||
printf(" SaltyNX / FPSLocker Patch Installer\n");
|
||||
printf(" ========================================\n\n");
|
||||
|
||||
unzFile zip = unzOpen(PATCHES_ZIP);
|
||||
if (!zip) {
|
||||
printf(" \x1b[31mFEHLER:\x1b[0m patches.zip nicht gefunden!\n\n");
|
||||
printf(" Pfad: %s\n\n", PATCHES_ZIP);
|
||||
printf(" Bist du sicher, dass du OmniNX OC installiert hast?\n\n");
|
||||
printf(" Die Datei patches.zip muss unter\n");
|
||||
printf(" sd:/SaltySD/plugins/FPSLocker/ liegen.\n\n");
|
||||
printf(" ----------------------------------------\n");
|
||||
printf(" Druecke + zum Beenden.\n");
|
||||
|
||||
while (appletMainLoop()) {
|
||||
padUpdate(&pad);
|
||||
if (padGetButtonsDown(&pad) & HidNpadButton_Plus) break;
|
||||
consoleUpdate(NULL);
|
||||
}
|
||||
consoleExit(NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
unz_global_info gi;
|
||||
unzGetGlobalInfo(zip, &gi);
|
||||
unsigned long total = gi.number_entry;
|
||||
printf(" patches.zip gefunden! (%lu Eintraege)\n", total);
|
||||
printf(" Druecke A zum Entpacken, + zum Abbrechen.\n\n");
|
||||
consoleUpdate(NULL);
|
||||
|
||||
while (appletMainLoop()) {
|
||||
padUpdate(&pad);
|
||||
u64 kDown = padGetButtonsDown(&pad);
|
||||
if (kDown & HidNpadButton_A) break;
|
||||
if (kDown & HidNpadButton_Plus) {
|
||||
unzClose(zip);
|
||||
consoleExit(NULL);
|
||||
return 0;
|
||||
}
|
||||
consoleUpdate(NULL);
|
||||
}
|
||||
|
||||
printf("\x1b[10;0H \x1b[93mBitte nicht beenden, bis der Vorgang abgeschlossen ist!\x1b[0m\n");
|
||||
consoleUpdate(NULL);
|
||||
|
||||
char filename[512];
|
||||
char fullpath[1024];
|
||||
unsigned char buf[READ_BUF_SIZE];
|
||||
unsigned long extracted = 0;
|
||||
unsigned long skipped = 0;
|
||||
int err = unzGoToFirstFile(zip);
|
||||
|
||||
while (err == UNZ_OK) {
|
||||
unz_file_info fi;
|
||||
unzGetCurrentFileInfo(zip, &fi, filename, sizeof(filename), NULL, 0, NULL, 0);
|
||||
|
||||
snprintf(fullpath, sizeof(fullpath), "%s%s", EXTRACT_DIR, filename);
|
||||
unsigned long progress = (unsigned long)((extracted * 100) / total);
|
||||
|
||||
size_t flen = strlen(filename);
|
||||
if (flen > 0 && filename[flen - 1] == '/') {
|
||||
mkdirs(fullpath);
|
||||
status(" [%3lu%%] DIR %s", progress, filename);
|
||||
} else {
|
||||
char dirpart[1024];
|
||||
snprintf(dirpart, sizeof(dirpart), "%s", fullpath);
|
||||
char *last_slash = strrchr(dirpart, '/');
|
||||
if (last_slash) {
|
||||
*last_slash = '\0';
|
||||
mkdirs(dirpart);
|
||||
}
|
||||
|
||||
if (unzOpenCurrentFile(zip) != UNZ_OK) {
|
||||
status(" [%3lu%%] \x1b[31mERR\x1b[0m %s", progress, filename);
|
||||
skipped++;
|
||||
extracted++;
|
||||
err = unzGoToNextFile(zip);
|
||||
continue;
|
||||
}
|
||||
|
||||
FILE *out = fopen(fullpath, "wb");
|
||||
if (!out) {
|
||||
status(" [%3lu%%] \x1b[31mERR\x1b[0m %s", progress, filename);
|
||||
unzCloseCurrentFile(zip);
|
||||
skipped++;
|
||||
extracted++;
|
||||
err = unzGoToNextFile(zip);
|
||||
continue;
|
||||
}
|
||||
|
||||
int bytes;
|
||||
while ((bytes = unzReadCurrentFile(zip, buf, READ_BUF_SIZE)) > 0) {
|
||||
fwrite(buf, 1, bytes, out);
|
||||
}
|
||||
|
||||
fclose(out);
|
||||
unzCloseCurrentFile(zip);
|
||||
status(" [%3lu%%] FILE %s", progress, filename);
|
||||
}
|
||||
|
||||
extracted++;
|
||||
consoleUpdate(NULL);
|
||||
err = unzGoToNextFile(zip);
|
||||
}
|
||||
|
||||
unzClose(zip);
|
||||
|
||||
status(" [100%%] Fertig! %lu / %lu entpackt.", extracted - skipped, total);
|
||||
consoleUpdate(NULL);
|
||||
|
||||
int cleanup_ok = 1;
|
||||
|
||||
printf("\x1b[%d;0H", STATUS_ROW + 2);
|
||||
if (remove(PATCHES_ZIP) == 0) {
|
||||
printf(" patches.zip geloescht.\n");
|
||||
} else {
|
||||
printf(" \x1b[31mpatches.zip konnte nicht geloescht werden.\x1b[0m\n");
|
||||
cleanup_ok = 0;
|
||||
}
|
||||
|
||||
if (remove(SELF_NRO) == 0) {
|
||||
printf(" PatchExtractor.nro geloescht (Selbstreinigung).\n");
|
||||
} else {
|
||||
printf(" \x1b[31mPatchExtractor.nro konnte nicht geloescht werden.\x1b[0m\n");
|
||||
cleanup_ok = 0;
|
||||
}
|
||||
|
||||
printf("\n ========================================\n");
|
||||
if (skipped == 0 && cleanup_ok) {
|
||||
printf(" \x1b[32mAlles erledigt!\x1b[0m\n");
|
||||
} else {
|
||||
printf(" \x1b[32mEntpacken abgeschlossen.\x1b[0m\n");
|
||||
if (skipped > 0)
|
||||
printf(" \x1b[31m%lu Eintraege fehlgeschlagen.\x1b[0m\n", skipped);
|
||||
}
|
||||
printf(" ========================================\n\n");
|
||||
printf(" Druecke + zum Beenden.\n");
|
||||
|
||||
while (appletMainLoop()) {
|
||||
padUpdate(&pad);
|
||||
if (padGetButtonsDown(&pad) & HidNpadButton_Plus) break;
|
||||
consoleUpdate(NULL);
|
||||
}
|
||||
|
||||
consoleExit(NULL);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user