It is currently 17 Nov 2025, 21:21
   
Text Size

Information pending...

Moderator: CCGHQ Admins

Re: Information pending...

Postby thefiremind » 14 Jun 2015, 08:24

drleg3nd wrote:this what you mean ?
Yes, you did it right. Try to complete at least a plane, then. If I remember correctly, GrovyleXShinyCelebi's WADs added the AI cards on Innistrad, maybe completing Innistrad helps.

-------------------------------------------------------

EDIT: I'm trying to build a program that should automate some of the most common actions in modding DotP2015. I'm still not sure about what I'll include, but first I wanted to be sure that I was able to rewrite spirolone's ZipToZed tool in C#. Since I did it right (I compared the output ZEDs with MD5 and they are identical), I'll post here the C# function as a reference, in case someone else wants to include it in a Visual Studio C# application:
spirolone's ZipToZed in C# | Open
Code: Select all
private static void ZipToZed(string oldZedFileName, string zipFileName, string newZedFileName)
{
    FileStream newZedFile = new FileStream(newZedFileName, FileMode.Create, FileAccess.Write);
    FileStream oldZedFile = new FileStream(oldZedFileName, FileMode.Open, FileAccess.Read);
    FileStream zipFile = new FileStream(zipFileName, FileMode.Open, FileAccess.Read);
    byte[] fileContent;
    zipFile.Seek(-10, SeekOrigin.End);
    zipFile.Read(fileContent = new byte[8], 0, fileContent.Length);
    int centralDirOffset = (fileContent[7] & 255) << 24 | (fileContent[6] & 255) << 16 | (fileContent[5] & 255) << 8 | fileContent[4] & 255;
    int centralDirSize = (fileContent[3] & 255) << 24 | (fileContent[2] & 255) << 16 | (fileContent[1] & 255) << 8 | fileContent[0] & 255;
    zipFile.Seek(centralDirOffset, SeekOrigin.Begin);
    byte[] centralDir = new byte[centralDirSize];
    zipFile.Read(centralDir, 0, centralDir.Length);
    oldZedFile.Seek(-8, SeekOrigin.End);
    oldZedFile.Read(fileContent = new byte[8], 0, fileContent.Length);
    for (int i = 7; i > 0; i--) fileContent[i] ^= fileContent[i - 1];
    fileContent[0] ^= fileContent[7];
    centralDirOffset = (fileContent[7] & 255) << 24 | (fileContent[5] & 255) << 16 | (fileContent[3] & 255) << 8 | fileContent[1] & 255;
    oldZedFile.Seek(centralDirOffset, SeekOrigin.Begin);
    byte[] centralDirHead = new byte[340];
    oldZedFile.Read(centralDirHead, 0, centralDirHead.Length);
    fileContent = new byte[8];
    for (int i = 0; i < 4; i++) fileContent[i] = (byte)(centralDirHead[257 + i] ^ centralDirHead[258 + i]);
    for (int i = 0; i < 4; i++) fileContent[4 + i] = (byte)(centralDirHead[279 + i] ^ centralDirHead[280 + i]);
    int length = (fileContent[3] & 255) << 24 | (fileContent[2] & 255) << 16 | (fileContent[1] & 255) << 8 | fileContent[0] & 255;
    length += (fileContent[7] & 255) << 24 | (fileContent[6] & 255) << 16 | (fileContent[5] & 255) << 8 | fileContent[4] & 255;
    oldZedFile.Seek(0, SeekOrigin.Begin);
    fileContent = new byte[length];
    oldZedFile.Read(fileContent, 0, fileContent.Length);
    newZedFile.Write(fileContent, 0, fileContent.Length);
    int pt = 0;
    int localFileCompSize;
    int localFileOffset;
    int localFileNameLen;
    byte[] localFileData;
    while (pt < centralDirSize - 1)
    {
        localFileCompSize = (centralDir[pt + 23] & 255) << 24 | (centralDir[pt + 22] & 255) << 16 | (centralDir[pt + 21] & 255) << 8 | centralDir[pt + 20] & 255;
        localFileNameLen = (centralDir[pt + 29] & 255) << 8 | centralDir[pt + 28] & 255;
        if (localFileCompSize > 0)
        {
            localFileOffset = (centralDir[pt + 45] & 255) << 24 | (centralDir[pt + 44] & 255) << 16 | (centralDir[pt + 43] & 255) << 8 | centralDir[pt + 42] & 255;
            localFileData = new byte[localFileCompSize];
            zipFile.Seek(localFileOffset + 30 + localFileNameLen, SeekOrigin.Begin);
            zipFile.Read(localFileData, 0, localFileData.Length);
            newZedFile.Write(localFileData, 0, localFileData.Length);
        }
        localFileOffset = (int)newZedFile.Position - localFileCompSize;
        centralDir[pt + 42] = (byte)(localFileOffset & 255);
        centralDir[pt + 43] = (byte)(localFileOffset >> 8 & 255);
        centralDir[pt + 44] = (byte)(localFileOffset >> 16 & 255);
        centralDir[pt + 45] = (byte)(localFileOffset >> 24 & 255);
        centralDir[pt + 9] = 1;
        pt += localFileNameLen + 82;
    }
    zipFile.Dispose();
    centralDirOffset = (int)newZedFile.Position;
    newZedFile.Write(centralDirHead, 0, centralDirHead.Length);
    oldZedFile.Seek(-10, SeekOrigin.End);
    centralDir[centralDirSize - 1] = (byte)(oldZedFile.ReadByte() ^ oldZedFile.ReadByte());
    oldZedFile.Dispose();
    centralDir[0] ^= centralDirHead[339];
    for (int i = 1; i < centralDirSize; i++) centralDir[i] ^= centralDir[i - 1];
    newZedFile.Write(centralDir, 0, centralDir.Length);
    centralDirSize += 340;
    fileContent = new byte[8];
    fileContent[0] = (byte)(centralDirSize & 255);
    fileContent[2] = (byte)(centralDirSize >> 8 & 255);
    fileContent[4] = (byte)(centralDirSize >> 16 & 255);
    fileContent[6] = (byte)(centralDirSize >> 24 & 255);
    fileContent[1] = (byte)(centralDirOffset & 255);
    fileContent[3] = (byte)(centralDirOffset >> 8 & 255);
    fileContent[5] = (byte)(centralDirOffset >> 16 & 255);
    fileContent[7] = (byte)(centralDirOffset >> 24 & 255);
    fileContent[0] ^= fileContent[7];
    for (int i = 1; i < 8; i++) fileContent[i] ^= fileContent[i - 1];
    newZedFile.Write(fileContent, 0, fileContent.Length);
    newZedFile.Dispose();
}
The next step would be creating the ZIP file automatically, maybe only in memory.

EDIT 2: Creating the ZIP file automatically is actually a nightmare, I can't seem to build it properly. I tried with DotNetZip and SharpZipLib libraries, both create ZIP files that can be read by WinRAR no problem, but they are a little smaller than the ZIP created by WinRAR itself (although both set to uncompressed), and they don't seem to be compatible with spirolone's code.
< Former DotP 2012/2013/2014 modder >
Currently busy with life...
User avatar
thefiremind
Programmer
 
Posts: 3515
Joined: 07 Nov 2011, 10:55
Has thanked: 118 times
Been thanked: 722 times

Re: Information pending...

Postby spirolone » 16 Jun 2015, 15:47

thefiremind wrote:Creating the ZIP file automatically is actually a nightmare, I can't seem to build it properly. I tried with DotNetZip and SharpZipLib libraries, both create ZIP files that can be read by WinRAR no problem, but they are a little smaller than the ZIP created by WinRAR itself (although both set to uncompressed), and they don't seem to be compatible with spirolone's code.
Maybe we had better not pass through zip file. I'll try to make a version of my program that reads files from a folder. It should be easy for me cause I know what any part of my code does. There is a part in my other code (ZedToZip) that creates zip headers and I'll use it... :wink:
spirolone
Programmer
 
Posts: 190
Joined: 31 Aug 2014, 23:14
Has thanked: 7 times
Been thanked: 107 times

Re: Information pending...

Postby spirolone » 18 Jun 2015, 04:21

I finished a version of my program that doesn't need a zed and a zip file: it uses a "Data.bin" file where I stored necessary parts of DATA_041.ZED file, and it reads all the files in "DATA_041" folder. I hope it could be more practical than precedent one. Please let me know if you find some bugs (likely event!)... :mrgreen:
Attachments
CreateZed.zip
(10.25 KiB) Downloaded 552 times
spirolone
Programmer
 
Posts: 190
Joined: 31 Aug 2014, 23:14
Has thanked: 7 times
Been thanked: 107 times

Re: Information pending...

Postby thefiremind » 18 Jun 2015, 08:15

Thanks a lot for your work as always, spirolone! I'll test it as soon as I have time, and report by editing this post. :)

EDIT: I haven't tried it yet, but looking at the code... doesn't your code add the outmost directory (DATA_041) as well? When we used the ZIP file, we needed to not include it. Is it OK anyway?

EDIT 2: In fact, it doesn't work this way. I'll try to code a workaround that excludes the outmost directory.

EDIT 3: Either I don't know the code enough to make it exclude the outmost directory properly, or there's something else wrong. If it helps, the ZED that this new tool produces is 654 Bytes larger than the old one (at least with my files). With my attempt at excluding the outmost directory, it was still 520 Bytes larger than the old one (again, at least with my files).
< Former DotP 2012/2013/2014 modder >
Currently busy with life...
User avatar
thefiremind
Programmer
 
Posts: 3515
Joined: 07 Nov 2011, 10:55
Has thanked: 118 times
Been thanked: 722 times

Re: Information pending...

Postby spirolone » 18 Jun 2015, 12:47

thefiremind wrote:Thanks a lot for your work as always, spirolone! I'll test it as soon as I have time, and report by editing this post. :)

EDIT: I haven't tried it yet, but looking at the code... doesn't your code add the outmost directory (DATA_041) as well? When we used the ZIP file, we needed to not include it. Is it OK anyway?

EDIT 2: In fact, it doesn't work this way. I'll try to code a workaround that excludes the outmost directory.

EDIT 3: Either I don't know the code enough to make it exclude the outmost directory properly, or there's something else wrong. If it helps, the ZED that this new tool produces is 654 Bytes larger than the old one (at least with my files). With my attempt at excluding the outmost directory, it was still 520 Bytes larger than the old one (again, at least with my files).
I tried my code only with few files and it's likely it could be bugged, but maybe we are now experiencing some problems due to usage and missing of info by me: "DATA_041" dir is the one at same level of ".METADATA", and you have to add content in "Data_All_Platforms" dir inside it, so that an entry will be something like "DATA_041/Data_All_Platforms/Cards/RISE_FROM_THE_GRAVE_TUT.xml"; isn't it correct?
spirolone
Programmer
 
Posts: 190
Joined: 31 Aug 2014, 23:14
Has thanked: 7 times
Been thanked: 107 times

Re: Information pending...

Postby thefiremind » 18 Jun 2015, 12:56

spirolone wrote:"DATA_041" dir is the one at same level of ".METADATA", and you have to add content in "Data_All_Platforms" dir inside it, so that an entry will be something like "DATA_041/Data_All_Platforms/Cards/RISE_FROM_THE_GRAVE_TUT.xml"; isn't it correct?
Oh, I thought that we were still using the .METADATA directory, since we were using it with your ZipToZed tool. #-o I'll test it with the inner DATA_0xx directory now.

