int unpackframe(Uint32 packfr,Uint8 *data,size_t len) { FRAME_t *pfr = fr + packfr % maxframes; int i; size_t n = 0; if( maxobjs!=(int)unpackbytes(data,len,&n,4) ) { SJC_Write("Your maxobjs setting (%d) differs from server's!",maxobjs); return 1; } for(i=0;i<maxobjs;i++) { pfr->objs[i].type = unpackbytes(data,len,&n,2); if(pfr->objs[i].type) { pfr->objs[i].flags = unpackbytes(data,len,&n,2); pfr->objs[i].context = unpackbytes(data,len,&n,4); pfr->objs[i].size = unpackbytes(data,len,&n,sizeof(size_t)); if( pfr->objs[i].size ) { if( len<n+pfr->objs[i].size ) { SJC_Write("Packed data ended early!"); return 1; } pfr->objs[i].data = malloc(pfr->objs[i].size); //FIXME: might already be allocated with pre-net data memcpy(pfr->objs[i].data, data+n, pfr->objs[i].size); n += pfr->objs[i].size; mod_recvobj( pfr->objs + i ); } } } return 0; }
int unpackframecmds(Uint32 packfr,Uint8 *data,size_t len) { FRAME_t *pfr = fr + packfr % maxframes; int i; size_t n = 0; if( maxclients!=(int)unpackbytes(data,len,&n,4) ) { SJC_Write("Your maxclients setting (%d) differs from server's! packfr=%d",maxclients,packfr); return -1; } for(i=0;i<maxclients;i++) { FCMD_t *c = pfr->cmds+i; c->cmd = unpackbytes(data,len,&n,1); c->mousehi = unpackbytes(data,len,&n,1); c->mousex = unpackbytes(data,len,&n,1); c->mousey = unpackbytes(data,len,&n,1); c->flags = unpackbytes(data,len,&n,2); if( c->flags & CMDF_DATA ) { //check for variable data c->datasz = unpackbytes(data,len,&n,2); if( c->datasz > sizeof c->data ) { SJC_Write("Treachery: datasz too large (%d) from server",c->datasz); break; } memcpy( c->data, data+n, c->datasz ); n += c->datasz; } if( c->flags & CMDF_NEW ) SJC_Write("%u: Unpacked CMDF_NEW for client %d",packfr,i); } return n; }
static void ghost_paint( FCMD_t *c, ghost *gh, context *co ) { size_t n = 0; int i, j, k; char letter = (char)unpackbytes(c->data, MAXCMDDATA, &n, 1); int dnx = (int) unpack(4); int dny = (int) unpack(4); int dnz = (int) unpack(4); int upx = (int) unpack(4); int upy = (int) unpack(4); int upz = (int) unpack(4); int sprnum = (int) unpack(4); if( letter!='p' ) { echo("Unknown edit command!"); return; } int tool_num = (sprites[sprnum].flags & TOOL_MASK); int shx = 0; int shy = 0; int shz = 0; int clipx = MAX(gh->clipboard_x, 1); int clipy = MAX(gh->clipboard_y, 1); int clipz = MAX(gh->clipboard_z, 1); //make so dn is less than up... also adjust clipboard shift if( dnx > upx ) { SWAP(upx, dnx, int); shx = clipx-(upx-dnx+1)%clipx; } if( dny > upy ) { SWAP(upy, dny, int); shy = clipy-(upy-dny+1)%clipy; } if( dnz > upz ) { SWAP(upz, dnz, int); shz = clipz-(upz-dnz+1)%clipz; } if( dnx<0 || dny<0 || dnz<0 || upx>=co->x || upy>=co->y || upz>=co->z ) { echo("Paint command out of bounds!"); return; } if( tool_num == TOOL_COPY ) //COPY tool texture { gh->clipboard_x = clipx = upx - dnx + 1; gh->clipboard_y = clipy = upy - dny + 1; gh->clipboard_z = clipz = upz - dnz + 1; gh->clipboard_data = malloc( clipx*clipy*clipz*(sizeof *gh->clipboard_data) ); //FIXME: mem leak } if( tool_num == TOOL_PSTE && !gh->clipboard_data ) { echo("Clipboard is empty"); return; } push_context(co); for( k=dnz; k<=upz; k++ ) for( j=dny; j<=upy; j++ ) for( i=dnx; i<=upx; i++ ) { int pos = k*co->y*co->x + j*co->x + i; if( !tool_num ) // regular tile painting { int dsprnum = sprnum; if( co->projection == ORTHOGRAPHIC ) dsprnum = sprite_grid_transform_xy(sprites + sprnum, co, i, j, k, i-dnx, j-dny, upx-dnx+1, upy-dny+1) - sprites; co->dmap[pos].flags &= ~CBF_NULL; co->dmap[pos].flags |= CBF_VIS; co->dmap[pos].spr = dsprnum; continue; } switch( tool_num ) { case TOOL_NUL: co->dmap[pos] = co->map[pos]; co->dmap[pos].flags |= CBF_NULL; break; case TOOL_SOL: co->dmap[pos].flags &= ~(CBF_NULL|CBF_PLAT); co->dmap[pos].flags |= CBF_SOLID; break; case TOOL_PLAT: co->dmap[pos].flags &= ~(CBF_NULL|CBF_SOLID); co->dmap[pos].flags |= CBF_PLAT; break; case TOOL_OPN: co->dmap[pos].flags &= ~(CBF_NULL|CBF_SOLID|CBF_PLAT); break; case TOOL_COPY: gh->clipboard_data[ (k-dnz)*clipy*clipx + (j-dny)*clipx + (i-dnx) ] = co->dmap[pos]; break; case TOOL_PSTE: { int x = (i-dnx+shx) % clipx; int y = (j-dny+shy) % clipy; int z = (k-dnz+shz) % clipz; co->dmap[pos] = gh->clipboard_data[ x + y*clipx + z*clipy*clipx ]; break; } case TOOL_OBJ: // disabled, PLAYER_T removed break; case TOOL_ERAS: co->dmap[pos].flags &= ~(CBF_VIS|CBF_NULL); break; case TOOL_VIS: co->map[pos].flags |= CBF_VIS; // hack for making a loaded-from-file tile visible (format change mess) break; } } }