Difference for socket/request.c from version 1.48 to 1.49


version 1.48 version 1.49
Line 1
 
Line 1
 /*  /*
  * static char *rcsid_init_c =   * static char *rcsid_init_c =
  *    "$Id: request.c,v 1.48 2003/04/02 08:13:31 mwedel Exp $";   *    "$Id: request.c,v 1.49 2003/06/19 10:59:33 tchize Exp $";
  */   */
   
 /*  /*
Line 214
 
Line 214
  */   */
  if ((x>11 || y>11) && ns->mapmode == Map0Cmd) ns->mapmode = 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);
        strcat(cmdback, tmpbuf);
  } else {   } else {
      /* Didn't get a setup command we understood -       /* Didn't get a setup command we understood -
       * report a failure to the client.        * report a failure to the client.
Line 249
 
Line 257
     settings=oldsettings;       settings=oldsettings;
 }  }
   
   void ToggleExtendedInfos (char *buf, int len, NewSocket *ns){
        char cmdback[MAX_BUF];
        char command[50];
        int info,nextinfo;
        cmdback[0]='\0';    
        nextinfo=0;
        while (1){
             /* 1. Extract an info*/
             info=nextinfo;
             while ( (info<len) && (buf[info]==' ') ) info++;
             if (info>=len)
                  break;
             nextinfo=info+1;
             while ( (nextinfo<len) && (buf[nextinfo]!=' ') )
                  nextinfo++; 
             if (nextinfo-info>=49) /*Erroneous info asked*/
                  continue;
             strncpy (command,&(buf[info]),nextinfo-info);
             command[nextinfo-info]='\0';
             /* 2. Interpret info*/
             if (!strcmp("smoothing",command)){
                  /* Toggle smoothing*/
                  ns->EMI_smooth=!ns->EMI_smooth;
             }else{
                  /*bad value*/
             }
             /*3. Next info*/
        }
        strcpy (cmdback,"ExtendedInfoSet");
        if (ns->EMI_smooth){
             strcat (cmdback," ");
             strcat (cmdback,"smoothing");
        }
        Write_String_To_Socket(ns, cmdback,strlen(cmdback));
   }
   
    /**
     * Tells client the picture it has to use
     * to smooth a picture number given as argument.
     * Also take care of sending those pictures to the client.
     * For information, here is where we get the smoothing inforations:
     * - Take the facename and add '_smoothed' to it.
     * - Look for that archetype and find it's animation.
     * - Use the animation elements from 0 to 8 for smoothing.
     */
   void AskSmooth (char *buf, int len, NewSocket *ns){    
        char* name;
        char* defaultsmooth="default_smoothed.111";
        char smoothname[MAX_BUF];
        char reply[MAX_BUF];
        int i;
        int smoothed[8];
        archetype* at;
        uint16 smoothfaces[8];   /*unsigned short int!*/ 
        int facenbr;
        facenbr=atoi (buf);
        if ((!FindSmooth (facenbr, smoothfaces)) &&
            (!FindSmooth (FindFace(defaultsmooth,0), smoothfaces))
           )
      
            LOG(llevError,"could not findsmooth for %d. Neither default (%s)\n",facenbr,defaultsmooth);
   #if 0
        name = FindFaceName(facenbr, NULL);
        if (name==NULL){
             LOG(llevError,"could not findsmooth for %d(%s). Back to default\n",facenbr);
             
             name=defaultsmooth;
        }
        strcpy (smoothname,name);
        strcat (smoothname,"_smoothed");
        /* A face name may have a dot in it's name. It is a bad
         * idea to create an archetype with a dot in it's name.
         * To do handle this, let's replace all '.' with '_'
         */
        for (i=0;i<strlen(smoothname);i++)
             if (smoothname[i]=='.')
                  smoothname[i]='_';
        at=find_archetype(smoothname);
        if (at==NULL){
             /* no correct smooth. Boggus client or boggus archetype definition
              * fall back to a default smooth for security reasons.
              * If we fail here, we have a boggus archetypes list!
              */
             LOG(llevError,"tried to smooth %s.\n",name);
             LOG(llevError,"previous: %s.\n",FindFaceName(facenbr-1, NULL));
             LOG(llevError,"next: %s.\n",FindFaceName(facenbr+1, NULL));
             at=find_archetype("default_smoothed");
        }
        if (at==NULL){
             LOG(llevError,"BOGGUS archetype file.\n");
             LOG(llevError,"Mandatory archetype named default_smoothed not found.\n");
             LOG(llevError,"Clients with smoothing will have LOTS of problems\n");
             LOG(llevError,"Sending first face as default smooth sequence\n");
             for (i=0;i<8;i++)
                  smoothfaces[i]=0;          
             if (ns->faces_sent[0] == 0)
                  esrv_send_face(ns, 0, 0);
        }
        else{
             for (i=0;i<8;i++){
                  smoothfaces[i]=GET_ANIMATION((&(at->clone)),i); 
                  if (ns->faces_sent[smoothfaces[i]] == 0)
                       esrv_send_face(ns, smoothfaces[i], 0);
             }
        }
   #endif
        for (i=0;i<8;i++){
            if (ns->faces_sent[smoothfaces[i]] == 0)
                       esrv_send_face(ns, smoothfaces[i], 0);
        }
        sprintf (reply,"smooth %d %d %d %d %d %d %d %d %d",facenbr,
             smoothfaces[0],smoothfaces[1],smoothfaces[2],smoothfaces[3],
             smoothfaces[4],smoothfaces[5],smoothfaces[6],smoothfaces[7]);
        Write_String_To_Socket(ns, reply,strlen(reply));
       
   }
 /* This handles the general commands from the client (ie, north, fire, cast,  /* This handles the general commands from the client (ie, north, fire, cast,
  * etc.)   * etc.)
  */   */
Line 426
 
Line 549
     }      }
 }  }
   
 /* Client tells its its version.  If there is a mismatch, we close the  /* Client tells its version.  If there is a mismatch, we close the
  * socket.  In real life, all we should care about is the client having   * socket.  In real life, all we should care about is the client having
  * something older than the server.  If we assume the client will be   * something older than the server.  If we assume the client will be
  * backwards compatible, having it be a later version should not be a    * backwards compatible, having it be a later version should not be a
Line 1116
 
Line 1239
     return 0;      return 0;
 }  }
   
   /* This function is mainly a copy of update_space,
    * except it handles update of the smoothing updates,
    * not the face updates.
    * Removes the need to replicate the same code for each layer.
    * this returns true if this smooth is now in fact different
    * than it was.
    * sl is the socklist this data is going into.
    * ns is the socket we are working on - all the info we care
    * about is in this socket structure, so know need to pass the
    * entire player object.
    * mx and my are map coordinate offsets for map mp
    * sx and sy are the offsets into the socket structure that
    * holds the old values.
    * layer is the layer to update, with 2 being the floor and 0 the
    * top layer (this matches what the GET_MAP_FACE and GET_MAP_FACE_OBJ
    * take. 
    */
   
   static inline int update_smooth(SockList *sl, NewSocket *ns, mapstruct  *mp, int mx, int my, int sx, int sy, int layer)
   {
       object *ob, *head;
       int smoothlevel; /* old face_num;*/
       int bx, by,i;
   
       /* If there is a multipart object stored away, treat that as more important.
        * If not, then do the normal processing.
        */
       ob=NULL;
       head = heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer];
   
       /* Check to see if this head is part of the set of objects
        * we would normally send for this space.  If so, then
        * don't use the head value.  We need to do the check
        * here and not when setting up the heads[] value for two reasons -
        * 1) the heads[] values will get used even if the space is not visible.
        * 2) its possible the head is not on the same map as a part, and I'd
        *    rather not need to do the map translation overhead.
        */
       /*if (head) {
    for (i=0; i<MAP_LAYERS; i++)
        if (GET_MAP_FACE_OBJ(mp, mx, my, i) &&
    GET_MAP_FACE_OBJ(mp, mx, my, i)->face == head->face) {
        heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer] = NULL;
        head = NULL;
        break;
        }
       }
   
       ob = head;*/
       if (!ob) ob = GET_MAP_FACE_OBJ(mp, mx, my, layer);
   
       /* If there is no object for this space, or if the face for the object
        * is the blank face, set the face number to zero.
        * else if we have the stored head object for this space, that takes
        * precedence over the other object for this space.
        * otherwise, we do special head processing
        */
       if (!ob || ob->face == blank_face) smoothlevel=0;
       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.
    */
   #if 0
        ///// Old code from update_Space, don't think tail interacts here
    /* 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);
        }
        /* 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; i<MAP_LAYERS; i++)
        if (heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + i] &&
    heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + i]->face->number == face_num)
    heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + i] = NULL;
        }
        else {
    /* 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) {
    heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + layer] = head;
    } else for (i=0; i<MAX_LAYERS; i++) {
        if (heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i] == NULL ||
    heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i] == head) {
        heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i] = head;
        }
    }
    face_num = 0; /* Don't send this object - we'll send the head later */
        }
    } else {
   #else
        {
   #endif
        /* In this case, we are already at the lower right or single part object,
         * so nothing special
         */
        smoothlevel = ob->smoothlevel;
   
        /* clear out any head entries that have the same face as this one */
        /* useless in update_smooth
             for (bx=0; bx<layer; bx++)
    if (heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + bx] &&
        heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + bx]->face->number == face_num)
    heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + bx] = NULL;
            */      
    }
       } /* else not already head object or blank face */
   
       /* 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 (smoothlevel>255)
            smoothlevel=255;
       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;
       }
       /* Nothing changed */
       return 0;
   }
   /* returns the size of a data for a map square as returned by
    * mapextended. There are CLIENTMAPX*CLIENTMAPY*LAYERS entries
    * available.
    */ 
   int getExtendedMapInfoSize(NewSocket* ns){
       int result=0;
       if (ns->ext_mapinfos){
           if (ns->EMI_smooth)
               result+=1; /*One byte for smoothlevel*/
       }
       return result;       
   }
 /* this function uses the new map1 protocol command to send the map  /* this function uses the new map1 protocol command to send the map
  * to the client.  It is necessary because the old map command supports   * to the client.  It is necessary because the old map command supports
  * a maximum map size of 15x15.   * a maximum map size of 15x15.
Line 1141
 
Line 1439
 void draw_client_map1(object *pl)  void draw_client_map1(object *pl)
 {  {
     int x,y,ax, ay, d, nx,ny, startlen, max_x, max_y, oldlen;      int x,y,ax, ay, d, nx,ny, startlen, max_x, max_y, oldlen;
       int estartlen, eoldlen;   
     SockList sl;      SockList sl;
     uint16  mask;      SockList esl; /*For extended Map info*/
       uint16  mask,emask,eentrysize;
       uint8   extendedinfos;
     mapstruct *m;      mapstruct *m;
   
     sl.buf=malloc(MAXSOCKBUF);      sl.buf=malloc(MAXSOCKBUF);
