Skip to content
Merged
1 change: 1 addition & 0 deletions include/Chroma.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ inline static constexpr const std::string_view STEP = "step";
inline static constexpr const std::string_view RING_ROTATION = "rotation";

inline static constexpr const std::string_view ENVIRONMENT = "environment";

inline static constexpr const std::string_view GAMEOBJECT_ID = "id";
inline static constexpr const std::string_view GEOMETRY = "geometry";
inline static constexpr const std::string_view MATERIAL = "material";
Expand Down
25 changes: 18 additions & 7 deletions include/ChromaEvents.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ struct AnimateComponentEventData {
};

AnimateComponentEventData(AnimateComponentEventData&&) = default;
AnimateComponentEventData(AnimateComponentEventData const&) = delete;

[[deprecated("Copy invoked")]]
AnimateComponentEventData(AnimateComponentEventData const&) = default;
~AnimateComponentEventData() = default;
AnimateComponentEventData() = default;
AnimateComponentEventData(float duration, Functions easing, TracksAD::TracksVector track,
Expand All @@ -48,18 +50,27 @@ struct CustomEventAssociatedData {
bool parsed = false;

CustomEventAssociatedData() : data(nullptr) {};
};

static std::unordered_map<CustomJSONData::CustomEventData const*, CustomEventAssociatedData> eventDataMap;
AssignBloomFogTrack* getAssignBloomFogTrack() {
return std::get_if<AssignBloomFogTrack>(&data);
}

AnimateComponentEventData* getAnimateComponentEventData() {
return std::get_if<AnimateComponentEventData>(&data);
}
};

static CustomEventAssociatedData& getEventAD(CustomJSONData::CustomEventData const* customData) {
return eventDataMap[customData];
static CustomEventAssociatedData& getEventAD(CustomJSONData::CustomEventData const* customEvent) {
auto& ad = customEvent->customData->associatedData['C'];
if (!ad.has_value()) {
ad = std::make_any<ChromaEvents::CustomEventAssociatedData>();
}
return std::any_cast<ChromaEvents::CustomEventAssociatedData&>(ad);
}

void deserialize(CustomJSONData::CustomBeatmapData* readOnlyBeatmap);

void parseEventData(TracksAD::BeatmapAssociatedData& beatmapAD, CustomJSONData::CustomEventData const* customEventData,
bool v2);
void parseEventData(TracksAD::BeatmapAssociatedData& beatmapAD, CustomJSONData::CustomEventData const* customEventData, bool v2);

void AddEventCallbacks();
} // namespace ChromaEvents
28 changes: 20 additions & 8 deletions include/ChromaObjectData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,21 @@ class BeatmapObjectData;

namespace CustomJSONData {
class CustomBeatmapData;
class CustomNoteData;
class CustomObstacleData;
class CustomSliderData;
}

// Third-party includes
#include "tracks/shared/Animation/Track.h"
#include "tracks/shared/Animation/PointDefinition.h"
#include "sombrero/shared/ColorUtils.hpp"

#include "custom-json-data/shared/JSONWrapper.h"

namespace Chroma {

class ChromaObjectData {
private:
ChromaObjectData(ChromaObjectData const&) = default;
friend class std::unordered_map<GlobalNamespace::BeatmapObjectData*, ChromaObjectData>;
friend class std::pair<GlobalNamespace::BeatmapObjectData* const, Chroma::ChromaObjectData>;

public:
std::optional<Sombrero::FastColor> Color;
std::span<TrackW const> Tracks; // probably a bad idea, this could be freed.
Expand All @@ -37,14 +37,26 @@ class ChromaObjectData {

ChromaObjectData() = default;
ChromaObjectData(ChromaObjectData&&) = default;

[[deprecated("Copy invoked")]]
ChromaObjectData(ChromaObjectData const&) = default;

ChromaObjectData& operator=(ChromaObjectData&&) noexcept = default;
ChromaObjectData& operator=(ChromaObjectData const&) = default;
};

class ChromaObjectDataManager {
public:
using ChromaObjectDataType = std::unordered_map<GlobalNamespace::BeatmapObjectData*, ChromaObjectData>;
inline static ChromaObjectDataType ChromaObjectDatas;

static void deserialize(CustomJSONData::CustomBeatmapData* beatmapData);
};

static ChromaObjectData& getObjectAD(CustomJSONData::JSONWrapper* customData) {
auto& ad = customData->associatedData['C'];
if (!ad.has_value()) ad = std::make_any<Chroma::ChromaObjectData>();
return std::any_cast<Chroma::ChromaObjectData&>(ad);
}

// defined in ChromaObjectData.cpp to avoid include bloat
ChromaObjectData* getObjectAD(GlobalNamespace::BeatmapObjectData* obj);

} // namespace Chroma
33 changes: 24 additions & 9 deletions include/lighting/ChromaEventData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "tracks/shared/Animation/Easings.h"

#include <functional>
#include <unordered_map>

#include "sombrero/shared/ColorUtils.hpp"
Expand All @@ -14,17 +15,18 @@
namespace GlobalNamespace {
class BasicBeatmapEventData;
class BeatmapObjectSpawnController;
};
}; // namespace GlobalNamespace

