Wargus / stargus

Importer and scripts for Starcraft
GNU General Public License v2.0
126 stars 24 forks source link

Startool fails to extract data from standard install.exe file #26

Closed Hypexed closed 1 year ago

Hypexed commented 7 years ago

I was testing the latest 2.4.1 build. I managed to compile it but it failed to extract data. So then I installed it using apt-get. And that also failed. I'm using Cinnamon Mint x64.

While it fails to extract data files it does manage to extract stardat.mpq but then after loops through looking for other archives before stopping.

I found it can work if I rename the install.exe to StarCraft.mpq and it then extracts files. I tested both an install.exe from a PC StarCraft CD as well as a Starcraft Archive from a Mac CD, which is actually just another install.exe. Both files give the same result as an install.exe or starcraft.mpq. PC install.exe does work with earlier version of Startool, such as 2.2.4.

Also it tries to find the mpqlist.txt where it extracts the data files instead of the current dir meaning it must be specified. This is different to previous behavior which was easier since it could find it.

Here are logs of install.exe and starcraft.mpq: `damien@damien-Presario-V6500-Notebook-PC ~/Development/stargus-master/build $ startool /media/damien/USB\ Stick data ../mpqlist.txt Extract from "/media/damien/USB Stick" to "data" Using mpq list file "../mpqlist.txt" Please be patient, the data may take a couple of minutes to extract... Archive "/media/damien/USB Stick/install.exe" extracted: files\stardat.mpq (578, 61009744 bytes) Archive "/media/damien/USB Stick/Install.exe" extracted: files\stardat.mpq (578, 61009744 bytes) Archive "/media/damien/USB Stick/starcraft.mpq" Can't open /media/damien/USB Stick/starcraft.mpq Could not open archive "/media/damien/USB Stick/starcraft.mpq", skipping Archive "/media/damien/USB Stick/Install.exe" Archive "/media/damien/USB Stick/starcraft.mpq" Can't open /media/damien/USB Stick/starcraft.mpq Could not open archive "/media/damien/USB Stick/starcraft.mpq", skipping Archive "/media/damien/USB Stick/starcraft.mpq" Can't open /media/damien/USB Stick/starcraft.mpq Could not open archive "/media/damien/USB Stick/starcraft.mpq", skipping Archive "/media/damien/USB Stick/StarCraft.mpq" Can't open /media/damien/USB Stick/StarCraft.mpq Could not open archive "/media/damien/USB Stick/StarCraft.mpq", skipping Archive "/media/damien/USB Stick/StarDat.mpq" Can't open /media/damien/USB Stick/StarDat.mpq Could not open archive "/media/damien/USB Stick/StarDat.mpq", skipping Archive "/media/damien/USB Stick/StarDat.mpq" Can't open /media/damien/USB Stick/StarDat.mpq Could not open archive "/media/damien/USB Stick/StarDat.mpq", skipping DONE!

damien@damien-Presario-V6500-Notebook-PC ~/Development/stargus-master/build $ startool /media/damien/USB\ Stick data ../mpqlist.txt Extract from "/media/damien/USB Stick" to "data" Using mpq list file "../mpqlist.txt" Please be patient, the data may take a couple of minutes to extract... Archive "/media/damien/USB Stick/install.exe" Can't open /media/damien/USB Stick/install.exe Could not open archive "/media/damien/USB Stick/install.exe", skipping Archive "/media/damien/USB Stick/Install.exe" Can't open /media/damien/USB Stick/Install.exe Could not open archive "/media/damien/USB Stick/Install.exe", skipping Archive "/media/damien/USB Stick/starcraft.mpq" Archive "/media/damien/USB Stick/StarCraft.mpq" extracted: files\font\font8.fnt (569, 6443 bytes) ... extracted: multimaps(2)Challenger.scm (628, 55297 bytes)`

Hypexed commented 7 years ago

There's something seriously wrong with the code. Once it finds a file to extract the "stardat.mpq" from, it keeps searching. For example if it finds an "install.exe" it still looks for an "Install.exe". The same thing in this case.

