--- deliantra/server/socket/request.C 2006/08/21 07:13:32 1.7 +++ deliantra/server/socket/request.C 2006/09/07 20:03:21 1.15 @@ -1,6 +1,6 @@ /* * static char *rcsid_init_c = - * "$Id: request.C,v 1.7 2006/08/21 07:13:32 root Exp $"; + * "$Id: request.C,v 1.15 2006/09/07 20:03:21 pippijn Exp $"; */ /* @@ -130,8 +130,8 @@ my = ns->mapy; if (ns->mapmode == Map1aCmd) { - mx += MAX_HEAD_OFFSET; - my += MAX_HEAD_OFFSET; + mx += MAX_HEAD_OFFSET; + my += MAX_HEAD_OFFSET; } /* the x and y here are coordinates for the new map, i.e. if we moved @@ -141,20 +141,20 @@ * are preserved, and the check_head thinks it needs to clear them. */ for(x=0; x= ns->mapx || y >= ns->mapy) { - /* clear cells outside the viewable area */ - memset(&newmap.cells[x][y], 0, sizeof(struct MapCell)); - } - else if ((x+dx) < 0 || (x+dx) >= ns->mapx || (y+dy) < 0 || (y + dy) >= ns->mapy) { - /* clear newly visible tiles within the viewable area */ - memset(&(newmap.cells[x][y]), 0, sizeof(struct MapCell)); - } - else { - memcpy(&(newmap.cells[x][y]), - &(ns->lastmap.cells[x+dx][y+dy]),sizeof(struct MapCell)); - } - } + for(y=0; y= ns->mapx || y >= ns->mapy) { + /* clear cells outside the viewable area */ + memset(&newmap.cells[x][y], 0, sizeof(struct MapCell)); + } + else if ((x+dx) < 0 || (x+dx) >= ns->mapx || (y+dy) < 0 || (y + dy) >= ns->mapy) { + /* clear newly visible tiles within the viewable area */ + memset(&(newmap.cells[x][y]), 0, sizeof(struct MapCell)); + } + else { + memcpy(&(newmap.cells[x][y]), + &(ns->lastmap.cells[x+dx][y+dy]),sizeof(struct MapCell)); + } + } } memcpy(&(ns->lastmap), &newmap,sizeof(struct Map)); @@ -235,7 +235,7 @@ void ExtCmd (char *buf, int len, player *pl) { - execute_global_event (EVENT_EXTCMD, pl, buf, len); + INVOKE_PLAYER (EXTCMD, pl, ARG_DATA (buf, len)); } void MapInfoCmd (char *buf, int len, player *pl) @@ -243,7 +243,7 @@ // mapinfo tag spatial flags x y w h hash - char bigbuf[MAX_BUF], *cp, *token; + char bigbuf[MAX_BUF], *token; token = buf; // copy token @@ -331,142 +331,142 @@ strcpy(cmdback,"setup"); for(s=0;s=len) - break; - - param = &buf[s]; - - for(;buf[s] && buf[s] != ' ';s++) ; - buf[s++]=0; - while (buf[s] == ' ') s++; - - slen = strlen(cmdback); - safe_strcat(cmdback, " ", &slen, HUGE_BUF); - safe_strcat(cmdback, cmd, &slen, HUGE_BUF); - safe_strcat(cmdback, " ", &slen, HUGE_BUF); - - if (!strcmp(cmd,"sound")) { - ns->sound = atoi(param); - safe_strcat(cmdback, param, &slen, HUGE_BUF); - } - else if (!strcmp(cmd,"exp64")) { - ns->exp64 = atoi(param); - safe_strcat(cmdback, param, &slen, HUGE_BUF); - } else if (!strcmp(cmd, "spellmon")) { - ns->monitor_spells = atoi(param); - safe_strcat(cmdback, param, &slen, HUGE_BUF); - } else if (!strcmp(cmd,"darkness")) { - ns->darkness = atoi(param); - safe_strcat(cmdback, param, &slen, HUGE_BUF); - } else if (!strcmp(cmd,"map1cmd")) { - if (atoi(param)) ns->mapmode = Map1Cmd; - /* if beyond this size, need to use map1cmd no matter what */ - if (ns->mapx>11 || ns->mapy>11) ns->mapmode = Map1Cmd; - safe_strcat(cmdback, ns->mapmode == Map1Cmd?"1":"0", &slen, HUGE_BUF); - } else if (!strcmp(cmd,"map1acmd")) { - if (atoi(param)) ns->mapmode = Map1aCmd; - /* if beyond this size, need to use map1acmd no matter what */ - if (ns->mapx>11 || ns->mapy>11) ns->mapmode = Map1aCmd; - safe_strcat(cmdback, ns->mapmode == Map1aCmd?"1":"0", &slen, HUGE_BUF); + /* find the next space, and put a null there */ + for(;buf[s] && buf[s] != ' ';s++) ; + buf[s++]=0; + while (buf[s] == ' ') s++; + + if(s>=len) + break; + + param = &buf[s]; + + for(;buf[s] && buf[s] != ' ';s++) ; + buf[s++]=0; + while (buf[s] == ' ') s++; + + slen = strlen(cmdback); + safe_strcat(cmdback, " ", &slen, HUGE_BUF); + safe_strcat(cmdback, cmd, &slen, HUGE_BUF); + safe_strcat(cmdback, " ", &slen, HUGE_BUF); + + if (!strcmp(cmd,"sound")) { + ns->sound = atoi(param); + safe_strcat(cmdback, param, &slen, HUGE_BUF); + } + else if (!strcmp(cmd,"exp64")) { + ns->exp64 = atoi(param); + safe_strcat(cmdback, param, &slen, HUGE_BUF); + } else if (!strcmp(cmd, "spellmon")) { + ns->monitor_spells = atoi(param); + safe_strcat(cmdback, param, &slen, HUGE_BUF); + } else if (!strcmp(cmd,"darkness")) { + ns->darkness = atoi(param); + safe_strcat(cmdback, param, &slen, HUGE_BUF); + } else if (!strcmp(cmd,"map1cmd")) { + if (atoi(param)) ns->mapmode = Map1Cmd; + /* if beyond this size, need to use map1cmd no matter what */ + if (ns->mapx>11 || ns->mapy>11) ns->mapmode = Map1Cmd; + safe_strcat(cmdback, ns->mapmode == Map1Cmd?"1":"0", &slen, HUGE_BUF); + } else if (!strcmp(cmd,"map1acmd")) { + if (atoi(param)) ns->mapmode = Map1aCmd; + /* if beyond this size, need to use map1acmd no matter what */ + if (ns->mapx>11 || ns->mapy>11) ns->mapmode = Map1aCmd; + safe_strcat(cmdback, ns->mapmode == Map1aCmd?"1":"0", &slen, HUGE_BUF); } else if (!strcmp(cmd,"newmapcmd")) { ns->newmapcmd= atoi(param); - safe_strcat(cmdback, param, &slen, HUGE_BUF); + safe_strcat(cmdback, param, &slen, HUGE_BUF); // } else if (!strcmp(cmd,"plugincmd")) { // ns->plugincmd = atoi(param); // safe_strcat(cmdback, param, &slen, HUGE_BUF); - } else if (!strcmp(cmd,"mapinfocmd")) { - ns->mapinfocmd = atoi(param); - safe_strcat(cmdback, "1", &slen, HUGE_BUF); - } else if (!strcmp(cmd,"extcmd")) { - ns->extcmd = atoi(param); - safe_strcat(cmdback, "1", &slen, HUGE_BUF); - } else if (!strcmp(cmd,"extmap")) { - ns->extmap = atoi(param); - safe_strcat(cmdback, "1", &slen, HUGE_BUF); - } else if (!strcmp(cmd,"facecache")) { - ns->facecache = atoi(param); - safe_strcat(cmdback, param, &slen, HUGE_BUF); - } else if (!strcmp(cmd,"faceset")) { - char tmpbuf[20]; - int q = atoi(param); - - if (is_valid_faceset(q)) - ns->faceset=q; - sprintf(tmpbuf,"%d", ns->faceset); - safe_strcat(cmdback, tmpbuf, &slen, HUGE_BUF); - /* if the client is using faceset, it knows about image2 command */ - ns->image2=1; - } else if (!strcmp(cmd,"itemcmd")) { - /* Version of the item protocol command to use. Currently, - * only supported versions are 1 and 2. Using a numeric - * value will make it very easy to extend this in the future. - */ - char tmpbuf[20]; - int q = atoi(param); - if (q<1 || q>2) { - strcpy(tmpbuf,"FALSE"); - } else { - ns->itemcmd = q; - sprintf(tmpbuf,"%d", ns->itemcmd); - } - safe_strcat(cmdback, tmpbuf, &slen, HUGE_BUF); + } else if (!strcmp(cmd,"mapinfocmd")) { + ns->mapinfocmd = atoi(param); + safe_strcat(cmdback, "1", &slen, HUGE_BUF); + } else if (!strcmp(cmd,"extcmd")) { + ns->extcmd = atoi(param); + safe_strcat(cmdback, "1", &slen, HUGE_BUF); + } else if (!strcmp(cmd,"extmap")) { + ns->extmap = atoi(param); + safe_strcat(cmdback, "1", &slen, HUGE_BUF); + } else if (!strcmp(cmd,"facecache")) { + ns->facecache = atoi(param); + safe_strcat(cmdback, param, &slen, HUGE_BUF); + } else if (!strcmp(cmd,"faceset")) { + char tmpbuf[20]; + int q = atoi(param); + + if (is_valid_faceset(q)) + ns->faceset=q; + sprintf(tmpbuf,"%d", ns->faceset); + safe_strcat(cmdback, tmpbuf, &slen, HUGE_BUF); + /* if the client is using faceset, it knows about image2 command */ + ns->image2=1; + } else if (!strcmp(cmd,"itemcmd")) { + /* Version of the item protocol command to use. Currently, + * only supported versions are 1 and 2. Using a numeric + * value will make it very easy to extend this in the future. + */ + char tmpbuf[20]; + int q = atoi(param); + if (q<1 || q>2) { + strcpy(tmpbuf,"FALSE"); + } else { + ns->itemcmd = q; + sprintf(tmpbuf,"%d", ns->itemcmd); + } + safe_strcat(cmdback, tmpbuf, &slen, HUGE_BUF); } else if (!strcmp(cmd,"mapsize")) { - int x, y=0; - char tmpbuf[MAX_BUF], *cp; + int x, y=0; + char tmpbuf[MAX_BUF], *cp; + + x = atoi(param); + for (cp = param; *cp!=0; cp++) + if (*cp == 'x' || *cp == 'X') { + y = atoi(cp+1); + break; + } + if (x < 9 || y < 9 || x>MAP_CLIENT_X || y > MAP_CLIENT_Y) { + sprintf(tmpbuf," %dx%d", MAP_CLIENT_X, MAP_CLIENT_Y); + safe_strcat(cmdback, tmpbuf, &slen, HUGE_BUF); + } else { + ns->mapx = x; + ns->mapy = y; + /* better to send back what we are really using and not the + * param as given to us in case it gets parsed differently. + */ + sprintf(tmpbuf,"%dx%d", x,y); + safe_strcat(cmdback, tmpbuf, &slen, HUGE_BUF); + /* If beyond this size and still using orig map command, need to + * go to map1cmd. + */ + if ((x>11 || y>11) && ns->mapmode == Map0Cmd) ns->mapmode = Map1Cmd; + } + } else if (!strcmp(cmd,"extendedMapInfos")) { + /* Added by tchize + * prepare to use the mapextended command + */ + char tmpbuf[20]; + ns->ext_mapinfos = (atoi(param)); + sprintf(tmpbuf,"%d", ns->ext_mapinfos); + safe_strcat(cmdback, tmpbuf, &slen, HUGE_BUF); + } else if (!strcmp(cmd,"extendedTextInfos")) { + /* Added by tchize + * prepare to use the extended text commands + * Client toggle this to non zero to get exttext + */ + char tmpbuf[20]; - x = atoi(param); - for (cp = param; *cp!=0; cp++) - if (*cp == 'x' || *cp == 'X') { - y = atoi(cp+1); - break; - } - if (x < 9 || y < 9 || x>MAP_CLIENT_X || y > MAP_CLIENT_Y) { - sprintf(tmpbuf," %dx%d", MAP_CLIENT_X, MAP_CLIENT_Y); - safe_strcat(cmdback, tmpbuf, &slen, HUGE_BUF); - } else { - ns->mapx = x; - ns->mapy = y; - /* better to send back what we are really using and not the - * param as given to us in case it gets parsed differently. - */ - sprintf(tmpbuf,"%dx%d", x,y); - safe_strcat(cmdback, tmpbuf, &slen, HUGE_BUF); - /* If beyond this size and still using orig map command, need to - * go to map1cmd. - */ - if ((x>11 || y>11) && ns->mapmode == Map0Cmd) ns->mapmode = Map1Cmd; - } - } else if (!strcmp(cmd,"extendedMapInfos")) { - /* Added by tchize - * prepare to use the mapextended command - */ - char tmpbuf[20]; - ns->ext_mapinfos = (atoi(param)); - sprintf(tmpbuf,"%d", ns->ext_mapinfos); - safe_strcat(cmdback, tmpbuf, &slen, HUGE_BUF); - } else if (!strcmp(cmd,"extendedTextInfos")) { - /* Added by tchize - * prepare to use the extended text commands - * Client toggle this to non zero to get exttext - */ - char tmpbuf[20]; - - ns->has_readable_type = (atoi(param)); - sprintf(tmpbuf,"%d", ns->has_readable_type); - safe_strcat(cmdback, tmpbuf, &slen, HUGE_BUF); - } else { - /* Didn't get a setup command we understood - - * report a failure to the client. - */ - safe_strcat(cmdback, "FALSE", &slen, HUGE_BUF); - } + ns->has_readable_type = (atoi(param)); + sprintf(tmpbuf,"%d", ns->has_readable_type); + safe_strcat(cmdback, tmpbuf, &slen, HUGE_BUF); + } else { + /* Didn't get a setup command we understood - + * report a failure to the client. + */ + safe_strcat(cmdback, "FALSE", &slen, HUGE_BUF); + } } /* for processing all the setup commands */ LOG(llevInfo,"SendBack SetupCmd:: %s\n", cmdback); Write_String_To_Socket(ns, cmdback, strlen(cmdback)); @@ -483,16 +483,16 @@ Settings oldsettings; oldsettings=settings; if (ns->status != Ns_Add || add_player(ns)) { - Write_String_To_Socket(ns, "addme_failed",12); + Write_String_To_Socket(ns, "addme_failed",12); } else { - /* Basically, the add_player copies the socket structure into - * the player structure, so this one (which is from init_sockets) - * is not needed anymore. The write below should still work, as the - * stuff in ns is still relevant. - */ - Write_String_To_Socket(ns, "addme_success",13); - socket_info.nconns--; - ns->status = Ns_Avail; + /* Basically, the add_player copies the socket structure into + * the player structure, so this one (which is from init_sockets) + * is not needed anymore. The write below should still work, as the + * stuff in ns is still relevant. + */ + Write_String_To_Socket(ns, "addme_success",13); + socket_info.nconns--; + ns->status = Ns_Avail; } settings=oldsettings; } @@ -596,13 +596,13 @@ if ((!FindSmooth (face, &smoothface)) && (!FindSmooth ( smooth_face->number, &smoothface))) { - LOG(llevError,"could not findsmooth for %d. Neither default (%s)\n",face,smooth_face->name); - ns->faces_sent[face] |= NS_FACESENT_SMOOTH; - return; + LOG(llevError,"could not findsmooth for %d. Neither default (%s)\n", face, &smooth_face->name); + ns->faces_sent[face] |= NS_FACESENT_SMOOTH; + return; } if (!(ns->faces_sent[smoothface] & NS_FACESENT_FACE)) - esrv_send_face(ns, smoothface, 0); + esrv_send_face(ns, smoothface, 0); ns->faces_sent[face] |= NS_FACESENT_SMOOTH; @@ -642,27 +642,27 @@ * an idea of the problem, but they deserve what they get */ if (pl->state!=ST_PLAYING) { - new_draw_info_format(NDI_UNIQUE, 0,pl->ob, - "You can not issue commands - state is not ST_PLAYING (%s)", buf); - return; + new_draw_info_format(NDI_UNIQUE, 0,pl->ob, + "You can not issue commands - state is not ST_PLAYING (%s)", buf); + return; } /* Check if there is a count. In theory, a zero count could also be * sent, so check for that also. */ if (atoi(buf) || buf[0]=='0') { - pl->count=atoi((char*)buf); - buf=strchr(buf,' '); /* advance beyond the numbers */ - if (!buf) { + pl->count=atoi((char*)buf); + buf=strchr(buf,' '); /* advance beyond the numbers */ + if (!buf) { #ifdef ESRV_DEBUG - LOG(llevDebug,"PlayerCmd: Got count but no command.\n"); + LOG(llevDebug,"PlayerCmd: Got count but no command.\n"); #endif - return; - } - buf++; + return; + } + buf++; } /* This should not happen anymore. */ if (pl->ob->speed_left<-1.0) { - LOG(llevError,"Player has negative time - shouldn't do command.\n"); + LOG(llevError,"Player has negative time - shouldn't do command.\n"); } /* In c_new.c */ execute_newserver_command(pl->ob, (char*)buf); @@ -691,15 +691,15 @@ SockList sl; if (len < 7) { - LOG(llevDebug,"Corrupt ncom command <%s> not long enough - discarding\n", buf); - return; + LOG(llevDebug,"Corrupt ncom command <%s> not long enough - discarding\n", buf); + return; } packet = GetShort_String(buf); repeat = GetInt_String(buf+2); /* -1 is special - no repeat, but don't update */ if (repeat!=-1) { - pl->count=repeat; + pl->count=repeat; } if ((len-4) >= MAX_BUF) len=MAX_BUF-5; @@ -712,14 +712,14 @@ * an idea of the problem, but they deserve what they get */ if (pl->state!=ST_PLAYING) { - new_draw_info_format(NDI_UNIQUE, 0,pl->ob, - "You can not issue commands - state is not ST_PLAYING (%s)", buf); - return; + new_draw_info_format(NDI_UNIQUE, 0,pl->ob, + "You can not issue commands - state is not ST_PLAYING (%s)", buf); + return; } /* This should not happen anymore. */ if (pl->ob->speed_left<-1.0) { - LOG(llevError,"Player has negative time - shouldn't do command.\n"); + LOG(llevError,"Player has negative time - shouldn't do command.\n"); } /* In c_new.c */ execute_newserver_command(pl->ob, (char*)command); @@ -737,7 +737,7 @@ SockList_AddShort(&sl,packet); if (FABS(pl->ob->speed) < 0.001) time=MAX_TIME * 100; else - time = ( int )( MAX_TIME/ FABS(pl->ob->speed) ); + time = ( int )( MAX_TIME/ FABS(pl->ob->speed) ); SockList_AddInt(&sl,time); Send_With_Handling(&pl->socket, &sl); } @@ -759,50 +759,50 @@ /* this avoids any hacking here */ switch (pl->state) { - case ST_PLAYING: - LOG(llevError,"Got reply message with ST_PLAYING input state\n"); - break; - - case ST_PLAY_AGAIN: - /* We can check this for return value (2==quit). Maybe we - * should, and do something appropriate? - */ - receive_play_again(pl->ob, buf[0]); - break; - - case ST_ROLL_STAT: - key_roll_stat(pl->ob,buf[0]); - break; + case ST_PLAYING: + LOG(llevError,"Got reply message with ST_PLAYING input state\n"); + break; + + case ST_PLAY_AGAIN: + /* We can check this for return value (2==quit). Maybe we + * should, and do something appropriate? + */ + receive_play_again(pl->ob, buf[0]); + break; + + case ST_ROLL_STAT: + key_roll_stat(pl->ob,buf[0]); + break; - case ST_CHANGE_CLASS: + case ST_CHANGE_CLASS: key_change_class(pl->ob, buf[0]); break; - case ST_CONFIRM_QUIT: - key_confirm_quit(pl->ob, buf[0]); - break; - - case ST_CONFIGURE: - LOG(llevError,"In client input handling, but into configure state\n"); - pl->state = ST_PLAYING; - break; - - case ST_GET_NAME: - receive_player_name(pl->ob,13); - break; - - case ST_GET_PASSWORD: - case ST_CONFIRM_PASSWORD: - receive_player_password(pl->ob,13); - break; - - case ST_GET_PARTY_PASSWORD: /* Get password for party */ - receive_party_password(pl->ob,13); - break; + case ST_CONFIRM_QUIT: + key_confirm_quit(pl->ob, buf[0]); + break; + + case ST_CONFIGURE: + LOG(llevError,"In client input handling, but into configure state\n"); + pl->state = ST_PLAYING; + break; + + case ST_GET_NAME: + receive_player_name(pl->ob,13); + break; + + case ST_GET_PASSWORD: + case ST_CONFIRM_PASSWORD: + receive_player_password(pl->ob,13); + break; + + case ST_GET_PARTY_PASSWORD: /* Get password for party */ + receive_party_password(pl->ob,13); + break; - default: - LOG(llevError,"Unknown input state: %d\n", pl->state); + default: + LOG(llevError,"Unknown input state: %d\n", pl->state); } } @@ -817,17 +817,17 @@ { char *cp; char version_warning[256]; - + if (!buf) { - LOG(llevError, "CS: received corrupted version command\n"); - return; + LOG(llevError, "CS: received corrupted version command\n"); + return; } ns->cs_version = atoi(buf); ns->sc_version = ns->cs_version; if (VERSION_CS != ns->cs_version) { #ifdef ESRV_DEBUG - LOG(llevDebug, "CS: csversion mismatch (%d,%d)\n", VERSION_CS,ns->cs_version); + LOG(llevDebug, "CS: csversion mismatch (%d,%d)\n", VERSION_CS,ns->cs_version); #endif } cp = strchr(buf+1,' '); @@ -835,29 +835,29 @@ ns->sc_version = atoi(cp); if (VERSION_SC != ns->sc_version) { #ifdef ESRV_DEBUG - LOG(llevDebug, "CS: scversion mismatch (%d,%d)\n",VERSION_SC,ns->sc_version); + LOG(llevDebug, "CS: scversion mismatch (%d,%d)\n",VERSION_SC,ns->sc_version); #endif } cp = strchr(cp+1, ' '); if (cp) { - LOG(llevDebug,"CS: connection from client of type <%s>, ip %s\n", cp, ns->host); + LOG(llevDebug,"CS: connection from client of type <%s>, ip %s\n", cp, ns->host); snprintf (ns->client, sizeof (ns->client), "%s", cp + 1); - /* This is first implementation - i skip all beta DX clients with it - * Add later stuff here for other clients - */ - - /* these are old dxclients */ - /* Version 1024 added support for singular + plural name values - - * requiing this minimal value reduces complexity of that code, and it - * has been around for a long time. - */ - if(!strcmp(" CF DX CLIENT", cp) || ns->sc_version < 1024 ) - { - sprintf(version_warning,"drawinfo %d %s", NDI_RED, "**** VERSION WARNING ****\n**** CLIENT IS TOO OLD!! UPDATE THE CLIENT!! ****"); - Write_String_To_Socket(ns, version_warning, strlen(version_warning)); - } + /* This is first implementation - i skip all beta DX clients with it + * Add later stuff here for other clients + */ + + /* these are old dxclients */ + /* Version 1024 added support for singular + plural name values - + * requiing this minimal value reduces complexity of that code, and it + * has been around for a long time. + */ + if(!strcmp(" CF DX CLIENT", cp) || ns->sc_version < 1024 ) + { + sprintf(version_warning,"drawinfo %d %s", NDI_RED, "**** VERSION WARNING ****\n**** CLIENT IS TOO OLD!! UPDATE THE CLIENT!! ****"); + Write_String_To_Socket(ns, version_warning, strlen(version_warning)); + } } } @@ -901,12 +901,12 @@ * sscanf? */ for (i=0; i<2; i++) { - vals[i]=atoi(buf); - if (!(buf = strchr(buf, ' '))) { - LOG(llevError,"Incomplete move command: %s\n", buf); - return; - } - buf++; + vals[i]=atoi(buf); + if (!(buf = strchr(buf, ' '))) { + LOG(llevError,"Incomplete move command: %s\n", buf); + return; + } + buf++; } vals[2]=atoi(buf); @@ -935,37 +935,37 @@ } #define AddIfInt64(Old,New,Type) if (Old != New) {\ - Old = New; \ - SockList_AddChar(&sl, Type); \ - SockList_AddInt64(&sl, New); \ - } + Old = New; \ + SockList_AddChar(&sl, Type); \ + SockList_AddInt64(&sl, New); \ + } #define AddIfInt(Old,New,Type) if (Old != New) {\ - Old = New; \ - SockList_AddChar(&sl, Type); \ - SockList_AddInt(&sl, New); \ - } + Old = New; \ + SockList_AddChar(&sl, Type); \ + SockList_AddInt(&sl, New); \ + } #define AddIfShort(Old,New,Type) if (Old != New) {\ - Old = New; \ - SockList_AddChar(&sl, Type); \ - SockList_AddShort(&sl, New); \ - } + Old = New; \ + SockList_AddChar(&sl, Type); \ + SockList_AddShort(&sl, New); \ + } #define AddIfFloat(Old,New,Type) if (Old != New) {\ - Old = New; \ - SockList_AddChar(&sl, Type); \ - SockList_AddInt(&sl,(long)(New*FLOAT_MULTI));\ - } + Old = New; \ + SockList_AddChar(&sl, Type); \ + SockList_AddInt(&sl,(long)(New*FLOAT_MULTI));\ + } #define AddIfString(Old,New,Type) if (Old == NULL || strcmp(Old,New)) {\ - if (Old) free(Old);\ - Old = strdup_local(New);\ - SockList_AddChar(&sl, Type); \ - SockList_AddChar(&sl, ( char )strlen(New)); \ - strcpy((char*)sl.buf + sl.len, New); \ - sl.len += strlen(New); \ - } + if (Old) free(Old);\ + Old = strdup_local(New);\ + SockList_AddChar(&sl, Type); \ + SockList_AddChar(&sl, ( char )strlen(New)); \ + strcpy((char*)sl.buf + sl.len, New); \ + sl.len += strlen(New); \ + } /** * Sends a statistics update. We look at the old values, @@ -1000,25 +1000,25 @@ AddIfShort(pl->last_stats.Cha, pl->ob->stats.Cha, CS_STAT_CHA); } if(pl->socket.exp64) { - uint8 s; - for(s=0;slast_skill_ob[s] && - pl->last_skill_exp[s] != pl->last_skill_ob[s]->stats.exp) { - - /* Always send along the level if exp changes. This is only - * 1 extra byte, but keeps processing simpler. - */ - SockList_AddChar(&sl, ( char )( s + CS_STAT_SKILLINFO )); - SockList_AddChar(&sl, ( char )pl->last_skill_ob[s]->level); - SockList_AddInt64(&sl, pl->last_skill_ob[s]->stats.exp); - pl->last_skill_exp[s] = pl->last_skill_ob[s]->stats.exp; - } - } + uint8 s; + for(s=0;slast_skill_ob[s] && + pl->last_skill_exp[s] != pl->last_skill_ob[s]->stats.exp) { + + /* Always send along the level if exp changes. This is only + * 1 extra byte, but keeps processing simpler. + */ + SockList_AddChar(&sl, ( char )( s + CS_STAT_SKILLINFO )); + SockList_AddChar(&sl, ( char )pl->last_skill_ob[s]->level); + SockList_AddInt64(&sl, pl->last_skill_ob[s]->stats.exp); + pl->last_skill_exp[s] = pl->last_skill_ob[s]->stats.exp; + } + } } if (pl->socket.exp64) { - AddIfInt64(pl->last_stats.exp, pl->ob->stats.exp, CS_STAT_EXP64); + AddIfInt64(pl->last_stats.exp, pl->ob->stats.exp, CS_STAT_EXP64); } else { - AddIfInt(pl->last_stats.exp, ( int )pl->ob->stats.exp, CS_STAT_EXP); + AddIfInt(pl->last_stats.exp, ( int )pl->ob->stats.exp, CS_STAT_EXP); } AddIfShort(pl->last_level, ( char )pl->ob->level, CS_STAT_LEVEL); AddIfShort(pl->last_stats.wc, pl->ob->stats.wc, CS_STAT_WC); @@ -1034,20 +1034,20 @@ AddIfShort(pl->last_flags, flags, CS_STAT_FLAGS); if (pl->socket.sc_version<1025) { - AddIfShort(pl->last_resist[ATNR_PHYSICAL], pl->ob->resist[ATNR_PHYSICAL], CS_STAT_ARMOUR); + AddIfShort(pl->last_resist[ATNR_PHYSICAL], pl->ob->resist[ATNR_PHYSICAL], CS_STAT_ARMOUR); } else { - int i; + int i; - for (i=0; ilast_resist[i], pl->ob->resist[i], ( char )atnr_cs_stat[i]); - } + for (i=0; ilast_resist[i], pl->ob->resist[i], ( char )atnr_cs_stat[i]); + } } if (pl->socket.monitor_spells) { - AddIfInt(pl->last_path_attuned, pl->ob->path_attuned, CS_STAT_SPELL_ATTUNE); - AddIfInt(pl->last_path_repelled, pl->ob->path_repelled, CS_STAT_SPELL_REPEL); - AddIfInt(pl->last_path_denied, pl->ob->path_denied, CS_STAT_SPELL_DENY); + AddIfInt(pl->last_path_attuned, pl->ob->path_attuned, CS_STAT_SPELL_ATTUNE); + AddIfInt(pl->last_path_repelled, pl->ob->path_repelled, CS_STAT_SPELL_REPEL); + AddIfInt(pl->last_path_denied, pl->ob->path_denied, CS_STAT_SPELL_DENY); } rangetostring(pl->ob, buf); /* we want use the new fire & run system in new client */ AddIfString(pl->socket.stats.range, buf, CS_STAT_RANGE); @@ -1057,9 +1057,9 @@ /* Only send it away if we have some actual data */ if (sl.len>6) { #ifdef ESRV_DEBUG - LOG(llevDebug,"Sending stats command, %d bytes long.\n", sl.len); + LOG(llevDebug,"Sending stats command, %d bytes long.\n", sl.len); #endif - Send_With_Handling(&pl->socket, &sl); + Send_With_Handling(&pl->socket, &sl); } free(sl.buf); } @@ -1109,8 +1109,8 @@ * range, it must be a valid animation. */ if (anim_num < 0 || anim_num > num_animations) { - LOG(llevError,"esrv_send_anim (%d) out of bounds??\n",anim_num); - return; + LOG(llevError,"esrv_send_anim (%d) out of bounds??\n",anim_num); + return; } sl.buf = (unsigned char*) malloc(MAXSOCKBUF); @@ -1122,9 +1122,9 @@ * the face itself) down to the client. */ for (i=0; ifaces_sent[animations[anim_num].faces[i]] & NS_FACESENT_FACE)) - esrv_send_face(ns,animations[anim_num].faces[i],0); - SockList_AddShort(&sl, animations[anim_num].faces[i]); /* flags - not used right now */ + if (!(ns->faces_sent[animations[anim_num].faces[i]] & NS_FACESENT_FACE)) + esrv_send_face(ns,animations[anim_num].faces[i],0); + SockList_AddShort(&sl, animations[anim_num].faces[i]); /* flags - not used right now */ } Send_With_Handling(ns, &sl); free(sl.buf); @@ -1143,17 +1143,17 @@ * the face yet, we will also send it. */ static void esrv_map_setbelow(NewSocket *ns, int x,int y, - short face_num, struct Map *newmap) + short face_num, struct Map *newmap) { if(newmap->cells[x][y].count >= MAP_LAYERS) { - LOG(llevError,"Too many faces in map cell %d %d\n",x,y); - return; - abort(); + LOG(llevError,"Too many faces in map cell %d %d\n",x,y); + return; + abort(); } newmap->cells[x][y].faces[newmap->cells[x][y].count] = face_num; newmap->cells[x][y].count ++; if (!(ns->faces_sent[face_num] & NS_FACESENT_FACE)) - esrv_send_face(ns,face_num,0); + esrv_send_face(ns,face_num,0); } struct LayerCell { @@ -1175,7 +1175,7 @@ return 1; for(k=0;kcells[i][j].count;k++) { if (ns->lastmap.cells[i][j].faces[k] != - newmap->cells[i][j].faces[k]) { + newmap->cells[i][j].faces[k]) { return 1; } } @@ -1189,7 +1189,7 @@ * how many layers of data we should back. */ static uint8 *compactlayer(NewSocket *ns, unsigned char *cur, int numlayers, - struct Map *newmap) + struct Map *newmap) { int x,y,k; int face; @@ -1197,58 +1197,58 @@ struct MapLayer layers[MAP_LAYERS]; for(k = 0;kmapx;x++) { - for(y=0;ymapy;y++) { - if (!mapcellchanged(ns,x,y,newmap)) - continue; - if (newmap->cells[x][y].count == 0) { - *cur = x*ns->mapy+y; /* mark empty space */ - cur++; - continue; - } - for(k=0;kcells[x][y].count;k++) { - layers[k].lcells[layers[k].count].xy = x*ns->mapy+y; - layers[k].lcells[layers[k].count].face = - newmap->cells[x][y].faces[k]; - layers[k].count++; - } - } + for(y=0;ymapy;y++) { + if (!mapcellchanged(ns,x,y,newmap)) + continue; + if (newmap->cells[x][y].count == 0) { + *cur = x*ns->mapy+y; /* mark empty space */ + cur++; + continue; + } + for(k=0;kcells[x][y].count;k++) { + layers[k].lcells[layers[k].count].xy = x*ns->mapy+y; + layers[k].lcells[layers[k].count].face = + newmap->cells[x][y].faces[k]; + layers[k].count++; + } + } } /* If no data, return now. */ if (fcur == cur && layers[0].count == 0) - return cur; + return cur; *cur = 255; /* mark end of explicitly cleared cells */ cur++; /* First pack by layers. */ for(k=0;k> 8; - cur++; - *cur = layers[k].lcells[x].face & 0xFF; - cur++; - face = layers[k].lcells[x].face; - /* Now, we back the redundant data into 1 byte xy pairings */ - for(y=x;y> 8; + cur++; + *cur = layers[k].lcells[x].face & 0xFF; + cur++; + face = layers[k].lcells[x].face; + /* Now, we back the redundant data into 1 byte xy pairings */ + for(y=x;y( int )strlen("map ") || ns->sent_scroll) { - /* All of this is just accounting stuff */ - if (tframes>100) { - tframes = tbytes = 0; - } - tframes++; - frames++; - tbytes += sl.len; - bytes += sl.len; - memcpy(&ns->lastmap,newmap,sizeof(struct Map)); - Send_With_Handling(ns, &sl); - ns->sent_scroll = 0; + /* All of this is just accounting stuff */ + if (tframes>100) { + tframes = tbytes = 0; + } + tframes++; + frames++; + tbytes += sl.len; + bytes += sl.len; + memcpy(&ns->lastmap,newmap,sizeof(struct Map)); + Send_With_Handling(ns, &sl); + ns->sent_scroll = 0; } free(sl.buf); } @@ -1294,6 +1294,7 @@ cell->faces[2] = face2; cell->count = count; cell->stat_hp = 0; + cell->player = 0; } #define MAX_HEAD_POS MAX(MAX_CLIENT_X, MAX_CLIENT_Y) @@ -1316,8 +1317,8 @@ static inline int have_head(int ax, int ay) { if (heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS] || - heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + 1] || - heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + 2]) return 1; + heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + 1] || + heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + 2]) return 1; return 0; } @@ -1333,17 +1334,17 @@ short face_num; if (heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer]) - face_num = heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer]->face->number; + face_num = heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer]->face->number; else - face_num = 0; + face_num = 0; if (face_num != ns.lastmap.cells[ax][ay].faces[layer]) { - SockList_AddShort (&sl, face_num); - if (face_num && !(ns.faces_sent[face_num] & NS_FACESENT_FACE)) - esrv_send_face (&ns, face_num, 0); - heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer] = NULL; - ns.lastmap.cells[ax][ay].faces[layer] = face_num; - return 1; + SockList_AddShort (&sl, face_num); + if (face_num && !(ns.faces_sent[face_num] & NS_FACESENT_FACE)) + esrv_send_face (&ns, face_num, 0); + heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer] = NULL; + ns.lastmap.cells[ax][ay].faces[layer] = face_num; + return 1; } return 0; /* No change */ @@ -1393,18 +1394,18 @@ * the head value, or is not multipart. */ if (head && !head->more) { - for (i=0; ihead) ob=ob->head; - - if (ob == head) { - heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer] = NULL; - head = NULL; - break; - } - } + for (i=0; ihead) ob=ob->head; + + if (ob == head) { + heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer] = NULL; + head = NULL; + break; + } + } } ob = head; @@ -1418,101 +1419,101 @@ */ if (!ob || ob->face == blank_face) face_num=0; else if (head){ - /* if this is a head that had previously been stored */ - face_num = ob->face->number; + /* if this is a head that had previously been stored */ + face_num = ob->face->number; } else { - /* if the faces for the different parts of a multipart object - * are the same, we only want to send the bottom right most - * portion of the object. That info is in the tail_.. values - * of the head. Note that for the head itself, ob->head will - * be null, so we only do this block if we are working on - * a tail piece. - */ - - /* tail_x and tail_y will only be set in the head object. If - * this is the head object and these are set, we proceed - * with logic to only send bottom right. Similarly, if - * this is one of the more parts but the head has those values - * set, we want to do the processing. There can be cases where - * the head is not visible but one of its parts is, so we just - * can always expect that ob->arch->tail_x will be true for all - * object we may want to display. - */ - if ((ob->arch->tail_x || ob->arch->tail_y) || - (ob->head && (ob->head->arch->tail_x || ob->head->arch->tail_y))) { - - if (ob->head) head = ob->head; - else head = ob; - - /* Basically figure out where the offset is from where we are right - * now. the ob->arch->clone.{x,y} values hold the offset that this current - * piece is from the head, and the tail is where the tail is from the - * head. Note that bx and by will equal sx and sy if we are already working - * on the bottom right corner. If ob is the head, the clone values - * will be zero, so the right thing will still happen. - */ - bx = sx + head->arch->tail_x - ob->arch->clone.x; - by = sy + head->arch->tail_y - ob->arch->clone.y; - - /* I don't think this can ever happen, but better to check for it just - * in case. - */ - if (bx < sx || by < sy) { - LOG(llevError,"update_space: bx (%d) or by (%d) is less than sx (%d) or sy (%d)\n", - bx, by, sx, sy); - face_num = 0; - } - /* single part object, multipart object with non merged faces, - * of multipart object already at lower right. - */ - else if (bx == sx && by == sy) { - face_num = ob->face->number; - - /* if this face matches one stored away, clear that one away. - * this code relies on the fact that the map1 commands - * goes from 2 down to 0. - */ - for (i=0; iface->number == face_num) - heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + i] = NULL; - } - else { - /* If this head is stored away, clear it - otherwise, - * there can be cases where a object is on multiple layers - - * we only want to send it once. - */ - face_num = head->face->number; - for (i=0; iface->number == face_num) - heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i] = NULL; - - /* First, try to put the new head on the same layer. If that is used up, - * then find another layer. - */ - if (heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + layer] == NULL) { - heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + layer] = head; - } else for (i=0; iface->number; - - /* clear out any head entries that have the same face as this one */ - for (bx=0; bxface->number == face_num) - heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + bx] = NULL; - } + /* if the faces for the different parts of a multipart object + * are the same, we only want to send the bottom right most + * portion of the object. That info is in the tail_.. values + * of the head. Note that for the head itself, ob->head will + * be null, so we only do this block if we are working on + * a tail piece. + */ + + /* tail_x and tail_y will only be set in the head object. If + * this is the head object and these are set, we proceed + * with logic to only send bottom right. Similarly, if + * this is one of the more parts but the head has those values + * set, we want to do the processing. There can be cases where + * the head is not visible but one of its parts is, so we just + * can always expect that ob->arch->tail_x will be true for all + * object we may want to display. + */ + if ((ob->arch->tail_x || ob->arch->tail_y) || + (ob->head && (ob->head->arch->tail_x || ob->head->arch->tail_y))) { + + if (ob->head) head = ob->head; + else head = ob; + + /* Basically figure out where the offset is from where we are right + * now. the ob->arch->clone.{x,y} values hold the offset that this current + * piece is from the head, and the tail is where the tail is from the + * head. Note that bx and by will equal sx and sy if we are already working + * on the bottom right corner. If ob is the head, the clone values + * will be zero, so the right thing will still happen. + */ + bx = sx + head->arch->tail_x - ob->arch->clone.x; + by = sy + head->arch->tail_y - ob->arch->clone.y; + + /* I don't think this can ever happen, but better to check for it just + * in case. + */ + if (bx < sx || by < sy) { + LOG(llevError,"update_space: bx (%d) or by (%d) is less than sx (%d) or sy (%d)\n", + bx, by, sx, sy); + face_num = 0; + } + /* single part object, multipart object with non merged faces, + * of multipart object already at lower right. + */ + else if (bx == sx && by == sy) { + face_num = ob->face->number; + + /* if this face matches one stored away, clear that one away. + * this code relies on the fact that the map1 commands + * goes from 2 down to 0. + */ + for (i=0; iface->number == face_num) + heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + i] = NULL; + } + else { + /* If this head is stored away, clear it - otherwise, + * there can be cases where a object is on multiple layers - + * we only want to send it once. + */ + face_num = head->face->number; + for (i=0; iface->number == face_num) + heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i] = NULL; + + /* First, try to put the new head on the same layer. If that is used up, + * then find another layer. + */ + if (heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + layer] == NULL) { + heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + layer] = head; + } else for (i=0; iface->number; + + /* clear out any head entries that have the same face as this one */ + for (bx=0; bxface->number == face_num) + heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + bx] = NULL; + } } /* else not already head object or blank face */ /* This is a real hack. Basically, if we have nothing to send for this layer, @@ -1523,8 +1524,8 @@ * This tends to make stacking also work/look better. */ if (!face_num && layer > 0 && heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer -1]) { - face_num = heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer -1]->face->number; - heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer -1] = NULL; + face_num = heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer -1]->face->number; + heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer -1] = NULL; } /* Another hack - because of heads and whatnot, this face may match one @@ -1532,18 +1533,18 @@ * this one. */ if (face_num && layer+1lastmap.cells[sx][sy].faces[layer+1] == face_num) { - face_num = 0; + face_num = 0; } /* We've gotten what face we want to use for the object. Now see if * if it has changed since we last sent it to the client. */ if (ns->lastmap.cells[sx][sy].faces[layer] != face_num) { - ns->lastmap.cells[sx][sy].faces[layer] = face_num; - if (!(ns->faces_sent[face_num] & NS_FACESENT_FACE)) - esrv_send_face(ns, face_num, 0); - SockList_AddShort(sl, face_num); - return 1; + ns->lastmap.cells[sx][sy].faces[layer] = face_num; + if (!(ns->faces_sent[face_num] & NS_FACESENT_FACE)) + esrv_send_face(ns, face_num, 0); + SockList_AddShort(sl, face_num); + return 1; } /* Nothing changed */ return 0; @@ -1580,9 +1581,9 @@ */ if (!ob || ob->face == blank_face || MAP_NOSMOOTH(mp)) smoothlevel=0; else { - smoothlevel = ob->smoothlevel; - if (smoothlevel && !(ns->faces_sent[ob->face->number] & NS_FACESENT_SMOOTH)) - SendSmooth(ns, ob->face->number); + smoothlevel = ob->smoothlevel; + if (smoothlevel && !(ns->faces_sent[ob->face->number] & NS_FACESENT_SMOOTH)) + SendSmooth(ns, ob->face->number); } /* else not already head object or blank face */ /* We've gotten what face we want to use for the object. Now see if @@ -1593,9 +1594,9 @@ else if (smoothlevel<0) smoothlevel=0; if (ns->lastmap.cells[sx][sy].smooth[layer] != smoothlevel) { - ns->lastmap.cells[sx][sy].smooth[layer] = smoothlevel; - SockList_AddChar(sl, (uint8) (smoothlevel&0xFF)); - return 1; + ns->lastmap.cells[sx][sy].smooth[layer] = smoothlevel; + SockList_AddChar(sl, (uint8) (smoothlevel&0xFF)); + return 1; } /* Nothing changed */ return 0; @@ -1654,9 +1655,9 @@ sl.buf=(unsigned char*)malloc(MAXSOCKBUF); if (socket.mapmode == Map1Cmd) - strcpy((char*)sl.buf,"map1 "); + strcpy((char*)sl.buf,"map1 "); else - strcpy((char*)sl.buf,"map1a "); + strcpy((char*)sl.buf,"map1a "); sl.len=strlen((char*)sl.buf); startlen = sl.len; /*Extendedmapinfo structure initialisation*/ @@ -1694,148 +1695,148 @@ max_x = pl->x+(socket.mapx+1)/2; max_y = pl->y+(socket.mapy+1)/2; if (socket.mapmode == Map1aCmd) { - max_x += MAX_HEAD_OFFSET; - max_y += MAX_HEAD_OFFSET; + max_x += MAX_HEAD_OFFSET; + max_y += MAX_HEAD_OFFSET; } for(y=pl->y-socket.mapy/2; yx-socket.mapx/2;xx-socket.mapx/2;x= socket.mapx || ay >= socket.mapy) { - int i, got_one; - - oldlen = sl.len; - - SockList_AddShort(&sl, mask); - - if (check_head (sl, socket, ax, ay, 2)) - mask |= 0x4; - if (check_head (sl, socket, ax, ay, 1)) - mask |= 0x2; - if (check_head (sl, socket, ax, ay, 0)) - mask |= 0x1; - - /* If all we are doing is sending 0 (blank) faces, we don't - * actually need to send that - just the coordinates - * with no faces tells the client to blank out the - * space. - */ - got_one=0; - for (i=oldlen+2; i= socket.mapx || ay >= socket.mapy) { + int i, got_one; + + oldlen = sl.len; + + SockList_AddShort(&sl, mask); + + if (check_head (sl, socket, ax, ay, 2)) + mask |= 0x4; + if (check_head (sl, socket, ax, ay, 1)) + mask |= 0x2; + if (check_head (sl, socket, ax, ay, 0)) + mask |= 0x1; + + /* If all we are doing is sending 0 (blank) faces, we don't + * actually need to send that - just the coordinates + * with no faces tells the client to blank out the + * space. + */ + got_one=0; + for (i=oldlen+2; icontr->blocked_los[ax][ay]; + d = pl->contr->blocked_los[ax][ay]; - /* If the coordinates are not valid, or it is too dark to see, - * we tell the client as such - */ - nx=x; - ny=y; - m = get_map_from_coord(pl->map, &nx, &ny); - if (!m) { - /* space is out of map. Update space and clear values - * if this hasn't already been done. If the space is out - * of the map, it shouldn't have a head - */ - if (lastcell.count != -1) { - SockList_AddShort(&sl, mask); - map_clearcell(&lastcell,0,0,0,-1); - } - } else if (d>3) { - int need_send=0, count; - /* This block deals with spaces that are not visible for whatever - * reason. Still may need to send the head for this space. - */ + /* If the coordinates are not valid, or it is too dark to see, + * we tell the client as such + */ + nx=x; + ny=y; + m = get_map_from_coord(pl->map, &nx, &ny); + if (!m) { + /* space is out of map. Update space and clear values + * if this hasn't already been done. If the space is out + * of the map, it shouldn't have a head + */ + if (lastcell.count != -1) { + SockList_AddShort(&sl, mask); + map_clearcell(&lastcell,0,0,0,-1); + } + } else if (d>3) { + int need_send=0, count; + /* This block deals with spaces that are not visible for whatever + * reason. Still may need to send the head for this space. + */ - oldlen = sl.len; + oldlen = sl.len; SockList_AddShort(&sl, mask); if (lastcell.count != -1) need_send=1; count = -1; - if (socket.mapmode == Map1aCmd && have_head(ax, ay)) { - /* Now check to see if any heads need to be sent */ + if (socket.mapmode == Map1aCmd && have_head(ax, ay)) { + /* Now check to see if any heads need to be sent */ - if (check_head (sl, socket, ax, ay, 2)) - mask |= 0x4; - if (check_head (sl, socket, ax, ay, 1)) - mask |= 0x2; - if (check_head (sl, socket, ax, ay, 0)) - mask |= 0x1; - - lastcell.count = count; - - } else { - struct MapCell *cell = &lastcell; - /* properly clear a previously sent big face */ - if(cell->faces[0] != 0 - || cell->faces[1] != 0 - || cell->faces[2] != 0) - need_send = 1; - map_clearcell(&lastcell, 0, 0, 0, count); - } - - if ((mask & 0xf) || need_send) { - sl.buf[oldlen+1] = mask & 0xff; - } else { - sl.len = oldlen; - } - } else { - /* In this block, the space is visible or there are head objects - * we need to send. - */ - - /* Rather than try to figure out what everything that we might - * need to send is, then form the packet after that, - * we presume that we will in fact form a packet, and update - * the bits by what we do actually send. If we send nothing, - * we just back out sl.len to the old value, and no harm - * is done. - * I think this is simpler than doing a bunch of checks to see - * what if anything we need to send, setting the bits, then - * doing those checks again to add the real data. - */ - oldlen = sl.len; - mask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4; - eoldlen = esl.len; - emask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4; - SockList_AddShort(&sl, mask); + if (check_head (sl, socket, ax, ay, 2)) + mask |= 0x4; + if (check_head (sl, socket, ax, ay, 1)) + mask |= 0x2; + if (check_head (sl, socket, ax, ay, 0)) + mask |= 0x1; + + lastcell.count = count; + + } else { + struct MapCell *cell = &lastcell; + /* properly clear a previously sent big face */ + if(cell->faces[0] != 0 + || cell->faces[1] != 0 + || cell->faces[2] != 0) + need_send = 1; + map_clearcell(&lastcell, 0, 0, 0, count); + } + + if ((mask & 0xf) || need_send) { + sl.buf[oldlen+1] = mask & 0xff; + } else { + sl.len = oldlen; + } + } else { + /* In this block, the space is visible or there are head objects + * we need to send. + */ + + /* Rather than try to figure out what everything that we might + * need to send is, then form the packet after that, + * we presume that we will in fact form a packet, and update + * the bits by what we do actually send. If we send nothing, + * we just back out sl.len to the old value, and no harm + * is done. + * I think this is simpler than doing a bunch of checks to see + * what if anything we need to send, setting the bits, then + * doing those checks again to add the real data. + */ + oldlen = sl.len; + mask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4; + eoldlen = esl.len; + emask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4; + SockList_AddShort(&sl, mask); - if (socket.ext_mapinfos) - SockList_AddShort(&esl, emask); + if (socket.ext_mapinfos) + SockList_AddShort(&esl, emask); unsigned char dummy; unsigned char *last_ext = &dummy; - /* Darkness changed */ - if (lastcell.count != d && socket.darkness) { - mask |= 0x8; + /* Darkness changed */ + if (lastcell.count != d && socket.darkness) { + mask |= 0x8; if (socket.extmap) { @@ -1843,25 +1844,37 @@ } else SockList_AddChar (&sl, 255 - 64 * d); - } + } - lastcell.count = d; + lastcell.count = d; if (socket.extmap) { - uint8 stat_hp = 0; + uint8 stat_hp = 0; uint8 stat_width = 0; + tag_t player = 0; // send hp information, if applicable if (object *op = GET_MAP_FACE_OBJ (m, nx, ny, 0)) - if (!op->head - && op->stats.maxhp > 0 - && (unsigned)op->stats.maxhp > (unsigned)op->stats.hp - && IS_LIVE (op)) - { - stat_hp = 255 - (op->stats.hp * 255 + 254) / op->stats.maxhp; - stat_width = op->arch->tail_x; - } + { + if (op->head || op->invisible) + ; // do not show + else if (op->type == PLAYER + || QUERY_FLAG (op, FLAG_MONSTER) + || QUERY_FLAG (op, FLAG_ALIVE) + || QUERY_FLAG (op, FLAG_GENERATOR)) + { + if (op->stats.maxhp > 0 + && (unsigned)op->stats.maxhp > (unsigned)op->stats.hp) + { + stat_hp = 255 - (op->stats.hp * 255 + 254) / op->stats.maxhp; + stat_width = op->arch->tail_x; + } + } + + if (op->type == PLAYER && op != pl) + player = op->count; + } if (lastcell.stat_hp != stat_hp) { @@ -1877,59 +1890,68 @@ SockList_AddChar (&sl, stat_width); } } + + if (lastcell.player != player) + { + lastcell.player = player; + mask |= 0x8; + *last_ext |= 0x80; last_ext = sl.buf + sl.len; SockList_AddChar (&sl, 0x47); + SockList_AddChar (&sl, 4); + SockList_AddInt (&sl, player); + } } - /* Floor face */ - if (update_space(&sl, &socket, m, nx, ny, ax, ay, 2)) - mask |= 0x4; - - if (socket.EMI_smooth) - if (update_smooth(&esl, &socket, m, nx, ny, ax, ay, 2)) - emask |= 0x4; - - /* Middle face */ - if (update_space(&sl, &socket, m, nx, ny, ax, ay, 1)) - mask |= 0x2; - - if (socket.EMI_smooth) - if (update_smooth(&esl, &socket, m, nx, ny, ax, ay, 1)) - emask |= 0x2; - - if(nx == pl->x && ny == pl->y && pl->invisible & (pl->invisible < 50 ? 4 : 1)) { - if (lastcell.faces[0] != pl->face->number) { - lastcell.faces[0] = pl->face->number; - mask |= 0x1; - if (!(socket.faces_sent[pl->face->number] &NS_FACESENT_FACE)) - esrv_send_face(&socket, pl->face->number, 0); - SockList_AddShort(&sl, pl->face->number); - } - } - /* Top face */ - else { - if (update_space(&sl, &socket, m, nx, ny, ax, ay, 0)) - mask |= 0x1; - if (socket.EMI_smooth) - if (update_smooth(&esl, &socket, m, nx, ny, ax, ay, 0)){ - emask |= 0x1; - } - } - /* Check to see if we are in fact sending anything for this - * space by checking the mask. If so, update the mask. - * if not, reset the len to that from before adding the mask - * value, so we don't send those bits. - */ - if (mask & 0xf) { - sl.buf[oldlen+1] = mask & 0xff; - } else { - sl.len = oldlen; - } - if (emask & 0xf) { - esl.buf[eoldlen+1] = emask & 0xff; - } else { - esl.len = eoldlen; - } - } /* else this is a viewable space */ - } /* for x loop */ + /* Floor face */ + if (update_space(&sl, &socket, m, nx, ny, ax, ay, 2)) + mask |= 0x4; + + if (socket.EMI_smooth) + if (update_smooth(&esl, &socket, m, nx, ny, ax, ay, 2)) + emask |= 0x4; + + /* Middle face */ + if (update_space(&sl, &socket, m, nx, ny, ax, ay, 1)) + mask |= 0x2; + + if (socket.EMI_smooth) + if (update_smooth(&esl, &socket, m, nx, ny, ax, ay, 1)) + emask |= 0x2; + + if(nx == pl->x && ny == pl->y && pl->invisible & (pl->invisible < 50 ? 4 : 1)) { + if (lastcell.faces[0] != pl->face->number) { + lastcell.faces[0] = pl->face->number; + mask |= 0x1; + if (!(socket.faces_sent[pl->face->number] &NS_FACESENT_FACE)) + esrv_send_face(&socket, pl->face->number, 0); + SockList_AddShort(&sl, pl->face->number); + } + } + /* Top face */ + else { + if (update_space(&sl, &socket, m, nx, ny, ax, ay, 0)) + mask |= 0x1; + if (socket.EMI_smooth) + if (update_smooth(&esl, &socket, m, nx, ny, ax, ay, 0)){ + emask |= 0x1; + } + } + /* Check to see if we are in fact sending anything for this + * space by checking the mask. If so, update the mask. + * if not, reset the len to that from before adding the mask + * value, so we don't send those bits. + */ + if (mask & 0xf) { + sl.buf[oldlen+1] = mask & 0xff; + } else { + sl.len = oldlen; + } + if (emask & 0xf) { + esl.buf[eoldlen+1] = emask & 0xff; + } else { + esl.len = eoldlen; + } + } /* else this is a viewable space */ + } /* for x loop */ } /* for y loop */ /* Verify that we in fact do need to send this */ @@ -1947,8 +1969,8 @@ free(esl.buf); } if (sl.len>startlen || socket.sent_scroll) { - Send_With_Handling(&socket, &sl); - socket.sent_scroll = 0; + Send_With_Handling(&socket, &sl); + socket.sent_scroll = 0; } free(sl.buf); } @@ -1967,15 +1989,11 @@ mapstruct *m, *pm; if (pl->type != PLAYER) { - LOG(llevError,"draw_client_map called with non player/non eric-server\n"); - return; + LOG(llevError,"draw_client_map called with non player/non eric-server\n"); + return; } - if (pl->contr->transport) { - pm = pl->contr->transport->map; - } - else - pm = pl->map; + pm = pl->map; /* If player is just joining the game, he isn't here yet, so the map * can get swapped out. If so, don't try to send them a map. All will @@ -1987,21 +2005,21 @@ for(j = (pl->y - pl->contr->socket.mapy/2) ; j < (pl->y + (pl->contr->socket.mapy+1)/2); j++) { for(i = (pl->x - pl->contr->socket.mapx/2) ; i < (pl->x + (pl->contr->socket.mapx+1)/2); i++) { - ax=i; - ay=j; - m = pm; - mflags = get_map_flags(m, &m, ax, ay, &ax, &ay); - if (mflags & P_OUT_OF_MAP) - continue; - if (mflags & P_NEED_UPDATE) - update_position(m, ax, ay); - /* If a map is visible to the player, we don't want to swap it out - * just to reload it. This should really call something like + ax=i; + ay=j; + m = pm; + mflags = get_map_flags(m, &m, ax, ay, &ax, &ay); + if (mflags & P_OUT_OF_MAP) + continue; + if (mflags & P_NEED_UPDATE) + update_position(m, ax, ay); + /* If a map is visible to the player, we don't want to swap it out + * just to reload it. This should really call something like * swap_map, but this is much more efficient and 'good enough' - */ - if (mflags & P_NEW_MAP) - m->timeout = 50; - } + */ + if (mflags & P_NEW_MAP) + m->timeout = 50; + } } /* do LOS after calls to update_position */ if(pl->contr->do_los) { @@ -2016,8 +2034,8 @@ } if(pl->invisible & (pl->invisible < 50 ? 4 : 1)) { - esrv_map_setbelow(&pl->contr->socket,pl->contr->socket.mapx/2, - pl->contr->socket.mapy/2,pl->face->number,&newmap); + esrv_map_setbelow(&pl->contr->socket,pl->contr->socket.mapx/2, + pl->contr->socket.mapy/2,pl->face->number,&newmap); } /* j and i are the y and x coordinates of the real map (which is @@ -2032,45 +2050,45 @@ */ ay=0; for(j=pl->y-pl->contr->socket.mapy/2; j<=pl->y+(pl->contr->socket.mapy-1)/2;j++, ay++) { - ax=0; - for(i=pl->x-pl->contr->socket.mapx/2;i<=pl->x+(pl->contr->socket.mapx-1)/2;i++, ax++) { + ax=0; + for(i=pl->x-pl->contr->socket.mapx/2;i<=pl->x+(pl->contr->socket.mapx-1)/2;i++, ax++) { - d = pl->contr->blocked_los[ax][ay]; - /* note the out_of_map and d>3 checks are both within the same - * negation check. - */ - nx = i; - ny = j; - m = get_map_from_coord(pm, &nx, &ny); - if (m && d<4) { - face = GET_MAP_FACE(m, nx, ny,0); - floor2 = GET_MAP_FACE(m, nx, ny,1); - floor = GET_MAP_FACE(m, nx, ny,2); - - /* If all is blank, send a blank face. */ - if ((!face || face == blank_face) && - (!floor2 || floor2 == blank_face) && - (!floor || floor == blank_face)) { - esrv_map_setbelow(&pl->contr->socket,ax,ay, - blank_face->number,&newmap); - } else { /* actually have something interesting */ - /* send the darkness mask, if any. */ - if (d && pl->contr->socket.darkness) - esrv_map_setbelow(&pl->contr->socket,ax,ay, - dark_faces[d-1]->number,&newmap); - - if (face && face != blank_face) - esrv_map_setbelow(&pl->contr->socket,ax,ay, - face->number,&newmap); - if (floor2 && floor2 != blank_face) - esrv_map_setbelow(&pl->contr->socket,ax,ay, - floor2->number,&newmap); - if (floor && floor != blank_face) - esrv_map_setbelow(&pl->contr->socket,ax,ay, - floor->number,&newmap); - } - } /* Is a valid space */ - } + d = pl->contr->blocked_los[ax][ay]; + /* note the out_of_map and d>3 checks are both within the same + * negation check. + */ + nx = i; + ny = j; + m = get_map_from_coord(pm, &nx, &ny); + if (m && d<4) { + face = GET_MAP_FACE(m, nx, ny,0); + floor2 = GET_MAP_FACE(m, nx, ny,1); + floor = GET_MAP_FACE(m, nx, ny,2); + + /* If all is blank, send a blank face. */ + if ((!face || face == blank_face) && + (!floor2 || floor2 == blank_face) && + (!floor || floor == blank_face)) { + esrv_map_setbelow(&pl->contr->socket,ax,ay, + blank_face->number,&newmap); + } else { /* actually have something interesting */ + /* send the darkness mask, if any. */ + if (d && pl->contr->socket.darkness) + esrv_map_setbelow(&pl->contr->socket,ax,ay, + dark_faces[d-1]->number,&newmap); + + if (face && face != blank_face) + esrv_map_setbelow(&pl->contr->socket,ax,ay, + face->number,&newmap); + if (floor2 && floor2 != blank_face) + esrv_map_setbelow(&pl->contr->socket,ax,ay, + floor2->number,&newmap); + if (floor && floor != blank_face) + esrv_map_setbelow(&pl->contr->socket,ax,ay, + floor->number,&newmap); + } + } /* Is a valid space */ + } } esrv_map_doneredraw(&pl->contr->socket, &newmap); @@ -2100,13 +2118,13 @@ sl.buf = (unsigned char*) malloc(MAXSOCKBUF); strcpy((char*)sl.buf,"replyinfo skill_info\n"); for (i=1; i< NUM_SKILLS; i++) { - sprintf((char*)sl.buf + strlen((char*)sl.buf), "%d:%s\n", i + CS_STAT_SKILLINFO, - skill_names[i]); + sprintf((char*)sl.buf + strlen((char*)sl.buf), "%d:%s\n", i + CS_STAT_SKILLINFO, + &skill_names[i]); } sl.len = strlen((char*)sl.buf); if (sl.len >= MAXSOCKBUF) { - LOG(llevError,"Buffer overflow in send_skill_info!\n"); - fatal(0); + LOG(llevError,"Buffer overflow in send_skill_info!\n"); + fatal(0); } Send_With_Handling(ns, &sl); free(sl.buf); @@ -2123,11 +2141,11 @@ sl.buf = (unsigned char*) malloc(MAXSOCKBUF); strcpy((char*)sl.buf,"replyinfo spell_paths\n"); for(i=0; i= MAXSOCKBUF) { - LOG(llevError,"Buffer overflow in send_spell_paths!\n"); - fatal(0); + LOG(llevError,"Buffer overflow in send_spell_paths!\n"); + fatal(0); } Send_With_Handling(ns, &sl); free(sl.buf); @@ -2143,34 +2161,34 @@ object *spell; if (!pl->socket.monitor_spells) return; for (spell=pl->ob->inv; spell!=NULL; spell=spell->below) { - if (spell->type == SPELL) { - /* check if we need to update it*/ - if (spell->last_sp != SP_level_spellpoint_cost(pl->ob, spell, SPELL_MANA)) { - spell->last_sp = SP_level_spellpoint_cost(pl->ob, spell, SPELL_MANA); - flags |= UPD_SP_MANA; - } - if (spell->last_grace != SP_level_spellpoint_cost(pl->ob, spell, SPELL_GRACE)) { - spell->last_grace = SP_level_spellpoint_cost(pl->ob, spell, SPELL_GRACE); - flags |= UPD_SP_GRACE; - } - if (spell->last_eat != spell->stats.dam+SP_level_dam_adjust(pl->ob, spell)) { - spell->last_eat = spell->stats.dam+SP_level_dam_adjust(pl->ob, spell); - flags |= UPD_SP_DAMAGE; - } - if (flags !=0) { - sl.buf =(unsigned char*) malloc(MAXSOCKBUF); - strcpy((char*)sl.buf,"updspell "); - sl.len=strlen((char*)sl.buf); - SockList_AddChar(&sl, flags); - SockList_AddInt(&sl, spell->count); - if (flags & UPD_SP_MANA) SockList_AddShort(&sl, spell->last_sp); - if (flags & UPD_SP_GRACE) SockList_AddShort(&sl, spell->last_grace); - if (flags & UPD_SP_DAMAGE) SockList_AddShort(&sl, spell->last_eat); - flags = 0; - Send_With_Handling(&pl->socket, &sl); - free(sl.buf); - } - } + if (spell->type == SPELL) { + /* check if we need to update it*/ + if (spell->last_sp != SP_level_spellpoint_cost(pl->ob, spell, SPELL_MANA)) { + spell->last_sp = SP_level_spellpoint_cost(pl->ob, spell, SPELL_MANA); + flags |= UPD_SP_MANA; + } + if (spell->last_grace != SP_level_spellpoint_cost(pl->ob, spell, SPELL_GRACE)) { + spell->last_grace = SP_level_spellpoint_cost(pl->ob, spell, SPELL_GRACE); + flags |= UPD_SP_GRACE; + } + if (spell->last_eat != spell->stats.dam+SP_level_dam_adjust(pl->ob, spell)) { + spell->last_eat = spell->stats.dam+SP_level_dam_adjust(pl->ob, spell); + flags |= UPD_SP_DAMAGE; + } + if (flags !=0) { + sl.buf =(unsigned char*) malloc(MAXSOCKBUF); + strcpy((char*)sl.buf,"updspell "); + sl.len=strlen((char*)sl.buf); + SockList_AddChar(&sl, flags); + SockList_AddInt(&sl, spell->count); + if (flags & UPD_SP_MANA) SockList_AddShort(&sl, spell->last_sp); + if (flags & UPD_SP_GRACE) SockList_AddShort(&sl, spell->last_grace); + if (flags & UPD_SP_DAMAGE) SockList_AddShort(&sl, spell->last_eat); + flags = 0; + Send_With_Handling(&pl->socket, &sl); + free(sl.buf); + } + } } } @@ -2179,8 +2197,8 @@ if (!pl->socket.monitor_spells) return; if (!pl || !spell || spell->env != pl->ob) { - LOG(llevError, "Invalid call to esrv_remove_spell"); - return; + LOG(llevError, "Invalid call to esrv_remove_spell"); + return; } sl.buf = (unsigned char*) malloc(MAXSOCKBUF); strcpy((char*)sl.buf,"delspell "); @@ -2212,11 +2230,11 @@ /* figure out which skill it uses, if it uses one */ if (spell->skill) { - for (i=1; i< NUM_SKILLS; i++) - if (!strcmp(spell->skill, skill_names[i])) { - skill = i+CS_STAT_SKILLINFO; - break; - } + for (i=1; i< NUM_SKILLS; i++) + if (!strcmp(spell->skill, skill_names[i])) { + skill = i+CS_STAT_SKILLINFO; + break; + } } SockList_AddChar(sl, skill); @@ -2229,13 +2247,13 @@ sl->len+=len; if (!spell->msg) { - SockList_AddShort(sl, 0); + SockList_AddShort(sl, 0); } else { - len = strlen(spell->msg); - SockList_AddShort(sl, len); - memcpy(sl->buf+sl->len, spell->msg, len); - sl->len+=len; + len = strlen(spell->msg); + SockList_AddShort(sl, len); + memcpy(sl->buf+sl->len, spell->msg, len); + sl->len+=len; } } @@ -2246,46 +2264,46 @@ void esrv_add_spells(player *pl, object *spell) { SockList sl; if (!pl) { - LOG(llevError, "esrv_add_spells, tried to add a spell to a NULL player"); - return; + LOG(llevError, "esrv_add_spells, tried to add a spell to a NULL player"); + return; } if (!pl->socket.monitor_spells) return; sl.buf = (unsigned char*) malloc(MAXSOCKBUF); strcpy((char*)sl.buf,"addspell "); sl.len=strlen((char*)sl.buf); if (!spell) { - for (spell=pl->ob->inv; spell!=NULL; spell=spell->below) { - /* were we to simply keep appending data here, we could exceed - * MAXSOCKBUF if the player has enough spells to add, we know that - * append_spells will always append 19 data bytes, plus 4 length + for (spell=pl->ob->inv; spell!=NULL; spell=spell->below) { + /* were we to simply keep appending data here, we could exceed + * MAXSOCKBUF if the player has enough spells to add, we know that + * append_spells will always append 19 data bytes, plus 4 length * bytes and 3 strings (because that is the spec) so we need to * check that the length of those 3 strings, plus the 23 bytes, * won't take us over the length limit for the socket, if it does, * we need to send what we already have, and restart packet formation */ - /* Seeing crashes by overflowed buffers. Quick arithemetic seems - * to show add_spell is 26 bytes + 2 strings. However, the overun - * is hundreds of bytes off, so correcting 22 vs 26 doesn't seem - * like it will fix this - */ - if (spell->type != SPELL) continue; - if (sl.len >= (MAXSOCKBUF - (26 + strlen(spell->name) + - (spell->msg?strlen(spell->msg):0)))) { - Send_With_Handling(&pl->socket, &sl); - strcpy((char*)sl.buf,"addspell "); - sl.len=strlen((char*)sl.buf); - } - append_spell(pl, &sl, spell); - } + /* Seeing crashes by overflowed buffers. Quick arithemetic seems + * to show add_spell is 26 bytes + 2 strings. However, the overun + * is hundreds of bytes off, so correcting 22 vs 26 doesn't seem + * like it will fix this + */ + if (spell->type != SPELL) continue; + if (sl.len >= (MAXSOCKBUF - (26 + strlen(spell->name) + + (spell->msg?strlen(spell->msg):0)))) { + Send_With_Handling(&pl->socket, &sl); + strcpy((char*)sl.buf,"addspell "); + sl.len=strlen((char*)sl.buf); + } + append_spell(pl, &sl, spell); + } } else if (spell->type != SPELL) { - LOG(llevError, "Asked to send a non-spell object as a spell"); - return; + LOG(llevError, "Asked to send a non-spell object as a spell"); + return; } else append_spell(pl, &sl, spell); if (sl.len >= MAXSOCKBUF) { - LOG(llevError,"Buffer overflow in esrv_add_spells!\n"); - fatal(0); + LOG(llevError,"Buffer overflow in esrv_add_spells!\n"); + fatal(0); } /* finally, we can send the packet */ Send_With_Handling(&pl->socket, &sl);