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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines