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

Mod path access through Mod Organizer 2 #890

Closed
ZashIn opened this issue Oct 18, 2023 · 8 comments · Fixed by #892
Closed

Mod path access through Mod Organizer 2 #890

ZashIn opened this issue Oct 18, 2023 · 8 comments · Fixed by #892

Comments

@ZashIn
Copy link

ZashIn commented Oct 18, 2023

Bug

Some CET mods accessing files from other mods do not always work with MO2.

Probable causes

  1. PR uvfs support for CET with MO2  #877 introduced a fix/workaround for MO2, which handles path resolution differently when MOs USVFS is detected: code for overwrite path.
    The issue is that MO overlays multiple mod paths, which cannot always be identified just by the path directly.

  2. as seen in the CET/CyberScript log below with the related code lines: dir("datapack") works, but io.open("datapack/.../desc.json")does not.

Game version: Cyberpunk v2.01
CET version: 1.27.1

Suggested solution

  1. Use relative paths (instead of resolving to absolute) as long as they are within the mods sub folders.
    (Or at least add handle also mods/*/bin/x64 as a "special" MO path, although these paths can be configured differently in MO)
  2. Patch also io.open etc. (similar to dir) to handle file access correctly

Reproduction

Mods (clear overwrite before each mod test):

  • mod Citizen Voices and NCPD Radio Chatter + dependencies (except for CET) installed via MO
    [12236] CyberScript Assets Loaded
    [12236] No DESC FOR ..\..\..\..\..\..\..\..\Citizen Voices and NCPD Radio Chatter\bin\x64\plugins\cyber_engine_tweaks\mods\cyberscript\datapack\Citizen Voices
    [12236] Can't load ..\..\..\..\..\..\..\..\Citizen Voices and NCPD Radio Chatter\bin\x64\plugins\cyber_engine_tweaks\mods\cyberscript\datapack\Citizen Voices from the cache : 
    | jsondesc is not null : false 
    | datapack have required flag: false 
    | datapack is null : true
    
  • Appearance Menu Mod + V's Original ApartmentPLUS (preset):
    • with AMM in load order before preset (AMM prio < preset): preset does not show up
    • preset before AMM (preset prio > AMM): preset does show up
    • expected: preset should always be shown

All mods in overwrite: work

@Drakonas
Copy link

Drakonas commented Oct 18, 2023

Can confirm that Appearance Change Unlocker seems to also be affected by this with loading its preset files from anywhere but overwrite. Accessing the presets from overwrite works.

Opening new game character customization, changing a few sliders and creating a preset: preset created successfully
In same game instance, changing the preset to another, then back to the one created: works
Closing the game and moving the preset to an empty mod: The preset shows in the list but does not load

@rfuzzo
Copy link
Contributor

rfuzzo commented Oct 19, 2023

@Drakonas I can't reproduce the problem with ACU (mo2 2.5.0beta-11, without @ZashIn's plugin). I have a new preset in a new mod in MO2 (and the same preset not in overwrite) and it loads it fine. I checked this by downloading a preset from nexus: https://www.nexusmods.com/cyberpunk2077/mods/5781 and installing it with MO2 normally.
also tested with the repro steps provided.

@rfuzzo
Copy link
Contributor

rfuzzo commented Oct 19, 2023

@ZashIn and regarding "Citizen Voices and NCPD Radio Chatter" - this mod is outdated and doesn't seem to work anymore? It (together with cyberscript) tries to call really weird paths like user/cache/..\..\..\..\..\..\..\..\Citizen Voices and NCPD Radio Chatter\bin\x64\plugins\cyber_engine_tweaks\mods\cyberscript\datapack\Citizen Voices.lua

  • a) that file doesn't exist anywhere
  • and b) this would resolve to F:\games\Cyberpunk 2077\Citizen Voices and NCPD Radio Chatter\bin\x64\plugins\cyber_engine_tweaks\mods\cyberscript\datapack\Citizen Voices.lua which is all kinds of wrong.

I don't think there is an issue here (the mod is just broken)

@rfuzzo
Copy link
Contributor

rfuzzo commented Oct 21, 2023

I found the issue: the sbRootpath under usvf can have 3 locations:

  • the game
  • overwrite
  • the mod install path

With mods that add to other mods the root path is the initial mod's root . An AMM pose pack mod for example adds files to /amm/poses but /amm/poses resolves to overwrite/amm/poses and should resolve to mod/amm/poses instead (since we're interested in the mod's additions and not AMM).

Specifically, the problem arises if the mod uses dir() in lua which returns an iterator for files. e.g.:

local files = dir(inDir)
for _, file in ipairs(files) do
    local dir2 = dir(file.name)
end

under uvfs file.name is a relative path to the mod's install dir (e.g. ..\..\..\..\..\..\..\..\..\Pose Pack\bin\x64\plugins\cyber_engine_tweaks\mods\AppearanceMenuMod\Collabs\Custom Poses\posepack) and not a simple filename (posepack).

There is no good and easy solution for that from the CET side but it can be easily resolved from the mod's lua side:

function extractFileName(path)
    local parts = {}
    for part in string.gmatch(path, "([^\\]+)") do
        table.insert(parts, part)
    end
    return parts[#parts]
end

local files = dir(inDir)
for _, file in ipairs(files) do
    local dir2 = dir(extractFileName(file.name))
end

I suggest closing this issue and fix it in the mods themselves for now.

@rfuzzo
Copy link
Contributor

rfuzzo commented Oct 21, 2023

@ZashIn
Copy link
Author

ZashIn commented Oct 21, 2023

It seems that the following line causes the file.name issue:

item["name"] = UTF16ToUTF8(relative(entry.path(), path).native());

I do not know what the intended API is here, but file.name does not return the name, but the relative path here, which not always the same (VFS, probably symlinks etc). A file.path vs file.name would make the distinction clear.
Mod authors seem to expect just a file name here, too.

So my suggestion (with limited C++ knowledge) is to change the above line to

item["name"] = UTF16ToUTF8(entry.path().filename);

And optionally add something like

item["relativePath"] = UTF16ToUTF8(relative(entry.path(), path).native());

Although the latter would have the same issues as before.
So @maximegmd please reopen, this is not fixed yet.

@WSSDude
Copy link
Collaborator

WSSDude commented Oct 23, 2023

That change was there for a long time, basically from the beginning of the sandbox so nearly 2 years... It is sort of custom replacement of an existing dir() lua command, it should return an array of tables with name and a type.

I believe that when I originally made it, original Lua command was returning absolute paths, but cannot find anything on the internet now about this and cannot test it...

Our version was returning "absolute" paths also, just relative to mod folder due to sandbox limitations.

If this changes, it may have consequences elsewhere where someone counts on this behavior.

We agreed with @rfuzzo to make this breaking change, but as part of separate fix. Shouldnt be mixed together, they are two separate issues Id say.

@WSSDude
Copy link
Collaborator

WSSDude commented Oct 23, 2023

+ Im unsure if this is even an error, it may well be mod error in this case.

I would rather double-check exact behavior of unmodified dir command again and do the change then based on that if it is required. Either in the mod or in the CET.

We do not return iterators etc. like original did but the resulting table you'll get from the array in for loop should be about the same.

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 a pull request may close this issue.

5 participants