Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loading assets from disk #22

Draft
wants to merge 27 commits into
base: main
Choose a base branch
from
Draft

Conversation

vswarte
Copy link
Contributor

@vswarte vswarte commented Aug 7, 2024

Messy draft PR to track work on the file-loading hook.

The end goal is to allow asset overrides like modengine2 allows while supporting the same folder structure such that we can load existing mods. Unfortunately the hook(s) used to achieve this in modengine2 is kinda smelly and ideally dropped for something a bit easier to maintain.

This PR implements a similar feature by hooking RSResourceFileRequest::vtable[1] (RSResourceFileRequest::IsPathStringEmpty unofficial name). Which seems to be called before actually handling file requests, granting us consistent access to the files path before the actual IO system does its thing.

In order to operate on the DLWstring that hosts the file path @Dasaav-dsv has modeled DLWString in C++ using std::basic_string. This PR introduces cxx as a dependency and a bunch of C++ code for that reason.

An important difference between me2 and me3's approach is that me2 was receiving fully expanded paths mapped to dataX and the like directly. This hook unfortunately gets us unexpanded paths eg: event:/common.emevd.dcx. This can be solved by asking the game to resolve it for us, acquiring the mapping from the games memory ourselves or keeping a manual table per game.

What still needs to happen:

  • Look into better ways to attach extensions like this to mod host
    • Remove the need for making the package source pub
  • Virtual root mapping
    • Look into possibilities with fetching it from the game dynamically?
    • Fixed mapping with additional manual work as plan B?
  • Dynamic hook locating
    • Vftable crawler for ER
    • AOB for AC6
  • Wwise hook

To cap it all off, I couldn't immediately get the code to run with the dependency and package ordering code on, still need to look into that 😄

@@ -54,14 +54,16 @@ fn run() -> LauncherResult<()> {

// TODO: merge
if let Some(mut profile) = profiles.into_iter().next() {
let ordered_natives = sort_dependencies(profile.natives())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you share the config this code is causing problems with?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

profileVersion = "v1"

[[natives]]
path = "waygate_client.dll"
optional = true

[[natives]]
path = "eldenring_alt_saves.dll"
optional = true

# [[packages]]
# id = "test-mod-emevd-rave"
# source = "Z:\\home\\vincent\\me3-test-mod\\emevd-rave"
#
# [[packages]]
# id = "test-mod-clevers"
# source = "Z:\\home\\vincent\\me3-test-mod\\clevers"

[[packages]]
id = "err"
source = "Z:\\home\\vincent\\me3-test-mod\\err"

@vswarte
Copy link
Contributor Author

vswarte commented Aug 16, 2024

The new hook had some nasty edge-cases around finalizing map loads causing the user to indefinitely be stuck in the loading screen under certain conditions. I'm updating the code to use the old hook again but since the old hook is taking in a DLWString (allocator included) we no longer need the second CreateFileW hook.

As a plus we can consider the virtual root mapping tasks done I suppose.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants