Staredit Network > Forums > General StarCraft > Topic: .chk SC1 Player Numbers field
.chk SC1 Player Numbers field
Feb 3 2014, 5:18 pm
By: khr1  

Feb 3 2014, 5:18 pm khr1 Post #1



Hello,
I am looking for a way to check the number of players of a given .chk map in command-line Linux.
If someone knows which field contains this, I will write a tool that extracts it and share it with the community. (Assuming there is no easier way).
All ideas are welcome.
Thanks!



None.

Feb 3 2014, 6:22 pm Cinolt Post #2



http://www.staredit.net/starcraft/Scenario.chk

IOWN/OWNR section.



None.

Feb 4 2014, 1:24 pm khr1 Post #3



Thanks a lot!
Is there any tool already that can extract it?



None.

Feb 4 2014, 2:21 pm khr1 Post #4



OK, assuming there's no such tool, I wrote one.
Here you go:


/* FEB 2014:
* Reads thru' the sections of .chk file (as outlined in http://www.staredit.net/starcraft/Scenario.chk#Section_headers )
* Returns the number of human players.
*/

# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <string.h>
# include <errno.h>
# include <fcntl.h>

int
main (int argc, char ** argv) {
int fd = 0,
n = 0,
i = 0,
humans = 0;
char buf [2048] = { 0 },
* new = NULL;
unsigned long kolku = 0;

if (argc < 2) {
fprintf (stderr, "%s scenario.chk\n", argv [0]);
exit (EXIT_FAILURE);
}

fd = open (argv [1], O_RDWR, 0);

if (-1 == fd) {
fprintf (stderr, "open: %s: %s\n", argv [1], strerror (errno));
exit (EXIT_FAILURE);
}

while (1) {
memset (buf, 0x00, sizeof (buf));

/* 4-byte starts with the name of the section, always. */
n = read (fd, buf, 4);

if (n != 4) {
fprintf (stderr, "Either we read it all, or wrong datafile given (we need scenario.chk, not mopaq file)\n");
break;
}

/* What follows is unsigned long telling us how long this section actually is. */
n = read (fd, &kolku, sizeof (unsigned long));

fprintf (stdout, "buf = '%s', n = %d, kolku = %ld\n", buf, n, kolku);

/* We need at least `kolku' bytes. */
new = malloc (kolku + 1);
if (new == NULL) {
fprintf (stderr, "Definitely buy RAM.. malloc failed!\n");
exit (EXIT_FAILURE);
}

read (fd, new, kolku); /* read them anyway. If its the section we need, OK, if not - we just skip it. */

if (strcmp (buf, "OWNR") == 0) {
/* THIS is the section we're interested in. Check it out. */

if (kolku != 12) {
/* Should be fixed 12 here, according to http://www.staredit.net/starcraft/Scenario.chk#Section_headers */
fprintf (stdout, "Something sinister is going on... kolku != 12..\n");
}

for (i = 0; i < kolku; i ++) {
switch (new [i]) {
case 0:
fprintf (stdout, "%d byte: Inactive player\n", i);
break;

case 1:
fprintf (stdout, "%d byte: Computer (game)\n", i);
break;

case 2:
fprintf (stdout, "%d byte: Occupied by Human player\n", i);
break;

case 3:
fprintf (stdout, "%d byte: Rescue Passive\n", i);
break;

case 4:
fprintf (stdout, "%d byte: Unused\n", i);
break;

case 5:
fprintf (stdout, "%d byte: Computer\n", i);
break;

case 6:
fprintf (stdout, "%d byte: Human (open slot)\n", i);
humans ++;
break;

case 7:
fprintf (stdout, "%d byte: Neutral\n", i);
break;

case 8:
fprintf (stdout, "%d byte: Closed slot\n", i);
break;

default:
/* wat? shouldn't happen */
break;
}
}
}

free (new);
}

close (fd);
fprintf (stdout, "humans = %d\n", humans);
return (0);
}



None.

Feb 4 2014, 4:46 pm Cinolt Post #5



Code seems functionally alright, but personally I'd just make it standard C instead of UNIX specific.

Also, I'd put the code in a standalone procedure so you can call it after decompressing a chk from a MPQ or such.

For "new = malloc (kolku + 1);" not sure why the +1 is there.

(strcmp (buf, "OWNR") == 0 is the same thing as *(long *)buf == *(long *)"OWNR" which to me seems more expressive.



None.

Feb 4 2014, 7:52 pm khr1 Post #6



The code is ANSI C, of course, and has nothing to do with UNIX. Why would you think that?
It is a 4-byte string. strcmp is prudent here, and should be treated as string, not as long* of course..
1 is a habit.

The code *is* tested and working. Making it into a function should take around 15-30 seconds.

Post has been edited 1 time(s), last time on Feb 5 2014, 7:52 pm by NudeRaider. Reason: removed inciting remark



None.

Feb 4 2014, 8:41 pm O)FaRTy1billion[MM] Post #7

👻 👾 👽 💪

Quote from khr1
It is a 4-byte string. strcmp is prudent here, and should be treated as string, not as long* of course..
It is usually read as an int. Were it a proper string it would be null-terminated.

If you only want to see it for informational purposes it is one of the stats shown in MapStats.



TinyMap2 - Latest in map compression! ( 7/09/14 - New build! )
EUD Action Enabler - Lightweight EUD/EPD support! (ChaosLauncher/MPQDraft support!)
EUDDB - topic - Help out by adding your EUDs! Or Submit reference files in the References tab!
MapSketch - New image->map generator!
EUDTrig - topic - Quickly and easily convert offsets to EUDs! (extended players supported)
SC2 Map Texture Mask Importer/Exporter - Edit texture placement in an image editor!
\:farty\: This page has been viewed [img]http://farty1billion.dyndns.org/Clicky.php?img.gif[/img] times!

Feb 4 2014, 10:44 pm Cinolt Post #8



unistd.h and fcntl.h is not ANSI C.

Never said it wasn't tested, never said it wasn't working.

know how to take constructive criticism.

Post has been edited 1 time(s), last time on Feb 5 2014, 7:56 pm by NudeRaider. Reason: removed response to inciting remark



None.

Feb 5 2014, 1:45 pm khr1 Post #9



You said it was UNIX specific.
But it is not.
You didn't even test it under any Windows compiler to see if you're wrong.
And you are.

I posted the code in case someone has the same problem as me, to save, eventually, someone's time.

Whats the point of your remarks, I can't understand..

Post has been edited 1 time(s), last time on Feb 5 2014, 7:58 pm by NudeRaider. Reason: removed inciting remark



None.

Feb 5 2014, 2:21 pm Heinermann Post #10

SDE, BWAPI owner, hacker.

Here's a version independent of the non-standard headers, with section string bug fixed, redundancy removed, but ultimately untested.

Code
/* FEB 2014:
* Reads thru' the sections of .chk file (as outlined in http://www.staredit.net/starcraft/Scenario.chk#Section_headers )
* Returns the number of human players.
*/

# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <errno.h>

int main (int argc, char ** argv)
{
    int n = 0, i = 0, humans = 0;
    FILE *fd;

    char buf[2048] = { 0 }, *pdata = NULL, *playertype;
    unsigned long kolku = 0;

    if (argc < 2)
    {
        fprintf(stderr, "%s scenario.chk\n", argv [0]);
        return 1;
    }

    fd = fopen(argv[1], "r+");
    if (NULL == fd)
    {
        fprintf(stderr, "open: %s: %s\n", argv [1], strerror(errno));
        return 1;
    }

    while (1)
    {
        memset(buf, 0, sizeof (buf));

        /* 4-byte starts with the name of the section, always. */
        n = fread(buf, 4, 1, fd);
        if (n == 0)
        {
            fprintf(stderr, "Either we read it all, or wrong datafile given (we need scenario.chk, not mopaq file)\n");
            break;
        }

        /* What follows is unsigned long telling us how long this section actually is. */
        n = fread(&kolku, sizeof (kolku), 1, fd);

        printf("buf = '%s', n = %d, kolku = %ld\n", buf, n, kolku);

        /* We need at least `kolku' bytes. */
        pdata = malloc(kolku + 1);
        if (pdata == NULL)
        {
            fprintf(stderr, "Definitely buy RAM.. malloc failed!\n");
            return 1;
        }

        fread(pdata, 1, kolku, fd); /* read them anyway. If its the section we need, OK, if not - we just skip it. */

        if ( strncmp(buf, "OWNR", 4) == 0 )
        {
            /* THIS is the section we're interested in. Check it out. */

            if (kolku != 12)
            {
                /* Should be fixed 12 here, according to http://www.staredit.net/starcraft/Scenario.chk#Section_headers */
                printf("Something sinister is going on... kolku != 12..\n");
            }

            for (i = 0; i < (int)kolku; ++i )
            {
                switch (pdata[i])
                {
                case 0:
                    playertype = "Inactive";
                    break;
                case 1:
                    playertype = "Computer (game)";
                    break;
                case 2:
                    playertype = "Occupied by human";
                    break;
                case 3:
                    playertype = "Rescue Passive";
                    break;
                case 4:
                    playertype = "Unused";
                    break;
                case 5:
                    playertype = "Computer";
                    break;
                case 6:
                    playertype = "Human (open)";
                    humans ++;
                    break;
                case 7:
                    playertype = "Neutral";
                    break;
                case 8:
                    playertype = "Closed";
                    break;
                default:
                    /* wat? shouldn't happen */
                    playertype = "WAT??";
                    break;
                }
                printf("%d byte: %s\n", i, playertype);
            }
        }

        free (pdata);
    }

    fclose(fd);
    printf("humans = %d\n", humans);

    return 0;
}


Post has been edited 1 time(s), last time on Feb 5 2014, 2:28 pm by Heinermann.




Feb 5 2014, 4:42 pm Cinolt Post #11



I don't give a shit that it works for whatever compiler you happened to test it with, I never said it didn't work.

Those header files that I mentioned are not ANSI C, and you said it was ANSI C, and it's not ANSI C, so you're wrong.

http://en.wikipedia.org/wiki/Unistd.h

"In the C and C programming languages, unistd.h is the name of the header file that provides access to the POSIX operating system API. It is defined by the POSIX.1 standard, the base of the Single Unix Specification, and should therefore be available in any conforming (or quasi-conforming) operating system/compiler (all official versions of UNIX, including Mac OS X, GNU/Linux, etc.)."

POSIX is not ANSI C.

By the way you wouldn't even have made this thread if you just searched "scenario.chk".

Post has been edited 1 time(s), last time on Feb 5 2014, 7:59 pm by NudeRaider. Reason: removed inciting remark



None.

Options
  Back to forum
Please log in to reply to this topic or to report it.
Members in this topic: None.
[10:00 am]
KrayZee -- :0
[09:36 am]
Suicidal Insanity -- They just have a discord for posting even more memes than they post here ;(
[08:20 am]
SiKiN -- You guys have a testing group for maps? Or a discord?
[06:34 am]
MasterJohnny -- Zoan
Zoan shouted: guys im going to China in 2 days
Bring dust mask things and a mosquitoes net. If anyone asks nothing happened on June 4 1984.
[06:34 am]
O)FaRTy1billion[MM] -- NudeRaider
NudeRaider shouted: FaRTy1billion I'm wondering: Does extended anything (like place extended units for supply) count as euds (i'd guess no)? Do these overflows still work?
I'm pretty sure all extended units and extended players were fixed
[06:14 am]
Pr0nogo -- I mean I get people not wanting to put in the work, it's not easy, but then they'll say as much without people whining in the shoutbox about my posts
[06:14 am]
Pr0nogo -- in this case quality is my priority, so... yeah, you should share that LMAO
[06:13 am]
Pr0nogo -- I was just snarking at dem0n with that response anyways, but i don't think you can argue that deliberately handicapping your work within sc's engine means you don't care as much about quality
[06:13 am]
Pr0nogo -- NudeRaider
NudeRaider shouted: Pr0nogo still turning a blind eye for the reason map making is more widespread than modding just insults your intelligence. It's an almost autistic view to demand that everyone shares your priorities.
i am autistic
[05:58 am]
NudeRaider -- Pr0nogo
Pr0nogo shouted: Dem0n people should probably stop just making maps
still turning a blind eye for the reason map making is more widespread than modding just insults your intelligence. It's an almost autistic view to demand that everyone shares your priorities.
Please log in to shout.


Members Online: Roy, oqoremawo