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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines