mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-14 19:15:05 -05:00
replace all c number parsing with numFromString
This commit is contained in:
parent
2cd1a9ee26
commit
006ede8f34
7 changed files with 65 additions and 89 deletions
|
@ -3,6 +3,7 @@
|
||||||
#include <Geode/utils/VersionInfo.hpp>
|
#include <Geode/utils/VersionInfo.hpp>
|
||||||
#include <Geode/utils/file.hpp>
|
#include <Geode/utils/file.hpp>
|
||||||
#include <Geode/utils/string.hpp>
|
#include <Geode/utils/string.hpp>
|
||||||
|
#include <Geode/utils/general.hpp>
|
||||||
#include <about.hpp>
|
#include <about.hpp>
|
||||||
#include <matjson.hpp>
|
#include <matjson.hpp>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
@ -149,13 +150,9 @@ Result<ModMetadata> ModMetadata::Impl::createFromSchemaV010(ModJson const& rawJs
|
||||||
ver = "0.000";
|
ver = "0.000";
|
||||||
}
|
}
|
||||||
if (ver != "*") {
|
if (ver != "*") {
|
||||||
double val = 0.0;
|
auto res = numFromString<double>(ver);
|
||||||
errno = 0;
|
if (res.isErr()) {
|
||||||
if (std::setlocale(LC_NUMERIC, "C")) {
|
return Err("[mod.json] has invalid target GD version");
|
||||||
val = std::strtod(ver.c_str(), nullptr);
|
|
||||||
if (errno == ERANGE) {
|
|
||||||
return Err("[mod.json] has invalid target GD version");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
impl->m_gdVersion = ver;
|
impl->m_gdVersion = ver;
|
||||||
}
|
}
|
||||||
|
@ -567,7 +564,11 @@ Result<> ModMetadata::checkGameVersion() const {
|
||||||
if (!m_impl->m_gdVersion.empty()) {
|
if (!m_impl->m_gdVersion.empty()) {
|
||||||
auto const ver = m_impl->m_gdVersion;
|
auto const ver = m_impl->m_gdVersion;
|
||||||
|
|
||||||
double modTargetVer = std::stod(ver);
|
auto res = numFromString<double>(ver);
|
||||||
|
if (res.isErr()) {
|
||||||
|
return Err("Invalid target GD version");
|
||||||
|
}
|
||||||
|
double modTargetVer = res.unwrap();
|
||||||
|
|
||||||
if (modTargetVer == 0.0) { // O.o
|
if (modTargetVer == 0.0) { // O.o
|
||||||
return Err(fmt::format("This mod doesn't support the current platform."));
|
return Err(fmt::format("This mod doesn't support the current platform."));
|
||||||
|
|
|
@ -264,7 +264,11 @@ int writeAndGetPid() {
|
||||||
log::warn("Failed to read last-pid file: {}", res.error());
|
log::warn("Failed to read last-pid file: {}", res.error());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lastPid = std::stoi(res.unwrap());
|
auto res = numFromString<int>(res.unwrap());
|
||||||
|
if (!res) {
|
||||||
|
log::warn("Failed to parse last-pid file: {}", res.error());
|
||||||
|
}
|
||||||
|
else lastPid = res.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
|
|
|
@ -9,37 +9,13 @@
|
||||||
#include <Geode/binding/CCMenuItemToggler.hpp>
|
#include <Geode/binding/CCMenuItemToggler.hpp>
|
||||||
#include <Geode/loader/Loader.hpp>
|
#include <Geode/loader/Loader.hpp>
|
||||||
#include <Geode/loader/Dirs.hpp>
|
#include <Geode/loader/Dirs.hpp>
|
||||||
|
#include <Geode/utils/general.hpp>
|
||||||
#include <charconv>
|
#include <charconv>
|
||||||
#include <clocale>
|
#include <clocale>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
|
|
||||||
template <class Num>
|
|
||||||
Num parseNumForInput(std::string const& str) {
|
|
||||||
if constexpr (std::is_same_v<Num, int64_t>) {
|
|
||||||
int64_t i = 0;
|
|
||||||
auto res = std::from_chars(str.data(), str.data() + str.size(), i);
|
|
||||||
if (res.ec == std::errc()) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if constexpr (std::is_same_v<Num, double>) {
|
|
||||||
double val = 0.0;
|
|
||||||
errno = 0;
|
|
||||||
if (std::setlocale(LC_NUMERIC, "C")) {
|
|
||||||
val = std::strtod(str.c_str(), nullptr);
|
|
||||||
if (errno == 0) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
static_assert(!std::is_same_v<Num, Num>, "Impl Num for parseNumForInput");
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
static float valueToSlider(T const& setting, typename T::ValueType value) {
|
static float valueToSlider(T const& setting, typename T::ValueType value) {
|
||||||
auto min = setting.min ? setting.min.value() : -100;
|
auto min = setting.min ? setting.min.value() : -100;
|
||||||
|
@ -193,7 +169,9 @@ void IntSettingNode::onArrow(CCObject* sender) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void IntSettingNode::textChanged(CCTextInputNode* input) {
|
void IntSettingNode::textChanged(CCTextInputNode* input) {
|
||||||
m_uncommittedValue = parseNumForInput<ValueType>(input->getString());
|
auto res = numFromString<ValueType>(input->getString());
|
||||||
|
if (!res) return;
|
||||||
|
m_uncommittedValue = res.unwrap();
|
||||||
this->valueChanged(false);
|
this->valueChanged(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,7 +253,9 @@ void FloatSettingNode::onArrow(CCObject* sender) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FloatSettingNode::textChanged(CCTextInputNode* input) {
|
void FloatSettingNode::textChanged(CCTextInputNode* input) {
|
||||||
m_uncommittedValue = parseNumForInput<ValueType>(input->getString());
|
auto res = numFromString<ValueType>(input->getString());
|
||||||
|
if (!res) return;
|
||||||
|
m_uncommittedValue = res.unwrap();
|
||||||
this->valueChanged(false);
|
this->valueChanged(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,27 +10,6 @@
|
||||||
|
|
||||||
using namespace geode::prelude;
|
using namespace geode::prelude;
|
||||||
|
|
||||||
static GLubyte parseInt(char const* str) {
|
|
||||||
int i = 0;
|
|
||||||
auto res = std::from_chars(str, str + strlen(str), i);
|
|
||||||
if (res.ec == std::errc()) {
|
|
||||||
return static_cast<GLubyte>(i);
|
|
||||||
}
|
|
||||||
return 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GLubyte parseFloat(char const* str) {
|
|
||||||
float val = 0.0f;
|
|
||||||
errno = 0;
|
|
||||||
if (std::setlocale(LC_NUMERIC, "C")) {
|
|
||||||
val = std::strtof(str, nullptr);
|
|
||||||
if (errno == 0) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 255.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ColorPickPopup::setup(ccColor4B const& color, bool isRGBA) {
|
bool ColorPickPopup::setup(ccColor4B const& color, bool isRGBA) {
|
||||||
m_noElasticity = true;
|
m_noElasticity = true;
|
||||||
m_color = color;
|
m_color = color;
|
||||||
|
@ -307,8 +286,7 @@ bool ColorPickPopup::setup(ccColor4B const& color, bool isRGBA) {
|
||||||
sliderWrapper->addChildAtPosition(m_opacitySlider, Anchor::Center, ccp(0, 0));
|
sliderWrapper->addChildAtPosition(m_opacitySlider, Anchor::Center, ccp(0, 0));
|
||||||
sliderColumn->addChild(sliderWrapper);
|
sliderColumn->addChild(sliderWrapper);
|
||||||
|
|
||||||
m_opacityInput = TextInput::create(60.f, "0.00");
|
m_opacityInput = TextInput::create(60.f, "Opacity");
|
||||||
m_opacityInput->setPosition(85.f, -95.f);
|
|
||||||
m_opacityInput->setScale(.7f);
|
m_opacityInput->setScale(.7f);
|
||||||
m_opacityInput->setDelegate(this, TAG_OPACITY_INPUT);
|
m_opacityInput->setDelegate(this, TAG_OPACITY_INPUT);
|
||||||
m_opacityInput->setID("opacity-input");
|
m_opacityInput->setID("opacity-input");
|
||||||
|
@ -382,15 +360,27 @@ void ColorPickPopup::textChanged(CCTextInputNode* input) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_OPACITY_INPUT:
|
case TAG_OPACITY_INPUT: {
|
||||||
{
|
auto res = numFromString<float>(input->getString().c_str());
|
||||||
m_color.a = parseFloat(input->getString().c_str());
|
if (res) m_color.a = std::clamp(static_cast<int>(res.unwrap() * 255.f), 0, 255);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case TAG_R_INPUT: m_color.r = parseInt(input->getString().c_str()); break;
|
case TAG_R_INPUT: {
|
||||||
case TAG_G_INPUT: m_color.g = parseInt(input->getString().c_str()); break;
|
auto res = numFromString<uint32_t>(input->getString().c_str());
|
||||||
case TAG_B_INPUT: m_color.b = parseInt(input->getString().c_str()); break;
|
if (res) m_color.r = std::clamp(res.unwrap(), 0u, 255u);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TAG_G_INPUT: {
|
||||||
|
auto res = numFromString<uint32_t>(input->getString().c_str());
|
||||||
|
if (res) m_color.g = std::clamp(res.unwrap(), 0u, 255u);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TAG_B_INPUT: {
|
||||||
|
auto res = numFromString<uint32_t>(input->getString().c_str());
|
||||||
|
if (res) m_color.b = std::clamp(res.unwrap(), 0u, 255u);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,12 +79,11 @@ public:
|
||||||
Result<ccColor3B> colorForIdentifier(std::string const& tag) {
|
Result<ccColor3B> colorForIdentifier(std::string const& tag) {
|
||||||
if (utils::string::contains(tag, ' ')) {
|
if (utils::string::contains(tag, ' ')) {
|
||||||
auto hexStr = utils::string::split(utils::string::normalize(tag), " ").at(1);
|
auto hexStr = utils::string::split(utils::string::normalize(tag), " ").at(1);
|
||||||
int hex = 0;
|
auto res = numFromString<uint32_t>(hexStr, 16);
|
||||||
auto res = std::from_chars(hexStr.data(), hexStr.data() + hexStr.size(), hex, 16);
|
if (res.isErr()) {
|
||||||
if (res.ec != std::errc()) {
|
|
||||||
return Err("Invalid hex");
|
return Err("Invalid hex");
|
||||||
}
|
}
|
||||||
return Ok(cc3x(hex));
|
return Ok(cc3x(res.unwrap()));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
auto colorText = tag.substr(1);
|
auto colorText = tag.substr(1);
|
||||||
|
@ -190,40 +189,36 @@ void MDTextArea::onGDProfile(CCObject* pSender) {
|
||||||
auto href = as<CCString*>(as<CCNode*>(pSender)->getUserObject());
|
auto href = as<CCString*>(as<CCNode*>(pSender)->getUserObject());
|
||||||
auto profile = std::string(href->getCString());
|
auto profile = std::string(href->getCString());
|
||||||
profile = profile.substr(profile.find(":") + 1);
|
profile = profile.substr(profile.find(":") + 1);
|
||||||
int id = 0;
|
auto res = numFromString<int>(profile);
|
||||||
auto res = std::from_chars(profile.data(), profile.data() + profile.size(), id);
|
if (res.isErr()) {
|
||||||
if (res.ec != std::errc()) {
|
|
||||||
FLAlertLayer::create(
|
FLAlertLayer::create(
|
||||||
"Error",
|
"Error",
|
||||||
"Invalid profile ID: <cr>" + profile +
|
"Invalid profile ID: <cr>" + profile +
|
||||||
"</c>. This is "
|
"</c>. This is "
|
||||||
"probably the mod developer's fault, report the bug to them.",
|
"probably the mod developer's fault, report the bug to them.",
|
||||||
"OK"
|
"OK"
|
||||||
)
|
)->show();
|
||||||
->show();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ProfilePage::create(id, false)->show();
|
ProfilePage::create(res.unwrap(), false)->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MDTextArea::onGDLevel(CCObject* pSender) {
|
void MDTextArea::onGDLevel(CCObject* pSender) {
|
||||||
auto href = as<CCString*>(as<CCNode*>(pSender)->getUserObject());
|
auto href = as<CCString*>(as<CCNode*>(pSender)->getUserObject());
|
||||||
auto level = std::string(href->getCString());
|
auto level = std::string(href->getCString());
|
||||||
level = level.substr(level.find(":") + 1);
|
level = level.substr(level.find(":") + 1);
|
||||||
int id = 0;
|
auto res = numFromString<int>(level);
|
||||||
auto res = std::from_chars(level.data(), level.data() + level.size(), id);
|
if (res.isErr()) {
|
||||||
if (res.ec != std::errc()) {
|
|
||||||
FLAlertLayer::create(
|
FLAlertLayer::create(
|
||||||
"Error",
|
"Error",
|
||||||
"Invalid level ID: <cr>" + level +
|
"Invalid level ID: <cr>" + level +
|
||||||
"</c>. This is "
|
"</c>. This is "
|
||||||
"probably the mod developers's fault, report the bug to them.",
|
"probably the mod developers's fault, report the bug to them.",
|
||||||
"OK"
|
"OK"
|
||||||
)
|
)->show();
|
||||||
->show();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto searchObject = GJSearchObject::create(SearchType::Type19, fmt::format("{}&gameVersion=22", id));
|
auto searchObject = GJSearchObject::create(SearchType::Type19, fmt::format("{}&gameVersion=22", res.unwrap()));
|
||||||
auto scene = LevelBrowserLayer::scene(searchObject);
|
auto scene = LevelBrowserLayer::scene(searchObject);
|
||||||
CCDirector::sharedDirector()->replaceScene(CCTransitionFade::create(0.5f, scene));
|
CCDirector::sharedDirector()->replaceScene(CCTransitionFade::create(0.5f, scene));
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,11 +131,11 @@ Result<ccColor3B> geode::cocos::cc3bFromHexString(std::string const& rawHexValue
|
||||||
if (hexValue.size() > 6) {
|
if (hexValue.size() > 6) {
|
||||||
return Err("Hex value too large");
|
return Err("Hex value too large");
|
||||||
}
|
}
|
||||||
size_t numValue;
|
auto res = numFromString<uint32_t>(hexValue, 16);
|
||||||
auto res = std::from_chars(hexValue.data(), hexValue.data() + hexValue.size(), numValue, 16);
|
if (!res) {
|
||||||
if (res.ec != std::errc()) {
|
|
||||||
return Err("Invalid hex value '{}'", hexValue);
|
return Err("Invalid hex value '{}'", hexValue);
|
||||||
}
|
}
|
||||||
|
auto numValue = res.unwrap();
|
||||||
switch (hexValue.size()) {
|
switch (hexValue.size()) {
|
||||||
case 6: {
|
case 6: {
|
||||||
auto r = static_cast<uint8_t>((numValue & 0xFF0000) >> 16);
|
auto r = static_cast<uint8_t>((numValue & 0xFF0000) >> 16);
|
||||||
|
@ -189,11 +189,11 @@ Result<ccColor4B> geode::cocos::cc4bFromHexString(std::string const& rawHexValue
|
||||||
if (hexValue.size() > 8) {
|
if (hexValue.size() > 8) {
|
||||||
return Err("Hex value too large");
|
return Err("Hex value too large");
|
||||||
}
|
}
|
||||||
size_t numValue;
|
auto res = numFromString<uint32_t>(hexValue, 16);
|
||||||
auto res = std::from_chars(hexValue.data(), hexValue.data() + hexValue.size(), numValue, 16);
|
if (!res) {
|
||||||
if (res.ec != std::errc()) {
|
|
||||||
return Err("Invalid hex value '{}'", hexValue);
|
return Err("Invalid hex value '{}'", hexValue);
|
||||||
}
|
}
|
||||||
|
auto numValue = res.unwrap();
|
||||||
switch (hexValue.size()) {
|
switch (hexValue.size()) {
|
||||||
case 8: {
|
case 8: {
|
||||||
auto r = static_cast<uint8_t>((numValue & 0xFF000000) >> 24);
|
auto r = static_cast<uint8_t>((numValue & 0xFF000000) >> 24);
|
||||||
|
|
|
@ -488,7 +488,13 @@ WebRequest& WebRequest::header(std::string_view name, std::string_view value) {
|
||||||
const size_t comma = value.find(',', numStart);
|
const size_t comma = value.find(',', numStart);
|
||||||
const size_t numLength = (comma == std::string::npos ? value.size() : comma) - numStart;
|
const size_t numLength = (comma == std::string::npos ? value.size() : comma) - numStart;
|
||||||
|
|
||||||
timeout(std::chrono::seconds(std::stol(std::string(value.substr(numStart, numLength)))));
|
int timeoutValue = 5;
|
||||||
|
auto res = numFromString<int>(value.substr(numStart, numLength));
|
||||||
|
if (res) {
|
||||||
|
timeoutValue = res.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
timeout(std::chrono::seconds(timeoutValue));
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue