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.
[2024-4-14. : 9:21 pm]
O)FaRTy1billion[MM] -- there are some real members mixed in those latter pages, but the *vast* majority are spam accounts
[2024-4-14. : 9:21 pm]
O)FaRTy1billion[MM] -- there are almost 3k pages
[2024-4-14. : 9:21 pm]
O)FaRTy1billion[MM] -- the real members stop around page 250
[2024-4-14. : 9:20 pm]
O)FaRTy1billion[MM] -- look at the members list
[2024-4-12. : 12:52 pm]
Oh_Man -- da real donwano
da real donwano shouted: This is the first time I've seen spam bots like this on SEN. But then again, for the last 15 years I haven't been very active.
it's pretty common
[2024-4-11. : 9:53 pm]
da real donwano -- This is the first time I've seen spam bots like this on SEN. But then again, for the last 15 years I haven't been very active.
[2024-4-11. : 4:18 pm]
IlyaSnopchenko -- still better than "Pakistani hookers in Sharjah" that I've seen advertised in another forum
[2024-4-11. : 4:07 pm]
Ultraviolet -- These guys are hella persistent
[2024-4-11. : 3:29 pm]
Vrael -- You know, the outdoors is overrated. Got any indoor gym and fitness equipment?
[2024-4-10. : 8:11 am]
Sylph-Of-Space -- Hello!
Please log in to shout.


Members Online: eksxo, Roy