EDIT: It still doesn't work. Are you totally sure that the .METADATA directory isn't needed? I substituted DATA_041 with DATA_082 (the number I'm using now) in Header.xml because I thought it was necessary.
< Former DotP 2012/2013/2014 modder >
Currently busy with life...
User avatar
thefiremind
Programmer
 
Posts: 3515
Joined: 07 Nov 2011, 10:55
Has thanked: 118 times
Been thanked: 722 times

Re: Information pending...

Postby spirolone » 18 Jun 2015, 13:33

thefiremind wrote:It still doesn't work. Are you totally sure that the .METADATA directory isn't needed? I substituted DATA_041 with DATA_082 (the number I'm using now) in Header.xml because I thought it was necessary.
It uses .METADATA dir from DATA_041.ZED that I stored in Data.bin file, so that we have Header.xml that "points" to DATA_041/Data_All_platforms/ dir, then actually you cannot change name of source dir (DATA_041). If you use ZedToZip on just created Zed file, do you obtain a valid Zip file?
spirolone
Programmer
 
Posts: 190
Joined: 31 Aug 2014, 23:14
Has thanked: 7 times
Been thanked: 107 times

Re: Information pending...

Postby GrovyleXShinyCelebi » 18 Jun 2015, 13:44

It worked for me; I removed the outer DATA_041 and .METADATA directory, and put just the inner DATA_041 directory straight in the Duels directory.
User avatar
GrovyleXShinyCelebi
 
Posts: 294
Joined: 12 Jun 2013, 18:23
Has thanked: 14 times
Been thanked: 37 times

Re: Information pending...

Postby thefiremind » 18 Jun 2015, 14:52

spirolone wrote:It uses .METADATA dir from DATA_041.ZED that I stored in Data.bin file, so that we have Header.xml that "points" to DATA_041/Data_All_platforms/ dir, then actually you cannot change name of source dir (DATA_041).
This is a step back from ZipToZed, but if it works anyway (even side by side with the original DATA_041.ZED without having to overwrite it), then it's OK.

GrovyleXShinyCelebi wrote:It worked for me; I removed the outer DATA_041 and .METADATA directory, and put just the inner DATA_041 directory straight in the Duels directory.
I think I just understood what's wrong. I made the usual modifications so that I could specify any path for the directory, but this probably puts the full path inside the ZED when
Code: Select all
source.toString();
is called, so I need to strip the part of the path that refers to the outer directories.

EDIT: Bingo! That was the problem indeed. I solved it, now the new tool works for me. :D

Here is my version, in case someone needs it. All the credit goes to spirolone, as always, but with this one you can specify the source directory and the destination ZED file name as arguments. You can also use a source directory that isn't called DATA_041: the name will be fixed by the tool when it's written in the ZED file. The included run.bat is, as usual, a usage example.
Attachments
tfm_CreateZed.zip
(6.89 KiB) Downloaded 479 times
< Former DotP 2012/2013/2014 modder >
Currently busy with life...
User avatar
thefiremind
Programmer
 
Posts: 3515
Joined: 07 Nov 2011, 10:55
Has thanked: 118 times
Been thanked: 722 times

Re: Information pending...

Postby Xander9009 » 18 Jun 2015, 18:46

Out of curiosity, it sounds like this is making both a folder and a file in the duels directory. Is that right? If so, would it be possible to move the file into the folder, and have the tool located the file inside the folder and use it as if it was outside? It's an extremely minor thing (which is why I wasn't saying anything until it was working fully), but if so, it'd be cleaner and easier to use (you'd only have to remember a single folder, never having to worry about any extra files, much as the headers being inside the folders means we don't have to worry about them usually. Makes it easier, I think.

Regardless of that minor detail, it's really awesome that there seems to be so much progress. It looks like we're getting pretty close to being able to quickly add cards. A more major question: has anyone done any tests to see if adding/removing/modifying decks in the profile is possible with vanilla and modded cards?
_______________________________
Community Wad - Community Wad Website - How to Help and Report Bugs
Discord: discord.gg/4AXvHzW
User avatar
Xander9009
Programmer
 
Posts: 2905
Joined: 29 Jun 2013, 07:44
Location: Indiana, United States
Has thanked: 121 times
Been thanked: 445 times

Re: Information pending...

Postby thefiremind » 18 Jun 2015, 18:59

Xander9009 wrote:Out of curiosity, it sounds like this is making both a folder and a file in the duels directory. Is that right?
No, if you use my CreateZed with the Data.bin file provided, you supply a folder path which will be read, and a ZED file name which will be written with the data from the folder (it must be the DATA_0xx folder which is at the same level as the .METADATA folder, which now is useless). You can use it anywhere you want with any folder you want, directed to any ZED file name.

About the profile question, I'll leave the answer to other people since I have never fiddled with it.
< Former DotP 2012/2013/2014 modder >
Currently busy with life...
User avatar
thefiremind
Programmer
 
Posts: 3515
Joined: 07 Nov 2011, 10:55
Has thanked: 118 times
Been thanked: 722 times

Re: Information pending...

Postby spirolone » 19 Jun 2015, 03:38

Xander9009 wrote:Out of curiosity, it sounds like this is making both a folder and a file in the duels directory. Is that right? If so, would it be possible to move the file into the folder, and have the tool located the file inside the folder and use it as if it was outside? It's an extremely minor thing (which is why I wasn't saying anything until it was working fully), but if so, it'd be cleaner and easier to use (you'd only have to remember a single folder, never having to worry about any extra files, much as the headers being inside the folders means we don't have to worry about them usually. Makes it easier, I think.
Actually, you'll have two files, CreateZed.jar and Data.bin, and a folder (DATA_041) with content you want to add; after you use CreateZed, you'll obtain a new file (DATA_041_New.ZED). With thefiremind version you can also set name of folder and of created Zed file, with even a path, so that you can store files in other places than game folder.
I tried to have a code as easy as I could, but now I could modify what we need, so advices are very welcome. But I don't understand what you mean: would you put Data.bin file in source folder?
spirolone
Programmer
 
Posts: 190
Joined: 31 Aug 2014, 23:14
Has thanked: 7 times
Been thanked: 107 times

Re: Information pending...

Postby Xander9009 » 19 Jun 2015, 04:13

spirolone wrote:
Xander9009 wrote:Out of curiosity, it sounds like this is making both a folder and a file in the duels directory. Is that right? If so, would it be possible to move the file into the folder, and have the tool located the file inside the folder and use it as if it was outside? It's an extremely minor thing (which is why I wasn't saying anything until it was working fully), but if so, it'd be cleaner and easier to use (you'd only have to remember a single folder, never having to worry about any extra files, much as the headers being inside the folders means we don't have to worry about them usually. Makes it easier, I think.
Actually, you'll have two files, CreateZed.jar and Data.bin, and a folder (DATA_041) with content you want to add; after you use CreateZed, you'll obtain a new file (DATA_041_New.ZED). With thefiremind version you can also set name of folder and of created Zed file, with even a path, so that you can store files in other places than game folder.
I tried to have a code as easy as I could, but now I could modify what we need, so advices are very welcome. But I don't understand what you mean: would you put Data.bin file in source folder?
Keep in mind I haven't used the tool (I've been really busy lately, so I've barely kept up with the Community Wad for 2014, let alone testing out modding for 2015). Anyway, I was under the impression that Data.bin was unique to each file extracted. So, when you pack a zed from a folder, you'd need a Data.bin that is different from one you'd need for a different zed/folder.

I'm pretty sure now that the Data.bin file is a single file used for all zed creation, meaning my suggestion wouldn't be necessary. So, you can safely ignore that.

Anyway, does anyone know at least if the profile file works the same way for steam and cracked versions of the game? I can't get it quite yet, but I'm interested in trying to see about adding/removing/modifying decks. Only, I'm afraid that if the deck storage is different between steam and cracked versions, I'd do a bunch of work and it would all be useless once I buy the game, which I'm definitely going to do now that modding it seems so much closer. I may end up actually sticking with 2014, personally, if the 1024 card limit can't be overcome, but we can't really find that out for sure until we can insert a deck directly into the profile, so I think that's the next step for my end of things.

So, if anyone (I think you might be the only one who could confirm either way, spirolone) if the profile works the same or different for steam and cracked versions, then I could go ahead and start on that (and if no one knows, then I might just get started anyway).
_______________________________
Community Wad - Community Wad Website - How to Help and Report Bugs
Discord: discord.gg/4AXvHzW
User avatar
Xander9009
Programmer
 
Posts: 2905
Joined: 29 Jun 2013, 07:44
Location: Indiana, United States
Has thanked: 121 times
Been thanked: 445 times

Re: Information pending...

Postby thefiremind » 19 Jun 2015, 08:39

Xander9009 wrote:I'm pretty sure now that the Data.bin file is a single file used for all zed creation, meaning my suggestion wouldn't be necessary. So, you can safely ignore that.
Yes, the data comes from DATA_041.ZED, but spirolone found out that it's possible to use it for any ZED (as long as the directory you store is called DATA_041, my version of his tool changes the name automatically).

--------------------------------------------------------

I really hate to ask this (I would have liked to do it on my own), but in my quest for porting spirolone's code to C# I have come to a dead end. I successfully ported ZipToZed and CreateZip, but I can't seem to make ZedToZip work. I tried to save the first DecodeFirst256B output to a file for both my C# version and spirolone's Java version and they are different for the same ZED so I guess the problem (at least one of the problems) is in the DecodeFirst256B function. I'm guessing it could be because of the SHA-1 function (maybe the C# version needs something else in order to produce the same output as the Java version?) and/or because C#'s byte is unsigned while Java's byte is signed (strangely enough, for ZipToZed and CreateZip this hasn't been a problem). If I run the code against DATA_010.ZED, it crashes because localFileOffset is a big negative number so it cannot seek that. Can you see anything blatantly wrong, spirolone?
ZedToZip code ported to C# (doesn't work) | Open
Code: Select all
        // --------------------------------- ZED TO ZIP ---------------------------------

        private static BigInteger n = BigInteger.Parse("00C4D0B8819CAB92E7E87A4D2E1A7B5C911F1D7CF1818BC8B5CDC955374A019E67984A3A26FE200D8187CEADEC5637EBC009CA1163CC5016E6FD59A4773D91AA361239AA16462C8A63FE086747BAD97F7607619A4BFA325272934639922F1EC3E94BC57E2352C2C7754625542884FDE95952702AB9EE39EB4BF9FB6D6605552C07190388ABD8E49E04732A2AA1B0070A84E8B85A68485919B8B66D5CF5D12A31C0C65F11C5695A2B3BC01B9038513A6CEB47892F1E679D2F7D6F1A30FEC526C6BE19D260E8568CC9B2074B759B473BB8DE7CFAB3CC540A7D69340496B65D45274C7A602FDA2155AF24D828E756EBB8555D2F379A57DCED0EE3BF6FF8543890A435", NumberStyles.HexNumber);
        private static BigInteger e = BigInteger.Parse("11", NumberStyles.HexNumber);

        private static byte[] DecodeFirst256B(byte[] data)
        {
            BigInteger c = new BigInteger(data);
            BigInteger r = BigInteger.ModPow(c, e, n);
            byte[] content = r.ToByteArray();
            byte[] result = new byte[256];
            if (content.Length == 256)
                result = content;
            else if (content.Length > 256)
                Array.Copy(content, 1, result, 0, 256);
            else if (content.Length < 256)
                Array.Copy(content, 0, result, 256 - content.Length, content.Length);
            byte[] m = new byte[24];
            for (int i = 0; i < 20; i++)
                m[i] = result[235 + i];
            m[20] = 0; m[21] = 0; m[22] = 0;
            byte[] mask = new byte[240];
            using (SHA1 sha1 = SHA1Managed.Create())
                for (int i = 0; i < 12; i++)
                {
                    m[23] = (byte)i;
                    content = sha1.ComputeHash(m);
                    Array.Copy(content, 0, mask, i * 20, 20);
                }
            for (int i = 0; i < 235; i++)
                result[i] ^= mask[i];
            int zeroes = 0;
            // Remove non-data bytes
            if (result[zeroes] == 0) // signed byte was -0x80
                zeroes++;
            while (result[zeroes] == 128) // signed byte was 0
                zeroes++;
            byte[] decoded = new byte[214 - zeroes];
            Array.Copy(result, zeroes + 1, decoded, 0, decoded.Length);

            return decoded;
        }

        public static void ZedToZip(string zedFileName, string zipFileName)
        {
            using (FileStream zipFile = new FileStream(zipFileName, FileMode.Create, FileAccess.Write))
            {
                using (FileStream zedFile = new FileStream(zedFileName, FileMode.Open, FileAccess.Read))
                {
                    // Read Offset and Size of Central Directory
                    byte[] fileContent = null;
                    zedFile.Seek(-8, SeekOrigin.End);
                    zedFile.Read(fileContent = new byte[8]);
                    for (int i = 7; i > 0; i--)
                        fileContent[i] ^= fileContent[i - 1];
                    fileContent[0] ^= fileContent[7];
                    int centralDirOffset = ((fileContent[7] & 255) << 24) | ((fileContent[5] & 255) << 16) | ((fileContent[3] & 255) << 8) | (fileContent[1] & 255);
                    int centralDirSize = ((fileContent[6] & 255) << 24) | ((fileContent[4] & 255) << 16) | ((fileContent[2] & 255) << 8) | (fileContent[0] & 255);

                    // Read first 256 bytes of Central Directory
                    zedFile.Seek(centralDirOffset, SeekOrigin.Begin);
                    fileContent = new byte[257];
                    zedFile.Read(fileContent, 1, 256);
                    fileContent[0] = 0; // c must be considered positive
                    // Decode first 256 bytes
                    fileContent = DecodeFirst256B(fileContent);
                    centralDirSize -= (256 - fileContent.Length);   // New Central Directory Size
                    byte[] centralDir = new byte[centralDirSize];
                    Array.Copy(fileContent, 0, centralDir, 0, fileContent.Length);
                    // Read rest of Central Directory
                    zedFile.Read(centralDir, fileContent.Length, centralDirSize - fileContent.Length);
                    // Xor
                    for (int i = centralDirSize - 1; i > 0; i--)
                        centralDir[i] ^= centralDir[i - 1];
                    centralDir[0] ^= centralDir[centralDirSize - 1];

                    int pt = 0;
                    int localFileCompSize = -1;
                    int localFileOffset = -1;
                    int localFileNameLen = -1;
                    byte[] localFileData = null;
                    byte[] localFileHeader = null;
                    int entries = 0;
                    while (pt < centralDirSize - 1)
                    {   //Scan Central Dir
                        localFileOffset = ((centralDir[pt + 45] & 255) << 24) | ((centralDir[pt + 44] & 255) << 16) | ((centralDir[pt + 43] & 255) << 8) | (centralDir[pt + 42] & 255);
                        localFileCompSize = ((centralDir[pt + 23] & 255) << 24) | ((centralDir[pt + 22] & 255) << 16) | ((centralDir[pt + 21] & 255) << 8) | (centralDir[pt + 20] & 255);
                        localFileData = new byte[0];
                        if (localFileCompSize > 0)
                        {   // Not a Directory
                            if (centralDir[pt + 10] == 8)
                            {   // Local File is compressed
                                // Read first 256 bytes of Local File
                                zedFile.Seek(localFileOffset, SeekOrigin.Begin);
                                fileContent = new byte[257];
                                zedFile.Read(fileContent, 1, 256);
                                fileContent[0] = 0; // c must be considered positive
                                // Decode first 256 bytes
                                fileContent = DecodeFirst256B(fileContent);
                                localFileCompSize -= (256 - fileContent.Length);    // New Local File Compressed Size
                                centralDir[pt + 20] = (byte)(localFileCompSize & 255);
                                centralDir[pt + 21] = (byte)((localFileCompSize >> 8) & 255);
                                centralDir[pt + 22] = (byte)((localFileCompSize >> 16) & 255);
                                centralDir[pt + 23] = (byte)((localFileCompSize >> 24) & 255);
                                localFileData = new byte[localFileCompSize];
                                Array.Copy(fileContent, 0, localFileData, 0, fileContent.Length);
                                // Read rest of Local File
                                zedFile.Read(localFileData, fileContent.Length, localFileCompSize - fileContent.Length);
                                // Xor
                                for (int i = localFileCompSize - 1; i > 0; i--)
                                    localFileData[i] ^= localFileData[i - 1];
                                localFileData[0] ^= 0x53;
                            }
                            else
                            {   // Read Local File
                                localFileData = new byte[localFileCompSize];
                                zedFile.Seek(localFileOffset, SeekOrigin.Begin);
                                zedFile.Read(localFileData, 0, localFileCompSize);
                            }
                        }
                        localFileOffset = (int)zipFile.Position;    // New Local File Offset
                        centralDir[pt + 42] = (byte)(localFileOffset & 255);
                        centralDir[pt + 43] = (byte)((localFileOffset >> 8) & 255);
                        centralDir[pt + 44] = (byte)((localFileOffset >> 16) & 255);
                        centralDir[pt + 45] = (byte)((localFileOffset >> 24) & 255);

                        // Create Local File Header
                        localFileNameLen = ((centralDir[pt + 29] & 255) << 8) | (centralDir[pt + 28] & 255);
                        localFileHeader = new byte[30 + localFileNameLen];
                        localFileHeader[0] = 0x50; localFileHeader[1] = 0x4B;   // Signature
                        localFileHeader[2] = 0x03; localFileHeader[3] = 0x04;   // Signature
                        Array.Copy(centralDir, pt + 6, localFileHeader, 4, 24);
                        localFileHeader[28] = 0; localFileHeader[29] = 0;   // Extra Field Length
                        Array.Copy(centralDir, pt + 46, localFileHeader, 30, localFileNameLen);     //Local File Name

                        // Write Local File
                        zipFile.Write(localFileHeader);
                        zipFile.Write(localFileData);
                        entries += 1;
                        pt += localFileNameLen + 82;
                    }
                    // Write Central Directory
                    centralDirOffset = (int)zipFile.Position;   // New Central Directory Offset
                    zipFile.Write(centralDir);

                    // Write End of Central Directory
                    byte[] endOfCentralDir = new byte[22];
                    endOfCentralDir[0] = 0x50; endOfCentralDir[1] = 0x4B;   // Signature
                    endOfCentralDir[2] = 0x05; endOfCentralDir[3] = 0x06;   // Signature
                    endOfCentralDir[4] = 0; endOfCentralDir[5] = 0; endOfCentralDir[6] = 0; endOfCentralDir[7] = 0;
                    endOfCentralDir[8] = (byte)(entries & 255);    // Disk Entries
                    endOfCentralDir[9] = (byte)((entries >> 8) & 255);     // Disk Entries
                    endOfCentralDir[10] = endOfCentralDir[8];   // Total Entries
                    endOfCentralDir[11] = endOfCentralDir[9];   // Total Entries
                    endOfCentralDir[12] = (byte)(centralDirSize & 255);    // Central Directory Size
                    endOfCentralDir[13] = (byte)((centralDirSize >> 8) & 255);     // Central Directory Size
                    endOfCentralDir[14] = (byte)((centralDirSize >> 16) & 255);    // Central Directory Size
                    endOfCentralDir[15] = (byte)((centralDirSize >> 24) & 255);    // Central Directory Size
                    endOfCentralDir[16] = (byte)(centralDirOffset & 255);  // Central Directory Offset
                    endOfCentralDir[17] = (byte)((centralDirOffset >> 8) & 255);   // Central Directory Offset
                    endOfCentralDir[18] = (byte)((centralDirOffset >> 16) & 255);  // Central Directory Offset
                    endOfCentralDir[19] = (byte)((centralDirOffset >> 24) & 255);  // Central Directory Offset 
                    endOfCentralDir[20] = 0; endOfCentralDir[21] = 0;   // Comment Length
                    zipFile.Write(endOfCentralDir);
                }
            }
        }