Line 1150
 
Line 1451
  strcpy((char*)sl.buf,"map1 ");   strcpy((char*)sl.buf,"map1 ");
     else      else
  strcpy((char*)sl.buf,"map1a ");   strcpy((char*)sl.buf,"map1a ");
   
     sl.len=strlen((char*)sl.buf);      sl.len=strlen((char*)sl.buf);
     startlen = sl.len;      startlen = sl.len;
       /*Extendedmapinfo structure initialisation*/
       if (pl->contr->socket.ext_mapinfos){
           esl.buf=malloc(MAXSOCKBUF);
           strcpy((char*)esl.buf,"mapextended ");
           esl.len=strlen((char*)esl.buf);
           extendedinfos=EMI_NOREDRAW;
           if (pl->contr->socket.EMI_smooth)
               extendedinfos|=EMI_SMOOTH;
           SockList_AddChar(&esl, extendedinfos);
           eentrysize=getExtendedMapInfoSize(&(pl->contr->socket));
           SockList_AddChar(&esl, eentrysize);
           estartlen = esl.len;           
       }
     /* Init data to zero */      /* Init data to zero */
     memset(heads, 0, sizeof(object *) * MAX_HEAD_POS * MAX_HEAD_POS * MAX_LAYERS);      memset(heads, 0, sizeof(object *) * MAX_HEAD_POS * MAX_HEAD_POS * MAX_LAYERS);
   
Line 1176
 
Line 1489
  for(x=pl->x-pl->contr->socket.mapx/2;x<max_x;x++,ax++) {   for(x=pl->x-pl->contr->socket.mapx/2;x<max_x;x++,ax++) {
   
      mask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4;       mask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4;
        emask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4;
   
      /* If this space is out of the normal viewable area, we only check       /* If this space is out of the normal viewable area, we only check
       * the heads value  ax or ay will only be greater than what        * the heads value  ax or ay will only be greater than what
Line 1185
 
Line 1499
       */        */
      if (ax >= pl->contr->socket.mapx || ay >= pl->contr->socket.mapy) {       if (ax >= pl->contr->socket.mapx || ay >= pl->contr->socket.mapy) {
  oldlen = sl.len;   oldlen = sl.len;
           if (pl->contr->socket.ext_mapinfos){
               SockList_AddShort(&sl, emask);
           }
   
  SockList_AddShort(&sl, mask);   SockList_AddShort(&sl, mask);
   
Line 1200
 
Line 1517
  } else {   } else {
      sl.len = oldlen;       sl.len = oldlen;
  }   }
           /*What concerns extendinfos, nothing to be done for now
            * (perhaps effects layer later)
            */
  continue;   /* don't do processing below */   continue;   /* don't do processing below */
      }       }
   
