Page 1 of 1

Problem with VC6-built server

Posted: Fri Feb 10, 2006 1:30 am
by Xypher
I built the latest CVS sources(as of 2/9/06) using VC6, and everything went fine. When I tried to start the server, though, it started printing out messages like "set_ob_value_s: 'Object' 'gravedirt' 1", and then it says "Setting up archetable". After that, a nice little error box comes up saying "Please report this error to Microsoft." (As if they can do anything about it) Does anyone know what's going on?

Posted: Fri Feb 10, 2006 8:12 am
by Ryo
Do you have the "share" directory, containing a copy of "lib" and the maps? Those are required for the game to work. Just create the "share" directory, and, using the command line, run the "copy_win32.bat" (or equivalent name) from the "lib" directory - it should copy required files to "share". Also, the server must be launched from the top-level directory containing the "share" directory.

That is, your structure should look like that:
- crossfire (directory)
- crossfire32.exe
-- plugins (directory)
-- share (directory)
--- maps (directory)

and launch the game from the crossfire directory.

I haven't tried compiling under Windows for a few weeks, maybe something is broken. I'll look and keep you informed.

That said, you could try to compile it in "debug" mode under VC6 and launch it from there, to see where it crashed. You'll need to adjust the "working directory" option for the project to suit your needs.

Posted: Sun Feb 12, 2006 3:04 pm
by Xypher
The latest versions of all of the files you talked about are in their correct places. I ran it through a debugger, and the problem occurs in arch.c, line 640, in the hasharch function.

Code: Select all

unsigned long
hasharch(const char *str, int tablesize) {
    unsigned long hash = 0;
    int i = 0;
    unsigned rot = 0;
    const char *p;

    for (p = str; i < MAXSTRING && *p; p++, i++) { // this is line 640
        hash ^= (unsigned long) *p << rot;
        rot += 2;
        if (rot >= (sizeof(long) - sizeof(char)) * 8)
            rot = 0;
    }
    return (hash % tablesize);
}
The Watch window says that when the error occurs, str is set to "", or 0x00000000.

EDIT: Fixed this bug, I added this right before the for statement:

Code: Select all

if (str == NULL) return 0;
Now there's another bug, when the treasures are being loaded. I'm working on fixing that one right now. This one is in treasure.c, line 140, in the load_treasure function. It's caused by an strcmp in an else if statement:

Code: Select all

static treasure *load_treasure(FILE *fp, int *line) {
    char buf[MAX_BUF], *cp, variable[MAX_BUF];
    treasure *t=get_empty_treasure();
    int value;

    nroftreasures++;
    while(fgets(buf,MAX_BUF,fp)!=NULL) {
	(*line)++;

	if(*buf=='#')
	    continue;
	if((cp=strchr(buf,'\n'))!=NULL)
	    *cp='\0';
	cp=buf;
	while(isspace(*cp)) /* Skip blanks */
	    cp++;

	if(sscanf(cp,"arch %s",variable)) {
	    if((t->item=find_archetype(variable))==NULL)
		LOG(llevError,"Treasure lacks archetype: %s\n",variable);
	} else if (sscanf(cp, "list %s", variable))
	    t->name = add_string(variable);
	else if (sscanf(cp, "change_name %s", variable))
	    t->change_arch.name = add_string(variable);
	else if (sscanf(cp, "change_title %s", variable))
	    t->change_arch.title = add_string(variable);
	else if (sscanf(cp, "change_slaying %s", variable))
	    t->change_arch.slaying = add_string(variable);
	else if(sscanf(cp,"chance %d",&value))
	    t->chance=(uint8) value;
	else if(sscanf(cp,"nrof %d",&value))
	    t->nrof=(uint16) value;
	else if(sscanf(cp,"magic %d",&value))
	    t->magic=(uint8) value;
	else if(!strcmp(cp,"yes")) // bug occurs here
	    t->next_yes=load_treasure(fp, line);
	else if(!strcmp(cp,"no")) // and probably here
	    t->next_no=load_treasure(fp, line);
	else if(!strcmp(cp,"end")) // and probably here
	    return t;
	else if(!strcmp(cp,"more")) { // and probably here
	    t->next=load_treasure(fp, line);
	    return t;
	} else
	    LOG(llevError,"Unknown treasure-command: '%s', last entry %s, line %d\n",
		cp,t->name?t->name:"null", *line);
    }
    LOG(llevError,"treasure lacks 'end'.\n");
    return t;
}
And, once again, it is caused by an empty string. Any ideas?