(For those who are familiar with C#, the Read/Write(array) for streams that I'm using here are extensions I made in order to make the code cleaner: they are wrappers for Read/Write(array, 0, array.Length).)
< Former DotP 2012/2013/2014 modder >
Currently busy with life...
User avatar
thefiremind
Programmer
 
Posts: 3515
Joined: 07 Nov 2011, 10:55
Has thanked: 118 times
Been thanked: 722 times

Re: Information pending...

Postby spirolone » 19 Jun 2015, 14:21

thefiremind wrote:I really hate to ask this (I would have liked to do it on my own), but in my quest for porting spirolone's code to C# I have come to a dead end. I successfully ported ZipToZed and CreateZip, but I can't seem to make ZedToZip work. I tried to save the first DecodeFirst256B output to a file for both my C# version and spirolone's Java version and they are different for the same ZED so I guess the problem (at least one of the problems) is in the DecodeFirst256B function. I'm guessing it could be because of the SHA-1 function (maybe the C# version needs something else in order to produce the same output as the Java version?) and/or because C#'s byte is unsigned while Java's byte is signed (strangely enough, for ZipToZed and CreateZip this hasn't been a problem). If I run the code against DATA_010.ZED, it crashes because localFileOffset is a big negative number so it cannot seek that. Can you see anything blatantly wrong, spirolone?
Don't worry, I like to help if I can and four eyes are better than two for finding a "bug"! :wink:
Maybe I find a problem: in C# BigInteger ToByteArray returns an array with bytes in little-endian order, instead Java one is filled with bytes in big-endian order!!! #-o
spirolone
Programmer
 
Posts: 190
Joined: 31 Aug 2014, 23:14
Has thanked: 7 times
Been thanked: 107 times

PreviousNext

Return to 2015

Who is online

Users browsing this forum: No registered users and 1 guest

Main Menu

User Menu

Our Partners


Who is online

In total there is 1 user online :: 0 registered, 0 hidden and 1 guest (based on users active over the past 10 minutes)
Most users ever online was 9824 on 10 Nov 2025, 04:33

Users browsing this forum: No registered users and 1 guest

Login Form