TASEmulators / BizHawk

BizHawk is a multi-system emulator written in C#. BizHawk provides nice features for casual gamers such as full screen, and joypad support in addition to full rerecording and debugging tools for all system cores.
http://tasvideos.org/BizHawk.html
Other
2.2k stars 385 forks source link

Lua client.getconfig object indexing issues #2368

Open TalicZealot opened 4 years ago

TalicZealot commented 4 years ago

Summary

As of 2.5.0 the client.getconfig().CoreSettings or CoreSyncSettings objects do not accept 'BizHawk.Emulation.Cores.Sony.PSX.Octoshock' as a valid index. Looking at config.ini the structure remains the same and it is listed the same way as before, so it seems like it should work just fine. I am using this to detect the display mode automatically for my script. Furthermore attempting to index CommonToolSettings with 'BizHawk.Client.EmuHawk.LuaConsole' does work without issues, so the problem seems to only be with CoreSettings or at least not all properties inside the settings object.

Note: In 2.4 and 2.3 a few users had the following issue, though the majority did not. I was not able to replicate that issue on both my Win7 and Win10 systems.

NLua.Exceptions.LuaScriptException: [string "main"]:34: attempt to call field 'getconfig' (a nil value)

Repro

client.getconfig().CoreSettings['BizHawk.Emulation.Cores.Sony.PSX.Octoshock'].ResolutionMode

Output

NLua.Exceptions.LuaScriptException: attempt to index field 'BizHawk.Emulation.Cores.Sony.PSX.Octoshock' (a nil value)

Problematic Build

Working Builds

YoshiRulz commented 4 years ago

Probably caused by 2f18ad5be.

edit: Off-topic, but others' reports of "attempt to call field 'getconfig' (a nil value)" was probably #1977.

TalicZealot commented 4 years ago

Hmmm maybe. From what I can see client.getconfig() grabs GlobalWin.Config, which is initialized from deserializing config.ini, so I would think it should still be fine, but I guess not.

YoshiRulz commented 4 years ago

That dictionary is now internal so the Lua bridge isn't exposing it to scripts. The linked commit added GetCoreSettings/PutCoreSettings extension methods for internal use, and the same for sync settings; if we want to continue supporting this use case then we can add Lua helper functions like so:

private static readonly Type[] CoresAssemblyTypes = typeof(ISettable<,>).Assembly.GetTypes();

[LuaMethod("getCoreSettings", "gets the core settings object for the core defined as `coreTypeName : ISettable<coreSettingsTypeName, *>`")]
public object GetCoreSettings(string coreTypeName, string coreSettingsTypeName)
{
    return GlobalWin.Config.GetCoreSettings(
        CoresAssemblyTypes.First(t => t.FullName == coreTypeName),
        CoresAssemblyTypes.First(t => t.FullName == coreSettingsTypeName)
    );
}

[LuaMethod("getCoreSyncSettings", "gets the core syncSettings object for the core defined as `coreTypeName : ISettable<*, coreSyncSettingsTypeName>`")]
public object GetCoreSyncSettings(string coreTypeName, string coreSyncSettingsTypeName)
{
    return GlobalWin.Config.GetCoreSyncSettings(
        CoresAssemblyTypes.First(t => t.FullName == coreTypeName),
        CoresAssemblyTypes.First(t => t.FullName == coreSyncSettingsTypeName)
    );
}

much later edit: I don't think Lua scripts should be able to get the global Config, ever. (Nor ext. tools, but under the current system they could just use reflection to get a reference, see https://github.com/TASEmulators/BizHawk/issues/2685#issuecomment-809795633.) That's why I called it ForbiddenConfigReference. If there's something in there, core settings or otherwise, that would be useful to read or write from Lua, it should be specifically exposed. For this use-case, a PSX library like the SNES one could be made.

nattthebear commented 4 years ago

Alternatively, the looah system could deal directly in the raw JTokens.. it's not like it needs the types

TalicZealot commented 4 years ago

That would work. The reason I did it this way is to automate detection of the different PSX resolution modes in order to adjust graphic overlay elements that need to line up in-game.