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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines