--- deliantra/server/socket/request.C 2006/09/10 13:43:33 1.16 +++ deliantra/server/socket/request.C 2006/12/13 18:08:02 1.27 @@ -1,9 +1,3 @@ - -/* - * static char *rcsid_init_c = - * "$Id: request.C,v 1.16 2006/09/10 13:43:33 root Exp $"; - */ - /* CrossFire, A Multiplayer game for X-windows @@ -24,7 +18,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - The author can be reached via e-mail to crossfire-devel@real-time.com + The author can be reached via e-mail to */ /** @@ -52,8 +46,6 @@ * esrv_map_doneredraw finishes the map update, and ships across the * map updates. * - * esrv_map_scroll tells the client to scroll the map, and does similarily - * for the locally cached copy. */ #include @@ -67,13 +59,11 @@ /* This block is basically taken from socket.c - I assume if it works there, * it should work here. */ -#ifndef WIN32 /* ---win32 exclude unix headers */ -# include -# include -# include -# include -# include -#endif /* win32 */ +#include +#include +#include +#include +#include #ifdef HAVE_UNISTD_H # include @@ -147,19 +137,13 @@ for (y = 0; y < my; y++) { if (x >= ns->mapx || y >= ns->mapy) - { - /* clear cells outside the viewable area */ - memset (&newmap.cells[x][y], 0, sizeof (struct MapCell)); - } + /* 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)); - } + /* 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 (&(newmap.cells[x][y]), &(ns->lastmap.cells[x + dx][y + dy]), sizeof (struct MapCell)); } } @@ -268,7 +252,7 @@ buf += 8; // initial map and its origin - mapstruct *map = pl->ob->map; + maptile *map = pl->ob->map; sint16 dx, dy; int mapx = pl->socket.mapx / 2 - pl->ob->x; int mapy = pl->socket.mapy / 2 - pl->ob->y; @@ -583,39 +567,46 @@ 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 ("smooth", command)) - { - /* Toggle smoothing */ - ns->EMI_smooth = !ns->EMI_smooth; - } + /* Toggle smoothing */ + ns->EMI_smooth = !ns->EMI_smooth; else - { - /*bad value */ - } + /*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)); } @@ -637,30 +628,40 @@ int info, nextinfo, i, flag; 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 */ i = sscanf (command, "%d", &flag); + if ((i == 1) && (flag > 0) && (flag <= MSG_TYPE_LAST)) ns->supported_readables |= (1 << flag); /*3. Next info */ } + /* Send resulting state */ strcpy (cmdback, "ExtendedTextSet"); + for (i = 0; i <= MSG_TYPE_LAST; i++) if (ns->supported_readables & (1 << i)) { @@ -668,6 +669,7 @@ snprintf (temp, sizeof (temp), "%d", i); strcat (cmdback, temp); } + Write_String_To_Socket (ns, cmdback, strlen (cmdback)); } @@ -704,8 +706,9 @@ sl.buf = reply; strcpy ((char *) sl.buf, "smooth "); sl.len = strlen ((char *) sl.buf); - SockList_AddShort (&sl, face); - SockList_AddShort (&sl, smoothface); + + sl << uint16 (face) << uint16 (smoothface); + Send_With_Handling (ns, &sl); } @@ -840,12 +843,14 @@ sl.buf = command; strcpy ((char *) sl.buf, "comc "); sl.len = 5; - SockList_AddShort (&sl, packet); + if (FABS (pl->ob->speed) < 0.001) time = MAX_TIME * 100; else time = (int) (MAX_TIME / FABS (pl->ob->speed)); - SockList_AddInt (&sl, time); + + sl << uint16 (packet) << uint32 (time); + Send_With_Handling (&pl->socket, &sl); } @@ -1123,6 +1128,7 @@ AddIfShort (pl->last_stats.Con, pl->ob->stats.Con, CS_STAT_CON); AddIfShort (pl->last_stats.Cha, pl->ob->stats.Cha, CS_STAT_CHA); } + if (pl->socket.exp64) { uint8 s; @@ -1142,14 +1148,12 @@ } } } + 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); AddIfShort (pl->last_stats.ac, pl->ob->stats.ac, CS_STAT_AC); @@ -1159,16 +1163,17 @@ AddIfFloat (pl->last_weapon_sp, pl->weapon_sp, CS_STAT_WEAP_SP); AddIfInt (pl->last_weight_limit, (sint32) weight_limit[pl->ob->stats.Str], CS_STAT_WEIGHT_LIM); flags = 0; + if (pl->fire_on) flags |= SF_FIREON; + if (pl->run_on) flags |= SF_RUNON; 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; @@ -1178,15 +1183,18 @@ /* Skip ones we won't send */ if (atnr_cs_stat[i] == -1) continue; + AddIfShort (pl->last_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); } + rangetostring (pl->ob, buf); /* we want use the new fire & run system in new client */ AddIfString (pl->socket.stats.range, buf, CS_STAT_RANGE); set_title (pl->ob, buf); @@ -1200,10 +1208,10 @@ #endif Send_With_Handling (&pl->socket, &sl); } + free (sl.buf); } - /** * Tells the client that here is a player it should start using. */ @@ -1231,7 +1239,6 @@ SET_FLAG (pl->ob, FLAG_CLIENT_SENT); } - /** * Need to send an animation sequence to the client. * We will send appropriate face commands to the client if we haven't @@ -1428,9 +1435,8 @@ { /* All of this is just accounting stuff */ if (tframes > 100) - { - tframes = tbytes = 0; - } + tframes = tbytes = 0; + tframes++; frames++; tbytes += sl.len; @@ -1439,6 +1445,7 @@ Send_With_Handling (ns, &sl); ns->sent_scroll = 0; } + free (sl.buf); } @@ -1450,9 +1457,10 @@ cell->faces[0] = face0; cell->faces[1] = face1; cell->faces[2] = face2; - cell->count = count; - cell->stat_hp = 0; - cell->player = 0; + cell->count = count; + cell->stat_hp = 0; + cell->flags = 0; + cell->player = 0; } #define MAX_HEAD_POS MAX(MAX_CLIENT_X, MAX_CLIENT_Y) @@ -1533,7 +1541,7 @@ */ static int -update_space (SockList * sl, NewSocket * ns, mapstruct *mp, int mx, int my, int sx, int sy, int layer) +update_space (SockList * sl, NewSocket * ns, maptile *mp, int mx, int my, int sx, int sy, int layer) { object *ob, *head; uint16 face_num; @@ -1757,7 +1765,7 @@ */ static inline int -update_smooth (SockList * sl, NewSocket * ns, mapstruct *mp, int mx, int my, int sx, int sy, int layer) +update_smooth (SockList * sl, NewSocket * ns, maptile *mp, int mx, int my, int sx, int sy, int layer) { object *ob; int smoothlevel; /* old face_num; */ @@ -1845,7 +1853,7 @@ uint8 eentrysize; uint16 ewhatstart, ewhatflag; uint8 extendedinfos; - mapstruct *m; + maptile *m; NewSocket & socket = pl->contr->socket; @@ -1858,6 +1866,7 @@ strcpy ((char *) sl.buf, "map1a "); sl.len = strlen ((char *) sl.buf); startlen = sl.len; + /*Extendedmapinfo structure initialisation */ if (socket.ext_mapinfos) { @@ -1865,8 +1874,10 @@ strcpy ((char *) esl.buf, "mapextended "); esl.len = strlen ((char *) esl.buf); extendedinfos = EMI_NOREDRAW; + if (socket.EMI_smooth) extendedinfos |= EMI_SMOOTH; + ewhatstart = esl.len; ewhatflag = extendedinfos; /*The EMI_NOREDRAW bit could need to be taken away */ @@ -1882,6 +1893,7 @@ ewhatflag = 0; estartlen = 0; } + /* Init data to zero */ memset (heads, 0, sizeof (object *) * MAX_HEAD_POS * MAX_HEAD_POS * MAX_LAYERS); @@ -1895,6 +1907,7 @@ */ 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; @@ -1937,15 +1950,11 @@ */ got_one = 0; for (i = oldlen + 2; i < sl.len; i++) - { - if (sl.buf[i]) - got_one = 1; - } + if (sl.buf[i]) + got_one = 1; if (got_one && (mask & 0xf)) - { - sl.buf[oldlen + 1] = mask & 0xff; - } + sl.buf[oldlen + 1] = mask & 0xff; else { /*either all faces blank, either no face at all */ if (mask & 0xf) /*at least 1 face, we know it's blank, only send coordinates */ @@ -1953,13 +1962,14 @@ else sl.len = oldlen; } + /*What concerns extendinfos, nothing to be done for now * (perhaps effects layer later) */ continue; /* don't do processing below */ } - MapCell & lastcell = socket.lastmap.cells[ax][ay]; + MapCell &lastcell = socket.lastmap.cells[ax][ay]; d = pl->contr->blocked_los[ax][ay]; @@ -1969,6 +1979,7 @@ 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 @@ -1992,8 +2003,10 @@ oldlen = sl.len; SockList_AddShort (&sl, mask); + if (lastcell.count != -1) need_send = 1; + count = -1; if (socket.mapmode == Map1aCmd && have_head (ax, ay)) @@ -2008,26 +2021,21 @@ 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) + if (lastcell.faces[0] != 0 || lastcell.faces[1] != 0 || lastcell.faces[2] != 0 + || lastcell.stat_hp || lastcell.flags || lastcell.player) need_send = 1; + map_clearcell (&lastcell, 0, 0, 0, count); } if ((mask & 0xf) || need_send) - { - sl.buf[oldlen + 1] = mask & 0xff; - } + sl.buf[oldlen + 1] = mask & 0xff; else - { - sl.len = oldlen; - } + sl.len = oldlen; } else { @@ -2078,7 +2086,8 @@ { uint8 stat_hp = 0; uint8 stat_width = 0; - tag_t player = 0; + uint8 flags = 0; + UUID player = 0; // send hp information, if applicable if (object *op = GET_MAP_FACE_OBJ (m, nx, ny, 0)) @@ -2095,6 +2104,9 @@ } } + if (op->msg && op->msg[0] == '@') + flags |= 1; + if (op->type == PLAYER && op != pl) player = op->count; } @@ -2106,28 +2118,38 @@ mask |= 0x8; *last_ext |= 0x80; last_ext = sl.buf + sl.len; - SockList_AddChar (&sl, 5); - SockList_AddChar (&sl, stat_hp); + + sl << uint8 (5) << uint8 (stat_hp); if (stat_width > 1) { *last_ext |= 0x80; last_ext = sl.buf + sl.len; - SockList_AddChar (&sl, 6); - SockList_AddChar (&sl, stat_width); + + sl << uint8 (6) << uint8 (stat_width); } } - if (lastcell.player !=player) + 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); + + sl << uint8 (0x47) << uint8 (8) << (uint64)player; + } + + if (lastcell.flags != flags) + { + lastcell.flags = flags; + + mask |= 0x8; + *last_ext |= 0x80; + last_ext = sl.buf + sl.len; + + sl << uint8 (8) << uint8 (flags); } } @@ -2153,43 +2175,38 @@ { 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); + + sl << uint16 (pl->face->number); } } - /* Top face */ else { + /* Top face */ 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; - } + 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; - } + sl.buf[oldlen + 1] = mask & 0xff; else - { - sl.len = oldlen; - } + sl.len = oldlen; + if (emask & 0xf) - { - esl.buf[eoldlen + 1] = emask & 0xff; - } + esl.buf[eoldlen + 1] = emask & 0xff; else - { - esl.len = eoldlen; - } + esl.len = eoldlen; } /* else this is a viewable space */ } /* for x loop */ } /* for y loop */ @@ -2205,17 +2222,19 @@ ewhatflag &= (~EMI_NOREDRAW); esl.buf[ewhatstart + 1] = ewhatflag & 0xff; } + if (esl.len > estartlen) - { - Send_With_Handling (&socket, &esl); - } + Send_With_Handling (&socket, &esl); + free (esl.buf); } + if (sl.len > startlen || socket.sent_scroll) { Send_With_Handling (&socket, &sl); socket.sent_scroll = 0; } + free (sl.buf); } @@ -2231,7 +2250,7 @@ New_Face *floor2; int d, mflags; struct Map newmap; - mapstruct *m, *pm; + maptile *m, *pm; if (pl->type != PLAYER) { @@ -2449,14 +2468,13 @@ 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); + + sl << uint8 (flags) << uint32 (spell->count); + + if (flags & UPD_SP_MANA ) sl << uint16 (spell->last_sp); + if (flags & UPD_SP_GRACE ) sl << uint16 (spell->last_grace); + if (flags & UPD_SP_DAMAGE) sl << uint16 (spell->last_eat); + flags = 0; Send_With_Handling (&pl->socket, &sl); free (sl.buf); @@ -2480,14 +2498,16 @@ sl.buf = (unsigned char *) malloc (MAXSOCKBUF); strcpy ((char *) sl.buf, "delspell "); sl.len = strlen ((char *) sl.buf); - SockList_AddInt (&sl, spell->count); + + sl << uint32 (spell->count); + Send_With_Handling (&pl->socket, &sl); free (sl.buf); } /* appends the spell *spell to the Socklist we will send the data to. */ static void -append_spell (player *pl, SockList * sl, object *spell) +append_spell (player *pl, SockList &sl, object *spell) { int len, i, skill = 0; @@ -2496,17 +2516,11 @@ LOG (llevError, "item number %d is a spell with no name.\n", spell->count); return; } - SockList_AddInt (sl, spell->count); - SockList_AddShort (sl, spell->level); - SockList_AddShort (sl, spell->casting_time); + /* store costs and damage in the object struct, to compare to later */ - spell->last_sp = SP_level_spellpoint_cost (pl->ob, spell, SPELL_MANA); + spell->last_sp = SP_level_spellpoint_cost (pl->ob, spell, SPELL_MANA); spell->last_grace = SP_level_spellpoint_cost (pl->ob, spell, SPELL_GRACE); - spell->last_eat = spell->stats.dam + SP_level_dam_adjust (pl->ob, spell); - /* send the current values */ - SockList_AddShort (sl, spell->last_sp); - SockList_AddShort (sl, spell->last_grace); - SockList_AddShort (sl, spell->last_eat); + spell->last_eat = spell->stats.dam + SP_level_dam_adjust (pl->ob, spell); /* figure out which skill it uses, if it uses one */ if (spell->skill) @@ -2518,27 +2532,19 @@ break; } } - SockList_AddChar (sl, skill); - SockList_AddInt (sl, spell->path_attuned); - SockList_AddInt (sl, (spell->face) ? spell->face->number : 0); - - len = strlen (spell->name); - SockList_AddChar (sl, (char) len); - memcpy (sl->buf + sl->len, spell->name, len); - sl->len += len; - - if (!spell->msg) - { - SockList_AddShort (sl, 0); - } - else - { - len = strlen (spell->msg); - SockList_AddShort (sl, len); - memcpy (sl->buf + sl->len, spell->msg, len); - sl->len += len; - } + /* send the current values */ + sl << uint32 (spell->count) + << uint16 (spell->level) + << uint16 (spell->casting_time) + << uint16 (spell->last_sp) + << uint16 (spell->last_grace) + << uint16 (spell->last_eat) + << uint8 (skill) + << uint32 (spell->path_attuned) + << uint32 (spell->face ? spell->face->number : 0) + << data8 (spell->name) + << data16 (spell->msg); } /** @@ -2579,13 +2585,15 @@ */ 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); + + append_spell (pl, sl, spell); } } else if (spell->type != SPELL) @@ -2594,12 +2602,14 @@ return; } else - append_spell (pl, &sl, spell); + append_spell (pl, sl, spell); + if (sl.len >= MAXSOCKBUF) { LOG (llevError, "Buffer overflow in esrv_add_spells!\n"); fatal (0); } + /* finally, we can send the packet */ Send_With_Handling (&pl->socket, &sl); free (sl.buf);