1 | |
|
|
2 | /* |
|
|
3 | * static char *rcsid_init_c = |
|
|
4 | * "$Id: request.C,v 1.16 2006/09/10 13:43:33 root Exp $"; |
|
|
5 | */ |
|
|
6 | |
|
|
7 | /* |
1 | /* |
8 | CrossFire, A Multiplayer game for X-windows |
2 | CrossFire, A Multiplayer game for X-windows |
9 | |
3 | |
10 | Copyright (C) 2001 Mark Wedel |
4 | Copyright (C) 2001 Mark Wedel |
11 | Copyright (C) 1992 Frank Tore Johansen |
5 | Copyright (C) 1992 Frank Tore Johansen |
… | |
… | |
22 | |
16 | |
23 | You should have received a copy of the GNU General Public License |
17 | You should have received a copy of the GNU General Public License |
24 | along with this program; if not, write to the Free Software |
18 | along with this program; if not, write to the Free Software |
25 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
26 | |
20 | |
27 | The author can be reached via e-mail to crossfire-devel@real-time.com |
21 | The author can be reached via e-mail to <crossfire@schmorp.de> |
28 | */ |
22 | */ |
29 | |
23 | |
30 | /** |
24 | /** |
31 | * \file |
25 | * \file |
32 | * Client handling. |
26 | * Client handling. |
… | |
… | |
50 | * operations |
44 | * operations |
51 | * |
45 | * |
52 | * esrv_map_doneredraw finishes the map update, and ships across the |
46 | * esrv_map_doneredraw finishes the map update, and ships across the |
53 | * map updates. |
47 | * map updates. |
54 | * |
48 | * |
55 | * esrv_map_scroll tells the client to scroll the map, and does similarily |
|
|
56 | * for the locally cached copy. |
|
|
57 | */ |
49 | */ |
58 | |
50 | |
59 | #include <global.h> |
51 | #include <global.h> |
60 | #include <sproto.h> |
52 | #include <sproto.h> |
61 | |
53 | |
… | |
… | |
266 | if (!strncmp (buf, "spatial ", 8)) |
258 | if (!strncmp (buf, "spatial ", 8)) |
267 | { |
259 | { |
268 | buf += 8; |
260 | buf += 8; |
269 | |
261 | |
270 | // initial map and its origin |
262 | // initial map and its origin |
271 | mapstruct *map = pl->ob->map; |
263 | maptile *map = pl->ob->map; |
272 | sint16 dx, dy; |
264 | sint16 dx, dy; |
273 | int mapx = pl->socket.mapx / 2 - pl->ob->x; |
265 | int mapx = pl->socket.mapx / 2 - pl->ob->x; |
274 | int mapy = pl->socket.mapy / 2 - pl->ob->y; |
266 | int mapy = pl->socket.mapy / 2 - pl->ob->y; |
275 | int max_distance = 8; // limit maximum path length to something generous |
267 | int max_distance = 8; // limit maximum path length to something generous |
276 | |
268 | |
… | |
… | |
581 | char command[50]; |
573 | char command[50]; |
582 | int info, nextinfo; |
574 | int info, nextinfo; |
583 | |
575 | |
584 | cmdback[0] = '\0'; |
576 | cmdback[0] = '\0'; |
585 | nextinfo = 0; |
577 | nextinfo = 0; |
|
|
578 | |
586 | while (1) |
579 | while (1) |
587 | { |
580 | { |
588 | /* 1. Extract an info */ |
581 | /* 1. Extract an info */ |
589 | info = nextinfo; |
582 | info = nextinfo; |
|
|
583 | |
590 | while ((info < len) && (buf[info] == ' ')) |
584 | while ((info < len) && (buf[info] == ' ')) |
591 | info++; |
585 | info++; |
|
|
586 | |
592 | if (info >= len) |
587 | if (info >= len) |
593 | break; |
588 | break; |
|
|
589 | |
594 | nextinfo = info + 1; |
590 | nextinfo = info + 1; |
|
|
591 | |
595 | while ((nextinfo < len) && (buf[nextinfo] != ' ')) |
592 | while ((nextinfo < len) && (buf[nextinfo] != ' ')) |
596 | nextinfo++; |
593 | nextinfo++; |
|
|
594 | |
597 | if (nextinfo - info >= 49) /*Erroneous info asked */ |
595 | if (nextinfo - info >= 49) /*Erroneous info asked */ |
598 | continue; |
596 | continue; |
|
|
597 | |
599 | strncpy (command, &(buf[info]), nextinfo - info); |
598 | strncpy (command, &(buf[info]), nextinfo - info); |
600 | command[nextinfo - info] = '\0'; |
599 | |
601 | /* 2. Interpret info */ |
600 | /* 2. Interpret info */ |
602 | if (!strcmp ("smooth", command)) |
601 | if (!strcmp ("smooth", command)) |
603 | { |
|
|
604 | /* Toggle smoothing */ |
602 | /* Toggle smoothing */ |
605 | ns->EMI_smooth = !ns->EMI_smooth; |
603 | ns->EMI_smooth = !ns->EMI_smooth; |
606 | } |
|
|
607 | else |
604 | else |
608 | { |
|
|
609 | /*bad value */ |
605 | /*bad value */; |
610 | } |
606 | |
611 | /*3. Next info */ |
607 | /*3. Next info */ |
612 | } |
608 | } |
|
|
609 | |
613 | strcpy (cmdback, "ExtendedInfoSet"); |
610 | strcpy (cmdback, "ExtendedInfoSet"); |
|
|
611 | |
614 | if (ns->EMI_smooth) |
612 | if (ns->EMI_smooth) |
615 | { |
613 | { |
616 | strcat (cmdback, " "); |
614 | strcat (cmdback, " "); |
617 | strcat (cmdback, "smoothing"); |
615 | strcat (cmdback, "smoothing"); |
618 | } |
616 | } |
|
|
617 | |
619 | Write_String_To_Socket (ns, cmdback, strlen (cmdback)); |
618 | Write_String_To_Socket (ns, cmdback, strlen (cmdback)); |
620 | } |
619 | } |
621 | |
620 | |
622 | /* |
621 | /* |
623 | #define MSG_TYPE_BOOK 1 |
622 | #define MSG_TYPE_BOOK 1 |
… | |
… | |
635 | char temp[10]; |
634 | char temp[10]; |
636 | char command[50]; |
635 | char command[50]; |
637 | int info, nextinfo, i, flag; |
636 | int info, nextinfo, i, flag; |
638 | |
637 | |
639 | cmdback[0] = '\0'; |
638 | cmdback[0] = '\0'; |
|
|
639 | |
640 | nextinfo = 0; |
640 | nextinfo = 0; |
641 | while (1) |
641 | while (1) |
642 | { |
642 | { |
643 | /* 1. Extract an info */ |
643 | /* 1. Extract an info */ |
644 | info = nextinfo; |
644 | info = nextinfo; |
|
|
645 | |
645 | while ((info < len) && (buf[info] == ' ')) |
646 | while ((info < len) && (buf[info] == ' ')) |
646 | info++; |
647 | info++; |
|
|
648 | |
647 | if (info >= len) |
649 | if (info >= len) |
648 | break; |
650 | break; |
|
|
651 | |
649 | nextinfo = info + 1; |
652 | nextinfo = info + 1; |
|
|
653 | |
650 | while ((nextinfo < len) && (buf[nextinfo] != ' ')) |
654 | while ((nextinfo < len) && (buf[nextinfo] != ' ')) |
651 | nextinfo++; |
655 | nextinfo++; |
|
|
656 | |
652 | if (nextinfo - info >= 49) /*Erroneous info asked */ |
657 | if (nextinfo - info >= 49) /*Erroneous info asked */ |
653 | continue; |
658 | continue; |
|
|
659 | |
654 | strncpy (command, &(buf[info]), nextinfo - info); |
660 | strncpy (command, &(buf[info]), nextinfo - info); |
655 | command[nextinfo - info] = '\0'; |
661 | command[nextinfo - info] = '\0'; |
656 | /* 2. Interpret info */ |
662 | /* 2. Interpret info */ |
657 | i = sscanf (command, "%d", &flag); |
663 | i = sscanf (command, "%d", &flag); |
|
|
664 | |
658 | if ((i == 1) && (flag > 0) && (flag <= MSG_TYPE_LAST)) |
665 | if ((i == 1) && (flag > 0) && (flag <= MSG_TYPE_LAST)) |
659 | ns->supported_readables |= (1 << flag); |
666 | ns->supported_readables |= (1 << flag); |
660 | /*3. Next info */ |
667 | /*3. Next info */ |
661 | } |
668 | } |
|
|
669 | |
662 | /* Send resulting state */ |
670 | /* Send resulting state */ |
663 | strcpy (cmdback, "ExtendedTextSet"); |
671 | strcpy (cmdback, "ExtendedTextSet"); |
|
|
672 | |
664 | for (i = 0; i <= MSG_TYPE_LAST; i++) |
673 | for (i = 0; i <= MSG_TYPE_LAST; i++) |
665 | if (ns->supported_readables & (1 << i)) |
674 | if (ns->supported_readables & (1 << i)) |
666 | { |
675 | { |
667 | strcat (cmdback, " "); |
676 | strcat (cmdback, " "); |
668 | snprintf (temp, sizeof (temp), "%d", i); |
677 | snprintf (temp, sizeof (temp), "%d", i); |
669 | strcat (cmdback, temp); |
678 | strcat (cmdback, temp); |
670 | } |
679 | } |
|
|
680 | |
671 | Write_String_To_Socket (ns, cmdback, strlen (cmdback)); |
681 | Write_String_To_Socket (ns, cmdback, strlen (cmdback)); |
672 | } |
682 | } |
673 | |
683 | |
674 | /** |
684 | /** |
675 | * A lot like the old AskSmooth (in fact, now called by AskSmooth). |
685 | * A lot like the old AskSmooth (in fact, now called by AskSmooth). |
… | |
… | |
1426 | |
1436 | |
1427 | if (sl.len > (int) strlen ("map ") || ns->sent_scroll) |
1437 | if (sl.len > (int) strlen ("map ") || ns->sent_scroll) |
1428 | { |
1438 | { |
1429 | /* All of this is just accounting stuff */ |
1439 | /* All of this is just accounting stuff */ |
1430 | if (tframes > 100) |
1440 | if (tframes > 100) |
1431 | { |
|
|
1432 | tframes = tbytes = 0; |
1441 | tframes = tbytes = 0; |
1433 | } |
1442 | |
1434 | tframes++; |
1443 | tframes++; |
1435 | frames++; |
1444 | frames++; |
1436 | tbytes += sl.len; |
1445 | tbytes += sl.len; |
1437 | bytes += sl.len; |
1446 | bytes += sl.len; |
1438 | memcpy (&ns->lastmap, newmap, sizeof (struct Map)); |
1447 | memcpy (&ns->lastmap, newmap, sizeof (struct Map)); |
1439 | Send_With_Handling (ns, &sl); |
1448 | Send_With_Handling (ns, &sl); |
1440 | ns->sent_scroll = 0; |
1449 | ns->sent_scroll = 0; |
1441 | } |
1450 | } |
|
|
1451 | |
1442 | free (sl.buf); |
1452 | free (sl.buf); |
1443 | } |
1453 | } |
1444 | |
1454 | |
1445 | |
1455 | |
1446 | /** Clears a map cell */ |
1456 | /** Clears a map cell */ |
… | |
… | |
1531 | * the case, it seems to make more sense to have these layer values |
1541 | * the case, it seems to make more sense to have these layer values |
1532 | * actually match. |
1542 | * actually match. |
1533 | */ |
1543 | */ |
1534 | |
1544 | |
1535 | static int |
1545 | static int |
1536 | update_space (SockList * sl, NewSocket * ns, mapstruct *mp, int mx, int my, int sx, int sy, int layer) |
1546 | update_space (SockList * sl, NewSocket * ns, maptile *mp, int mx, int my, int sx, int sy, int layer) |
1537 | { |
1547 | { |
1538 | object *ob, *head; |
1548 | object *ob, *head; |
1539 | uint16 face_num; |
1549 | uint16 face_num; |
1540 | int bx, by, i; |
1550 | int bx, by, i; |
1541 | |
1551 | |
… | |
… | |
1755 | * top layer (this matches what the GET_MAP_FACE and GET_MAP_FACE_OBJ |
1765 | * top layer (this matches what the GET_MAP_FACE and GET_MAP_FACE_OBJ |
1756 | * take. |
1766 | * take. |
1757 | */ |
1767 | */ |
1758 | |
1768 | |
1759 | static inline int |
1769 | static inline int |
1760 | update_smooth (SockList * sl, NewSocket * ns, mapstruct *mp, int mx, int my, int sx, int sy, int layer) |
1770 | update_smooth (SockList * sl, NewSocket * ns, maptile *mp, int mx, int my, int sx, int sy, int layer) |
1761 | { |
1771 | { |
1762 | object *ob; |
1772 | object *ob; |
1763 | int smoothlevel; /* old face_num; */ |
1773 | int smoothlevel; /* old face_num; */ |
1764 | |
1774 | |
1765 | ob = GET_MAP_FACE_OBJ (mp, mx, my, layer); |
1775 | ob = GET_MAP_FACE_OBJ (mp, mx, my, layer); |
… | |
… | |
1843 | SockList esl; /*For extended Map info */ |
1853 | SockList esl; /*For extended Map info */ |
1844 | uint16 mask, emask; |
1854 | uint16 mask, emask; |
1845 | uint8 eentrysize; |
1855 | uint8 eentrysize; |
1846 | uint16 ewhatstart, ewhatflag; |
1856 | uint16 ewhatstart, ewhatflag; |
1847 | uint8 extendedinfos; |
1857 | uint8 extendedinfos; |
1848 | mapstruct *m; |
1858 | maptile *m; |
1849 | |
1859 | |
1850 | NewSocket & socket = pl->contr->socket; |
1860 | NewSocket & socket = pl->contr->socket; |
1851 | |
1861 | |
1852 | check_map_change (pl->contr); |
1862 | check_map_change (pl->contr); |
1853 | |
1863 | |
… | |
… | |
2116 | SockList_AddChar (&sl, 6); |
2126 | SockList_AddChar (&sl, 6); |
2117 | SockList_AddChar (&sl, stat_width); |
2127 | SockList_AddChar (&sl, stat_width); |
2118 | } |
2128 | } |
2119 | } |
2129 | } |
2120 | |
2130 | |
2121 | if (lastcell.player !=player) |
2131 | if (lastcell.player != player) |
2122 | { |
2132 | { |
2123 | lastcell.player = player; |
2133 | lastcell.player = player; |
2124 | |
2134 | |
2125 | mask |= 0x8; |
2135 | mask |= 0x8; |
2126 | *last_ext |= 0x80; |
2136 | *last_ext |= 0x80; |
… | |
… | |
2203 | * it doesn't need draw! |
2213 | * it doesn't need draw! |
2204 | */ |
2214 | */ |
2205 | ewhatflag &= (~EMI_NOREDRAW); |
2215 | ewhatflag &= (~EMI_NOREDRAW); |
2206 | esl.buf[ewhatstart + 1] = ewhatflag & 0xff; |
2216 | esl.buf[ewhatstart + 1] = ewhatflag & 0xff; |
2207 | } |
2217 | } |
|
|
2218 | |
2208 | if (esl.len > estartlen) |
2219 | if (esl.len > estartlen) |
2209 | { |
|
|
2210 | Send_With_Handling (&socket, &esl); |
2220 | Send_With_Handling (&socket, &esl); |
2211 | } |
2221 | |
2212 | free (esl.buf); |
2222 | free (esl.buf); |
2213 | } |
2223 | } |
|
|
2224 | |
2214 | if (sl.len > startlen || socket.sent_scroll) |
2225 | if (sl.len > startlen || socket.sent_scroll) |
2215 | { |
2226 | { |
2216 | Send_With_Handling (&socket, &sl); |
2227 | Send_With_Handling (&socket, &sl); |
2217 | socket.sent_scroll = 0; |
2228 | socket.sent_scroll = 0; |
2218 | } |
2229 | } |
|
|
2230 | |
2219 | free (sl.buf); |
2231 | free (sl.buf); |
2220 | } |
2232 | } |
2221 | |
2233 | |
2222 | /** |
2234 | /** |
2223 | * Draws client map. |
2235 | * Draws client map. |
… | |
… | |
2229 | sint16 ax, ay, nx, ny; /* ax and ay goes from 0 to max-size of arrays */ |
2241 | sint16 ax, ay, nx, ny; /* ax and ay goes from 0 to max-size of arrays */ |
2230 | New_Face *face, *floor; |
2242 | New_Face *face, *floor; |
2231 | New_Face *floor2; |
2243 | New_Face *floor2; |
2232 | int d, mflags; |
2244 | int d, mflags; |
2233 | struct Map newmap; |
2245 | struct Map newmap; |
2234 | mapstruct *m, *pm; |
2246 | maptile *m, *pm; |
2235 | |
2247 | |
2236 | if (pl->type != PLAYER) |
2248 | if (pl->type != PLAYER) |
2237 | { |
2249 | { |
2238 | LOG (llevError, "draw_client_map called with non player/non eric-server\n"); |
2250 | LOG (llevError, "draw_client_map called with non player/non eric-server\n"); |
2239 | return; |
2251 | return; |