ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/socket/request.C
(Generate patch)

Comparing deliantra/server/socket/request.C (file contents):
Revision 1.16 by root, Sun Sep 10 13:43:33 2006 UTC vs.
Revision 1.33 by root, Thu Dec 14 01:21:58 2006 UTC

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
65#include <commands.h> 57#include <commands.h>
66 58
67/* This block is basically taken from socket.c - I assume if it works there, 59/* This block is basically taken from socket.c - I assume if it works there,
68 * it should work here. 60 * it should work here.
69 */ 61 */
70#ifndef WIN32 /* ---win32 exclude unix headers */
71# include <sys/types.h> 62#include <sys/types.h>
72# include <sys/time.h> 63#include <sys/time.h>
73# include <sys/socket.h> 64#include <sys/socket.h>
74# include <netinet/in.h> 65#include <netinet/in.h>
75# include <netdb.h> 66#include <netdb.h>
76#endif /* win32 */
77 67
78#ifdef HAVE_UNISTD_H 68#ifdef HAVE_UNISTD_H
79# include <unistd.h> 69# include <unistd.h>
80#endif 70#endif
81 71
112{ 102{
113 struct Map newmap; 103 struct Map newmap;
114 int x, y, mx, my; 104 int x, y, mx, my;
115 105
116 { 106 {
117 char buf[MAXSOCKBUF]; 107 packet sl;
118 108
119 sprintf (buf, "map_scroll %d %d", dx, dy); 109 sl.printf ("map_scroll %d %d", dx, dy);
120 Write_String_To_Socket (ns, buf, strlen (buf)); 110 ns->send_packet (sl);
121 } 111 }
122 112
123 /* If we are using the Map1aCmd, we may in fact send 113 /* If we are using the Map1aCmd, we may in fact send
124 * head information that is outside the viewable map. 114 * head information that is outside the viewable map.
125 * So set the mx,my to the max value we want to 115 * So set the mx,my to the max value we want to
145 for (x = 0; x < mx; x++) 135 for (x = 0; x < mx; x++)
146 { 136 {
147 for (y = 0; y < my; y++) 137 for (y = 0; y < my; y++)
148 { 138 {
149 if (x >= ns->mapx || y >= ns->mapy) 139 if (x >= ns->mapx || y >= ns->mapy)
150 {
151 /* clear cells outside the viewable area */ 140 /* clear cells outside the viewable area */
152 memset (&newmap.cells[x][y], 0, sizeof (struct MapCell)); 141 memset (&newmap.cells[x][y], 0, sizeof (struct MapCell));
153 }
154 else if ((x + dx) < 0 || (x + dx) >= ns->mapx || (y + dy) < 0 || (y + dy) >= ns->mapy) 142 else if ((x + dx) < 0 || (x + dx) >= ns->mapx || (y + dy) < 0 || (y + dy) >= ns->mapy)
155 {
156 /* clear newly visible tiles within the viewable area */ 143 /* clear newly visible tiles within the viewable area */
157 memset (&(newmap.cells[x][y]), 0, sizeof (struct MapCell)); 144 memset (&(newmap.cells[x][y]), 0, sizeof (struct MapCell));
158 }
159 else 145 else
160 {
161 memcpy (&(newmap.cells[x][y]), &(ns->lastmap.cells[x + dx][y + dy]), sizeof (struct MapCell)); 146 memcpy (&(newmap.cells[x][y]), &(ns->lastmap.cells[x + dx][y + dy]), sizeof (struct MapCell));
162 }
163 } 147 }
164 } 148 }
165 149
166 memcpy (&(ns->lastmap), &newmap, sizeof (struct Map)); 150 memcpy (&(ns->lastmap), &newmap, sizeof (struct Map));
167 151
177 NewSocket & socket = pl->socket; 161 NewSocket & socket = pl->socket;
178 162
179 memset (&socket.lastmap, 0, sizeof (socket.lastmap)); 163 memset (&socket.lastmap, 0, sizeof (socket.lastmap));
180 164
181 if (socket.newmapcmd == 1) 165 if (socket.newmapcmd == 1)
182 Write_String_To_Socket (&socket, "newmap", 6); 166 socket.send_packet ("newmap");
183 167
184 socket.update_look = 1; 168 socket.update_look = 1;
185 socket.look_position = 0; 169 socket.look_position = 0;
186} 170}
187 171
218 flags, socket.mapx / 2 - ob->x, socket.mapy / 2 - ob->y, ob->map->width, ob->map->height, ob->map->path); 202 flags, socket.mapx / 2 - ob->x, socket.mapy / 2 - ob->y, ob->map->width, ob->map->height, ob->map->path);
219 } 203 }
220 else 204 else
221 snprintf (buf, MAX_BUF, "mapinfo current"); 205 snprintf (buf, MAX_BUF, "mapinfo current");
222 206
223 Write_String_To_Socket (&socket, buf, strlen (buf)); 207 socket.send_packet (buf);
224 } 208 }
225 } 209 }
226 else if (socket.current_x != ob->x || socket.current_y != ob->y) 210 else if (socket.current_x != ob->x || socket.current_y != ob->y)
227 { 211 {
228 int dx = ob->x - socket.current_x; 212 int dx = ob->x - socket.current_x;
266 if (!strncmp (buf, "spatial ", 8)) 250 if (!strncmp (buf, "spatial ", 8))
267 { 251 {
268 buf += 8; 252 buf += 8;
269 253
270 // initial map and its origin 254 // initial map and its origin
271 mapstruct *map = pl->ob->map; 255 maptile *map = pl->ob->map;
272 sint16 dx, dy; 256 sint16 dx, dy;
273 int mapx = pl->socket.mapx / 2 - pl->ob->x; 257 int mapx = pl->socket.mapx / 2 - pl->ob->x;
274 int mapy = pl->socket.mapy / 2 - pl->ob->y; 258 int mapy = pl->socket.mapy / 2 - pl->ob->y;
275 int max_distance = 8; // limit maximum path length to something generous 259 int max_distance = 8; // limit maximum path length to something generous
276 260
330 snprintf (bigbuf, MAX_BUF, "mapinfo %s nomap", token); 314 snprintf (bigbuf, MAX_BUF, "mapinfo %s nomap", token);
331 } 315 }
332 else 316 else
333 snprintf (bigbuf, MAX_BUF, "mapinfo %s unsupported", token); 317 snprintf (bigbuf, MAX_BUF, "mapinfo %s unsupported", token);
334 318
335 Write_String_To_Socket (&pl->socket, bigbuf, strlen (bigbuf)); 319 pl->socket.send_packet (bigbuf);
336} 320}
337 321
338/** This is the Setup cmd - easy first implementation */ 322/** This is the Setup cmd - easy first implementation */
339void 323void
340SetUp (char *buf, int len, NewSocket * ns) 324SetUp (char *buf, int len, NewSocket * ns)
347 * 331 *
348 * we send the status of the cmd back, or a FALSE is the cmd is the server unknown 332 * we send the status of the cmd back, or a FALSE is the cmd is the server unknown
349 * The client then must sort this out 333 * The client then must sort this out
350 */ 334 */
351 335
352 LOG (llevInfo, "Get SetupCmd:: %s\n", buf); 336 //LOG (llevInfo, "Get SetupCmd:: %s\n", buf);
337
353 strcpy (cmdback, "setup"); 338 strcpy (cmdback, "setup");
354 for (s = 0; s < len;) 339 for (s = 0; s < len; )
355 { 340 {
356
357 cmd = &buf[s]; 341 cmd = &buf[s];
358 342
359 /* find the next space, and put a null there */ 343 /* find the next space, and put a null there */
360 for (; buf[s] && buf[s] != ' '; s++); 344 for (; buf[s] && buf[s] != ' '; s++)
345 ;
346
361 buf[s++] = 0; 347 buf[s++] = 0;
348
362 while (buf[s] == ' ') 349 while (buf[s] == ' ')
363 s++; 350 s++;
364 351
365 if (s >= len) 352 if (s >= len)
366 break; 353 break;
367 354
368 param = &buf[s]; 355 param = &buf[s];
369 356
370 for (; buf[s] && buf[s] != ' '; s++); 357 for (; buf[s] && buf[s] != ' '; s++)
358 ;
359
371 buf[s++] = 0; 360 buf[s++] = 0;
361
372 while (buf[s] == ' ') 362 while (buf[s] == ' ')
373 s++; 363 s++;
374 364
375 slen = strlen (cmdback); 365 slen = strlen (cmdback);
376 safe_strcat (cmdback, " ", &slen, HUGE_BUF); 366 safe_strcat (cmdback, " ", &slen, HUGE_BUF);
537 * report a failure to the client. 527 * report a failure to the client.
538 */ 528 */
539 safe_strcat (cmdback, "FALSE", &slen, HUGE_BUF); 529 safe_strcat (cmdback, "FALSE", &slen, HUGE_BUF);
540 } 530 }
541 } /* for processing all the setup commands */ 531 } /* for processing all the setup commands */
532
542 LOG (llevInfo, "SendBack SetupCmd:: %s\n", cmdback); 533 LOG (llevInfo, "SendBack SetupCmd:: %s\n", cmdback);
543 Write_String_To_Socket (ns, cmdback, strlen (cmdback)); 534 ns->send_packet (cmdback);
544} 535}
545 536
546/** 537/**
547 * The client has requested to be added to the game. 538 * The client has requested to be added to the game.
548 * This is what takes care of it. We tell the client how things worked out. 539 * This is what takes care of it. We tell the client how things worked out.
554{ 545{
555 Settings oldsettings; 546 Settings oldsettings;
556 547
557 oldsettings = settings; 548 oldsettings = settings;
558 if (ns->status != Ns_Add || add_player (ns)) 549 if (ns->status != Ns_Add || add_player (ns))
559 { 550 ns->send_packet ("addme_failed");
560 Write_String_To_Socket (ns, "addme_failed", 12);
561 }
562 else 551 else
563 { 552 {
564 /* Basically, the add_player copies the socket structure into 553 /* Basically, the add_player copies the socket structure into
565 * the player structure, so this one (which is from init_sockets) 554 * the player structure, so this one (which is from init_sockets)
566 * is not needed anymore. The write below should still work, as the 555 * is not needed anymore. The write below should still work, as the
567 * stuff in ns is still relevant. 556 * stuff in ns is still relevant.
568 */ 557 */
569 Write_String_To_Socket (ns, "addme_success", 13); 558 ns->send_packet ("addme_success");
570 socket_info.nconns--; 559 socket_info.nconns--;
571 ns->status = Ns_Avail; 560 ns->status = Ns_Avail;
572 } 561 }
562
573 settings = oldsettings; 563 settings = oldsettings;
574} 564}
575 565
576/** Reply to ExtendedInfos command */ 566/** Reply to ExtendedInfos command */
577void 567void
581 char command[50]; 571 char command[50];
582 int info, nextinfo; 572 int info, nextinfo;
583 573
584 cmdback[0] = '\0'; 574 cmdback[0] = '\0';
585 nextinfo = 0; 575 nextinfo = 0;
576
586 while (1) 577 while (1)
587 { 578 {
588 /* 1. Extract an info */ 579 /* 1. Extract an info */
589 info = nextinfo; 580 info = nextinfo;
581
590 while ((info < len) && (buf[info] == ' ')) 582 while ((info < len) && (buf[info] == ' '))
591 info++; 583 info++;
584
592 if (info >= len) 585 if (info >= len)
593 break; 586 break;
587
594 nextinfo = info + 1; 588 nextinfo = info + 1;
589
595 while ((nextinfo < len) && (buf[nextinfo] != ' ')) 590 while ((nextinfo < len) && (buf[nextinfo] != ' '))
596 nextinfo++; 591 nextinfo++;
592
597 if (nextinfo - info >= 49) /*Erroneous info asked */ 593 if (nextinfo - info >= 49) /*Erroneous info asked */
598 continue; 594 continue;
595
599 strncpy (command, &(buf[info]), nextinfo - info); 596 strncpy (command, &(buf[info]), nextinfo - info);
600 command[nextinfo - info] = '\0'; 597
601 /* 2. Interpret info */ 598 /* 2. Interpret info */
602 if (!strcmp ("smooth", command)) 599 if (!strcmp ("smooth", command))
603 {
604 /* Toggle smoothing */ 600 /* Toggle smoothing */
605 ns->EMI_smooth = !ns->EMI_smooth; 601 ns->EMI_smooth = !ns->EMI_smooth;
606 }
607 else 602 else
608 {
609 /*bad value */ 603 /*bad value */;
610 } 604
611 /*3. Next info */ 605 /*3. Next info */
612 } 606 }
607
613 strcpy (cmdback, "ExtendedInfoSet"); 608 strcpy (cmdback, "ExtendedInfoSet");
609
614 if (ns->EMI_smooth) 610 if (ns->EMI_smooth)
615 { 611 {
616 strcat (cmdback, " "); 612 strcat (cmdback, " ");
617 strcat (cmdback, "smoothing"); 613 strcat (cmdback, "smoothing");
618 } 614 }
619 Write_String_To_Socket (ns, cmdback, strlen (cmdback)); 615
616 ns->send_packet (cmdback);
620} 617}
621 618
622/* 619/*
623#define MSG_TYPE_BOOK 1 620#define MSG_TYPE_BOOK 1
624#define MSG_TYPE_CARD 2 621#define MSG_TYPE_CARD 2
635 char temp[10]; 632 char temp[10];
636 char command[50]; 633 char command[50];
637 int info, nextinfo, i, flag; 634 int info, nextinfo, i, flag;
638 635
639 cmdback[0] = '\0'; 636 cmdback[0] = '\0';
637
640 nextinfo = 0; 638 nextinfo = 0;
641 while (1) 639 while (1)
642 { 640 {
643 /* 1. Extract an info */ 641 /* 1. Extract an info */
644 info = nextinfo; 642 info = nextinfo;
643
645 while ((info < len) && (buf[info] == ' ')) 644 while ((info < len) && (buf[info] == ' '))
646 info++; 645 info++;
646
647 if (info >= len) 647 if (info >= len)
648 break; 648 break;
649
649 nextinfo = info + 1; 650 nextinfo = info + 1;
651
650 while ((nextinfo < len) && (buf[nextinfo] != ' ')) 652 while ((nextinfo < len) && (buf[nextinfo] != ' '))
651 nextinfo++; 653 nextinfo++;
654
652 if (nextinfo - info >= 49) /*Erroneous info asked */ 655 if (nextinfo - info >= 49) /*Erroneous info asked */
653 continue; 656 continue;
657
654 strncpy (command, &(buf[info]), nextinfo - info); 658 strncpy (command, &(buf[info]), nextinfo - info);
655 command[nextinfo - info] = '\0'; 659 command[nextinfo - info] = '\0';
656 /* 2. Interpret info */ 660 /* 2. Interpret info */
657 i = sscanf (command, "%d", &flag); 661 i = sscanf (command, "%d", &flag);
662
658 if ((i == 1) && (flag > 0) && (flag <= MSG_TYPE_LAST)) 663 if ((i == 1) && (flag > 0) && (flag <= MSG_TYPE_LAST))
659 ns->supported_readables |= (1 << flag); 664 ns->supported_readables |= (1 << flag);
660 /*3. Next info */ 665 /*3. Next info */
661 } 666 }
667
662 /* Send resulting state */ 668 /* Send resulting state */
663 strcpy (cmdback, "ExtendedTextSet"); 669 strcpy (cmdback, "ExtendedTextSet");
670
664 for (i = 0; i <= MSG_TYPE_LAST; i++) 671 for (i = 0; i <= MSG_TYPE_LAST; i++)
665 if (ns->supported_readables & (1 << i)) 672 if (ns->supported_readables & (1 << i))
666 { 673 {
667 strcat (cmdback, " "); 674 strcat (cmdback, " ");
668 snprintf (temp, sizeof (temp), "%d", i); 675 snprintf (temp, sizeof (temp), "%d", i);
669 strcat (cmdback, temp); 676 strcat (cmdback, temp);
670 } 677 }
671 Write_String_To_Socket (ns, cmdback, strlen (cmdback)); 678
679 ns->send_packet (cmdback);
672} 680}
673 681
674/** 682/**
675 * A lot like the old AskSmooth (in fact, now called by AskSmooth). 683 * A lot like the old AskSmooth (in fact, now called by AskSmooth).
676 * Basically, it makes no sense to wait for the client to request a 684 * Basically, it makes no sense to wait for the client to request a
680 */ 688 */
681static void 689static void
682SendSmooth (NewSocket * ns, uint16 face) 690SendSmooth (NewSocket * ns, uint16 face)
683{ 691{
684 uint16 smoothface; 692 uint16 smoothface;
685 unsigned char reply[MAX_BUF];
686 SockList sl;
687 693
688 /* If we can't find a face, return and set it so we won't try to send this 694 /* If we can't find a face, return and set it so we won't try to send this
689 * again. 695 * again.
690 */ 696 */
691 if ((!FindSmooth (face, &smoothface)) && (!FindSmooth (smooth_face->number, &smoothface))) 697 if ((!FindSmooth (face, &smoothface)) && (!FindSmooth (smooth_face->number, &smoothface)))
699 if (!(ns->faces_sent[smoothface] & NS_FACESENT_FACE)) 705 if (!(ns->faces_sent[smoothface] & NS_FACESENT_FACE))
700 esrv_send_face (ns, smoothface, 0); 706 esrv_send_face (ns, smoothface, 0);
701 707
702 ns->faces_sent[face] |= NS_FACESENT_SMOOTH; 708 ns->faces_sent[face] |= NS_FACESENT_SMOOTH;
703 709
704 sl.buf = reply; 710 packet sl;
705 strcpy ((char *) sl.buf, "smooth "); 711
706 sl.len = strlen ((char *) sl.buf); 712 sl << "smooth "
707 SockList_AddShort (&sl, face); 713 << uint16 (face)
708 SockList_AddShort (&sl, smoothface); 714 << uint16 (smoothface);
715
709 Send_With_Handling (ns, &sl); 716 Send_With_Handling (ns, &sl);
710} 717}
711 718
712 /** 719 /**
713 * Tells client the picture it has to use 720 * Tells client the picture it has to use
720 727
721 facenbr = atoi (buf); 728 facenbr = atoi (buf);
722 SendSmooth (ns, facenbr); 729 SendSmooth (ns, facenbr);
723} 730}
724 731
725
726
727
728
729/** 732/**
730 * This handles the general commands from the client (ie, north, fire, cast, 733 * This handles the general commands from the client (ie, north, fire, cast,
731 * etc.) 734 * etc.)
732 */ 735 */
733void 736void
786 */ 789 */
787void 790void
788NewPlayerCmd (uint8 * buf, int len, player *pl) 791NewPlayerCmd (uint8 * buf, int len, player *pl)
789{ 792{
790 int time, repeat; 793 int time, repeat;
791 short packet;
792 unsigned char command[MAX_BUF]; 794 char command[MAX_BUF];
793 SockList sl; 795 int pktlen;
794 796
795 if (len < 7) 797 if (len < 7)
796 { 798 {
797 LOG (llevDebug, "Corrupt ncom command <%s> not long enough - discarding\n", buf); 799 LOG (llevDebug, "Corrupt ncom command <%s> not long enough - discarding\n", buf);
798 return; 800 return;
799 } 801 }
800 802
801 packet = GetShort_String (buf); 803 pktlen = net_uint16 (buf);
802 repeat = GetInt_String (buf + 2); 804 repeat = net_uint32 (buf + 2);
805
803 /* -1 is special - no repeat, but don't update */ 806 /* -1 is special - no repeat, but don't update */
804 if (repeat != -1) 807 if (repeat != -1)
805 {
806 pl->count = repeat; 808 pl->count = repeat;
807 } 809
808 if ((len - 4) >= MAX_BUF) 810 if ((len - 4) >= MAX_BUF)
809 len = MAX_BUF - 5; 811 len = MAX_BUF - 5;
810 812
811 strncpy ((char *) command, (char *) buf + 6, len - 4); 813 strncpy ((char *) command, (char *) buf + 6, len - 4);
812 command[len - 4] = '\0'; 814 command[len - 4] = '\0';
822 return; 824 return;
823 } 825 }
824 826
825 /* This should not happen anymore. */ 827 /* This should not happen anymore. */
826 if (pl->ob->speed_left < -1.0) 828 if (pl->ob->speed_left < -1.0)
827 {
828 LOG (llevError, "Player has negative time - shouldn't do command.\n"); 829 LOG (llevError, "Player has negative time - shouldn't do command.\n");
829 } 830
830 /* In c_new.c */ 831 /* In c_new.c */
831 execute_newserver_command (pl->ob, (char *) command); 832 execute_newserver_command (pl->ob, (char *) command);
832 /* Perhaps something better should be done with a left over count. 833 /* Perhaps something better should be done with a left over count.
833 * Cleaning up the input should probably be done first - all actions 834 * Cleaning up the input should probably be done first - all actions
834 * for the command that issued the count should be done before any other 835 * for the command that issued the count should be done before any other
835 * commands. 836 * commands.
836 */ 837 */
837 pl->count = 0; 838 pl->count = 0;
838 839
839 /* Send confirmation of command execution now */
840 sl.buf = command;
841 strcpy ((char *) sl.buf, "comc ");
842 sl.len = 5;
843 SockList_AddShort (&sl, packet);
844 if (FABS (pl->ob->speed) < 0.001) 840 if (FABS (pl->ob->speed) < 0.001)
845 time = MAX_TIME * 100; 841 time = MAX_TIME * 100;
846 else 842 else
847 time = (int) (MAX_TIME / FABS (pl->ob->speed)); 843 time = (int) (MAX_TIME / FABS (pl->ob->speed));
848 SockList_AddInt (&sl, time); 844
845 /* Send confirmation of command execution now */
846
847 packet sl;
848 sl << "comc " << uint16 (pktlen) << uint32 (time);
849 Send_With_Handling (&pl->socket, &sl); 849 Send_With_Handling (&pl->socket, &sl);
850} 850}
851 851
852 852
853/** This is a reply to a previous query. */ 853/** This is a reply to a previous query. */
966 /* these are old dxclients */ 966 /* these are old dxclients */
967 /* Version 1024 added support for singular + plural name values - 967 /* Version 1024 added support for singular + plural name values -
968 * requiing this minimal value reduces complexity of that code, and it 968 * requiing this minimal value reduces complexity of that code, and it
969 * has been around for a long time. 969 * has been around for a long time.
970 */ 970 */
971 if (!strcmp (" CF DX CLIENT", cp) || ns->sc_version < 1024) 971 if (ns->sc_version < 1026)
972 { 972 {
973 sprintf (version_warning, "drawinfo %d %s", NDI_RED, 973 sprintf (version_warning, "drawinfo %d %s", NDI_RED,
974 "**** VERSION WARNING ****\n**** CLIENT IS TOO OLD!! UPDATE THE CLIENT!! ****"); 974 "**** VERSION WARNING ****\n**** CLIENT IS TOO OLD!! UPDATE THE CLIENT!! ****");
975 Write_String_To_Socket (ns, version_warning, strlen (version_warning)); 975 ns->send_packet (version_warning);
976 } 976 }
977 977
978 } 978 }
979} 979}
980 980
1052send_query (NewSocket * ns, uint8 flags, char *text) 1052send_query (NewSocket * ns, uint8 flags, char *text)
1053{ 1053{
1054 char buf[MAX_BUF]; 1054 char buf[MAX_BUF];
1055 1055
1056 sprintf (buf, "query %d %s", flags, text ? text : ""); 1056 sprintf (buf, "query %d %s", flags, text ? text : "");
1057 Write_String_To_Socket (ns, buf, strlen (buf)); 1057 ns->send_packet (buf);
1058} 1058}
1059 1059
1060#define AddIfInt64(Old,New,Type) if (Old != New) {\ 1060#define AddIfInt64(Old,New,Type) if (Old != New) {\
1061 Old = New; \ 1061 Old = New; \
1062 SockList_AddChar(&sl, Type); \ 1062 sl << uint8 (Type) << uint64 (New); \
1063 SockList_AddInt64(&sl, New); \
1064 } 1063 }
1065 1064
1066#define AddIfInt(Old,New,Type) if (Old != New) {\ 1065#define AddIfInt(Old,New,Type) if (Old != New) {\
1067 Old = New; \ 1066 Old = New; \
1068 SockList_AddChar(&sl, Type); \ 1067 sl << uint8 (Type) << uint32 (New); \
1069 SockList_AddInt(&sl, New); \
1070 } 1068 }
1071 1069
1072#define AddIfShort(Old,New,Type) if (Old != New) {\ 1070#define AddIfShort(Old,New,Type) if (Old != New) {\
1073 Old = New; \ 1071 Old = New; \
1074 SockList_AddChar(&sl, Type); \ 1072 sl << uint8 (Type) << uint16 (New); \
1075 SockList_AddShort(&sl, New); \
1076 } 1073 }
1077 1074
1078#define AddIfFloat(Old,New,Type) if (Old != New) {\ 1075#define AddIfFloat(Old,New,Type) if (Old != New) {\
1079 Old = New; \ 1076 Old = New; \
1080 SockList_AddChar(&sl, Type); \ 1077 sl << uint8 (Type) << uint32 (New*FLOAT_MULTI); \
1081 SockList_AddInt(&sl,(long)(New*FLOAT_MULTI));\
1082 } 1078 }
1083 1079
1084#define AddIfString(Old,New,Type) if (Old == NULL || strcmp(Old,New)) {\ 1080#define AddIfString(Old,New,Type) if (Old == NULL || strcmp(Old,New)) {\
1085 if (Old) free(Old);\
1086 Old = strdup_local(New);\ 1081 free(Old); Old = strdup (New);\
1087 SockList_AddChar(&sl, Type); \ 1082 sl << uint8 (Type) << data8 (New); \
1088 SockList_AddChar(&sl, ( char )strlen(New)); \
1089 strcpy((char*)sl.buf + sl.len, New); \
1090 sl.len += strlen(New); \
1091 } 1083 }
1092 1084
1093/** 1085/**
1094 * Sends a statistics update. We look at the old values, 1086 * Sends a statistics update. We look at the old values,
1095 * and only send what has changed. Stat mapping values are in newclient.h 1087 * and only send what has changed. Stat mapping values are in newclient.h
1097 * commands for now. 1089 * commands for now.
1098 */ 1090 */
1099void 1091void
1100esrv_update_stats (player *pl) 1092esrv_update_stats (player *pl)
1101{ 1093{
1102 SockList sl;
1103 char buf[MAX_BUF]; 1094 char buf[MAX_BUF];
1104 uint16 flags; 1095 uint16 flags;
1105 1096
1106 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 1097 packet sl;
1107 strcpy ((char *) sl.buf, "stats "); 1098 sl << "stats ";
1108 sl.len = strlen ((char *) sl.buf);
1109 1099
1110 if (pl->ob != NULL) 1100 if (pl->ob != NULL)
1111 { 1101 {
1112 AddIfShort (pl->last_stats.hp, pl->ob->stats.hp, CS_STAT_HP); 1102 AddIfShort (pl->last_stats.hp, pl->ob->stats.hp, CS_STAT_HP);
1113 AddIfShort (pl->last_stats.maxhp, pl->ob->stats.maxhp, CS_STAT_MAXHP); 1103 AddIfShort (pl->last_stats.maxhp, pl->ob->stats.maxhp, CS_STAT_MAXHP);
1121 AddIfShort (pl->last_stats.Wis, pl->ob->stats.Wis, CS_STAT_WIS); 1111 AddIfShort (pl->last_stats.Wis, pl->ob->stats.Wis, CS_STAT_WIS);
1122 AddIfShort (pl->last_stats.Dex, pl->ob->stats.Dex, CS_STAT_DEX); 1112 AddIfShort (pl->last_stats.Dex, pl->ob->stats.Dex, CS_STAT_DEX);
1123 AddIfShort (pl->last_stats.Con, pl->ob->stats.Con, CS_STAT_CON); 1113 AddIfShort (pl->last_stats.Con, pl->ob->stats.Con, CS_STAT_CON);
1124 AddIfShort (pl->last_stats.Cha, pl->ob->stats.Cha, CS_STAT_CHA); 1114 AddIfShort (pl->last_stats.Cha, pl->ob->stats.Cha, CS_STAT_CHA);
1125 } 1115 }
1116
1126 if (pl->socket.exp64) 1117 if (pl->socket.exp64)
1127 { 1118 {
1128 uint8 s; 1119 uint8 s;
1129 1120
1130 for (s = 0; s < NUM_SKILLS; s++) 1121 for (s = 0; s < NUM_SKILLS; s++)
1131 { 1122 {
1132 if (pl->last_skill_ob[s] && pl->last_skill_exp[s] != pl->last_skill_ob[s]->stats.exp) 1123 if (pl->last_skill_ob[s] && pl->last_skill_exp[s] != pl->last_skill_ob[s]->stats.exp)
1133 { 1124 {
1134
1135 /* Always send along the level if exp changes. This is only 1125 /* Always send along the level if exp changes. This is only
1136 * 1 extra byte, but keeps processing simpler. 1126 * 1 extra byte, but keeps processing simpler.
1137 */ 1127 */
1138 SockList_AddChar (&sl, (char) (s + CS_STAT_SKILLINFO)); 1128 sl << uint8 (s + CS_STAT_SKILLINFO)
1139 SockList_AddChar (&sl, (char) pl->last_skill_ob[s]->level); 1129 << uint8 (pl->last_skill_ob[s]->level)
1140 SockList_AddInt64 (&sl, pl->last_skill_ob[s]->stats.exp); 1130 << uint64 (pl->last_skill_ob[s]->stats.exp);
1131
1141 pl->last_skill_exp[s] = pl->last_skill_ob[s]->stats.exp; 1132 pl->last_skill_exp[s] = pl->last_skill_ob[s]->stats.exp;
1142 } 1133 }
1143 } 1134 }
1144 } 1135 }
1136
1145 if (pl->socket.exp64) 1137 if (pl->socket.exp64)
1146 {
1147 AddIfInt64 (pl->last_stats.exp, pl->ob->stats.exp, CS_STAT_EXP64); 1138 { AddIfInt64 (pl->last_stats.exp, pl->ob->stats.exp, CS_STAT_EXP64) }
1148 }
1149 else 1139 else
1150 {
1151 AddIfInt (pl->last_stats.exp, (int) pl->ob->stats.exp, CS_STAT_EXP); 1140 { AddIfInt (pl->last_stats.exp, (int) pl->ob->stats.exp, CS_STAT_EXP) }
1152 } 1141
1153 AddIfShort (pl->last_level, (char) pl->ob->level, CS_STAT_LEVEL); 1142 AddIfShort (pl->last_level, (char) pl->ob->level, CS_STAT_LEVEL);
1154 AddIfShort (pl->last_stats.wc, pl->ob->stats.wc, CS_STAT_WC); 1143 AddIfShort (pl->last_stats.wc, pl->ob->stats.wc, CS_STAT_WC);
1155 AddIfShort (pl->last_stats.ac, pl->ob->stats.ac, CS_STAT_AC); 1144 AddIfShort (pl->last_stats.ac, pl->ob->stats.ac, CS_STAT_AC);
1156 AddIfShort (pl->last_stats.dam, pl->ob->stats.dam, CS_STAT_DAM); 1145 AddIfShort (pl->last_stats.dam, pl->ob->stats.dam, CS_STAT_DAM);
1157 AddIfFloat (pl->last_speed, pl->ob->speed, CS_STAT_SPEED); 1146 AddIfFloat (pl->last_speed, pl->ob->speed, CS_STAT_SPEED);
1158 AddIfShort (pl->last_stats.food, pl->ob->stats.food, CS_STAT_FOOD); 1147 AddIfShort (pl->last_stats.food, pl->ob->stats.food, CS_STAT_FOOD);
1159 AddIfFloat (pl->last_weapon_sp, pl->weapon_sp, CS_STAT_WEAP_SP); 1148 AddIfFloat (pl->last_weapon_sp, pl->weapon_sp, CS_STAT_WEAP_SP);
1160 AddIfInt (pl->last_weight_limit, (sint32) weight_limit[pl->ob->stats.Str], CS_STAT_WEIGHT_LIM); 1149 AddIfInt (pl->last_weight_limit, (sint32) weight_limit[pl->ob->stats.Str], CS_STAT_WEIGHT_LIM);
1161 flags = 0; 1150 flags = 0;
1151
1162 if (pl->fire_on) 1152 if (pl->fire_on)
1163 flags |= SF_FIREON; 1153 flags |= SF_FIREON;
1154
1164 if (pl->run_on) 1155 if (pl->run_on)
1165 flags |= SF_RUNON; 1156 flags |= SF_RUNON;
1166 1157
1167 AddIfShort (pl->last_flags, flags, CS_STAT_FLAGS); 1158 AddIfShort (pl->last_flags, flags, CS_STAT_FLAGS);
1159
1168 if (pl->socket.sc_version < 1025) 1160 if (pl->socket.sc_version < 1025)
1169 {
1170 AddIfShort (pl->last_resist[ATNR_PHYSICAL], pl->ob->resist[ATNR_PHYSICAL], CS_STAT_ARMOUR); 1161 { AddIfShort (pl->last_resist[ATNR_PHYSICAL], pl->ob->resist[ATNR_PHYSICAL], CS_STAT_ARMOUR) }
1171 }
1172 else 1162 else
1173 { 1163 {
1174 int i; 1164 int i;
1175 1165
1176 for (i = 0; i < NROFATTACKS; i++) 1166 for (i = 0; i < NROFATTACKS; i++)
1177 { 1167 {
1178 /* Skip ones we won't send */ 1168 /* Skip ones we won't send */
1179 if (atnr_cs_stat[i] == -1) 1169 if (atnr_cs_stat[i] == -1)
1180 continue; 1170 continue;
1171
1181 AddIfShort (pl->last_resist[i], pl->ob->resist[i], (char) atnr_cs_stat[i]); 1172 AddIfShort (pl->last_resist[i], pl->ob->resist[i], (char) atnr_cs_stat[i]);
1182 } 1173 }
1183 } 1174 }
1175
1184 if (pl->socket.monitor_spells) 1176 if (pl->socket.monitor_spells)
1185 { 1177 {
1186 AddIfInt (pl->last_path_attuned, pl->ob->path_attuned, CS_STAT_SPELL_ATTUNE); 1178 AddIfInt (pl->last_path_attuned, pl->ob->path_attuned, CS_STAT_SPELL_ATTUNE);
1187 AddIfInt (pl->last_path_repelled, pl->ob->path_repelled, CS_STAT_SPELL_REPEL); 1179 AddIfInt (pl->last_path_repelled, pl->ob->path_repelled, CS_STAT_SPELL_REPEL);
1188 AddIfInt (pl->last_path_denied, pl->ob->path_denied, CS_STAT_SPELL_DENY); 1180 AddIfInt (pl->last_path_denied, pl->ob->path_denied, CS_STAT_SPELL_DENY);
1189 } 1181 }
1182
1190 rangetostring (pl->ob, buf); /* we want use the new fire & run system in new client */ 1183 rangetostring (pl->ob, buf); /* we want use the new fire & run system in new client */
1191 AddIfString (pl->socket.stats.range, buf, CS_STAT_RANGE); 1184 AddIfString (pl->socket.stats.range, buf, CS_STAT_RANGE);
1192 set_title (pl->ob, buf); 1185 set_title (pl->ob, buf);
1193 AddIfString (pl->socket.stats.title, buf, CS_STAT_TITLE); 1186 AddIfString (pl->socket.stats.title, buf, CS_STAT_TITLE);
1194 1187
1198#ifdef ESRV_DEBUG 1191#ifdef ESRV_DEBUG
1199 LOG (llevDebug, "Sending stats command, %d bytes long.\n", sl.len); 1192 LOG (llevDebug, "Sending stats command, %d bytes long.\n", sl.len);
1200#endif 1193#endif
1201 Send_With_Handling (&pl->socket, &sl); 1194 Send_With_Handling (&pl->socket, &sl);
1202 } 1195 }
1203 free (sl.buf);
1204}
1205 1196
1197}
1206 1198
1207/** 1199/**
1208 * Tells the client that here is a player it should start using. 1200 * Tells the client that here is a player it should start using.
1209 */ 1201 */
1210void 1202void
1211esrv_new_player (player *pl, uint32 weight) 1203esrv_new_player (player *pl, uint32 weight)
1212{ 1204{
1213 SockList sl;
1214
1215 pl->last_weight = weight; 1205 pl->last_weight = weight;
1216 1206
1217 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 1207 packet sl;
1208 sl << "player ";
1218 1209
1219 strcpy ((char *) sl.buf, "player "); 1210 sl << uint32 (pl->ob->count)
1220 sl.len = strlen ((char *) sl.buf); 1211 << uint32 (weight)
1221 SockList_AddInt (&sl, pl->ob->count); 1212 << uint32 (pl->ob->face->number)
1222 SockList_AddInt (&sl, weight); 1213 << data8 (pl->ob->name);
1223 SockList_AddInt (&sl, pl->ob->face->number);
1224
1225 SockList_AddChar (&sl, (char) strlen (pl->ob->name));
1226 strcpy ((char *) sl.buf + sl.len, pl->ob->name);
1227 sl.len += strlen (pl->ob->name);
1228 1214
1229 Send_With_Handling (&pl->socket, &sl); 1215 Send_With_Handling (&pl->socket, &sl);
1230 free (sl.buf);
1231 SET_FLAG (pl->ob, FLAG_CLIENT_SENT); 1216 SET_FLAG (pl->ob, FLAG_CLIENT_SENT);
1232} 1217}
1233
1234 1218
1235/** 1219/**
1236 * Need to send an animation sequence to the client. 1220 * Need to send an animation sequence to the client.
1237 * We will send appropriate face commands to the client if we haven't 1221 * We will send appropriate face commands to the client if we haven't
1238 * sent them the face yet (this can become quite costly in terms of 1222 * sent them the face yet (this can become quite costly in terms of
1240 * when the player logs in and picks stuff up. 1224 * when the player logs in and picks stuff up.
1241 */ 1225 */
1242void 1226void
1243esrv_send_animation (NewSocket * ns, short anim_num) 1227esrv_send_animation (NewSocket * ns, short anim_num)
1244{ 1228{
1245 SockList sl;
1246 int i; 1229 int i;
1247 1230
1248 /* Do some checking on the anim_num we got. Note that the animations 1231 /* Do some checking on the anim_num we got. Note that the animations
1249 * are added in contigous order, so if the number is in the valid 1232 * are added in contigous order, so if the number is in the valid
1250 * range, it must be a valid animation. 1233 * range, it must be a valid animation.
1253 { 1236 {
1254 LOG (llevError, "esrv_send_anim (%d) out of bounds??\n", anim_num); 1237 LOG (llevError, "esrv_send_anim (%d) out of bounds??\n", anim_num);
1255 return; 1238 return;
1256 } 1239 }
1257 1240
1258 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 1241 packet sl;
1259 strcpy ((char *) sl.buf, "anim "); 1242
1260 sl.len = 5; 1243 sl << "anim "
1261 SockList_AddShort (&sl, anim_num); 1244 << uint16 (anim_num)
1262 SockList_AddShort (&sl, 0); /* flags - not used right now */ 1245 << uint16 (0); /* flags - not used right now */
1246
1263 /* Build up the list of faces. Also, send any information (ie, the 1247 /* Build up the list of faces. Also, send any information (ie, the
1264 * the face itself) down to the client. 1248 * the face itself) down to the client.
1265 */ 1249 */
1266 for (i = 0; i < animations[anim_num].num_animations; i++) 1250 for (i = 0; i < animations[anim_num].num_animations; i++)
1267 { 1251 {
1268 if (!(ns->faces_sent[animations[anim_num].faces[i]] & NS_FACESENT_FACE)) 1252 if (!(ns->faces_sent[animations[anim_num].faces[i]] & NS_FACESENT_FACE))
1269 esrv_send_face (ns, animations[anim_num].faces[i], 0); 1253 esrv_send_face (ns, animations[anim_num].faces[i], 0);
1270 SockList_AddShort (&sl, animations[anim_num].faces[i]); /* flags - not used right now */ 1254 sl << uint16 (animations[anim_num].faces[i]); /* flags - not used right now */
1271 } 1255 }
1256
1272 Send_With_Handling (ns, &sl); 1257 Send_With_Handling (ns, &sl);
1273 free (sl.buf); 1258
1274 ns->anims_sent[anim_num] = 1; 1259 ns->anims_sent[anim_num] = 1;
1275} 1260}
1276 1261
1277 1262
1278/****************************************************************************** 1263/******************************************************************************
1292 { 1277 {
1293 LOG (llevError, "Too many faces in map cell %d %d\n", x, y); 1278 LOG (llevError, "Too many faces in map cell %d %d\n", x, y);
1294 return; 1279 return;
1295 abort (); 1280 abort ();
1296 } 1281 }
1282
1297 newmap->cells[x][y].faces[newmap->cells[x][y].count] = face_num; 1283 newmap->cells[x][y].faces[newmap->cells[x][y].count] = face_num;
1298 newmap->cells[x][y].count++; 1284 newmap->cells[x][y].count++;
1285
1299 if (!(ns->faces_sent[face_num] & NS_FACESENT_FACE)) 1286 if (!(ns->faces_sent[face_num] & NS_FACESENT_FACE))
1300 esrv_send_face (ns, face_num, 0); 1287 esrv_send_face (ns, face_num, 0);
1301} 1288}
1302 1289
1303struct LayerCell 1290struct LayerCell
1410static void 1397static void
1411esrv_map_doneredraw (NewSocket * ns, struct Map *newmap) 1398esrv_map_doneredraw (NewSocket * ns, struct Map *newmap)
1412{ 1399{
1413 static long frames, bytes, tbytes, tframes; 1400 static long frames, bytes, tbytes, tframes;
1414 char *cur; 1401 char *cur;
1415 SockList sl;
1416 1402
1417 1403 packet sl;
1418 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 1404 sl << "map ";
1419 strcpy ((char *) sl.buf, "map ");
1420 sl.len = strlen ((char *) sl.buf);
1421 1405
1422 cur = (char *) compactlayer (ns, (unsigned char *) sl.buf + sl.len, MAP_LAYERS, newmap); 1406 cur = (char *) compactlayer (ns, (unsigned char *) sl.buf + sl.len, MAP_LAYERS, newmap);
1423 sl.len = cur - (char *) sl.buf; 1407 sl.len = cur - (char *) sl.buf;
1424 1408
1425/* LOG(llevDebug, "Sending map command.\n");*/ 1409/* LOG(llevDebug, "Sending map command.\n");*/
1426 1410
1427 if (sl.len > (int) strlen ("map ") || ns->sent_scroll) 1411 if (sl.len > (int) strlen ("map ") || ns->sent_scroll)
1428 { 1412 {
1429 /* All of this is just accounting stuff */ 1413 /* All of this is just accounting stuff */
1430 if (tframes > 100) 1414 if (tframes > 100)
1431 {
1432 tframes = tbytes = 0; 1415 tframes = tbytes = 0;
1433 } 1416
1434 tframes++; 1417 tframes++;
1435 frames++; 1418 frames++;
1436 tbytes += sl.len; 1419 tbytes += sl.len;
1437 bytes += sl.len; 1420 bytes += sl.len;
1438 memcpy (&ns->lastmap, newmap, sizeof (struct Map)); 1421 memcpy (&ns->lastmap, newmap, sizeof (struct Map));
1439 Send_With_Handling (ns, &sl); 1422 Send_With_Handling (ns, &sl);
1440 ns->sent_scroll = 0; 1423 ns->sent_scroll = 0;
1441 } 1424 }
1442 free (sl.buf); 1425
1443} 1426}
1444 1427
1445 1428
1446/** Clears a map cell */ 1429/** Clears a map cell */
1447static void 1430static void
1448map_clearcell (struct MapCell *cell, int face0, int face1, int face2, int count) 1431map_clearcell (struct MapCell *cell, int face0, int face1, int face2, int count)
1449{ 1432{
1450 cell->faces[0] = face0; 1433 cell->faces[0] = face0;
1451 cell->faces[1] = face1; 1434 cell->faces[1] = face1;
1452 cell->faces[2] = face2; 1435 cell->faces[2] = face2;
1453 cell->count = count; 1436 cell->count = count;
1454 cell->stat_hp = 0; 1437 cell->stat_hp = 0;
1438 cell->flags = 0;
1455 cell->player = 0; 1439 cell->player = 0;
1456} 1440}
1457 1441
1458#define MAX_HEAD_POS MAX(MAX_CLIENT_X, MAX_CLIENT_Y) 1442#define MAX_HEAD_POS MAX(MAX_CLIENT_X, MAX_CLIENT_Y)
1459#define MAX_LAYERS 3 1443#define MAX_LAYERS 3
1460 1444
1488 * needs to get sent - if so, it adds the data, sending the head 1472 * needs to get sent - if so, it adds the data, sending the head
1489 * if needed, and returning 1. If this no data needs to get 1473 * if needed, and returning 1. If this no data needs to get
1490 * sent, it returns zero. 1474 * sent, it returns zero.
1491 */ 1475 */
1492static int 1476static int
1493check_head (SockList & sl, NewSocket & ns, int ax, int ay, int layer) 1477check_head (packet &sl, NewSocket &ns, int ax, int ay, int layer)
1494{ 1478{
1495 short face_num; 1479 short face_num;
1496 1480
1497 if (heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer]) 1481 if (heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer])
1498 face_num = heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer]->face->number; 1482 face_num = heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer]->face->number;
1499 else 1483 else
1500 face_num = 0; 1484 face_num = 0;
1501 1485
1502 if (face_num != ns.lastmap.cells[ax][ay].faces[layer]) 1486 if (face_num != ns.lastmap.cells[ax][ay].faces[layer])
1503 { 1487 {
1504 SockList_AddShort (&sl, face_num); 1488 sl << uint16 (face_num);
1505 if (face_num && !(ns.faces_sent[face_num] & NS_FACESENT_FACE)) 1489 if (face_num && !(ns.faces_sent[face_num] & NS_FACESENT_FACE))
1506 esrv_send_face (&ns, face_num, 0); 1490 esrv_send_face (&ns, face_num, 0);
1491
1507 heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer] = NULL; 1492 heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer] = NULL;
1508 ns.lastmap.cells[ax][ay].faces[layer] = face_num; 1493 ns.lastmap.cells[ax][ay].faces[layer] = face_num;
1509 return 1; 1494 return 1;
1510 } 1495 }
1511 1496
1531 * the case, it seems to make more sense to have these layer values 1516 * the case, it seems to make more sense to have these layer values
1532 * actually match. 1517 * actually match.
1533 */ 1518 */
1534 1519
1535static int 1520static int
1536update_space (SockList * sl, NewSocket * ns, mapstruct *mp, int mx, int my, int sx, int sy, int layer) 1521update_space (packet &sl, NewSocket &ns, maptile *mp, int mx, int my, int sx, int sy, int layer)
1537{ 1522{
1538 object *ob, *head; 1523 object *ob, *head;
1539 uint16 face_num; 1524 uint16 face_num;
1540 int bx, by, i; 1525 int bx, by, i;
1541 1526
1542 /* If there is a multipart object stored away, treat that as more important. 1527 /* If there is a multipart object stored away, treat that as more important.
1543 * If not, then do the normal processing. 1528 * If not, then do the normal processing.
1544 */ 1529 */
1545
1546 head = heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer]; 1530 head = heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer];
1547 1531
1548 /* Check to see if this head is part of the set of objects 1532 /* Check to see if this head is part of the set of objects
1549 * we would normally send for this space. If so, then 1533 * we would normally send for this space. If so, then
1550 * don't use the head value. We need to do the check 1534 * don't use the head value. We need to do the check
1715 1699
1716 /* Another hack - because of heads and whatnot, this face may match one 1700 /* Another hack - because of heads and whatnot, this face may match one
1717 * we already sent for a lower layer. In that case, don't send 1701 * we already sent for a lower layer. In that case, don't send
1718 * this one. 1702 * this one.
1719 */ 1703 */
1720 if (face_num && layer + 1 < MAP_LAYERS && ns->lastmap.cells[sx][sy].faces[layer + 1] == face_num) 1704 if (face_num && layer + 1 < MAP_LAYERS && ns.lastmap.cells[sx][sy].faces[layer + 1] == face_num)
1721 {
1722 face_num = 0; 1705 face_num = 0;
1723 }
1724 1706
1725 /* We've gotten what face we want to use for the object. Now see if 1707 /* We've gotten what face we want to use for the object. Now see if
1726 * if it has changed since we last sent it to the client. 1708 * if it has changed since we last sent it to the client.
1727 */ 1709 */
1728 if (ns->lastmap.cells[sx][sy].faces[layer] != face_num) 1710 if (ns.lastmap.cells[sx][sy].faces[layer] != face_num)
1729 { 1711 {
1730 ns->lastmap.cells[sx][sy].faces[layer] = face_num; 1712 ns.lastmap.cells[sx][sy].faces[layer] = face_num;
1731 if (!(ns->faces_sent[face_num] & NS_FACESENT_FACE)) 1713 if (!(ns.faces_sent[face_num] & NS_FACESENT_FACE))
1732 esrv_send_face (ns, face_num, 0); 1714 esrv_send_face (&ns, face_num, 0);
1733 SockList_AddShort (sl, face_num); 1715
1716 sl << uint16 (face_num);
1734 return 1; 1717 return 1;
1735 } 1718 }
1719
1736 /* Nothing changed */ 1720 /* Nothing changed */
1737 return 0; 1721 return 0;
1738} 1722}
1739 1723
1740/** 1724/**
1755 * top layer (this matches what the GET_MAP_FACE and GET_MAP_FACE_OBJ 1739 * top layer (this matches what the GET_MAP_FACE and GET_MAP_FACE_OBJ
1756 * take. 1740 * take.
1757 */ 1741 */
1758 1742
1759static inline int 1743static inline int
1760update_smooth (SockList * sl, NewSocket * ns, mapstruct *mp, int mx, int my, int sx, int sy, int layer) 1744update_smooth (packet &sl, NewSocket &ns, maptile *mp, int mx, int my, int sx, int sy, int layer)
1761{ 1745{
1762 object *ob; 1746 object *ob;
1763 int smoothlevel; /* old face_num; */ 1747 int smoothlevel; /* old face_num; */
1764 1748
1765 ob = GET_MAP_FACE_OBJ (mp, mx, my, layer); 1749 ob = GET_MAP_FACE_OBJ (mp, mx, my, layer);
1770 if (!ob || ob->face == blank_face || MAP_NOSMOOTH (mp)) 1754 if (!ob || ob->face == blank_face || MAP_NOSMOOTH (mp))
1771 smoothlevel = 0; 1755 smoothlevel = 0;
1772 else 1756 else
1773 { 1757 {
1774 smoothlevel = ob->smoothlevel; 1758 smoothlevel = ob->smoothlevel;
1775 if (smoothlevel && !(ns->faces_sent[ob->face->number] & NS_FACESENT_SMOOTH)) 1759 if (smoothlevel && !(ns.faces_sent[ob->face->number] & NS_FACESENT_SMOOTH))
1776 SendSmooth (ns, ob->face->number); 1760 SendSmooth (&ns, ob->face->number);
1777 } /* else not already head object or blank face */ 1761 } /* else not already head object or blank face */
1778 1762
1779 /* We've gotten what face we want to use for the object. Now see if 1763 /* We've gotten what face we want to use for the object. Now see if
1780 * if it has changed since we last sent it to the client. 1764 * if it has changed since we last sent it to the client.
1781 */ 1765 */
1782 if (smoothlevel > 255) 1766 if (smoothlevel > 255)
1783 smoothlevel = 255; 1767 smoothlevel = 255;
1784 else if (smoothlevel < 0) 1768 else if (smoothlevel < 0)
1785 smoothlevel = 0; 1769 smoothlevel = 0;
1770
1786 if (ns->lastmap.cells[sx][sy].smooth[layer] != smoothlevel) 1771 if (ns.lastmap.cells[sx][sy].smooth[layer] != smoothlevel)
1787 { 1772 {
1788 ns->lastmap.cells[sx][sy].smooth[layer] = smoothlevel; 1773 ns.lastmap.cells[sx][sy].smooth[layer] = smoothlevel;
1789 SockList_AddChar (sl, (uint8) (smoothlevel & 0xFF)); 1774 sl << uint8 (smoothlevel);
1790 return 1; 1775 return 1;
1791 } 1776 }
1777
1792 /* Nothing changed */ 1778 /* Nothing changed */
1793 return 0; 1779 return 0;
1794} 1780}
1795 1781
1796/** 1782/**
1837draw_client_map1 (object *pl) 1823draw_client_map1 (object *pl)
1838{ 1824{
1839 int x, y, ax, ay, d, startlen, max_x, max_y, oldlen; 1825 int x, y, ax, ay, d, startlen, max_x, max_y, oldlen;
1840 sint16 nx, ny; 1826 sint16 nx, ny;
1841 int estartlen, eoldlen; 1827 int estartlen, eoldlen;
1842 SockList sl;
1843 SockList esl; /*For extended Map info */
1844 uint16 mask, emask; 1828 uint16 mask, emask;
1845 uint8 eentrysize; 1829 uint8 eentrysize;
1846 uint16 ewhatstart, ewhatflag; 1830 uint16 ewhatstart, ewhatflag;
1847 uint8 extendedinfos; 1831 uint8 extendedinfos;
1848 mapstruct *m; 1832 maptile *m;
1849 1833
1850 NewSocket & socket = pl->contr->socket; 1834 NewSocket &socket = pl->contr->socket;
1851 1835
1852 check_map_change (pl->contr); 1836 check_map_change (pl->contr);
1853 1837
1854 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 1838 packet sl;
1855 if (socket.mapmode == Map1Cmd) 1839 packet esl;
1856 strcpy ((char *) sl.buf, "map1 "); 1840
1857 else 1841 sl << (socket.mapmode == Map1Cmd ? "map1 " : "map1a ");
1858 strcpy ((char *) sl.buf, "map1a ");
1859 sl.len = strlen ((char *) sl.buf);
1860 startlen = sl.len; 1842 startlen = sl.len;
1843
1861 /*Extendedmapinfo structure initialisation */ 1844 /*Extendedmapinfo structure initialisation */
1862 if (socket.ext_mapinfos) 1845 if (socket.ext_mapinfos)
1863 { 1846 {
1864 esl.buf = (unsigned char *) malloc (MAXSOCKBUF);
1865 strcpy ((char *) esl.buf, "mapextended ");
1866 esl.len = strlen ((char *) esl.buf);
1867 extendedinfos = EMI_NOREDRAW; 1847 extendedinfos = EMI_NOREDRAW;
1848
1868 if (socket.EMI_smooth) 1849 if (socket.EMI_smooth)
1869 extendedinfos |= EMI_SMOOTH; 1850 extendedinfos |= EMI_SMOOTH;
1851
1870 ewhatstart = esl.len; 1852 ewhatstart = esl.len;
1871 ewhatflag = extendedinfos; /*The EMI_NOREDRAW bit 1853 ewhatflag = extendedinfos; /*The EMI_NOREDRAW bit
1872 could need to be taken away */ 1854 could need to be taken away */
1873 SockList_AddChar (&esl, extendedinfos);
1874 eentrysize = getExtendedMapInfoSize (&socket); 1855 eentrysize = getExtendedMapInfoSize (&socket);
1875 SockList_AddChar (&esl, eentrysize); 1856 esl << "mapextended "
1857 << uint8 (extendedinfos)
1858 << uint8 (eentrysize);
1876 estartlen = esl.len; 1859 estartlen = esl.len;
1877 } 1860 }
1878 else 1861 else
1879 { 1862 {
1880 /* suppress compiler warnings */ 1863 /* suppress compiler warnings */
1881 ewhatstart = 0; 1864 ewhatstart = 0;
1882 ewhatflag = 0; 1865 ewhatflag = 0;
1883 estartlen = 0; 1866 estartlen = 0;
1884 } 1867 }
1868
1885 /* Init data to zero */ 1869 /* Init data to zero */
1886 memset (heads, 0, sizeof (object *) * MAX_HEAD_POS * MAX_HEAD_POS * MAX_LAYERS); 1870 memset (heads, 0, sizeof (object *) * MAX_HEAD_POS * MAX_HEAD_POS * MAX_LAYERS);
1887 1871
1888 /* x,y are the real map locations. ax, ay are viewport relative 1872 /* x,y are the real map locations. ax, ay are viewport relative
1889 * locations. 1873 * locations.
1893 /* We could do this logic as conditionals in the if statement, 1877 /* We could do this logic as conditionals in the if statement,
1894 * but that started to get a bit messy to look at. 1878 * but that started to get a bit messy to look at.
1895 */ 1879 */
1896 max_x = pl->x + (socket.mapx + 1) / 2; 1880 max_x = pl->x + (socket.mapx + 1) / 2;
1897 max_y = pl->y + (socket.mapy + 1) / 2; 1881 max_y = pl->y + (socket.mapy + 1) / 2;
1882
1898 if (socket.mapmode == Map1aCmd) 1883 if (socket.mapmode == Map1aCmd)
1899 { 1884 {
1900 max_x += MAX_HEAD_OFFSET; 1885 max_x += MAX_HEAD_OFFSET;
1901 max_y += MAX_HEAD_OFFSET; 1886 max_y += MAX_HEAD_OFFSET;
1902 } 1887 }
1919 { 1904 {
1920 int i, got_one; 1905 int i, got_one;
1921 1906
1922 oldlen = sl.len; 1907 oldlen = sl.len;
1923 1908
1924 SockList_AddShort (&sl, mask); 1909 sl << uint16 (mask);
1925 1910
1926 if (check_head (sl, socket, ax, ay, 2)) 1911 if (check_head (sl, socket, ax, ay, 2)) mask |= 0x4;
1927 mask |= 0x4;
1928 if (check_head (sl, socket, ax, ay, 1)) 1912 if (check_head (sl, socket, ax, ay, 1)) mask |= 0x2;
1929 mask |= 0x2;
1930 if (check_head (sl, socket, ax, ay, 0)) 1913 if (check_head (sl, socket, ax, ay, 0)) mask |= 0x1;
1931 mask |= 0x1;
1932 1914
1933 /* If all we are doing is sending 0 (blank) faces, we don't 1915 /* If all we are doing is sending 0 (blank) faces, we don't
1934 * actually need to send that - just the coordinates 1916 * actually need to send that - just the coordinates
1935 * with no faces tells the client to blank out the 1917 * with no faces tells the client to blank out the
1936 * space. 1918 * space.
1937 */ 1919 */
1938 got_one = 0; 1920 got_one = 0;
1939 for (i = oldlen + 2; i < sl.len; i++) 1921 for (i = oldlen + 2; i < sl.len; i++)
1940 {
1941 if (sl.buf[i]) 1922 if (sl.buf[i])
1942 got_one = 1; 1923 got_one = 1;
1943 }
1944 1924
1945 if (got_one && (mask & 0xf)) 1925 if (got_one && (mask & 0xf))
1946 {
1947 sl.buf[oldlen + 1] = mask & 0xff; 1926 sl.buf[oldlen + 1] = mask & 0xff;
1948 }
1949 else 1927 else
1950 { /*either all faces blank, either no face at all */ 1928 { /*either all faces blank, either no face at all */
1951 if (mask & 0xf) /*at least 1 face, we know it's blank, only send coordinates */ 1929 if (mask & 0xf) /*at least 1 face, we know it's blank, only send coordinates */
1952 sl.len = oldlen + 2; 1930 sl.len = oldlen + 2;
1953 else 1931 else
1954 sl.len = oldlen; 1932 sl.len = oldlen;
1955 } 1933 }
1934
1956 /*What concerns extendinfos, nothing to be done for now 1935 /*What concerns extendinfos, nothing to be done for now
1957 * (perhaps effects layer later) 1936 * (perhaps effects layer later)
1958 */ 1937 */
1959 continue; /* don't do processing below */ 1938 continue; /* don't do processing below */
1960 } 1939 }
1961 1940
1962 MapCell & lastcell = socket.lastmap.cells[ax][ay]; 1941 MapCell &lastcell = socket.lastmap.cells[ax][ay];
1963 1942
1964 d = pl->contr->blocked_los[ax][ay]; 1943 d = pl->contr->blocked_los[ax][ay];
1965 1944
1966 /* If the coordinates are not valid, or it is too dark to see, 1945 /* If the coordinates are not valid, or it is too dark to see,
1967 * we tell the client as such 1946 * we tell the client as such
1968 */ 1947 */
1969 nx = x; 1948 nx = x;
1970 ny = y; 1949 ny = y;
1971 m = get_map_from_coord (pl->map, &nx, &ny); 1950 m = get_map_from_coord (pl->map, &nx, &ny);
1951
1972 if (!m) 1952 if (!m)
1973 { 1953 {
1974 /* space is out of map. Update space and clear values 1954 /* space is out of map. Update space and clear values
1975 * if this hasn't already been done. If the space is out 1955 * if this hasn't already been done. If the space is out
1976 * of the map, it shouldn't have a head 1956 * of the map, it shouldn't have a head
1977 */ 1957 */
1978 if (lastcell.count != -1) 1958 if (lastcell.count != -1)
1979 { 1959 {
1980 SockList_AddShort (&sl, mask); 1960 sl << uint16 (mask);
1981 map_clearcell (&lastcell, 0, 0, 0, -1); 1961 map_clearcell (&lastcell, 0, 0, 0, -1);
1982 } 1962 }
1983 } 1963 }
1984 else if (d > 3) 1964 else if (d > 3)
1985 { 1965 {
1989 * reason. Still may need to send the head for this space. 1969 * reason. Still may need to send the head for this space.
1990 */ 1970 */
1991 1971
1992 oldlen = sl.len; 1972 oldlen = sl.len;
1993 1973
1994 SockList_AddShort (&sl, mask); 1974 sl << uint16 (mask);
1975
1995 if (lastcell.count != -1) 1976 if (lastcell.count != -1)
1996 need_send = 1; 1977 need_send = 1;
1978
1997 count = -1; 1979 count = -1;
1998 1980
1999 if (socket.mapmode == Map1aCmd && have_head (ax, ay)) 1981 if (socket.mapmode == Map1aCmd && have_head (ax, ay))
2000 { 1982 {
2001 /* Now check to see if any heads need to be sent */ 1983 /* Now check to see if any heads need to be sent */
2002 1984
2003 if (check_head (sl, socket, ax, ay, 2)) 1985 if (check_head (sl, socket, ax, ay, 2)) mask |= 0x4;
2004 mask |= 0x4;
2005 if (check_head (sl, socket, ax, ay, 1)) 1986 if (check_head (sl, socket, ax, ay, 1)) mask |= 0x2;
2006 mask |= 0x2;
2007 if (check_head (sl, socket, ax, ay, 0)) 1987 if (check_head (sl, socket, ax, ay, 0)) mask |= 0x1;
2008 mask |= 0x1;
2009 1988
2010 lastcell.count = count; 1989 lastcell.count = count;
2011
2012 } 1990 }
2013 else 1991 else
2014 { 1992 {
2015 struct MapCell *cell = &lastcell;
2016
2017 /* properly clear a previously sent big face */ 1993 /* properly clear a previously sent big face */
2018 if (cell->faces[0] != 0 || cell->faces[1] != 0 || cell->faces[2] != 0) 1994 if (lastcell.faces[0] != 0 || lastcell.faces[1] != 0 || lastcell.faces[2] != 0
1995 || lastcell.stat_hp || lastcell.flags || lastcell.player)
2019 need_send = 1; 1996 need_send = 1;
1997
2020 map_clearcell (&lastcell, 0, 0, 0, count); 1998 map_clearcell (&lastcell, 0, 0, 0, count);
2021 } 1999 }
2022 2000
2023 if ((mask & 0xf) || need_send) 2001 if ((mask & 0xf) || need_send)
2024 {
2025 sl.buf[oldlen + 1] = mask & 0xff; 2002 sl.buf[oldlen + 1] = mask & 0xff;
2026 }
2027 else 2003 else
2028 {
2029 sl.len = oldlen; 2004 sl.len = oldlen;
2030 }
2031 } 2005 }
2032 else 2006 else
2033 { 2007 {
2034 /* In this block, the space is visible or there are head objects 2008 /* In this block, the space is visible or there are head objects
2035 * we need to send. 2009 * we need to send.
2047 */ 2021 */
2048 oldlen = sl.len; 2022 oldlen = sl.len;
2049 mask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4; 2023 mask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4;
2050 eoldlen = esl.len; 2024 eoldlen = esl.len;
2051 emask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4; 2025 emask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4;
2052 SockList_AddShort (&sl, mask); 2026 sl << uint16 (mask);
2053 2027
2054 if (socket.ext_mapinfos) 2028 if (socket.ext_mapinfos)
2055 SockList_AddShort (&esl, emask); 2029 esl << uint16 (emask);
2056 2030
2057 unsigned char dummy; 2031 unsigned char dummy;
2058 unsigned char *last_ext = &dummy; 2032 unsigned char *last_ext = &dummy;
2059 2033
2060 /* Darkness changed */ 2034 /* Darkness changed */
2064 2038
2065 if (socket.extmap) 2039 if (socket.extmap)
2066 { 2040 {
2067 *last_ext |= 0x80; 2041 *last_ext |= 0x80;
2068 last_ext = sl.buf + sl.len; 2042 last_ext = sl.buf + sl.len;
2069 SockList_AddChar (&sl, d); 2043 sl << uint8 (d);
2070 } 2044 }
2071 else 2045 else
2072 SockList_AddChar (&sl, 255 - 64 * d); 2046 sl << uint8 (255 - 64 * d);
2073 } 2047 }
2074 2048
2075 lastcell.count = d; 2049 lastcell.count = d;
2076 2050
2077 if (socket.extmap) 2051 if (socket.extmap)
2078 { 2052 {
2079 uint8 stat_hp = 0; 2053 uint8 stat_hp = 0;
2080 uint8 stat_width = 0; 2054 uint8 stat_width = 0;
2055 uint8 flags = 0;
2081 tag_t player = 0; 2056 UUID player = 0;
2082 2057
2083 // send hp information, if applicable 2058 // send hp information, if applicable
2084 if (object *op = GET_MAP_FACE_OBJ (m, nx, ny, 0)) 2059 if (object *op = GET_MAP_FACE_OBJ (m, nx, ny, 0))
2085 { 2060 {
2086 if (op->head || op->invisible) 2061 if (op->head || op->invisible)
2093 stat_hp = 255 - (op->stats.hp * 255 + 254) / op->stats.maxhp; 2068 stat_hp = 255 - (op->stats.hp * 255 + 254) / op->stats.maxhp;
2094 stat_width = op->arch->tail_x; 2069 stat_width = op->arch->tail_x;
2095 } 2070 }
2096 } 2071 }
2097 2072
2073 if (op->msg && op->msg[0] == '@')
2074 flags |= 1;
2075
2098 if (op->type == PLAYER && op != pl) 2076 if (op->type == PLAYER && op != pl)
2099 player = op->count; 2077 player = op->count;
2100 } 2078 }
2101 2079
2102 if (lastcell.stat_hp != stat_hp) 2080 if (lastcell.stat_hp != stat_hp)
2104 lastcell.stat_hp = stat_hp; 2082 lastcell.stat_hp = stat_hp;
2105 2083
2106 mask |= 0x8; 2084 mask |= 0x8;
2107 *last_ext |= 0x80; 2085 *last_ext |= 0x80;
2108 last_ext = sl.buf + sl.len; 2086 last_ext = sl.buf + sl.len;
2109 SockList_AddChar (&sl, 5); 2087
2110 SockList_AddChar (&sl, stat_hp); 2088 sl << uint8 (5) << uint8 (stat_hp);
2111 2089
2112 if (stat_width > 1) 2090 if (stat_width > 1)
2113 { 2091 {
2114 *last_ext |= 0x80; 2092 *last_ext |= 0x80;
2115 last_ext = sl.buf + sl.len; 2093 last_ext = sl.buf + sl.len;
2116 SockList_AddChar (&sl, 6); 2094
2117 SockList_AddChar (&sl, stat_width); 2095 sl << uint8 (6) << uint8 (stat_width);
2118 } 2096 }
2119 } 2097 }
2120 2098
2121 if (lastcell.player !=player) 2099 if (lastcell.player != player)
2122 { 2100 {
2123 lastcell.player = player; 2101 lastcell.player = player;
2124 2102
2125 mask |= 0x8; 2103 mask |= 0x8;
2126 *last_ext |= 0x80; 2104 *last_ext |= 0x80;
2127 last_ext = sl.buf + sl.len; 2105 last_ext = sl.buf + sl.len;
2128 SockList_AddChar (&sl, 0x47); 2106
2129 SockList_AddChar (&sl, 4); 2107 sl << uint8 (0x47) << uint8 (8) << (uint64)player;
2130 SockList_AddInt (&sl, player); 2108 }
2109
2110 if (lastcell.flags != flags)
2111 {
2112 lastcell.flags = flags;
2113
2114 mask |= 0x8;
2115 *last_ext |= 0x80;
2116 last_ext = sl.buf + sl.len;
2117
2118 sl << uint8 (8) << uint8 (flags);
2131 } 2119 }
2132 } 2120 }
2133 2121
2134 /* Floor face */ 2122 /* Floor face */
2135 if (update_space (&sl, &socket, m, nx, ny, ax, ay, 2)) 2123 if (update_space (sl, socket, m, nx, ny, ax, ay, 2))
2136 mask |= 0x4; 2124 mask |= 0x4;
2137 2125
2138 if (socket.EMI_smooth) 2126 if (socket.EMI_smooth)
2139 if (update_smooth (&esl, &socket, m, nx, ny, ax, ay, 2)) 2127 if (update_smooth (esl, socket, m, nx, ny, ax, ay, 2))
2140 emask |= 0x4; 2128 emask |= 0x4;
2141 2129
2142 /* Middle face */ 2130 /* Middle face */
2143 if (update_space (&sl, &socket, m, nx, ny, ax, ay, 1)) 2131 if (update_space (sl, socket, m, nx, ny, ax, ay, 1))
2144 mask |= 0x2; 2132 mask |= 0x2;
2145 2133
2146 if (socket.EMI_smooth) 2134 if (socket.EMI_smooth)
2147 if (update_smooth (&esl, &socket, m, nx, ny, ax, ay, 1)) 2135 if (update_smooth (esl, socket, m, nx, ny, ax, ay, 1))
2148 emask |= 0x2; 2136 emask |= 0x2;
2149 2137
2150 if (nx == pl->x && ny == pl->y && pl->invisible & (pl->invisible < 50 ? 4 : 1)) 2138 if (nx == pl->x && ny == pl->y && pl->invisible & (pl->invisible < 50 ? 4 : 1))
2151 { 2139 {
2152 if (lastcell.faces[0] != pl->face->number) 2140 if (lastcell.faces[0] != pl->face->number)
2153 { 2141 {
2154 lastcell.faces[0] = pl->face->number; 2142 lastcell.faces[0] = pl->face->number;
2155 mask |= 0x1; 2143 mask |= 0x1;
2144
2156 if (!(socket.faces_sent[pl->face->number] & NS_FACESENT_FACE)) 2145 if (!(socket.faces_sent[pl->face->number] & NS_FACESENT_FACE))
2157 esrv_send_face (&socket, pl->face->number, 0); 2146 esrv_send_face (&socket, pl->face->number, 0);
2158 SockList_AddShort (&sl, pl->face->number); 2147
2148 sl << uint16 (pl->face->number);
2159 } 2149 }
2160 } 2150 }
2161 /* Top face */
2162 else 2151 else
2163 { 2152 {
2153 /* Top face */
2164 if (update_space (&sl, &socket, m, nx, ny, ax, ay, 0)) 2154 if (update_space (sl, socket, m, nx, ny, ax, ay, 0))
2165 mask |= 0x1; 2155 mask |= 0x1;
2156
2166 if (socket.EMI_smooth) 2157 if (socket.EMI_smooth)
2167 if (update_smooth (&esl, &socket, m, nx, ny, ax, ay, 0)) 2158 if (update_smooth (esl, socket, m, nx, ny, ax, ay, 0))
2168 {
2169 emask |= 0x1; 2159 emask |= 0x1;
2170 }
2171 } 2160 }
2161
2172 /* Check to see if we are in fact sending anything for this 2162 /* Check to see if we are in fact sending anything for this
2173 * space by checking the mask. If so, update the mask. 2163 * space by checking the mask. If so, update the mask.
2174 * if not, reset the len to that from before adding the mask 2164 * if not, reset the len to that from before adding the mask
2175 * value, so we don't send those bits. 2165 * value, so we don't send those bits.
2176 */ 2166 */
2177 if (mask & 0xf) 2167 if (mask & 0xf)
2178 {
2179 sl.buf[oldlen + 1] = mask & 0xff; 2168 sl.buf[oldlen + 1] = mask & 0xff;
2180 }
2181 else 2169 else
2182 {
2183 sl.len = oldlen; 2170 sl.len = oldlen;
2184 } 2171
2185 if (emask & 0xf) 2172 if (emask & 0xf)
2186 {
2187 esl.buf[eoldlen + 1] = emask & 0xff; 2173 esl.buf[eoldlen + 1] = emask & 0xff;
2188 }
2189 else 2174 else
2190 {
2191 esl.len = eoldlen; 2175 esl.len = eoldlen;
2192 }
2193 } /* else this is a viewable space */ 2176 } /* else this is a viewable space */
2194 } /* for x loop */ 2177 } /* for x loop */
2195 } /* for y loop */ 2178 } /* for y loop */
2196 2179
2197 /* Verify that we in fact do need to send this */ 2180 /* Verify that we in fact do need to send this */
2203 * it doesn't need draw! 2186 * it doesn't need draw!
2204 */ 2187 */
2205 ewhatflag &= (~EMI_NOREDRAW); 2188 ewhatflag &= (~EMI_NOREDRAW);
2206 esl.buf[ewhatstart + 1] = ewhatflag & 0xff; 2189 esl.buf[ewhatstart + 1] = ewhatflag & 0xff;
2207 } 2190 }
2191
2208 if (esl.len > estartlen) 2192 if (esl.len > estartlen)
2209 {
2210 Send_With_Handling (&socket, &esl); 2193 Send_With_Handling (&socket, &esl);
2211 }
2212 free (esl.buf);
2213 } 2194 }
2195
2214 if (sl.len > startlen || socket.sent_scroll) 2196 if (sl.len > startlen || socket.sent_scroll)
2215 { 2197 {
2216 Send_With_Handling (&socket, &sl); 2198 Send_With_Handling (&socket, &sl);
2217 socket.sent_scroll = 0; 2199 socket.sent_scroll = 0;
2218 } 2200 }
2219 free (sl.buf);
2220} 2201}
2221 2202
2222/** 2203/**
2223 * Draws client map. 2204 * Draws client map.
2224 */ 2205 */
2229 sint16 ax, ay, nx, ny; /* ax and ay goes from 0 to max-size of arrays */ 2210 sint16 ax, ay, nx, ny; /* ax and ay goes from 0 to max-size of arrays */
2230 New_Face *face, *floor; 2211 New_Face *face, *floor;
2231 New_Face *floor2; 2212 New_Face *floor2;
2232 int d, mflags; 2213 int d, mflags;
2233 struct Map newmap; 2214 struct Map newmap;
2234 mapstruct *m, *pm; 2215 maptile *m, *pm;
2235 2216
2236 if (pl->type != PLAYER) 2217 if (pl->type != PLAYER)
2237 { 2218 {
2238 LOG (llevError, "draw_client_map called with non player/non eric-server\n"); 2219 LOG (llevError, "draw_client_map called with non player/non eric-server\n");
2239 return; 2220 return;
2338 esrv_map_setbelow (&pl->contr->socket, ax, ay, floor->number, &newmap); 2319 esrv_map_setbelow (&pl->contr->socket, ax, ay, floor->number, &newmap);
2339 } 2320 }
2340 } /* Is a valid space */ 2321 } /* Is a valid space */
2341 } 2322 }
2342 } 2323 }
2324
2343 esrv_map_doneredraw (&pl->contr->socket, &newmap); 2325 esrv_map_doneredraw (&pl->contr->socket, &newmap);
2344 2326
2345 check_map_change (pl->contr); 2327 check_map_change (pl->contr);
2346} 2328}
2347 2329
2356 2338
2357/*****************************************************************************/ 2339/*****************************************************************************/
2358void 2340void
2359send_plugin_custom_message (object *pl, char *buf) 2341send_plugin_custom_message (object *pl, char *buf)
2360{ 2342{
2361 cs_write_string (&pl->contr->socket, buf, strlen (buf)); 2343 pl->contr->socket.send_packet (buf);
2362} 2344}
2363 2345
2364/** 2346/**
2365 * This sends the skill number to name mapping. We ignore 2347 * This sends the skill number to name mapping. We ignore
2366 * the params - we always send the same info no matter what. 2348 * the params - we always send the same info no matter what.
2367 */ 2349 */
2368void 2350void
2369send_skill_info (NewSocket * ns, char *params) 2351send_skill_info (NewSocket *ns, char *params)
2370{ 2352{
2371 SockList sl; 2353 packet sl;
2372 int i; 2354 sl << "replyinfo skill_info\n";
2373 2355
2374 sl.buf = (unsigned char *) malloc (MAXSOCKBUF);
2375 strcpy ((char *) sl.buf, "replyinfo skill_info\n");
2376 for (i = 1; i < NUM_SKILLS; i++) 2356 for (int i = 1; i < NUM_SKILLS; i++)
2377 { 2357 sl.printf ("%d:%s\n", i + CS_STAT_SKILLINFO, &skill_names[i]);
2378 sprintf ((char *) sl.buf + strlen ((char *) sl.buf), "%d:%s\n", i + CS_STAT_SKILLINFO, &skill_names[i]); 2358
2379 }
2380 sl.len = strlen ((char *) sl.buf);
2381 if (sl.len >= MAXSOCKBUF) 2359 if (sl.len >= MAXSOCKBUF)
2382 { 2360 {
2383 LOG (llevError, "Buffer overflow in send_skill_info!\n"); 2361 LOG (llevError, "Buffer overflow in send_skill_info!\n");
2384 fatal (0); 2362 fatal (0);
2385 } 2363 }
2364
2386 Send_With_Handling (ns, &sl); 2365 Send_With_Handling (ns, &sl);
2387 free (sl.buf);
2388} 2366}
2389 2367
2390/** 2368/**
2391 * This sends the spell path to name mapping. We ignore 2369 * This sends the spell path to name mapping. We ignore
2392 * the params - we always send the same info no matter what. 2370 * the params - we always send the same info no matter what.
2393 */ 2371 */
2394void 2372void
2395send_spell_paths (NewSocket * ns, char *params) 2373send_spell_paths (NewSocket * ns, char *params)
2396{ 2374{
2397 SockList sl; 2375 packet sl;
2398 int i;
2399 2376
2400 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 2377 sl << "replyinfo spell_paths\n";
2401 strcpy ((char *) sl.buf, "replyinfo spell_paths\n"); 2378
2402 for (i = 0; i < NRSPELLPATHS; i++) 2379 for (int i = 0; i < NRSPELLPATHS; i++)
2403 sprintf ((char *) sl.buf + strlen ((char *) sl.buf), "%d:%s\n", 1 << i, spellpathnames[i]); 2380 sl.printf ("%d:%s\n", 1 << i, spellpathnames[i]);
2404 sl.len = strlen ((char *) sl.buf); 2381
2405 if (sl.len >= MAXSOCKBUF) 2382 if (sl.len >= MAXSOCKBUF)
2406 { 2383 {
2407 LOG (llevError, "Buffer overflow in send_spell_paths!\n"); 2384 LOG (llevError, "Buffer overflow in send_spell_paths!\n");
2408 fatal (0); 2385 fatal (0);
2409 } 2386 }
2387
2410 Send_With_Handling (ns, &sl); 2388 Send_With_Handling (ns, &sl);
2411 free (sl.buf);
2412} 2389}
2413 2390
2414/** 2391/**
2415 * This looks for any spells the player may have that have changed their stats. 2392 * This looks for any spells the player may have that have changed their stats.
2416 * it then sends an updspell packet for each spell that has changed in this way 2393 * it then sends an updspell packet for each spell that has changed in this way
2417 */ 2394 */
2418void 2395void
2419esrv_update_spells (player *pl) 2396esrv_update_spells (player *pl)
2420{ 2397{
2421 SockList sl;
2422 int flags = 0;
2423 object *spell;
2424
2425 if (!pl->socket.monitor_spells) 2398 if (!pl->socket.monitor_spells)
2426 return; 2399 return;
2400
2427 for (spell = pl->ob->inv; spell != NULL; spell = spell->below) 2401 for (object *spell = pl->ob->inv; spell; spell = spell->below)
2428 { 2402 {
2429 if (spell->type == SPELL) 2403 if (spell->type == SPELL)
2430 { 2404 {
2405 int flags = 0;
2406
2431 /* check if we need to update it */ 2407 /* check if we need to update it */
2432 if (spell->last_sp != SP_level_spellpoint_cost (pl->ob, spell, SPELL_MANA)) 2408 if (spell->last_sp != SP_level_spellpoint_cost (pl->ob, spell, SPELL_MANA))
2433 { 2409 {
2434 spell->last_sp = SP_level_spellpoint_cost (pl->ob, spell, SPELL_MANA); 2410 spell->last_sp = SP_level_spellpoint_cost (pl->ob, spell, SPELL_MANA);
2435 flags |= UPD_SP_MANA; 2411 flags |= UPD_SP_MANA;
2436 } 2412 }
2413
2437 if (spell->last_grace != SP_level_spellpoint_cost (pl->ob, spell, SPELL_GRACE)) 2414 if (spell->last_grace != SP_level_spellpoint_cost (pl->ob, spell, SPELL_GRACE))
2438 { 2415 {
2439 spell->last_grace = SP_level_spellpoint_cost (pl->ob, spell, SPELL_GRACE); 2416 spell->last_grace = SP_level_spellpoint_cost (pl->ob, spell, SPELL_GRACE);
2440 flags |= UPD_SP_GRACE; 2417 flags |= UPD_SP_GRACE;
2441 } 2418 }
2419
2442 if (spell->last_eat != spell->stats.dam + SP_level_dam_adjust (pl->ob, spell)) 2420 if (spell->last_eat != spell->stats.dam + SP_level_dam_adjust (pl->ob, spell))
2443 { 2421 {
2444 spell->last_eat = spell->stats.dam + SP_level_dam_adjust (pl->ob, spell); 2422 spell->last_eat = spell->stats.dam + SP_level_dam_adjust (pl->ob, spell);
2445 flags |= UPD_SP_DAMAGE; 2423 flags |= UPD_SP_DAMAGE;
2446 } 2424 }
2425
2447 if (flags != 0) 2426 if (flags)
2448 { 2427 {
2449 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 2428 packet sl;
2450 strcpy ((char *) sl.buf, "updspell "); 2429
2451 sl.len = strlen ((char *) sl.buf); 2430 sl << "updspell "
2452 SockList_AddChar (&sl, flags); 2431 << uint8 (flags)
2453 SockList_AddInt (&sl, spell->count); 2432 << uint32 (spell->count);
2454 if (flags & UPD_SP_MANA) 2433
2455 SockList_AddShort (&sl, spell->last_sp); 2434 if (flags & UPD_SP_MANA ) sl << uint16 (spell->last_sp);
2456 if (flags & UPD_SP_GRACE) 2435 if (flags & UPD_SP_GRACE ) sl << uint16 (spell->last_grace);
2457 SockList_AddShort (&sl, spell->last_grace); 2436 if (flags & UPD_SP_DAMAGE) sl << uint16 (spell->last_eat);
2458 if (flags & UPD_SP_DAMAGE) 2437
2459 SockList_AddShort (&sl, spell->last_eat);
2460 flags = 0;
2461 Send_With_Handling (&pl->socket, &sl); 2438 Send_With_Handling (&pl->socket, &sl);
2462 free (sl.buf);
2463 } 2439 }
2464 } 2440 }
2465 } 2441 }
2466} 2442}
2467 2443
2468void 2444void
2469esrv_remove_spell (player *pl, object *spell) 2445esrv_remove_spell (player *pl, object *spell)
2470{ 2446{
2471 SockList sl;
2472
2473 if (!pl->socket.monitor_spells) 2447 if (!pl->socket.monitor_spells)
2474 return; 2448 return;
2449
2475 if (!pl || !spell || spell->env != pl->ob) 2450 if (!pl || !spell || spell->env != pl->ob)
2476 { 2451 {
2477 LOG (llevError, "Invalid call to esrv_remove_spell"); 2452 LOG (llevError, "Invalid call to esrv_remove_spell");
2478 return; 2453 return;
2479 } 2454 }
2480 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 2455
2481 strcpy ((char *) sl.buf, "delspell "); 2456 packet sl;
2482 sl.len = strlen ((char *) sl.buf); 2457
2483 SockList_AddInt (&sl, spell->count); 2458 sl << "delspell "
2459 << uint32 (spell->count);
2460
2484 Send_With_Handling (&pl->socket, &sl); 2461 Send_With_Handling (&pl->socket, &sl);
2485 free (sl.buf);
2486} 2462}
2487 2463
2488/* appends the spell *spell to the Socklist we will send the data to. */ 2464/* appends the spell *spell to the Socklist we will send the data to. */
2489static void 2465static void
2490append_spell (player *pl, SockList * sl, object *spell) 2466append_spell (player *pl, packet &sl, object *spell)
2491{ 2467{
2492 int len, i, skill = 0; 2468 int len, i, skill = 0;
2493 2469
2494 if (!(spell->name)) 2470 if (!(spell->name))
2495 { 2471 {
2496 LOG (llevError, "item number %d is a spell with no name.\n", spell->count); 2472 LOG (llevError, "item number %d is a spell with no name.\n", spell->count);
2497 return; 2473 return;
2498 } 2474 }
2499 SockList_AddInt (sl, spell->count); 2475
2500 SockList_AddShort (sl, spell->level);
2501 SockList_AddShort (sl, spell->casting_time);
2502 /* store costs and damage in the object struct, to compare to later */ 2476 /* store costs and damage in the object struct, to compare to later */
2503 spell->last_sp = SP_level_spellpoint_cost (pl->ob, spell, SPELL_MANA); 2477 spell->last_sp = SP_level_spellpoint_cost (pl->ob, spell, SPELL_MANA);
2504 spell->last_grace = SP_level_spellpoint_cost (pl->ob, spell, SPELL_GRACE); 2478 spell->last_grace = SP_level_spellpoint_cost (pl->ob, spell, SPELL_GRACE);
2505 spell->last_eat = spell->stats.dam + SP_level_dam_adjust (pl->ob, spell); 2479 spell->last_eat = spell->stats.dam + SP_level_dam_adjust (pl->ob, spell);
2506 /* send the current values */
2507 SockList_AddShort (sl, spell->last_sp);
2508 SockList_AddShort (sl, spell->last_grace);
2509 SockList_AddShort (sl, spell->last_eat);
2510 2480
2511 /* figure out which skill it uses, if it uses one */ 2481 /* figure out which skill it uses, if it uses one */
2512 if (spell->skill) 2482 if (spell->skill)
2513 { 2483 {
2514 for (i = 1; i < NUM_SKILLS; i++) 2484 for (i = 1; i < NUM_SKILLS; i++)
2516 { 2486 {
2517 skill = i + CS_STAT_SKILLINFO; 2487 skill = i + CS_STAT_SKILLINFO;
2518 break; 2488 break;
2519 } 2489 }
2520 } 2490 }
2521 SockList_AddChar (sl, skill);
2522 2491
2523 SockList_AddInt (sl, spell->path_attuned); 2492 /* send the current values */
2493 sl << uint32 (spell->count)
2494 << uint16 (spell->level)
2495 << uint16 (spell->casting_time)
2496 << uint16 (spell->last_sp)
2497 << uint16 (spell->last_grace)
2498 << uint16 (spell->last_eat)
2499 << uint8 (skill)
2500 << uint32 (spell->path_attuned)
2524 SockList_AddInt (sl, (spell->face) ? spell->face->number : 0); 2501 << uint32 (spell->face ? spell->face->number : 0)
2525 2502 << data8 (spell->name)
2526 len = strlen (spell->name); 2503 << data16 (spell->msg);
2527 SockList_AddChar (sl, (char) len);
2528 memcpy (sl->buf + sl->len, spell->name, len);
2529 sl->len += len;
2530
2531 if (!spell->msg)
2532 {
2533 SockList_AddShort (sl, 0);
2534 }
2535 else
2536 {
2537 len = strlen (spell->msg);
2538 SockList_AddShort (sl, len);
2539 memcpy (sl->buf + sl->len, spell->msg, len);
2540 sl->len += len;
2541 }
2542} 2504}
2543 2505
2544/** 2506/**
2545 * This tells the client to add the spell *ob, if *ob is NULL, then add 2507 * This tells the client to add the spell *ob, if *ob is NULL, then add
2546 * all spells in the player's inventory. 2508 * all spells in the player's inventory.
2547 */ 2509 */
2548void 2510void
2549esrv_add_spells (player *pl, object *spell) 2511esrv_add_spells (player *pl, object *spell)
2550{ 2512{
2551 SockList sl;
2552
2553 if (!pl) 2513 if (!pl)
2554 { 2514 {
2555 LOG (llevError, "esrv_add_spells, tried to add a spell to a NULL player"); 2515 LOG (llevError, "esrv_add_spells, tried to add a spell to a NULL player");
2556 return; 2516 return;
2557 } 2517 }
2518
2558 if (!pl->socket.monitor_spells) 2519 if (!pl->socket.monitor_spells)
2559 return; 2520 return;
2560 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 2521
2561 strcpy ((char *) sl.buf, "addspell "); 2522 packet sl;
2562 sl.len = strlen ((char *) sl.buf); 2523
2524 sl << "addspell ";
2525
2563 if (!spell) 2526 if (!spell)
2564 { 2527 {
2565 for (spell = pl->ob->inv; spell != NULL; spell = spell->below) 2528 for (spell = pl->ob->inv; spell != NULL; spell = spell->below)
2566 { 2529 {
2567 /* were we to simply keep appending data here, we could exceed 2530 /* were we to simply keep appending data here, we could exceed
2577 * is hundreds of bytes off, so correcting 22 vs 26 doesn't seem 2540 * is hundreds of bytes off, so correcting 22 vs 26 doesn't seem
2578 * like it will fix this 2541 * like it will fix this
2579 */ 2542 */
2580 if (spell->type != SPELL) 2543 if (spell->type != SPELL)
2581 continue; 2544 continue;
2545
2582 if (sl.len >= (MAXSOCKBUF - (26 + strlen (spell->name) + (spell->msg ? strlen (spell->msg) : 0)))) 2546 if (sl.len >= (MAXSOCKBUF - (26 + strlen (spell->name) + (spell->msg ? strlen (spell->msg) : 0))))
2583 { 2547 {
2584 Send_With_Handling (&pl->socket, &sl); 2548 Send_With_Handling (&pl->socket, &sl);
2585 strcpy ((char *) sl.buf, "addspell "); 2549 strcpy ((char *) sl.buf, "addspell ");
2586 sl.len = strlen ((char *) sl.buf); 2550 sl.len = strlen ((char *) sl.buf);
2587 } 2551 }
2552
2588 append_spell (pl, &sl, spell); 2553 append_spell (pl, sl, spell);
2589 } 2554 }
2590 } 2555 }
2591 else if (spell->type != SPELL) 2556 else if (spell->type != SPELL)
2592 { 2557 {
2593 LOG (llevError, "Asked to send a non-spell object as a spell"); 2558 LOG (llevError, "Asked to send a non-spell object as a spell");
2594 return; 2559 return;
2595 } 2560 }
2596 else 2561 else
2597 append_spell (pl, &sl, spell); 2562 append_spell (pl, sl, spell);
2563
2598 if (sl.len >= MAXSOCKBUF) 2564 if (sl.length () >= MAXSOCKBUF)
2599 { 2565 {
2600 LOG (llevError, "Buffer overflow in esrv_add_spells!\n"); 2566 LOG (llevError, "Buffer overflow in esrv_add_spells!\n");
2601 fatal (0); 2567 fatal (0);
2602 } 2568 }
2569
2603 /* finally, we can send the packet */ 2570 /* finally, we can send the packet */
2604 Send_With_Handling (&pl->socket, &sl); 2571 Send_With_Handling (&pl->socket, &sl);
2605 free (sl.buf); 2572
2606} 2573}
2574

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines