mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-24 05:03:34 -04:00
fix non-ascii filenames for most .zip readers
This commit is contained in:
parent
9d1f88de82
commit
481bd1b9fd
@ -18,13 +18,15 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace MCGalaxy {
|
namespace MCGalaxy {
|
||||||
|
|
||||||
struct ZipEntry {
|
struct ZipEntry {
|
||||||
public string Filename;
|
public byte[] Filename;
|
||||||
public long CompressedSize, UncompressedSize, LocalHeaderOffset;
|
public long CompressedSize, UncompressedSize, LocalHeaderOffset;
|
||||||
public uint Crc32;
|
public uint Crc32;
|
||||||
|
public ushort BitFlags, CompressionMethod;
|
||||||
|
|
||||||
public void Reset() {
|
public void Reset() {
|
||||||
// signify to use zip64 version of these fields instead
|
// signify to use zip64 version of these fields instead
|
||||||
@ -112,13 +114,18 @@ namespace MCGalaxy {
|
|||||||
|
|
||||||
public void WriteEntry(Stream src, string file) {
|
public void WriteEntry(Stream src, string file) {
|
||||||
ZipEntry entry = default(ZipEntry);
|
ZipEntry entry = default(ZipEntry);
|
||||||
entry.Filename = file;
|
entry.Filename = Encoding.UTF8.GetBytes(file);
|
||||||
entry.LocalHeaderOffset = stream.Position;
|
entry.LocalHeaderOffset = stream.Position;
|
||||||
|
|
||||||
// leave some room to fill in header later
|
// leave some room to fill in header later
|
||||||
int headerSize = 30 + file.Length + zip64Extra;
|
int headerSize = 30 + entry.Filename.Length + zip64Extra;
|
||||||
stream.Write(buffer, 0, headerSize);
|
stream.Write(buffer, 0, headerSize);
|
||||||
|
|
||||||
|
// bit flag for non-ascii filename
|
||||||
|
foreach (char c in file) {
|
||||||
|
if (c < ' ' || c > '~') entry.BitFlags |= (1 << 11);
|
||||||
|
}
|
||||||
|
|
||||||
ZipEntryStream dst;
|
ZipEntryStream dst;
|
||||||
using (dst = new ZipEntryStream(stream)) {
|
using (dst = new ZipEntryStream(stream)) {
|
||||||
int read = 0;
|
int read = 0;
|
||||||
@ -184,8 +191,8 @@ namespace MCGalaxy {
|
|||||||
|
|
||||||
w.Write(0x04034b50);
|
w.Write(0x04034b50);
|
||||||
w.Write(version);
|
w.Write(version);
|
||||||
w.Write((ushort)0); // bitflags
|
w.Write(entry.BitFlags);
|
||||||
w.Write((ushort)0); // compression method
|
w.Write(entry.CompressionMethod);
|
||||||
WriteLastModified();
|
WriteLastModified();
|
||||||
w.Write(entry.Crc32);
|
w.Write(entry.Crc32);
|
||||||
w.Write((int)entry.CompressedSize);
|
w.Write((int)entry.CompressedSize);
|
||||||
@ -193,7 +200,7 @@ namespace MCGalaxy {
|
|||||||
w.Write((ushort)entry.Filename.Length);
|
w.Write((ushort)entry.Filename.Length);
|
||||||
w.Write(extraLen);
|
w.Write(extraLen);
|
||||||
|
|
||||||
WriteString(entry.Filename);
|
w.Write(entry.Filename);
|
||||||
if (zip64) WriteZip64ExtraField(copy, false);
|
if (zip64) WriteZip64ExtraField(copy, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,8 +213,8 @@ namespace MCGalaxy {
|
|||||||
w.Write(0x02014b50); // signature
|
w.Write(0x02014b50); // signature
|
||||||
w.Write(version);
|
w.Write(version);
|
||||||
w.Write(version);
|
w.Write(version);
|
||||||
w.Write((ushort)0); // bitflags
|
w.Write(entry.BitFlags);
|
||||||
w.Write((ushort)0); // compression method
|
w.Write(entry.CompressionMethod);
|
||||||
WriteLastModified();
|
WriteLastModified();
|
||||||
w.Write(entry.Crc32);
|
w.Write(entry.Crc32);
|
||||||
w.Write((int)entry.CompressedSize);
|
w.Write((int)entry.CompressedSize);
|
||||||
@ -220,16 +227,10 @@ namespace MCGalaxy {
|
|||||||
w.Write(0); // external attributes
|
w.Write(0); // external attributes
|
||||||
w.Write((int)entry.LocalHeaderOffset);
|
w.Write((int)entry.LocalHeaderOffset);
|
||||||
|
|
||||||
WriteString(entry.Filename);
|
w.Write(entry.Filename);
|
||||||
if (zip64) WriteZip64ExtraField(copy, true);
|
if (zip64) WriteZip64ExtraField(copy, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteString(string str) {
|
|
||||||
for (int i = 0; i < str.Length; i++) {
|
|
||||||
w.Write((byte)str[i].UnicodeToCp437());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WriteZip64ExtraField(ZipEntry entry, bool offset) {
|
void WriteZip64ExtraField(ZipEntry entry, bool offset) {
|
||||||
int len = zip64Extra - 4; // ignore header size
|
int len = zip64Extra - 4; // ignore header size
|
||||||
if (!offset) len -= 8;
|
if (!offset) len -= 8;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user