What helper class does this issue occur on?
Unity
Description
Game: Sker Ritual
I am getting an error about finding the name of a MonoField when trying to load a property. I believe this is because the struct it is using to describe the MonoClass is slightly incorrect, causing it to read the incorrect field_count
, or something like that. See "Potential Causes and Fixes".
Reproduction Steps
state("SkerRitual") { }
startup
{
Assembly.Load(File.ReadAllBytes("Components/asl-help")).CreateInstance("Unity");
}
init
{
vars.Helper.TryLoad = (Func<dynamic, bool>)(mono =>
{
var gm = mono["GameplayManager"];
vars.Helper["InGame"] = gm.Make<bool>("InGame");
return true;
});
}
Error Messages
[25856] System.NullReferenceException: Object reference not set to an instance of an object.
[25856] at AslHelp.Extensions.StringExt.ToValidIdentifierUnity(String value)
[25856] at AslHelp.Mono.Models.MonoField.get_Name()
[25856] at AslHelp.Mono.Models.MonoClass.GetKey(MonoField monoField)
[25856] at AslHelp.Collections.CachedEnumerable`2.TryGetValue(TKey key, TValue& value)
[25856] at AslHelp.Mono.Models.MonoClass.get_Item(String fieldName)
[25856] at CallSite.Target(Closure , CallSite , Object , String )
[25856] at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
[25856] at CompiledScript.<>c__DisplayClassd.<Execute>b__c(Object mono) in c:\Users\Mitchell\AppData\Local\Temp\kdyjcsdh\kdyjcsdh.0.cs:line 33
[25856] at AslHelp.HelperBase`1.<DoOnLoad>b__32_0(TaskBuilderContext`1 ctx)
[25856] at AslHelp.Tasks.BuilderFunc`1.Invoke(TaskBuilderContext`1 ctx, Object[] args)
[25856] at AslHelp.Tasks.TaskBuilder`1.<AslHelp-Tasks-IFinalizeStage<TResult>-RunAsync>d__25.MoveNext()
[25856] --- End of stack trace from previous location where exception was thrown ---
[25856] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
[25856] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
[25856] at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
[25856] at AslHelp.HelperBase`1.<DoOnLoad>d__32.MoveNext()
[25856] --- End of stack trace from previous location where exception was thrown ---
[25856] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
[25856] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
[25856] at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
[25856] at AslHelp.HelperBase`1.<<Load>b__31_0>d.MoveNext()
Regression?
No response
Potential Causes and Fixes
I was able to resolve this using a local build of asl-help which inserted some padding in the il2cpp_2020.xml
MonoClass
struct like so:
...
<Field Name="instance_size" Type="uint" />
<Field Name="actualSize" Type="uint" />
<Field Name="element_size" Type="uint" />
<Field Name="padding1" Type="uint" /> <!-- <<<<< SOMEWHERE HERE -->
<Field Name="native_size" Type="int" />
<Field Name="static_fields_size" Type="uint" />
<Field Name="thread_static_fields_size" Type="uint" />
<Field Name="thread_static_fields_offset" Type="int" />
<Field Name="flags" Type="uint" />
<Field Name="token" Type="uint" />
...
I don't know much about Unity internals, but peeking around the source code and figuring out where this struct is, and working backwards, I'm reasonably sure element_size
is in the correct spot according to this struct, but flags
is offset by this padding. Adding this padding causes it to read the field_count
and other stuff correctly. Don't know where it's actually meant to be though or what it is.
Not sure if there's some new layout or something that this game should be using instead.
You can use this script to verify it's working, it just uses the game time in the current round, which you get booted to fairly soon after starting the game:
state("SkerRitual") { }
startup
{
Assembly.Load(File.ReadAllBytes("Components/asl-help")).CreateInstance("Unity");
vars.Helper.GameName = "Sker Ritual";
vars.Helper.AlertGameTime();
}
init
{
vars.Helper.TryLoad = (Func<dynamic, bool>)(mono =>
{
var ggmm = mono["GlobalGameModeManager", 1];
var gmm = mono["GameModeManager"];
vars.Helper["elapsedTime"] = ggmm.Make<float>(
"_Instance"
,ggmm["CurrentGameModeManager"]
,gmm["m_ElapsedTime"]
);
return true;
});
}
gameTime
{
return TimeSpan.FromSeconds(current.elapsedTime);
}
isLoading
{
return true;
}