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.18 by root, Thu Sep 14 19:08:41 2006 UTC vs.
Revision 1.29 by root, Wed Dec 13 21:27:09 2006 UTC

1
2/*
3 * static char *rcsid_init_c =
4 * "$Id: request.C,v 1.18 2006/09/14 19:08:41 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.
63#include <commands.h> 57#include <commands.h>
64 58
65/* 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,
66 * it should work here. 60 * it should work here.
67 */ 61 */
68#ifndef WIN32 /* ---win32 exclude unix headers */
69# include <sys/types.h> 62#include <sys/types.h>
70# include <sys/time.h> 63#include <sys/time.h>
71# include <sys/socket.h> 64#include <sys/socket.h>
72# include <netinet/in.h> 65#include <netinet/in.h>
73# include <netdb.h> 66#include <netdb.h>
74#endif /* win32 */
75 67
76#ifdef HAVE_UNISTD_H 68#ifdef HAVE_UNISTD_H
77# include <unistd.h> 69# include <unistd.h>
78#endif 70#endif
79 71
143 for (x = 0; x < mx; x++) 135 for (x = 0; x < mx; x++)
144 { 136 {
145 for (y = 0; y < my; y++) 137 for (y = 0; y < my; y++)
146 { 138 {
147 if (x >= ns->mapx || y >= ns->mapy) 139 if (x >= ns->mapx || y >= ns->mapy)
148 {
149 /* clear cells outside the viewable area */ 140 /* clear cells outside the viewable area */
150 memset (&newmap.cells[x][y], 0, sizeof (struct MapCell)); 141 memset (&newmap.cells[x][y], 0, sizeof (struct MapCell));
151 }
152 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)
153 {
154 /* clear newly visible tiles within the viewable area */ 143 /* clear newly visible tiles within the viewable area */
155 memset (&(newmap.cells[x][y]), 0, sizeof (struct MapCell)); 144 memset (&(newmap.cells[x][y]), 0, sizeof (struct MapCell));
156 }
157 else 145 else
158 {
159 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));
160 }
161 } 147 }
162 } 148 }
163 149
164 memcpy (&(ns->lastmap), &newmap, sizeof (struct Map)); 150 memcpy (&(ns->lastmap), &newmap, sizeof (struct Map));
165 151
264 if (!strncmp (buf, "spatial ", 8)) 250 if (!strncmp (buf, "spatial ", 8))
265 { 251 {
266 buf += 8; 252 buf += 8;
267 253
268 // initial map and its origin 254 // initial map and its origin
269 mapstruct *map = pl->ob->map; 255 maptile *map = pl->ob->map;
270 sint16 dx, dy; 256 sint16 dx, dy;
271 int mapx = pl->socket.mapx / 2 - pl->ob->x; 257 int mapx = pl->socket.mapx / 2 - pl->ob->x;
272 int mapy = pl->socket.mapy / 2 - pl->ob->y; 258 int mapy = pl->socket.mapy / 2 - pl->ob->y;
273 int max_distance = 8; // limit maximum path length to something generous 259 int max_distance = 8; // limit maximum path length to something generous
274 260
696 */ 682 */
697static void 683static void
698SendSmooth (NewSocket * ns, uint16 face) 684SendSmooth (NewSocket * ns, uint16 face)
699{ 685{
700 uint16 smoothface; 686 uint16 smoothface;
701 unsigned char reply[MAX_BUF];
702 SockList sl;
703 687
704 /* 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
705 * again. 689 * again.
706 */ 690 */
707 if ((!FindSmooth (face, &smoothface)) && (!FindSmooth (smooth_face->number, &smoothface))) 691 if ((!FindSmooth (face, &smoothface)) && (!FindSmooth (smooth_face->number, &smoothface)))
715 if (!(ns->faces_sent[smoothface] & NS_FACESENT_FACE)) 699 if (!(ns->faces_sent[smoothface] & NS_FACESENT_FACE))
716 esrv_send_face (ns, smoothface, 0); 700 esrv_send_face (ns, smoothface, 0);
717 701
718 ns->faces_sent[face] |= NS_FACESENT_SMOOTH; 702 ns->faces_sent[face] |= NS_FACESENT_SMOOTH;
719 703
720 sl.buf = reply; 704 SockList sl (MAXSOCKBUF);
721 strcpy ((char *) sl.buf, "smooth "); 705
722 sl.len = strlen ((char *) sl.buf); 706 sl << "smooth "
723 SockList_AddShort (&sl, face); 707 << uint16 (face)
724 SockList_AddShort (&sl, smoothface); 708 << uint16 (smoothface);
709
725 Send_With_Handling (ns, &sl); 710 Send_With_Handling (ns, &sl);
711 sl.free ();
726} 712}
727 713
728 /** 714 /**
729 * Tells client the picture it has to use 715 * Tells client the picture it has to use
730 * to smooth a picture number given as argument. 716 * to smooth a picture number given as argument.
736 722
737 facenbr = atoi (buf); 723 facenbr = atoi (buf);
738 SendSmooth (ns, facenbr); 724 SendSmooth (ns, facenbr);
739} 725}
740 726
741
742
743
744
745/** 727/**
746 * 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,
747 * etc.) 729 * etc.)
748 */ 730 */
749void 731void
802 */ 784 */
803void 785void
804NewPlayerCmd (uint8 * buf, int len, player *pl) 786NewPlayerCmd (uint8 * buf, int len, player *pl)
805{ 787{
806 int time, repeat; 788 int time, repeat;
789 char command[MAX_BUF];
807 short packet; 790 short packet;
808 unsigned char command[MAX_BUF];
809 SockList sl;
810 791
811 if (len < 7) 792 if (len < 7)
812 { 793 {
813 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);
814 return; 795 return;
816 797
817 packet = GetShort_String (buf); 798 packet = GetShort_String (buf);
818 repeat = GetInt_String (buf + 2); 799 repeat = GetInt_String (buf + 2);
819 /* -1 is special - no repeat, but don't update */ 800 /* -1 is special - no repeat, but don't update */
820 if (repeat != -1) 801 if (repeat != -1)
821 {
822 pl->count = repeat; 802 pl->count = repeat;
823 } 803
824 if ((len - 4) >= MAX_BUF) 804 if ((len - 4) >= MAX_BUF)
825 len = MAX_BUF - 5; 805 len = MAX_BUF - 5;
826 806
827 strncpy ((char *) command, (char *) buf + 6, len - 4); 807 strncpy ((char *) command, (char *) buf + 6, len - 4);
828 command[len - 4] = '\0'; 808 command[len - 4] = '\0';
838 return; 818 return;
839 } 819 }
840 820
841 /* This should not happen anymore. */ 821 /* This should not happen anymore. */
842 if (pl->ob->speed_left < -1.0) 822 if (pl->ob->speed_left < -1.0)
843 {
844 LOG (llevError, "Player has negative time - shouldn't do command.\n"); 823 LOG (llevError, "Player has negative time - shouldn't do command.\n");
845 } 824
846 /* In c_new.c */ 825 /* In c_new.c */
847 execute_newserver_command (pl->ob, (char *) command); 826 execute_newserver_command (pl->ob, (char *) command);
848 /* Perhaps something better should be done with a left over count. 827 /* Perhaps something better should be done with a left over count.
849 * Cleaning up the input should probably be done first - all actions 828 * Cleaning up the input should probably be done first - all actions
850 * 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
851 * commands. 830 * commands.
852 */ 831 */
853 pl->count = 0; 832 pl->count = 0;
854 833
855 /* Send confirmation of command execution now */
856 sl.buf = command;
857 strcpy ((char *) sl.buf, "comc ");
858 sl.len = 5;
859 SockList_AddShort (&sl, packet);
860 if (FABS (pl->ob->speed) < 0.001) 834 if (FABS (pl->ob->speed) < 0.001)
861 time = MAX_TIME * 100; 835 time = MAX_TIME * 100;
862 else 836 else
863 time = (int) (MAX_TIME / FABS (pl->ob->speed)); 837 time = (int) (MAX_TIME / FABS (pl->ob->speed));
864 SockList_AddInt (&sl, time); 838
839 /* Send confirmation of command execution now */
840
841 SockList sl (MAXSOCKBUF);
842 sl << "comc " << uint16 (packet) << uint32 (time);
865 Send_With_Handling (&pl->socket, &sl); 843 Send_With_Handling (&pl->socket, &sl);
844 sl.free ();
866} 845}
867 846
868 847
869/** This is a reply to a previous query. */ 848/** This is a reply to a previous query. */
870void 849void
982 /* these are old dxclients */ 961 /* these are old dxclients */
983 /* Version 1024 added support for singular + plural name values - 962 /* Version 1024 added support for singular + plural name values -
984 * requiing this minimal value reduces complexity of that code, and it 963 * requiing this minimal value reduces complexity of that code, and it
985 * has been around for a long time. 964 * has been around for a long time.
986 */ 965 */
987 if (!strcmp (" CF DX CLIENT", cp) || ns->sc_version < 1024) 966 if (ns->sc_version < 1026)
988 { 967 {
989 sprintf (version_warning, "drawinfo %d %s", NDI_RED, 968 sprintf (version_warning, "drawinfo %d %s", NDI_RED,
990 "**** VERSION WARNING ****\n**** CLIENT IS TOO OLD!! UPDATE THE CLIENT!! ****"); 969 "**** VERSION WARNING ****\n**** CLIENT IS TOO OLD!! UPDATE THE CLIENT!! ****");
991 Write_String_To_Socket (ns, version_warning, strlen (version_warning)); 970 Write_String_To_Socket (ns, version_warning, strlen (version_warning));
992 } 971 }
1073 Write_String_To_Socket (ns, buf, strlen (buf)); 1052 Write_String_To_Socket (ns, buf, strlen (buf));
1074} 1053}
1075 1054
1076#define AddIfInt64(Old,New,Type) if (Old != New) {\ 1055#define AddIfInt64(Old,New,Type) if (Old != New) {\
1077 Old = New; \ 1056 Old = New; \
1078 SockList_AddChar(&sl, Type); \ 1057 sl << uint8 (Type) << uint64 (New); \
1079 SockList_AddInt64(&sl, New); \
1080 } 1058 }
1081 1059
1082#define AddIfInt(Old,New,Type) if (Old != New) {\ 1060#define AddIfInt(Old,New,Type) if (Old != New) {\
1083 Old = New; \ 1061 Old = New; \
1084 SockList_AddChar(&sl, Type); \ 1062 sl << uint8 (Type) << uint32 (New); \
1085 SockList_AddInt(&sl, New); \
1086 } 1063 }
1087 1064
1088#define AddIfShort(Old,New,Type) if (Old != New) {\ 1065#define AddIfShort(Old,New,Type) if (Old != New) {\
1089 Old = New; \ 1066 Old = New; \
1090 SockList_AddChar(&sl, Type); \ 1067 sl << uint8 (Type) << uint16 (New); \
1091 SockList_AddShort(&sl, New); \
1092 } 1068 }
1093 1069
1094#define AddIfFloat(Old,New,Type) if (Old != New) {\ 1070#define AddIfFloat(Old,New,Type) if (Old != New) {\
1095 Old = New; \ 1071 Old = New; \
1096 SockList_AddChar(&sl, Type); \ 1072 sl << uint8 (Type) << uint32 (New*FLOAT_MULTI); \
1097 SockList_AddInt(&sl,(long)(New*FLOAT_MULTI));\
1098 } 1073 }
1099 1074
1100#define AddIfString(Old,New,Type) if (Old == NULL || strcmp(Old,New)) {\ 1075#define AddIfString(Old,New,Type) if (Old == NULL || strcmp(Old,New)) {\
1101 if (Old) free(Old);\
1102 Old = strdup_local(New);\ 1076 free(Old); Old = strdup (New);\
1103 SockList_AddChar(&sl, Type); \ 1077 sl << uint8 (Type) << data8 (New); \
1104 SockList_AddChar(&sl, ( char )strlen(New)); \
1105 strcpy((char*)sl.buf + sl.len, New); \
1106 sl.len += strlen(New); \
1107 } 1078 }
1108 1079
1109/** 1080/**
1110 * Sends a statistics update. We look at the old values, 1081 * Sends a statistics update. We look at the old values,
1111 * 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
1113 * commands for now. 1084 * commands for now.
1114 */ 1085 */
1115void 1086void
1116esrv_update_stats (player *pl) 1087esrv_update_stats (player *pl)
1117{ 1088{
1118 SockList sl;
1119 char buf[MAX_BUF]; 1089 char buf[MAX_BUF];
1120 uint16 flags; 1090 uint16 flags;
1121 1091
1122 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 1092 SockList sl (MAXSOCKBUF);
1123 strcpy ((char *) sl.buf, "stats "); 1093 sl << "stats ";
1124 sl.len = strlen ((char *) sl.buf);
1125 1094
1126 if (pl->ob != NULL) 1095 if (pl->ob != NULL)
1127 { 1096 {
1128 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);
1129 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);
1137 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);
1138 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);
1139 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);
1140 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);
1141 } 1110 }
1111
1142 if (pl->socket.exp64) 1112 if (pl->socket.exp64)
1143 { 1113 {
1144 uint8 s; 1114 uint8 s;
1145 1115
1146 for (s = 0; s < NUM_SKILLS; s++) 1116 for (s = 0; s < NUM_SKILLS; s++)
1147 { 1117 {
1148 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)
1149 { 1119 {
1150
1151 /* Always send along the level if exp changes. This is only 1120 /* Always send along the level if exp changes. This is only
1152 * 1 extra byte, but keeps processing simpler. 1121 * 1 extra byte, but keeps processing simpler.
1153 */ 1122 */
1154 SockList_AddChar (&sl, (char) (s + CS_STAT_SKILLINFO)); 1123 sl << uint8 (s + CS_STAT_SKILLINFO)
1155 SockList_AddChar (&sl, (char) pl->last_skill_ob[s]->level); 1124 << uint8 (pl->last_skill_ob[s]->level)
1156 SockList_AddInt64 (&sl, pl->last_skill_ob[s]->stats.exp); 1125 << uint64 (pl->last_skill_ob[s]->stats.exp);
1126
1157 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;
1158 } 1128 }
1159 } 1129 }
1160 } 1130 }
1131
1161 if (pl->socket.exp64) 1132 if (pl->socket.exp64)
1162 {
1163 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) }
1164 }
1165 else 1134 else
1166 {
1167 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) }
1168 } 1136
1169 AddIfShort (pl->last_level, (char) pl->ob->level, CS_STAT_LEVEL); 1137 AddIfShort (pl->last_level, (char) pl->ob->level, CS_STAT_LEVEL);
1170 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);
1171 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);
1172 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);
1173 AddIfFloat (pl->last_speed, pl->ob->speed, CS_STAT_SPEED); 1141 AddIfFloat (pl->last_speed, pl->ob->speed, CS_STAT_SPEED);
1174 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);
1175 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);
1176 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);
1177 flags = 0; 1145 flags = 0;
1146
1178 if (pl->fire_on) 1147 if (pl->fire_on)
1179 flags |= SF_FIREON; 1148 flags |= SF_FIREON;
1149
1180 if (pl->run_on) 1150 if (pl->run_on)
1181 flags |= SF_RUNON; 1151 flags |= SF_RUNON;
1182 1152
1183 AddIfShort (pl->last_flags, flags, CS_STAT_FLAGS); 1153 AddIfShort (pl->last_flags, flags, CS_STAT_FLAGS);
1154
1184 if (pl->socket.sc_version < 1025) 1155 if (pl->socket.sc_version < 1025)
1185 {
1186 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) }
1187 }
1188 else 1157 else
1189 { 1158 {
1190 int i; 1159 int i;
1191 1160
1192 for (i = 0; i < NROFATTACKS; i++) 1161 for (i = 0; i < NROFATTACKS; i++)
1193 { 1162 {
1194 /* Skip ones we won't send */ 1163 /* Skip ones we won't send */
1195 if (atnr_cs_stat[i] == -1) 1164 if (atnr_cs_stat[i] == -1)
1196 continue; 1165 continue;
1166
1197 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]);
1198 } 1168 }
1199 } 1169 }
1170
1200 if (pl->socket.monitor_spells) 1171 if (pl->socket.monitor_spells)
1201 { 1172 {
1202 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);
1203 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);
1204 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);
1205 } 1176 }
1177
1206 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 */
1207 AddIfString (pl->socket.stats.range, buf, CS_STAT_RANGE); 1179 AddIfString (pl->socket.stats.range, buf, CS_STAT_RANGE);
1208 set_title (pl->ob, buf); 1180 set_title (pl->ob, buf);
1209 AddIfString (pl->socket.stats.title, buf, CS_STAT_TITLE); 1181 AddIfString (pl->socket.stats.title, buf, CS_STAT_TITLE);
1210 1182
1214#ifdef ESRV_DEBUG 1186#ifdef ESRV_DEBUG
1215 LOG (llevDebug, "Sending stats command, %d bytes long.\n", sl.len); 1187 LOG (llevDebug, "Sending stats command, %d bytes long.\n", sl.len);
1216#endif 1188#endif
1217 Send_With_Handling (&pl->socket, &sl); 1189 Send_With_Handling (&pl->socket, &sl);
1218 } 1190 }
1219 free (sl.buf);
1220}
1221 1191
1192 sl.free ();
1193}
1222 1194
1223/** 1195/**
1224 * 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.
1225 */ 1197 */
1226void 1198void
1227esrv_new_player (player *pl, uint32 weight) 1199esrv_new_player (player *pl, uint32 weight)
1228{ 1200{
1229 SockList sl;
1230
1231 pl->last_weight = weight; 1201 pl->last_weight = weight;
1232 1202
1233 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 1203 SockList sl (MAXSOCKBUF);
1204 sl << "player ";
1234 1205
1235 strcpy ((char *) sl.buf, "player "); 1206 sl << uint32 (pl->ob->count)
1236 sl.len = strlen ((char *) sl.buf); 1207 << uint32 (weight)
1237 SockList_AddInt (&sl, pl->ob->count); 1208 << uint32 (pl->ob->face->number)
1238 SockList_AddInt (&sl, weight); 1209 << data8 (pl->ob->name);
1239 SockList_AddInt (&sl, pl->ob->face->number);
1240
1241 SockList_AddChar (&sl, (char) strlen (pl->ob->name));
1242 strcpy ((char *) sl.buf + sl.len, pl->ob->name);
1243 sl.len += strlen (pl->ob->name);
1244 1210
1245 Send_With_Handling (&pl->socket, &sl); 1211 Send_With_Handling (&pl->socket, &sl);
1246 free (sl.buf); 1212 sl.free ();
1247 SET_FLAG (pl->ob, FLAG_CLIENT_SENT); 1213 SET_FLAG (pl->ob, FLAG_CLIENT_SENT);
1248} 1214}
1249
1250 1215
1251/** 1216/**
1252 * Need to send an animation sequence to the client. 1217 * Need to send an animation sequence to the client.
1253 * 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
1254 * 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
1256 * when the player logs in and picks stuff up. 1221 * when the player logs in and picks stuff up.
1257 */ 1222 */
1258void 1223void
1259esrv_send_animation (NewSocket * ns, short anim_num) 1224esrv_send_animation (NewSocket * ns, short anim_num)
1260{ 1225{
1261 SockList sl;
1262 int i; 1226 int i;
1263 1227
1264 /* 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
1265 * 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
1266 * range, it must be a valid animation. 1230 * range, it must be a valid animation.
1269 { 1233 {
1270 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);
1271 return; 1235 return;
1272 } 1236 }
1273 1237
1274 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 1238 SockList sl (MAXSOCKBUF);
1275 strcpy ((char *) sl.buf, "anim "); 1239
1276 sl.len = 5; 1240 sl << "anim "
1277 SockList_AddShort (&sl, anim_num); 1241 << uint16 (anim_num)
1278 SockList_AddShort (&sl, 0); /* flags - not used right now */ 1242 << uint16 (0); /* flags - not used right now */
1243
1279 /* 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
1280 * the face itself) down to the client. 1245 * the face itself) down to the client.
1281 */ 1246 */
1282 for (i = 0; i < animations[anim_num].num_animations; i++) 1247 for (i = 0; i < animations[anim_num].num_animations; i++)
1283 { 1248 {
1284 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))
1285 esrv_send_face (ns, animations[anim_num].faces[i], 0); 1250 esrv_send_face (ns, animations[anim_num].faces[i], 0);
1286 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 */
1287 } 1252 }
1253
1288 Send_With_Handling (ns, &sl); 1254 Send_With_Handling (ns, &sl);
1289 free (sl.buf); 1255 sl.free ();
1256
1290 ns->anims_sent[anim_num] = 1; 1257 ns->anims_sent[anim_num] = 1;
1291} 1258}
1292 1259
1293 1260
1294/****************************************************************************** 1261/******************************************************************************
1308 { 1275 {
1309 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);
1310 return; 1277 return;
1311 abort (); 1278 abort ();
1312 } 1279 }
1280
1313 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;
1314 newmap->cells[x][y].count++; 1282 newmap->cells[x][y].count++;
1283
1315 if (!(ns->faces_sent[face_num] & NS_FACESENT_FACE)) 1284 if (!(ns->faces_sent[face_num] & NS_FACESENT_FACE))
1316 esrv_send_face (ns, face_num, 0); 1285 esrv_send_face (ns, face_num, 0);
1317} 1286}
1318 1287
1319struct LayerCell 1288struct LayerCell
1426static void 1395static void
1427esrv_map_doneredraw (NewSocket * ns, struct Map *newmap) 1396esrv_map_doneredraw (NewSocket * ns, struct Map *newmap)
1428{ 1397{
1429 static long frames, bytes, tbytes, tframes; 1398 static long frames, bytes, tbytes, tframes;
1430 char *cur; 1399 char *cur;
1431 SockList sl;
1432 1400
1433 1401 SockList sl (MAXSOCKBUF);
1434 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 1402 sl << "map ";
1435 strcpy ((char *) sl.buf, "map ");
1436 sl.len = strlen ((char *) sl.buf);
1437 1403
1438 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);
1439 sl.len = cur - (char *) sl.buf; 1405 sl.len = cur - (char *) sl.buf;
1440 1406
1441/* LOG(llevDebug, "Sending map command.\n");*/ 1407/* LOG(llevDebug, "Sending map command.\n");*/
1453 memcpy (&ns->lastmap, newmap, sizeof (struct Map)); 1419 memcpy (&ns->lastmap, newmap, sizeof (struct Map));
1454 Send_With_Handling (ns, &sl); 1420 Send_With_Handling (ns, &sl);
1455 ns->sent_scroll = 0; 1421 ns->sent_scroll = 0;
1456 } 1422 }
1457 1423
1458 free (sl.buf); 1424 sl.free ();
1459} 1425}
1460 1426
1461 1427
1462/** Clears a map cell */ 1428/** Clears a map cell */
1463static void 1429static void
1464map_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)
1465{ 1431{
1466 cell->faces[0] = face0; 1432 cell->faces[0] = face0;
1467 cell->faces[1] = face1; 1433 cell->faces[1] = face1;
1468 cell->faces[2] = face2; 1434 cell->faces[2] = face2;
1469 cell->count = count; 1435 cell->count = count;
1470 cell->stat_hp = 0; 1436 cell->stat_hp = 0;
1437 cell->flags = 0;
1471 cell->player = 0; 1438 cell->player = 0;
1472} 1439}
1473 1440
1474#define MAX_HEAD_POS MAX(MAX_CLIENT_X, MAX_CLIENT_Y) 1441#define MAX_HEAD_POS MAX(MAX_CLIENT_X, MAX_CLIENT_Y)
1475#define MAX_LAYERS 3 1442#define MAX_LAYERS 3
1476 1443
1504 * 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
1505 * 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
1506 * sent, it returns zero. 1473 * sent, it returns zero.
1507 */ 1474 */
1508static int 1475static int
1509check_head (SockList & sl, NewSocket & ns, int ax, int ay, int layer) 1476check_head (SockList &sl, NewSocket &ns, int ax, int ay, int layer)
1510{ 1477{
1511 short face_num; 1478 short face_num;
1512 1479
1513 if (heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer]) 1480 if (heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer])
1514 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;
1518 if (face_num != ns.lastmap.cells[ax][ay].faces[layer]) 1485 if (face_num != ns.lastmap.cells[ax][ay].faces[layer])
1519 { 1486 {
1520 SockList_AddShort (&sl, face_num); 1487 SockList_AddShort (&sl, face_num);
1521 if (face_num && !(ns.faces_sent[face_num] & NS_FACESENT_FACE)) 1488 if (face_num && !(ns.faces_sent[face_num] & NS_FACESENT_FACE))
1522 esrv_send_face (&ns, face_num, 0); 1489 esrv_send_face (&ns, face_num, 0);
1490
1523 heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer] = NULL; 1491 heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer] = NULL;
1524 ns.lastmap.cells[ax][ay].faces[layer] = face_num; 1492 ns.lastmap.cells[ax][ay].faces[layer] = face_num;
1525 return 1; 1493 return 1;
1526 } 1494 }
1527 1495
1547 * 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
1548 * actually match. 1516 * actually match.
1549 */ 1517 */
1550 1518
1551static int 1519static int
1552update_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)
1553{ 1521{
1554 object *ob, *head; 1522 object *ob, *head;
1555 uint16 face_num; 1523 uint16 face_num;
1556 int bx, by, i; 1524 int bx, by, i;
1557 1525
1558 /* 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.
1559 * If not, then do the normal processing. 1527 * If not, then do the normal processing.
1560 */ 1528 */
1561
1562 head = heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer]; 1529 head = heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer];
1563 1530
1564 /* 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
1565 * we would normally send for this space. If so, then 1532 * we would normally send for this space. If so, then
1566 * 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
1731 1698
1732 /* 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
1733 * 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
1734 * this one. 1701 * this one.
1735 */ 1702 */
1736 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)
1737 {
1738 face_num = 0; 1704 face_num = 0;
1739 }
1740 1705
1741 /* 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
1742 * 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.
1743 */ 1708 */
1744 if (ns->lastmap.cells[sx][sy].faces[layer] != face_num) 1709 if (ns.lastmap.cells[sx][sy].faces[layer] != face_num)
1745 { 1710 {
1746 ns->lastmap.cells[sx][sy].faces[layer] = face_num; 1711 ns.lastmap.cells[sx][sy].faces[layer] = face_num;
1747 if (!(ns->faces_sent[face_num] & NS_FACESENT_FACE)) 1712 if (!(ns.faces_sent[face_num] & NS_FACESENT_FACE))
1748 esrv_send_face (ns, face_num, 0); 1713 esrv_send_face (&ns, face_num, 0);
1749 SockList_AddShort (sl, face_num); 1714
1715 sl << uint16 (face_num);
1750 return 1; 1716 return 1;
1751 } 1717 }
1718
1752 /* Nothing changed */ 1719 /* Nothing changed */
1753 return 0; 1720 return 0;
1754} 1721}
1755 1722
1756/** 1723/**
1771 * 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
1772 * take. 1739 * take.
1773 */ 1740 */
1774 1741
1775static inline int 1742static inline int
1776update_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)
1777{ 1744{
1778 object *ob; 1745 object *ob;
1779 int smoothlevel; /* old face_num; */ 1746 int smoothlevel; /* old face_num; */
1780 1747
1781 ob = GET_MAP_FACE_OBJ (mp, mx, my, layer); 1748 ob = GET_MAP_FACE_OBJ (mp, mx, my, layer);
1786 if (!ob || ob->face == blank_face || MAP_NOSMOOTH (mp)) 1753 if (!ob || ob->face == blank_face || MAP_NOSMOOTH (mp))
1787 smoothlevel = 0; 1754 smoothlevel = 0;
1788 else 1755 else
1789 { 1756 {
1790 smoothlevel = ob->smoothlevel; 1757 smoothlevel = ob->smoothlevel;
1791 if (smoothlevel && !(ns->faces_sent[ob->face->number] & NS_FACESENT_SMOOTH)) 1758 if (smoothlevel && !(ns.faces_sent[ob->face->number] & NS_FACESENT_SMOOTH))
1792 SendSmooth (ns, ob->face->number); 1759 SendSmooth (&ns, ob->face->number);
1793 } /* else not already head object or blank face */ 1760 } /* else not already head object or blank face */
1794 1761
1795 /* 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
1796 * 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.
1797 */ 1764 */
1798 if (smoothlevel > 255) 1765 if (smoothlevel > 255)
1799 smoothlevel = 255; 1766 smoothlevel = 255;
1800 else if (smoothlevel < 0) 1767 else if (smoothlevel < 0)
1801 smoothlevel = 0; 1768 smoothlevel = 0;
1769
1802 if (ns->lastmap.cells[sx][sy].smooth[layer] != smoothlevel) 1770 if (ns.lastmap.cells[sx][sy].smooth[layer] != smoothlevel)
1803 { 1771 {
1804 ns->lastmap.cells[sx][sy].smooth[layer] = smoothlevel; 1772 ns.lastmap.cells[sx][sy].smooth[layer] = smoothlevel;
1805 SockList_AddChar (sl, (uint8) (smoothlevel & 0xFF)); 1773 sl << uint8 (smoothlevel);
1806 return 1; 1774 return 1;
1807 } 1775 }
1776
1808 /* Nothing changed */ 1777 /* Nothing changed */
1809 return 0; 1778 return 0;
1810} 1779}
1811 1780
1812/** 1781/**
1853draw_client_map1 (object *pl) 1822draw_client_map1 (object *pl)
1854{ 1823{
1855 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;
1856 sint16 nx, ny; 1825 sint16 nx, ny;
1857 int estartlen, eoldlen; 1826 int estartlen, eoldlen;
1858 SockList sl;
1859 SockList esl; /*For extended Map info */
1860 uint16 mask, emask; 1827 uint16 mask, emask;
1861 uint8 eentrysize; 1828 uint8 eentrysize;
1862 uint16 ewhatstart, ewhatflag; 1829 uint16 ewhatstart, ewhatflag;
1863 uint8 extendedinfos; 1830 uint8 extendedinfos;
1864 mapstruct *m; 1831 maptile *m;
1865 1832
1866 NewSocket & socket = pl->contr->socket; 1833 NewSocket &socket = pl->contr->socket;
1867 1834
1868 check_map_change (pl->contr); 1835 check_map_change (pl->contr);
1869 1836
1870 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 1837 SockList sl (MAXSOCKBUF);
1871 if (socket.mapmode == Map1Cmd) 1838 SockList esl (MAXSOCKBUF);
1872 strcpy ((char *) sl.buf, "map1 "); 1839
1873 else 1840 sl << (socket.mapmode == Map1Cmd ? "map1 " : "map1a ");
1874 strcpy ((char *) sl.buf, "map1a ");
1875 sl.len = strlen ((char *) sl.buf);
1876 startlen = sl.len; 1841 startlen = sl.len;
1842
1877 /*Extendedmapinfo structure initialisation */ 1843 /*Extendedmapinfo structure initialisation */
1878 if (socket.ext_mapinfos) 1844 if (socket.ext_mapinfos)
1879 { 1845 {
1880 esl.buf = (unsigned char *) malloc (MAXSOCKBUF);
1881 strcpy ((char *) esl.buf, "mapextended ");
1882 esl.len = strlen ((char *) esl.buf);
1883 extendedinfos = EMI_NOREDRAW; 1846 extendedinfos = EMI_NOREDRAW;
1847
1884 if (socket.EMI_smooth) 1848 if (socket.EMI_smooth)
1885 extendedinfos |= EMI_SMOOTH; 1849 extendedinfos |= EMI_SMOOTH;
1850
1886 ewhatstart = esl.len; 1851 ewhatstart = esl.len;
1887 ewhatflag = extendedinfos; /*The EMI_NOREDRAW bit 1852 ewhatflag = extendedinfos; /*The EMI_NOREDRAW bit
1888 could need to be taken away */ 1853 could need to be taken away */
1889 SockList_AddChar (&esl, extendedinfos);
1890 eentrysize = getExtendedMapInfoSize (&socket); 1854 eentrysize = getExtendedMapInfoSize (&socket);
1891 SockList_AddChar (&esl, eentrysize); 1855 esl << "mapextended "
1856 << uint8 (extendedinfos)
1857 << uint8 (eentrysize);
1892 estartlen = esl.len; 1858 estartlen = esl.len;
1893 } 1859 }
1894 else 1860 else
1895 { 1861 {
1896 /* suppress compiler warnings */ 1862 /* suppress compiler warnings */
1897 ewhatstart = 0; 1863 ewhatstart = 0;
1898 ewhatflag = 0; 1864 ewhatflag = 0;
1899 estartlen = 0; 1865 estartlen = 0;
1900 } 1866 }
1867
1901 /* Init data to zero */ 1868 /* Init data to zero */
1902 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);
1903 1870
1904 /* 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
1905 * locations. 1872 * locations.
1909 /* We could do this logic as conditionals in the if statement, 1876 /* We could do this logic as conditionals in the if statement,
1910 * but that started to get a bit messy to look at. 1877 * but that started to get a bit messy to look at.
1911 */ 1878 */
1912 max_x = pl->x + (socket.mapx + 1) / 2; 1879 max_x = pl->x + (socket.mapx + 1) / 2;
1913 max_y = pl->y + (socket.mapy + 1) / 2; 1880 max_y = pl->y + (socket.mapy + 1) / 2;
1881
1914 if (socket.mapmode == Map1aCmd) 1882 if (socket.mapmode == Map1aCmd)
1915 { 1883 {
1916 max_x += MAX_HEAD_OFFSET; 1884 max_x += MAX_HEAD_OFFSET;
1917 max_y += MAX_HEAD_OFFSET; 1885 max_y += MAX_HEAD_OFFSET;
1918 } 1886 }
1935 { 1903 {
1936 int i, got_one; 1904 int i, got_one;
1937 1905
1938 oldlen = sl.len; 1906 oldlen = sl.len;
1939 1907
1940 SockList_AddShort (&sl, mask); 1908 sl << uint16 (mask);
1941 1909
1942 if (check_head (sl, socket, ax, ay, 2)) 1910 if (check_head (sl, socket, ax, ay, 2)) mask |= 0x4;
1943 mask |= 0x4;
1944 if (check_head (sl, socket, ax, ay, 1)) 1911 if (check_head (sl, socket, ax, ay, 1)) mask |= 0x2;
1945 mask |= 0x2;
1946 if (check_head (sl, socket, ax, ay, 0)) 1912 if (check_head (sl, socket, ax, ay, 0)) mask |= 0x1;
1947 mask |= 0x1;
1948 1913
1949 /* 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
1950 * actually need to send that - just the coordinates 1915 * actually need to send that - just the coordinates
1951 * with no faces tells the client to blank out the 1916 * with no faces tells the client to blank out the
1952 * space. 1917 * space.
1953 */ 1918 */
1954 got_one = 0; 1919 got_one = 0;
1955 for (i = oldlen + 2; i < sl.len; i++) 1920 for (i = oldlen + 2; i < sl.len; i++)
1956 {
1957 if (sl.buf[i]) 1921 if (sl.buf[i])
1958 got_one = 1; 1922 got_one = 1;
1959 }
1960 1923
1961 if (got_one && (mask & 0xf)) 1924 if (got_one && (mask & 0xf))
1962 {
1963 sl.buf[oldlen + 1] = mask & 0xff; 1925 sl.buf[oldlen + 1] = mask & 0xff;
1964 }
1965 else 1926 else
1966 { /*either all faces blank, either no face at all */ 1927 { /*either all faces blank, either no face at all */
1967 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 */
1968 sl.len = oldlen + 2; 1929 sl.len = oldlen + 2;
1969 else 1930 else
1970 sl.len = oldlen; 1931 sl.len = oldlen;
1971 } 1932 }
1933
1972 /*What concerns extendinfos, nothing to be done for now 1934 /*What concerns extendinfos, nothing to be done for now
1973 * (perhaps effects layer later) 1935 * (perhaps effects layer later)
1974 */ 1936 */
1975 continue; /* don't do processing below */ 1937 continue; /* don't do processing below */
1976 } 1938 }
1977 1939
1978 MapCell & lastcell = socket.lastmap.cells[ax][ay]; 1940 MapCell &lastcell = socket.lastmap.cells[ax][ay];
1979 1941
1980 d = pl->contr->blocked_los[ax][ay]; 1942 d = pl->contr->blocked_los[ax][ay];
1981 1943
1982 /* 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,
1983 * we tell the client as such 1945 * we tell the client as such
1984 */ 1946 */
1985 nx = x; 1947 nx = x;
1986 ny = y; 1948 ny = y;
1987 m = get_map_from_coord (pl->map, &nx, &ny); 1949 m = get_map_from_coord (pl->map, &nx, &ny);
1950
1988 if (!m) 1951 if (!m)
1989 { 1952 {
1990 /* space is out of map. Update space and clear values 1953 /* space is out of map. Update space and clear values
1991 * 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
1992 * of the map, it shouldn't have a head 1955 * of the map, it shouldn't have a head
1993 */ 1956 */
1994 if (lastcell.count != -1) 1957 if (lastcell.count != -1)
1995 { 1958 {
1996 SockList_AddShort (&sl, mask); 1959 sl << uint16 (mask);
1997 map_clearcell (&lastcell, 0, 0, 0, -1); 1960 map_clearcell (&lastcell, 0, 0, 0, -1);
1998 } 1961 }
1999 } 1962 }
2000 else if (d > 3) 1963 else if (d > 3)
2001 { 1964 {
2005 * reason. Still may need to send the head for this space. 1968 * reason. Still may need to send the head for this space.
2006 */ 1969 */
2007 1970
2008 oldlen = sl.len; 1971 oldlen = sl.len;
2009 1972
2010 SockList_AddShort (&sl, mask); 1973 sl << uint16 (mask);
1974
2011 if (lastcell.count != -1) 1975 if (lastcell.count != -1)
2012 need_send = 1; 1976 need_send = 1;
1977
2013 count = -1; 1978 count = -1;
2014 1979
2015 if (socket.mapmode == Map1aCmd && have_head (ax, ay)) 1980 if (socket.mapmode == Map1aCmd && have_head (ax, ay))
2016 { 1981 {
2017 /* Now check to see if any heads need to be sent */ 1982 /* Now check to see if any heads need to be sent */
2018 1983
2019 if (check_head (sl, socket, ax, ay, 2)) 1984 if (check_head (sl, socket, ax, ay, 2)) mask |= 0x4;
2020 mask |= 0x4;
2021 if (check_head (sl, socket, ax, ay, 1)) 1985 if (check_head (sl, socket, ax, ay, 1)) mask |= 0x2;
2022 mask |= 0x2;
2023 if (check_head (sl, socket, ax, ay, 0)) 1986 if (check_head (sl, socket, ax, ay, 0)) mask |= 0x1;
2024 mask |= 0x1;
2025 1987
2026 lastcell.count = count; 1988 lastcell.count = count;
2027
2028 } 1989 }
2029 else 1990 else
2030 { 1991 {
2031 struct MapCell *cell = &lastcell;
2032
2033 /* properly clear a previously sent big face */ 1992 /* properly clear a previously sent big face */
2034 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)
2035 need_send = 1; 1995 need_send = 1;
1996
2036 map_clearcell (&lastcell, 0, 0, 0, count); 1997 map_clearcell (&lastcell, 0, 0, 0, count);
2037 } 1998 }
2038 1999
2039 if ((mask & 0xf) || need_send) 2000 if ((mask & 0xf) || need_send)
2040 {
2041 sl.buf[oldlen + 1] = mask & 0xff; 2001 sl.buf[oldlen + 1] = mask & 0xff;
2042 }
2043 else 2002 else
2044 {
2045 sl.len = oldlen; 2003 sl.len = oldlen;
2046 }
2047 } 2004 }
2048 else 2005 else
2049 { 2006 {
2050 /* 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
2051 * we need to send. 2008 * we need to send.
2063 */ 2020 */
2064 oldlen = sl.len; 2021 oldlen = sl.len;
2065 mask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4; 2022 mask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4;
2066 eoldlen = esl.len; 2023 eoldlen = esl.len;
2067 emask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4; 2024 emask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4;
2068 SockList_AddShort (&sl, mask); 2025 sl << uint16 (mask);
2069 2026
2070 if (socket.ext_mapinfos) 2027 if (socket.ext_mapinfos)
2071 SockList_AddShort (&esl, emask); 2028 esl << uint16 (emask);
2072 2029
2073 unsigned char dummy; 2030 unsigned char dummy;
2074 unsigned char *last_ext = &dummy; 2031 unsigned char *last_ext = &dummy;
2075 2032
2076 /* Darkness changed */ 2033 /* Darkness changed */
2080 2037
2081 if (socket.extmap) 2038 if (socket.extmap)
2082 { 2039 {
2083 *last_ext |= 0x80; 2040 *last_ext |= 0x80;
2084 last_ext = sl.buf + sl.len; 2041 last_ext = sl.buf + sl.len;
2085 SockList_AddChar (&sl, d); 2042 sl << uint8 (d);
2086 } 2043 }
2087 else 2044 else
2088 SockList_AddChar (&sl, 255 - 64 * d); 2045 sl << uint8 (255 - 64 * d);
2089 } 2046 }
2090 2047
2091 lastcell.count = d; 2048 lastcell.count = d;
2092 2049
2093 if (socket.extmap) 2050 if (socket.extmap)
2094 { 2051 {
2095 uint8 stat_hp = 0; 2052 uint8 stat_hp = 0;
2096 uint8 stat_width = 0; 2053 uint8 stat_width = 0;
2054 uint8 flags = 0;
2097 tag_t player = 0; 2055 UUID player = 0;
2098 2056
2099 // send hp information, if applicable 2057 // send hp information, if applicable
2100 if (object *op = GET_MAP_FACE_OBJ (m, nx, ny, 0)) 2058 if (object *op = GET_MAP_FACE_OBJ (m, nx, ny, 0))
2101 { 2059 {
2102 if (op->head || op->invisible) 2060 if (op->head || op->invisible)
2109 stat_hp = 255 - (op->stats.hp * 255 + 254) / op->stats.maxhp; 2067 stat_hp = 255 - (op->stats.hp * 255 + 254) / op->stats.maxhp;
2110 stat_width = op->arch->tail_x; 2068 stat_width = op->arch->tail_x;
2111 } 2069 }
2112 } 2070 }
2113 2071
2072 if (op->msg && op->msg[0] == '@')
2073 flags |= 1;
2074
2114 if (op->type == PLAYER && op != pl) 2075 if (op->type == PLAYER && op != pl)
2115 player = op->count; 2076 player = op->count;
2116 } 2077 }
2117 2078
2118 if (lastcell.stat_hp != stat_hp) 2079 if (lastcell.stat_hp != stat_hp)
2120 lastcell.stat_hp = stat_hp; 2081 lastcell.stat_hp = stat_hp;
2121 2082
2122 mask |= 0x8; 2083 mask |= 0x8;
2123 *last_ext |= 0x80; 2084 *last_ext |= 0x80;
2124 last_ext = sl.buf + sl.len; 2085 last_ext = sl.buf + sl.len;
2125 SockList_AddChar (&sl, 5); 2086
2126 SockList_AddChar (&sl, stat_hp); 2087 sl << uint8 (5) << uint8 (stat_hp);
2127 2088
2128 if (stat_width > 1) 2089 if (stat_width > 1)
2129 { 2090 {
2130 *last_ext |= 0x80; 2091 *last_ext |= 0x80;
2131 last_ext = sl.buf + sl.len; 2092 last_ext = sl.buf + sl.len;
2132 SockList_AddChar (&sl, 6); 2093
2133 SockList_AddChar (&sl, stat_width); 2094 sl << uint8 (6) << uint8 (stat_width);
2134 } 2095 }
2135 } 2096 }
2136 2097
2137 if (lastcell.player !=player) 2098 if (lastcell.player != player)
2138 { 2099 {
2139 lastcell.player = player; 2100 lastcell.player = player;
2140 2101
2141 mask |= 0x8; 2102 mask |= 0x8;
2142 *last_ext |= 0x80; 2103 *last_ext |= 0x80;
2143 last_ext = sl.buf + sl.len; 2104 last_ext = sl.buf + sl.len;
2144 SockList_AddChar (&sl, 0x47); 2105
2145 SockList_AddChar (&sl, 4); 2106 sl << uint8 (0x47) << uint8 (8) << (uint64)player;
2146 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);
2147 } 2118 }
2148 } 2119 }
2149 2120
2150 /* Floor face */ 2121 /* Floor face */
2151 if (update_space (&sl, &socket, m, nx, ny, ax, ay, 2)) 2122 if (update_space (sl, socket, m, nx, ny, ax, ay, 2))
2152 mask |= 0x4; 2123 mask |= 0x4;
2153 2124
2154 if (socket.EMI_smooth) 2125 if (socket.EMI_smooth)
2155 if (update_smooth (&esl, &socket, m, nx, ny, ax, ay, 2)) 2126 if (update_smooth (esl, socket, m, nx, ny, ax, ay, 2))
2156 emask |= 0x4; 2127 emask |= 0x4;
2157 2128
2158 /* Middle face */ 2129 /* Middle face */
2159 if (update_space (&sl, &socket, m, nx, ny, ax, ay, 1)) 2130 if (update_space (sl, socket, m, nx, ny, ax, ay, 1))
2160 mask |= 0x2; 2131 mask |= 0x2;
2161 2132
2162 if (socket.EMI_smooth) 2133 if (socket.EMI_smooth)
2163 if (update_smooth (&esl, &socket, m, nx, ny, ax, ay, 1)) 2134 if (update_smooth (esl, socket, m, nx, ny, ax, ay, 1))
2164 emask |= 0x2; 2135 emask |= 0x2;
2165 2136
2166 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))
2167 { 2138 {
2168 if (lastcell.faces[0] != pl->face->number) 2139 if (lastcell.faces[0] != pl->face->number)
2169 { 2140 {
2170 lastcell.faces[0] = pl->face->number; 2141 lastcell.faces[0] = pl->face->number;
2171 mask |= 0x1; 2142 mask |= 0x1;
2143
2172 if (!(socket.faces_sent[pl->face->number] & NS_FACESENT_FACE)) 2144 if (!(socket.faces_sent[pl->face->number] & NS_FACESENT_FACE))
2173 esrv_send_face (&socket, pl->face->number, 0); 2145 esrv_send_face (&socket, pl->face->number, 0);
2174 SockList_AddShort (&sl, pl->face->number); 2146
2147 sl << uint16 (pl->face->number);
2175 } 2148 }
2176 } 2149 }
2177 /* Top face */
2178 else 2150 else
2179 { 2151 {
2152 /* Top face */
2180 if (update_space (&sl, &socket, m, nx, ny, ax, ay, 0)) 2153 if (update_space (sl, socket, m, nx, ny, ax, ay, 0))
2181 mask |= 0x1; 2154 mask |= 0x1;
2155
2182 if (socket.EMI_smooth) 2156 if (socket.EMI_smooth)
2183 if (update_smooth (&esl, &socket, m, nx, ny, ax, ay, 0)) 2157 if (update_smooth (esl, socket, m, nx, ny, ax, ay, 0))
2184 {
2185 emask |= 0x1; 2158 emask |= 0x1;
2186 }
2187 } 2159 }
2160
2188 /* 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
2189 * space by checking the mask. If so, update the mask. 2162 * space by checking the mask. If so, update the mask.
2190 * 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
2191 * value, so we don't send those bits. 2164 * value, so we don't send those bits.
2192 */ 2165 */
2193 if (mask & 0xf) 2166 if (mask & 0xf)
2194 {
2195 sl.buf[oldlen + 1] = mask & 0xff; 2167 sl.buf[oldlen + 1] = mask & 0xff;
2196 }
2197 else 2168 else
2198 {
2199 sl.len = oldlen; 2169 sl.len = oldlen;
2200 } 2170
2201 if (emask & 0xf) 2171 if (emask & 0xf)
2202 {
2203 esl.buf[eoldlen + 1] = emask & 0xff; 2172 esl.buf[eoldlen + 1] = emask & 0xff;
2204 }
2205 else 2173 else
2206 {
2207 esl.len = eoldlen; 2174 esl.len = eoldlen;
2208 }
2209 } /* else this is a viewable space */ 2175 } /* else this is a viewable space */
2210 } /* for x loop */ 2176 } /* for x loop */
2211 } /* for y loop */ 2177 } /* for y loop */
2212 2178
2213 /* Verify that we in fact do need to send this */ 2179 /* Verify that we in fact do need to send this */
2222 esl.buf[ewhatstart + 1] = ewhatflag & 0xff; 2188 esl.buf[ewhatstart + 1] = ewhatflag & 0xff;
2223 } 2189 }
2224 2190
2225 if (esl.len > estartlen) 2191 if (esl.len > estartlen)
2226 Send_With_Handling (&socket, &esl); 2192 Send_With_Handling (&socket, &esl);
2227
2228 free (esl.buf);
2229 } 2193 }
2230 2194
2231 if (sl.len > startlen || socket.sent_scroll) 2195 if (sl.len > startlen || socket.sent_scroll)
2232 { 2196 {
2233 Send_With_Handling (&socket, &sl); 2197 Send_With_Handling (&socket, &sl);
2234 socket.sent_scroll = 0; 2198 socket.sent_scroll = 0;
2235 } 2199 }
2236 2200
2237 free (sl.buf); 2201 sl.free ();
2202 esl.free ();
2238} 2203}
2239 2204
2240/** 2205/**
2241 * Draws client map. 2206 * Draws client map.
2242 */ 2207 */
2247 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 */
2248 New_Face *face, *floor; 2213 New_Face *face, *floor;
2249 New_Face *floor2; 2214 New_Face *floor2;
2250 int d, mflags; 2215 int d, mflags;
2251 struct Map newmap; 2216 struct Map newmap;
2252 mapstruct *m, *pm; 2217 maptile *m, *pm;
2253 2218
2254 if (pl->type != PLAYER) 2219 if (pl->type != PLAYER)
2255 { 2220 {
2256 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");
2257 return; 2222 return;
2356 esrv_map_setbelow (&pl->contr->socket, ax, ay, floor->number, &newmap); 2321 esrv_map_setbelow (&pl->contr->socket, ax, ay, floor->number, &newmap);
2357 } 2322 }
2358 } /* Is a valid space */ 2323 } /* Is a valid space */
2359 } 2324 }
2360 } 2325 }
2326
2361 esrv_map_doneredraw (&pl->contr->socket, &newmap); 2327 esrv_map_doneredraw (&pl->contr->socket, &newmap);
2362 2328
2363 check_map_change (pl->contr); 2329 check_map_change (pl->contr);
2364} 2330}
2365 2331
2382/** 2348/**
2383 * This sends the skill number to name mapping. We ignore 2349 * This sends the skill number to name mapping. We ignore
2384 * the params - we always send the same info no matter what. 2350 * the params - we always send the same info no matter what.
2385 */ 2351 */
2386void 2352void
2387send_skill_info (NewSocket * ns, char *params) 2353send_skill_info (NewSocket *ns, char *params)
2388{ 2354{
2389 SockList sl; 2355 SockList sl (MAXSOCKBUF);
2390 int i; 2356 sl << "replyinfo skill_info\n";
2391 2357
2392 sl.buf = (unsigned char *) malloc (MAXSOCKBUF);
2393 strcpy ((char *) sl.buf, "replyinfo skill_info\n");
2394 for (i = 1; i < NUM_SKILLS; i++) 2358 for (int i = 1; i < NUM_SKILLS; i++)
2395 { 2359 sl.printf ("%d:%s\n", i + CS_STAT_SKILLINFO, &skill_names[i]);
2396 sprintf ((char *) sl.buf + strlen ((char *) sl.buf), "%d:%s\n", i + CS_STAT_SKILLINFO, &skill_names[i]); 2360
2397 }
2398 sl.len = strlen ((char *) sl.buf);
2399 if (sl.len >= MAXSOCKBUF) 2361 if (sl.len >= MAXSOCKBUF)
2400 { 2362 {
2401 LOG (llevError, "Buffer overflow in send_skill_info!\n"); 2363 LOG (llevError, "Buffer overflow in send_skill_info!\n");
2402 fatal (0); 2364 fatal (0);
2403 } 2365 }
2366
2404 Send_With_Handling (ns, &sl); 2367 Send_With_Handling (ns, &sl);
2405 free (sl.buf); 2368 sl.free ();
2406} 2369}
2407 2370
2408/** 2371/**
2409 * This sends the spell path to name mapping. We ignore 2372 * This sends the spell path to name mapping. We ignore
2410 * the params - we always send the same info no matter what. 2373 * the params - we always send the same info no matter what.
2411 */ 2374 */
2412void 2375void
2413send_spell_paths (NewSocket * ns, char *params) 2376send_spell_paths (NewSocket * ns, char *params)
2414{ 2377{
2415 SockList sl; 2378 SockList sl (MAXSOCKBUF);
2416 int i;
2417 2379
2418 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 2380 sl << "replyinfo spell_paths\n";
2419 strcpy ((char *) sl.buf, "replyinfo spell_paths\n"); 2381
2420 for (i = 0; i < NRSPELLPATHS; i++) 2382 for (int i = 0; i < NRSPELLPATHS; i++)
2421 sprintf ((char *) sl.buf + strlen ((char *) sl.buf), "%d:%s\n", 1 << i, spellpathnames[i]); 2383 sl.printf ("%d:%s\n", 1 << i, spellpathnames[i]);
2422 sl.len = strlen ((char *) sl.buf); 2384
2423 if (sl.len >= MAXSOCKBUF) 2385 if (sl.len >= MAXSOCKBUF)
2424 { 2386 {
2425 LOG (llevError, "Buffer overflow in send_spell_paths!\n"); 2387 LOG (llevError, "Buffer overflow in send_spell_paths!\n");
2426 fatal (0); 2388 fatal (0);
2427 } 2389 }
2390
2428 Send_With_Handling (ns, &sl); 2391 Send_With_Handling (ns, &sl);
2429 free (sl.buf); 2392 sl.free ();
2430} 2393}
2431 2394
2432/** 2395/**
2433 * 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.
2434 * 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
2435 */ 2398 */
2436void 2399void
2437esrv_update_spells (player *pl) 2400esrv_update_spells (player *pl)
2438{ 2401{
2439 SockList sl;
2440 int flags = 0;
2441 object *spell;
2442
2443 if (!pl->socket.monitor_spells) 2402 if (!pl->socket.monitor_spells)
2444 return; 2403 return;
2404
2445 for (spell = pl->ob->inv; spell != NULL; spell = spell->below) 2405 for (object *spell = pl->ob->inv; spell; spell = spell->below)
2446 { 2406 {
2447 if (spell->type == SPELL) 2407 if (spell->type == SPELL)
2448 { 2408 {
2409 int flags = 0;
2410
2449 /* check if we need to update it */ 2411 /* check if we need to update it */
2450 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))
2451 { 2413 {
2452 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);
2453 flags |= UPD_SP_MANA; 2415 flags |= UPD_SP_MANA;
2454 } 2416 }
2417
2455 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))
2456 { 2419 {
2457 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);
2458 flags |= UPD_SP_GRACE; 2421 flags |= UPD_SP_GRACE;
2459 } 2422 }
2423
2460 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))
2461 { 2425 {
2462 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);
2463 flags |= UPD_SP_DAMAGE; 2427 flags |= UPD_SP_DAMAGE;
2464 } 2428 }
2429
2465 if (flags != 0) 2430 if (flags)
2466 { 2431 {
2467 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 2432 SockList sl (MAXSOCKBUF);
2468 strcpy ((char *) sl.buf, "updspell "); 2433
2469 sl.len = strlen ((char *) sl.buf); 2434 sl << "updspell "
2470 SockList_AddChar (&sl, flags); 2435 << uint8 (flags)
2471 SockList_AddInt (&sl, spell->count); 2436 << uint32 (spell->count);
2472 if (flags & UPD_SP_MANA) 2437
2473 SockList_AddShort (&sl, spell->last_sp); 2438 if (flags & UPD_SP_MANA ) sl << uint16 (spell->last_sp);
2474 if (flags & UPD_SP_GRACE) 2439 if (flags & UPD_SP_GRACE ) sl << uint16 (spell->last_grace);
2475 SockList_AddShort (&sl, spell->last_grace); 2440 if (flags & UPD_SP_DAMAGE) sl << uint16 (spell->last_eat);
2476 if (flags & UPD_SP_DAMAGE) 2441
2477 SockList_AddShort (&sl, spell->last_eat);
2478 flags = 0;
2479 Send_With_Handling (&pl->socket, &sl); 2442 Send_With_Handling (&pl->socket, &sl);
2480 free (sl.buf); 2443 sl.free ();
2481 } 2444 }
2482 } 2445 }
2483 } 2446 }
2484} 2447}
2485 2448
2486void 2449void
2487esrv_remove_spell (player *pl, object *spell) 2450esrv_remove_spell (player *pl, object *spell)
2488{ 2451{
2489 SockList sl;
2490
2491 if (!pl->socket.monitor_spells) 2452 if (!pl->socket.monitor_spells)
2492 return; 2453 return;
2454
2493 if (!pl || !spell || spell->env != pl->ob) 2455 if (!pl || !spell || spell->env != pl->ob)
2494 { 2456 {
2495 LOG (llevError, "Invalid call to esrv_remove_spell"); 2457 LOG (llevError, "Invalid call to esrv_remove_spell");
2496 return; 2458 return;
2497 } 2459 }
2498 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 2460
2499 strcpy ((char *) sl.buf, "delspell "); 2461 SockList sl (MAXSOCKBUF);
2500 sl.len = strlen ((char *) sl.buf); 2462
2501 SockList_AddInt (&sl, spell->count); 2463 sl << "delspell "
2464 << uint32 (spell->count);
2465
2502 Send_With_Handling (&pl->socket, &sl); 2466 Send_With_Handling (&pl->socket, &sl);
2503 free (sl.buf); 2467 sl.free ();
2504} 2468}
2505 2469
2506/* 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. */
2507static void 2471static void
2508append_spell (player *pl, SockList * sl, object *spell) 2472append_spell (player *pl, SockList &sl, object *spell)
2509{ 2473{
2510 int len, i, skill = 0; 2474 int len, i, skill = 0;
2511 2475
2512 if (!(spell->name)) 2476 if (!(spell->name))
2513 { 2477 {
2514 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);
2515 return; 2479 return;
2516 } 2480 }
2517 SockList_AddInt (sl, spell->count); 2481
2518 SockList_AddShort (sl, spell->level);
2519 SockList_AddShort (sl, spell->casting_time);
2520 /* 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 */
2521 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);
2522 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);
2523 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);
2524 /* send the current values */
2525 SockList_AddShort (sl, spell->last_sp);
2526 SockList_AddShort (sl, spell->last_grace);
2527 SockList_AddShort (sl, spell->last_eat);
2528 2486
2529 /* figure out which skill it uses, if it uses one */ 2487 /* figure out which skill it uses, if it uses one */
2530 if (spell->skill) 2488 if (spell->skill)
2531 { 2489 {
2532 for (i = 1; i < NUM_SKILLS; i++) 2490 for (i = 1; i < NUM_SKILLS; i++)
2534 { 2492 {
2535 skill = i + CS_STAT_SKILLINFO; 2493 skill = i + CS_STAT_SKILLINFO;
2536 break; 2494 break;
2537 } 2495 }
2538 } 2496 }
2539 SockList_AddChar (sl, skill);
2540 2497
2541 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)
2542 SockList_AddInt (sl, (spell->face) ? spell->face->number : 0); 2507 << uint32 (spell->face ? spell->face->number : 0)
2543 2508 << data8 (spell->name)
2544 len = strlen (spell->name); 2509 << data16 (spell->msg);
2545 SockList_AddChar (sl, (char) len);
2546 memcpy (sl->buf + sl->len, spell->name, len);
2547 sl->len += len;
2548
2549 if (!spell->msg)
2550 {
2551 SockList_AddShort (sl, 0);
2552 }
2553 else
2554 {
2555 len = strlen (spell->msg);
2556 SockList_AddShort (sl, len);
2557 memcpy (sl->buf + sl->len, spell->msg, len);
2558 sl->len += len;
2559 }
2560} 2510}
2561 2511
2562/** 2512/**
2563 * 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
2564 * all spells in the player's inventory. 2514 * all spells in the player's inventory.
2565 */ 2515 */
2566void 2516void
2567esrv_add_spells (player *pl, object *spell) 2517esrv_add_spells (player *pl, object *spell)
2568{ 2518{
2569 SockList sl;
2570
2571 if (!pl) 2519 if (!pl)
2572 { 2520 {
2573 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");
2574 return; 2522 return;
2575 } 2523 }
2524
2576 if (!pl->socket.monitor_spells) 2525 if (!pl->socket.monitor_spells)
2577 return; 2526 return;
2578 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 2527
2579 strcpy ((char *) sl.buf, "addspell "); 2528 SockList sl (MAXSOCKBUF);
2580 sl.len = strlen ((char *) sl.buf); 2529
2530 sl << "addspell ";
2531
2581 if (!spell) 2532 if (!spell)
2582 { 2533 {
2583 for (spell = pl->ob->inv; spell != NULL; spell = spell->below) 2534 for (spell = pl->ob->inv; spell != NULL; spell = spell->below)
2584 { 2535 {
2585 /* were we to simply keep appending data here, we could exceed 2536 /* were we to simply keep appending data here, we could exceed
2595 * 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
2596 * like it will fix this 2547 * like it will fix this
2597 */ 2548 */
2598 if (spell->type != SPELL) 2549 if (spell->type != SPELL)
2599 continue; 2550 continue;
2551
2600 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))))
2601 { 2553 {
2602 Send_With_Handling (&pl->socket, &sl); 2554 Send_With_Handling (&pl->socket, &sl);
2603 strcpy ((char *) sl.buf, "addspell "); 2555 strcpy ((char *) sl.buf, "addspell ");
2604 sl.len = strlen ((char *) sl.buf); 2556 sl.len = strlen ((char *) sl.buf);
2605 } 2557 }
2558
2606 append_spell (pl, &sl, spell); 2559 append_spell (pl, sl, spell);
2607 } 2560 }
2608 } 2561 }
2609 else if (spell->type != SPELL) 2562 else if (spell->type != SPELL)
2610 { 2563 {
2611 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");
2612 return; 2565 return;
2613 } 2566 }
2614 else 2567 else
2615 append_spell (pl, &sl, spell); 2568 append_spell (pl, sl, spell);
2569
2616 if (sl.len >= MAXSOCKBUF) 2570 if (sl.length () >= MAXSOCKBUF)
2617 { 2571 {
2618 LOG (llevError, "Buffer overflow in esrv_add_spells!\n"); 2572 LOG (llevError, "Buffer overflow in esrv_add_spells!\n");
2619 fatal (0); 2573 fatal (0);
2620 } 2574 }
2575
2621 /* finally, we can send the packet */ 2576 /* finally, we can send the packet */
2622 Send_With_Handling (&pl->socket, &sl); 2577 Send_With_Handling (&pl->socket, &sl);
2623 free (sl.buf); 2578
2579 sl.free ();
2624} 2580}
2581

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines