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.10 by root, Fri Aug 25 17:11:54 2006 UTC vs.
Revision 1.41 by root, Fri Dec 15 19:59:20 2006 UTC

1/*
2 * static char *rcsid_init_c =
3 * "$Id: request.C,v 1.10 2006/08/25 17:11:54 root Exp $";
4 */
5
6/* 1/*
7 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
8 3
9 Copyright (C) 2001 Mark Wedel 4 Copyright (C) 2001 Mark Wedel
10 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
21 16
22 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
23 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 20
26 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>
27*/ 22*/
28 23
29/** 24/**
30 * \file 25 * \file
31 * Client handling. 26 * Client handling.
46 * if a face has not already been sent to the client, it is sent now. 41 * if a face has not already been sent to the client, it is sent now.
47 * 42 *
48 * mapcellchanged, compactlayer, compactstack, perform the map compressing 43 * mapcellchanged, compactlayer, compactstack, perform the map compressing
49 * operations 44 * operations
50 * 45 *
51 * esrv_map_doneredraw finishes the map update, and ships across the
52 * map updates.
53 *
54 * esrv_map_scroll tells the client to scroll the map, and does similarily
55 * for the locally cached copy.
56 */ 46 */
57 47
58#include <global.h> 48#include <global.h>
59#include <sproto.h> 49#include <sproto.h>
60 50
61#include <newclient.h>
62#include <newserver.h>
63#include <living.h> 51#include <living.h>
64#include <commands.h> 52#include <commands.h>
65 53
66/* This block is basically taken from socket.c - I assume if it works there, 54/* This block is basically taken from socket.c - I assume if it works there,
67 * it should work here. 55 * it should work here.
68 */ 56 */
69#ifndef WIN32 /* ---win32 exclude unix headers */
70#include <sys/types.h> 57#include <sys/types.h>
71#include <sys/time.h> 58#include <sys/time.h>
72#include <sys/socket.h> 59#include <sys/socket.h>
73#include <netinet/in.h> 60#include <netinet/in.h>
74#include <netdb.h> 61#include <netdb.h>
75#endif /* win32 */
76 62
77#ifdef HAVE_UNISTD_H
78#include <unistd.h> 63#include <unistd.h>
79#endif
80
81#ifdef HAVE_SYS_TIME_H
82#include <sys/time.h> 64#include <sys/time.h>
83#endif
84 65
85#include "sounds.h" 66#include "sounds.h"
86 67
87/** 68/**
88 * This table translates the attack numbers as used within the 69 * This table translates the attack numbers as used within the
89 * program to the value we use when sending STATS command to the 70 * program to the value we use when sending STATS command to the
90 * client. If a value is -1, then we don't send that to the 71 * client. If a value is -1, then we don't send that to the
91 * client. 72 * client.
92 */ 73 */
93short atnr_cs_stat[NROFATTACKS] = {CS_STAT_RES_PHYS, 74short atnr_cs_stat[NROFATTACKS] = { CS_STAT_RES_PHYS,
94 CS_STAT_RES_MAG,CS_STAT_RES_FIRE, CS_STAT_RES_ELEC, 75 CS_STAT_RES_MAG, CS_STAT_RES_FIRE, CS_STAT_RES_ELEC,
95 CS_STAT_RES_COLD, CS_STAT_RES_CONF, CS_STAT_RES_ACID, 76 CS_STAT_RES_COLD, CS_STAT_RES_CONF, CS_STAT_RES_ACID,
96 CS_STAT_RES_DRAIN, -1 /* weaponmagic */, 77 CS_STAT_RES_DRAIN, -1 /* weaponmagic */ ,
97 CS_STAT_RES_GHOSTHIT, CS_STAT_RES_POISON, 78 CS_STAT_RES_GHOSTHIT, CS_STAT_RES_POISON,
98 CS_STAT_RES_SLOW, CS_STAT_RES_PARA, CS_STAT_TURN_UNDEAD, 79 CS_STAT_RES_SLOW, CS_STAT_RES_PARA, CS_STAT_TURN_UNDEAD,
99 CS_STAT_RES_FEAR, -1 /* Cancellation */, 80 CS_STAT_RES_FEAR, -1 /* Cancellation */ ,
100 CS_STAT_RES_DEPLETE, CS_STAT_RES_DEATH, 81 CS_STAT_RES_DEPLETE, CS_STAT_RES_DEATH,
101 -1 /* Chaos */, -1 /* Counterspell */, 82 -1 /* Chaos */ , -1 /* Counterspell */ ,
102 -1 /* Godpower */, CS_STAT_RES_HOLYWORD, 83 -1 /* Godpower */ , CS_STAT_RES_HOLYWORD,
103 CS_STAT_RES_BLIND, 84 CS_STAT_RES_BLIND,
104 -1, /* Internal */ 85 -1, /* Internal */
105 -1, /* life stealing */ 86 -1, /* life stealing */
106 -1 /* Disease - not fully done yet */ 87 -1 /* Disease - not fully done yet */
107}; 88};
108 89
109static void 90static void
110socket_map_scroll (NewSocket *ns, int dx, int dy) 91socket_map_scroll (client * ns, int dx, int dy)
111{ 92{
112 struct Map newmap; 93 struct Map newmap;
113 int x,y, mx, my; 94 int x, y, mx, my;
114 95
115 { 96 {
116 char buf[MAXSOCKBUF]; 97 packet sl;
117 98
118 sprintf(buf,"map_scroll %d %d", dx, dy); 99 sl.printf ("map_scroll %d %d", dx, dy);
119 Write_String_To_Socket(ns, buf, strlen (buf)); 100 ns->send_packet (sl);
120 } 101 }
121 102
122 /* If we are using the Map1aCmd, we may in fact send 103 /* If we are using the Map1aCmd, we may in fact send
123 * head information that is outside the viewable map. 104 * head information that is outside the viewable map.
124 * So set the mx,my to the max value we want to 105 * So set the mx,my to the max value we want to
125 * look for. Removed code to do so - it caused extra 106 * look for. Removed code to do so - it caused extra
126 * complexities for the client, and probably doesn't make 107 * complexities for the client, and probably doesn't make
127 * that much difference in bandwidth. 108 * that much difference in bandwidth.
128 */ 109 */
129 mx = ns->mapx; 110 mx = ns->mapx;
130 my = ns->mapy; 111 my = ns->mapy;
131 112
132 if (ns->mapmode == Map1aCmd) { 113 if (ns->mapmode == Map1aCmd)
114 {
133 mx += MAX_HEAD_OFFSET; 115 mx += MAX_HEAD_OFFSET;
134 my += MAX_HEAD_OFFSET; 116 my += MAX_HEAD_OFFSET;
135 } 117 }
136 118
137 /* the x and y here are coordinates for the new map, i.e. if we moved 119 /* the x and y here are coordinates for the new map, i.e. if we moved
138 * (dx,dy), newmap[x][y] = oldmap[x-dx][y-dy]. For this reason, 120 * (dx,dy), newmap[x][y] = oldmap[x-dx][y-dy]. For this reason,
139 * if the destination x or y coordinate is outside the viewable 121 * if the destination x or y coordinate is outside the viewable
140 * area, we clear the values - otherwise, the old values 122 * area, we clear the values - otherwise, the old values
141 * are preserved, and the check_head thinks it needs to clear them. 123 * are preserved, and the check_head thinks it needs to clear them.
142 */ 124 */
143 for(x=0; x<mx; x++) { 125 for (x = 0; x < mx; x++)
144 for(y=0; y<my; y++) { 126 {
127 for (y = 0; y < my; y++)
128 {
145 if(x >= ns->mapx || y >= ns->mapy) { 129 if (x >= ns->mapx || y >= ns->mapy)
146 /* clear cells outside the viewable area */ 130 /* clear cells outside the viewable area */
147 memset(&newmap.cells[x][y], 0, sizeof(struct MapCell)); 131 memset (&newmap.cells[x][y], 0, sizeof (struct MapCell));
148 }
149 else if ((x+dx) < 0 || (x+dx) >= ns->mapx || (y+dy) < 0 || (y + dy) >= ns->mapy) { 132 else if ((x + dx) < 0 || (x + dx) >= ns->mapx || (y + dy) < 0 || (y + dy) >= ns->mapy)
150 /* clear newly visible tiles within the viewable area */ 133 /* clear newly visible tiles within the viewable area */
151 memset(&(newmap.cells[x][y]), 0, sizeof(struct MapCell)); 134 memset (&(newmap.cells[x][y]), 0, sizeof (struct MapCell));
135 else
136 memcpy (&(newmap.cells[x][y]), &(ns->lastmap.cells[x + dx][y + dy]), sizeof (struct MapCell));
137 }
152 } 138 }
153 else {
154 memcpy(&(newmap.cells[x][y]),
155 &(ns->lastmap.cells[x+dx][y+dy]),sizeof(struct MapCell));
156 }
157 }
158 }
159 139
160 memcpy(&(ns->lastmap), &newmap,sizeof(struct Map)); 140 memcpy (&(ns->lastmap), &newmap, sizeof (struct Map));
161 141
162 /* Make sure that the next "map1" command will be sent (even if it is 142 /* Make sure that the next "map1" command will be sent (even if it is
163 * empty). 143 * empty).
164 */ 144 */
165 ns->sent_scroll = 1; 145 ns->sent_scroll = 1;
166} 146}
167 147
168static void 148static void
169clear_map (player *pl) 149clear_map (player *pl)
170{ 150{
171 NewSocket &socket = pl->socket; 151 client &socket = *pl->socket;
172 152
173 memset (&socket.lastmap, 0, sizeof (socket.lastmap)); 153 memset (&socket.lastmap, 0, sizeof (socket.lastmap));
174 154
175 if (socket.newmapcmd == 1) 155 if (socket.newmapcmd == 1)
176 Write_String_To_Socket (&socket, "newmap", 6); 156 socket.send_packet ("newmap");
177 157
178 socket.update_look = 1; 158 socket.update_look = 1;
179 socket.look_position = 0; 159 socket.look_position = 0;
180} 160}
181 161
182/** check for map change and send new map data */ 162/** check for map change and send new map data */
183static void 163static void
184check_map_change (player *pl) 164check_map_change (player *pl)
185{ 165{
186 NewSocket &socket = pl->socket; 166 client &socket = *pl->socket;
187 object *ob = pl->ob; 167 object *ob = pl->ob;
188 char buf[MAX_BUF]; /* eauugggh */ 168 char buf[MAX_BUF]; /* eauugggh */
189 169
190 if (socket.current_map != ob->map) 170 if (socket.current_map != ob->map)
191 { 171 {
192 socket.current_map = ob->map; 172 socket.current_map = ob->map;
193 173
194 clear_map (pl); 174 clear_map (pl);
195 175
196 if (socket.mapinfocmd) 176 if (socket.mapinfocmd)
197 { 177 {
198 if (ob->map && ob->map->path [0]) 178 if (ob->map && ob->map->path[0])
199 { 179 {
200 int flags = 0; 180 int flags = 0;
201 181
202 if (ob->map->tile_path [0]) flags |= 1; 182 if (ob->map->tile_path[0])
183 flags |= 1;
203 if (ob->map->tile_path [1]) flags |= 2; 184 if (ob->map->tile_path[1])
185 flags |= 2;
204 if (ob->map->tile_path [2]) flags |= 4; 186 if (ob->map->tile_path[2])
187 flags |= 4;
205 if (ob->map->tile_path [3]) flags |= 8; 188 if (ob->map->tile_path[3])
189 flags |= 8;
206 190
207 snprintf (buf, MAX_BUF, "mapinfo - spatial %d %d %d %d %d %s", 191 snprintf (buf, MAX_BUF, "mapinfo - spatial %d %d %d %d %d %s",
208 flags, socket.mapx / 2 - ob->x, socket.mapy / 2 - ob->y, 192 flags, socket.mapx / 2 - ob->x, socket.mapy / 2 - ob->y, ob->map->width, ob->map->height, ob->map->path);
209 ob->map->width, ob->map->height, ob->map->path);
210 } 193 }
211 else 194 else
212 snprintf (buf, MAX_BUF, "mapinfo current"); 195 snprintf (buf, MAX_BUF, "mapinfo current");
213 196
214 Write_String_To_Socket (&socket, buf, strlen (buf)); 197 socket.send_packet (buf);
215 } 198 }
216 } 199 }
217 else if (socket.current_x != ob->x || socket.current_y != ob->y) 200 else if (socket.current_x != ob->x || socket.current_y != ob->y)
218 { 201 {
219 int dx = ob->x - socket.current_x; 202 int dx = ob->x - socket.current_x;
220 int dy = ob->y - socket.current_y; 203 int dy = ob->y - socket.current_y;
221 204
222 if (socket.buggy_mapscroll && (abs (dx) > 8 || abs (dy) > 8)) 205 if (socket.buggy_mapscroll && (abs (dx) > 8 || abs (dy) > 8))
223 clear_map (pl); // current (<= 1.9.1) clients have unchecked buffer overflows 206 clear_map (pl); // current (<= 1.9.1) clients have unchecked buffer overflows
224 else 207 else
225 { 208 {
226 socket_map_scroll (&socket, ob->x - socket.current_x, ob->y - socket.current_y); 209 socket_map_scroll (&socket, ob->x - socket.current_x, ob->y - socket.current_y);
227 socket.update_look = 1; 210 socket.update_look = 1;
228 socket.look_position = 0; 211 socket.look_position = 0;
231 214
232 socket.current_x = ob->x; 215 socket.current_x = ob->x;
233 socket.current_y = ob->y; 216 socket.current_y = ob->y;
234} 217}
235 218
219/**
220 * RequestInfo is sort of a meta command. There is some specific
221 * request of information, but we call other functions to provide
222 * that information.
223 */
224void
225RequestInfo (char *buf, int len, client * ns)
226{
227 char *params = NULL, *cp;
228
229 /* No match */
230 char bigbuf[MAX_BUF];
231 int slen;
232
233 /* Set up replyinfo before we modify any of the buffers - this is used
234 * if we don't find a match.
235 */
236 strcpy (bigbuf, "replyinfo ");
237 slen = strlen (bigbuf);
238 safe_strcat (bigbuf, buf, &slen, MAX_BUF);
239
240 /* find the first space, make it null, and update the
241 * params pointer.
242 */
243 for (cp = buf; *cp != '\0'; cp++)
244 if (*cp == ' ')
245 {
246 *cp = '\0';
247 params = cp + 1;
248 break;
249 }
250
251 if (!strcmp (buf, "image_info"))
252 send_image_info (ns, params);
253 else if (!strcmp (buf, "image_sums"))
254 send_image_sums (ns, params);
255 else if (!strcmp (buf, "skill_info"))
256 send_skill_info (ns, params);
257 else if (!strcmp (buf, "spell_paths"))
258 send_spell_paths (ns, params);
259 else
260 ns->send_packet (bigbuf, len);
261}
262
263void
236void ExtCmd (char *buf, int len, player *pl) 264ExtCmd (char *buf, int len, player *pl)
237{ 265{
238 INVOKE_PLAYER (EXTCMD, pl, ARG_DATA (buf, len)); 266 INVOKE_PLAYER (EXTCMD, pl, ARG_DATA (buf, len));
239} 267}
240 268
269void
241void MapInfoCmd (char *buf, int len, player *pl) 270MapInfoCmd (char *buf, int len, player *pl)
242{ 271{
243 // <mapinfo tag spatial tile-path 272 // <mapinfo tag spatial tile-path
244 // >mapinfo tag spatial flags x y w h hash 273 // >mapinfo tag spatial flags x y w h hash
245 274
246 char bigbuf[MAX_BUF], *cp, *token; 275 char bigbuf[MAX_BUF], *token;
247 276
248 token = buf; 277 token = buf;
249 // copy token 278 // copy token
250 if (!(buf = strchr (buf, ' '))) 279 if (!(buf = strchr (buf, ' ')))
251 return; 280 return;
255 if (!strncmp (buf, "spatial ", 8)) 284 if (!strncmp (buf, "spatial ", 8))
256 { 285 {
257 buf += 8; 286 buf += 8;
258 287
259 // initial map and its origin 288 // initial map and its origin
260 mapstruct *map = pl->ob->map; 289 maptile *map = pl->ob->map;
261 sint16 dx, dy; 290 sint16 dx, dy;
262 int mapx = pl->socket.mapx / 2 - pl->ob->x; 291 int mapx = pl->socket->mapx / 2 - pl->ob->x;
263 int mapy = pl->socket.mapy / 2 - pl->ob->y; 292 int mapy = pl->socket->mapy / 2 - pl->ob->y;
264 int max_distance = 8; // limit maximum path length to something generous 293 int max_distance = 8; // limit maximum path length to something generous
265 294
266 while (*buf && map && max_distance) 295 while (*buf && map && max_distance)
267 { 296 {
268 int dir = *buf++; 297 int dir = *buf++;
269 298
270 switch (dir) 299 switch (dir)
271 { 300 {
272 case '1': 301 case '1':
302 dx = 0;
303 dy = -1;
273 dx = 0; dy = -1; map = get_map_from_coord (map, &dx, &dy); 304 map = get_map_from_coord (map, &dx, &dy);
274 map && (mapy -= map->height); 305 map && (mapy -= map->height);
275 break; 306 break;
276 case '2': 307 case '2':
277 mapx += map->width; 308 mapx += map->width;
309 dx = map->width;
310 dy = 0;
278 dx = map->width; dy = 0; map = get_map_from_coord (map, &dx, &dy); 311 map = get_map_from_coord (map, &dx, &dy);
279 break; 312 break;
280 case '3': 313 case '3':
281 mapy += map->height; 314 mapy += map->height;
315 dx = 0;
316 dy = map->height;
282 dx = 0; dy = map->height; map = get_map_from_coord (map, &dx, &dy); 317 map = get_map_from_coord (map, &dx, &dy);
283 break; 318 break;
284 case '4': 319 case '4':
320 dx = -1;
321 dy = 0;
285 dx = -1; dy = 0; map = get_map_from_coord (map, &dx, &dy); 322 map = get_map_from_coord (map, &dx, &dy);
286 map && (mapx -= map->width); 323 map && (mapx -= map->width);
287 break; 324 break;
288 } 325 }
289 326
290 --max_distance; 327 --max_distance;
291 } 328 }
292 329
293 if (!max_distance) 330 if (!max_distance)
294 snprintf (bigbuf, MAX_BUF, "mapinfo %s error", token); 331 snprintf (bigbuf, MAX_BUF, "mapinfo %s error", token);
295 else if (map && map->path [0]) 332 else if (map && map->path[0])
296 { 333 {
297 int flags = 0; 334 int flags = 0;
298 335
299 if (map->tile_path [0]) flags |= 1; 336 if (map->tile_path[0])
337 flags |= 1;
300 if (map->tile_path [1]) flags |= 2; 338 if (map->tile_path[1])
339 flags |= 2;
301 if (map->tile_path [2]) flags |= 4; 340 if (map->tile_path[2])
341 flags |= 4;
302 if (map->tile_path [3]) flags |= 8; 342 if (map->tile_path[3])
343 flags |= 8;
303 344
304 snprintf (bigbuf, MAX_BUF, "mapinfo %s spatial %d %d %d %d %d %s", 345 snprintf (bigbuf, MAX_BUF, "mapinfo %s spatial %d %d %d %d %d %s", token, flags, mapx, mapy, map->width, map->height, map->path);
305 token, flags, mapx, mapy,
306 map->width, map->height, map->path);
307 } 346 }
308 else 347 else
309 snprintf (bigbuf, MAX_BUF, "mapinfo %s nomap", token); 348 snprintf (bigbuf, MAX_BUF, "mapinfo %s nomap", token);
310 } 349 }
311 else 350 else
312 snprintf (bigbuf, MAX_BUF, "mapinfo %s unsupported", token); 351 snprintf (bigbuf, MAX_BUF, "mapinfo %s unsupported", token);
313 352
314 Write_String_To_Socket (&pl->socket, bigbuf, strlen (bigbuf)); 353 pl->socket->send_packet (bigbuf);
315} 354}
316 355
317/** This is the Setup cmd - easy first implementation */ 356/** This is the Setup cmd - easy first implementation */
357void
318void SetUp(char *buf, int len, NewSocket *ns) 358SetUp (char *buf, int len, client * ns)
319{ 359{
320 int s, slen; 360 int s, slen;
321 char *cmd, *param, cmdback[HUGE_BUF]; 361 char *cmd, *param, cmdback[HUGE_BUF];
322 362
323 /* run through the cmds of setup 363 /* run through the cmds of setup
324 * syntax is setup <cmdname1> <parameter> <cmdname2> <parameter> ... 364 * syntax is setup <cmdname1> <parameter> <cmdname2> <parameter> ...
325 * 365 *
326 * we send the status of the cmd back, or a FALSE is the cmd is the server unknown 366 * we send the status of the cmd back, or a FALSE is the cmd is the server unknown
327 * The client then must sort this out 367 * The client then must sort this out
328 */ 368 */
329 369
330 LOG(llevInfo,"Get SetupCmd:: %s\n", buf); 370 //LOG (llevInfo, "Get SetupCmd:: %s\n", buf);
371
331 strcpy(cmdback,"setup"); 372 strcpy (cmdback, "setup");
332 for(s=0;s<len; ) { 373 for (s = 0; s < len; )
333 374 {
334 cmd = &buf[s]; 375 cmd = &buf[s];
335 376
336 /* find the next space, and put a null there */ 377 /* find the next space, and put a null there */
337 for(;buf[s] && buf[s] != ' ';s++) ; 378 for (; buf[s] && buf[s] != ' '; s++)
338 buf[s++]=0; 379 ;
380
381 buf[s++] = 0;
382
339 while (buf[s] == ' ') s++; 383 while (buf[s] == ' ')
384 s++;
340 385
341 if(s>=len) 386 if (s >= len)
342 break; 387 break;
343 388
344 param = &buf[s]; 389 param = &buf[s];
345 390
346 for(;buf[s] && buf[s] != ' ';s++) ; 391 for (; buf[s] && buf[s] != ' '; s++)
347 buf[s++]=0; 392 ;
393
394 buf[s++] = 0;
395
348 while (buf[s] == ' ') s++; 396 while (buf[s] == ' ')
349 397 s++;
398
350 slen = strlen(cmdback); 399 slen = strlen (cmdback);
351 safe_strcat(cmdback, " ", &slen, HUGE_BUF); 400 safe_strcat (cmdback, " ", &slen, HUGE_BUF);
352 safe_strcat(cmdback, cmd, &slen, HUGE_BUF); 401 safe_strcat (cmdback, cmd, &slen, HUGE_BUF);
353 safe_strcat(cmdback, " ", &slen, HUGE_BUF); 402 safe_strcat (cmdback, " ", &slen, HUGE_BUF);
354 403
355 if (!strcmp(cmd,"sound")) { 404 if (!strcmp (cmd, "sound"))
405 {
356 ns->sound = atoi(param); 406 ns->sound = atoi (param);
357 safe_strcat(cmdback, param, &slen, HUGE_BUF); 407 safe_strcat (cmdback, param, &slen, HUGE_BUF);
358 } 408 }
359 else if (!strcmp(cmd,"exp64")) { 409 else if (!strcmp (cmd, "exp64"))
410 {
360 ns->exp64 = atoi(param); 411 ns->exp64 = atoi (param);
361 safe_strcat(cmdback, param, &slen, HUGE_BUF); 412 safe_strcat (cmdback, param, &slen, HUGE_BUF);
413 }
362 } else if (!strcmp(cmd, "spellmon")) { 414 else if (!strcmp (cmd, "spellmon"))
415 {
363 ns->monitor_spells = atoi(param); 416 ns->monitor_spells = atoi (param);
364 safe_strcat(cmdback, param, &slen, HUGE_BUF); 417 safe_strcat (cmdback, param, &slen, HUGE_BUF);
418 }
365 } else if (!strcmp(cmd,"darkness")) { 419 else if (!strcmp (cmd, "darkness"))
420 {
366 ns->darkness = atoi(param); 421 ns->darkness = atoi (param);
367 safe_strcat(cmdback, param, &slen, HUGE_BUF); 422 safe_strcat (cmdback, param, &slen, HUGE_BUF);
423 }
368 } else if (!strcmp(cmd,"map1cmd")) { 424 else if (!strcmp (cmd, "map1cmd"))
369 if (atoi(param)) ns->mapmode = Map1Cmd; 425 {
426 if (atoi (param))
427 ns->mapmode = Map1Cmd;
370 /* if beyond this size, need to use map1cmd no matter what */ 428 /* if beyond this size, need to use map1cmd no matter what */
371 if (ns->mapx>11 || ns->mapy>11) ns->mapmode = Map1Cmd; 429 if (ns->mapx > 11 || ns->mapy > 11)
430 ns->mapmode = Map1Cmd;
372 safe_strcat(cmdback, ns->mapmode == Map1Cmd?"1":"0", &slen, HUGE_BUF); 431 safe_strcat (cmdback, ns->mapmode == Map1Cmd ? "1" : "0", &slen, HUGE_BUF);
432 }
373 } else if (!strcmp(cmd,"map1acmd")) { 433 else if (!strcmp (cmd, "map1acmd"))
374 if (atoi(param)) ns->mapmode = Map1aCmd; 434 {
435 if (atoi (param))
436 ns->mapmode = Map1aCmd;
375 /* if beyond this size, need to use map1acmd no matter what */ 437 /* if beyond this size, need to use map1acmd no matter what */
376 if (ns->mapx>11 || ns->mapy>11) ns->mapmode = Map1aCmd; 438 if (ns->mapx > 11 || ns->mapy > 11)
439 ns->mapmode = Map1aCmd;
377 safe_strcat(cmdback, ns->mapmode == Map1aCmd?"1":"0", &slen, HUGE_BUF); 440 safe_strcat (cmdback, ns->mapmode == Map1aCmd ? "1" : "0", &slen, HUGE_BUF);
441 }
378 } else if (!strcmp(cmd,"newmapcmd")) { 442 else if (!strcmp (cmd, "newmapcmd"))
443 {
379 ns->newmapcmd= atoi(param); 444 ns->newmapcmd = atoi (param);
380 safe_strcat(cmdback, param, &slen, HUGE_BUF); 445 safe_strcat (cmdback, param, &slen, HUGE_BUF);
381// } else if (!strcmp(cmd,"plugincmd")) { 446// } else if (!strcmp(cmd,"plugincmd")) {
382// ns->plugincmd = atoi(param); 447// ns->plugincmd = atoi(param);
383// safe_strcat(cmdback, param, &slen, HUGE_BUF); 448// safe_strcat(cmdback, param, &slen, HUGE_BUF);
449 }
384 } else if (!strcmp(cmd,"mapinfocmd")) { 450 else if (!strcmp (cmd, "mapinfocmd"))
451 {
385 ns->mapinfocmd = atoi(param); 452 ns->mapinfocmd = atoi (param);
386 safe_strcat(cmdback, "1", &slen, HUGE_BUF); 453 safe_strcat (cmdback, "1", &slen, HUGE_BUF);
454 }
387 } else if (!strcmp(cmd,"extcmd")) { 455 else if (!strcmp (cmd, "extcmd"))
456 {
388 ns->extcmd = atoi(param); 457 ns->extcmd = atoi (param);
389 safe_strcat(cmdback, "1", &slen, HUGE_BUF); 458 safe_strcat (cmdback, "1", &slen, HUGE_BUF);
459 }
390 } else if (!strcmp(cmd,"extmap")) { 460 else if (!strcmp (cmd, "extmap"))
461 {
391 ns->extmap = atoi(param); 462 ns->extmap = atoi (param);
392 safe_strcat(cmdback, "1", &slen, HUGE_BUF); 463 safe_strcat (cmdback, "1", &slen, HUGE_BUF);
464 }
393 } else if (!strcmp(cmd,"facecache")) { 465 else if (!strcmp (cmd, "facecache"))
466 {
394 ns->facecache = atoi(param); 467 ns->facecache = atoi (param);
395 safe_strcat(cmdback, param, &slen, HUGE_BUF); 468 safe_strcat (cmdback, param, &slen, HUGE_BUF);
469 }
396 } else if (!strcmp(cmd,"faceset")) { 470 else if (!strcmp (cmd, "faceset"))
471 {
397 char tmpbuf[20]; 472 char tmpbuf[20];
398 int q = atoi(param); 473 int q = atoi (param);
399 474
400 if (is_valid_faceset(q)) 475 if (is_valid_faceset (q))
401 ns->faceset=q; 476 ns->faceset = q;
402 sprintf(tmpbuf,"%d", ns->faceset); 477 sprintf (tmpbuf, "%d", ns->faceset);
403 safe_strcat(cmdback, tmpbuf, &slen, HUGE_BUF); 478 safe_strcat (cmdback, tmpbuf, &slen, HUGE_BUF);
404 /* if the client is using faceset, it knows about image2 command */ 479 /* if the client is using faceset, it knows about image2 command */
405 ns->image2=1; 480 ns->image2 = 1;
481 }
406 } else if (!strcmp(cmd,"itemcmd")) { 482 else if (!strcmp (cmd, "itemcmd"))
483 {
407 /* Version of the item protocol command to use. Currently, 484 /* Version of the item protocol command to use. Currently,
408 * only supported versions are 1 and 2. Using a numeric 485 * only supported versions are 1 and 2. Using a numeric
409 * value will make it very easy to extend this in the future. 486 * value will make it very easy to extend this in the future.
410 */ 487 */
411 char tmpbuf[20]; 488 char tmpbuf[20];
412 int q = atoi(param); 489 int q = atoi (param);
413 if (q<1 || q>2) { 490
414 strcpy(tmpbuf,"FALSE"); 491 if (q < 1 || q > 2)
415 } else { 492 {
416 ns->itemcmd = q; 493 strcpy (tmpbuf, "FALSE");
494 }
495 else
496 {
497 ns->itemcmd = q;
417 sprintf(tmpbuf,"%d", ns->itemcmd); 498 sprintf (tmpbuf, "%d", ns->itemcmd);
418 } 499 }
419 safe_strcat(cmdback, tmpbuf, &slen, HUGE_BUF); 500 safe_strcat (cmdback, tmpbuf, &slen, HUGE_BUF);
501 }
420 } else if (!strcmp(cmd,"mapsize")) { 502 else if (!strcmp (cmd, "mapsize"))
503 {
421 int x, y=0; 504 int x, y = 0;
422 char tmpbuf[MAX_BUF], *cp; 505 char tmpbuf[MAX_BUF], *cp;
423 506
424 x = atoi(param); 507 x = atoi (param);
425 for (cp = param; *cp!=0; cp++) 508 for (cp = param; *cp != 0; cp++)
426 if (*cp == 'x' || *cp == 'X') { 509 if (*cp == 'x' || *cp == 'X')
427 y = atoi(cp+1); 510 {
428 break; 511 y = atoi (cp + 1);
429 } 512 break;
513 }
430 if (x < 9 || y < 9 || x>MAP_CLIENT_X || y > MAP_CLIENT_Y) { 514 if (x < 9 || y < 9 || x > MAP_CLIENT_X || y > MAP_CLIENT_Y)
515 {
431 sprintf(tmpbuf," %dx%d", MAP_CLIENT_X, MAP_CLIENT_Y); 516 sprintf (tmpbuf, " %dx%d", MAP_CLIENT_X, MAP_CLIENT_Y);
432 safe_strcat(cmdback, tmpbuf, &slen, HUGE_BUF); 517 safe_strcat (cmdback, tmpbuf, &slen, HUGE_BUF);
433 } else { 518 }
434 ns->mapx = x; 519 else
435 ns->mapy = y; 520 {
521 ns->mapx = x;
522 ns->mapy = y;
436 /* better to send back what we are really using and not the 523 /* better to send back what we are really using and not the
437 * param as given to us in case it gets parsed differently. 524 * param as given to us in case it gets parsed differently.
438 */ 525 */
439 sprintf(tmpbuf,"%dx%d", x,y); 526 sprintf (tmpbuf, "%dx%d", x, y);
440 safe_strcat(cmdback, tmpbuf, &slen, HUGE_BUF); 527 safe_strcat (cmdback, tmpbuf, &slen, HUGE_BUF);
441 /* If beyond this size and still using orig map command, need to 528 /* If beyond this size and still using orig map command, need to
442 * go to map1cmd. 529 * go to map1cmd.
443 */ 530 */
444 if ((x>11 || y>11) && ns->mapmode == Map0Cmd) ns->mapmode = Map1Cmd; 531 if ((x > 11 || y > 11) && ns->mapmode == Map0Cmd)
445 } 532 ns->mapmode = Map1Cmd;
533 }
534 }
446 } else if (!strcmp(cmd,"extendedMapInfos")) { 535 else if (!strcmp (cmd, "extendedMapInfos"))
536 {
447 /* Added by tchize 537 /* Added by tchize
448 * prepare to use the mapextended command 538 * prepare to use the mapextended command
449 */ 539 */
450 char tmpbuf[20]; 540 char tmpbuf[20];
541
451 ns->ext_mapinfos = (atoi(param)); 542 ns->ext_mapinfos = (atoi (param));
452 sprintf(tmpbuf,"%d", ns->ext_mapinfos); 543 sprintf (tmpbuf, "%d", ns->ext_mapinfos);
453 safe_strcat(cmdback, tmpbuf, &slen, HUGE_BUF); 544 safe_strcat (cmdback, tmpbuf, &slen, HUGE_BUF);
545 }
454 } else if (!strcmp(cmd,"extendedTextInfos")) { 546 else if (!strcmp (cmd, "extendedTextInfos"))
547 {
455 /* Added by tchize 548 /* Added by tchize
456 * prepare to use the extended text commands 549 * prepare to use the extended text commands
457 * Client toggle this to non zero to get exttext 550 * Client toggle this to non zero to get exttext
458 */ 551 */
459 char tmpbuf[20]; 552 char tmpbuf[20];
460 553
461 ns->has_readable_type = (atoi(param)); 554 ns->has_readable_type = (atoi (param));
462 sprintf(tmpbuf,"%d", ns->has_readable_type); 555 sprintf (tmpbuf, "%d", ns->has_readable_type);
463 safe_strcat(cmdback, tmpbuf, &slen, HUGE_BUF); 556 safe_strcat (cmdback, tmpbuf, &slen, HUGE_BUF);
464 } else { 557 }
558 else
559 {
465 /* Didn't get a setup command we understood - 560 /* Didn't get a setup command we understood -
466 * report a failure to the client. 561 * report a failure to the client.
467 */ 562 */
468 safe_strcat(cmdback, "FALSE", &slen, HUGE_BUF); 563 safe_strcat (cmdback, "FALSE", &slen, HUGE_BUF);
469 } 564 }
470 } /* for processing all the setup commands */ 565 } /* for processing all the setup commands */
566
471 LOG(llevInfo,"SendBack SetupCmd:: %s\n", cmdback); 567 LOG (llevInfo, "SendBack SetupCmd:: %s\n", cmdback);
472 Write_String_To_Socket(ns, cmdback, strlen(cmdback)); 568 ns->send_packet (cmdback);
473} 569}
474 570
475/** 571/**
476 * The client has requested to be added to the game. 572 * The client has requested to be added to the game.
477 * This is what takes care of it. We tell the client how things worked out. 573 * This is what takes care of it. We tell the client how things worked out.
478 * I am not sure if this file is the best place for this function. however, 574 * I am not sure if this file is the best place for this function. however,
479 * it either has to be here or init_sockets needs to be exported. 575 * it either has to be here or init_sockets needs to be exported.
480 */ 576 */
577void
481void AddMeCmd(char *buf, int len, NewSocket *ns) 578AddMeCmd (char *buf, int len, client * ns)
482{ 579{
483 Settings oldsettings; 580 Settings oldsettings;
581
484 oldsettings=settings; 582 oldsettings = settings;
485 if (ns->status != Ns_Add || add_player(ns)) { 583 if (ns->status != Ns_Add || add_player (ns))
486 Write_String_To_Socket(ns, "addme_failed",12); 584 ns->send_packet ("addme_failed");
487 } else { 585 else
488 /* Basically, the add_player copies the socket structure into 586 ns->send_packet ("addme_success");
489 * the player structure, so this one (which is from init_sockets) 587
490 * is not needed anymore. The write below should still work, as the
491 * stuff in ns is still relevant.
492 */
493 Write_String_To_Socket(ns, "addme_success",13);
494 socket_info.nconns--;
495 ns->status = Ns_Avail;
496 }
497 settings=oldsettings; 588 settings = oldsettings;
498} 589}
499 590
500/** Reply to ExtendedInfos command */ 591/** Reply to ExtendedInfos command */
592void
501void ToggleExtendedInfos (char *buf, int len, NewSocket *ns){ 593ToggleExtendedInfos (char *buf, int len, client * ns)
594{
502 char cmdback[MAX_BUF]; 595 char cmdback[MAX_BUF];
503 char command[50]; 596 char command[50];
504 int info,nextinfo; 597 int info, nextinfo;
598
505 cmdback[0]='\0'; 599 cmdback[0] = '\0';
506 nextinfo=0; 600 nextinfo = 0;
601
507 while (1){ 602 while (1)
603 {
508 /* 1. Extract an info*/ 604 /* 1. Extract an info */
509 info=nextinfo; 605 info = nextinfo;
606
510 while ( (info<len) && (buf[info]==' ') ) info++; 607 while ((info < len) && (buf[info] == ' '))
608 info++;
609
511 if (info>=len) 610 if (info >= len)
512 break; 611 break;
612
513 nextinfo=info+1; 613 nextinfo = info + 1;
614
514 while ( (nextinfo<len) && (buf[nextinfo]!=' ') ) 615 while ((nextinfo < len) && (buf[nextinfo] != ' '))
515 nextinfo++; 616 nextinfo++;
617
516 if (nextinfo-info>=49) /*Erroneous info asked*/ 618 if (nextinfo - info >= 49) /*Erroneous info asked */
517 continue; 619 continue;
620
518 strncpy (command,&(buf[info]),nextinfo-info); 621 strncpy (command, &(buf[info]), nextinfo - info);
519 command[nextinfo-info]='\0'; 622
520 /* 2. Interpret info*/ 623 /* 2. Interpret info */
521 if (!strcmp("smooth",command)){ 624 if (!strcmp ("smooth", command))
522 /* Toggle smoothing*/ 625 /* Toggle smoothing */
523 ns->EMI_smooth=!ns->EMI_smooth; 626 ns->EMI_smooth = !ns->EMI_smooth;
524 }else{ 627 else
525 /*bad value*/ 628 /*bad value */;
526 } 629
527 /*3. Next info*/ 630 /*3. Next info */
528 } 631 }
632
529 strcpy (cmdback,"ExtendedInfoSet"); 633 strcpy (cmdback, "ExtendedInfoSet");
634
530 if (ns->EMI_smooth){ 635 if (ns->EMI_smooth)
636 {
531 strcat (cmdback," "); 637 strcat (cmdback, " ");
532 strcat (cmdback,"smoothing"); 638 strcat (cmdback, "smoothing");
533 } 639 }
534 Write_String_To_Socket(ns, cmdback,strlen(cmdback)); 640
641 ns->send_packet (cmdback);
535} 642}
643
536/* 644/*
537#define MSG_TYPE_BOOK 1 645#define MSG_TYPE_BOOK 1
538#define MSG_TYPE_CARD 2 646#define MSG_TYPE_CARD 2
539#define MSG_TYPE_PAPER 3 647#define MSG_TYPE_PAPER 3
540#define MSG_TYPE_SIGN 4 648#define MSG_TYPE_SIGN 4
541#define MSG_TYPE_MONUMENT 5 649#define MSG_TYPE_MONUMENT 5
542#define MSG_TYPE_SCRIPTED_DIALOG 6*/ 650#define MSG_TYPE_SCRIPTED_DIALOG 6*/
651
543/** Reply to ExtendedInfos command */ 652/** Reply to ExtendedInfos command */
653void
544void ToggleExtendedText (char *buf, int len, NewSocket *ns){ 654ToggleExtendedText (char *buf, int len, client * ns)
655{
545 char cmdback[MAX_BUF]; 656 char cmdback[MAX_BUF];
546 char temp[10]; 657 char temp[10];
547 char command[50]; 658 char command[50];
548 int info,nextinfo,i,flag; 659 int info, nextinfo, i, flag;
660
549 cmdback[0]='\0'; 661 cmdback[0] = '\0';
662
550 nextinfo=0; 663 nextinfo = 0;
551 while (1){ 664 while (1)
665 {
552 /* 1. Extract an info*/ 666 /* 1. Extract an info */
553 info=nextinfo; 667 info = nextinfo;
668
554 while ( (info<len) && (buf[info]==' ') ) info++; 669 while ((info < len) && (buf[info] == ' '))
670 info++;
671
555 if (info>=len) 672 if (info >= len)
556 break; 673 break;
674
557 nextinfo=info+1; 675 nextinfo = info + 1;
676
558 while ( (nextinfo<len) && (buf[nextinfo]!=' ') ) 677 while ((nextinfo < len) && (buf[nextinfo] != ' '))
559 nextinfo++; 678 nextinfo++;
679
560 if (nextinfo-info>=49) /*Erroneous info asked*/ 680 if (nextinfo - info >= 49) /*Erroneous info asked */
561 continue; 681 continue;
682
562 strncpy (command,&(buf[info]),nextinfo-info); 683 strncpy (command, &(buf[info]), nextinfo - info);
563 command[nextinfo-info]='\0'; 684 command[nextinfo - info] = '\0';
564 /* 2. Interpret info*/ 685 /* 2. Interpret info */
565 i = sscanf(command,"%d",&flag); 686 i = sscanf (command, "%d", &flag);
687
566 if ( (i==1) && (flag>0) && (flag<=MSG_TYPE_LAST)) 688 if ((i == 1) && (flag > 0) && (flag <= MSG_TYPE_LAST))
567 ns->supported_readables|=(1<<flag); 689 ns->supported_readables |= (1 << flag);
568 /*3. Next info*/ 690 /*3. Next info */
569 } 691 }
692
570 /* Send resulting state */ 693 /* Send resulting state */
571 strcpy (cmdback,"ExtendedTextSet"); 694 strcpy (cmdback, "ExtendedTextSet");
695
572 for (i=0;i<=MSG_TYPE_LAST;i++) 696 for (i = 0; i <= MSG_TYPE_LAST; i++)
573 if (ns->supported_readables &(1<<i)){ 697 if (ns->supported_readables & (1 << i))
698 {
574 strcat (cmdback," "); 699 strcat (cmdback, " ");
575 snprintf(temp,sizeof(temp),"%d",i); 700 snprintf (temp, sizeof (temp), "%d", i);
576 strcat (cmdback,temp); 701 strcat (cmdback, temp);
577 } 702 }
578 Write_String_To_Socket(ns, cmdback,strlen(cmdback)); 703
704 ns->send_packet (cmdback);
579} 705}
580 706
581/** 707/**
582 * A lot like the old AskSmooth (in fact, now called by AskSmooth). 708 * A lot like the old AskSmooth (in fact, now called by AskSmooth).
583 * Basically, it makes no sense to wait for the client to request a 709 * Basically, it makes no sense to wait for the client to request a
584 * a piece of data from us that we know the client wants. So 710 * a piece of data from us that we know the client wants. So
585 * if we know the client wants it, might as well push it to the 711 * if we know the client wants it, might as well push it to the
586 * client. 712 * client.
587 */ 713 */
588static void SendSmooth(NewSocket *ns, uint16 face) { 714static void
715SendSmooth (client * ns, uint16 face)
716{
589 uint16 smoothface; 717 uint16 smoothface;
590 unsigned char reply[MAX_BUF];
591 SockList sl;
592 718
593 /* If we can't find a face, return and set it so we won't try to send this 719 /* If we can't find a face, return and set it so we won't try to send this
594 * again. 720 * again.
595 */ 721 */
596 if ((!FindSmooth (face, &smoothface)) && 722 if ((!FindSmooth (face, &smoothface)) && (!FindSmooth (smooth_face->number, &smoothface)))
597 (!FindSmooth ( smooth_face->number, &smoothface))) { 723 {
598 724
599 LOG(llevError,"could not findsmooth for %d. Neither default (%s)\n",face,smooth_face->name); 725 LOG (llevError, "could not findsmooth for %d. Neither default (%s)\n", face, &smooth_face->name);
600 ns->faces_sent[face] |= NS_FACESENT_SMOOTH; 726 ns->faces_sent[face] |= NS_FACESENT_SMOOTH;
601 return; 727 return;
602 } 728 }
603 729
604 if (!(ns->faces_sent[smoothface] & NS_FACESENT_FACE)) 730 if (!(ns->faces_sent[smoothface] & NS_FACESENT_FACE))
605 esrv_send_face(ns, smoothface, 0); 731 esrv_send_face (ns, smoothface, 0);
606 732
607 ns->faces_sent[face] |= NS_FACESENT_SMOOTH; 733 ns->faces_sent[face] |= NS_FACESENT_SMOOTH;
608 734
609 sl.buf=reply; 735 packet sl;
610 strcpy((char*)sl.buf,"smooth "); 736
611 sl.len=strlen((char*)sl.buf); 737 sl << "smooth "
612 SockList_AddShort(&sl, face); 738 << uint16 (face)
613 SockList_AddShort(&sl, smoothface); 739 << uint16 (smoothface);
614 Send_With_Handling(ns, &sl); 740
741 ns->send_packet (sl);
615} 742}
616 743
617 /** 744 /**
618 * Tells client the picture it has to use 745 * Tells client the picture it has to use
619 * to smooth a picture number given as argument. 746 * to smooth a picture number given as argument.
620 */ 747 */
748void
621void AskSmooth (char *buf, int len, NewSocket *ns){ 749AskSmooth (char *buf, int len, client * ns)
750{
622 uint16 facenbr; 751 uint16 facenbr;
623 752
624 facenbr=atoi (buf); 753 facenbr = atoi (buf);
625 SendSmooth(ns, facenbr); 754 SendSmooth (ns, facenbr);
626} 755}
627
628
629
630
631 756
632/** 757/**
633 * This handles the general commands from the client (ie, north, fire, cast, 758 * This handles the general commands from the client (ie, north, fire, cast,
634 * etc.) 759 * etc.)
635 */ 760 */
761void
636void PlayerCmd(char *buf, int len, player *pl) 762PlayerCmd (char *buf, int len, player *pl)
637{ 763{
638 764
639 /* The following should never happen with a proper or honest client. 765 /* The following should never happen with a proper or honest client.
640 * Therefore, the error message doesn't have to be too clear - if 766 * Therefore, the error message doesn't have to be too clear - if
641 * someone is playing with a hacked/non working client, this gives them 767 * someone is playing with a hacked/non working client, this gives them
642 * an idea of the problem, but they deserve what they get 768 * an idea of the problem, but they deserve what they get
643 */ 769 */
644 if (pl->state!=ST_PLAYING) { 770 if (pl->state != ST_PLAYING)
645 new_draw_info_format(NDI_UNIQUE, 0,pl->ob,
646 "You can not issue commands - state is not ST_PLAYING (%s)", buf);
647 return;
648 } 771 {
772 new_draw_info_format (NDI_UNIQUE, 0, pl->ob, "You can not issue commands - state is not ST_PLAYING (%s)", buf);
773 return;
774 }
649 /* Check if there is a count. In theory, a zero count could also be 775 /* Check if there is a count. In theory, a zero count could also be
650 * sent, so check for that also. 776 * sent, so check for that also.
651 */ 777 */
652 if (atoi(buf) || buf[0]=='0') { 778 if (atoi (buf) || buf[0] == '0')
779 {
653 pl->count=atoi((char*)buf); 780 pl->count = atoi ((char *) buf);
654 buf=strchr(buf,' '); /* advance beyond the numbers */ 781 buf = strchr (buf, ' '); /* advance beyond the numbers */
655 if (!buf) { 782 if (!buf)
783 {
656#ifdef ESRV_DEBUG 784#ifdef ESRV_DEBUG
657 LOG(llevDebug,"PlayerCmd: Got count but no command.\n"); 785 LOG (llevDebug, "PlayerCmd: Got count but no command.\n");
658#endif 786#endif
659 return; 787 return;
660 } 788 }
661 buf++; 789 buf++;
662 } 790 }
663 /* This should not happen anymore. */ 791 /* This should not happen anymore. */
664 if (pl->ob->speed_left<-1.0) { 792 if (pl->ob->speed_left < -1.0)
793 {
665 LOG(llevError,"Player has negative time - shouldn't do command.\n"); 794 LOG (llevError, "Player has negative time - shouldn't do command.\n");
666 } 795 }
667 /* In c_new.c */ 796 /* In c_new.c */
668 execute_newserver_command(pl->ob, (char*)buf); 797 execute_newserver_command (pl->ob, (char *) buf);
669 /* Perhaps something better should be done with a left over count. 798 /* Perhaps something better should be done with a left over count.
670 * Cleaning up the input should probably be done first - all actions 799 * Cleaning up the input should probably be done first - all actions
671 * for the command that issued the count should be done before any other 800 * for the command that issued the count should be done before any other
672 * commands. 801 * commands.
673 */ 802 */
674 803
675 pl->count=0; 804 pl->count = 0;
676 805
677} 806}
678 807
679 808
680/** 809/**
681 * This handles the general commands from the client (ie, north, fire, cast, 810 * This handles the general commands from the client (ie, north, fire, cast,
682 * etc.). It is a lot like PlayerCmd above, but is called with the 811 * etc.). It is a lot like PlayerCmd above, but is called with the
683 * 'ncom' method which gives more information back to the client so it 812 * 'ncom' method which gives more information back to the client so it
684 * can throttle. 813 * can throttle.
685 */ 814 */
815void
686void NewPlayerCmd(uint8 *buf, int len, player *pl) 816NewPlayerCmd (char *buf, int len, player *pl)
687{ 817{
688 int time,repeat; 818 int time, repeat;
689 short packet;
690 unsigned char command[MAX_BUF]; 819 char command[MAX_BUF];
691 SockList sl; 820 int pktlen;
692 821
693 if (len < 7) { 822 if (len < 7)
823 {
694 LOG(llevDebug,"Corrupt ncom command <%s> not long enough - discarding\n", buf); 824 LOG (llevDebug, "Corrupt ncom command <%s> not long enough - discarding\n", buf);
695 return; 825 return;
696 } 826 }
697 827
698 packet = GetShort_String(buf); 828 pktlen = net_uint16 ((uint8 *)buf);
699 repeat = GetInt_String(buf+2); 829 repeat = net_uint32 ((uint8 *)buf + 2);
830
700 /* -1 is special - no repeat, but don't update */ 831 /* -1 is special - no repeat, but don't update */
701 if (repeat!=-1) { 832 if (repeat != -1)
702 pl->count=repeat; 833 pl->count = repeat;
703 }
704 if ((len-4) >= MAX_BUF) len=MAX_BUF-5;
705 834
835 if ((len - 4) >= MAX_BUF)
836 len = MAX_BUF - 5;
837
706 strncpy((char*)command, (char*)buf+6, len-4); 838 strncpy ((char *) command, (char *) buf + 6, len - 4);
707 command[len-4]='\0'; 839 command[len - 4] = 0;
708 840
709 /* The following should never happen with a proper or honest client.
710 * Therefore, the error message doesn't have to be too clear - if
711 * someone is playing with a hacked/non working client, this gives them
712 * an idea of the problem, but they deserve what they get
713 */
714 if (pl->state!=ST_PLAYING) {
715 new_draw_info_format(NDI_UNIQUE, 0,pl->ob,
716 "You can not issue commands - state is not ST_PLAYING (%s)", buf);
717 return;
718 }
719
720 /* This should not happen anymore. */ 841 /* This should not happen anymore. */
721 if (pl->ob->speed_left<-1.0) { 842 if (pl->ob->speed_left < -1.0)
722 LOG(llevError,"Player has negative time - shouldn't do command.\n"); 843 LOG (llevError, "Player has negative time - shouldn't do command.\n");
723 } 844
724 /* In c_new.c */ 845 /* In c_new.c */
725 execute_newserver_command(pl->ob, (char*)command); 846 execute_newserver_command (pl->ob, (char *) command);
726 /* Perhaps something better should be done with a left over count. 847 /* Perhaps something better should be done with a left over count.
727 * Cleaning up the input should probably be done first - all actions 848 * Cleaning up the input should probably be done first - all actions
728 * for the command that issued the count should be done before any other 849 * for the command that issued the count should be done before any other
729 * commands. 850 * commands.
730 */ 851 */
731 pl->count=0; 852 pl->count = 0;
732 853
854 if (FABS (pl->ob->speed) < 0.001)
855 time = MAX_TIME * 100;
856 else
857 time = (int) (MAX_TIME / FABS (pl->ob->speed));
858
733 /* Send confirmation of command execution now */ 859 /* Send confirmation of command execution now */
734 sl.buf = command; 860
735 strcpy((char*)sl.buf,"comc "); 861 packet sl;
736 sl.len=5; 862 sl << "comc " << uint16 (pktlen) << uint32 (time);
737 SockList_AddShort(&sl,packet); 863 pl->socket->send_packet (sl);
738 if (FABS(pl->ob->speed) < 0.001) time=MAX_TIME * 100;
739 else
740 time = ( int )( MAX_TIME/ FABS(pl->ob->speed) );
741 SockList_AddInt(&sl,time);
742 Send_With_Handling(&pl->socket, &sl);
743} 864}
744 865
745 866
746/** This is a reply to a previous query. */ 867/** This is a reply to a previous query. */
868void
747void ReplyCmd(char *buf, int len, player *pl) 869ReplyCmd (char *buf, int len, player *pl)
748{ 870{
749 /* This is to synthesize how the data would be stored if it 871 /* This is to synthesize how the data would be stored if it
750 * was normally entered. A bit of a hack, and should be cleaned up 872 * was normally entered. A bit of a hack, and should be cleaned up
751 * once all the X11 code is removed from the server. 873 * once all the X11 code is removed from the server.
752 * 874 *
753 * We pass 13 to many of the functions because this way they 875 * We pass 13 to many of the functions because this way they
754 * think it was the carriage return that was entered, and the 876 * think it was the carriage return that was entered, and the
755 * function then does not try to do additional input. 877 * function then does not try to do additional input.
756 */ 878 */
757 snprintf(pl->write_buf, sizeof(pl->write_buf), ":%s", buf); 879 snprintf (pl->write_buf, sizeof (pl->write_buf), ":%s", buf);
758 880
759 /* this avoids any hacking here */ 881 /* this avoids any hacking here */
760 882
761 switch (pl->state) { 883 switch (pl->state)
884 {
762 case ST_PLAYING: 885 case ST_PLAYING:
763 LOG(llevError,"Got reply message with ST_PLAYING input state\n"); 886 LOG (llevError, "Got reply message with ST_PLAYING input state\n");
764 break; 887 break;
765 888
766 case ST_PLAY_AGAIN: 889 case ST_PLAY_AGAIN:
767 /* We can check this for return value (2==quit). Maybe we 890 /* We can check this for return value (2==quit). Maybe we
768 * should, and do something appropriate? 891 * should, and do something appropriate?
769 */ 892 */
770 receive_play_again(pl->ob, buf[0]); 893 receive_play_again (pl->ob, buf[0]);
771 break; 894 break;
772 895
773 case ST_ROLL_STAT: 896 case ST_ROLL_STAT:
774 key_roll_stat(pl->ob,buf[0]); 897 key_roll_stat (pl->ob, buf[0]);
775 break; 898 break;
776 899
777 case ST_CHANGE_CLASS: 900 case ST_CHANGE_CLASS:
778 901
779 key_change_class(pl->ob, buf[0]); 902 key_change_class (pl->ob, buf[0]);
780 break; 903 break;
781 904
782 case ST_CONFIRM_QUIT: 905 case ST_CONFIRM_QUIT:
783 key_confirm_quit(pl->ob, buf[0]); 906 key_confirm_quit (pl->ob, buf[0]);
784 break; 907 break;
785 908
786 case ST_CONFIGURE: 909 case ST_CONFIGURE:
787 LOG(llevError,"In client input handling, but into configure state\n"); 910 LOG (llevError, "In client input handling, but into configure state\n");
788 pl->state = ST_PLAYING; 911 pl->state = ST_PLAYING;
789 break; 912 break;
790 913
791 case ST_GET_NAME: 914 case ST_GET_NAME:
792 receive_player_name(pl->ob,13); 915 receive_player_name (pl->ob, 13);
793 break; 916 break;
794 917
795 case ST_GET_PASSWORD: 918 case ST_GET_PASSWORD:
796 case ST_CONFIRM_PASSWORD: 919 case ST_CONFIRM_PASSWORD:
797 receive_player_password(pl->ob,13); 920 receive_player_password (pl->ob, 13);
798 break; 921 break;
799 922
800 case ST_GET_PARTY_PASSWORD: /* Get password for party */ 923 case ST_GET_PARTY_PASSWORD: /* Get password for party */
801 receive_party_password(pl->ob,13); 924 receive_party_password (pl->ob, 13);
802 break; 925 break;
803 926
804 default: 927 default:
805 LOG(llevError,"Unknown input state: %d\n", pl->state); 928 LOG (llevError, "Unknown input state: %d\n", pl->state);
806 } 929 }
807} 930}
808 931
809/** 932/**
810 * Client tells its version. If there is a mismatch, we close the 933 * Client tells its version. If there is a mismatch, we close the
811 * socket. In real life, all we should care about is the client having 934 * socket. In real life, all we should care about is the client having
812 * something older than the server. If we assume the client will be 935 * something older than the server. If we assume the client will be
813 * backwards compatible, having it be a later version should not be a 936 * backwards compatible, having it be a later version should not be a
814 * problem. 937 * problem.
815 */ 938 */
939void
816void VersionCmd(char *buf, int len,NewSocket *ns) 940VersionCmd (char *buf, int len, client * ns)
817{ 941{
818 char *cp; 942 char *cp;
819 char version_warning[256]; 943 char version_warning[256];
820 944
821 if (!buf) { 945 if (!buf)
946 {
822 LOG(llevError, "CS: received corrupted version command\n"); 947 LOG (llevError, "CS: received corrupted version command\n");
823 return; 948 return;
824 } 949 }
825 950
826 ns->cs_version = atoi(buf); 951 ns->cs_version = atoi (buf);
827 ns->sc_version = ns->cs_version; 952 ns->sc_version = ns->cs_version;
828 if (VERSION_CS != ns->cs_version) { 953 if (VERSION_CS != ns->cs_version)
954 {
829#ifdef ESRV_DEBUG 955#ifdef ESRV_DEBUG
830 LOG(llevDebug, "CS: csversion mismatch (%d,%d)\n", VERSION_CS,ns->cs_version); 956 LOG (llevDebug, "CS: csversion mismatch (%d,%d)\n", VERSION_CS, ns->cs_version);
831#endif 957#endif
832 } 958 }
833 cp = strchr(buf+1,' '); 959 cp = strchr (buf + 1, ' ');
834 if (!cp) return; 960 if (!cp)
961 return;
835 ns->sc_version = atoi(cp); 962 ns->sc_version = atoi (cp);
836 if (VERSION_SC != ns->sc_version) { 963 if (VERSION_SC != ns->sc_version)
964 {
837#ifdef ESRV_DEBUG 965#ifdef ESRV_DEBUG
838 LOG(llevDebug, "CS: scversion mismatch (%d,%d)\n",VERSION_SC,ns->sc_version); 966 LOG (llevDebug, "CS: scversion mismatch (%d,%d)\n", VERSION_SC, ns->sc_version);
839#endif 967#endif
840 } 968 }
841 cp = strchr(cp+1, ' '); 969 cp = strchr (cp + 1, ' ');
842 if (cp) { 970 if (cp)
971 {
843 LOG(llevDebug,"CS: connection from client of type <%s>, ip %s\n", cp, ns->host); 972 LOG (llevDebug, "CS: connection from client of type <%s>, ip %s\n", cp, ns->host);
844 973
845 snprintf (ns->client, sizeof (ns->client), "%s", cp + 1); 974 assign (ns->version, cp + 1);
846 975
847 /* This is first implementation - i skip all beta DX clients with it 976 if (ns->sc_version < 1026)
848 * Add later stuff here for other clients 977 {
849 */ 978 sprintf (version_warning, "drawinfo %d %s", NDI_RED,
850 979 "**** VERSION WARNING ****\n**** CLIENT IS TOO OLD!! UPDATE THE CLIENT!! ****");
851 /* these are old dxclients */ 980 ns->send_packet (version_warning);
852 /* Version 1024 added support for singular + plural name values - 981 }
853 * requiing this minimal value reduces complexity of that code, and it
854 * has been around for a long time.
855 */
856 if(!strcmp(" CF DX CLIENT", cp) || ns->sc_version < 1024 )
857 {
858 sprintf(version_warning,"drawinfo %d %s", NDI_RED, "**** VERSION WARNING ****\n**** CLIENT IS TOO OLD!! UPDATE THE CLIENT!! ****");
859 Write_String_To_Socket(ns, version_warning, strlen(version_warning));
860 }
861 982
862 } 983 }
863} 984}
864 985
865/** sound related functions. */ 986/** sound related functions. */
866 987void
867void SetSound(char *buf, int len, NewSocket *ns) 988SetSound (char *buf, int len, client * ns)
868{ 989{
869 ns->sound = atoi(buf); 990 ns->sound = atoi (buf);
870} 991}
871 992
872/** client wants the map resent */ 993/** client wants the map resent */
873 994
995void
874void MapRedrawCmd(char *buf, int len, player *pl) 996MapRedrawCmd (char *buf, int len, player *pl)
875{ 997{
998
876/* This function is currently disabled; just clearing the map state results in 999/* This function is currently disabled; just clearing the map state results in
877 * display errors. It should clear the cache and send a newmap command. 1000 * display errors. It should clear the cache and send a newmap command.
878 * Unfortunately this solution does not work because some client versions send 1001 * Unfortunately this solution does not work because some client versions send
879 * a mapredraw command after receiving a newmap command. 1002 * a mapredraw command after receiving a newmap command.
880 */ 1003 */
881#if 0 1004#if 0
882 /* Okay, this is MAJOR UGLY. but the only way I know how to 1005 /* Okay, this is MAJOR UGLY. but the only way I know how to
883 * clear the "cache" 1006 * clear the "cache"
884 */ 1007 */
885 memset(&pl->socket.lastmap, 0, sizeof(struct Map)); 1008 memset (&pl->socket->lastmap, 0, sizeof (struct Map));
886 draw_client_map(pl->ob); 1009 draw_client_map (pl->ob);
887#endif 1010#endif
888} 1011}
889 1012
890/** 1013/**
891 * Moves an object (typically, container to inventory). 1014 * Moves an object (typically, container to inventory).
892 * syntax is: move (to) (tag) (nrof) 1015 * syntax is: move (to) (tag) (nrof)
893 */ 1016 */
1017void
894void MoveCmd(char *buf, int len,player *pl) 1018MoveCmd (char *buf, int len, player *pl)
895{ 1019{
896 int vals[3], i; 1020 int vals[3], i;
897 1021
898 /* A little funky here. We only cycle for 2 records, because 1022 /* A little funky here. We only cycle for 2 records, because
899 * we obviously am not going to find a space after the third 1023 * we obviously am not going to find a space after the third
900 * record. Perhaps we should just replace this with a 1024 * record. Perhaps we should just replace this with a
901 * sscanf? 1025 * sscanf?
902 */ 1026 */
903 for (i=0; i<2; i++) { 1027 for (i = 0; i < 2; i++)
1028 {
904 vals[i]=atoi(buf); 1029 vals[i] = atoi (buf);
905 if (!(buf = strchr(buf, ' '))) { 1030 if (!(buf = strchr (buf, ' ')))
1031 {
906 LOG(llevError,"Incomplete move command: %s\n", buf); 1032 LOG (llevError, "Incomplete move command: %s\n", buf);
907 return; 1033 return;
908 } 1034 }
909 buf++; 1035 buf++;
910 } 1036 }
911 vals[2]=atoi(buf); 1037 vals[2] = atoi (buf);
912 1038
913/* LOG(llevDebug,"Move item %d (nrof=%d) to %d.\n", vals[1], vals[2], vals[0]);*/ 1039/* LOG(llevDebug,"Move item %d (nrof=%d) to %d.\n", vals[1], vals[2], vals[0]);*/
914 esrv_move_object(pl->ob,vals[0], vals[1], vals[2]); 1040 esrv_move_object (pl->ob, vals[0], vals[1], vals[2]);
915} 1041}
916 1042
917 1043
918 1044
919/****************************************************************************** 1045/******************************************************************************
924 1050
925/** 1051/**
926 * Asks the client to query the user. This way, the client knows 1052 * Asks the client to query the user. This way, the client knows
927 * it needs to send something back (vs just printing out a message) 1053 * it needs to send something back (vs just printing out a message)
928 */ 1054 */
1055void
929void send_query(NewSocket *ns, uint8 flags, char *text) 1056send_query (client * ns, uint8 flags, char *text)
930{ 1057{
931 char buf[MAX_BUF]; 1058 char buf[MAX_BUF];
932 1059
933 sprintf(buf,"query %d %s", flags, text?text:""); 1060 sprintf (buf, "query %d %s", flags, text ? text : "");
934 Write_String_To_Socket(ns, buf, strlen(buf)); 1061 ns->send_packet (buf);
935} 1062}
936 1063
937#define AddIfInt64(Old,New,Type) if (Old != New) {\ 1064#define AddIfInt64(Old,New,Type) if (Old != New) {\
938 Old = New; \ 1065 Old = New; \
939 SockList_AddChar(&sl, Type); \ 1066 sl << uint8 (Type) << uint64 (New); \
940 SockList_AddInt64(&sl, New); \ 1067 }
941 }
942 1068
943#define AddIfInt(Old,New,Type) if (Old != New) {\ 1069#define AddIfInt(Old,New,Type) if (Old != New) {\
944 Old = New; \ 1070 Old = New; \
945 SockList_AddChar(&sl, Type); \ 1071 sl << uint8 (Type) << uint32 (New); \
946 SockList_AddInt(&sl, New); \ 1072 }
947 }
948 1073
949#define AddIfShort(Old,New,Type) if (Old != New) {\ 1074#define AddIfShort(Old,New,Type) if (Old != New) {\
950 Old = New; \ 1075 Old = New; \
951 SockList_AddChar(&sl, Type); \ 1076 sl << uint8 (Type) << uint16 (New); \
952 SockList_AddShort(&sl, New); \ 1077 }
953 }
954 1078
955#define AddIfFloat(Old,New,Type) if (Old != New) {\ 1079#define AddIfFloat(Old,New,Type) if (Old != New) {\
956 Old = New; \ 1080 Old = New; \
957 SockList_AddChar(&sl, Type); \ 1081 sl << uint8 (Type) << uint32 (New*FLOAT_MULTI); \
958 SockList_AddInt(&sl,(long)(New*FLOAT_MULTI));\ 1082 }
959 }
960 1083
961#define AddIfString(Old,New,Type) if (Old == NULL || strcmp(Old,New)) {\ 1084#define AddIfString(Old,New,Type) if (Old == NULL || strcmp(Old,New)) {\
962 if (Old) free(Old);\ 1085 free(Old); Old = strdup (New);\
963 Old = strdup_local(New);\ 1086 sl << uint8 (Type) << data8 (New); \
964 SockList_AddChar(&sl, Type); \ 1087 }
965 SockList_AddChar(&sl, ( char )strlen(New)); \
966 strcpy((char*)sl.buf + sl.len, New); \
967 sl.len += strlen(New); \
968 }
969 1088
970/** 1089/**
971 * Sends a statistics update. We look at the old values, 1090 * Sends a statistics update. We look at the old values,
972 * and only send what has changed. Stat mapping values are in newclient.h 1091 * and only send what has changed. Stat mapping values are in newclient.h
973 * Since this gets sent a lot, this is actually one of the few binary 1092 * Since this gets sent a lot, this is actually one of the few binary
974 * commands for now. 1093 * commands for now.
975 */ 1094 */
1095void
976void esrv_update_stats(player *pl) 1096esrv_update_stats (player *pl)
977{ 1097{
978 SockList sl;
979 char buf[MAX_BUF]; 1098 char buf[MAX_BUF];
980 uint16 flags; 1099 uint16 flags;
981 1100
982 sl.buf=(unsigned char*)malloc(MAXSOCKBUF); 1101 packet sl;
983 strcpy((char*)sl.buf,"stats "); 1102 sl << "stats ";
984 sl.len=strlen((char*)sl.buf); 1103
985
986 if(pl->ob != NULL) 1104 if (pl->ob != NULL)
987 { 1105 {
988 AddIfShort(pl->last_stats.hp, pl->ob->stats.hp, CS_STAT_HP); 1106 AddIfShort (pl->last_stats.hp, pl->ob->stats.hp, CS_STAT_HP);
989 AddIfShort(pl->last_stats.maxhp, pl->ob->stats.maxhp, CS_STAT_MAXHP); 1107 AddIfShort (pl->last_stats.maxhp, pl->ob->stats.maxhp, CS_STAT_MAXHP);
990 AddIfShort(pl->last_stats.sp, pl->ob->stats.sp, CS_STAT_SP); 1108 AddIfShort (pl->last_stats.sp, pl->ob->stats.sp, CS_STAT_SP);
991 AddIfShort(pl->last_stats.maxsp, pl->ob->stats.maxsp, CS_STAT_MAXSP); 1109 AddIfShort (pl->last_stats.maxsp, pl->ob->stats.maxsp, CS_STAT_MAXSP);
992 AddIfShort(pl->last_stats.grace, pl->ob->stats.grace, CS_STAT_GRACE); 1110 AddIfShort (pl->last_stats.grace, pl->ob->stats.grace, CS_STAT_GRACE);
993 AddIfShort(pl->last_stats.maxgrace, pl->ob->stats.maxgrace, CS_STAT_MAXGRACE); 1111 AddIfShort (pl->last_stats.maxgrace, pl->ob->stats.maxgrace, CS_STAT_MAXGRACE);
994 AddIfShort(pl->last_stats.Str, pl->ob->stats.Str, CS_STAT_STR); 1112 AddIfShort (pl->last_stats.Str, pl->ob->stats.Str, CS_STAT_STR);
995 AddIfShort(pl->last_stats.Int, pl->ob->stats.Int, CS_STAT_INT); 1113 AddIfShort (pl->last_stats.Int, pl->ob->stats.Int, CS_STAT_INT);
996 AddIfShort(pl->last_stats.Pow, pl->ob->stats.Pow, CS_STAT_POW); 1114 AddIfShort (pl->last_stats.Pow, pl->ob->stats.Pow, CS_STAT_POW);
997 AddIfShort(pl->last_stats.Wis, pl->ob->stats.Wis, CS_STAT_WIS); 1115 AddIfShort (pl->last_stats.Wis, pl->ob->stats.Wis, CS_STAT_WIS);
998 AddIfShort(pl->last_stats.Dex, pl->ob->stats.Dex, CS_STAT_DEX); 1116 AddIfShort (pl->last_stats.Dex, pl->ob->stats.Dex, CS_STAT_DEX);
999 AddIfShort(pl->last_stats.Con, pl->ob->stats.Con, CS_STAT_CON); 1117 AddIfShort (pl->last_stats.Con, pl->ob->stats.Con, CS_STAT_CON);
1000 AddIfShort(pl->last_stats.Cha, pl->ob->stats.Cha, CS_STAT_CHA); 1118 AddIfShort (pl->last_stats.Cha, pl->ob->stats.Cha, CS_STAT_CHA);
1001 }
1002 if(pl->socket.exp64) {
1003 uint8 s;
1004 for(s=0;s<NUM_SKILLS;s++) {
1005 if (pl->last_skill_ob[s] &&
1006 pl->last_skill_exp[s] != pl->last_skill_ob[s]->stats.exp) {
1007
1008 /* Always send along the level if exp changes. This is only
1009 * 1 extra byte, but keeps processing simpler.
1010 */
1011 SockList_AddChar(&sl, ( char )( s + CS_STAT_SKILLINFO ));
1012 SockList_AddChar(&sl, ( char )pl->last_skill_ob[s]->level);
1013 SockList_AddInt64(&sl, pl->last_skill_ob[s]->stats.exp);
1014 pl->last_skill_exp[s] = pl->last_skill_ob[s]->stats.exp;
1015 } 1119 }
1016 } 1120
1017 }
1018 if (pl->socket.exp64) { 1121 if (pl->socket->exp64)
1122 {
1123 uint8 s;
1124
1125 for (s = 0; s < NUM_SKILLS; s++)
1126 {
1127 if (pl->last_skill_ob[s] && pl->last_skill_exp[s] != pl->last_skill_ob[s]->stats.exp)
1128 {
1129 /* Always send along the level if exp changes. This is only
1130 * 1 extra byte, but keeps processing simpler.
1131 */
1132 sl << uint8 (s + CS_STAT_SKILLINFO)
1133 << uint8 (pl->last_skill_ob[s]->level)
1134 << uint64 (pl->last_skill_ob[s]->stats.exp);
1135
1136 pl->last_skill_exp[s] = pl->last_skill_ob[s]->stats.exp;
1137 }
1138 }
1139 }
1140
1141 if (pl->socket->exp64)
1019 AddIfInt64(pl->last_stats.exp, pl->ob->stats.exp, CS_STAT_EXP64); 1142 { AddIfInt64 (pl->last_stats.exp, pl->ob->stats.exp, CS_STAT_EXP64) }
1020 } else { 1143 else
1021 AddIfInt(pl->last_stats.exp, ( int )pl->ob->stats.exp, CS_STAT_EXP); 1144 { AddIfInt (pl->last_stats.exp, (int) pl->ob->stats.exp, CS_STAT_EXP) }
1022 } 1145
1023 AddIfShort(pl->last_level, ( char )pl->ob->level, CS_STAT_LEVEL); 1146 AddIfShort (pl->last_level, (char) pl->ob->level, CS_STAT_LEVEL);
1024 AddIfShort(pl->last_stats.wc, pl->ob->stats.wc, CS_STAT_WC); 1147 AddIfShort (pl->last_stats.wc, pl->ob->stats.wc, CS_STAT_WC);
1025 AddIfShort(pl->last_stats.ac, pl->ob->stats.ac, CS_STAT_AC); 1148 AddIfShort (pl->last_stats.ac, pl->ob->stats.ac, CS_STAT_AC);
1026 AddIfShort(pl->last_stats.dam, pl->ob->stats.dam, CS_STAT_DAM); 1149 AddIfShort (pl->last_stats.dam, pl->ob->stats.dam, CS_STAT_DAM);
1027 AddIfFloat(pl->last_speed, pl->ob->speed, CS_STAT_SPEED); 1150 AddIfFloat (pl->last_speed, pl->ob->speed, CS_STAT_SPEED);
1028 AddIfShort(pl->last_stats.food, pl->ob->stats.food, CS_STAT_FOOD); 1151 AddIfShort (pl->last_stats.food, pl->ob->stats.food, CS_STAT_FOOD);
1029 AddIfFloat(pl->last_weapon_sp, pl->weapon_sp, CS_STAT_WEAP_SP); 1152 AddIfFloat (pl->last_weapon_sp, pl->weapon_sp, CS_STAT_WEAP_SP);
1030 AddIfInt(pl->last_weight_limit, (sint32)weight_limit[pl->ob->stats.Str], CS_STAT_WEIGHT_LIM); 1153 AddIfInt (pl->last_weight_limit, (sint32) weight_limit[pl->ob->stats.Str], CS_STAT_WEIGHT_LIM);
1031 flags=0; 1154 flags = 0;
1032 if (pl->fire_on) flags |=SF_FIREON;
1033 if (pl->run_on) flags |= SF_RUNON;
1034 1155
1156 if (pl->fire_on)
1157 flags |= SF_FIREON;
1158
1159 if (pl->run_on)
1160 flags |= SF_RUNON;
1161
1035 AddIfShort(pl->last_flags, flags, CS_STAT_FLAGS); 1162 AddIfShort (pl->last_flags, flags, CS_STAT_FLAGS);
1163
1036 if (pl->socket.sc_version<1025) { 1164 if (pl->socket->sc_version < 1025)
1037 AddIfShort(pl->last_resist[ATNR_PHYSICAL], pl->ob->resist[ATNR_PHYSICAL], CS_STAT_ARMOUR); 1165 { AddIfShort (pl->last_resist[ATNR_PHYSICAL], pl->ob->resist[ATNR_PHYSICAL], CS_STAT_ARMOUR) }
1038 } else { 1166 else
1039 int i; 1167 {
1168 int i;
1040 1169
1041 for (i=0; i<NROFATTACKS; i++) { 1170 for (i = 0; i < NROFATTACKS; i++)
1171 {
1042 /* Skip ones we won't send */ 1172 /* Skip ones we won't send */
1043 if (atnr_cs_stat[i]==-1) continue; 1173 if (atnr_cs_stat[i] == -1)
1174 continue;
1175
1044 AddIfShort(pl->last_resist[i], pl->ob->resist[i], ( char )atnr_cs_stat[i]); 1176 AddIfShort (pl->last_resist[i], pl->ob->resist[i], (char) atnr_cs_stat[i]);
1045 } 1177 }
1046 } 1178 }
1179
1047 if (pl->socket.monitor_spells) { 1180 if (pl->socket->monitor_spells)
1181 {
1048 AddIfInt(pl->last_path_attuned, pl->ob->path_attuned, CS_STAT_SPELL_ATTUNE); 1182 AddIfInt (pl->last_path_attuned, pl->ob->path_attuned, CS_STAT_SPELL_ATTUNE);
1049 AddIfInt(pl->last_path_repelled, pl->ob->path_repelled, CS_STAT_SPELL_REPEL); 1183 AddIfInt (pl->last_path_repelled, pl->ob->path_repelled, CS_STAT_SPELL_REPEL);
1050 AddIfInt(pl->last_path_denied, pl->ob->path_denied, CS_STAT_SPELL_DENY); 1184 AddIfInt (pl->last_path_denied, pl->ob->path_denied, CS_STAT_SPELL_DENY);
1051 } 1185 }
1186
1052 rangetostring(pl->ob, buf); /* we want use the new fire & run system in new client */ 1187 rangetostring (pl->ob, buf); /* we want use the new fire & run system in new client */
1053 AddIfString(pl->socket.stats.range, buf, CS_STAT_RANGE); 1188 AddIfString (pl->socket->stats.range, buf, CS_STAT_RANGE);
1054 set_title(pl->ob, buf); 1189 set_title (pl->ob, buf);
1055 AddIfString(pl->socket.stats.title, buf, CS_STAT_TITLE); 1190 AddIfString (pl->socket->stats.title, buf, CS_STAT_TITLE);
1056 1191
1057 /* Only send it away if we have some actual data */ 1192 /* Only send it away if we have some actual data */
1058 if (sl.len>6) { 1193 if (sl.length () > 6)
1059#ifdef ESRV_DEBUG 1194 pl->socket->send_packet (sl);
1060 LOG(llevDebug,"Sending stats command, %d bytes long.\n", sl.len);
1061#endif
1062 Send_With_Handling(&pl->socket, &sl);
1063 }
1064 free(sl.buf);
1065} 1195}
1066
1067 1196
1068/** 1197/**
1069 * Tells the client that here is a player it should start using. 1198 * Tells the client that here is a player it should start using.
1070 */ 1199 */
1200void
1071void esrv_new_player(player *pl, uint32 weight) 1201esrv_new_player (player *pl, uint32 weight)
1072{ 1202{
1073 SockList sl;
1074
1075 pl->last_weight = weight; 1203 pl->last_weight = weight;
1076 1204
1077 sl.buf=(unsigned char*)malloc(MAXSOCKBUF); 1205 packet sl;
1206 sl << "player ";
1078 1207
1079 strcpy((char*)sl.buf,"player "); 1208 sl << uint32 (pl->ob->count)
1080 sl.len=strlen((char*)sl.buf); 1209 << uint32 (weight)
1081 SockList_AddInt(&sl, pl->ob->count); 1210 << uint32 (pl->ob->face->number)
1082 SockList_AddInt(&sl, weight); 1211 << data8 (pl->ob->name);
1083 SockList_AddInt(&sl, pl->ob->face->number);
1084 1212
1085 SockList_AddChar(&sl, ( char )strlen(pl->ob->name)); 1213 pl->socket->send_packet (sl);
1086 strcpy((char*)sl.buf+sl.len, pl->ob->name);
1087 sl.len += strlen(pl->ob->name);
1088
1089 Send_With_Handling(&pl->socket, &sl);
1090 free(sl.buf);
1091 SET_FLAG(pl->ob, FLAG_CLIENT_SENT); 1214 SET_FLAG (pl->ob, FLAG_CLIENT_SENT);
1092} 1215}
1093
1094 1216
1095/** 1217/**
1096 * Need to send an animation sequence to the client. 1218 * Need to send an animation sequence to the client.
1097 * 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
1098 * 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
1099 * how much we are sending - on the other hand, this should only happen 1221 * how much we are sending - on the other hand, this should only happen
1100 * when the player logs in and picks stuff up. 1222 * when the player logs in and picks stuff up.
1101 */ 1223 */
1224void
1102void esrv_send_animation(NewSocket *ns, short anim_num) 1225esrv_send_animation (client * ns, short anim_num)
1103{ 1226{
1104 SockList sl;
1105 int i; 1227 int i;
1106 1228
1107 /* 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
1108 * 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
1109 * range, it must be a valid animation. 1231 * range, it must be a valid animation.
1110 */ 1232 */
1111 if (anim_num < 0 || anim_num > num_animations) { 1233 if (anim_num < 0 || anim_num > num_animations)
1234 {
1112 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);
1113 return; 1236 return;
1114 } 1237 }
1115 1238
1116 sl.buf = (unsigned char*) malloc(MAXSOCKBUF); 1239 packet sl;
1117 strcpy((char*)sl.buf, "anim "); 1240
1118 sl.len=5; 1241 sl << "anim "
1119 SockList_AddShort(&sl, anim_num); 1242 << uint16 (anim_num)
1120 SockList_AddShort(&sl, 0); /* flags - not used right now */ 1243 << uint16 (0); /* flags - not used right now */
1244
1121 /* 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
1122 * the face itself) down to the client. 1246 * the face itself) down to the client.
1123 */ 1247 */
1124 for (i=0; i<animations[anim_num].num_animations; i++) { 1248 for (i = 0; i < animations[anim_num].num_animations; i++)
1249 {
1125 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))
1126 esrv_send_face(ns,animations[anim_num].faces[i],0); 1251 esrv_send_face (ns, animations[anim_num].faces[i], 0);
1127 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 */
1128 } 1253 }
1129 Send_With_Handling(ns, &sl); 1254
1130 free(sl.buf); 1255 ns->send_packet (sl);
1256
1131 ns->anims_sent[anim_num] = 1; 1257 ns->anims_sent[anim_num] = 1;
1132} 1258}
1133 1259
1134 1260
1135/****************************************************************************** 1261/******************************************************************************
1136 * 1262 *
1140 1266
1141/** 1267/**
1142 * This adds face_num to a map cell at x,y. If the client doesn't have 1268 * This adds face_num to a map cell at x,y. If the client doesn't have
1143 * the face yet, we will also send it. 1269 * the face yet, we will also send it.
1144 */ 1270 */
1145static void esrv_map_setbelow(NewSocket *ns, int x,int y, 1271static void
1146 short face_num, struct Map *newmap) 1272esrv_map_setbelow (client * ns, int x, int y, short face_num, struct Map *newmap)
1147{ 1273{
1148 if(newmap->cells[x][y].count >= MAP_LAYERS) { 1274 if (newmap->cells[x][y].count >= MAP_LAYERS)
1275 {
1149 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);
1150 return; 1277 return;
1151 abort(); 1278 abort ();
1152 } 1279 }
1280
1153 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;
1154 newmap->cells[x][y].count ++; 1282 newmap->cells[x][y].count++;
1283
1155 if (!(ns->faces_sent[face_num] & NS_FACESENT_FACE)) 1284 if (!(ns->faces_sent[face_num] & NS_FACESENT_FACE))
1156 esrv_send_face(ns,face_num,0); 1285 esrv_send_face (ns, face_num, 0);
1157} 1286}
1158 1287
1159struct LayerCell { 1288struct LayerCell
1289{
1160 uint16 xy; 1290 uint16 xy;
1161 short face; 1291 short face;
1162}; 1292};
1163 1293
1164struct MapLayer { 1294struct MapLayer
1295{
1165 int count; 1296 int count;
1166 struct LayerCell lcells[MAP_CLIENT_X * MAP_CLIENT_Y]; 1297 struct LayerCell lcells[MAP_CLIENT_X * MAP_CLIENT_Y];
1167}; 1298};
1168 1299
1169/** Checkes if map cells have changed */ 1300/** Checkes if map cells have changed */
1301static int
1170static int mapcellchanged(NewSocket *ns,int i,int j, struct Map *newmap) 1302mapcellchanged (client * ns, int i, int j, struct Map *newmap)
1171{ 1303{
1172 int k; 1304 int k;
1173 1305
1174 if (ns->lastmap.cells[i][j].count != newmap->cells[i][j].count) 1306 if (ns->lastmap.cells[i][j].count != newmap->cells[i][j].count)
1175 return 1; 1307 return 1;
1176 for(k=0;k<newmap->cells[i][j].count;k++) { 1308 for (k = 0; k < newmap->cells[i][j].count; k++)
1177 if (ns->lastmap.cells[i][j].faces[k] != 1309 {
1178 newmap->cells[i][j].faces[k]) { 1310 if (ns->lastmap.cells[i][j].faces[k] != newmap->cells[i][j].faces[k])
1311 {
1179 return 1; 1312 return 1;
1180 } 1313 }
1181 } 1314 }
1182 return 0; 1315 return 0;
1183} 1316}
1184 1317
1185/** 1318/**
1186 * Basically, what this does is pack the data into layers. 1319 * Basically, what this does is pack the data into layers.
1187 * cnum is the client number, cur is the the buffer we put all of 1320 * cnum is the client number, cur is the the buffer we put all of
1188 * this data into. we return the end of the data. layers is 1321 * this data into. we return the end of the data. layers is
1189 * how many layers of data we should back. 1322 * how many layers of data we should back.
1190 */ 1323 */
1191static uint8 *compactlayer(NewSocket *ns, unsigned char *cur, int numlayers, 1324static uint8 *
1192 struct Map *newmap) 1325compactlayer (client * ns, unsigned char *cur, int numlayers, struct Map *newmap)
1193{ 1326{
1194 int x,y,k; 1327 int x, y, k;
1195 int face; 1328 int face;
1196 unsigned char *fcur; 1329 unsigned char *fcur;
1197 struct MapLayer layers[MAP_LAYERS]; 1330 struct MapLayer layers[MAP_LAYERS];
1198 1331
1199 for(k = 0;k<MAP_LAYERS;k++) 1332 for (k = 0; k < MAP_LAYERS; k++)
1200 layers[k].count = 0; 1333 layers[k].count = 0;
1201 fcur = cur; 1334 fcur = cur;
1202 for(x=0;x<ns->mapx;x++) { 1335 for (x = 0; x < ns->mapx; x++)
1203 for(y=0;y<ns->mapy;y++) { 1336 {
1337 for (y = 0; y < ns->mapy; y++)
1338 {
1204 if (!mapcellchanged(ns,x,y,newmap)) 1339 if (!mapcellchanged (ns, x, y, newmap))
1205 continue; 1340 continue;
1206 if (newmap->cells[x][y].count == 0) { 1341 if (newmap->cells[x][y].count == 0)
1342 {
1207 *cur = x*ns->mapy+y; /* mark empty space */ 1343 *cur = x * ns->mapy + y; /* mark empty space */
1208 cur++; 1344 cur++;
1209 continue; 1345 continue;
1346 }
1347 for (k = 0; k < newmap->cells[x][y].count; k++)
1348 {
1349 layers[k].lcells[layers[k].count].xy = x * ns->mapy + y;
1350 layers[k].lcells[layers[k].count].face = newmap->cells[x][y].faces[k];
1351 layers[k].count++;
1352 }
1353 }
1210 } 1354 }
1211 for(k=0;k<newmap->cells[x][y].count;k++) {
1212 layers[k].lcells[layers[k].count].xy = x*ns->mapy+y;
1213 layers[k].lcells[layers[k].count].face =
1214 newmap->cells[x][y].faces[k];
1215 layers[k].count++;
1216 }
1217 }
1218 }
1219 /* If no data, return now. */ 1355 /* If no data, return now. */
1220 if (fcur == cur && layers[0].count == 0) 1356 if (fcur == cur && layers[0].count == 0)
1221 return cur;
1222 *cur = 255; /* mark end of explicitly cleared cells */
1223 cur++;
1224 /* First pack by layers. */
1225 for(k=0;k<numlayers;k++) {
1226 if (layers[k].count == 0)
1227 break; /* once a layer is entirely empty, no layer below it can
1228 have anything in it either */
1229 /* Pack by entries in thie layer */
1230 for(x=0;x<layers[k].count;) {
1231 fcur = cur;
1232 *cur = layers[k].lcells[x].face >> 8;
1233 cur++;
1234 *cur = layers[k].lcells[x].face & 0xFF;
1235 cur++;
1236 face = layers[k].lcells[x].face;
1237 /* Now, we back the redundant data into 1 byte xy pairings */
1238 for(y=x;y<layers[k].count;y++) {
1239 if (layers[k].lcells[y].face == face) {
1240 *cur = ( uint8 )layers[k].lcells[y].xy;
1241 cur++;
1242 layers[k].lcells[y].face = -1;
1243 }
1244 }
1245 *(cur-1) = *(cur-1) | 128; /* mark for end of xy's; 11*11 < 128 */
1246 /* forward over the now redundant data */
1247 while(x < layers[k].count &&
1248 layers[k].lcells[x].face == -1)
1249 x++;
1250 }
1251 *fcur = *fcur | 128; /* mark for end of faces at this layer */
1252 }
1253 return cur; 1357 return cur;
1254} 1358 *cur = 255; /* mark end of explicitly cleared cells */
1255 1359 cur++;
1256static void esrv_map_doneredraw(NewSocket *ns, struct Map *newmap) 1360 /* First pack by layers. */
1257{ 1361 for (k = 0; k < numlayers; k++)
1258 static long frames,bytes,tbytes,tframes;
1259 char *cur;
1260 SockList sl;
1261
1262
1263 sl.buf=(unsigned char*)malloc(MAXSOCKBUF);
1264 strcpy((char*)sl.buf,"map ");
1265 sl.len=strlen((char*)sl.buf);
1266
1267 cur = (char *) compactlayer(ns,(unsigned char*) sl.buf+sl.len,MAP_LAYERS,newmap);
1268 sl.len=cur-(char*)sl.buf;
1269
1270/* LOG(llevDebug, "Sending map command.\n");*/
1271
1272 if (sl.len>( int )strlen("map ") || ns->sent_scroll) {
1273 /* All of this is just accounting stuff */
1274 if (tframes>100) {
1275 tframes = tbytes = 0;
1276 }
1277 tframes++;
1278 frames++;
1279 tbytes += sl.len;
1280 bytes += sl.len;
1281 memcpy(&ns->lastmap,newmap,sizeof(struct Map));
1282 Send_With_Handling(ns, &sl);
1283 ns->sent_scroll = 0;
1284 } 1362 {
1285 free(sl.buf); 1363 if (layers[k].count == 0)
1364 break; /* once a layer is entirely empty, no layer below it can
1365 have anything in it either */
1366 /* Pack by entries in thie layer */
1367 for (x = 0; x < layers[k].count;)
1368 {
1369 fcur = cur;
1370 *cur = layers[k].lcells[x].face >> 8;
1371 cur++;
1372 *cur = layers[k].lcells[x].face & 0xFF;
1373 cur++;
1374 face = layers[k].lcells[x].face;
1375 /* Now, we back the redundant data into 1 byte xy pairings */
1376 for (y = x; y < layers[k].count; y++)
1377 {
1378 if (layers[k].lcells[y].face == face)
1379 {
1380 *cur = (uint8) layers[k].lcells[y].xy;
1381 cur++;
1382 layers[k].lcells[y].face = -1;
1383 }
1384 }
1385 *(cur - 1) = *(cur - 1) | 128; /* mark for end of xy's; 11*11 < 128 */
1386 /* forward over the now redundant data */
1387 while (x < layers[k].count && layers[k].lcells[x].face == -1)
1388 x++;
1389 }
1390 *fcur = *fcur | 128; /* mark for end of faces at this layer */
1391 }
1392 return cur;
1286} 1393}
1287
1288 1394
1289/** Clears a map cell */ 1395/** Clears a map cell */
1396static void
1290static void map_clearcell(struct MapCell *cell, int face0, int face1, int face2, int count) 1397map_clearcell (struct MapCell *cell, int face0, int face1, int face2, int count)
1291{ 1398{
1292 cell->faces[0] = face0; 1399 cell->faces[0] = face0;
1293 cell->faces[1] = face1; 1400 cell->faces[1] = face1;
1294 cell->faces[2] = face2; 1401 cell->faces[2] = face2;
1295 cell->count = count; 1402 cell->count = count;
1296 cell->stat_hp = 0; 1403 cell->stat_hp = 0;
1404 cell->flags = 0;
1297 cell->player = 0; 1405 cell->player = 0;
1298} 1406}
1299 1407
1300#define MAX_HEAD_POS MAX(MAX_CLIENT_X, MAX_CLIENT_Y) 1408#define MAX_HEAD_POS MAX(MAX_CLIENT_X, MAX_CLIENT_Y)
1301#define MAX_LAYERS 3 1409#define MAX_LAYERS 3
1302 1410
1305 * and saves the space of allocating this in the socket object when we only 1413 * and saves the space of allocating this in the socket object when we only
1306 * need it for this cycle. If the serve is ever threaded, this needs to be 1414 * need it for this cycle. If the serve is ever threaded, this needs to be
1307 * re-examined. 1415 * re-examined.
1308 */ 1416 */
1309 1417
1310static object *heads[MAX_HEAD_POS * MAX_HEAD_POS * MAX_LAYERS]; 1418static object *heads[MAX_HEAD_POS * MAX_HEAD_POS * MAX_LAYERS];
1311 1419
1312/** 1420/**
1313 * Returns true if any of the heads for this 1421 * Returns true if any of the heads for this
1314 * space is set. Returns false if all are blank - this is used 1422 * space is set. Returns false if all are blank - this is used
1315 * for empty space checking. 1423 * for empty space checking.
1316 */ 1424 */
1317static inline int have_head(int ax, int ay) { 1425static inline int
1426have_head (int ax, int ay)
1427{
1318 1428
1319 if (heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS] || 1429 if (heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS] ||
1320 heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + 1] || 1430 heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + 1] || heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + 2])
1321 heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + 2]) return 1;
1322 return 0; 1431 return 1;
1432 return 0;
1323} 1433}
1324 1434
1325/** 1435/**
1326 * check_head is a bit simplistic version of update_space below. 1436 * check_head is a bit simplistic version of update_space below.
1327 * basically, it only checks the that the head on space ax,ay at layer 1437 * basically, it only checks the that the head on space ax,ay at layer
1328 * needs to get sent - if so, it adds the data, sending the head 1438 * needs to get sent - if so, it adds the data, sending the head
1329 * if needed, and returning 1. If this no data needs to get 1439 * if needed, and returning 1. If this no data needs to get
1330 * sent, it returns zero. 1440 * sent, it returns zero.
1331 */ 1441 */
1442static int
1332static int check_head (SockList &sl, NewSocket &ns, int ax, int ay, int layer) 1443check_head (packet &sl, client &ns, int ax, int ay, int layer)
1333{ 1444{
1334 short face_num; 1445 short face_num;
1335 1446
1336 if (heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer]) 1447 if (heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer])
1337 face_num = heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer]->face->number; 1448 face_num = heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer]->face->number;
1338 else 1449 else
1339 face_num = 0; 1450 face_num = 0;
1340 1451
1341 if (face_num != ns.lastmap.cells[ax][ay].faces[layer]) { 1452 if (face_num != ns.lastmap.cells[ax][ay].faces[layer])
1342 SockList_AddShort (&sl, face_num); 1453 {
1454 sl << uint16 (face_num);
1343 if (face_num && !(ns.faces_sent[face_num] & NS_FACESENT_FACE)) 1455 if (face_num && !(ns.faces_sent[face_num] & NS_FACESENT_FACE))
1344 esrv_send_face (&ns, face_num, 0); 1456 esrv_send_face (&ns, face_num, 0);
1457
1345 heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer] = NULL; 1458 heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer] = NULL;
1346 ns.lastmap.cells[ax][ay].faces[layer] = face_num; 1459 ns.lastmap.cells[ax][ay].faces[layer] = face_num;
1347 return 1; 1460 return 1;
1348 } 1461 }
1349 1462
1350 return 0; /* No change */ 1463 return 0; /* No change */
1351} 1464}
1352 1465
1353/** 1466/**
1354 * Removes the need to replicate the same code for each layer. 1467 * Removes the need to replicate the same code for each layer.
1355 * this returns true if this space is now in fact different than 1468 * this returns true if this space is now in fact different than
1368 * the map command, where the faces stack up. Sinces that is no longer 1481 * the map command, where the faces stack up. Sinces that is no longer
1369 * the case, it seems to make more sense to have these layer values 1482 * the case, it seems to make more sense to have these layer values
1370 * actually match. 1483 * actually match.
1371 */ 1484 */
1372 1485
1373static int update_space(SockList *sl, NewSocket *ns, mapstruct *mp, int mx, int my, int sx, int sy, int layer) 1486static int
1487update_space (packet &sl, client &ns, maptile *mp, int mx, int my, int sx, int sy, int layer)
1374{ 1488{
1375 object *ob, *head; 1489 object *ob, *head;
1376 uint16 face_num; 1490 uint16 face_num;
1377 int bx, by,i; 1491 int bx, by, i;
1378 1492
1379 /* If there is a multipart object stored away, treat that as more important. 1493 /* If there is a multipart object stored away, treat that as more important.
1380 * If not, then do the normal processing. 1494 * If not, then do the normal processing.
1381 */ 1495 */
1382
1383 head = heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer]; 1496 head = heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer];
1384 1497
1385 /* Check to see if this head is part of the set of objects 1498 /* Check to see if this head is part of the set of objects
1386 * we would normally send for this space. If so, then 1499 * we would normally send for this space. If so, then
1387 * don't use the head value. We need to do the check 1500 * don't use the head value. We need to do the check
1388 * here and not when setting up the heads[] value for two reasons - 1501 * here and not when setting up the heads[] value for two reasons -
1389 * 1) the heads[] values will get used even if the space is not visible. 1502 * 1) the heads[] values will get used even if the space is not visible.
1390 * 2) its possible the head is not on the same map as a part, and I'd 1503 * 2) its possible the head is not on the same map as a part, and I'd
1391 * rather not need to do the map translation overhead. 1504 * rather not need to do the map translation overhead.
1392 * 3) We need to do some extra checking to make sure that we will 1505 * 3) We need to do some extra checking to make sure that we will
1393 * otherwise send the image as this layer, eg, either it matches 1506 * otherwise send the image as this layer, eg, either it matches
1394 * the head value, or is not multipart. 1507 * the head value, or is not multipart.
1395 */ 1508 */
1396 if (head && !head->more) { 1509 if (head && !head->more)
1510 {
1397 for (i=0; i<MAP_LAYERS; i++) { 1511 for (i = 0; i < MAP_LAYERS; i++)
1512 {
1398 ob = GET_MAP_FACE_OBJ(mp, mx, my, i); 1513 ob = GET_MAP_FACE_OBJ (mp, mx, my, i);
1399 if (!ob) continue; 1514 if (!ob)
1515 continue;
1400 1516
1401 if (ob->head) ob=ob->head; 1517 if (ob->head)
1518 ob = ob->head;
1402 1519
1403 if (ob == head) { 1520 if (ob == head)
1521 {
1404 heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer] = NULL; 1522 heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer] = NULL;
1405 head = NULL; 1523 head = NULL;
1406 break; 1524 break;
1525 }
1526 }
1407 } 1527 }
1408 }
1409 }
1410 1528
1411 ob = head; 1529 ob = head;
1530 if (!ob)
1412 if (!ob) ob = GET_MAP_FACE_OBJ(mp, mx, my, layer); 1531 ob = GET_MAP_FACE_OBJ (mp, mx, my, layer);
1413 1532
1414 /* If there is no object for this space, or if the face for the object 1533 /* If there is no object for this space, or if the face for the object
1415 * is the blank face, set the face number to zero. 1534 * is the blank face, set the face number to zero.
1416 * else if we have the stored head object for this space, that takes 1535 * else if we have the stored head object for this space, that takes
1417 * precedence over the other object for this space. 1536 * precedence over the other object for this space.
1418 * otherwise, we do special head processing 1537 * otherwise, we do special head processing
1419 */ 1538 */
1420 if (!ob || ob->face == blank_face) face_num=0; 1539 if (!ob || ob->face == blank_face)
1540 face_num = 0;
1421 else if (head){ 1541 else if (head)
1542 {
1422 /* if this is a head that had previously been stored */ 1543 /* if this is a head that had previously been stored */
1423 face_num = ob->face->number; 1544 face_num = ob->face->number;
1424 } else { 1545 }
1546 else
1547 {
1425 /* if the faces for the different parts of a multipart object 1548 /* if the faces for the different parts of a multipart object
1426 * are the same, we only want to send the bottom right most 1549 * are the same, we only want to send the bottom right most
1427 * portion of the object. That info is in the tail_.. values 1550 * portion of the object. That info is in the tail_.. values
1428 * of the head. Note that for the head itself, ob->head will 1551 * of the head. Note that for the head itself, ob->head will
1429 * be null, so we only do this block if we are working on 1552 * be null, so we only do this block if we are working on
1430 * a tail piece. 1553 * a tail piece.
1431 */ 1554 */
1432 1555
1433 /* tail_x and tail_y will only be set in the head object. If 1556 /* tail_x and tail_y will only be set in the head object. If
1434 * this is the head object and these are set, we proceed 1557 * this is the head object and these are set, we proceed
1435 * with logic to only send bottom right. Similarly, if 1558 * with logic to only send bottom right. Similarly, if
1436 * this is one of the more parts but the head has those values 1559 * this is one of the more parts but the head has those values
1437 * set, we want to do the processing. There can be cases where 1560 * set, we want to do the processing. There can be cases where
1438 * the head is not visible but one of its parts is, so we just 1561 * the head is not visible but one of its parts is, so we just
1439 * can always expect that ob->arch->tail_x will be true for all 1562 * can always expect that ob->arch->tail_x will be true for all
1440 * object we may want to display. 1563 * object we may want to display.
1441 */ 1564 */
1442 if ((ob->arch->tail_x || ob->arch->tail_y) || 1565 if ((ob->arch->tail_x || ob->arch->tail_y) || (ob->head && (ob->head->arch->tail_x || ob->head->arch->tail_y)))
1443 (ob->head && (ob->head->arch->tail_x || ob->head->arch->tail_y))) { 1566 {
1444 1567
1445 if (ob->head) head = ob->head; 1568 if (ob->head)
1446 else head = ob; 1569 head = ob->head;
1570 else
1571 head = ob;
1447 1572
1448 /* Basically figure out where the offset is from where we are right 1573 /* Basically figure out where the offset is from where we are right
1449 * now. the ob->arch->clone.{x,y} values hold the offset that this current 1574 * now. the ob->arch->clone.{x,y} values hold the offset that this current
1450 * piece is from the head, and the tail is where the tail is from the 1575 * piece is from the head, and the tail is where the tail is from the
1451 * head. Note that bx and by will equal sx and sy if we are already working 1576 * head. Note that bx and by will equal sx and sy if we are already working
1452 * on the bottom right corner. If ob is the head, the clone values 1577 * on the bottom right corner. If ob is the head, the clone values
1453 * will be zero, so the right thing will still happen. 1578 * will be zero, so the right thing will still happen.
1454 */ 1579 */
1455 bx = sx + head->arch->tail_x - ob->arch->clone.x; 1580 bx = sx + head->arch->tail_x - ob->arch->clone.x;
1456 by = sy + head->arch->tail_y - ob->arch->clone.y; 1581 by = sy + head->arch->tail_y - ob->arch->clone.y;
1457 1582
1458 /* I don't think this can ever happen, but better to check for it just 1583 /* I don't think this can ever happen, but better to check for it just
1459 * in case. 1584 * in case.
1460 */ 1585 */
1461 if (bx < sx || by < sy) { 1586 if (bx < sx || by < sy)
1587 {
1462 LOG(llevError,"update_space: bx (%d) or by (%d) is less than sx (%d) or sy (%d)\n", 1588 LOG (llevError, "update_space: bx (%d) or by (%d) is less than sx (%d) or sy (%d)\n", bx, by, sx, sy);
1463 bx, by, sx, sy); 1589 face_num = 0;
1464 face_num = 0; 1590 }
1465 }
1466 /* single part object, multipart object with non merged faces, 1591 /* single part object, multipart object with non merged faces,
1467 * of multipart object already at lower right. 1592 * of multipart object already at lower right.
1468 */ 1593 */
1469 else if (bx == sx && by == sy) { 1594 else if (bx == sx && by == sy)
1595 {
1470 face_num = ob->face->number; 1596 face_num = ob->face->number;
1471 1597
1472 /* if this face matches one stored away, clear that one away. 1598 /* if this face matches one stored away, clear that one away.
1473 * this code relies on the fact that the map1 commands 1599 * this code relies on the fact that the map1 commands
1474 * goes from 2 down to 0. 1600 * goes from 2 down to 0.
1475 */ 1601 */
1476 for (i=0; i<MAP_LAYERS; i++) 1602 for (i = 0; i < MAP_LAYERS; i++)
1477 if (heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + i] && 1603 if (heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + i] &&
1478 heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + i]->face->number == face_num) 1604 heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + i]->face->number == face_num)
1479 heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + i] = NULL; 1605 heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + i] = NULL;
1480 } 1606 }
1481 else { 1607 else
1608 {
1482 /* If this head is stored away, clear it - otherwise, 1609 /* If this head is stored away, clear it - otherwise,
1483 * there can be cases where a object is on multiple layers - 1610 * there can be cases where a object is on multiple layers -
1484 * we only want to send it once. 1611 * we only want to send it once.
1485 */ 1612 */
1486 face_num = head->face->number; 1613 face_num = head->face->number;
1487 for (i=0; i<MAP_LAYERS; i++) 1614 for (i = 0; i < MAP_LAYERS; i++)
1488 if (heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i] && 1615 if (heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i] &&
1489 heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i]->face->number == face_num) 1616 heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i]->face->number == face_num)
1490 heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i] = NULL; 1617 heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i] = NULL;
1491 1618
1492 /* First, try to put the new head on the same layer. If that is used up, 1619 /* First, try to put the new head on the same layer. If that is used up,
1493 * then find another layer. 1620 * then find another layer.
1494 */ 1621 */
1495 if (heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + layer] == NULL) { 1622 if (heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + layer] == NULL)
1623 {
1496 heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + layer] = head; 1624 heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + layer] = head;
1497 } else for (i=0; i<MAX_LAYERS; i++) { 1625 }
1626 else
1627 for (i = 0; i < MAX_LAYERS; i++)
1628 {
1498 if (heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i] == NULL || 1629 if (heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i] == NULL ||
1499 heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i] == head) { 1630 heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i] == head)
1631 {
1500 heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i] = head; 1632 heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i] = head;
1501 } 1633 }
1502 } 1634 }
1503 face_num = 0; /* Don't send this object - we'll send the head later */ 1635 face_num = 0; /* Don't send this object - we'll send the head later */
1504 } 1636 }
1505 } else { 1637 }
1638 else
1639 {
1506 /* In this case, we are already at the lower right or single part object, 1640 /* In this case, we are already at the lower right or single part object,
1507 * so nothing special 1641 * so nothing special
1508 */ 1642 */
1509 face_num = ob->face->number; 1643 face_num = ob->face->number;
1510 1644
1511 /* clear out any head entries that have the same face as this one */ 1645 /* clear out any head entries that have the same face as this one */
1512 for (bx=0; bx<layer; bx++) 1646 for (bx = 0; bx < layer; bx++)
1513 if (heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + bx] && 1647 if (heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + bx] &&
1514 heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + bx]->face->number == face_num) 1648 heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + bx]->face->number == face_num)
1515 heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + bx] = NULL; 1649 heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + bx] = NULL;
1516 } 1650 }
1517 } /* else not already head object or blank face */ 1651 } /* else not already head object or blank face */
1518 1652
1519 /* This is a real hack. Basically, if we have nothing to send for this layer, 1653 /* This is a real hack. Basically, if we have nothing to send for this layer,
1520 * but there is a head on the next layer, send that instead. 1654 * but there is a head on the next layer, send that instead.
1521 * Without this, what happens is you can get the case where the player stands 1655 * Without this, what happens is you can get the case where the player stands
1522 * on the same space as the head. However, if you have overlapping big objects 1656 * on the same space as the head. However, if you have overlapping big objects
1523 * of the same type, what happens then is it doesn't think it needs to send 1657 * of the same type, what happens then is it doesn't think it needs to send
1524 * This tends to make stacking also work/look better. 1658 * This tends to make stacking also work/look better.
1525 */ 1659 */
1526 if (!face_num && layer > 0 && heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer -1]) { 1660 if (!face_num && layer > 0 && heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer - 1])
1661 {
1527 face_num = heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer -1]->face->number; 1662 face_num = heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer - 1]->face->number;
1528 heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer -1] = NULL; 1663 heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer - 1] = NULL;
1529 } 1664 }
1530 1665
1531 /* Another hack - because of heads and whatnot, this face may match one 1666 /* Another hack - because of heads and whatnot, this face may match one
1532 * we already sent for a lower layer. In that case, don't send 1667 * we already sent for a lower layer. In that case, don't send
1533 * this one. 1668 * this one.
1534 */ 1669 */
1535 if (face_num && layer+1<MAP_LAYERS && ns->lastmap.cells[sx][sy].faces[layer+1] == face_num) { 1670 if (face_num && layer + 1 < MAP_LAYERS && ns.lastmap.cells[sx][sy].faces[layer + 1] == face_num)
1536 face_num = 0; 1671 face_num = 0;
1537 }
1538 1672
1539 /* We've gotten what face we want to use for the object. Now see if 1673 /* We've gotten what face we want to use for the object. Now see if
1540 * if it has changed since we last sent it to the client. 1674 * if it has changed since we last sent it to the client.
1541 */ 1675 */
1542 if (ns->lastmap.cells[sx][sy].faces[layer] != face_num) { 1676 if (ns.lastmap.cells[sx][sy].faces[layer] != face_num)
1677 {
1543 ns->lastmap.cells[sx][sy].faces[layer] = face_num; 1678 ns.lastmap.cells[sx][sy].faces[layer] = face_num;
1544 if (!(ns->faces_sent[face_num] & NS_FACESENT_FACE)) 1679 if (!(ns.faces_sent[face_num] & NS_FACESENT_FACE))
1545 esrv_send_face(ns, face_num, 0); 1680 esrv_send_face (&ns, face_num, 0);
1546 SockList_AddShort(sl, face_num); 1681
1547 return 1; 1682 sl << uint16 (face_num);
1683 return 1;
1548 } 1684 }
1685
1549 /* Nothing changed */ 1686 /* Nothing changed */
1550 return 0; 1687 return 0;
1551} 1688}
1552 1689
1553/** 1690/**
1554 * This function is mainly a copy of update_space, 1691 * This function is mainly a copy of update_space,
1555 * except it handles update of the smoothing updates, 1692 * except it handles update of the smoothing updates,
1567 * layer is the layer to update, with 2 being the floor and 0 the 1704 * layer is the layer to update, with 2 being the floor and 0 the
1568 * top layer (this matches what the GET_MAP_FACE and GET_MAP_FACE_OBJ 1705 * top layer (this matches what the GET_MAP_FACE and GET_MAP_FACE_OBJ
1569 * take. 1706 * take.
1570 */ 1707 */
1571 1708
1572static inline int update_smooth(SockList *sl, NewSocket *ns, mapstruct *mp, int mx, int my, int sx, int sy, int layer) 1709static inline int
1710update_smooth (packet &sl, client &ns, maptile *mp, int mx, int my, int sx, int sy, int layer)
1573{ 1711{
1574 object *ob; 1712 object *ob;
1575 int smoothlevel; /* old face_num;*/ 1713 int smoothlevel; /* old face_num; */
1576 1714
1577 ob = GET_MAP_FACE_OBJ(mp, mx, my, layer); 1715 ob = GET_MAP_FACE_OBJ (mp, mx, my, layer);
1578 1716
1579 /* If there is no object for this space, or if the face for the object 1717 /* If there is no object for this space, or if the face for the object
1580 * is the blank face, set the smoothlevel to zero. 1718 * is the blank face, set the smoothlevel to zero.
1581 */ 1719 */
1582 if (!ob || ob->face == blank_face || MAP_NOSMOOTH(mp)) smoothlevel=0; 1720 if (!ob || ob->face == blank_face || MAP_NOSMOOTH (mp))
1721 smoothlevel = 0;
1583 else { 1722 else
1723 {
1584 smoothlevel = ob->smoothlevel; 1724 smoothlevel = ob->smoothlevel;
1585 if (smoothlevel && !(ns->faces_sent[ob->face->number] & NS_FACESENT_SMOOTH)) 1725 if (smoothlevel && !(ns.faces_sent[ob->face->number] & NS_FACESENT_SMOOTH))
1586 SendSmooth(ns, ob->face->number); 1726 SendSmooth (&ns, ob->face->number);
1587 } /* else not already head object or blank face */ 1727 } /* else not already head object or blank face */
1588 1728
1589 /* We've gotten what face we want to use for the object. Now see if 1729 /* We've gotten what face we want to use for the object. Now see if
1590 * if it has changed since we last sent it to the client. 1730 * if it has changed since we last sent it to the client.
1591 */ 1731 */
1592 if (smoothlevel>255) 1732 if (smoothlevel > 255)
1593 smoothlevel=255; 1733 smoothlevel = 255;
1594 else if (smoothlevel<0) 1734 else if (smoothlevel < 0)
1595 smoothlevel=0; 1735 smoothlevel = 0;
1736
1596 if (ns->lastmap.cells[sx][sy].smooth[layer] != smoothlevel) { 1737 if (ns.lastmap.cells[sx][sy].smooth[layer] != smoothlevel)
1738 {
1597 ns->lastmap.cells[sx][sy].smooth[layer] = smoothlevel; 1739 ns.lastmap.cells[sx][sy].smooth[layer] = smoothlevel;
1598 SockList_AddChar(sl, (uint8) (smoothlevel&0xFF)); 1740 sl << uint8 (smoothlevel);
1599 return 1; 1741 return 1;
1600 } 1742 }
1743
1601 /* Nothing changed */ 1744 /* Nothing changed */
1602 return 0; 1745 return 0;
1603} 1746}
1604 1747
1605/** 1748/**
1606 * Returns the size of a data for a map square as returned by 1749 * Returns the size of a data for a map square as returned by
1607 * mapextended. There are CLIENTMAPX*CLIENTMAPY*LAYERS entries 1750 * mapextended. There are CLIENTMAPX*CLIENTMAPY*LAYERS entries
1608 * available. 1751 * available.
1609 */ 1752 */
1753int
1610int getExtendedMapInfoSize(NewSocket* ns){ 1754getExtendedMapInfoSize (client * ns)
1755{
1611 int result=0; 1756 int result = 0;
1757
1612 if (ns->ext_mapinfos){ 1758 if (ns->ext_mapinfos)
1759 {
1613 if (ns->EMI_smooth) 1760 if (ns->EMI_smooth)
1614 result+=1; /*One byte for smoothlevel*/ 1761 result += 1; /*One byte for smoothlevel */
1615 } 1762 }
1616 return result; 1763 return result;
1617} 1764}
1765
1618/** 1766/**
1619 * This function uses the new map1 protocol command to send the map 1767 * This function uses the new map1 protocol command to send the map
1620 * to the client. It is necessary because the old map command supports 1768 * to the client. It is necessary because the old map command supports
1621 * a maximum map size of 15x15. 1769 * a maximum map size of 15x15.
1622 * This function is much simpler than the old one. This is because 1770 * This function is much simpler than the old one. This is because
1635 * we use the count value to hold the darkness value. If -1, then this space 1783 * we use the count value to hold the darkness value. If -1, then this space
1636 * is not viewable. 1784 * is not viewable.
1637 * we use faces[0] faces[1] faces[2] to hold what the three layers 1785 * we use faces[0] faces[1] faces[2] to hold what the three layers
1638 * look like. 1786 * look like.
1639 */ 1787 */
1788void
1640void draw_client_map1(object *pl) 1789draw_client_map1 (object *pl)
1641{ 1790{
1642 int x,y,ax, ay, d, startlen, max_x, max_y, oldlen; 1791 int x, y, ax, ay, d, startlen, max_x, max_y, oldlen;
1643 sint16 nx, ny; 1792 sint16 nx, ny;
1644 int estartlen, eoldlen; 1793 int estartlen, eoldlen;
1645 SockList sl;
1646 SockList esl; /*For extended Map info*/
1647 uint16 mask,emask; 1794 uint16 mask, emask;
1648 uint8 eentrysize; 1795 uint8 eentrysize;
1649 uint16 ewhatstart,ewhatflag; 1796 uint16 ewhatstart, ewhatflag;
1650 uint8 extendedinfos; 1797 uint8 extendedinfos;
1651 mapstruct *m; 1798 maptile *m;
1799
1652 NewSocket &socket = pl->contr->socket; 1800 client &socket = *pl->contr->socket;
1653 1801
1654 check_map_change (pl->contr); 1802 check_map_change (pl->contr);
1655 1803
1656 sl.buf=(unsigned char*)malloc(MAXSOCKBUF); 1804 packet sl;
1657 if (socket.mapmode == Map1Cmd) 1805 packet esl;
1658 strcpy((char*)sl.buf,"map1 "); 1806
1659 else 1807 sl << (socket.mapmode == Map1Cmd ? "map1 " : "map1a ");
1660 strcpy((char*)sl.buf,"map1a ");
1661 sl.len=strlen((char*)sl.buf);
1662 startlen = sl.len; 1808 startlen = sl.length ();
1809
1663 /*Extendedmapinfo structure initialisation*/ 1810 /*Extendedmapinfo structure initialisation */
1664 if (socket.ext_mapinfos){ 1811 if (socket.ext_mapinfos)
1665 esl.buf=(unsigned char*)malloc(MAXSOCKBUF); 1812 {
1666 strcpy((char*)esl.buf,"mapextended ");
1667 esl.len=strlen((char*)esl.buf);
1668 extendedinfos=EMI_NOREDRAW; 1813 extendedinfos = EMI_NOREDRAW;
1814
1669 if (socket.EMI_smooth) 1815 if (socket.EMI_smooth)
1670 extendedinfos|=EMI_SMOOTH; 1816 extendedinfos |= EMI_SMOOTH;
1817
1671 ewhatstart=esl.len; 1818 ewhatstart = esl.length ();
1672 ewhatflag=extendedinfos; /*The EMI_NOREDRAW bit 1819 ewhatflag = extendedinfos; /*The EMI_NOREDRAW bit
1673 could need to be taken away*/ 1820 could need to be taken away */
1674 SockList_AddChar(&esl, extendedinfos);
1675 eentrysize=getExtendedMapInfoSize(&socket); 1821 eentrysize = getExtendedMapInfoSize (&socket);
1676 SockList_AddChar(&esl, eentrysize); 1822 esl << "mapextended "
1823 << uint8 (extendedinfos)
1824 << uint8 (eentrysize);
1825
1677 estartlen = esl.len; 1826 estartlen = esl.length ();
1678 } else { 1827 }
1828 else
1829 {
1679 /* suppress compiler warnings */ 1830 /* suppress compiler warnings */
1680 ewhatstart = 0; 1831 ewhatstart = 0;
1681 ewhatflag = 0; 1832 ewhatflag = 0;
1682 estartlen = 0; 1833 estartlen = 0;
1683 } 1834 }
1835
1684 /* Init data to zero */ 1836 /* Init data to zero */
1685 memset(heads, 0, sizeof(object *) * MAX_HEAD_POS * MAX_HEAD_POS * MAX_LAYERS); 1837 memset (heads, 0, sizeof (object *) * MAX_HEAD_POS * MAX_HEAD_POS * MAX_LAYERS);
1686 1838
1687 /* x,y are the real map locations. ax, ay are viewport relative 1839 /* x,y are the real map locations. ax, ay are viewport relative
1688 * locations. 1840 * locations.
1689 */ 1841 */
1690 ay=0; 1842 ay = 0;
1691 1843
1692 /* We could do this logic as conditionals in the if statement, 1844 /* We could do this logic as conditionals in the if statement,
1693 * but that started to get a bit messy to look at. 1845 * but that started to get a bit messy to look at.
1694 */ 1846 */
1695 max_x = pl->x+(socket.mapx+1)/2; 1847 max_x = pl->x + (socket.mapx + 1) / 2;
1696 max_y = pl->y+(socket.mapy+1)/2; 1848 max_y = pl->y + (socket.mapy + 1) / 2;
1849
1697 if (socket.mapmode == Map1aCmd) { 1850 if (socket.mapmode == Map1aCmd)
1851 {
1698 max_x += MAX_HEAD_OFFSET; 1852 max_x += MAX_HEAD_OFFSET;
1699 max_y += MAX_HEAD_OFFSET; 1853 max_y += MAX_HEAD_OFFSET;
1700 } 1854 }
1701 1855
1702 for(y=pl->y-socket.mapy/2; y<max_y; y++,ay++) { 1856 for (y = pl->y - socket.mapy / 2; y < max_y; y++, ay++)
1703 ax=0; 1857 {
1858 ax = 0;
1704 for(x=pl->x-socket.mapx/2;x<max_x;x++,ax++) { 1859 for (x = pl->x - socket.mapx / 2; x < max_x; x++, ax++)
1860 {
1705 1861
1706 emask = mask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4; 1862 emask = mask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4;
1707 1863
1708 /* If this space is out of the normal viewable area, we only check 1864 /* If this space is out of the normal viewable area, we only check
1709 * the heads value ax or ay will only be greater than what 1865 * the heads value ax or ay will only be greater than what
1710 * the client wants if using the map1a command - this is because 1866 * the client wants if using the map1a command - this is because
1711 * if the map1a command is not used, max_x and max_y will be 1867 * if the map1a command is not used, max_x and max_y will be
1712 * set to lower values. 1868 * set to lower values.
1713 */ 1869 */
1714 if (ax >= socket.mapx || ay >= socket.mapy) { 1870 if (ax >= socket.mapx || ay >= socket.mapy)
1715 int i, got_one; 1871 {
1872 int i, got_one;
1716 1873
1717 oldlen = sl.len; 1874 oldlen = sl.length ();
1718 1875
1719 SockList_AddShort(&sl, mask); 1876 sl << uint16 (mask);
1720 1877
1721 if (check_head (sl, socket, ax, ay, 2)) 1878 if (check_head (sl, socket, ax, ay, 2)) mask |= 0x4;
1722 mask |= 0x4; 1879 if (check_head (sl, socket, ax, ay, 1)) mask |= 0x2;
1723 if (check_head (sl, socket, ax, ay, 1)) 1880 if (check_head (sl, socket, ax, ay, 0)) mask |= 0x1;
1724 mask |= 0x2;
1725 if (check_head (sl, socket, ax, ay, 0))
1726 mask |= 0x1;
1727 1881
1728 /* If all we are doing is sending 0 (blank) faces, we don't 1882 /* If all we are doing is sending 0 (blank) faces, we don't
1729 * actually need to send that - just the coordinates 1883 * actually need to send that - just the coordinates
1730 * with no faces tells the client to blank out the 1884 * with no faces tells the client to blank out the
1731 * space. 1885 * space.
1732 */ 1886 */
1733 got_one=0; 1887 got_one = 0;
1734 for (i=oldlen+2; i<sl.len; i++) { 1888 for (i = oldlen + 2; i < sl.length (); i++)
1735 if (sl.buf[i]) got_one=1; 1889 if (sl[i])
1736 } 1890 got_one = 1;
1737 1891
1738 if (got_one && (mask & 0xf)) { 1892 if (got_one && (mask & 0xf))
1739 sl.buf[oldlen+1] = mask & 0xff; 1893 sl[oldlen + 1] = mask & 0xff;
1740 } else { /*either all faces blank, either no face at all*/ 1894 else
1895 { /*either all faces blank, either no face at all */
1741 if (mask & 0xf) /*at least 1 face, we know it's blank, only send coordinates*/ 1896 if (mask & 0xf) /*at least 1 face, we know it's blank, only send coordinates */
1742 sl.len = oldlen + 2; 1897 sl.reset (oldlen + 2);
1743 else 1898 else
1744 sl.len = oldlen; 1899 sl.reset (oldlen);
1745 } 1900 }
1901
1746 /*What concerns extendinfos, nothing to be done for now 1902 /*What concerns extendinfos, nothing to be done for now
1747 * (perhaps effects layer later) 1903 * (perhaps effects layer later)
1748 */ 1904 */
1749 continue; /* don't do processing below */ 1905 continue; /* don't do processing below */
1750 } 1906 }
1751 1907
1752 MapCell &lastcell = socket.lastmap.cells[ax][ay]; 1908 MapCell &lastcell = socket.lastmap.cells[ax][ay];
1753 1909
1754 d = pl->contr->blocked_los[ax][ay]; 1910 d = pl->contr->blocked_los[ax][ay];
1755 1911
1756 /* If the coordinates are not valid, or it is too dark to see, 1912 /* If the coordinates are not valid, or it is too dark to see,
1757 * we tell the client as such 1913 * we tell the client as such
1758 */ 1914 */
1759 nx=x; 1915 nx = x;
1760 ny=y; 1916 ny = y;
1761 m = get_map_from_coord(pl->map, &nx, &ny); 1917 m = get_map_from_coord (pl->map, &nx, &ny);
1762 if (!m) { 1918
1919 if (!m)
1920 {
1763 /* space is out of map. Update space and clear values 1921 /* space is out of map. Update space and clear values
1764 * if this hasn't already been done. If the space is out 1922 * if this hasn't already been done. If the space is out
1765 * of the map, it shouldn't have a head 1923 * of the map, it shouldn't have a head
1766 */ 1924 */
1767 if (lastcell.count != -1) { 1925 if (lastcell.count != -1)
1768 SockList_AddShort(&sl, mask); 1926 {
1927 sl << uint16 (mask);
1769 map_clearcell(&lastcell,0,0,0,-1); 1928 map_clearcell (&lastcell, 0, 0, 0, -1);
1770 } 1929 }
1771 } else if (d>3) { 1930 }
1772 int need_send=0, count; 1931 else if (d > 3)
1932 {
1933 int need_send = 0, count;
1934
1773 /* This block deals with spaces that are not visible for whatever 1935 /* This block deals with spaces that are not visible for whatever
1774 * reason. Still may need to send the head for this space. 1936 * reason. Still may need to send the head for this space.
1775 */ 1937 */
1776 1938
1777 oldlen = sl.len; 1939 oldlen = sl.length ();
1778 1940
1779 SockList_AddShort(&sl, mask); 1941 sl << uint16 (mask);
1942
1780 if (lastcell.count != -1) need_send=1; 1943 if (lastcell.count != -1)
1944 need_send = 1;
1945
1781 count = -1; 1946 count = -1;
1782 1947
1783 if (socket.mapmode == Map1aCmd && have_head(ax, ay)) { 1948 if (socket.mapmode == Map1aCmd && have_head (ax, ay))
1949 {
1784 /* Now check to see if any heads need to be sent */ 1950 /* Now check to see if any heads need to be sent */
1785 1951
1786 if (check_head (sl, socket, ax, ay, 2)) 1952 if (check_head (sl, socket, ax, ay, 2)) mask |= 0x4;
1787 mask |= 0x4; 1953 if (check_head (sl, socket, ax, ay, 1)) mask |= 0x2;
1788 if (check_head (sl, socket, ax, ay, 1)) 1954 if (check_head (sl, socket, ax, ay, 0)) mask |= 0x1;
1789 mask |= 0x2;
1790 if (check_head (sl, socket, ax, ay, 0))
1791 mask |= 0x1;
1792 1955
1793 lastcell.count = count; 1956 lastcell.count = count;
1794 1957 }
1795 } else { 1958 else
1796 struct MapCell *cell = &lastcell; 1959 {
1797 /* properly clear a previously sent big face */ 1960 /* properly clear a previously sent big face */
1798 if(cell->faces[0] != 0 1961 if (lastcell.faces[0] != 0 || lastcell.faces[1] != 0 || lastcell.faces[2] != 0
1799 || cell->faces[1] != 0 1962 || lastcell.stat_hp || lastcell.flags || lastcell.player)
1800 || cell->faces[2] != 0) 1963 need_send = 1;
1801 need_send = 1; 1964
1802 map_clearcell(&lastcell, 0, 0, 0, count); 1965 map_clearcell (&lastcell, 0, 0, 0, count);
1803 } 1966 }
1804 1967
1805 if ((mask & 0xf) || need_send) { 1968 if ((mask & 0xf) || need_send)
1806 sl.buf[oldlen+1] = mask & 0xff; 1969 sl[oldlen + 1] = mask & 0xff;
1807 } else { 1970 else
1808 sl.len = oldlen; 1971 sl.reset (oldlen);
1809 } 1972 }
1810 } else { 1973 else
1974 {
1811 /* In this block, the space is visible or there are head objects 1975 /* In this block, the space is visible or there are head objects
1812 * we need to send. 1976 * we need to send.
1813 */ 1977 */
1814 1978
1815 /* Rather than try to figure out what everything that we might 1979 /* Rather than try to figure out what everything that we might
1816 * need to send is, then form the packet after that, 1980 * need to send is, then form the packet after that,
1817 * we presume that we will in fact form a packet, and update 1981 * we presume that we will in fact form a packet, and update
1818 * the bits by what we do actually send. If we send nothing, 1982 * the bits by what we do actually send. If we send nothing,
1819 * we just back out sl.len to the old value, and no harm 1983 * we just back out sl.length () to the old value, and no harm
1820 * is done. 1984 * is done.
1821 * I think this is simpler than doing a bunch of checks to see 1985 * I think this is simpler than doing a bunch of checks to see
1822 * what if anything we need to send, setting the bits, then 1986 * what if anything we need to send, setting the bits, then
1823 * doing those checks again to add the real data. 1987 * doing those checks again to add the real data.
1824 */ 1988 */
1825 oldlen = sl.len; 1989 oldlen = sl.length ();
1826 mask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4; 1990 mask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4;
1827 eoldlen = esl.len; 1991 eoldlen = esl.length ();
1828 emask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4; 1992 emask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4;
1829 SockList_AddShort(&sl, mask); 1993 sl << uint16 (mask);
1830 1994
1831 if (socket.ext_mapinfos) 1995 if (socket.ext_mapinfos)
1832 SockList_AddShort(&esl, emask); 1996 esl << uint16 (emask);
1833 1997
1834 unsigned char dummy; 1998 unsigned char dummy;
1835 unsigned char *last_ext = &dummy; 1999 unsigned char *last_ext = &dummy;
1836 2000
1837 /* Darkness changed */ 2001 /* Darkness changed */
1838 if (lastcell.count != d && socket.darkness) { 2002 if (lastcell.count != d && socket.darkness)
1839 mask |= 0x8; 2003 {
2004 mask |= 0x8;
1840 2005
1841 if (socket.extmap) 2006 if (socket.extmap)
1842 { 2007 {
1843 *last_ext |= 0x80; last_ext = sl.buf + sl.len; SockList_AddChar (&sl, d); 2008 *last_ext |= 0x80;
2009 last_ext = &sl[sl.length ()];
2010 sl << uint8 (d);
1844 } 2011 }
1845 else 2012 else
1846 SockList_AddChar (&sl, 255 - 64 * d); 2013 sl << uint8 (255 - 64 * d);
1847 } 2014 }
1848 2015
1849 lastcell.count = d; 2016 lastcell.count = d;
1850 2017
1851 if (socket.extmap) 2018 if (socket.extmap)
1852 { 2019 {
1853 uint8 stat_hp = 0; 2020 uint8 stat_hp = 0;
1854 uint8 stat_width = 0; 2021 uint8 stat_width = 0;
2022 uint8 flags = 0;
1855 tag_t player = 0; 2023 UUID player = 0;
1856 2024
1857 // send hp information, if applicable 2025 // send hp information, if applicable
1858 if (object *op = GET_MAP_FACE_OBJ (m, nx, ny, 0)) 2026 if (object *op = GET_MAP_FACE_OBJ (m, nx, ny, 0))
1859 { 2027 {
1860 if (op->head || op->invisible) 2028 if (op->head || op->invisible)
1861 ; // do not show 2029 ; // do not show
1862 else if (op->type == PLAYER 2030 else if (op->type == PLAYER
1863 || QUERY_FLAG (op, FLAG_MONSTER) 2031 || QUERY_FLAG (op, FLAG_MONSTER) || QUERY_FLAG (op, FLAG_ALIVE) || QUERY_FLAG (op, FLAG_GENERATOR))
1864 || QUERY_FLAG (op, FLAG_ALIVE)
1865 || QUERY_FLAG (op, FLAG_GENERATOR))
1866 { 2032 {
1867 if (op->stats.maxhp > 0 2033 if (op->stats.maxhp > 0 && (unsigned) op->stats.maxhp > (unsigned) op->stats.hp)
1868 && (unsigned)op->stats.maxhp > (unsigned)op->stats.hp)
1869 { 2034 {
1870 stat_hp = 255 - (op->stats.hp * 255 + 254) / op->stats.maxhp; 2035 stat_hp = 255 - (op->stats.hp * 255 + 254) / op->stats.maxhp;
1871 stat_width = op->arch->tail_x; 2036 stat_width = op->arch->tail_x;
1872 } 2037 }
1873 } 2038 }
1874 2039
2040 if (op->msg && op->msg[0] == '@')
2041 flags |= 1;
2042
1875 if (op->type == PLAYER && op != pl) 2043 if (op->type == PLAYER && op != pl)
1876 player = op->count; 2044 player = op->count;
1877 } 2045 }
1878 2046
1879 if (lastcell.stat_hp != stat_hp && 0) 2047 if (lastcell.stat_hp != stat_hp)
1880 { 2048 {
1881 lastcell.stat_hp = stat_hp; 2049 lastcell.stat_hp = stat_hp;
1882 2050
1883 mask |= 0x8; 2051 mask |= 0x8;
1884 *last_ext |= 0x80; last_ext = sl.buf + sl.len; SockList_AddChar (&sl, 5); 2052 *last_ext |= 0x80;
1885 SockList_AddChar (&sl, stat_hp); 2053 last_ext = &sl[sl.length ()];
1886 2054
2055 sl << uint8 (5) << uint8 (stat_hp);
2056
1887 if (stat_width > 1) 2057 if (stat_width > 1)
1888 { 2058 {
1889 *last_ext |= 0x80; last_ext = sl.buf + sl.len; SockList_AddChar (&sl, 6); 2059 *last_ext |= 0x80;
1890 SockList_AddChar (&sl, stat_width); 2060 last_ext = &sl[sl.length ()];
2061
2062 sl << uint8 (6) << uint8 (stat_width);
1891 } 2063 }
1892 } 2064 }
1893 2065
1894 if (lastcell.player != player && 0) 2066 if (lastcell.player != player)
1895 { 2067 {
1896 lastcell.player = player; 2068 lastcell.player = player;
2069
1897 mask |= 0x8; 2070 mask |= 0x8;
1898 *last_ext |= 0x80; last_ext = sl.buf + sl.len; SockList_AddChar (&sl, 0x47); 2071 *last_ext |= 0x80;
1899 SockList_AddChar (&sl, 4); 2072 last_ext = &sl[sl.length ()];
1900 SockList_AddInt (&sl, player); 2073
2074 sl << uint8 (0x47) << uint8 (8) << (uint64)player;
1901 } 2075 }
2076
2077 if (lastcell.flags != flags)
2078 {
2079 lastcell.flags = flags;
2080
2081 mask |= 0x8;
2082 *last_ext |= 0x80;
2083 last_ext = &sl[sl.length ()];
2084
2085 sl << uint8 (8) << uint8 (flags);
1902 } 2086 }
2087 }
1903 2088
1904 /* Floor face */ 2089 /* Floor face */
1905 if (update_space(&sl, &socket, m, nx, ny, ax, ay, 2)) 2090 if (update_space (sl, socket, m, nx, ny, ax, ay, 2))
1906 mask |= 0x4; 2091 mask |= 0x4;
1907 2092
1908 if (socket.EMI_smooth) 2093 if (socket.EMI_smooth)
1909 if (update_smooth(&esl, &socket, m, nx, ny, ax, ay, 2)) 2094 if (update_smooth (esl, socket, m, nx, ny, ax, ay, 2))
1910 emask |= 0x4; 2095 emask |= 0x4;
1911 2096
1912 /* Middle face */ 2097 /* Middle face */
1913 if (update_space(&sl, &socket, m, nx, ny, ax, ay, 1)) 2098 if (update_space (sl, socket, m, nx, ny, ax, ay, 1))
1914 mask |= 0x2; 2099 mask |= 0x2;
1915 2100
1916 if (socket.EMI_smooth) 2101 if (socket.EMI_smooth)
1917 if (update_smooth(&esl, &socket, m, nx, ny, ax, ay, 1)) 2102 if (update_smooth (esl, socket, m, nx, ny, ax, ay, 1))
1918 emask |= 0x2; 2103 emask |= 0x2;
1919 2104
1920 if(nx == pl->x && ny == pl->y && pl->invisible & (pl->invisible < 50 ? 4 : 1)) { 2105 if (nx == pl->x && ny == pl->y && pl->invisible & (pl->invisible < 50 ? 4 : 1))
2106 {
1921 if (lastcell.faces[0] != pl->face->number) { 2107 if (lastcell.faces[0] != pl->face->number)
1922 lastcell.faces[0] = pl->face->number; 2108 {
1923 mask |= 0x1; 2109 lastcell.faces[0] = pl->face->number;
2110 mask |= 0x1;
2111
1924 if (!(socket.faces_sent[pl->face->number] &NS_FACESENT_FACE)) 2112 if (!(socket.faces_sent[pl->face->number] & NS_FACESENT_FACE))
1925 esrv_send_face(&socket, pl->face->number, 0); 2113 esrv_send_face (&socket, pl->face->number, 0);
1926 SockList_AddShort(&sl, pl->face->number); 2114
1927 } 2115 sl << uint16 (pl->face->number);
1928 } 2116 }
1929 /* Top face */ 2117 }
1930 else { 2118 else
2119 {
2120 /* Top face */
1931 if (update_space(&sl, &socket, m, nx, ny, ax, ay, 0)) 2121 if (update_space (sl, socket, m, nx, ny, ax, ay, 0))
1932 mask |= 0x1; 2122 mask |= 0x1;
2123
1933 if (socket.EMI_smooth) 2124 if (socket.EMI_smooth)
1934 if (update_smooth(&esl, &socket, m, nx, ny, ax, ay, 0)){ 2125 if (update_smooth (esl, socket, m, nx, ny, ax, ay, 0))
1935 emask |= 0x1; 2126 emask |= 0x1;
1936 } 2127 }
1937 } 2128
1938 /* Check to see if we are in fact sending anything for this 2129 /* Check to see if we are in fact sending anything for this
1939 * space by checking the mask. If so, update the mask. 2130 * space by checking the mask. If so, update the mask.
1940 * if not, reset the len to that from before adding the mask 2131 * if not, reset the len to that from before adding the mask
1941 * value, so we don't send those bits. 2132 * value, so we don't send those bits.
1942 */ 2133 */
1943 if (mask & 0xf) { 2134 if (mask & 0xf)
1944 sl.buf[oldlen+1] = mask & 0xff; 2135 sl[oldlen + 1] = mask & 0xff;
1945 } else { 2136 else
1946 sl.len = oldlen; 2137 sl.reset (oldlen);
1947 } 2138
1948 if (emask & 0xf) { 2139 if (emask & 0xf)
1949 esl.buf[eoldlen+1] = emask & 0xff; 2140 esl[eoldlen + 1] = emask & 0xff;
1950 } else { 2141 else
1951 esl.len = eoldlen; 2142 esl.reset (eoldlen);
1952 }
1953 } /* else this is a viewable space */ 2143 } /* else this is a viewable space */
1954 } /* for x loop */ 2144 } /* for x loop */
1955 } /* for y loop */ 2145 } /* for y loop */
1956 2146
1957 /* Verify that we in fact do need to send this */ 2147 /* Verify that we in fact do need to send this */
1958 if (socket.ext_mapinfos){ 2148 if (socket.ext_mapinfos)
2149 {
1959 if (!(sl.len>startlen || socket.sent_scroll)){ 2150 if (!(sl.length () > startlen || socket.sent_scroll))
2151 {
1960 /* No map data will follow, so don't say the client 2152 /* No map data will follow, so don't say the client
1961 * it doesn't need draw! 2153 * it doesn't need draw!
1962 */ 2154 */
1963 ewhatflag&=(~EMI_NOREDRAW); 2155 ewhatflag &= (~EMI_NOREDRAW);
1964 esl.buf[ewhatstart+1] = ewhatflag & 0xff; 2156 esl[ewhatstart + 1] = ewhatflag & 0xff;
1965 } 2157 }
2158
1966 if (esl.len>estartlen) { 2159 if (esl.length () > estartlen)
1967 Send_With_Handling(&socket, &esl); 2160 socket.send_packet (esl);
1968 }
1969 free(esl.buf);
1970 } 2161 }
2162
1971 if (sl.len>startlen || socket.sent_scroll) { 2163 if (sl.length () > startlen || socket.sent_scroll)
1972 Send_With_Handling(&socket, &sl); 2164 {
2165 socket.send_packet (sl);
1973 socket.sent_scroll = 0; 2166 socket.sent_scroll = 0;
1974 } 2167 }
1975 free(sl.buf);
1976} 2168}
1977 2169
1978/** 2170/**
1979 * Draws client map. 2171 * Draws client map.
1980 */ 2172 */
2173void
1981void draw_client_map(object *pl) 2174draw_client_map (object *pl)
1982{ 2175{
1983 int i,j; 2176 int i, j;
1984 sint16 ax, ay, nx, ny;/* ax and ay goes from 0 to max-size of arrays */ 2177 sint16 ax, ay, nx, ny; /* ax and ay goes from 0 to max-size of arrays */
1985 New_Face *face,*floor; 2178 New_Face *face, *floor;
1986 New_Face *floor2; 2179 New_Face *floor2;
1987 int d, mflags; 2180 int d, mflags;
1988 struct Map newmap; 2181 struct Map newmap;
1989 mapstruct *m, *pm; 2182 maptile *m, *pm;
1990 2183
1991 if (pl->type != PLAYER) { 2184 if (pl->type != PLAYER)
2185 {
1992 LOG(llevError,"draw_client_map called with non player/non eric-server\n"); 2186 LOG (llevError, "draw_client_map called with non player/non eric-server\n");
1993 return; 2187 return;
1994 } 2188 }
1995 2189
1996 if (pl->contr->transport) {
1997 pm = pl->contr->transport->map;
1998 }
1999 else
2000 pm = pl->map; 2190 pm = pl->map;
2001 2191
2002 /* If player is just joining the game, he isn't here yet, so the map 2192 /* If player is just joining the game, he isn't here yet, so the map
2003 * can get swapped out. If so, don't try to send them a map. All will 2193 * can get swapped out. If so, don't try to send them a map. All will
2004 * be OK once they really log in. 2194 * be OK once they really log in.
2005 */ 2195 */
2006 if (pm==NULL || pm->in_memory!=MAP_IN_MEMORY) return; 2196 if (pm == NULL || pm->in_memory != MAP_IN_MEMORY)
2197 return;
2007 2198
2008 memset(&newmap, 0, sizeof(struct Map)); 2199 memset (&newmap, 0, sizeof (struct Map));
2009 2200
2010 for(j = (pl->y - pl->contr->socket.mapy/2) ; j < (pl->y + (pl->contr->socket.mapy+1)/2); j++) { 2201 for (j = (pl->y - pl->contr->socket->mapy / 2); j < (pl->y + (pl->contr->socket->mapy + 1) / 2); j++)
2202 {
2011 for(i = (pl->x - pl->contr->socket.mapx/2) ; i < (pl->x + (pl->contr->socket.mapx+1)/2); i++) { 2203 for (i = (pl->x - pl->contr->socket->mapx / 2); i < (pl->x + (pl->contr->socket->mapx + 1) / 2); i++)
2012 ax=i; 2204 {
2013 ay=j; 2205 ax = i;
2206 ay = j;
2014 m = pm; 2207 m = pm;
2015 mflags = get_map_flags(m, &m, ax, ay, &ax, &ay); 2208 mflags = get_map_flags (m, &m, ax, ay, &ax, &ay);
2016 if (mflags & P_OUT_OF_MAP) 2209 if (mflags & P_OUT_OF_MAP)
2017 continue; 2210 continue;
2018 if (mflags & P_NEED_UPDATE) 2211 if (mflags & P_NEED_UPDATE)
2019 update_position(m, ax, ay); 2212 update_position (m, ax, ay);
2020 /* If a map is visible to the player, we don't want to swap it out 2213 /* If a map is visible to the player, we don't want to swap it out
2021 * just to reload it. This should really call something like 2214 * just to reload it. This should really call something like
2022 * swap_map, but this is much more efficient and 'good enough' 2215 * swap_map, but this is much more efficient and 'good enough'
2023 */ 2216 */
2024 if (mflags & P_NEW_MAP) 2217 if (mflags & P_NEW_MAP)
2025 m->timeout = 50; 2218 m->timeout = 50;
2026 } 2219 }
2027 } 2220 }
2028 /* do LOS after calls to update_position */ 2221 /* do LOS after calls to update_position */
2029 if(pl->contr->do_los) { 2222 if (pl->contr->do_los)
2223 {
2030 update_los(pl); 2224 update_los (pl);
2031 pl->contr->do_los = 0; 2225 pl->contr->do_los = 0;
2032 } 2226 }
2033 2227
2034 if (pl->contr->socket.mapmode == Map1Cmd || pl->contr->socket.mapmode == Map1aCmd) {
2035 /* Big maps need a different drawing mechanism to work */ 2228 /* Big maps need a different drawing mechanism to work */
2036 draw_client_map1(pl); 2229 draw_client_map1 (pl);
2037 return;
2038 }
2039
2040 if(pl->invisible & (pl->invisible < 50 ? 4 : 1)) {
2041 esrv_map_setbelow(&pl->contr->socket,pl->contr->socket.mapx/2,
2042 pl->contr->socket.mapy/2,pl->face->number,&newmap);
2043 }
2044
2045 /* j and i are the y and x coordinates of the real map (which is
2046 * basically some number of spaces around the player)
2047 * ax and ay are values from within the viewport (ie, 0, 0 is upper
2048 * left corner) and are thus disconnected from the map values.
2049 * Subtract 1 from the max values so that we properly handle cases where
2050 * player has specified an even map. Otherwise, we try to send them too
2051 * much, ie, if mapx is 10, we would try to send from -5 to 5, which is actually
2052 * 11 spaces. Now, we would send from -5 to 4, which is properly. If mapx is
2053 * odd, this still works fine.
2054 */
2055 ay=0;
2056 for(j=pl->y-pl->contr->socket.mapy/2; j<=pl->y+(pl->contr->socket.mapy-1)/2;j++, ay++) {
2057 ax=0;
2058 for(i=pl->x-pl->contr->socket.mapx/2;i<=pl->x+(pl->contr->socket.mapx-1)/2;i++, ax++) {
2059
2060 d = pl->contr->blocked_los[ax][ay];
2061 /* note the out_of_map and d>3 checks are both within the same
2062 * negation check.
2063 */
2064 nx = i;
2065 ny = j;
2066 m = get_map_from_coord(pm, &nx, &ny);
2067 if (m && d<4) {
2068 face = GET_MAP_FACE(m, nx, ny,0);
2069 floor2 = GET_MAP_FACE(m, nx, ny,1);
2070 floor = GET_MAP_FACE(m, nx, ny,2);
2071
2072 /* If all is blank, send a blank face. */
2073 if ((!face || face == blank_face) &&
2074 (!floor2 || floor2 == blank_face) &&
2075 (!floor || floor == blank_face)) {
2076 esrv_map_setbelow(&pl->contr->socket,ax,ay,
2077 blank_face->number,&newmap);
2078 } else { /* actually have something interesting */
2079 /* send the darkness mask, if any. */
2080 if (d && pl->contr->socket.darkness)
2081 esrv_map_setbelow(&pl->contr->socket,ax,ay,
2082 dark_faces[d-1]->number,&newmap);
2083
2084 if (face && face != blank_face)
2085 esrv_map_setbelow(&pl->contr->socket,ax,ay,
2086 face->number,&newmap);
2087 if (floor2 && floor2 != blank_face)
2088 esrv_map_setbelow(&pl->contr->socket,ax,ay,
2089 floor2->number,&newmap);
2090 if (floor && floor != blank_face)
2091 esrv_map_setbelow(&pl->contr->socket,ax,ay,
2092 floor->number,&newmap);
2093 }
2094 } /* Is a valid space */
2095 }
2096 }
2097 esrv_map_doneredraw(&pl->contr->socket, &newmap);
2098
2099 check_map_change (pl->contr);
2100} 2230}
2101 2231
2102 2232
2103/*****************************************************************************/ 2233/*****************************************************************************/
2234
2104/* GROS: The following one is used to allow a plugin to send a generic cmd to*/ 2235/* GROS: The following one is used to allow a plugin to send a generic cmd to*/
2236
2105/* a player. Of course, the client need to know the command to be able to */ 2237/* a player. Of course, the client need to know the command to be able to */
2238
2106/* manage it ! */ 2239/* manage it ! */
2240
2107/*****************************************************************************/ 2241/*****************************************************************************/
2242void
2108void send_plugin_custom_message(object *pl, char *buf) 2243send_plugin_custom_message (object *pl, char *buf)
2109{ 2244{
2110 cs_write_string(&pl->contr->socket,buf,strlen(buf)); 2245 pl->contr->socket->send_packet (buf);
2111} 2246}
2112 2247
2113/** 2248/**
2114 * This sends the skill number to name mapping. We ignore 2249 * This sends the skill number to name mapping. We ignore
2115 * the params - we always send the same info no matter what. 2250 * the params - we always send the same info no matter what.
2116 */ 2251 */
2252void
2117void send_skill_info(NewSocket *ns, char *params) 2253send_skill_info (client *ns, char *params)
2118{ 2254{
2119 SockList sl; 2255 packet sl;
2120 int i; 2256 sl << "replyinfo skill_info\n";
2121 2257
2122 sl.buf = (unsigned char*) malloc(MAXSOCKBUF);
2123 strcpy((char*)sl.buf,"replyinfo skill_info\n");
2124 for (i=1; i< NUM_SKILLS; i++) { 2258 for (int i = 1; i < NUM_SKILLS; i++)
2125 sprintf((char*)sl.buf + strlen((char*)sl.buf), "%d:%s\n", i + CS_STAT_SKILLINFO, 2259 sl.printf ("%d:%s\n", i + CS_STAT_SKILLINFO, &skill_names[i]);
2126 skill_names[i]); 2260
2127 }
2128 sl.len = strlen((char*)sl.buf);
2129 if (sl.len >= MAXSOCKBUF) { 2261 if (sl.length () >= MAXSOCKBUF)
2262 {
2130 LOG(llevError,"Buffer overflow in send_skill_info!\n"); 2263 LOG (llevError, "Buffer overflow in send_skill_info!\n");
2131 fatal(0); 2264 fatal (0);
2132 } 2265 }
2133 Send_With_Handling(ns, &sl); 2266
2134 free(sl.buf); 2267 ns->send_packet (sl);
2135} 2268}
2136 2269
2137/** 2270/**
2138 * This sends the spell path to name mapping. We ignore 2271 * This sends the spell path to name mapping. We ignore
2139 * the params - we always send the same info no matter what. 2272 * the params - we always send the same info no matter what.
2140 */ 2273 */
2274void
2141void send_spell_paths (NewSocket *ns, char *params) { 2275send_spell_paths (client * ns, char *params)
2142 SockList sl; 2276{
2143 int i; 2277 packet sl;
2144 2278
2145 sl.buf = (unsigned char*) malloc(MAXSOCKBUF); 2279 sl << "replyinfo spell_paths\n";
2146 strcpy((char*)sl.buf,"replyinfo spell_paths\n"); 2280
2147 for(i=0; i<NRSPELLPATHS; i++) 2281 for (int i = 0; i < NRSPELLPATHS; i++)
2148 sprintf((char*)sl.buf + strlen((char*)sl.buf), "%d:%s\n", 1<<i, spellpathnames[i]); 2282 sl.printf ("%d:%s\n", 1 << i, spellpathnames[i]);
2149 sl.len = strlen((char*)sl.buf); 2283
2150 if (sl.len >= MAXSOCKBUF) { 2284 if (sl.length () >= MAXSOCKBUF)
2285 {
2151 LOG(llevError,"Buffer overflow in send_spell_paths!\n"); 2286 LOG (llevError, "Buffer overflow in send_spell_paths!\n");
2152 fatal(0); 2287 fatal (0);
2153 } 2288 }
2154 Send_With_Handling(ns, &sl); 2289
2155 free(sl.buf); 2290 ns->send_packet (sl);
2156} 2291}
2157 2292
2158/** 2293/**
2159 * This looks for any spells the player may have that have changed their stats. 2294 * This looks for any spells the player may have that have changed their stats.
2160 * it then sends an updspell packet for each spell that has changed in this way 2295 * it then sends an updspell packet for each spell that has changed in this way
2161 */ 2296 */
2297void
2162void esrv_update_spells(player *pl) { 2298esrv_update_spells (player *pl)
2163 SockList sl; 2299{
2164 int flags=0;
2165 object *spell;
2166 if (!pl->socket.monitor_spells) return; 2300 if (!pl->socket->monitor_spells)
2301 return;
2302
2167 for (spell=pl->ob->inv; spell!=NULL; spell=spell->below) { 2303 for (object *spell = pl->ob->inv; spell; spell = spell->below)
2304 {
2168 if (spell->type == SPELL) { 2305 if (spell->type == SPELL)
2306 {
2307 int flags = 0;
2308
2169 /* check if we need to update it*/ 2309 /* check if we need to update it */
2170 if (spell->last_sp != SP_level_spellpoint_cost(pl->ob, spell, SPELL_MANA)) { 2310 if (spell->last_sp != SP_level_spellpoint_cost (pl->ob, spell, SPELL_MANA))
2311 {
2171 spell->last_sp = SP_level_spellpoint_cost(pl->ob, spell, SPELL_MANA); 2312 spell->last_sp = SP_level_spellpoint_cost (pl->ob, spell, SPELL_MANA);
2172 flags |= UPD_SP_MANA; 2313 flags |= UPD_SP_MANA;
2173 } 2314 }
2315
2174 if (spell->last_grace != SP_level_spellpoint_cost(pl->ob, spell, SPELL_GRACE)) { 2316 if (spell->last_grace != SP_level_spellpoint_cost (pl->ob, spell, SPELL_GRACE))
2317 {
2175 spell->last_grace = SP_level_spellpoint_cost(pl->ob, spell, SPELL_GRACE); 2318 spell->last_grace = SP_level_spellpoint_cost (pl->ob, spell, SPELL_GRACE);
2176 flags |= UPD_SP_GRACE; 2319 flags |= UPD_SP_GRACE;
2177 } 2320 }
2321
2178 if (spell->last_eat != spell->stats.dam+SP_level_dam_adjust(pl->ob, spell)) { 2322 if (spell->last_eat != spell->stats.dam + SP_level_dam_adjust (pl->ob, spell))
2323 {
2179 spell->last_eat = spell->stats.dam+SP_level_dam_adjust(pl->ob, spell); 2324 spell->last_eat = spell->stats.dam + SP_level_dam_adjust (pl->ob, spell);
2180 flags |= UPD_SP_DAMAGE; 2325 flags |= UPD_SP_DAMAGE;
2326 }
2327
2328 if (flags)
2329 {
2330 packet sl;
2331
2332 sl << "updspell "
2333 << uint8 (flags)
2334 << uint32 (spell->count);
2335
2336 if (flags & UPD_SP_MANA ) sl << uint16 (spell->last_sp);
2337 if (flags & UPD_SP_GRACE ) sl << uint16 (spell->last_grace);
2338 if (flags & UPD_SP_DAMAGE) sl << uint16 (spell->last_eat);
2339
2340 pl->socket->send_packet (sl);
2341 }
2342 }
2181 } 2343 }
2182 if (flags !=0) {
2183 sl.buf =(unsigned char*) malloc(MAXSOCKBUF);
2184 strcpy((char*)sl.buf,"updspell ");
2185 sl.len=strlen((char*)sl.buf);
2186 SockList_AddChar(&sl, flags);
2187 SockList_AddInt(&sl, spell->count);
2188 if (flags & UPD_SP_MANA) SockList_AddShort(&sl, spell->last_sp);
2189 if (flags & UPD_SP_GRACE) SockList_AddShort(&sl, spell->last_grace);
2190 if (flags & UPD_SP_DAMAGE) SockList_AddShort(&sl, spell->last_eat);
2191 flags = 0;
2192 Send_With_Handling(&pl->socket, &sl);
2193 free(sl.buf);
2194 }
2195 }
2196 }
2197} 2344}
2198 2345
2346void
2199void esrv_remove_spell(player *pl, object *spell) { 2347esrv_remove_spell (player *pl, object *spell)
2200 SockList sl; 2348{
2201
2202 if (!pl->socket.monitor_spells) return; 2349 if (!pl->socket->monitor_spells)
2350 return;
2351
2203 if (!pl || !spell || spell->env != pl->ob) { 2352 if (!pl || !spell || spell->env != pl->ob)
2353 {
2204 LOG(llevError, "Invalid call to esrv_remove_spell"); 2354 LOG (llevError, "Invalid call to esrv_remove_spell");
2205 return; 2355 return;
2206 } 2356 }
2207 sl.buf = (unsigned char*) malloc(MAXSOCKBUF); 2357
2208 strcpy((char*)sl.buf,"delspell "); 2358 packet sl;
2209 sl.len=strlen((char*)sl.buf); 2359
2210 SockList_AddInt(&sl, spell->count); 2360 sl << "delspell "
2211 Send_With_Handling(&pl->socket, &sl); 2361 << uint32 (spell->count);
2212 free(sl.buf); 2362
2363 pl->socket->send_packet (sl);
2213} 2364}
2214 2365
2215/* appends the spell *spell to the Socklist we will send the data to. */ 2366/* appends the spell *spell to the Socklist we will send the data to. */
2367static void
2216static void append_spell (player *pl, SockList *sl, object *spell) { 2368append_spell (player *pl, packet &sl, object *spell)
2369{
2217 int len, i, skill=0; 2370 int len, i, skill = 0;
2218 2371
2219 if (!(spell->name)) { 2372 if (!(spell->name))
2373 {
2220 LOG(llevError, "item number %d is a spell with no name.\n", spell->count); 2374 LOG (llevError, "item number %d is a spell with no name.\n", spell->count);
2221 return; 2375 return;
2222 } 2376 }
2223 SockList_AddInt(sl, spell->count); 2377
2224 SockList_AddShort(sl, spell->level);
2225 SockList_AddShort(sl, spell->casting_time);
2226 /* store costs and damage in the object struct, to compare to later */ 2378 /* store costs and damage in the object struct, to compare to later */
2227 spell->last_sp = SP_level_spellpoint_cost(pl->ob, spell, SPELL_MANA); 2379 spell->last_sp = SP_level_spellpoint_cost (pl->ob, spell, SPELL_MANA);
2228 spell->last_grace = SP_level_spellpoint_cost(pl->ob, spell, SPELL_GRACE); 2380 spell->last_grace = SP_level_spellpoint_cost (pl->ob, spell, SPELL_GRACE);
2229 spell->last_eat = spell->stats.dam+SP_level_dam_adjust(pl->ob, spell); 2381 spell->last_eat = spell->stats.dam + SP_level_dam_adjust (pl->ob, spell);
2230 /* send the current values */
2231 SockList_AddShort(sl, spell->last_sp);
2232 SockList_AddShort(sl, spell->last_grace);
2233 SockList_AddShort(sl, spell->last_eat);
2234 2382
2235 /* figure out which skill it uses, if it uses one */ 2383 /* figure out which skill it uses, if it uses one */
2236 if (spell->skill) { 2384 if (spell->skill)
2385 {
2237 for (i=1; i< NUM_SKILLS; i++) 2386 for (i = 1; i < NUM_SKILLS; i++)
2238 if (!strcmp(spell->skill, skill_names[i])) { 2387 if (!strcmp (spell->skill, skill_names[i]))
2388 {
2239 skill = i+CS_STAT_SKILLINFO; 2389 skill = i + CS_STAT_SKILLINFO;
2240 break; 2390 break;
2391 }
2241 } 2392 }
2242 }
2243 SockList_AddChar(sl, skill);
2244 2393
2245 SockList_AddInt(sl, spell->path_attuned); 2394 /* send the current values */
2246 SockList_AddInt(sl, (spell->face)?spell->face->number:0); 2395 sl << uint32 (spell->count)
2247 2396 << uint16 (spell->level)
2248 len = strlen(spell->name); 2397 << uint16 (spell->casting_time)
2249 SockList_AddChar(sl, (char)len); 2398 << uint16 (spell->last_sp)
2250 memcpy(sl->buf+sl->len, spell->name, len); 2399 << uint16 (spell->last_grace)
2251 sl->len+=len; 2400 << uint16 (spell->last_eat)
2252 2401 << uint8 (skill)
2253 if (!spell->msg) { 2402 << uint32 (spell->path_attuned)
2254 SockList_AddShort(sl, 0); 2403 << uint32 (spell->face ? spell->face->number : 0)
2255 } 2404 << data8 (spell->name)
2256 else { 2405 << data16 (spell->msg);
2257 len = strlen(spell->msg);
2258 SockList_AddShort(sl, len);
2259 memcpy(sl->buf+sl->len, spell->msg, len);
2260 sl->len+=len;
2261 }
2262} 2406}
2263 2407
2264/** 2408/**
2265 * This tells the client to add the spell *ob, if *ob is NULL, then add 2409 * This tells the client to add the spell *ob, if *ob is NULL, then add
2266 * all spells in the player's inventory. 2410 * all spells in the player's inventory.
2267 */ 2411 */
2412void
2268void esrv_add_spells(player *pl, object *spell) { 2413esrv_add_spells (player *pl, object *spell)
2269 SockList sl; 2414{
2270 if (!pl) { 2415 if (!pl)
2416 {
2271 LOG(llevError, "esrv_add_spells, tried to add a spell to a NULL player"); 2417 LOG (llevError, "esrv_add_spells, tried to add a spell to a NULL player");
2272 return; 2418 return;
2273 } 2419 }
2420
2274 if (!pl->socket.monitor_spells) return; 2421 if (!pl->socket->monitor_spells)
2275 sl.buf = (unsigned char*) malloc(MAXSOCKBUF); 2422 return;
2276 strcpy((char*)sl.buf,"addspell "); 2423
2277 sl.len=strlen((char*)sl.buf); 2424 packet sl;
2425
2426 sl << "addspell ";
2427
2278 if (!spell) { 2428 if (!spell)
2429 {
2279 for (spell=pl->ob->inv; spell!=NULL; spell=spell->below) { 2430 for (spell = pl->ob->inv; spell != NULL; spell = spell->below)
2431 {
2280 /* were we to simply keep appending data here, we could exceed 2432 /* were we to simply keep appending data here, we could exceed
2281 * MAXSOCKBUF if the player has enough spells to add, we know that 2433 * MAXSOCKBUF if the player has enough spells to add, we know that
2282 * append_spells will always append 19 data bytes, plus 4 length 2434 * append_spells will always append 19 data bytes, plus 4 length
2283 * bytes and 3 strings (because that is the spec) so we need to 2435 * bytes and 3 strings (because that is the spec) so we need to
2284 * check that the length of those 3 strings, plus the 23 bytes, 2436 * check that the length of those 3 strings, plus the 23 bytes,
2285 * won't take us over the length limit for the socket, if it does, 2437 * won't take us over the length limit for the socket, if it does,
2286 * we need to send what we already have, and restart packet formation 2438 * we need to send what we already have, and restart packet formation
2287 */ 2439 */
2288 /* Seeing crashes by overflowed buffers. Quick arithemetic seems 2440 /* Seeing crashes by overflowed buffers. Quick arithemetic seems
2289 * to show add_spell is 26 bytes + 2 strings. However, the overun 2441 * to show add_spell is 26 bytes + 2 strings. However, the overun
2290 * is hundreds of bytes off, so correcting 22 vs 26 doesn't seem 2442 * is hundreds of bytes off, so correcting 22 vs 26 doesn't seem
2291 * like it will fix this 2443 * like it will fix this
2292 */ 2444 */
2293 if (spell->type != SPELL) continue; 2445 if (spell->type != SPELL)
2294 if (sl.len >= (MAXSOCKBUF - (26 + strlen(spell->name) + 2446 continue;
2295 (spell->msg?strlen(spell->msg):0)))) { 2447
2296 Send_With_Handling(&pl->socket, &sl); 2448 if (sl.length () >= (MAXSOCKBUF - (26 + strlen (spell->name) + (spell->msg ? strlen (spell->msg) : 0))))
2297 strcpy((char*)sl.buf,"addspell "); 2449 {
2298 sl.len=strlen((char*)sl.buf); 2450 pl->socket->send_packet (sl);
2451
2452 sl.reset ();
2453 sl << "addspell ";
2454 }
2455
2456 append_spell (pl, sl, spell);
2457 }
2299 } 2458 }
2459 else if (spell->type != SPELL)
2460 {
2461 LOG (llevError, "Asked to send a non-spell object as a spell");
2462 return;
2463 }
2464 else
2300 append_spell(pl, &sl, spell); 2465 append_spell (pl, sl, spell);
2301 } 2466
2302 }
2303 else if (spell->type != SPELL) {
2304 LOG(llevError, "Asked to send a non-spell object as a spell");
2305 return;
2306 }
2307 else append_spell(pl, &sl, spell);
2308 if (sl.len >= MAXSOCKBUF) { 2467 if (sl.length () >= MAXSOCKBUF)
2468 {
2309 LOG(llevError,"Buffer overflow in esrv_add_spells!\n"); 2469 LOG (llevError, "Buffer overflow in esrv_add_spells!\n");
2310 fatal(0); 2470 fatal (0);
2311 } 2471 }
2472
2312 /* finally, we can send the packet */ 2473 /* finally, we can send the packet */
2313 Send_With_Handling(&pl->socket, &sl); 2474 pl->socket->send_packet (sl);
2314 free(sl.buf);
2315} 2475}
2316 2476

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines