From a65201e7cfb410b1e42b431bf5f6e2e479be8603 Mon Sep 17 00:00:00 2001 From: Arne Kiesewetter Date: Thu, 22 Jan 2026 23:36:57 +0100 Subject: [PATCH 1/3] Prevent ChildParentAudioClipPlayer component crashing the game Adds a fix for https://github.com/Yellow-Dog-Man/Resonite-Issues/issues/1457 --- CommunityBugFixCollection/Locale/de.json | 5 +- CommunityBugFixCollection/Locale/en.json | 5 +- .../NoParentUnderSelfAudioClipPlayer.cs | 62 +++++++++++++++++++ README.md | 1 + 4 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 CommunityBugFixCollection/NoParentUnderSelfAudioClipPlayer.cs diff --git a/CommunityBugFixCollection/Locale/de.json b/CommunityBugFixCollection/Locale/de.json index e31e69b..ef4cffd 100644 --- a/CommunityBugFixCollection/Locale/de.json +++ b/CommunityBugFixCollection/Locale/de.json @@ -38,6 +38,7 @@ "CommunityBugFixCollection.NodeNameAdjustments.Description": "Verbessert die verwirrenden Namen der Remap [-1; 1] zu [0; 1] ProtoFlux Nodes.", "CommunityBugFixCollection.NonHDRColorClamping.Description": "Korrigiert, dass die nicht-HDR Varianten der Color(X) Kanal-Additionen die Werte nicht limitieren.", "CommunityBugFixCollection.NonLinearColorXFromHexCode.Description": "Zwingt colorX From HexCode das sRGB statt dem Linearen Farbprofil zu nutzen.", + "CommunityBugFixCollection.NoParentUnderSelfAudioClipPlayer.Description": "Verhindert, dass die ChildParentAudioClipPlayer-Komponente das Spiel crasht, wenn ihr ParentUnder-Feld auf den Slot, auf dem sie ist, gesetzt ist. Fügt außerdem eine Erklärung des Problems im Header hinzu.", "CommunityBugFixCollection.PauseAnimatorUpdates.Description": "Verhindert, dass Animatoren jeden Frame in alle assoziierten Felder schreiben, obwohl sie nicht am animieren sind.", "CommunityBugFixCollection.ReallyNoDestroyUndo.Description": "Sorgt dafür, dass die NoDestroyUndo Komponente tatsächlich verhindert, dass das Zerstören eines Objekts rückgängig gemacht werden kann.", "CommunityBugFixCollection.SmoothDraggables.Description": "Umgeht, dass Slider und Joints in Headless-Sessions verrutschen.", @@ -50,6 +51,8 @@ "CommunityBugFixCollection.Config.Options.Name": "Optionen", "CommunityBugFixCollection.Config.Options.Description": "Enthällt die Einstellungen für die wenigen Fixes die diese anbieten.", "CommunityBugFixCollection.Config.Options.UseIecByteFormat.Name": "IEC Byte-Format Benutzen", - "CommunityBugFixCollection.Config.Options.UseIecByteFormat.Description": "Ob Bytes nach IEC (Faktor 1024) statt dezimal (Faktor 1000) formatiert werden sollen, wenn LocalizedByteFormatting aktiviert ist." + "CommunityBugFixCollection.Config.Options.UseIecByteFormat.Description": "Ob Bytes nach IEC (Faktor 1024) statt dezimal (Faktor 1000) formatiert werden sollen, wenn LocalizedByteFormatting aktiviert ist.", + + "CommunityBugFixCollection.ChildParentAudioClipPlayer.Header": "Das ParentUnder-Feld dieser AudioClipPlayer-Komponente darf niemals auf den Slot, auf dem sie ist, gesetzt werden. Andernfalls crasht das Spiel wenn ein Clip ausgelöst wird." } } \ No newline at end of file diff --git a/CommunityBugFixCollection/Locale/en.json b/CommunityBugFixCollection/Locale/en.json index 44aa892..628284d 100644 --- a/CommunityBugFixCollection/Locale/en.json +++ b/CommunityBugFixCollection/Locale/en.json @@ -44,6 +44,7 @@ "CommunityBugFixCollection.NodeNameAdjustments.Description": "Fixes the confusing names of the Remap [-1; 1] to [0; 1] ProtoFlux nodes.", "CommunityBugFixCollection.NonHDRColorClamping.Description": "Fixes non-HDR variants of Color(X) channel addition not clamping.", "CommunityBugFixCollection.NonLinearColorXFromHexCode.Description": "Forces colorX From HexCode to use the sRGB rather than Linear profile.", + "CommunityBugFixCollection.NoParentUnderSelfAudioClipPlayer.Description": "Prevents the ChildParentAudioClipPlayer components from crashing the game if their ParentUnder field is set to the slot that it's on. Also adds a header text explaining the problem.", "CommunityBugFixCollection.PauseAnimatorUpdates.Description": "Fixes animators updating all associated fields every frame while enabled but not playing.", "CommunityBugFixCollection.ReallyNoDestroyUndo.Description": "Makes the NoDestroyUndo component actually prevent undoing destroying something.", "CommunityBugFixCollection.SmoothDraggables.Description": "Workaround for Sliders and Joints snapping in sessions hosted by a headless.", @@ -70,6 +71,8 @@ "CommunityBugFixCollection.StorageUnits.MB": "MB", "CommunityBugFixCollection.StorageUnits.GB": "GB", "CommunityBugFixCollection.StorageUnits.TB": "TB", - "CommunityBugFixCollection.StorageUnits.PB": "PB" + "CommunityBugFixCollection.StorageUnits.PB": "PB", + + "CommunityBugFixCollection.ChildParentAudioClipPlayer.Header": "This AudioClipPlayer component's ParentUnder field must never be set to the slot it's on. Otherwise, the game will crash when a clip is triggered." } } \ No newline at end of file diff --git a/CommunityBugFixCollection/NoParentUnderSelfAudioClipPlayer.cs b/CommunityBugFixCollection/NoParentUnderSelfAudioClipPlayer.cs new file mode 100644 index 0000000..689ff9a --- /dev/null +++ b/CommunityBugFixCollection/NoParentUnderSelfAudioClipPlayer.cs @@ -0,0 +1,62 @@ +using FrooxEngine; +using HarmonyLib; +using MonkeyLoader.Resonite; +using MonkeyLoader.Resonite.UI.Inspectors; + +namespace CommunityBugFixCollection +{ + [HarmonyPatch(typeof(ChildParentAudioClipPlayer))] + [HarmonyPatchCategory(nameof(NoParentUnderSelfAudioClipPlayer))] + internal sealed class NoParentUnderSelfAudioClipPlayer : ResoniteEventHandlerMonkey + { + public override IEnumerable Authors => Contributors.Banane9; + + public override bool CanBeDisabled => true; + + public override int Priority => HarmonyLib.Priority.Low; + + protected override void Handle(ResolveInspectorHeaderTextEvent eventData) + => eventData.AddItem(new(Mod.GetLocaleString("ChildParentAudioClipPlayer.Header"))); + + private static User? GetAllocatingUser(ChildParentAudioClipPlayer element) + { + if (element.FilterWorldElement() is null) + return null; + + element.ReferenceID.ExtractIDs(out var position, out var allocationId); + var user = element.World.GetUserByAllocationID(allocationId); + + if (user is null || position < user.AllocationIDStart) + return null; + + return user; + } + + [HarmonyPostfix] + [HarmonyPatch(nameof(ChildParentAudioClipPlayer.OnAwake))] + private static void OnAwakePostfix(ChildParentAudioClipPlayer __instance) + { + if (__instance.ParentUnder.Target == __instance.Slot) + { + Logger.Warn(() => $"User [{GetAllocatingUser(__instance)}] tried loading a ChildParentAudioClipPlayer targeting itself on: {__instance.ParentHierarchyToString()}"); + + if (Enabled) + __instance.ParentUnder.Target = null!; + } + + __instance.ParentUnder.OnTargetChange += _ => + { + if (Enabled && __instance.ParentUnder.Target == __instance.Slot) + __instance.RunSynchronously(() => __instance.ParentUnder.Target = null!); + }; + } + + [HarmonyPostfix] + [HarmonyPatch(nameof(ChildParentAudioClipPlayer.PlayClip))] + private static void PlayClipPrefix(ChildParentAudioClipPlayer __instance) + { + if (Enabled && __instance.World.CanMakeSynchronousChanges && __instance.ParentUnder.Target == __instance.Slot) + __instance.ParentUnder.Target = null!; + } + } +} \ No newline at end of file diff --git a/README.md b/README.md index 7a54b4f..7be72e0 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ just disable them in the settings in the meantime. * https://github.com/Yellow-Dog-Man/Locale/issues/186 * FlipAtUser component does not respect view position (https://github.com/Yellow-Dog-Man/Resonite-Issues/issues/1335) * ColorX From HexCode (ProtoFlux node) defaults to Linear profile (https://github.com/Yellow-Dog-Man/Resonite-Issues/issues/1404) +* ChildParentAudioClipPlayer component crashes the game when it's triggered while its *ParentUnder* field is set to the slot it's on (https://github.com/Yellow-Dog-Man/Resonite-Issues/issues/1457) * Resolution scale may get stuck at 0.5 when opening and closing the SteamVR dashboard while the game is hitching (https://github.com/Yellow-Dog-Man/Resonite-Issues/issues/2337) * `ValueMod` node crashes the game when B input is set to zero or disconnected. (https://github.com/Yellow-Dog-Man/Resonite-Issues/issues/2746) * Grid World grid being off-center (https://github.com/Yellow-Dog-Man/Resonite-Issues/issues/2754) From 049931b70737e7420fea35398610f17e30e3224e Mon Sep 17 00:00:00 2001 From: Arne Kiesewetter Date: Fri, 23 Jan 2026 00:23:01 +0100 Subject: [PATCH 2/3] Update CI for SDK --- .github/workflows/build.yml | 13 +++---------- .github/workflows/publish.yml | 5 +---- CommunityBugFixCollection.sln | 9 +++++++++ 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c0386f5..303b0d8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,7 +43,7 @@ jobs: - name: Setup Dotnet uses: actions/setup-dotnet@v4 with: - dotnet-version: 9.x + dotnet-version: 10.x source-url: https://nuget.pkg.github.com/ResoniteModdingGroup/index.json - name: Add MonkeyLoader NuGet Source @@ -69,10 +69,6 @@ jobs: - name: Move NuGet Packages run: mv (Get-ChildItem -Recurse ./ -Include *.nupkg) ./ - - # Removes the version number from the package name - - name: Rename NuGet Packages - run: Get-ChildItem -Include *.nupkg -Path ./* | Rename-Item -NewName { $_.Name -Replace '\.\d+\.\d+\.\d+.*$','.nupkg' } # Publish the NuGet package(s) as an artifact, so they can be used in the following jobs - name: Upload NuGet Packages Artifact @@ -81,7 +77,7 @@ jobs: name: NuGet Packages if-no-files-found: error retention-days: 7 - path: ./*.nupkg + path: ./CommunityBugFixCollection.nupkg # Only when it's not from a PR to avoid any funny packages in the cache - name: Save NuGet Package Cache @@ -98,12 +94,9 @@ jobs: - name: Setup Dotnet uses: actions/setup-dotnet@v4 with: - dotnet-version: 9.x + dotnet-version: 10.x source-url: https://nuget.pkg.github.com/ResoniteModdingGroup/index.json - - name: Add MonkeyLoader NuGet Source - run: dotnet nuget add source https://pkg.munally.com/MonkeyModdingTroop/index.json - - name: Restore NuGet Package Cache uses: actions/cache/restore@v4 with: diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3fe7a28..3e65cc7 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -68,11 +68,8 @@ jobs: - name: Setup Dotnet uses: actions/setup-dotnet@v4 with: - dotnet-version: 9.x + dotnet-version: 10.x source-url: https://nuget.pkg.github.com/ResoniteModdingGroup/index.json - - - name: Add MonkeyLoader NuGet Source - run: dotnet nuget add source https://pkg.munally.com/MonkeyModdingTroop/index.json # Publish all NuGet packages to the GitHub feed # Use --skip-duplicate to prevent errors if a package with the same version already exists. diff --git a/CommunityBugFixCollection.sln b/CommunityBugFixCollection.sln index 0f886f2..e96a192 100644 --- a/CommunityBugFixCollection.sln +++ b/CommunityBugFixCollection.sln @@ -11,6 +11,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution README.md = README.md EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}" + ProjectSection(SolutionItems) = preProject + .github\workflows\build.yml = .github\workflows\build.yml + .github\workflows\publish.yml = .github\workflows\publish.yml + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -25,6 +31,9 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {07124CF9-EE3D-4A7E-A2F8-8FD07966E423} + EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {7D505B2E-FBA2-4F50-BC1C-838BC8DF0D5C} EndGlobalSection From b368950e9944656e489ab5d0471386101bead1f4 Mon Sep 17 00:00:00 2001 From: Arne Kiesewetter Date: Sun, 25 Jan 2026 23:27:44 +0100 Subject: [PATCH 3/3] Fix ChildParentAudioClipPlayer warning appearing on every component --- CommunityBugFixCollection/NoParentUnderSelfAudioClipPlayer.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CommunityBugFixCollection/NoParentUnderSelfAudioClipPlayer.cs b/CommunityBugFixCollection/NoParentUnderSelfAudioClipPlayer.cs index 689ff9a..27c86eb 100644 --- a/CommunityBugFixCollection/NoParentUnderSelfAudioClipPlayer.cs +++ b/CommunityBugFixCollection/NoParentUnderSelfAudioClipPlayer.cs @@ -15,6 +15,9 @@ internal sealed class NoParentUnderSelfAudioClipPlayer : ResoniteEventHandlerMon public override int Priority => HarmonyLib.Priority.Low; + protected override bool AppliesTo(ResolveInspectorHeaderTextEvent eventData) + => base.AppliesTo(eventData) && eventData.Worker is ChildParentAudioClipPlayer; + protected override void Handle(ResolveInspectorHeaderTextEvent eventData) => eventData.AddItem(new(Mod.GetLocaleString("ChildParentAudioClipPlayer.Header")));