draft transfer implementation
This commit is contained in:
444
source/util.cpp
444
source/util.cpp
@@ -1,351 +1,169 @@
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
#include <sys/stat.h>
|
||||
#include <json-c/json.h>
|
||||
/*
|
||||
* This file is part of Checkpoint
|
||||
* Copyright (C) 2017-2021 Bernardo Giordano, FlagBrew
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "fs/file.h"
|
||||
#include "data.h"
|
||||
#include "util.h"
|
||||
#include "type.h"
|
||||
#include "util.hpp"
|
||||
#include <logger.hpp>
|
||||
#include <MainApplication.hpp>
|
||||
#include "main.hpp"
|
||||
|
||||
static const uint32_t verboten[] = { L',', L'/', L'\\', L'<', L'>', L':', L'"', L'|', L'?', L'*', L'™', L'©', L'®'};
|
||||
|
||||
static bool isVerboten(const uint32_t& t)
|
||||
void servicesExit(void)
|
||||
{
|
||||
for(unsigned i = 0; i < 13; i++)
|
||||
{
|
||||
if(t == verboten[i])
|
||||
return true;
|
||||
Logger::getInstance().flush();
|
||||
pdmqryExit();
|
||||
socketExit();
|
||||
Account::exit();
|
||||
nsExit();
|
||||
plExit();
|
||||
romfsExit();
|
||||
}
|
||||
|
||||
Result servicesInit(void)
|
||||
{
|
||||
io::createDirectory("sdmc:/switch");
|
||||
io::createDirectory("sdmc:/switch/NXST");
|
||||
io::createDirectory("sdmc:/switch/NXST/saves");
|
||||
|
||||
Logger::getInstance().log(Logger::INFO, "Starting Checkpoint loading...");
|
||||
|
||||
if (appletGetAppletType() != AppletType_Application) {
|
||||
Logger::getInstance().log(Logger::WARN, "Please do not run Checkpoint in applet mode.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
// Result socinit = 0;
|
||||
// if ((socinit = socketInitializeDefault()) == 0) {
|
||||
// nxlinkStdio();
|
||||
// }
|
||||
// else {
|
||||
// Logger::getInstance().log(Logger::INFO, "Unable to initialize socket. Result code 0x%08lX.", socinit);
|
||||
// }
|
||||
|
||||
void util::replaceStr(std::string& _str, const std::string& _find, const std::string& _rep)
|
||||
{
|
||||
size_t pos = 0;
|
||||
while((pos = _str.find(_find)) != _str.npos)
|
||||
_str.replace(pos, _find.length(), _rep);
|
||||
}
|
||||
// g_shouldExitNetworkLoop = R_FAILED(socinit);
|
||||
|
||||
//Used to split version tag git
|
||||
static void getVersionFromTag(const std::string& tag, unsigned& _year, unsigned& _month, unsigned& _day)
|
||||
{
|
||||
_month = strtoul(tag.substr(0, 2).c_str(), NULL, 10);
|
||||
_day = strtoul(tag.substr(3, 5).c_str(), NULL, 10);
|
||||
_year = strtoul(tag.substr(6, 10).c_str(), NULL, 10);
|
||||
}
|
||||
Result res = 0;
|
||||
|
||||
//Missing swkbd config funcs for now
|
||||
typedef enum
|
||||
{
|
||||
SwkbdPosStart = 0,
|
||||
SwkbdPosEnd = 1
|
||||
} SwkbdInitPos;
|
||||
romfsInit();
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t read[0x32 / sizeof(uint16_t)];
|
||||
uint16_t word[0x32 / sizeof(uint16_t)];
|
||||
} dictWord;
|
||||
padConfigureInput(1, HidNpadStyleSet_NpadStandard);
|
||||
hidInitializeTouchScreen();
|
||||
|
||||
void swkbdDictWordCreate(dictWord *w, const char *read, const char *word)
|
||||
{
|
||||
memset(w, 0, sizeof(*w));
|
||||
|
||||
utf8_to_utf16(w->read, (uint8_t *)read, (sizeof(w->read) / sizeof(uint16_t)) - 1);
|
||||
utf8_to_utf16(w->word, (uint8_t *)word, (sizeof(w->word) / sizeof(uint16_t)) - 1);
|
||||
}
|
||||
|
||||
uint32_t replaceChar(uint32_t c)
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
case L'é':
|
||||
return 'e';
|
||||
break;
|
||||
if (R_FAILED(res = plInitialize(PlServiceType_User))) {
|
||||
Logger::getInstance().log(Logger::ERROR, "plInitialize failed. Result code 0x%08lX.", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static inline void replaceCharCStr(char *_s, char _find, char _rep)
|
||||
{
|
||||
size_t strLength = strlen(_s);
|
||||
for(unsigned i = 0; i < strLength; i++)
|
||||
{
|
||||
if(_s[i] == _find)
|
||||
_s[i] = _rep;
|
||||
}
|
||||
}
|
||||
|
||||
std::string util::getDateTime(int fmt)
|
||||
{
|
||||
char ret[128];
|
||||
|
||||
time_t raw;
|
||||
time(&raw);
|
||||
tm *Time = localtime(&raw);
|
||||
|
||||
switch(fmt)
|
||||
{
|
||||
case DATE_FMT_YMD:
|
||||
sprintf(ret, "%04d.%02d.%02d @ %02d.%02d.%02d", Time->tm_year + 1900, Time->tm_mon + 1, Time->tm_mday, Time->tm_hour, Time->tm_min, Time->tm_sec);
|
||||
break;
|
||||
|
||||
case DATE_FMT_YDM:
|
||||
sprintf(ret, "%04d.%02d.%02d @ %02d.%02d.%02d", Time->tm_year + 1900, Time->tm_mday, Time->tm_mon + 1, Time->tm_hour, Time->tm_min, Time->tm_sec);
|
||||
break;
|
||||
|
||||
case DATE_FMT_HOYSTE:
|
||||
sprintf(ret, "%02d.%02d.%04d", Time->tm_mday, Time->tm_mon + 1, Time->tm_year + 1900);
|
||||
break;
|
||||
|
||||
case DATE_FMT_JHK:
|
||||
sprintf(ret, "%04d%02d%02d_%02d%02d", Time->tm_year + 1900, Time->tm_mon + 1, Time->tm_mday, Time->tm_hour, Time->tm_min);
|
||||
break;
|
||||
|
||||
case DATE_FMT_ASC:
|
||||
strcpy(ret, asctime(Time));
|
||||
replaceCharCStr(ret, ':', '_');
|
||||
replaceCharCStr(ret, '\n', 0x00);
|
||||
break;
|
||||
if (R_FAILED(res = Account::init())) {
|
||||
Logger::getInstance().log(Logger::ERROR, "Account::init failed. Result code 0x%08lX.", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
return std::string(ret);
|
||||
}
|
||||
|
||||
//void util::copyDirListToMenu(const fs::dirList& d, ui::menu& m)
|
||||
//{
|
||||
// m.reset();
|
||||
// m.addOpt(NULL, ".");
|
||||
// m.addOpt(NULL, "..");
|
||||
// for(unsigned i = 0; i < d.getCount(); i++)
|
||||
// {
|
||||
// if(d.isDir(i))
|
||||
// m.addOpt(NULL, "D " + d.getItem(i));
|
||||
// else
|
||||
// m.addOpt(NULL, "F " + d.getItem(i));
|
||||
// }
|
||||
//}
|
||||
|
||||
void util::removeLastFolderFromString(std::string& _path)
|
||||
{
|
||||
unsigned last = _path.find_last_of('/', _path.length() - 2);
|
||||
_path.erase(last + 1, _path.length());
|
||||
}
|
||||
|
||||
size_t util::getTotalPlacesInPath(const std::string& _path)
|
||||
{
|
||||
//Skip device
|
||||
size_t pos = _path.find_first_of('/'), ret = 0;
|
||||
while((pos = _path.find_first_of('/', ++pos)) != _path.npos)
|
||||
++ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void util::trimPath(std::string& _path, uint8_t _places)
|
||||
{
|
||||
size_t pos = _path.find_first_of('/');
|
||||
for(int i = 0; i < _places; i++)
|
||||
pos = _path.find_first_of('/', ++pos);
|
||||
_path = _path.substr(++pos, _path.npos);
|
||||
}
|
||||
|
||||
std::string util::safeString(const std::string& s)
|
||||
{
|
||||
std::string ret = "";
|
||||
for(unsigned i = 0; i < s.length(); )
|
||||
{
|
||||
uint32_t tmpChr = 0;
|
||||
ssize_t untCnt = decode_utf8(&tmpChr, (uint8_t *)&s.data()[i]);
|
||||
|
||||
i += untCnt;
|
||||
|
||||
tmpChr = replaceChar(tmpChr);
|
||||
|
||||
if(isVerboten(tmpChr))
|
||||
ret += ' ';
|
||||
else if(!isASCII(tmpChr))
|
||||
return ""; //return empty string so titledata::init defaults to titleID
|
||||
else
|
||||
ret += (char)tmpChr;
|
||||
if (R_FAILED(res = nsInitialize())) {
|
||||
Logger::getInstance().log(Logger::ERROR, "nsInitialize failed. Result code 0x%08lX.", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
//Check for spaces at end
|
||||
while(ret[ret.length() - 1] == ' ' || ret[ret.length() - 1] == '.')
|
||||
ret.erase(ret.length() - 1, 1);
|
||||
// Configuration::getInstance();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline std::string getTimeString(const uint32_t& _h, const uint32_t& _m)
|
||||
{
|
||||
char tmp[32];
|
||||
sprintf(tmp, "%02d:%02d", _h, _m);
|
||||
return std::string(tmp);
|
||||
}
|
||||
|
||||
std::string util::getStringInput(SwkbdType _type, const std::string& def, const std::string& head, size_t maxLength, unsigned dictCnt, const std::string dictWords[])
|
||||
{
|
||||
SwkbdConfig swkbd;
|
||||
swkbdCreate(&swkbd, dictCnt);
|
||||
swkbdConfigSetBlurBackground(&swkbd, true);
|
||||
swkbdConfigSetInitialText(&swkbd, def.c_str());
|
||||
swkbdConfigSetHeaderText(&swkbd, head.c_str());
|
||||
swkbdConfigSetGuideText(&swkbd, head.c_str());
|
||||
swkbdConfigSetInitialCursorPos(&swkbd, SwkbdPosEnd);
|
||||
swkbdConfigSetType(&swkbd, _type);
|
||||
swkbdConfigSetStringLenMax(&swkbd, maxLength);
|
||||
swkbdConfigSetKeySetDisableBitmask(&swkbd, SwkbdKeyDisableBitmask_Backslash | SwkbdKeyDisableBitmask_Percent);
|
||||
swkbdConfigSetDicFlag(&swkbd, 1);
|
||||
|
||||
if(dictCnt > 0)
|
||||
{
|
||||
dictWord words[dictCnt];
|
||||
for(unsigned i = 0; i < dictCnt; i++)
|
||||
swkbdDictWordCreate(&words[i], dictWords[i].c_str(), dictWords[i].c_str());
|
||||
|
||||
swkbdConfigSetDictionary(&swkbd, (SwkbdDictWord *)words, dictCnt);
|
||||
if (R_SUCCEEDED(res = pdmqryInitialize())) {}
|
||||
else {
|
||||
Logger::getInstance().log(Logger::WARN, "pdmqryInitialize failed with result 0x%08lX.", res);
|
||||
}
|
||||
|
||||
char out[maxLength + 1];
|
||||
memset(out, 0, maxLength + 1);
|
||||
swkbdShow(&swkbd, out, maxLength + 1);
|
||||
swkbdClose(&swkbd);
|
||||
Logger::getInstance().log(Logger::INFO, "NXST loading completed!");
|
||||
|
||||
return std::string(out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string util::getExtensionFromString(const std::string& get)
|
||||
std::u16string StringUtils::UTF8toUTF16(const char* src)
|
||||
{
|
||||
size_t ext = get.find_last_of('.');
|
||||
if(ext != get.npos)
|
||||
return get.substr(ext + 1, get.npos);
|
||||
else
|
||||
return "";
|
||||
char16_t tmp[256] = {0};
|
||||
utf8_to_utf16((uint16_t*)tmp, (uint8_t*)src, 256);
|
||||
return std::u16string(tmp);
|
||||
}
|
||||
|
||||
std::string util::getFilenameFromPath(const std::string& get)
|
||||
// https://stackoverflow.com/questions/14094621/change-all-accented-letters-to-normal-letters-in-c
|
||||
std::string StringUtils::removeAccents(std::string str)
|
||||
{
|
||||
size_t nameStart = get.find_last_of('/');
|
||||
if(nameStart != get.npos)
|
||||
return get.substr(nameStart + 1, get.npos);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
std::u16string src = UTF8toUTF16(str.c_str());
|
||||
const std::u16string illegal = UTF8toUTF16("ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüūýþÿ");
|
||||
const std::u16string fixed = UTF8toUTF16("AAAAAAECEEEEIIIIDNOOOOOx0UUUUYPsaaaaaaeceeeeiiiiOnooooo/0uuuuuypy");
|
||||
|
||||
std::string util::generateAbbrev(const uint64_t& tid)
|
||||
{
|
||||
data::titleInfo *tmp = data::getTitleInfoByTID(tid);
|
||||
size_t titleLength = tmp->safeTitle.length();
|
||||
|
||||
char temp[titleLength + 1];
|
||||
memset(temp, 0, titleLength + 1);
|
||||
memcpy(temp, tmp->safeTitle.c_str(), titleLength);
|
||||
|
||||
std::string ret;
|
||||
char *tok = strtok(temp, " ");
|
||||
while(tok)
|
||||
{
|
||||
if(isASCII(tok[0]))
|
||||
ret += tok[0];
|
||||
tok = strtok(NULL, " ");
|
||||
for (size_t i = 0, sz = src.length(); i < sz; i++) {
|
||||
size_t index = illegal.find(src[i]);
|
||||
if (index != std::string::npos) {
|
||||
src[i] = fixed[index];
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
||||
return UTF16toUTF8(src);
|
||||
}
|
||||
|
||||
void util::stripChar(char _c, std::string& _s)
|
||||
std::string StringUtils::removeNotAscii(std::string str)
|
||||
{
|
||||
size_t pos = 0;
|
||||
while((pos = _s.find(_c)) != _s.npos)
|
||||
_s.erase(pos, 1);
|
||||
for (size_t i = 0, sz = str.length(); i < sz; i++) {
|
||||
if (!isascii(str[i])) {
|
||||
str[i] = ' ';
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
void util::replaceButtonsInString(std::string& rep)
|
||||
HidsysNotificationLedPattern blinkLedPattern(u8 times)
|
||||
{
|
||||
replaceStr(rep, "[A]", "\ue0e0");
|
||||
replaceStr(rep, "[B]", "\ue0e1");
|
||||
replaceStr(rep, "[X]", "\ue0e2");
|
||||
replaceStr(rep, "[Y]", "\ue0e3");
|
||||
replaceStr(rep, "[L]", "\ue0e4");
|
||||
replaceStr(rep, "[R]", "\ue0e5");
|
||||
replaceStr(rep, "[ZL]", "\ue0e6");
|
||||
replaceStr(rep, "[ZR]", "\ue0e7");
|
||||
replaceStr(rep, "[SL]", "\ue0e8");
|
||||
replaceStr(rep, "[SR]", "\ue0e9");
|
||||
replaceStr(rep, "[DPAD]", "\ue0ea");
|
||||
replaceStr(rep, "[DUP]", "\ue0eb");
|
||||
replaceStr(rep, "[DDOWN]", "\ue0ec");
|
||||
replaceStr(rep, "[DLEFT]", "\ue0ed");
|
||||
replaceStr(rep, "[DRIGHT]", "\ue0ee");
|
||||
replaceStr(rep, "[+]", "\ue0ef");
|
||||
replaceStr(rep, "[-]", "\ue0f0");
|
||||
HidsysNotificationLedPattern pattern;
|
||||
memset(&pattern, 0, sizeof(pattern));
|
||||
|
||||
pattern.baseMiniCycleDuration = 0x1; // 12.5ms.
|
||||
pattern.totalMiniCycles = 0x2; // 2 mini cycles.
|
||||
pattern.totalFullCycles = times; // Repeat n times.
|
||||
pattern.startIntensity = 0x0; // 0%.
|
||||
|
||||
pattern.miniCycles[0].ledIntensity = 0xF; // 100%.
|
||||
pattern.miniCycles[0].transitionSteps = 0xF; // 15 steps. Total 187.5ms.
|
||||
pattern.miniCycles[0].finalStepDuration = 0x0; // Forced 12.5ms.
|
||||
pattern.miniCycles[1].ledIntensity = 0x0; // 0%.
|
||||
pattern.miniCycles[1].transitionSteps = 0xF; // 15 steps. Total 187.5ms.
|
||||
pattern.miniCycles[1].finalStepDuration = 0x0; // Forced 12.5ms.
|
||||
|
||||
return pattern;
|
||||
}
|
||||
|
||||
void util::sysBoost()
|
||||
void blinkLed(u8 times)
|
||||
{
|
||||
if(R_FAILED(clkrstInitialize()))
|
||||
return;
|
||||
|
||||
ClkrstSession cpu, gpu, ram;
|
||||
clkrstOpenSession(&cpu, PcvModuleId_CpuBus, 3);
|
||||
clkrstOpenSession(&gpu, PcvModuleId_GPU, 3);
|
||||
clkrstOpenSession(&ram, PcvModuleId_EMC, 3);
|
||||
|
||||
clkrstSetClockRate(&cpu, util::CPU_SPEED_1785MHz);
|
||||
clkrstSetClockRate(&gpu, util::GPU_SPEED_76MHz);
|
||||
clkrstSetClockRate(&ram, util::RAM_SPEED_1600MHz);
|
||||
|
||||
clkrstCloseSession(&cpu);
|
||||
clkrstCloseSession(&gpu);
|
||||
clkrstCloseSession(&ram);
|
||||
clkrstExit();
|
||||
}
|
||||
|
||||
void util::sysNormal()
|
||||
{
|
||||
if(R_FAILED(clkrstInitialize()))
|
||||
return;
|
||||
|
||||
ClkrstSession cpu, gpu, ram;
|
||||
clkrstOpenSession(&cpu, PcvModuleId_CpuBus, 3);
|
||||
clkrstOpenSession(&gpu, PcvModuleId_GPU, 3);
|
||||
clkrstOpenSession(&ram, PcvModuleId_EMC, 3);
|
||||
|
||||
clkrstSetClockRate(&cpu, util::CPU_SPEED_1020MHz);
|
||||
clkrstSetClockRate(&gpu, util::GPU_SPEED_76MHz);
|
||||
clkrstSetClockRate(&ram, util::RAM_SPEED_1331MHz);
|
||||
|
||||
clkrstCloseSession(&cpu);
|
||||
clkrstCloseSession(&gpu);
|
||||
clkrstCloseSession(&ram);
|
||||
clkrstExit();
|
||||
|
||||
}
|
||||
|
||||
std::string util::getSizeString(const uint64_t& _size)
|
||||
{
|
||||
char sizeStr[32];
|
||||
if(_size >= 0x40000000)
|
||||
sprintf(sizeStr, "%.2fGB", (float)_size / 1024.0f / 1024.0f / 1024.0f);
|
||||
else if(_size >= 0x100000)
|
||||
sprintf(sizeStr, "%.2fMB", (float)_size / 1024.0f / 1024.0f);
|
||||
else if(_size >= 0x400)
|
||||
sprintf(sizeStr, "%.2fKB", (float)_size / 1024.0f);
|
||||
else
|
||||
sprintf(sizeStr, "%lu Bytes", _size);
|
||||
return std::string(sizeStr);
|
||||
}
|
||||
|
||||
Result util::accountDeleteUser(AccountUid *uid)
|
||||
{
|
||||
Service *account = accountGetServiceSession();
|
||||
struct
|
||||
{
|
||||
AccountUid uid;
|
||||
} in = {*uid};
|
||||
|
||||
return serviceDispatchIn(account, 203, in);
|
||||
if (g_notificationLedAvailable) {
|
||||
PadState pad;
|
||||
padInitializeDefault(&pad);
|
||||
s32 n;
|
||||
HidsysUniquePadId uniquePadIds[2] = {0};
|
||||
HidsysNotificationLedPattern pattern = blinkLedPattern(times);
|
||||
memset(uniquePadIds, 0, sizeof(uniquePadIds));
|
||||
Result res = hidsysGetUniquePadsFromNpad(padIsHandheld(&pad) ? HidNpadIdType_Handheld : HidNpadIdType_No1, uniquePadIds, 2, &n);
|
||||
if (R_SUCCEEDED(res)) {
|
||||
for (s32 i = 0; i < n; i++) {
|
||||
hidsysSetNotificationLedPattern(&pattern, uniquePadIds[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user