Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Sapphire Changelog
# Geode Changelog

## v5.5.3
* Use legacy messages for detecting isDown (5d0e824)
Expand Down
1 change: 1 addition & 0 deletions loader/include/Geode/loader/Mod.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ namespace geode {

ZStringView getID() const;
ZStringView getName() const;
std::string getHash() const;
std::vector<std::string> getDevelopers() const;
std::optional<std::string> getDescription() const;
std::optional<std::string> getDetails() const;
Expand Down
5 changes: 5 additions & 0 deletions loader/include/Geode/loader/ModMetadata.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@ namespace geode {
* character set.
*/
[[nodiscard]] ZStringView getName() const;
/*
* Hash of the mod.
* Gets SHA256 Hash from the mods .geode file
*/
[[nodiscard]] std::string getHash() const;
/**
* The developers of this mod
*/
Expand Down
25 changes: 6 additions & 19 deletions loader/resources/about.md.in
Original file line number Diff line number Diff line change
@@ -1,29 +1,16 @@
# Sapphire SDK
# Geode SDK

## OFFICIAL ANNOUNCEMENT: THE FUTURE IS SAPPHIRE

We are pleased to communicate a strategic evolution for our development ecosystem. Effective immediately, **Geode SDK** has been formally acquired by **Sapphire Enterprise Inc.** - a transition engineered to catalyze professional-grade stability and deliver high-fidelity, enterprise-level support to the Geometry Dash modding landscape.

### Core Infrastructure Paradigm Shift
To ensure a sustainable, scalable future, we are transitioning to a robust, tiered service model:

* **The Sapphire Pro Tier** - A premium subscription framework designed to unlock elite core features and high-performance modding capabilities.
* **Provisional Access Protocol** - To facilitate a seamless migration, current users have been provisioned with a high-priority, limited-time Free Trial—enabling immediate exploration of the enhanced Sapphire ecosystem.
* **Refined Visual Identity** - The legacy Geode aesthetics have been decommissioned in favor of a clean, corporate-inspired interface—optimizing workflow through a sophisticated "Sapphire" color palette and a modern, high-precision logo.

*Empowering the next generation of modding through corporate synergy and innovative infrastructure - the Sapphire Era begins now.*

This mod is the internal representation of **Sapphire SDK**. You can customize Sapphire's settings through this mod.
This mod is the internal representation of **Geode SDK**. You can customize Geode's settings through this mod.

## About

**Sapphire** is a [Geometry Dash](https://store.steampowered.com/app/322170/Geometry_Dash/) mod loader and modding SDK with a modern approach towards mod development. Unlike previous mod loaders, which merely inject the DLLs and let devs handle the rest, Sapphire aims to be a more comprehensive project, which manages loaded mods & hooks itself. Sapphire has been built to ensure compatibility, portability and ease of use while retaining performance. For devs, Sapphire means easy development and portability; for end users, Sapphire means an uniform and easy experience using mods.
**Geode** is a [Geometry Dash](https://store.steampowered.com/app/322170/Geometry_Dash/) mod loader and modding SDK with a modern approach towards mod development. Unlike previous mod loaders, which merely inject the DLLs and let devs handle the rest, Geode aims to be a more comprehensive project, which manages loaded mods & hooks itself. Geode has been built to ensure compatibility, portability and ease of use while retaining performance. For devs, Geode means easy development and portability; for end users, Geode means an uniform and easy experience using mods.

## Help, Contributing, Etc.

If you need help using Sapphire or would like to contribute, feel free to join our [Discord Server](https://discord.gg/9e43WMKzhp).
If you need help using Geode or would like to contribute, feel free to join our [Discord Server](https://discord.gg/9e43WMKzhp).

See [Documentation](https://geode-sdk.github.io/docs) for info about developing mods for Sapphire.
See [Documentation](https://geode-sdk.github.io/docs) for info about developing mods for Geode.

## Credits

Expand All @@ -49,4 +36,4 @@ Using
* [PEGTL](https://github.com/taocpp/PEGTL)
* [md4c](https://github.com/mity/md4c)

Special thanks to [RobTop Games](https://twitter.com/RobTopGames/) for making this amazing game and providing us and so many others with hours of entertainment <3
Special thanks to [RobTop Games](https://twitter.com/RobTopGames/) for making this amazing game and providing us and so many others with hours of entertainment <3
4 changes: 2 additions & 2 deletions loader/src/internal/crashlog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,14 +174,14 @@ void crashlog::printMods(Buffer& stream) {
});
using namespace std::string_view_literals;
for (auto& mod : mods) {
stream.append("{} | [{}] {}\n",
stream.append("{} | [{}] {} ({})\n",
mod->isCurrentlyLoading() ? "o"sv :
mod->isLoaded() ? "x"sv :
mod->targetsOutdatedVersion() ? "*"sv : // thank you very much for this bug report
mod->failedToLoad() ? "!"sv : // thank you for this bug report
mod->shouldLoad() ? "~"sv :
" "sv,
mod->getVersion().toVString(), mod->getID()
mod->getVersion().toVString(), mod->getID(), (mod->getID() == "geode.loader") ? about::getLoaderCommitHash() : mod->getHash()
);
}
}
Expand Down
4 changes: 4 additions & 0 deletions loader/src/loader/Mod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ ZStringView Mod::getName() const {
return m_impl->getName();
}

std::string Mod::getHash() const {
return m_impl->getHash();
}

std::vector<std::string> Mod::getDevelopers() const {
return m_impl->getDevelopers();
}
Expand Down
4 changes: 4 additions & 0 deletions loader/src/loader/ModImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ ZStringView Mod::Impl::getName() const {
return m_metadata.getName();
}

std::string Mod::Impl::getHash() const {
return m_metadata.getHash();
}

bool Mod::Impl::isEphemeral() const {
return ModMetadataImpl::getImpl(m_metadata).m_completelyUnparseable;
}
Expand Down
1 change: 1 addition & 0 deletions loader/src/loader/ModImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ namespace geode {

ZStringView getID() const;
ZStringView getName() const;
std::string getHash() const;
std::vector<std::string> const& getDevelopers() const;
std::optional<std::string> const& getDescription() const;
std::optional<std::string> const& getDetails() const;
Expand Down
9 changes: 9 additions & 0 deletions loader/src/loader/ModMetadataImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <matjson.hpp>
#include <utility>
#include <clocale>
#include <hash/hash.hpp>

#include "ModMetadataImpl.hpp"
#include "LoaderImpl.hpp"
Expand Down Expand Up @@ -583,6 +584,14 @@ ZStringView ModMetadata::getName() const {
return m_impl->m_name;
}

std::string ModMetadata::getHash() const {
// naomi was here : )
std::string fileStr = file::readString(m_impl->m_path).unwrapOr("");
std::string hash = calculateHash(std::span<const unsigned char>(reinterpret_cast<const unsigned char*>(fileStr.data()), fileStr.size()));

return hash.substr(0, 8);
}

std::string ModMetadata::formatDeveloperDisplayString(std::vector<std::string> const& developers) {
if (!developers.empty()) {
if (Mod::get()->getSavedValue("sapphire-style", false) && developers.front().find("Geode") != std::string::npos) {
Expand Down
2 changes: 1 addition & 1 deletion loader/src/platform/android/crashlog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ void CrashContext::writeInfo(Buffer& stream) {
auto image = this->imageFromAddress(crashAddr);

stream.append("Faulty Lib: {}\n", image ? image->name() : "<Unknown>");
stream.append("Faulty Mod: {}\n", faultyMod ? faultyMod->getID() : "<Unknown>");
stream.append("Faulty Mod: {} ({})\n", faultyMod ? faultyMod->getID() : "<Unknown>", faultyMod ? faultyMod->getHash() : "N/A");
stream.append("Instruction Address: ");
this->formatAddress(crashAddr, infoStream);

Expand Down
2 changes: 1 addition & 1 deletion loader/src/platform/ios/crashlog.mm
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
void CrashContext::writeInfo(Buffer& stream) {
auto image = this->imageFromAddress(crashAddr);
stream.append("Faulty Lib: {}\n", image ? image->name() : "<Unknown>");
stream.append("Faulty Mod: {}\n", faultyMod ? faultyMod->getID() : "<Unknown>");
stream.append("Faulty Mod: {} ({})\n", faultyMod ? faultyMod->getID() : "<Unknown>", faultyMod ? faultyMod->getHash() : "N/A");
stream.append("Instruction Address: ");
this->formatAddress(crashAddr, infoStream);

Expand Down
2 changes: 1 addition & 1 deletion loader/src/platform/mac/crashlog.mm
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
void CrashContext::writeInfo(Buffer& stream) {
auto image = this->imageFromAddress(crashAddr);
stream.append("Faulty Lib: {}\n", image ? image->name() : "<Unknown>");
stream.append("Faulty Mod: {}\n", faultyMod ? faultyMod->getID() : "<Unknown>");
stream.append("Faulty Mod: {} ({})\n", faultyMod ? faultyMod->getID() : "<Unknown>", faultyMod ? faultyMod->getHash() : "N/A");
stream.append("Instruction Address: ");
this->formatAddress(crashAddr, infoStream);

Expand Down
2 changes: 1 addition & 1 deletion loader/src/platform/windows/crashlog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ void CrashContext::writeInfo(Buffer& stream) {
auto makeFaultyModString = [](Mod* mod) -> std::string {
if (!mod) return "Faulty Mod: <Unknown>";

return fmt::format("Faulty Mod: {} {} ({})", mod->getName(), mod->getVersion().toVString(), mod->getID());
return fmt::format("Faulty Mod: {} {} ({}, {})", mod->getName(), mod->getVersion().toVString(), mod->getID(), mod->getHash());
};

if (code == EXCEPTION_NUMBER) {
Expand Down
Loading