Giter Club home page Giter Club logo

asl-help's Introduction

asl-help

Welcome!


Third Party Notice

This repository is not responsible for scripts malfunctioning due to issues that are not caused by asl-help. We reserve the right to immediately close any issues which report problems out of our control.

Instead, please either open an issue in the repository of the script's creator, or ask a question in the Speedrun Tool Development Discord server.

asl-help's People

Contributors

apple1417 avatar just-ero avatar mitchell-merry avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

asl-help's Issues

[Bug]: IL2CPP 32-bit struct layouts are mismatched

What helper class does this issue occur on?

Unity

Description

32-bit versions of IL2CPP act somewhat special.

Games on Unity 2020.1 appear to load pre-2019 structs (Il2CppClass version which does not contain unity_user_data). However, the cctor_thread field is decorated with ALIGN_TYPE(8). It is likely a field of pointer-type size, but it must be 8-byte aligned, which causes alignment issues on 32-bit games.

Since there aren't many 32-bit IL2CPP games, this issue is currently not of high priority.

Shown below is an example from the game "Granny 3" for the PC.

Reproduction Steps

state("Granny 3") {}

startup
{
  Assembly.Load(File.ReadAllBytes("Components/asl-help")).CreateInstance("Unity");
}

init
{
  vars.Helper.TryLoad = (Func<dynamic, bool>)(mono =>
  {
    var invSys = mono["InventorySystem"];

    return true;
  });
}

Error Messages

---

Regression?

No response

Potential Causes and Fixes

The structs being outdated like that may go back to the version of the IL2CPP library, which the helper is able to infer. It may be possible to fix that issue through that.

The alignment issue cannot be fixed easily. It likely requires a new custom attribute in the structs which the TypeParser class will have to account for.

Write extensive documentation and tutorials for all classes and methods

Since I would like asl-help to be as accessible as possible, it is of high priority to create understandable and extensive documentation for the possible use a developer can get out of the library. The documentation will be inspired by how the Microsoft Docs for C# are structured.

As documentation is currently still very work-in-progress, it will be located on its own branch at asl-help/documentation.

Alongside documentation for asl-help, tutorials for using it, as well as tutorials on how to gather information to be used with asl-help are very important.

Besides these important docs, it could also be great to extend LiveSplit's own documentation to include classes which are often used in auto splitter development.


  • asl-help documentation

    • Basic class
    • Unity class
    • Unreal class
    • Other classes
  • Tutorials

    • Setting up asl-help (testing, debugging)
    • Finding information for Unity games
    • Finding information for Unreal Engine games
  • LiveSplit documentation

    • timer
    • game
    • Signature scanning

`Il2CppClass` inference from its `Il2CppType`

It is currently not possible to find the Il2CppClass from a FieldInfo's Il2CppType.

Getting the underlying TypeDefinition from an Il2CppType โ€“ much like getting the MonoClass from a MonoType โ€“ is currently not supported. The relevant pieces of the Il2CppType's data union are __klassIndex and typeHandle, with the latter being the more relevant one.
With it, it needs to be figured out how to get the offset of the TypeDefinition which corresponds to the Il2CppClass' index in the TypeDefinitionTable.

Some helpful code may be located at Perfare/Il2CppDumper.

[Bug]: Unreal helper reading FName names incorrectly

What helper class does this issue occur on?

Unreal

Description

The following issue was discovered when attempting to use the Unreal helper with Scorn. @just-ero and I recently observed that when trying to read FName names from the FName pool, the strings being read appear to be offset by 6 bytes which causes an over-read, resulting in mangled names which, in turn, cannot be converted into valid identifiers.

While the objects are (apparently) identified correctly, given that addresses do show up under ue.UObjects, not having proper names makes them unreachable through Make<T>.

Reproduction Steps

state("Scorn-Win64-Shipping") {}

startup
{
    Assembly.Load(File.ReadAllBytes(@"Components/asl-help")).CreateInstance("Unreal");
}

init
{

    vars.Helper.TryLoad = (Func<dynamic, bool>)(ue =>
    {   
        int counter = 0;
        foreach (var obj in ue.UObjects) {
            if (counter > 40) break;
            vars.Log(obj.Address);
            vars.Log(obj.ToString() == null);
            counter++;
        }


        return true;
    });
}

Error Messages

None

Regression?

See potential causes and fixes

Potential Causes and Fixes

While this could potentially be a knock-on from a recent change to fix an AOB scan error (GUObjectArray signature could not be resolved), we don't have confirmation yet.

In addition, this could also be caused by some struct alignment problems.

[Bug]: Calling Loaded.Count does not update the cache correctly

What helper class does this issue occur on?

Unity

Description

When I tried to move an autosplitter from LiveSplit.AslHelp to asl-help, the loaded scenes were not updating correctly (always stuck at Loaded.Count == 0).

Logging the Count in update revealed it was always 0. I checked the scene manager in memory and it was correctly being updated there, where asl-help thought it should be (according to offsets etc).

The game was In Sound Mind (commit with code that broke).

Reproduction Steps

state("any game") {}

startup
{
    Assembly.Load(File.ReadAllBytes("Components/asl-help")).CreateInstance("Unity");
    vars.Helper.GameName = "In Sound Mind";
    vars.Helper.LoadSceneManager = true;
}