But the main problem is with the Todo pointer. So it saves out a file called "remove-stardat.mpq" into the data folder. That;s fine. But, it never gets to it! It never looks in Todo or Todo[0] where that filename is stored. It always skips it and goes to the camel case version at Todo[1]! I've been playing with the code and I can't figure the damn thing out. It doesn't make sense.

When i = 4 c = Todo and that happens. But when it executes it never looks in Todo. It looks in Todo[1]! I think this code needs refactoring.

Hypexed commented 7 years ago

Okay I found the problem. I knew it would be something simple. I needed a debugger to see it. The Todo case statements are missing breaks! I hate those case statements.

That leaves the issue with the archives. As soon as it finds one it opens it up. But then it keeps looking for other archives. When it fails it skips the rest of the file list and closes the open archive. It then continues along until it reaches the end.

The end result is that it can open an archive and extract a file out but then does nothing else. So it needs to check if an archive is open before attempting to open another and if so skip trying.

On top of this, the specific checks for CDTodo or Todo are a problem also, since the file may not be in that exact location but at another index. Checking "i" for a range would be better than checking a pointer. :-)

Hypexed commented 7 years ago

Suggest fixing it like so. As it stands the code it not manageable. It needs to account for different filenames. And there should be a filename table such as a null terminated string pointer array. Even so it may be best to just scan the folder and match it without case with C functions. Since the list here is now outdated. Accounting for all cases (pun intended ;-) is getting redundant or rather out of control. :-)

Edit: It keeps messing up the code codes for some reason. Not going to try and fix again. What sort of code is a single quote for code? :-?