namespace Chroma {
class ChromaEventData {
private:
ChromaEventData(ChromaEventData const&) = default;
friend class std::unordered_map<GlobalNamespace::BeatmapEventData*, ChromaEventData>;
friend class std::pair<GlobalNamespace::BeatmapEventData* const, Chroma::ChromaEventData>;

public:
ChromaEventData() = default;
[[deprecated("Copy invoked")]]
ChromaEventData(ChromaEventData const&) = default;
ChromaEventData(ChromaEventData&&) = default;

ChromaEventData& operator=(ChromaEventData&&) noexcept = default;
ChromaEventData& operator=(ChromaEventData const&) = default;

std::optional<Functions> Easing;

Expand Down Expand Up @@ -81,10 +83,23 @@ class ChromaEventData {

class ChromaEventDataManager {
public:
using EventMapType = std::unordered_map<GlobalNamespace::BeatmapEventData*, ChromaEventData>;
inline static EventMapType ChromaEventDatas;

static void deserialize(CustomJSONData::CustomBeatmapData* beatmapData);
};

constexpr ChromaEventData& getLightAD(CustomJSONData::JSONWrapper* customData) {
auto& ad = customData->associatedData['C'];
if (!ad.has_value()) {
ad = std::make_any<Chroma::ChromaEventData>();
}
return std::any_cast<Chroma::ChromaEventData&>(ad);
}

constexpr ChromaEventData* getLightAD(GlobalNamespace::BeatmapEventData* beatmap) {
auto customBeatmapEvent = il2cpp_utils::try_cast<CustomJSONData::CustomBeatmapEventData>(beatmap);
if (!customBeatmapEvent) {
return nullptr;
}
return &getLightAD(customBeatmapEvent.value()->customData);
}

} // namespace Chroma
94 changes: 41 additions & 53 deletions src/ChromaEvents.cpp
Original file line number Diff line number Diff line change
@@ -1,37 +1,32 @@
#include <algorithm>
#include <utility>


#include "ChromaEvents.hpp"
#include "Chroma.hpp"
#include "ChromaLogger.hpp"
#include "lighting/ChromaFogController.hpp"
#include "ChromaComponentManager.hpp"


#include "GlobalNamespace/BeatmapData.hpp"
#include "GlobalNamespace/BeatmapCallbacksController.hpp"


#include "custom-json-data/shared/CustomBeatmapData.h"
#include "custom-json-data/shared/CustomEventData.h"
#include "tracks/shared/TimeSourceHelper.h"
#include "tracks/shared/Vector.h"
#include "tracks/shared/Json.h"



using namespace GlobalNamespace;
using namespace NEVector;

void ChromaEvents::parseEventData(TracksAD::BeatmapAssociatedData& beatmapAD,
CustomJSONData::CustomEventData const* customEventData, bool v2) {
void ChromaEvents::parseEventData(TracksAD::BeatmapAssociatedData& beatmapAD, CustomJSONData::CustomEventData const* customEventData,
bool v2) {
bool isType = false;

auto typeHash = customEventData->typeHash;

#define TYPE_GET(jsonName, varName) \
static auto jsonNameHash_##varName = std::hash<std::string_view>()(jsonName); \
#define TYPE_GET(jsonName, varName) \
static auto jsonNameHash_##varName = std::hash<std::string_view>()(jsonName); \
if (!isType && typeHash == (jsonNameHash_##varName)) isType = true;

TYPE_GET(Chroma::OldConstants::ASSIGNFOGTRACK, ASSIGNFOGTRACK)
Expand All @@ -41,25 +36,22 @@ void ChromaEvents::parseEventData(TracksAD::BeatmapAssociatedData& beatmapAD,
return;
}

if (!customEventData->customData || !customEventData->customData->value) {
return;
}

rapidjson::Value const& eventData = *customEventData->customData->value;
auto& eventAD = getEventAD(customEventData);

if (eventAD.parsed) {
return;
}

if (!customEventData->customData || !customEventData->customData->value) {
return;
}
eventAD.parsed = true;

rapidjson::Value const& eventData = *customEventData->customData->value;

if (typeHash == jsonNameHash_ASSIGNFOGTRACK) {
auto trackIt = eventData.FindMember((v2 ? Chroma::NewConstants::V2_TRACK : Chroma::NewConstants::TRACK).data());

if (trackIt == eventData.MemberEnd() || trackIt->value.IsNull() || !trackIt->value.IsString()) {
ChromaLogger::Logger.debug("Track data is missing for Chroma custom event {}",
customEventData->____time_k__BackingField);
ChromaLogger::Logger.debug("Track data is missing for Chroma custom event {}", customEventData->____time_k__BackingField);
return;
}

Expand All @@ -73,20 +65,18 @@ void ChromaEvents::parseEventData(TracksAD::BeatmapAssociatedData& beatmapAD,
auto trackIt = eventData.FindMember((v2 ? Chroma::NewConstants::V2_TRACK : Chroma::NewConstants::TRACK).data());

if (trackIt == eventData.MemberEnd() || trackIt->value.IsNull() || !trackIt->value.IsString()) {
ChromaLogger::Logger.debug("Track data is missing for Chroma custom event {}",
customEventData->____time_k__BackingField);
ChromaLogger::Logger.debug("Track data is missing for Chroma custom event {}", customEventData->____time_k__BackingField);
return;
}

float const duration = NEJSON::ReadOptionalFloat(eventData, Chroma::NewConstants::DURATION.data()).value_or(0);

auto easing = static_cast<Functions>(NEJSON::ReadOptionalInt(eventData, Chroma::NewConstants::EASING.data())
.value_or(static_cast<int>(Functions::EaseLinear)));
auto easing = static_cast<Functions>(
NEJSON::ReadOptionalInt(eventData, Chroma::NewConstants::EASING.data()).value_or(static_cast<int>(Functions::EaseLinear)));

auto tracks = NEJSON::ReadOptionalTracks(eventData, Chroma::NewConstants::TRACK, beatmapAD).value();

auto const availableNames = { Chroma::NewConstants::BLOOM_FOG_ENVIRONMENT,
Chroma::NewConstants::TUBE_BLOOM_PRE_PASS_LIGHT };
auto const availableNames = { Chroma::NewConstants::BLOOM_FOG_ENVIRONMENT, Chroma::NewConstants::TUBE_BLOOM_PRE_PASS_LIGHT };
std::unordered_map<std::string_view, std::vector<AnimateComponentEventData::ComponentData>> coroutineInfos;

// eventData -> {
Expand Down Expand Up @@ -150,43 +140,41 @@ void ChromaEvents::deserialize(CustomJSONData::CustomBeatmapData* readOnlyBeatma
}
}

void CustomEventCallback(BeatmapCallbacksController* callbackController,
CustomJSONData::CustomEventData* customEventData) {
PAPER_IL2CPP_CATCH_HANDLER(
bool isType = false;
void CustomEventCallback(BeatmapCallbacksController* callbackController, CustomJSONData::CustomEventData* customEventData) {

auto typeHash = customEventData->typeHash;
bool isType = false;

#define TYPE_GET(jsonName, varName) \
static auto jsonNameHash_##varName = std::hash<std::string_view>()(jsonName); \
if (!isType && typeHash == (jsonNameHash_##varName)) isType = true;
auto typeHash = customEventData->typeHash;

TYPE_GET(Chroma::OldConstants::ASSIGNFOGTRACK, ASSIGNFOGTRACK)
TYPE_GET(Chroma::NewConstants::ANIMATE_COMPONENT, ANIMATE_COMPONENT)
#define TYPE_GET(jsonName, varName) \
static auto jsonNameHash_##varName = std::hash<std::string_view>()(jsonName); \
if (!isType && typeHash == (jsonNameHash_##varName)) isType = true;

if (!isType) { return; }
TYPE_GET(Chroma::OldConstants::ASSIGNFOGTRACK, ASSIGNFOGTRACK)
TYPE_GET(Chroma::NewConstants::ANIMATE_COMPONENT, ANIMATE_COMPONENT)

auto const& ad = ChromaEvents::getEventAD(customEventData);
if (!isType) {
return;
}

// fail safe, idek why this needs to be done smh
// CJD you bugger
auto* customBeatmapData = il2cpp_utils::cast<CustomJSONData::CustomBeatmapData>(callbackController->_beatmapData);
if (!ad.parsed) {
TracksAD::BeatmapAssociatedData& beatmapAD = TracksAD::getBeatmapAD(customBeatmapData->customData);
ChromaEvents::parseEventData(beatmapAD, customEventData, customBeatmapData->v2orEarlier);
}
auto const& ad = ChromaEvents::getEventAD(customEventData);

if (typeHash == jsonNameHash_ASSIGNFOGTRACK) {
Chroma::ChromaFogController::getInstance()->AssignTrack(
std::get<ChromaEvents::AssignBloomFogTrack>(ad.data).track);
CJDLogger::Logger.fmtLog<Paper::LogLevel::INF>("Assigned fog controller to track");
} if (typeHash == jsonNameHash_ANIMATE_COMPONENT && !customBeatmapData->v2orEarlier) {
CJDLogger::Logger.fmtLog<Paper::LogLevel::INF>("Animated component");
Chroma::Component::StartEvent(callbackController, customEventData,
std::get<ChromaEvents::AnimateComponentEventData>(ad.data));
}
// fail safe, idek why this needs to be done smh
// CJD you bugger
auto* customBeatmapData = il2cpp_utils::cast<CustomJSONData::CustomBeatmapData>(callbackController->_beatmapData);
if (!ad.parsed) {
TracksAD::BeatmapAssociatedData& beatmapAD = TracksAD::getBeatmapAD(customBeatmapData->customData);
ChromaEvents::parseEventData(beatmapAD, customEventData, customBeatmapData->v2orEarlier);
}

)
if (typeHash == jsonNameHash_ASSIGNFOGTRACK) {
Chroma::ChromaFogController::getInstance()->AssignTrack(std::get<ChromaEvents::AssignBloomFogTrack>(ad.data).track);
CJDLogger::Logger.fmtLog<Paper::LogLevel::INF>("Assigned fog controller to track");
}
if (typeHash == jsonNameHash_ANIMATE_COMPONENT && !customBeatmapData->v2orEarlier) {
CJDLogger::Logger.fmtLog<Paper::LogLevel::INF>("Animated component");
Chroma::Component::StartEvent(callbackController, customEventData, std::get<ChromaEvents::AnimateComponentEventData>(ad.data));
}
}

void ChromaEvents::AddEventCallbacks() {
Expand Down
36 changes: 15 additions & 21 deletions src/ChromaObjectData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ using namespace ChromaUtils;
using namespace GlobalNamespace;

void Chroma::ChromaObjectDataManager::deserialize(CustomJSONData::CustomBeatmapData* beatmapData) {
ChromaObjectDatas.clear();

auto* beatmapDataCast = beatmapData;
bool v2 = beatmapDataCast->v2orEarlier;

Expand Down Expand Up @@ -79,24 +77,6 @@ void Chroma::ChromaObjectDataManager::deserialize(CustomJSONData::CustomBeatmapD
objectDynData = customObstacleData->customData;
chromaObjectData.Color = ChromaUtilities::GetColorFromData(objectDynData->value, v2);
}
// else if (false && ASSIGNMENT_CHECK(CustomWaypointDataKlass,beatmapObjectData->klass)) {
// debugSpamLog("Custom waypoint");
// auto *customBeatmapEvent =
// il2cpp_utils::cast<CustomJSONData::CustomWaypointData>(beatmapObjectData);
//
// // TODO: uncomment when CJD adds customData
// // bool isCustomData = customBeatmapEvent->customData && customBeatmapEvent->customData->value
// &&
// // customBeatmapEvent->customData->value->IsObject();
// // dynData = isCustomData ? customBeatmapEvent->customData->value : nullptr;
//
// auto data = std::make_shared<ChromaObjectData>();
//
// data->Color = std::nullopt;
//
//
// chromaObjectData = data;
// }
else {
continue;
}
Expand All @@ -116,6 +96,20 @@ void Chroma::ChromaObjectDataManager::deserialize(CustomJSONData::CustomBeatmapD
auto const& tracks = TracksAD::getAD(objectDynData).tracks;
chromaObjectData.Tracks = tracks;

ChromaObjectDatas.try_emplace(beatmapObjectData, chromaObjectData);
getObjectAD(objectDynData) = std::move(chromaObjectData);
}
}

Chroma::ChromaObjectData* Chroma::getObjectAD(GlobalNamespace::BeatmapObjectData* obj) {
if (auto note = il2cpp_utils::try_cast<CustomJSONData::CustomNoteData>(obj)) {
return &getObjectAD(note.value()->customData);
}
if (auto obstacle = il2cpp_utils::try_cast<CustomJSONData::CustomObstacleData>(obj)) {
return &getObjectAD(obstacle.value()->customData);
}
if (auto slider = il2cpp_utils::try_cast<CustomJSONData::CustomSliderData>(obj)) {
return &getObjectAD(slider.value()->customData);
}

return nullptr;
}
Loading
Loading