update
{
    vars.Log("vars.Helper.Scenes.Loaded.Count: " + vars.Helper.Scenes.Loaded.Count);
}

Error Messages

[4324] [asl-help] Unity loading complete. 
[4324] LiveSplit.exe Information: 0 : 
[4324] [In Sound Mind] vars.Helper.Scenes.Loaded.Count: 0 
[4324] LiveSplit.exe Information: 0 : 
[4324] [In Sound Mind] vars.Helper.Scenes.Loaded.Count: 0 
[4324] LiveSplit.exe Information: 0 : 
[4324] [In Sound Mind] vars.Helper.Scenes.Loaded.Count: 0 
[4324] LiveSplit.exe Information: 0 : 
[4324] [In Sound Mind] vars.Helper.Scenes.Loaded.Count: 0 
[4324] LiveSplit.exe Information: 0 : 
[4324] [In Sound Mind] vars.Helper.Scenes.Loaded.Count: 0 
...

Regression?

This worked in LiveSplit.AslHelp.

Potential Causes and Fixes

I have fixed this on a branch, I will explain on that PR. #16

Find `MonoBehaviour`s attached to components in any given scene

Unity's model highly encourages not using any static instances of classes, but instead, to attach a MonoBehaviour to a GameObject, Component, ScriptableObject, etc. Unfortunately, this makes asl-help-unity completely unable to function for classes and games like that.

Luckily, there are ways to find these attached classes within the scene. Each Unity Scene (the C++ versions) contains a linked list of loaded GameObjects. These objects are often loaded in the same order every time. Each of these GameObjects contains an array of attached Components. These components contain the scripts, which finally get linked to the actual MonoClass.

Some helpful code can be found at Micrologist/UnityInstanceDumper.

Re-introduce `asl-help-emu`

Because of low demand, as well as insufficient knowledge on my own part, asl-help-emu has been removed from asl-help for the time being. It could be quite a large help for emulator auto splitter developers if a robust system of helpers which find the emulator's WRAM address could be built.

Use the other existing helpers for inspiration.

[Bug]: MonoClass struct definition incorrect for IL2CPP 29 Game

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;
}

[Bug]: Game unable to find a class if the asl is opened before the game, finds after reload

What helper class does this issue occur on?

Unity

Description

Game is Bendy and the Dark Revival.

When the asl is loaded before the game, it repeatedly is unable to find the GameManager class, never - even if you leave it running for a while, if you go into levels, but if the asl is refreshed at any point then it will find it on it's next attempt.

Reproduction Steps

state("Bendy and the Dark Revival") { }

startup
{
  Assembly.Load(File.ReadAllBytes("Components/asl-help")).CreateInstance("Unity");
}

init
{
  vars.Helper.TryLoad = (Func<dynamic, bool>)(mono =>
  {
    var gm = mono["GameManager"];
    return true;
  });
}
// ...

Error Messages

Connected to game: Bendy and the Dark Revival (using default state descriptor)
Initializing
Init completed, running main methods
Searching for module with names: mono.dll, mono-2.0-bdwgc.dll, GameAssembly.dll...
  => No module found yet.
  => Retrying 2 more times in 1000ms...
  => Found mono-2.0-bdwgc.dll.
Retrieving Unity version...
  => Unity 2021.3.6f1.
  => Doesn't look right? You can set the helper's `UnityVersion` manually in 'startup {}':
     `vars.Helper.UnityVersion = new Version(2017, 2);`
Loading Unity mono.v3 structs...
  => Success.

Executing TryLoad...
Searching for image 'Assembly-CSharp'...
  => Found at 0x1FDB06B73E0.
    => class_cache.size is 11.
    => class_cache.table at 0x1FDB07D55F0.
Executing TryLoad...
Searching for image 'Assembly-CSharp'...
  => Found at 0x1FDB06B73E0.
    => class_cache.size is 11.
    => class_cache.table at 0x1FDB07D55F0.
Searching for class 'GameManager'...
  => Not found!
  => Class 'GameManager' could not be found.
TryLoad not successful.
  => Retrying in 3000ms... 
Exception thrown: 'System.ComponentModel.Win32Exception' in 'update' method:
The handle is invalid

   at ASL line 28 in 'update'

   at LiveSplit.ASL.ASLMethod.Call(LiveSplitState timer, ExpandoObject vars, String& version, Double& refreshRate, Object settings, ExpandoObject old, ExpandoObject current, Process game) 
   at LiveSplit.ASL.ASLScript.RunMethod(ASLMethod method, LiveSplitState state, String& version) 
   at LiveSplit.ASL.ASLScript.DoUpdate(LiveSplitState state) 
   at LiveSplit.UI.Components.ASLComponent.UpdateScript()
  => Found at 0x1FDB06B73E0.
    => class_cache.size is 11.
    => class_cache.table at 0x1FDB07D55F0.
Searching for class 'GameManager'...
  => Not found!
  => Class 'GameManager' could not be found.
TryLoad not successful.
  => Retrying in 3000ms...
  => Found at 0x1FDB06B73E0.
    => class_cache.size is 11.
    => class_cache.table at 0x1FDB07D55F0.
Searching for class 'GameManager'...
  => Not found!
  => Class 'GameManager' could not be found.
TryLoad not successful. 
...

Regression?

No response

Potential Causes and Fixes

A way to catch this error or somehow force a complete refresh of asl-help would be a nice option to have if TryLoad fails.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.