mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-22 23:48:08 -05:00
Merge branch 'main' into anchor-layout
This commit is contained in:
commit
389c8b1bda
15 changed files with 153 additions and 35 deletions
2
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
2
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
|
@ -31,7 +31,7 @@ body:
|
||||||
attributes:
|
attributes:
|
||||||
label: Additional Information
|
label: Additional Information
|
||||||
description: Any additional information you wish to provide. Please add anything which did not fit into the other sections here.
|
description: Any additional information you wish to provide. Please add anything which did not fit into the other sections here.
|
||||||
placeholder: "Example: This is likely achieveable by doing X because..."
|
placeholder: "Example: This is likely achievable by doing X because..."
|
||||||
validations:
|
validations:
|
||||||
required: false
|
required: false
|
||||||
- type: markdown
|
- type: markdown
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
* Add utils for setting thread name, show it on log (832bcf81, ce53fb31)
|
* Add utils for setting thread name, show it on log (832bcf81, ce53fb31)
|
||||||
* Add some launch arguments for geode (7ccaef90)
|
* Add some launch arguments for geode (7ccaef90)
|
||||||
* Deprecate blocking file picking utils (ee97e2da)
|
* Deprecate blocking file picking utils (ee97e2da)
|
||||||
|
* Sort mods by id in crashlog (984d1482)
|
||||||
|
|
||||||
|
|
||||||
## v2.0.0-beta.11
|
## v2.0.0-beta.11
|
||||||
|
|
|
@ -35,7 +35,9 @@ namespace geode {
|
||||||
EnableFailed,
|
EnableFailed,
|
||||||
MissingDependency,
|
MissingDependency,
|
||||||
PresentIncompatibility,
|
PresentIncompatibility,
|
||||||
UnzipFailed
|
UnzipFailed,
|
||||||
|
UnsupportedVersion,
|
||||||
|
UnsupportedGeodeVersion,
|
||||||
};
|
};
|
||||||
Type type;
|
Type type;
|
||||||
std::variant<ghc::filesystem::path, ModMetadata, Mod*> cause;
|
std::variant<ghc::filesystem::path, ModMetadata, Mod*> cause;
|
||||||
|
|
|
@ -161,6 +161,11 @@ namespace geode {
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] std::optional<std::string> getGameVersion() const;
|
[[nodiscard]] std::optional<std::string> getGameVersion() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the target Geode version for the current platform.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] VersionInfo getGeodeVersion() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if mod can be installed on the current GD version.
|
* Checks if mod can be installed on the current GD version.
|
||||||
* Returns Ok() if it can, Err otherwise.
|
* Returns Ok() if it can, Err otherwise.
|
||||||
|
|
|
@ -19,6 +19,10 @@ namespace geode {
|
||||||
cocos2d::CCTouchDispatcher::get()->unregisterForcePrio(this);
|
cocos2d::CCTouchDispatcher::get()->unregisterForcePrio(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void registerWithTouchDispatcher() override {
|
||||||
|
cocos2d::CCTouchDispatcher::get()->addTargetedDelegate(this, -500, true);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool initBase(
|
bool initBase(
|
||||||
float width, float height, InitArgs... args, char const* bg,
|
float width, float height, InitArgs... args, char const* bg,
|
||||||
|
@ -26,9 +30,11 @@ namespace geode {
|
||||||
) {
|
) {
|
||||||
m_dynamic = dynamic;
|
m_dynamic = dynamic;
|
||||||
|
|
||||||
auto winSize = cocos2d::CCDirector::sharedDirector()->getWinSize();
|
auto winSize = cocos2d::CCDirector::get()->getWinSize();
|
||||||
m_size = cocos2d::CCSize { width, height };
|
m_size = cocos2d::CCSize { width, height };
|
||||||
|
|
||||||
|
cocos2d::CCTouchDispatcher::get()->registerForcePrio(this, 2);
|
||||||
|
|
||||||
if (!this->initWithColor({ 0, 0, 0, 105 })) return false;
|
if (!this->initWithColor({ 0, 0, 0, 105 })) return false;
|
||||||
m_mainLayer = cocos2d::CCLayer::create();
|
m_mainLayer = cocos2d::CCLayer::create();
|
||||||
this->addChild(m_mainLayer);
|
this->addChild(m_mainLayer);
|
||||||
|
@ -76,10 +82,6 @@ namespace geode {
|
||||||
this->setKeypadEnabled(true);
|
this->setKeypadEnabled(true);
|
||||||
this->setTouchEnabled(true);
|
this->setTouchEnabled(true);
|
||||||
|
|
||||||
cocos2d::CCTouchDispatcher::get()->registerForcePrio(this, 2);
|
|
||||||
|
|
||||||
cocos::handleTouchPriority(this);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -228,6 +228,8 @@ namespace geode {
|
||||||
std::string toString() const;
|
std::string toString() const;
|
||||||
friend GEODE_DLL std::string format_as(ComparableVersionInfo const& version);
|
friend GEODE_DLL std::string format_as(ComparableVersionInfo const& version);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool GEODE_DLL semverCompare(VersionInfo const& current, VersionInfo const& target);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class V>
|
template <class V>
|
||||||
|
|
|
@ -31,6 +31,13 @@ void crashlog::printMods(std::stringstream& stream) {
|
||||||
if (mods.empty()) {
|
if (mods.empty()) {
|
||||||
stream << "<None>\n";
|
stream << "<None>\n";
|
||||||
}
|
}
|
||||||
|
std::sort(mods.begin(), mods.end(), [](Mod* a, Mod* b) {
|
||||||
|
auto const s1 = a->getID();
|
||||||
|
auto const s2 = b->getID();
|
||||||
|
return std::lexicographical_compare(s1.begin(), s1.end(), s2.begin(), s2.end(), [](auto a, auto b) {
|
||||||
|
return std::tolower(a) < std::tolower(b);
|
||||||
|
});
|
||||||
|
});
|
||||||
using namespace std::string_view_literals;
|
using namespace std::string_view_literals;
|
||||||
for (auto& mod : mods) {
|
for (auto& mod : mods) {
|
||||||
stream << fmt::format("{} | [{}] {}\n",
|
stream << fmt::format("{} | [{}] {}\n",
|
||||||
|
@ -51,7 +58,7 @@ std::string crashlog::writeCrashlog(geode::Mod* faultyMod, std::string const& in
|
||||||
std::stringstream file;
|
std::stringstream file;
|
||||||
|
|
||||||
file << getDateString(false) << "\n"
|
file << getDateString(false) << "\n"
|
||||||
<< std::showbase << "Whoopsies! An unhandled exception has occured.\n";
|
<< std::showbase << "Whoopsies! An unhandled exception has occurred.\n";
|
||||||
|
|
||||||
if (faultyMod) {
|
if (faultyMod) {
|
||||||
file << "It appears that the crash occurred while executing code from "
|
file << "It appears that the crash occurred while executing code from "
|
||||||
|
|
|
@ -148,10 +148,8 @@ VersionInfo Loader::Impl::maxModVersion() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Loader::Impl::isModVersionSupported(VersionInfo const& version) {
|
bool Loader::Impl::isModVersionSupported(VersionInfo const& target) {
|
||||||
return
|
return semverCompare(this->getVersion(), target);
|
||||||
version >= this->minModVersion() &&
|
|
||||||
version <= this->maxModVersion();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Data saving
|
// Data saving
|
||||||
|
@ -421,6 +419,37 @@ void Loader::Impl::loadModGraph(Mod* node, bool early) {
|
||||||
m_refreshingModCount -= 1;
|
m_refreshingModCount -= 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
{ // version checking
|
||||||
|
auto res = node->getMetadata().checkGameVersion();
|
||||||
|
if (!res) {
|
||||||
|
m_problems.push_back({
|
||||||
|
LoadProblem::Type::UnsupportedVersion,
|
||||||
|
node,
|
||||||
|
res.unwrapErr()
|
||||||
|
});
|
||||||
|
log::error("Unsupported game version: {}", res.unwrapErr());
|
||||||
|
m_refreshingModCount -= 1;
|
||||||
|
log::popNest();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->isModVersionSupported(node->getMetadata().getGeodeVersion())) {
|
||||||
|
m_problems.push_back({
|
||||||
|
LoadProblem::Type::UnsupportedGeodeVersion,
|
||||||
|
node,
|
||||||
|
fmt::format(
|
||||||
|
"Geode version {} is not supported (current: {})",
|
||||||
|
node->getMetadata().getGeodeVersion().toString(),
|
||||||
|
this->getVersion().toString()
|
||||||
|
)
|
||||||
|
});
|
||||||
|
log::error("Unsupported Geode version: {}", node->getMetadata().getGeodeVersion());
|
||||||
|
m_refreshingModCount -= 1;
|
||||||
|
log::popNest();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (early) {
|
if (early) {
|
||||||
auto res = unzipFunction();
|
auto res = unzipFunction();
|
||||||
if (!res) {
|
if (!res) {
|
||||||
|
|
|
@ -357,8 +357,6 @@ bool Mod::Impl::getLaunchFlag(std::string_view const name) const {
|
||||||
// Loading, Toggling, Installing
|
// Loading, Toggling, Installing
|
||||||
|
|
||||||
Result<> Mod::Impl::loadBinary() {
|
Result<> Mod::Impl::loadBinary() {
|
||||||
// i dont know where to put this so ill just plop it here
|
|
||||||
GEODE_UNWRAP(m_metadata.checkGameVersion());
|
|
||||||
|
|
||||||
log::debug("Loading binary for mod {}", m_metadata.getID());
|
log::debug("Loading binary for mod {}", m_metadata.getID());
|
||||||
if (m_enabled)
|
if (m_enabled)
|
||||||
|
|
|
@ -67,7 +67,7 @@ Result<ModMetadata> ModMetadata::Impl::createFromSchemaV010(ModJson const& rawJs
|
||||||
JsonChecker checker(impl->m_rawJSON);
|
JsonChecker checker(impl->m_rawJSON);
|
||||||
auto root = checker.root(checkerRoot).obj();
|
auto root = checker.root(checkerRoot).obj();
|
||||||
|
|
||||||
root.addKnownKey("geode");
|
root.needs("geode").into(impl->m_geodeVersion);
|
||||||
root.addKnownKey("gd");
|
root.addKnownKey("gd");
|
||||||
|
|
||||||
// Check GD version
|
// Check GD version
|
||||||
|
@ -194,23 +194,23 @@ Result<ModMetadata> ModMetadata::Impl::create(ModJson const& json) {
|
||||||
"specified, or its formatting is invalid (required: \"[v]X.X.X\")!"
|
"specified, or its formatting is invalid (required: \"[v]X.X.X\")!"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (schema < Loader::get()->minModVersion()) {
|
// if (schema < Loader::get()->minModVersion()) {
|
||||||
return Err(
|
// return Err(
|
||||||
"[mod.json] is built for an older version (" + schema.toString() +
|
// "[mod.json] is built for an older version (" + schema.toString() +
|
||||||
") of Geode (current: " + Loader::get()->getVersion().toString() +
|
// ") of Geode (current: " + Loader::get()->getVersion().toString() +
|
||||||
"). Please update the mod to the latest version, "
|
// "). Please update the mod to the latest version, "
|
||||||
"and if the problem persists, contact the developer "
|
// "and if the problem persists, contact the developer "
|
||||||
"to update it."
|
// "to update it."
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
if (schema > Loader::get()->maxModVersion()) {
|
// if (schema > Loader::get()->maxModVersion()) {
|
||||||
return Err(
|
// return Err(
|
||||||
"[mod.json] is built for a newer version (" + schema.toString() +
|
// "[mod.json] is built for a newer version (" + schema.toString() +
|
||||||
") of Geode (current: " + Loader::get()->getVersion().toString() +
|
// ") of Geode (current: " + Loader::get()->getVersion().toString() +
|
||||||
"). You need to update Geode in order to use "
|
// "). You need to update Geode in order to use "
|
||||||
"this mod."
|
// "this mod."
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Handle mod.json data based on target
|
// Handle mod.json data based on target
|
||||||
if (schema < VersionInfo(0, 1, 0)) {
|
if (schema < VersionInfo(0, 1, 0)) {
|
||||||
|
@ -407,6 +407,10 @@ std::optional<std::string> ModMetadata::getGameVersion() const {
|
||||||
return m_impl->m_gdVersion;
|
return m_impl->m_gdVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VersionInfo ModMetadata::getGeodeVersion() const {
|
||||||
|
return m_impl->m_geodeVersion;
|
||||||
|
}
|
||||||
|
|
||||||
Result<> ModMetadata::checkGameVersion() const {
|
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;
|
||||||
|
|
|
@ -17,6 +17,7 @@ namespace geode {
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
std::string m_developer;
|
std::string m_developer;
|
||||||
std::string m_gdVersion;
|
std::string m_gdVersion;
|
||||||
|
VersionInfo m_geodeVersion;
|
||||||
std::optional<std::string> m_description;
|
std::optional<std::string> m_description;
|
||||||
std::optional<std::string> m_details;
|
std::optional<std::string> m_details;
|
||||||
std::optional<std::string> m_changelog;
|
std::optional<std::string> m_changelog;
|
||||||
|
|
|
@ -572,8 +572,6 @@ void ModListLayer::reloadList(bool keepScroll, std::optional<ModListQuery> const
|
||||||
m_checkForUpdatesBtn->removeFromParent();
|
m_checkForUpdatesBtn->removeFromParent();
|
||||||
m_checkForUpdatesBtn = nullptr;
|
m_checkForUpdatesBtn = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleTouchPriority(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModListLayer::updateAllStates() {
|
void ModListLayer::updateAllStates() {
|
||||||
|
|
|
@ -95,6 +95,16 @@ bool ProblemsListCell::init(LoadProblem problem, ProblemsListPopup* list, CCSize
|
||||||
message = fmt::format("{} has failed unzipping", cause);
|
message = fmt::format("{} has failed unzipping", cause);
|
||||||
m_longMessage = problem.message;
|
m_longMessage = problem.message;
|
||||||
break;
|
break;
|
||||||
|
case LoadProblem::Type::UnsupportedVersion:
|
||||||
|
icon = "info-alert.png"_spr;
|
||||||
|
message = fmt::format("{} is incompatible with this version of GD", cause);
|
||||||
|
m_longMessage = problem.message;
|
||||||
|
break;
|
||||||
|
case LoadProblem::Type::UnsupportedGeodeVersion:
|
||||||
|
icon = "info-alert.png"_spr;
|
||||||
|
message = fmt::format("{} is incompatible with this version of Geode", cause);
|
||||||
|
m_longMessage = problem.message;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_problem = std::move(problem);
|
m_problem = std::move(problem);
|
||||||
|
|
|
@ -182,3 +182,62 @@ std::string ComparableVersionInfo::toString() const {
|
||||||
std::string geode::format_as(ComparableVersionInfo const& version) {
|
std::string geode::format_as(ComparableVersionInfo const& version) {
|
||||||
return version.toString();
|
return version.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool geode::semverCompare(VersionInfo const& current, VersionInfo const& target) {
|
||||||
|
if (target.getMajor() != current.getMajor()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (target.getMinor() > current.getMinor()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto ct = current.getTag();
|
||||||
|
auto tt = target.getTag();
|
||||||
|
if (ct && tt) {
|
||||||
|
auto currentTag = ct.value();
|
||||||
|
auto targetTag = tt.value();
|
||||||
|
switch (targetTag.value) {
|
||||||
|
case VersionTag::Alpha:
|
||||||
|
if (currentTag.value > VersionTag::Alpha) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (currentTag.number && targetTag.number) {
|
||||||
|
return currentTag.number.value() == targetTag.number.value();
|
||||||
|
}
|
||||||
|
if (currentTag.number) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (targetTag.number) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
case VersionTag::Beta:
|
||||||
|
if (currentTag.number && targetTag.number) {
|
||||||
|
return currentTag.number.value() >= targetTag.number.value();
|
||||||
|
}
|
||||||
|
if (currentTag.number) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (targetTag.number) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ct) {
|
||||||
|
auto currentTag = ct.value();
|
||||||
|
if (currentTag.value > VersionTag::Alpha) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (tt) {
|
||||||
|
auto targetTag = tt.value();
|
||||||
|
if (targetTag.value > VersionTag::Alpha) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue