mitchell-merry / autosplitters

A collection of all of my autosplitters and load removers - tools for the speedrunning program LiveSplit.
MIT License
3 stars 4 forks source link

Hitman 3 Auto Split Doesn't work for Xbox(PC) version #4

Closed la-moreno closed 1 year ago

la-moreno commented 1 year ago

I notice in the .asl there is an "Epic" and "Steam" state but no "Microsoft" or "Xbox" state. Is it possible to add support for this version of Hitman 3?

mitchell-merry commented 1 year ago

It's of course possible - I just don't have access to that version. If you have access to that version, then you can try following what I wrote in the README there: https://github.com/mitchell-merry/autosplitters/blob/main/Hitman%203/README.md.

I'm not sure if it's useful, and I'm honestly not sure what level of knowledge it assumes. But please, be my guest and give it a go. If you find something that works, then communicate that to me and I can guide you to properly adding the state here.

Sorry for the long response time.

mitchell-merry commented 1 year ago

I've just updated that readme to hopefully be better. Let us know how it goes!

la-moreno commented 1 year ago

Thank you for the reply! I'll give it a try and let you know how it goes.

la-moreno commented 1 year ago

It's telling me access is denied. Keeps spamming this in DebugView.

[8596] LiveSplit.exe Information: 0 : [8596] [ASL/58892473] Initializing [8596] LiveSplit.exe Error: 0 : [8596] Exception thrown: 'System.UnauthorizedAccessException' in 'init' method: [8596] Access to the path 'C:\Program Files\WindowsApps\IOInteractiveAS.PC-HITMAN3-BaseGame_1.0.34.0_x64__6h0y724g59e1w\Retail\hitman3.exe' is denied. [8596] [8596] at ASL line 16 in 'init' [8596] [8596] at LiveSplit.ASL.ASLMethod.Call(LiveSplitState timer, ExpandoObject vars, String& version, Double& refreshRate, Object settings, ExpandoObject old, ExpandoObject current, Process game) [8596] at LiveSplit.ASL.ASLScript.RunMethod(ASLMethod method, LiveSplitState state, String& version) [8596] at LiveSplit.ASL.ASLScript.DoInit(LiveSplitState state) [8596] at LiveSplit.UI.Components.ASLComponent.UpdateScript()

mitchell-merry commented 1 year ago

run livesplit as administrator, I believe

This looks specific to your version, though :thinking:

la-moreno commented 1 year ago

LiveSplits is running as admin but I think the windowsapps folder requires special privileges perhaps. Not sure how to get around this. Looking into it though.

mitchell-merry commented 1 year ago

Hm, that doesn't bode well for others actually using the ASL if you do get it working. It might be caused by the MD5 code.

(I originally posted a code snippet here, but I don't think it'll work)

mitchell-merry commented 1 year ago

What does this give you?

var mms = modules.First().ModuleMemorySize;
print(mms.ToString("X"));
la-moreno commented 1 year ago

I think this is the output: [1616] 4ABE000

mitchell-merry commented 1 year ago

Ok, I got 4A71000 for steam, so that's somewhat promising. Maybe we can be cheeky and switch to this instead. I'll ask the person who did the Epic version to run this as well, and if it's all different then we should be good to go.

In the meantime, just move onto finding isLoading. You can use the following asl to test:

state("HITMAN3", "Steam")
{
    bool isLoading: 0x39B220C;
}

// state("HITMAN3", "Epic")
// {
//     bool isLoading: 0x14D530, 0xFEC;
// }

state("HITMAN3", "Microsoft")
{
    // bool isLoading: 0x14D530, 0xFEC;
}

init
{
    var mms = modules.First().ModuleMemorySize.ToString("X");
    print("MMS is: " + mms);

    switch (mms) {
        case "4A71000": version = "Steam"; break;
        // case "F9B0347F278B533ACE9A744B5B5353F9": version = "Epic"; break;
        case "4ABE000": version = "Microsoft"; break;

        default: version = "UNKNOWN"; break;
    }

    print("Chose version " + version);
}

isLoading
{
    return current.isLoading;
}
la-moreno commented 1 year ago

When I click First Scan in CE it says: Scan error: thread 0: Please fill something in (100)

I think im missing something.

la-moreno commented 1 year ago

Oh I see I have to put the value im looking for.

la-moreno commented 1 year ago

CE seems to be stuck or something. When I try to do the next scan it says: "Cheat Engine Scan Busy." Although it completed the first scan. A popup comes up that says : "The previous scan is still being processed. Please wait (Still copying the results for the first scan scanner option)." Is this normal and how long should it take?

Edit: It just takes a long time, haha

la-moreno commented 1 year ago

Ok so i've got the address now what?

mitchell-merry commented 1 year ago

Assuming you mean you tested the load remover with that address and it worked, send it here. Could you clarify if this is an Xbox game pass game or on the Microsoft Store?

la-moreno commented 1 year ago

0014DB3C I got the game through Game Pass.

I didnt test the load remover. But this was the address that had a 1 while loading and 0 everywhere else I tested. Also the only one.

How do i test it?

mitchell-merry commented 1 year ago

Try loading this into livesplit, load it into the ScriptableAutosplitter component I mentioned in that readme.

state("HITMAN3", "Steam")
{
    bool isLoading: 0x39B220C;
}

state("HITMAN3", "Epic")
{
    bool isLoading: 0x14D530, 0xFEC;
}

state("HITMAN3", "Xbox")
{
    bool isLoading: 0x14DB3C;
}

init
{
    var mms = modules.First().ModuleMemorySize.ToString("X");
    print("MMS is: " + mms);

    // MMS as a workaround to the Xbox game pass not working (#4)
    switch (mms) {
        case "4A67000": version = "Epic"; break;
        case "4A71000": version = "Steam"; break;
        case "4ABE000": version = "Xbox"; break;

        default: version = "UNKNOWN - raise an issue on GitHub if you want support for this version"; break;
    }

    print("Chose version " + version);
}

isLoading
{
    return current.isLoading;
}
la-moreno commented 1 year ago

It doesn't pause the timer. It's entirely possible I did something wrong or missed a step though. So I add a Scriptable Auto Splitter and load the asl file (which I renamed to hitman3Test.asl)

mitchell-merry commented 1 year ago

did you right click on livesplit and set compare against to game time?

la-moreno commented 1 year ago

When I do that the timer doesn't move. It just stays 0. I tried game time before using the auto splitter with the same result.

mitchell-merry commented 1 year ago

and you're comparing it to the value in cheat engine and verify that the path is still working as expected?

la-moreno commented 1 year ago

I reopened cheat engine and the game and added that address manually. The address still has a value of 0 outside loads and 1 during the loads in CE.

mitchell-merry commented 1 year ago

Is the version being detected correctly? (Check for the log)

Can you take a screenshot of the address you found in CE as well?

la-moreno commented 1 year ago

Heres a video of cheat engine during the game and loading screen. You'll see the value change from 0 outside loads and to 1 inside loads. https://www.youtube.com/watch?v=9f49v-00YRw

la-moreno commented 1 year ago

Here's the log when I open live split.

[23984] LiveSplit.exe Information: 0 : [23984] [ASL] Loading new script: C:\Users\lucas\LiveSplit_1.8.26\Components\hitman3.asl [23984] LiveSplit.exe Information: 0 : [23984] [ASL/24152954] Running startup [23984] LiveSplit.exe Information: 0 : [23984] [ASL/24152954] Connected to game: HITMAN3 (state descriptor for version 'Steam' chosen as default) [23984] LiveSplit.exe Information: 0 : [23984] [ASL/24152954] Initializing [23984] LiveSplit.exe Information: 0 : [23984] MMS is: 4ABE000 [23984] LiveSplit.exe Information: 0 : [23984] Chose version Xbox [23984] LiveSplit.exe Information: 0 : [23984] [ASL/24152954] Switched to state descriptor for version 'Xbox' [23984] LiveSplit.exe Information: 0 : [23984] [ASL/24152954] Init completed, running main methods

When i start the timer it will add a small amount of time like .04 and stop.

mitchell-merry commented 1 year ago

I see the issue. There's a misunderstanding. The address you have in the address table is the calculated address. That is the final, actual address of the value in memory. We want the address relative to a module (in this case, "hitman3.exe").

For example, in the address table, my address shows as 0x1439B220C. But if I were to double click on that address, it reveals that the address is really "hitman3.exe"+0x39B220C. This is because the "hitman3.exe" module is offset at apparently 0x140000000 to the base.

I see the ASL code is confusing, because I have omitted the "hitman3.exe". This is because it's the main module, so LiveSplit will use the main module by default if one is not specified. So really, the path in the Steam state block is "hitman3.exe"+0x39B220C as desired.

Erm, at least, that's what I'm assuming is happening. The first address in the Epic path looks pretty similar to what you ended up with, so I'm somewhat concerned I have it wrong. But, that's my best guess.

In any case, could you send me the path as it appears in the following window? image

P.S: the reason why it goes to 0.04 and stops is because it will run for one tick before calculating isLoading. So one tick of time will pass until it will decide the timer should be paused.

la-moreno commented 1 year ago

Sorry for the late reply! Okay I got it working! Here's the address I used: 0x3AA4BFC

There are 8 other addresses that should also work.

mitchell-merry commented 1 year ago

Okay, try to load up the load remover inside LiveSplit natively by following these instructions: https://hitruns-wiki.vercel.app/docs/livesplit_freelancer and let me know how if it works!

mitchell-merry commented 1 year ago

Followed up with https://github.com/solderq35/hitruns-wiki/pull/15

la-moreno commented 1 year ago

I removed the scriptable auto splitter component and activated the native load remover and it works just fine :)