Skip to content
This repository was archived by the owner on Sep 20, 2026. It is now read-only.
Merged
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
10 changes: 5 additions & 5 deletions src/BazaarPlusPlus/Game/OverlayPanels/OverlayPanelHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal sealed class OverlayPanelHost : MonoBehaviour
private readonly OverlayLifecycleCore _core = new();
private readonly OverlayPanelHostLogState _logState = new();
private readonly List<OverlayPanelRegistration> _registrations = new();
private int _sceneTokenHandle;
private Scene _sceneTokenScene;
private bool _sceneTokenLoaded;
private string _sceneToken = string.Empty;

Expand Down Expand Up @@ -128,18 +128,18 @@ private void Unregister(string panelId)
private bool ReadIsInCombat() =>
_logState.ReadIsInCombat(static () => TheBazaar.Data.IsInCombat);

// name/path/buildIndex are fixed for a given scene handle, so the token string is rebuilt
// only when the active scene (or its loaded flag) actually changes.
// Compare Scene values, not Scene.handle: Unity 6 changed that getter's return type
// from int to SceneHandle. The equality operator's ABI is stable across both versions.
private string GetSceneToken(Scene scene)
{
if (
_sceneToken.Length != 0
&& _sceneTokenHandle == scene.handle
&& _sceneTokenScene == scene
&& _sceneTokenLoaded == scene.isLoaded
)
return _sceneToken;

_sceneTokenHandle = scene.handle;
_sceneTokenScene = scene;
_sceneTokenLoaded = scene.isLoaded;
_sceneToken = $"{scene.name}|{scene.path}|{scene.buildIndex}|{scene.isLoaded}";
return _sceneToken;
Expand Down
6 changes: 3 additions & 3 deletions src/BazaarPlusPlus/GameInterop/Scenes/ActiveSceneNameCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace BazaarPlusPlus.GameInterop.Scenes;
/// </summary>
internal static class ActiveSceneNameCache
{
private static int _handle;
private static Scene _scene;
private static bool _loaded;
private static bool _hasName;
private static string _name = string.Empty;
Expand All @@ -20,10 +20,10 @@ internal static string Current
get
{
var scene = SceneManager.GetActiveScene();
if (_hasName && _handle == scene.handle && _loaded == scene.isLoaded)
if (_hasName && _scene == scene && _loaded == scene.isLoaded)
return _name;

_handle = scene.handle;
_scene = scene;
_loaded = scene.isLoaded;
_name = scene.name;
_hasName = true;
Expand Down
34 changes: 34 additions & 0 deletions tests/RuntimeIntegration.Tests/SceneRuntimeCompatibilityTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using Xunit;

namespace RuntimeIntegration.Tests;

public sealed class SceneRuntimeCompatibilityTests
{
[Fact]
public void Compiled_mod_does_not_bind_to_the_version_specific_scene_handle_getter()
{
using var stream = File.OpenRead(
Path.Combine(AppContext.BaseDirectory, "BazaarPlusPlus.dll")
);
using var pe = new PEReader(stream);
var metadata = pe.GetMetadataReader();
var sceneMembers = new List<string>();
foreach (var handle in metadata.MemberReferences)
{
var member = metadata.GetMemberReference(handle);
if (member.Parent.Kind != HandleKind.TypeReference)
continue;
var type = metadata.GetTypeReference((TypeReferenceHandle)member.Parent);
if (
metadata.GetString(type.Namespace) == "UnityEngine.SceneManagement"
&& metadata.GetString(type.Name) == "Scene"
)
sceneMembers.Add(metadata.GetString(member.Name));
}

Assert.DoesNotContain("get_handle", sceneMembers);
Assert.Contains("op_Equality", sceneMembers);
}
}