zip-rs / zip-old

Zip implementation in Rust
MIT License
731 stars 204 forks source link

Doesn't Work With Minecraft Shaderpack Loaders? #418

Closed What42Pizza closed 5 months ago

What42Pizza commented 10 months ago

I'm not sure how to write professional issues, especially for a situation like this, but I can't get this to create a zip file that is recognized by the mod Iris. I still haven't done much testing, but not even the 'write_dir' example works.

How to reproduce: 1: Take a Minecraft shaderpack 2: Unzip the contents 3: Rezip the contents with the 'write_dir' example program 4: Inspect contents to make sure the layout is the same 5: Load Minecraft 1.19.4 with Iris 1.6.10 6: Try loading shaderpack (doesn't work, at least for me)

7: Unzip contents 8: Rezip contents (not using zip crate example) 9: Try loading shaderpack, works fine

Things I've already done:

The result is always exactly the same. I've looked at Minecraft's log file and it's absolutely useless. I don't want to rush into blaming the crate, but I can't think of anything else. Also, this isn't an urgent problem in any way, I just wanted to automate zipping files. And as I said in the beginning, I'm pretty new to contributing to open source, so please tell me if I'm doing anything wrong

DrChat commented 10 months ago

Could you upload an example zip that was generated with this library as well as the source zip?

What42Pizza commented 10 months ago

Sure, here's a shader zipped with this crate: https://www.mediafire.com/file/42xgkztk2dubkmg/What42%2527s_Shader_Base_b1.9.0_%2528crate%2529.zip/file and the same files zipped with winrar: https://www.mediafire.com/file/i16uota8zxl82if/What42%2527s_Shader_Base_b1.9.0_%2528winrar%2529.zip/file

And it's not just the example that creates a bad output, I originally found this because my own program which uses this crate has the exact same problem

DrChat commented 10 months ago

Okay cool, thanks! It looks like we're running into the same bug so we'll take a look.

What42Pizza commented 10 months ago

Thanks so much!

allilo1 commented 10 months ago

Try testing the zip generated with this library in 7zip or another program. When I test the zip in 7zip, I see "unsupported compression method" errors.

What42Pizza commented 10 months ago

Do you mean zip with this crate then unzip with 7zip?

allilo1 commented 10 months ago

You can test the zip in 7zip or another program and it will report errors if it finds them (open 7zip, find the zip to test, and click "test" at the top). Based on the errors I see when testing, I would use a different compression method.

Pr0methean commented 5 months ago

Looks like you're using Zstd rather than Deflate as the compression algorithm, which isn't the default unless you manually disable all the Deflate and Bzip2 features. Minecraft Java Edition probably uses OpenJDK's ZipFile class, which doesn't support any compression method except Store and Deflate: https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/zip/ZipFile.java#L418

Enable one of the Deflate features (I recommend deflate-zopfli) and it should work.

If that doesn't solve the problem, please open a new issue at https://github.com/zip-rs/zip2/issues. This repo is no longer maintained.

Pr0methean commented 5 months ago

Update: Starting in version 1.2.1, the default compression method will be Stored (i.e. no compression at all) if no implementation of Deflate is enabled. That way the default options will produce a file that almost all ZIP-file decoders can read, regardless of feature flags.

Pr0methean commented 5 months ago

Incidentally, if you ever build Zip-based content packs for Bedrock Edition and need better compression than deflate-zopfli can provide, then your best bet is probably Deflate64, since that's what Windows 11 produces and therefore more likely than bzip2 or zstd to be supported by .NET (whether Framework or Core). Currently zip can only decompress Deflate64 and not compress into it, but we're hoping to eventually change that.

But Java Edition won't benefit even on Windows, because OpenJDK prefers to rely on a standard library mostly written in Java with as little platform-dependent code as possible, and is more interested than Microsoft's .NET team in supporting old hardware (e.g. 32-bit ARM) and operating-system versions. Microsoft makes more money when people buy new laptops that come with Windows OEM licences; whereas Oracle makes more money when they can sell "extended support" to server owners that lets them keep old Java code running on old-but-still-working server hardware, and workarounds for the security bugs in old Windows and MacOS versions they can't afford to upgrade.