cwoac / TTS-Manager

Import/Export Mods from Tabletop Simulator
MIT License
24 stars 10 forks source link

AssetBundles and PDFs are mistakenly downloaded/backed up as models #33

Open bobpaul opened 3 years ago

bobpaul commented 3 years ago

Mods consist of folders Workshop, AssetBundles, Images, Models, PDFs,


Along with that, currently assets are identified as Images or Not-Images based on the file extension. JSON is a structured document. The file type can be determined from parsing the JSON file itself. Additionally to the sections they're in, each type has a unique FooURL keyname:

AssetbundleSecondaryURL - AssetBundles
AssetbundleURL - AssetBundles
BackURL - Images
ColliderURL - Models
CurrentAudioURL - N/A, Don't Download
DiffuseURL - Images
FaceURL - Images
ImageSecondaryURL - Images
ImageURL - Images
LutURL - Models? it's a Lookup Table, not sure what the format is :-/
MeshURL - Models
NormalURL - Images
PageURL - (Inside the subkey of Tablet) - don't download, can be anything that displays in a browser.
PDFUrl - (inside CustomPDF) - PDFs
SkyURL - Images
TableURL - Images
URL - inside `CustomUIAssets[]` - Images
bobpaul commented 3 years ago

https://kb.tabletopsimulator.com/custom-content/save-file-format/ has most defined, but doesn't include Page or PDF

Here's jq queries for each of the URLs. This exposes the structure. Ex: Get cat FOO.json | jq '.TableURL' to grab the table URL.

AssetbundleURL, AssetbundleSecondaryURL
'.ObjectStates[] | select(.ContainedObjects != null) | .ContainedObjects[] | select(.CustomAssetbundle != null) | select(.CustomAssetbundle != null) | .CustomAssetbundle | .AssetbundleURL, .AssetbundleSecondaryURL'
'.ObjectStates[] | select(.CustomAssetbundle != null) | select(.CustomAssetbundle != null) | .CustomAssetbundle | .AssetbundleURL, .AssetbundleSecondaryURL'
'.ObjectStates[] | select(.States) |.States[] |select(.CustomAssetbundle != null) | select(.CustomAssetbundle != null) | .CustomAssetbundle | .AssetbundleURL, .AssetbundleSecondaryURL'

BackURL, FaceURL
'.ObjectStates[] | select(.ContainedObjects != null) | .ContainedObjects[] | select(.CustomDeck != null) | select(.CustomDeck != null) | .CustomDeck[] | .FaceURL, .BackURL'
'.ObjectStates[] | select(.CustomDeck != null) | .CustomDeck[] | .FaceURL, .BackURL'

CurrentAudioURL

ImageURL, ImageSecondaryURL
'.ObjectStates[] | select(.ContainedObjects != null) | .ContainedObjects[] | select(.CustomImage != null) | .CustomImage | (.ImageURL, .ImageSecondaryURL)'
'.ObjectStates[] | select(.CustomImage != null) | .CustomImage | (.ImageURL, .ImageSecondaryURL)'

LutURL
'. | select(.Lighting != null) | .Lighting | select(.LutURL != null) | .LutURL'

ColliderURL, DiffuseURL, MeshURL, NormalURL
'.ObjectStates[] | select(.ContainedObjects != null) | .ContainedObjects[] | select(.CustomMesh != null) | .CustomMesh | (.MeshURL, .DiffuseURL, .NormalURL, .ColliderURL)'
'.ObjectStates[] | select(.CustomMesh != null) | .CustomMesh | (.MeshURL, .DiffuseURL, .NormalURL, .ColliderURL)'

PDFUrl
'.ObjectStates[] | select(.ContainedObjects != null) | .ContainedObjects[] | select(.CustomPDF != null) | .CustomPDF.PDFUrl'
'.ObjectStates[] | select(.CustomPDF != null) | .CustomPDF.PDFUrl'

PageURL
'.ObjectStates[] | select(.ContainedObjects != null) | .ContainedObjects[] | select(.Tablet != null) | .Tablet.PageURL'
'.ObjectStates[] | select(.Tablet != null) | .Tablet.PageURL'

SkyURL
'.SkyURL'

TableURL
'.TableURL'

URL
'. | select(.CustomUIAssets != null) | .CustomUIAssets[].URL
'.ObjectStates[] | select(.ContainedObjects != null) | .ContainedObjects[] | select(.CustomUIAssets != null) | .CustomUIAssets[].URL
cwoac commented 3 years ago

Yeah, the format has moved on a lot since I last looked at this. This is useful information though, thanks.

bobpaul commented 3 years ago

So I have a ttsmod branch in my fork where I introduced a Mod class (currently in the save.py file). My idea is that the Mod class will represent the Mod/Save/Chest whether fed from a zip file or a files on disk. It does introduce an opportunity for a major refactor that I've only partially started... but I'm not 100% sure I'm sold on it.

Right now it's just sort of pigeon holed in. I think I see it replacing most/all of the Save class and simplifying Filesystem. The Mod class tracks the relative paths common between the filesystem and the zip.

My goal is to use that for #27, #33, and #28. As it stands, it does implement #28 and fixes #33 at least partially. For #33 I'd like to make it import PDFs and AssetBundles from the old .pak files that were storing them in the Models folder, but I haven't gotten that far and it might be a few weeks before I get back to this.

cwoac commented 3 years ago

So, I ended up implementing this yesterday, as I realised it was pretty much required for #27, by basically adding a FileType enum and deferring the decisions on what something is and where it is going to go to to that.

I'm not entirely sure what the distinction between a Mod and the existing Save class would be - there is a decent argument to rename Save to Mod - the track of where the files map to is kinda mostly in the (also now badly named Url class) - There definitely needs to be a bit of a refactoring.

cwoac commented 3 years ago

Importing from old ones is a good point, I'll add a new issue for it.