CDTodo[]: Control CDTodo[] = { {F,0,"","install.exe" __4}, {F,0,"","Install.exe" __4}, {F,0,"","starcraft.mpq" __4 }, {F,0,"","StarCraft.mpq" __4 }, {F,0,"","installer tome.mpq" __4 }, {F,0,"","Installer Tome.mpq" __4 }, {F,0,"","starcraft archive" __4 }, {F,0,"","StarCraft Archive" __4 }

File extraction loop: ` for (i = 0; i <= 9; ++i) { Control *c; unsigned len;

if (i <= 7) {   // CD install.exe or other MPQ file
c = &(CDTodo[i]);
len=sizeof(CDTodo) / sizeof(*CDTodo) - i;
} else {    // stardat.mpq from cd or hard drive
c = &(Todo[i-8]);
len = sizeof(Todo) / sizeof(*Todo) - (i-8);
}

for (u = 0; u < len; ++u) {
switch (c[u].Type) {
case F:
if (MpqFD) break;
if(! (strncmp(c[u].ListFile,"remove-",7)) ) {

// printf("remove\n"); psprintf(buf, c[u].ListFile, Dir); } else { psprintf(buf, c[u].ListFile, archivedir); } printf("Archive \"%s\"\n", buf); if (OpenArchive(buf) == -1) { printf("Could not open archive \"%s\", skipping\n", buf); u=len; if ((i == 9) && (arcs <2)) { fprintf(stderr, "Fatal error: Cannot extract data\n"); return 1; } } else { arcs++; if (i <= 7) {

ifdef DEBUG

printf("%s:\n", "remove-stardat.mpq");

endif

RawExtract("files\\stardat.mpq", "remove-stardat.mpq");
Todo[0].ListFile = "remove-stardat.mpq";

// printf("R %s:\n", Todo[0].ListFile); } } break; case M: ConvertMap(c[u].ListFile, c[u].File); break; case R: ConvertRgb(c[u].ListFile, c[u].File); break; case T: ConvertTileset(c[u].ListFile, c[u].File); break; case G: ConvertGfx(c[u].ListFile, c[u].File, c[u].Arg1); break; case U: ConvertGfu(c[u].ListFile, c[u].File, c[u].Arg1); break; case I: ConvertWidgets(c[u].ListFile, c[u].File, c[u].Arg1); break; case N: ConvertFont(c[u].ListFile, c[u].File, 2, c[u].Arg1); break; case W: ConvertWav(c[u].ListFile, c[u].File, c[u].Arg1); break; case H: ConvertPcx(c[u].ListFile, c[u].File); break; case E: RawExtract(c[u].ListFile, c[u].File); break; default: break; } }

if( MpqFD ) {
CloseArchive();
}

if( !strncmp(c[0].ListFile,"remove-",7) ) {
psprintf(buf,c[0].ListFile,Dir);
printf("removing \"%s\"\n",buf);
unlink(buf);
}
}`
timfel commented 7 years ago

Can you open a pull request? I am sorry to be a pain about this, but I have almost no time to work on this. If you could open a pull request i can just click merge (btw, i think you're big-endianness support pull request was based off of the wrong branch, there no endianess related commits in there)

Hypexed notifications@github.com schrieb am Sa., 13. Mai 2017, 17:44:

Suggest fixing it like so. As it stands the code it not manageable. It needs to account for different filenames. And there should be a filename table such as a null terminated string pointer array. Even so it may be best to just scan the folder and match it without case with C functions. Since the list here is now outdated. Accounting for all cases (pun intended ;-) is getting redundant or rather out of control. :-)

CDTodo[]: [code] Control CDTodo[] = { {F,0,"","install.exe" 4}, {F,0,"","Install.exe" 4}, {F,0,"","starcraft.mpq" 4 }, {F,0,"","StarCraft.mpq" 4 }, {F,0,"","installer tome.mpq" 4 }, {F,0,"","Installer Tome.mpq" 4 }, {F,0,"","starcraft archive" 4 }, {F,0,"","StarCraft Archive" 4 }, [/code]

File extraction loop: [code] for (i = 0; i <= 9; ++i) { Control *c; unsigned len;

if (i <= 7) { // CD install.exe or other MPQ file c = &(CDTodo[i]); len=sizeof(CDTodo) / sizeof(CDTodo) - i; } else { // stardat.mpq from cd or hard drive c = &(Todo[i-8]); len = sizeof(Todo) / sizeof(Todo) - (i-8); }

for (u = 0; u < len; ++u) { switch (c[u].Type) { case F: if (MpqFD) break; if(! (strncmp(c[u].ListFile,"remove-",7)) ) {

// printf("remove\n"); psprintf(buf, c[u].ListFile, Dir); } else { psprintf(buf, c[u].ListFile, archivedir); } printf("Archive "%s"\n", buf); if (OpenArchive(buf) == -1) { printf("Could not open archive "%s", skipping\n", buf); u=len; if ((i == 9) && (arcs <2)) { fprintf(stderr, "Fatal error: Cannot extract data\n"); return 1; } } else { arcs++; if (i <= 7) {

ifdef DEBUG

printf("%s:\n", "remove-stardat.mpq");

endif

RawExtract("files\stardat.mpq", "remove-stardat.mpq"); Todo[0].ListFile = "remove-stardat.mpq"; // printf("R %s:\n", Todo[0].ListFile); } } break; case M: ConvertMap(c[u].ListFile, c[u].File); break; case R: ConvertRgb(c[u].ListFile, c[u].File); break; case T: ConvertTileset(c[u].ListFile, c[u].File); break; case G: ConvertGfx(c[u].ListFile, c[u].File, c[u].Arg1); break; case U: ConvertGfu(c[u].ListFile, c[u].File, c[u].Arg1); break; case I: ConvertWidgets(c[u].ListFile, c[u].File, c[u].Arg1); break; case N: ConvertFont(c[u].ListFile, c[u].File, 2, c[u].Arg1); break; case W: ConvertWav(c[u].ListFile, c[u].File, c[u].Arg1); break; case H: ConvertPcx(c[u].ListFile, c[u].File); break; case E: RawExtract(c[u].ListFile, c[u].File); break; default: break; } }

if( MpqFD ) { CloseArchive(); }

if( !strncmp(c[0].ListFile,"remove-",7) ) { psprintf(buf,c[0].ListFile,Dir); printf("removing \"%s\"\n",buf); unlink(buf); } }

[/code]

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/Wargus/stargus/issues/26#issuecomment-301256222, or mute the thread https://github.com/notifications/unsubscribe-auth/AAC0m1iTiUHoBNyoEcS295bMs4K-x-nCks5r5c_GgaJpZM4LpUA2 .

Hypexed commented 7 years ago

I could but I'm not used to GF. In fact my coding is done on my computer and it stays there. Only binaries come out in public. :-)

Yes I hadn't yet added changes to my pull. Still need to figure that one out. Still reading Git docs...