From 303abf57aa86c9370939a7b9805b44819121d388 Mon Sep 17 00:00:00 2001 From: CatsaCode Date: Sun, 19 Apr 2026 20:52:14 -0400 Subject: [PATCH 1/4] Fix Standard to Glowing override logic --- src/environment_enhancements/MaterialsManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/environment_enhancements/MaterialsManager.cpp b/src/environment_enhancements/MaterialsManager.cpp index 8b5fe23..ac7ee41 100644 --- a/src/environment_enhancements/MaterialsManager.cpp +++ b/src/environment_enhancements/MaterialsManager.cpp @@ -190,7 +190,7 @@ MaterialInfo Chroma::MaterialsManager::CreateMaterialInfo(rapidjson::Value const // stupid janky fix to the fact that they changed simplelit shader in 1.38 - if (shaderType == ShaderType::Standard || shaderType == ShaderType::BTSPillar && (!shaderKeywords || shaderKeywords.size() == 0)) { + if ((shaderType == ShaderType::Standard || shaderType == ShaderType::BTSPillar) && (shaderKeywords && shaderKeywords.size() == 0)) { shaderKeywords = ArrayW(nullptr); From 17a8d783323b2b65b3f6bb8049f41b71f3528b0a Mon Sep 17 00:00:00 2001 From: CatsaCode Date: Mon, 20 Apr 2026 23:27:31 -0400 Subject: [PATCH 2/4] Fix lightWithIds initialization --- .../ComponentInitializer.cpp | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/environment_enhancements/ComponentInitializer.cpp b/src/environment_enhancements/ComponentInitializer.cpp index aaf0099..1073f29 100644 --- a/src/environment_enhancements/ComponentInitializer.cpp +++ b/src/environment_enhancements/ComponentInitializer.cpp @@ -32,6 +32,7 @@ #include "UnityEngine/Material.hpp" #include "System/Collections/Generic/List_1.hpp" +#include "System/Array.hpp" #include "Zenject/DiContainer.hpp" @@ -48,6 +49,8 @@ #include "sombrero/shared/linq_functional.hpp" +#include "beatsaber-hook/shared/utils/il2cpp-utils-boxing.hpp" + using namespace GlobalNamespace; using namespace Chroma; using namespace Sombrero::Linq::Functional; @@ -76,12 +79,13 @@ GameObjectInfo const& Chroma::ComponentInitializer::InitializeComponents(UnityEn if (auto lightsWithIds = il2cpp_utils::try_cast(rootComp)) { if (lightsWithIds.value()->lightWithIds) { - auto* enumerator = lightsWithIds.value()->lightWithIds->GetEnumerator(); - while (enumerator->i___System__Collections__IEnumerator()->MoveNext()) { - auto* light = enumerator->get_Current(); - LightIdRegisterer::MarkForTableRegister(light->i___GlobalNamespace__ILightWithId()); + auto enumerator = il2cpp_utils::Unbox>( + reinterpret_cast(lightsWithIds.value()->lightWithIds->GetEnumerator())); + while (enumerator.MoveNext()) { + auto* light = enumerator.get_Current(); + LightIdRegisterer::MarkForTableRegister(light); } - enumerator->i___System__IDisposable()->Dispose(); + enumerator.Dispose(); } } @@ -357,18 +361,19 @@ static void InitializeLights(rapidjson::Value const& data, std::spanlightWithIds->GetEnumerator(); + auto enumerator = il2cpp_utils::Unbox>( + reinterpret_cast(castedLights.value()->lightWithIds->GetEnumerator())); // MEMORY LEAK YAY // TODO: Fix // auto dispose = bs_hook::Disposable(enumerator->i_IDisposable()); - while (enumerator->i___System__Collections__IEnumerator()->MoveNext()) { - auto* e = enumerator->get_Current(); - lightWithIds.emplace_back(e->i___GlobalNamespace__ILightWithId()); + while (enumerator.MoveNext()) { + auto* e = enumerator.get_Current(); + lightWithIds.emplace_back(e); } - enumerator->i___System__IDisposable()->Dispose(); + enumerator.Dispose(); } else if (auto castedMonoLight = il2cpp_utils::try_cast(comp)) { lightWithIds.emplace_back(castedMonoLight.value()->i___GlobalNamespace__ILightWithId()); } From 19be9082cdcafedc3980e04a4151682baa233006 Mon Sep 17 00:00:00 2001 From: CatsaCode Date: Thu, 23 Apr 2026 02:22:25 -0400 Subject: [PATCH 3/4] Fix registration of geometry lightIDs and type Ensure that `LightColorizer`s are created before `InitializeLights` attempts to set the light type. A missing type would result in the `LightWithIdManager::RegisterLight` hook failing to find the requested lightID. `ChromaLightSwitchEventEffect::HandleEvent` would then be unable to find the `ILightWithId` associated with the custom lightID. --- .../colorizer/LightSwitchEventEffect.cpp | 25 ++----------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/src/hooks/colorizer/LightSwitchEventEffect.cpp b/src/hooks/colorizer/LightSwitchEventEffect.cpp index f5b7b82..ad7dac8 100644 --- a/src/hooks/colorizer/LightSwitchEventEffect.cpp +++ b/src/hooks/colorizer/LightSwitchEventEffect.cpp @@ -3,20 +3,11 @@ #include "colorizer/LightColorizer.hpp" -#include -#include -#include "custom-json-data/shared/CustomBeatmapData.h" -#include "System/Collections/IEnumerator.hpp" -#include "custom-types/shared/coroutine.hpp" -#include "UnityEngine/Color.hpp" -#include "UnityEngine/WaitForEndOfFrame.hpp" -#include "GlobalNamespace/ILightWithId.hpp" #include "GlobalNamespace/BeatmapCallbacksController.hpp" #include "GlobalNamespace/CallbacksInTime.hpp" #include "System/Collections/Generic/Dictionary_2.hpp" #include "UnityEngine/GameObject.hpp" #include "hooks/LightSwitchEventEffect.hpp" -#include "lighting/LightIDTableManager.hpp" using namespace CustomJSONData; using namespace Chroma; @@ -27,17 +18,6 @@ using namespace custom_types::Helpers; BeatmapCallbacksController* beatmapCallbacksController; -custom_types::Helpers::Coroutine WaitThenStartLight(LightSwitchEventEffect* instance, BasicBeatmapEventType eventType) { - co_yield reinterpret_cast(CRASH_UNLESS(WaitForEndOfFrame::New_ctor())); - - auto* newEffect = instance->get_gameObject()->AddComponent(); - newEffect->CopyValues(instance); - - IL2CPP_CATCH_HANDLER(Object::Destroy(instance);) - - co_return; -} - MAKE_HOOK_MATCH(LightSwitchEventEffect_Start, &LightSwitchEventEffect::Start, void, LightSwitchEventEffect* self) { static auto* ChromaLightSwitchEventEffectKlass = classof(ChromaLightSwitchEventEffect*); @@ -51,9 +31,8 @@ MAKE_HOOK_MATCH(LightSwitchEventEffect_Start, &LightSwitchEventEffect::Start, vo return; } - auto coro = custom_types::Helpers::CoroutineHelper::New(WaitThenStartLight(self, self->_event)); - - self->StartCoroutine(coro); + auto* newEffect = self->get_gameObject()->AddComponent(); + newEffect->CopyValues(self); } MAKE_HOOK_MATCH(BeatmapCallbacksController_ManualUpdate, &BeatmapCallbacksController::ManualUpdate, void, From d902f64c39ce9a08f7799d2d24b8b241c2bcacdb Mon Sep 17 00:00:00 2001 From: CatsaCode Date: Sat, 25 Apr 2026 09:47:52 -0400 Subject: [PATCH 4/4] Add TODO --- src/environment_enhancements/ComponentInitializer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/environment_enhancements/ComponentInitializer.cpp b/src/environment_enhancements/ComponentInitializer.cpp index 1073f29..6549a4f 100644 --- a/src/environment_enhancements/ComponentInitializer.cpp +++ b/src/environment_enhancements/ComponentInitializer.cpp @@ -361,6 +361,7 @@ static void InitializeLights(rapidjson::Value const& data, std::span>( reinterpret_cast(castedLights.value()->lightWithIds->GetEnumerator()));