Line 1284
 
Line 1604
  */   */
  oldlen = sl.len;   oldlen = sl.len;
  mask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4;   mask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4;
    eoldlen = esl.len;
    emask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4;
  SockList_AddShort(&sl, mask);   SockList_AddShort(&sl, mask);
           if (pl->contr->socket.ext_mapinfos)
               SockList_AddShort(&esl, emask);
   
  /* Darkness changed */   /* Darkness changed */
  if (pl->contr->socket.lastmap.cells[ax][ay].count != d && pl->contr->socket.darkness) {   if (pl->contr->socket.lastmap.cells[ax][ay].count != d && pl->contr->socket.darkness) {
Line 1312
 
Line 1636
  if (update_space(&sl, &pl->contr->socket, m, nx, ny, ax, ay, 2))   if (update_space(&sl, &pl->contr->socket, m, nx, ny, ax, ay, 2))
      mask |= 0x4;       mask |= 0x4;
   
           if (pl->contr->socket.EMI_smooth)
               if (update_smooth(&esl, &pl->contr->socket, m, nx, ny, ax, ay, 2)){
                   emask |= 0x4;
               }
   
  /* Middle face */   /* Middle face */
  if (update_space(&sl, &pl->contr->socket, m, nx, ny, ax, ay, 1))   if (update_space(&sl, &pl->contr->socket, m, nx, ny, ax, ay, 1))
      mask |= 0x2;       mask |= 0x2;
           if (pl->contr->socket.EMI_smooth)
               if (update_smooth(&esl, &pl->contr->socket, m, nx, ny, ax, ay, 1)){
                   emask |= 0x2;
               }
   
   
  if(nx == pl->x && ny == pl->y && pl->invisible & (pl->invisible < 50 ? 4 : 1)) {   if(nx == pl->x && ny == pl->y && pl->invisible & (pl->invisible < 50 ? 4 : 1)) {
Line 1327
 
Line 1660
      }       }
  }   }
  /* Top face */   /* Top face */
  else if (update_space(&sl, &pl->contr->socket, m, nx, ny, ax, ay, 0))   else{
               if (update_space(&sl, &pl->contr->socket, m, nx, ny, ax, ay, 0))
      mask |= 0x1;       mask |= 0x1;
               if (pl->contr->socket.EMI_smooth)
                   if (update_smooth(&esl, &pl->contr->socket, m, nx, ny, ax, ay, 0)){
                       emask |= 0x1;
                   }
           }
  /* Check to see if we are in fact sending anything for this   /* Check to see if we are in fact sending anything for this
  * space by checking the mask.  If so, update the mask.   * space by checking the mask.  If so, update the mask.
  * if not, reset the len to that from before adding the mask   * if not, reset the len to that from before adding the mask
Line 1340
 
Line 1678
  } else {   } else {
      sl.len = oldlen;       sl.len = oldlen;
  }   }
    if (emask & 0xf) {
        esl.buf[eoldlen+1] = emask & 0xff;
    } else {
               /*printf ("rollbacking esl %d on %d \n",eoldlen,estartlen);*/
        esl.len = eoldlen;
    }
      } /* else this is a viewable space */       } /* else this is a viewable space */
  } /* for x loop */   } /* for x loop */
     } /* for y loop */      } /* for y loop */
   
     /* Verify that we in fact do need to send this */      /* Verify that we in fact do need to send this */
       if (pl->contr->socket.ext_mapinfos)
           if (esl.len>estartlen) {
               Send_With_Handling(&pl->contr->socket, &esl);       
           free(esl.buf);
           }
     if (sl.len>startlen || pl->contr->socket.sent_scroll) {      if (sl.len>startlen || pl->contr->socket.sent_scroll) {
  Send_With_Handling(&pl->contr->socket, &sl);   Send_With_Handling(&pl->contr->socket, &sl);
  pl->contr->socket.sent_scroll = 0;   pl->contr->socket.sent_scroll = 0;


Legend:
line(s) removed in v.1.48 
line(s) changed
 line(s) added in v.1.49

File made using version 1.98 of cvs2html by leaf at 2011-07-21 19:37