cheahjs / palworld-save-tools

Tools for converting Palworld .sav files to JSON and back
MIT License
776 stars 66 forks source link

[Feature Request] Packaging into a wheel and uploading to PyPi #118

Closed xNul closed 5 months ago

xNul commented 5 months ago

I've started integrating your tool here with my fix https://github.com/xNul/palworld-host-save-fix and at the moment I'm planning to add it as a submodule but it would be very convenient to have it as a pip package.

xNul commented 5 months ago

@cheahjs I'm not able to use the PyPi package. I think you're missing the imports that belong in __init__.py.

>>> import palworld_save_tools
>>> dir(palworld_save_tools)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__']
>>>
cheahjs commented 5 months ago

With how the package is currently structured, you'll need to import from the underlying modules, eg

from palworld_save_tools.palsav import decompress_sav_to_gvas
from palworld_save_tools.gvas import GvasFile
from palworld_save_tools.paltypes import PALWORLD_TYPE_HINTS, PALWORLD_CUSTOM_PROPERTIES

I can look into lifting the modules into the package so that you could do this instead:

import palworld_savre_tools
palworld_save_tools.archive.FArchiveReader
>>> from palworld_save_tools.palsav import decompress_sav_to_gvas
>>> decompress_sav_to_gvas
<function decompress_sav_to_gvas at 0x00000288CB1827A0>
>>> from palworld_save_tools.gvas import GvasFile
>>> GvasFile
<class 'palworld_save_tools.gvas.GvasFile'>
>>> from palworld_save_tools.paltypes import PALWORLD_TYPE_HINTS, PALWORLD_CUSTOM_PROPERTIES
>>> PALWORLD_TYPE_HINTS
{'.worldSaveData.CharacterContainerSaveData.Key': 'StructProperty', '.worldSaveData.CharacterSaveParameterMap.Key': 'StructProperty', '.worldSaveData.CharacterSaveParameterMap.Value': 'StructProperty', '.worldSaveData.FoliageGridSaveDataMap.Key': 'StructProperty', '.worldSaveData.FoliageGridSaveDataMap.Value.ModelMap.Value': 'StructProperty', '.worldSaveData.FoliageGridSaveDataMap.Value.ModelMap.Value.InstanceDataMap.Key': 'StructProperty', '.worldSaveData.FoliageGridSaveDataMap.Value.ModelMap.Value.InstanceDataMap.Value': 'StructProperty', '.worldSaveData.FoliageGridSaveDataMap.Value': 'StructProperty', '.worldSaveData.ItemContainerSaveData.Key': 'StructProperty', '.worldSaveData.MapObjectSaveData.MapObjectSaveData.ConcreteModel.ModuleMap.Value': 'StructProperty', '.worldSaveData.MapObjectSaveData.MapObjectSaveData.Model.EffectMap.Value': 'StructProperty', '.worldSaveData.MapObjectSpawnerInStageSaveData.Key': 'StructProperty', '.worldSaveData.MapObjectSpawnerInStageSaveData.Value': 'StructProperty', '.worldSaveData.MapObjectSpawnerInStageSaveData.Value.SpawnerDataMapByLevelObjectInstanceId.Key': 'Guid', '.worldSaveData.MapObjectSpawnerInStageSaveData.Value.SpawnerDataMapByLevelObjectInstanceId.Value': 'StructProperty', '.worldSaveData.MapObjectSpawnerInStageSaveData.Value.SpawnerDataMapByLevelObjectInstanceId.Value.ItemMap.Value': 'StructProperty', '.worldSaveData.WorkSaveData.WorkSaveData.WorkAssignMap.Value': 'StructProperty', '.worldSaveData.BaseCampSaveData.Key': 'Guid', '.worldSaveData.BaseCampSaveData.Value': 'StructProperty', '.worldSaveData.BaseCampSaveData.Value.ModuleMap.Value': 'StructProperty', '.worldSaveData.ItemContainerSaveData.Value': 'StructProperty', '.worldSaveData.CharacterContainerSaveData.Value': 'StructProperty', '.worldSaveData.GroupSaveDataMap.Key': 'Guid', '.worldSaveData.GroupSaveDataMap.Value': 'StructProperty', '.worldSaveData.EnemyCampSaveData.EnemyCampStatusMap.Value': 'StructProperty', '.worldSaveData.DungeonSaveData.DungeonSaveData.MapObjectSaveData.MapObjectSaveData.Model.EffectMap.Value': 'StructProperty', '.worldSaveData.DungeonSaveData.DungeonSaveData.MapObjectSaveData.MapObjectSaveData.ConcreteModel.ModuleMap.Value': 'StructProperty'}
>>> PALWORLD_CUSTOM_PROPERTIES
{'.worldSaveData.GroupSaveDataMap': (<function decode at 0x00000288CB4900E0>, <function encode at 0x00000288CB490360>), '.worldSaveData.CharacterSaveParameterMap.Value.RawData': (<function decode at 0x00000288CB4727A0>, <function encode at 0x00000288CB4728E0>), '.worldSaveData.MapObjectSaveData.MapObjectSaveData.Model.BuildProcess.RawData': (<function decode at 0x00000288CB472480>, <function encode at 0x00000288CB4725C0>), '.worldSaveData.MapObjectSaveData.MapObjectSaveData.Model.Connector.RawData': (<function decode at 0x00000288CB472FC0>, <function encode at 0x00000288CB473240>), '.worldSaveData.MapObjectSaveData.MapObjectSaveData.Model.RawData': (<function decode at 0x00000288CB490C20>, <function encode at 0x00000288CB490D60>), '.worldSaveData.ItemContainerSaveData.Value.RawData': (<function decode at 0x00000288CB490540>, <function encode at 0x00000288CB490680>), '.worldSaveData.ItemContainerSaveData.Value.Slots.Slots.RawData': (<function decode at 0x00000288CB490900>, <function encode at 0x00000288CB490A40>), '.worldSaveData.CharacterContainerSaveData.Value.Slots.Slots.RawData': (<function decode at 0x00000288CB472CA0>, <function encode at 0x00000288CB472DE0>), '.worldSaveData.DynamicItemSaveData.DynamicItemSaveData.RawData': (<function decode at 0x00000288CB473600>, <function encode at 0x00000288CB4737E0>), '.worldSaveData.FoliageGridSaveDataMap.Value.ModelMap.Value.RawData': (<function decode at 0x00000288CB4739C0>, <function encode at 0x00000288CB473B00>), '.worldSaveData.FoliageGridSaveDataMap.Value.ModelMap.Value.InstanceDataMap.Value.RawData': (<function decode at 0x00000288CB473E20>, <function encode at 0x00000288CB473F60>), '.worldSaveData.BaseCampSaveData.Value.RawData': (<function decode at 0x00000288CB472160>, <function encode at 0x00000288CB4722A0>), '.worldSaveData.BaseCampSaveData.Value.WorkerDirector.RawData': (<function decode at 0x00000288CB491760>, <function encode at 0x00000288CB4918A0>), '.worldSaveData.BaseCampSaveData.Value.WorkCollection.RawData': (<function decode at 0x00000288CB491440>, <function encode at 0x00000288CB491580>), '.worldSaveData.WorkSaveData': (<function decode at 0x00000288CB490EA0>, <function encode at 0x00000288CB491120>)}
xNul commented 5 months ago

Oh, no this is perfect, thank you! I thought

import package_x
package_x.y

was equivalent to

from package_x import y

so I didn't even try the latter.