From 1c86f8ced474c41131eeb0a88b6d532f8cbdeefa Mon Sep 17 00:00:00 2001 From: CatsaCode Date: Tue, 30 Sep 2025 21:37:56 -0400 Subject: [PATCH 1/7] Bump for 1.40.8 --- mod.template.json | 2 +- qpm.json | 10 ++-- qpm.shared.json | 130 +++++++++++++++++++++++----------------------- 3 files changed, 71 insertions(+), 71 deletions(-) diff --git a/mod.template.json b/mod.template.json index 22f2c38..df5bdc8 100644 --- a/mod.template.json +++ b/mod.template.json @@ -6,7 +6,7 @@ "author": "StackDoubleFlow, Fernthedev", "version": "${version}", "packageId": "com.beatgames.beatsaber", - "packageVersion": "1.40.7_7060", + "packageVersion": "1.40.8_7379", "description": "Funny maps go brrr", "dependencies": [], "modFiles": [], diff --git a/qpm.json b/qpm.json index 66d6d88..87b8fbc 100644 --- a/qpm.json +++ b/qpm.json @@ -6,7 +6,7 @@ "info": { "name": "CustomJSONData", "id": "custom-json-data", - "version": "0.24.3", + "version": "0.24.4", "url": "https://github.com/StackDoubleFlow/CustomJSONData", "additionalData": { "overrideSoName": "libcustom-json-data.so", @@ -36,7 +36,7 @@ "pwsh ./scripts/ndk-stack.ps1" ] }, - "ndk": "^27.2.12479018", + "ndk": "^27.3.13750724", "qmodIncludeDirs": [ "./build", "./extern/libs" @@ -52,19 +52,19 @@ }, { "id": "bs-cordl", - "versionRange": "4007.*", + "versionRange": "4008.*", "additionalData": {} }, { "id": "custom-types", - "versionRange": "^0.18.3", + "versionRange": "^0.18.4", "additionalData": { "includeQmod": true } }, { "id": "songcore", - "versionRange": "^1.1.23", + "versionRange": "^1.1.25", "additionalData": { "includeQmod": true, "private": true diff --git a/qpm.shared.json b/qpm.shared.json index 6429666..03287c0 100644 --- a/qpm.shared.json +++ b/qpm.shared.json @@ -1,5 +1,4 @@ { - "$schema": "https://raw.githubusercontent.com/QuestPackageManager/QPM.Package/refs/heads/main/qpm.shared.schema.json", "config": { "version": "0.4.0", "sharedDir": "shared", @@ -7,7 +6,7 @@ "info": { "name": "CustomJSONData", "id": "custom-json-data", - "version": "0.24.3", + "version": "0.24.4", "url": "https://github.com/StackDoubleFlow/CustomJSONData", "additionalData": { "overrideSoName": "libcustom-json-data.so", @@ -37,6 +36,7 @@ "pwsh ./scripts/ndk-stack.ps1" ] }, + "ndk": "^27.3.13750724", "qmodIncludeDirs": [ "./build", "./extern/libs" @@ -52,7 +52,7 @@ }, { "id": "bs-cordl", - "versionRange": "4007.*", + "versionRange": "4008.*", "additionalData": {} }, { @@ -64,7 +64,7 @@ }, { "id": "songcore", - "versionRange": "^1.1.23", + "versionRange": "^1.1.25", "additionalData": { "includeQmod": true, "private": true @@ -99,16 +99,51 @@ ] }, "restoredDependencies": [ + { + "dependency": { + "id": "paper2_scotland2", + "versionRange": "=4.7.0", + "additionalData": { + "soLink": "https://github.com/Fernthedev/paperlog/releases/download/v4.7.0/libpaper2_scotland2.so", + "overrideSoName": "libpaper2_scotland2.so", + "modLink": "https://github.com/Fernthedev/paperlog/releases/download/v4.7.0/paper2_scotland2.qmod", + "branchName": "version/v4_7_0", + "compileOptions": { + "systemIncludes": [ + "shared/utfcpp/source" + ] + }, + "cmake": false + } + }, + "version": "4.7.0" + }, + { + "dependency": { + "id": "libil2cpp", + "versionRange": "=0.4.0", + "additionalData": { + "headersOnly": true, + "compileOptions": { + "systemIncludes": [ + "il2cpp/external/baselib/Include", + "il2cpp/external/baselib/Platforms/Android/Include" + ] + } + } + }, + "version": "0.4.0" + }, { "dependency": { "id": "custom-types", - "versionRange": "=0.18.3", + "versionRange": "=0.18.4", "additionalData": { - "soLink": "https://github.com/QuestPackageManager/Il2CppQuestTypePatching/releases/download/v0.18.3/libcustom-types.so", - "debugSoLink": "https://github.com/QuestPackageManager/Il2CppQuestTypePatching/releases/download/v0.18.3/debug_libcustom-types.so", + "soLink": "https://github.com/QuestPackageManager/Il2CppQuestTypePatching/releases/download/v0.18.4/libcustom-types.so", + "debugSoLink": "https://github.com/QuestPackageManager/Il2CppQuestTypePatching/releases/download/v0.18.4/debug_libcustom-types.so", "overrideSoName": "libcustom-types.so", - "modLink": "https://github.com/QuestPackageManager/Il2CppQuestTypePatching/releases/download/v0.18.3/CustomTypes.qmod", - "branchName": "version/v0_18_3", + "modLink": "https://github.com/QuestPackageManager/Il2CppQuestTypePatching/releases/download/v0.18.4/CustomTypes.qmod", + "branchName": "version/v0_18_4", "compileOptions": { "cppFlags": [ "-Wno-invalid-offsetof" @@ -117,7 +152,7 @@ "cmake": true } }, - "version": "0.18.3" + "version": "0.18.4" }, { "dependency": { @@ -133,10 +168,10 @@ { "dependency": { "id": "bs-cordl", - "versionRange": "=4007.0.0", + "versionRange": "=4008.0.0", "additionalData": { "headersOnly": true, - "branchName": "version/v4007_0_0", + "branchName": "version/v4008_0_0", "compileOptions": { "includePaths": [ "include" @@ -152,26 +187,7 @@ } } }, - "version": "4007.0.0" - }, - { - "dependency": { - "id": "paper2_scotland2", - "versionRange": "=4.6.4", - "additionalData": { - "soLink": "https://github.com/Fernthedev/paperlog/releases/download/v4.6.4/libpaper2_scotland2.so", - "overrideSoName": "libpaper2_scotland2.so", - "modLink": "https://github.com/Fernthedev/paperlog/releases/download/v4.6.4/paper2_scotland2.qmod", - "branchName": "version/v4_6_4", - "compileOptions": { - "systemIncludes": [ - "shared/utfcpp/source" - ] - }, - "cmake": false - } - }, - "version": "4.6.4" + "version": "4008.0.0" }, { "dependency": { @@ -186,22 +202,18 @@ }, { "dependency": { - "id": "fmt", - "versionRange": "=11.0.2", + "id": "songcore", + "versionRange": "=1.1.25", "additionalData": { - "headersOnly": true, - "branchName": "version/v11_0_2", - "compileOptions": { - "systemIncludes": [ - "fmt/include/" - ], - "cppFlags": [ - "-DFMT_HEADER_ONLY" - ] - } + "soLink": "https://github.com/raineaeternal/Quest-SongCore/releases/download/v1.1.25/libsongcore.so", + "debugSoLink": "https://github.com/raineaeternal/Quest-SongCore/releases/download/v1.1.25/debug_libsongcore.so", + "overrideSoName": "libsongcore.so", + "modLink": "https://github.com/raineaeternal/Quest-SongCore/releases/download/v1.1.25/SongCore.qmod", + "branchName": "version/v1_1_25", + "cmake": true } }, - "version": "11.0.2" + "version": "1.1.25" }, { "dependency": { @@ -223,21 +235,6 @@ }, "version": "6.4.2" }, - { - "dependency": { - "id": "songcore", - "versionRange": "=1.1.23", - "additionalData": { - "soLink": "https://github.com/raineaeternal/Quest-SongCore/releases/download/v1.1.23/libsongcore.so", - "debugSoLink": "https://github.com/raineaeternal/Quest-SongCore/releases/download/v1.1.23/debug_libsongcore.so", - "overrideSoName": "libsongcore.so", - "modLink": "https://github.com/raineaeternal/Quest-SongCore/releases/download/v1.1.23/SongCore.qmod", - "branchName": "version/v1_1_23", - "cmake": true - } - }, - "version": "1.1.23" - }, { "dependency": { "id": "scotland2", @@ -253,19 +250,22 @@ }, { "dependency": { - "id": "libil2cpp", - "versionRange": "=0.4.0", + "id": "fmt", + "versionRange": "=11.0.2", "additionalData": { "headersOnly": true, + "branchName": "version/v11_0_2", "compileOptions": { "systemIncludes": [ - "il2cpp/external/baselib/Include", - "il2cpp/external/baselib/Platforms/Android/Include" + "fmt/include/" + ], + "cppFlags": [ + "-DFMT_HEADER_ONLY" ] } } }, - "version": "0.4.0" + "version": "11.0.2" } ] } \ No newline at end of file From 5a0fdd9e71e36547a4c261e24636999f0316b83c Mon Sep 17 00:00:00 2001 From: Futuremapper <54294576+Futuremappermydud@users.noreply.github.com> Date: Mon, 8 Dec 2025 18:34:47 -0500 Subject: [PATCH 2/7] Fix optional pair parsing "coordinates": [4, null] would crash before, now it provides std::nullopt --- shared/JsonUtils.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/shared/JsonUtils.h b/shared/JsonUtils.h index a829585..e11a5f0 100644 --- a/shared/JsonUtils.h +++ b/shared/JsonUtils.h @@ -98,14 +98,16 @@ static OptPair ReadOptionalPair(rapidjson::Value const& object, std::string_view auto itr = object.FindMember(key.data()); if (itr != object.MemberEnd() && itr->value.Size() >= 1) { - float x = itr->value[0].GetFloat(); - float y = 0; + const auto& val = itr->value[0]; + std::optional x = val.IsNull() ? std::nullopt : std::optional{ val.GetFloat() }; + std::optional y = 0; if (itr->value.Size() >= 2) { - y = itr->value[1].GetFloat(); - return { std::optional(x), std::optional(y) }; + const auto& val2 = itr->value[1]; + y = val2.IsNull() ? std::nullopt : std::optional{ val2.GetFloat() }; + return { x, y }; } - return { std::optional(x), std::nullopt }; + return { x, std::nullopt }; } return { std::nullopt, std::nullopt }; } From 2c9d97ea705549caa0965c8edbcfbb19692c6b73 Mon Sep 17 00:00:00 2001 From: CatsaCode Date: Wed, 21 Jan 2026 15:54:32 -0500 Subject: [PATCH 3/7] Fix CustomSliderData Arcs and chains now spawn correctly. --- src/CustomBeatmapData.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/CustomBeatmapData.cpp b/src/CustomBeatmapData.cpp index 6b3bdf3..02b73ce 100644 --- a/src/CustomBeatmapData.cpp +++ b/src/CustomBeatmapData.cpp @@ -206,11 +206,11 @@ void CustomJSONData::CustomSliderData::ctor( ::GlobalNamespace::SliderMidAnchorMode midAnchorMode, int sliceCount, float squishAmount) { static auto const* SliderData_Ctor = il2cpp_utils::FindMethodUnsafe(classof(SliderData*), ".ctor", 24); il2cpp_utils::RunMethodRethrow( - this, SliderData_Ctor, time, beat, rotation, sliderType, colorType, hasHeadNote, headTime, headLineIndex, - headLineLayer, headBeforeJumpLineLayer, headControlPointLengthMultiplier, headCutDirection, - headCutDirectionAngleOffset, hasTailNote, tailTime, tailLineIndex, tailLineLayer, tailBeforeJumpLineLayer, - tailControlPointLengthMultiplier, tailCutDirection, tailCutDirectionAngleOffset, midAnchorMode, sliceCount, - squishAmount); + this, SliderData_Ctor, sliderType, colorType, hasHeadNote, headTime, headBeat, headRotation, + headLineIndex, headLineLayer, headBeforeJumpLineLayer, headControlPointLengthMultiplier, headCutDirection, + headCutDirectionAngleOffset, hasTailNote, tailTime, tailRotation, tailLineIndex, tailLineLayer, + tailBeforeJumpLineLayer, tailControlPointLengthMultiplier, tailCutDirection, tailCutDirectionAngleOffset, + midAnchorMode, sliceCount, squishAmount); INVOKE_CTOR(); this->aheadTimeNoodle = std::numeric_limits::infinity(); } From 5201fa9a5c782138fbb83c1bc476b48324d609cb Mon Sep 17 00:00:00 2001 From: CatsaCode Date: Tue, 27 Jan 2026 20:56:38 -0500 Subject: [PATCH 4/7] Install V4 hooks --- src/hooks/CustomJSONDataHooks.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hooks/CustomJSONDataHooks.cpp b/src/hooks/CustomJSONDataHooks.cpp index f42e24e..832f988 100644 --- a/src/hooks/CustomJSONDataHooks.cpp +++ b/src/hooks/CustomJSONDataHooks.cpp @@ -594,5 +594,6 @@ void CustomJSONData::InstallHooks() { v2::InstallHooks(); v3::InstallHooks(); + v4::InstallHooks(); InstallBeatmapHooks(); } From cfeae7f67b529f62e3f82dca397bdcdd3905a233 Mon Sep 17 00:00:00 2001 From: CatsaCode Date: Tue, 27 Jan 2026 22:02:54 -0500 Subject: [PATCH 5/7] Fix VNJS Variable Note Jump Speed must have been bound to willStartProcessingCallbacksThisFrameEvent. Updated the transpile and now it works. --- src/hooks/CustomJSONDataHooks.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/hooks/CustomJSONDataHooks.cpp b/src/hooks/CustomJSONDataHooks.cpp index 832f988..776f9df 100644 --- a/src/hooks/CustomJSONDataHooks.cpp +++ b/src/hooks/CustomJSONDataHooks.cpp @@ -28,6 +28,7 @@ #include "GlobalNamespace/BeatmapEventDataLightsExtensions.hpp" #include "System/Action.hpp" +#include "System/Action_1.hpp" #include "System/Collections/Generic/Dictionary_2.hpp" #include "UnityEngine/JsonUtility.hpp" @@ -486,6 +487,10 @@ MAKE_PAPER_HOOK_MATCH(BeatmapCallbacksController_ManualUpdateTranspile, &Beatmap return; } + if(self->willStartProcessingCallbacksThisFrameEvent) { + self->willStartProcessingCallbacksThisFrameEvent->Invoke(songTime); + } + self->_songTime = songTime; self->_processingCallbacks = true; if (songTime > self->_prevSongTime) { From f24f74f2871fd9abd2de1e6ddb33891824c7a1a0 Mon Sep 17 00:00:00 2001 From: Fernthedev <15272073+Fernthedev@users.noreply.github.com> Date: Sat, 31 Jan 2026 09:28:33 -0400 Subject: [PATCH 6/7] Use cordl calls to avoid mismatched argument errors --- src/CustomBeatmapData.cpp | 53 ++++++++++----------------------- src/CustomBeatmapSaveDatav2.cpp | 16 ++++------ src/CustomBeatmapSaveDatav3.cpp | 19 ++++-------- src/CustomEventData.cpp | 3 +- 4 files changed, 28 insertions(+), 63 deletions(-) diff --git a/src/CustomBeatmapData.cpp b/src/CustomBeatmapData.cpp index 02b73ce..5daea8a 100644 --- a/src/CustomBeatmapData.cpp +++ b/src/CustomBeatmapData.cpp @@ -21,10 +21,8 @@ DEFINE_TYPE(CustomJSONData, CustomWaypointData); DEFINE_TYPE(CustomJSONData, CustomSliderData); void CustomJSONData::CustomBeatmapData::ctor(int numberOfLines) { - static auto const* ctor = il2cpp_utils::FindMethodUnsafe("", "BeatmapData", ".ctor", 1); - PAPER_IL2CPP_CATCH_HANDLER(il2cpp_utils::RunMethodRethrow(this, ctor, numberOfLines);) - INVOKE_CTOR(); + this->_ctor(numberOfLines); ____beatmapDataItemsPerTypeAndId->_sortedListsDataProcessors->Add(csTypeOf(CustomEventData*), nullptr); // _beatmapDataItemsPerTypeAndId->_items->Add(csTypeOf(CustomEventData*), @@ -36,33 +34,25 @@ void CustomJSONData::CustomBeatmapData::ctor(int numberOfLines) { [[deprecated("to remove")]] void CustomJSONData::CustomBeatmapData::AddBeatmapObjectDataOverride( GlobalNamespace::BeatmapObjectData* beatmapObjectData) { - static auto const* base = il2cpp_utils::FindMethodUnsafe("", "BeatmapData", "AddBeatmapObjectData", 1); - - il2cpp_utils::RunMethodRethrow(this, base, beatmapObjectData); + this->AddBeatmapObjectData(beatmapObjectData); } [[deprecated("To remove")]] void CustomJSONData::CustomBeatmapData::AddBeatmapObjectDataInOrderOverride( GlobalNamespace::BeatmapObjectData* beatmapObjectData) { - static auto const* base = il2cpp_utils::FindMethodUnsafe("", "BeatmapData", "AddBeatmapObjectDataInOrder", 1); - - PAPER_IL2CPP_CATCH_HANDLER(il2cpp_utils::RunMethodRethrow(this, base, beatmapObjectData);) + this->AddBeatmapObjectData(beatmapObjectData); } [[deprecated("to remove")]] void CustomJSONData::CustomBeatmapData::InsertBeatmapEventDataOverride( GlobalNamespace::BeatmapEventData* beatmapObjectData) { - static auto const* base = il2cpp_utils::FindMethodUnsafe("", "BeatmapData", "InsertBeatmapEventData", 1); - - PAPER_IL2CPP_CATCH_HANDLER(il2cpp_utils::RunMethodRethrow(this, base, beatmapObjectData);) + this->InsertBeatmapEventData(beatmapObjectData); } [[deprecated("To remove")]] void CustomJSONData::CustomBeatmapData::InsertBeatmapEventDataInOrderOverride( GlobalNamespace::BeatmapEventData* beatmapEventData) { - static auto const* base = il2cpp_utils::FindMethodUnsafe("", "BeatmapData", "InsertBeatmapEventDataInOrder", 1); - - PAPER_IL2CPP_CATCH_HANDLER(il2cpp_utils::RunMethodRethrow(this, base, beatmapEventData);) + this->InsertBeatmapEventDataInOrder(beatmapEventData); } void CustomJSONData::CustomBeatmapData::InsertCustomEventData(CustomJSONData::CustomEventData* customEventData) { @@ -141,11 +131,8 @@ CustomJSONData::CustomBeatmapData* CustomJSONData::CustomBeatmapData::BaseCopy() void CustomJSONData::CustomBeatmapEventData::ctor(float time, ::GlobalNamespace::BasicBeatmapEventType basicBeatmapEventType, int value, float floatValue) { - static auto const* BeatmapEventData_Ctor = - CRASH_UNLESS(il2cpp_utils::FindMethodUnsafe(classof(BasicBeatmapEventData*), ".ctor", 4)); - il2cpp_utils::RunMethodRethrow(this, BeatmapEventData_Ctor, time, - basicBeatmapEventType, value, floatValue); INVOKE_CTOR(); + this->_ctor(time, basicBeatmapEventType, value, floatValue); this->_time_k__BackingField = time; this->basicBeatmapEventType = basicBeatmapEventType; this->value = value; @@ -172,10 +159,8 @@ CustomJSONData::CustomBeatmapEventData* CustomJSONData::CustomBeatmapEventData:: void CustomJSONData::CustomObstacleData::ctor(float time, float beat, float endBeat, int rotation, int lineIndex, ::GlobalNamespace::NoteLineLayer lineLayer, float duration, int width, int height) { - static auto const* ObstacleData_Ctor = il2cpp_utils::FindMethodUnsafe(classof(ObstacleData*), ".ctor", 9); - il2cpp_utils::RunMethodRethrow(this, ObstacleData_Ctor, time, beat, endBeat, rotation, lineIndex, - lineLayer, duration, width, height); INVOKE_CTOR(); + this->_ctor(time, beat, endBeat, rotation, lineIndex, lineLayer, duration, width, height); this->____executionOrder_k__BackingField = beat; this->____subtypeIdentifier_k__BackingField = rotation; this->aheadTimeNoodle = std::numeric_limits::infinity(); @@ -204,14 +189,12 @@ void CustomJSONData::CustomSliderData::ctor( ::GlobalNamespace::NoteLineLayer tailBeforeJumpLineLayer, float tailControlPointLengthMultiplier, ::GlobalNamespace::NoteCutDirection tailCutDirection, float tailCutDirectionAngleOffset, ::GlobalNamespace::SliderMidAnchorMode midAnchorMode, int sliceCount, float squishAmount) { - static auto const* SliderData_Ctor = il2cpp_utils::FindMethodUnsafe(classof(SliderData*), ".ctor", 24); - il2cpp_utils::RunMethodRethrow( - this, SliderData_Ctor, sliderType, colorType, hasHeadNote, headTime, headBeat, headRotation, - headLineIndex, headLineLayer, headBeforeJumpLineLayer, headControlPointLengthMultiplier, headCutDirection, - headCutDirectionAngleOffset, hasTailNote, tailTime, tailRotation, tailLineIndex, tailLineLayer, - tailBeforeJumpLineLayer, tailControlPointLengthMultiplier, tailCutDirection, tailCutDirectionAngleOffset, - midAnchorMode, sliceCount, squishAmount); INVOKE_CTOR(); + this->_ctor(sliderType, colorType, hasHeadNote, headTime, headBeat, headRotation, headLineIndex, headLineLayer, + headBeforeJumpLineLayer, headControlPointLengthMultiplier, headCutDirection, headCutDirectionAngleOffset, + hasTailNote, tailTime, tailRotation, tailLineIndex, tailLineLayer, tailBeforeJumpLineLayer, + tailControlPointLengthMultiplier, tailCutDirection, tailCutDirectionAngleOffset, midAnchorMode, + sliceCount, squishAmount); this->aheadTimeNoodle = std::numeric_limits::infinity(); } @@ -236,12 +219,10 @@ void CustomJSONData::CustomNoteData::ctor( ::GlobalNamespace::NoteData::ScoringType scoringType, ::GlobalNamespace::ColorType colorType, ::GlobalNamespace::NoteCutDirection cutDirection, float timeToNextColorNote, float timeToPrevColorNote, int flipLineIndex, float flipYSide, float cutDirectionAngleOffset, float cutSfxVolumeMultiplier) { - static auto const* NoteData_Ctor = il2cpp_utils::FindMethodUnsafe(classof(NoteData*), ".ctor", 16); - il2cpp_utils::RunMethodRethrow(this, NoteData_Ctor, time, beat, rotation, lineIndex, noteLineLayer, - beforeJumpNoteLineLayer, gameplayType, scoringType, colorType, - cutDirection, timeToNextColorNote, timeToPrevColorNote, flipLineIndex, - flipYSide, cutDirectionAngleOffset, cutSfxVolumeMultiplier); INVOKE_CTOR(); + this->_ctor(time, beat, rotation, lineIndex, noteLineLayer, beforeJumpNoteLineLayer, gameplayType, scoringType, + colorType, cutDirection, timeToNextColorNote, timeToPrevColorNote, flipLineIndex, flipYSide, + cutDirectionAngleOffset, cutSfxVolumeMultiplier); this->____executionOrder_k__BackingField = beat; this->____subtypeIdentifier_k__BackingField = rotation; this->aheadTimeNoodle = std::numeric_limits::infinity(); @@ -265,10 +246,8 @@ CustomJSONData::CustomNoteData* CustomJSONData::CustomNoteData::GetCopy() { void CustomJSONData::CustomWaypointData::ctor(float time, float beat, int rotation, int lineIndex, GlobalNamespace::NoteLineLayer noteLineLayer, GlobalNamespace::OffsetDirection offsetDirection) { - static auto const* WaypointData_Ctor = il2cpp_utils::FindMethodUnsafe(classof(WaypointData*), ".ctor", 6); - il2cpp_utils::RunMethodRethrow(this, WaypointData_Ctor, time, beat, rotation, lineIndex, noteLineLayer, - offsetDirection); INVOKE_CTOR(); + this->_ctor(time, beat, rotation, lineIndex, noteLineLayer, offsetDirection); this->____executionOrder_k__BackingField = beat; this->____subtypeIdentifier_k__BackingField = rotation; } diff --git a/src/CustomBeatmapSaveDatav2.cpp b/src/CustomBeatmapSaveDatav2.cpp index 1aa8539..19a6e9a 100644 --- a/src/CustomBeatmapSaveDatav2.cpp +++ b/src/CustomBeatmapSaveDatav2.cpp @@ -24,9 +24,8 @@ void CustomJSONData::v2::CustomBeatmapSaveData::ctor(System::Collections::Generi System::Collections::Generic::List_1* obstacles, SpecialEventKeywordFiltersData* specialEventsKeywordFilters) { INVOKE_CTOR(); - static auto const* ctor = il2cpp_utils::FindMethodUnsafe(classof(BeatmapSaveData*), ".ctor", 6); - il2cpp_utils::RunMethodRethrow(this, ctor, events, notes, sliders, waypoints, obstacles, specialEventsKeywordFilters); + this->_ctor( events, notes, sliders, waypoints, obstacles, specialEventsKeywordFilters); // this->events = events; // this->notes = notes; // this->waypoints = waypoints; @@ -39,8 +38,7 @@ void CustomJSONData::v2::CustomBeatmapSaveData_NoteData::ctor(float time, int li NoteType type, BeatmapSaveDataCommon::NoteCutDirection cutDirection) { INVOKE_CTOR(); - static auto const* ctor = il2cpp_utils::FindMethodUnsafe(classof(NoteData*), ".ctor", 5); - il2cpp_utils::RunMethodRethrow(this, ctor, time, lineIndex, lineLayer, type, cutDirection); + this->_ctor( time, lineIndex, lineLayer, type, cutDirection); // this->time = time; // this->lineIndex = lineIndex; // this->lineLayer = lineLayer; @@ -51,8 +49,7 @@ void CustomJSONData::v2::CustomBeatmapSaveData_NoteData::ctor(float time, int li void CustomJSONData::v2::CustomBeatmapSaveData_ObstacleData::ctor(float time, int lineIndex, ObstacleType type, float duration, int width) { INVOKE_CTOR(); - static auto const* ctor = il2cpp_utils::FindMethodUnsafe(classof(ObstacleData*), ".ctor", 5); - il2cpp_utils::RunMethodRethrow(this, ctor, time, lineIndex, type, duration, width); + this->_ctor( time, lineIndex, type, duration, width); this->_time = time; this->_lineIndex = lineIndex; this->_type = type; @@ -63,8 +60,7 @@ void CustomJSONData::v2::CustomBeatmapSaveData_ObstacleData::ctor(float time, in void CustomJSONData::v2::CustomBeatmapSaveData_EventData::ctor(float time, BeatmapSaveDataCommon::BeatmapEventType type, int value, float floatValue) { INVOKE_CTOR(); - static auto const* ctor = il2cpp_utils::FindMethodUnsafe(classof(EventData*), ".ctor", 4); - il2cpp_utils::RunMethodRethrow(this, ctor, time, type, value, floatValue); + this->_ctor( time, type, value, floatValue); this->_time = time; this->_type = type; @@ -79,9 +75,7 @@ void CustomJSONData::v2::CustomBeatmapSaveData_SliderData::ctor( BeatmapSaveDataCommon::NoteCutDirection tailCutDirection, BeatmapSaveDataCommon::SliderMidAnchorMode sliderMidAnchorMode) { INVOKE_CTOR(); - static auto const* ctor = il2cpp_utils::FindMethodUnsafe(classof(SliderData*), ".ctor", 12); - il2cpp_utils::RunMethodRethrow( - this, ctor, colorType, headTime, headLineIndex, headLineLayer, headControlPointLengthMultiplier, headCutDirection, + this->_ctor( colorType, headTime, headLineIndex, headLineLayer, headControlPointLengthMultiplier, headCutDirection, tailTime, tailLineIndex, tailLineLayer, tailControlPointLengthMultiplier, tailCutDirection, sliderMidAnchorMode); } diff --git a/src/CustomBeatmapSaveDatav3.cpp b/src/CustomBeatmapSaveDatav3.cpp index 3e109ad..5d21d85 100644 --- a/src/CustomBeatmapSaveDatav3.cpp +++ b/src/CustomBeatmapSaveDatav3.cpp @@ -118,14 +118,12 @@ void CustomBeatmapSaveData_ColorNoteData::ctor(float beat, int line, int layer, ::BeatmapSaveDataCommon::NoteColorType color, ::BeatmapSaveDataCommon::NoteCutDirection cutDirection, int angleOffset) { INVOKE_CTOR(); - static auto const* ctor = il2cpp_utils::FindMethodUnsafe(classof(BeatmapSaveDataVersion3::ColorNoteData*), ".ctor", 6); - il2cpp_utils::RunMethodRethrow(this, ctor, beat, line, layer, color, cutDirection, angleOffset); + this->_ctor( beat, line, layer, color, cutDirection, angleOffset); } void CustomBeatmapSaveData_BombNoteData::ctor(float beat, int line, int layer) { INVOKE_CTOR(); - static auto const* ctor = il2cpp_utils::FindMethodUnsafe(classof(BeatmapSaveDataVersion3::BombNoteData*), ".ctor", 3); - il2cpp_utils::RunMethodRethrow(this, ctor, beat, line, layer); + this->_ctor( beat, line, layer); } void CustomBeatmapSaveData_SliderData::ctor(BeatmapSaveDataCommon::NoteColorType colorType, @@ -136,9 +134,7 @@ void CustomBeatmapSaveData_SliderData::ctor(BeatmapSaveDataCommon::NoteColorType ::BeatmapSaveDataCommon::NoteCutDirection tailCutDirection, ::BeatmapSaveDataCommon::SliderMidAnchorMode sliderMidAnchorMode) { INVOKE_CTOR(); - static auto const* ctor = il2cpp_utils::FindMethodUnsafe(classof(BeatmapSaveDataVersion3::SliderData*), ".ctor", 12); - il2cpp_utils::RunMethodRethrow( - this, ctor, colorType, headBeat, headLine, headLayer, headControlPointLengthMultiplier, headCutDirection, + this->_ctor( colorType, headBeat, headLine, headLayer, headControlPointLengthMultiplier, headCutDirection, tailBeat, tailLine, tailLayer, tailControlPointLengthMultiplier, tailCutDirection, sliderMidAnchorMode); } @@ -147,23 +143,20 @@ void CustomBeatmapSaveData_BurstSliderData::ctor(BeatmapSaveDataCommon::NoteColo ::BeatmapSaveDataCommon::NoteCutDirection headCutDirection, float tailBeat, int tailLine, int tailLayer, int sliceCount, float squishAmount) { INVOKE_CTOR(); - static auto const* ctor = il2cpp_utils::FindMethodUnsafe(classof(BeatmapSaveDataVersion3::BurstSliderData*), ".ctor", 10); - il2cpp_utils::RunMethodRethrow(this, ctor, colorType, headBeat, headLine, headLayer, headCutDirection, tailBeat, + this->_ctor( colorType, headBeat, headLine, headLayer, headCutDirection, tailBeat, tailLine, tailLayer, sliceCount, squishAmount); } void CustomBeatmapSaveData_ObstacleData::ctor(float beat, int line, int layer, float duration, int width, int height) { INVOKE_CTOR(); - static auto const* ctor = il2cpp_utils::FindMethodUnsafe(classof(BeatmapSaveDataVersion3::ObstacleData*), ".ctor", 6); - il2cpp_utils::RunMethodRethrow(this, ctor, beat, line, layer, duration, width, height); + this->_ctor( beat, line, layer, duration, width, height); } void CustomJSONData::v3::CustomBeatmapSaveData_BasicEventData::ctor( float time, BeatmapSaveDataCommon::BeatmapEventType type, int value, float floatValue) { INVOKE_CTOR(); - static auto const* ctor = il2cpp_utils::FindMethodUnsafe(classof(BeatmapSaveDataVersion3::BasicEventData*), ".ctor", 4); - il2cpp_utils::RunMethodRethrow(this, ctor, time, type, value, floatValue); + this->_ctor( time, type, value, floatValue); } diff --git a/src/CustomEventData.cpp b/src/CustomEventData.cpp index 963c359..d37304e 100644 --- a/src/CustomEventData.cpp +++ b/src/CustomEventData.cpp @@ -28,8 +28,7 @@ CJD_MOD_EXPORT SafePtr_ctor(time, 0, 0, BeatmapDataItemType(2)); BeatmapDataItem::_time_k__BackingField = time; BeatmapDataItem::type = 2; } From 25ee2004cafd3a186b99d1b2a8b5cacb57bc7bc6 Mon Sep 17 00:00:00 2001 From: Fernthedev <15272073+Fernthedev@users.noreply.github.com> Date: Sun, 1 Feb 2026 10:18:36 -0400 Subject: [PATCH 7/7] Migrate to JSONWrapper for CustomEventData --- shared/CustomBeatmapSaveDatav3.h | 6 ++++-- shared/CustomEventData.h | 5 +++-- shared/misc/BeatmapFieldUtils.hpp | 11 +++++++++++ src/CustomBeatmapSaveDatav2.cpp | 3 ++- src/CustomEventData.cpp | 6 +++--- src/hooks/V2Hooks.cpp | 4 +++- src/hooks/V3Hooks.cpp | 4 +++- 7 files changed, 29 insertions(+), 10 deletions(-) diff --git a/shared/CustomBeatmapSaveDatav3.h b/shared/CustomBeatmapSaveDatav3.h index 9dd1603..731b952 100644 --- a/shared/CustomBeatmapSaveDatav3.h +++ b/shared/CustomBeatmapSaveDatav3.h @@ -66,8 +66,10 @@ static inline auto const customData = "customData"; } // namespace CustomJSONData::v3::Constants namespace CustomJSONData::v3 { -using CustomDataOpt = std::optional>; -using CustomDataOptUTF16 = std::optional>; +using CustomData = rapidjson::Value const; +using CustomDataUTF16 = SongCore::CustomJSONData::ValueUTF16 const; +using CustomDataOpt = std::optional>; +using CustomDataOptUTF16 = std::optional>; } // namespace CustomJSONData::v3 diff --git a/shared/CustomEventData.h b/shared/CustomEventData.h index 2e95c8c..dfa4277 100644 --- a/shared/CustomEventData.h +++ b/shared/CustomEventData.h @@ -1,5 +1,6 @@ #pragma once +#include "JSONWrapper.h" #include "_config.hpp" #include "custom-types/shared/macros.hpp" @@ -30,14 +31,14 @@ DECLARE_CLASS_CODEGEN(CustomJSONData, CustomEventData, GlobalNamespace::BeatmapD DECLARE_FASTER_CTOR(ctor, float time); public: - static CustomEventData* New(float time, std::string_view type, size_t typeHash, rapidjson::Value const* data); + static CustomEventData* New(float time, std::string_view type, size_t typeHash, JSONWrapper* customData); DECLARE_OVERRIDE_METHOD(CustomEventData*, GetCopy, il2cpp_utils::FindMethod("", "BeatmapDataItem", "GetCopy")); public: std::string_view type; size_t typeHash; - rapidjson::Value const* data; + DECLARE_INSTANCE_FIELD(JSONWrapper*, customData); }; DECLARE_CLASS_CODEGEN(CustomJSONData, CustomBeatmapDataCallbackWrapper, GlobalNamespace::BeatmapDataCallbackWrapper) { diff --git a/shared/misc/BeatmapFieldUtils.hpp b/shared/misc/BeatmapFieldUtils.hpp index 57e256a..157d5b2 100644 --- a/shared/misc/BeatmapFieldUtils.hpp +++ b/shared/misc/BeatmapFieldUtils.hpp @@ -24,6 +24,17 @@ static JSONWrapper* JSONWrapperOrNull(v3::CustomDataOpt const& val) { return wrapper; } +static JSONWrapper* JSONWrapperOrNull(v3::CustomData* val) { + auto* wrapper = JSONWrapper::New_ctor(); + + if (!val || !val->IsObject()) { + return wrapper; + } + + wrapper->value = *val; + + return wrapper; +} static v3::CustomDataOptUTF16 JSONObjectOrNull(v3::CustomDataOptUTF16 const& val) { if (!val || !val->get().IsObject()) { diff --git a/src/CustomBeatmapSaveDatav2.cpp b/src/CustomBeatmapSaveDatav2.cpp index 19a6e9a..bf49d0f 100644 --- a/src/CustomBeatmapSaveDatav2.cpp +++ b/src/CustomBeatmapSaveDatav2.cpp @@ -115,7 +115,8 @@ static void ConvertBeatmapSaveDataPreV2_5_0(CustomJSONData::v2::CustomBeatmapSav beatmapSaveData->_events = list; } -static decltype(CustomJSONData::JSONWrapper::value) GetCustomData(rapidjson::Value const& doc) { +// get the rapidjson value for _customData if it exists +static CustomJSONData::v2::CustomDataOpt GetCustomData(rapidjson::Value const& doc) { auto customDataIt = doc.FindMember("_customData"); if (customDataIt != doc.MemberEnd() && customDataIt->value.IsObject()) { return customDataIt->value; diff --git a/src/CustomEventData.cpp b/src/CustomEventData.cpp index d37304e..bccef83 100644 --- a/src/CustomEventData.cpp +++ b/src/CustomEventData.cpp @@ -32,19 +32,19 @@ void CustomEventData::ctor(float time) { BeatmapDataItem::_time_k__BackingField = time; BeatmapDataItem::type = 2; } -CustomEventData* CustomEventData::New(float time, std::string_view type, size_t typeHash, rapidjson::Value const* data) { +CustomEventData* CustomEventData::New(float time, std::string_view type, size_t typeHash, JSONWrapper* data) { auto event = CustomEventData::New_ctor(time); CRASH_UNLESS(data); event->typeHash = typeHash; event->type = type; - event->data = data; + event->customData = data; return event; } CustomEventData* CustomEventData::GetCopy() { - auto* copy = CustomJSONData::CustomEventData::New(this->time, this->type, typeHash, this->data); + auto* copy = CustomJSONData::CustomEventData::New(this->time, this->type, typeHash, this->customData->GetCopy()); return copy; } diff --git a/src/hooks/V2Hooks.cpp b/src/hooks/V2Hooks.cpp index 9c739b1..5fa3ca8 100644 --- a/src/hooks/V2Hooks.cpp +++ b/src/hooks/V2Hooks.cpp @@ -542,9 +542,11 @@ MAKE_PAPER_HOOK_MATCH(BeatmapDataLoader_GetBeatmapDataFromSaveData_v2, [](auto const& a, auto const& b) constexpr { return a.time < b.time; }); for (auto const& customEventSaveData : *customBeatmapSaveData.value()->customEventsData) { + auto wrapper = CustomJSONData::JSONWrapperOrNull(customEventSaveData.data); + beatmapData->InsertCustomEventData( CustomEventData::New(bpmTimeProcessor.ConvertBeatToTime(customEventSaveData.time), customEventSaveData.type, - customEventSaveData.typeHash, customEventSaveData.data)); + customEventSaveData.typeHash, wrapper)); } CJDLogger::Logger.fmtLog("Added {} custom events", diff --git a/src/hooks/V3Hooks.cpp b/src/hooks/V3Hooks.cpp index fb20d98..d1c8fe7 100644 --- a/src/hooks/V3Hooks.cpp +++ b/src/hooks/V3Hooks.cpp @@ -531,9 +531,11 @@ MAKE_PAPER_HOOK_MATCH(BeatmapDataLoader_GetBeatmapDataFromSaveData_v3, [](auto const& a, auto const& b) constexpr { return a.time < b.time; }); for (auto const& customEventSaveData : *customBeatmapSaveData.value()->customEventsData) { + + auto wrapper = CustomJSONData::JSONWrapperOrNull(customEventSaveData.data); beatmapData->InsertCustomEventData( CustomEventData::New(bpmTimeProcessor.ConvertBeatToTime(customEventSaveData.time), customEventSaveData.type, - customEventSaveData.typeHash, customEventSaveData.data)); + customEventSaveData.typeHash, wrapper)); } CJDLogger::Logger.fmtLog("Added {} custom events",