GandaG / pyfomod

A high-level fomod library written in Python.

Home Page:https://pyfomod.rtfd.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Installer cannot return multiple directory paths with same destination

krateng opened this issue · comments

This happens on multiple mods, but just as an example, I have the fomod Bijin Wives. The ModuleConfig.xml file is properly parsed to install multiple paths for one option:

mod = pyfomod.parse((None,"./ModuleConfig.xml"))

page1 = mod.pages[0]
group1 = page1[0]
option1 = group1[0]
print(option1.name)
# All IN ONE
print(option1.files)
# <pyfomod.fomod.Files object at 0x7f2d77c68b80>
print(list(option1.files))
# ['02 ESPs\\AIO/', '00 Common/', '01 Characters\\Camilla/', '01 Characters\\Grelka/', '01 Characters\\Morwen/', '01 Characters\\Muiri/', '01 Characters\\Senna/', '01 Characters\\Sylgja/', '01 Characters\\Taarie/', '01 Characters\\Temba/', '01 Characters\\Ysolda/']

However, when I actually select that option with the installer, it only remembers the last path:

mod = pyfomod.parse((None,"./ModuleConfig.xml"))
installer = pyfomod.Installer(mod)

page1 = installer.next()
group1 = page1[0]
option1 = group1[0]
print(option1.name)
# All IN ONE
installer.next([option1])
print(installer.files())
# {'01 Characters\\Ysolda': '.'}

From multiple test cases, this seems to be always the last file added - and not just per page or group, but over the entire installer.

I did some digging through the code and I'm not sure I fully understand it, but it seems the source -> destination file dict is first built in reverse (as a destination -> source dict)

file_dict = {} # src -> dst
priority_dict = {} # dst -> priority
for info in required_files + user_files + conditional_files:
if info.destination in priority_dict:
if priority_dict[info.destination] > info.priority:
continue
del file_dict[info.destination]
file_dict[info.destination] = info.source
priority_dict[info.destination] = info.priority
return {b: a for a, b in file_dict.items()}

This leads to paths with duplicate destinations being ignored, which breaks if the fomod uses directory destinations (copying whole directories instead of individual files).

Removing that whole logic fixes the issue, but obviously breaks the priority calculation.