ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/socket/item.C
(Generate patch)

Comparing deliantra/server/socket/item.C (file contents):
Revision 1.5 by root, Sun Sep 10 13:43:33 2006 UTC vs.
Revision 1.17 by root, Thu Dec 14 01:59:10 2006 UTC

1
2/*
3 * static char *rcsid_item_c =
4 * "$Id: item.C,v 1.5 2006/09/10 13:43:33 root Exp $";
5 */
6
7/* 1/*
8 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
9 3
10 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
22 16
23 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 20
27 The author can be reached via e-mail to crossfire-devel@real-time.com 21 The author can be reached via e-mail to <crossfire@schmorp.de>
28*/ 22*/
29 23
30/** 24/**
31 * \file 25 * \file
32 * Client/server logic. 26 * Client/server logic.
51/******************************************************************************* 45/*******************************************************************************
52 * 46 *
53 * Functions related to sending object data to the client. 47 * Functions related to sending object data to the client.
54 * 48 *
55 ******************************************************************************/ 49 ******************************************************************************/
56
57/**
58 * Adds string to socklist.
59 *
60 * This is a simple function that we use a lot here. It basically
61 * adds the specified buffer into the socklist, but prepends a
62 * single byte in length. If the data is longer than that byte, it is
63 * truncated approprately.
64 */
65inline void
66add_stringlen_to_sockbuf (const char *buf, SockList * sl)
67{
68 int len;
69
70 len = strlen (buf);
71 if (len > 255)
72 len = 255;
73 SockList_AddChar (sl, (char) len);
74 strncpy ((char *) sl->buf + sl->len, buf, len);
75 sl->len += len;
76}
77 50
78/** 51/**
79 * This is a similar to query_name, but returns flags 52 * This is a similar to query_name, but returns flags
80 * to be sended to client. 53 * to be sended to client.
81 */ 54 */
136 flags |= F_LOCKED; 109 flags |= F_LOCKED;
137 110
138 return flags; 111 return flags;
139} 112}
140 113
141/* Used in the send_look to put object head into SockList 114/* Used in the send_look to put object head into packet
142 * sl for socket ns. Need socket to know if we need to send 115 * sl for socket ns. Need socket to know if we need to send
143 * animation of face to the client. 116 * animation of face to the client.
144 */ 117 */
145static void 118static void
146add_object_to_socklist (NewSocket * ns, SockList * sl, object *head) 119add_object_to_socklist (NewSocket &ns, packet &sl, object *head)
147{ 120{
148 int flags, len, anim_speed; 121 int flags, len, anim_speed;
149 char item_n[MAX_BUF]; 122 char item_n[MAX_BUF];
150 const char *item_p; 123 const char *item_p;
151 124
152 flags = query_flags (head); 125 flags = query_flags (head);
153 if (QUERY_FLAG (head, FLAG_NO_PICK)) 126 if (QUERY_FLAG (head, FLAG_NO_PICK))
154 flags |= F_NOPICK; 127 flags |= F_NOPICK;
155 128
156 if (!(ns->faces_sent[head->face->number] & NS_FACESENT_FACE)) 129 if (!(ns.faces_sent[head->face->number] & NS_FACESENT_FACE))
157 esrv_send_face (ns, head->face->number, 0); 130 esrv_send_face (&ns, head->face->number, 0);
158 131
159 if (QUERY_FLAG (head, FLAG_ANIMATE) && !ns->anims_sent[head->animation_id]) 132 if (QUERY_FLAG (head, FLAG_ANIMATE) && !ns.anims_sent[head->animation_id])
160 esrv_send_animation (ns, head->animation_id); 133 esrv_send_animation (&ns, head->animation_id);
161 134
162 SockList_AddInt (sl, head->count); 135 sl << uint32 (head->count)
163 SockList_AddInt (sl, flags); 136 << uint32 (flags)
164 SockList_AddInt (sl, QUERY_FLAG (head, FLAG_NO_PICK) ? -1 : WEIGHT (head)); 137 << uint32 (QUERY_FLAG (head, FLAG_NO_PICK) ? -1 : WEIGHT (head))
165 SockList_AddInt (sl, head->face->number); 138 << uint32 (head->face->number);
166 139
167 if (!head->custom_name) 140 if (!head->custom_name)
168 { 141 {
169 strncpy (item_n, query_base_name (head, 0), 127); 142 strncpy (item_n, query_base_name (head, 0), 127);
170 item_n[127] = 0; 143 item_n[127] = 0;
176 strncpy (item_n, head->custom_name, 127); 149 strncpy (item_n, head->custom_name, 127);
177 item_n[127] = 0; 150 item_n[127] = 0;
178 len = strlen (item_n); 151 len = strlen (item_n);
179 item_p = head->custom_name; 152 item_p = head->custom_name;
180 } 153 }
154
181 strncpy (item_n + len + 1, item_p, 127); 155 strncpy (item_n + len + 1, item_p, 127);
182 item_n[254] = 0; 156 item_n[254] = 0;
183 len += strlen (item_n + 1 + len) + 1; 157 len += strlen (item_n + 1 + len) + 1;
184 SockList_AddChar (sl, (char) len);
185 memcpy (sl->buf + sl->len, item_n, len);
186 sl->len += len;
187 158
188 SockList_AddShort (sl, head->animation_id); 159 sl << data8 (item_n, len)
160 << uint16 (head->animation_id);
161
189 anim_speed = 0; 162 anim_speed = 0;
190 if (QUERY_FLAG (head, FLAG_ANIMATE)) 163 if (QUERY_FLAG (head, FLAG_ANIMATE))
191 { 164 {
192 if (head->anim_speed) 165 if (head->anim_speed)
193 anim_speed = head->anim_speed; 166 anim_speed = head->anim_speed;
198 else if (FABS (head->speed) >= 1.0) 171 else if (FABS (head->speed) >= 1.0)
199 anim_speed = 1; 172 anim_speed = 1;
200 else 173 else
201 anim_speed = (int) (1.0 / FABS (head->speed)); 174 anim_speed = (int) (1.0 / FABS (head->speed));
202 } 175 }
176
203 if (anim_speed > 255) 177 if (anim_speed > 255)
204 anim_speed = 255; 178 anim_speed = 255;
205 } 179 }
206 SockList_AddChar (sl, (char) anim_speed);
207 SockList_AddInt (sl, head->nrof);
208 180
181 sl << uint8 (anim_speed)
182 << uint32 (head->nrof);
183
209 if (ns->itemcmd == 2) 184 if (ns.itemcmd == 2)
210 SockList_AddShort (sl, head->client_type); 185 sl << uint16 (head->client_type);
211 186
212 SET_FLAG (head, FLAG_CLIENT_SENT); 187 SET_FLAG (head, FLAG_CLIENT_SENT);
213} 188}
214 189
215 190
222void 197void
223esrv_draw_look (object *pl) 198esrv_draw_look (object *pl)
224{ 199{
225 object *tmp, *last; 200 object *tmp, *last;
226 int got_one = 0, start_look = 0, end_look = 0; 201 int got_one = 0, start_look = 0, end_look = 0;
227 SockList sl;
228 char buf[MAX_BUF]; 202 char buf[MAX_BUF];
229 203
230 if (!pl->contr->socket.update_look) 204 if (!pl->contr->socket.update_look)
231 { 205 {
232 LOG (llevDebug, "esrv_draw_look called when update_look was not set\n"); 206 LOG (llevDebug, "esrv_draw_look called when update_look was not set\n");
233 return; 207 return;
234 } 208 }
235 else 209 else
236 {
237 pl->contr->socket.update_look = 0; 210 pl->contr->socket.update_look = 0;
238 }
239 211
240 if (QUERY_FLAG (pl, FLAG_REMOVED) || pl->map == NULL || pl->map->in_memory != MAP_IN_MEMORY || out_of_map (pl->map, pl->x, pl->y)) 212 if (QUERY_FLAG (pl, FLAG_REMOVED)
213 || !pl->map
214 || pl->map->in_memory != MAP_IN_MEMORY
215 || out_of_map (pl->map, pl->x, pl->y))
241 return; 216 return;
242 217
243 for (tmp = get_map_ob (pl->map, pl->x, pl->y); tmp && tmp->above; tmp = tmp->above); 218 for (tmp = get_map_ob (pl->map, pl->x, pl->y); tmp && tmp->above; tmp = tmp->above)
219 ;
244 220
245 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 221 packet sl;
246 222
247 Write_String_To_Socket (&pl->contr->socket, "delinv 0", strlen ("delinv 0")); 223 pl->contr->socket.send_packet ("delinv 0");
224
248 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd); 225 sl.printf ("item%d ", pl->contr->socket.itemcmd);
249 sl.len = strlen ((char *) sl.buf);
250 226
251 SockList_AddInt (&sl, 0); 227 sl << uint32 (0);
252 228
253 if (!(pl->contr->socket.faces_sent[empty_face->number] & NS_FACESENT_FACE)) 229 if (!(pl->contr->socket.faces_sent[empty_face->number] & NS_FACESENT_FACE))
254 esrv_send_face (&pl->contr->socket, empty_face->number, 0); 230 esrv_send_face (&pl->contr->socket, empty_face->number, 0);
255 231
256 if (pl->contr->socket.look_position) 232 if (pl->contr->socket.look_position)
257 { 233 {
258 SockList_AddInt (&sl, 0x80000000 | (pl->contr->socket.look_position - NUM_LOOK_OBJECTS)); 234 sl << uint32 (0x80000000 | (pl->contr->socket.look_position - NUM_LOOK_OBJECTS))
259 SockList_AddInt (&sl, 0); 235 << uint32 (0)
260 SockList_AddInt (&sl, (uint32) - 1); 236 << sint32 (-1)
261 SockList_AddInt (&sl, empty_face->number); 237 << uint32 (empty_face->number);
238
262 sprintf (buf, "Click here to see %d previous items", NUM_LOOK_OBJECTS); 239 sl.printf ("Click here to see %d previous items", NUM_LOOK_OBJECTS);
263 add_stringlen_to_sockbuf (buf, &sl); 240
264 SockList_AddShort (&sl, 0); 241 sl << uint16 (0)
265 SockList_AddChar (&sl, 0); 242 << uint8 (0)
266 SockList_AddInt (&sl, 0); 243 << uint32 (0);
244
267 if (pl->contr->socket.itemcmd == 2) 245 if (pl->contr->socket.itemcmd == 2)
268 SockList_AddShort (&sl, 0); 246 sl << uint16 (0);
269 } 247 }
270 248
271 for (last = NULL; tmp != last; tmp = tmp->below) 249 for (last = NULL; tmp != last; tmp = tmp->below)
272 { 250 {
273 object *head; 251 object *head;
276 { 254 {
277 last = tmp->below; /* assumes double floor mode */ 255 last = tmp->below; /* assumes double floor mode */
278 if (last && QUERY_FLAG (last, FLAG_IS_FLOOR)) 256 if (last && QUERY_FLAG (last, FLAG_IS_FLOOR))
279 last = last->below; 257 last = last->below;
280 } 258 }
259
281 if (LOOK_OBJ (tmp)) 260 if (LOOK_OBJ (tmp))
282 { 261 {
283 if (++start_look < pl->contr->socket.look_position) 262 if (++start_look < pl->contr->socket.look_position)
284 continue; 263 continue;
264
285 end_look++; 265 end_look++;
266
286 if (end_look > NUM_LOOK_OBJECTS) 267 if (end_look > NUM_LOOK_OBJECTS)
287 { 268 {
288 /* What we basically do is make a 'fake' object - when the user applies it, 269 /* What we basically do is make a 'fake' object - when the user applies it,
289 * we notice the special tag the object has, and act accordingly. 270 * we notice the special tag the object has, and act accordingly.
290 */ 271 */
291 SockList_AddInt (&sl, 0x80000000 | (pl->contr->socket.look_position + NUM_LOOK_OBJECTS)); 272 sl << uint32 (0x80000000 | (pl->contr->socket.look_position + NUM_LOOK_OBJECTS))
292 SockList_AddInt (&sl, 0); 273 << uint32 (0)
293 SockList_AddInt (&sl, (uint32) - 1); 274 << uint32 ((uint32) - 1)
294 SockList_AddInt (&sl, empty_face->number); 275 << uint32 (empty_face->number);
276
295 sprintf (buf, "Click here to see next group of items"); 277 sl.printf ("Click here to see next group of items");
296 add_stringlen_to_sockbuf (buf, &sl); 278
297 SockList_AddShort (&sl, 0); 279 sl << uint16 (0)
298 SockList_AddChar (&sl, 0); 280 << uint8 (0)
299 SockList_AddInt (&sl, 0); 281 << uint32 (0);
282
300 if (pl->contr->socket.itemcmd == 2) 283 if (pl->contr->socket.itemcmd == 2)
301 SockList_AddShort (&sl, 0); 284 sl << uint16 (0);
285
302 break; 286 break;
303 } 287 }
288
304 if (tmp->head) 289 if (tmp->head)
305 head = tmp->head; 290 head = tmp->head;
306 else 291 else
307 head = tmp; 292 head = tmp;
308 293
309 add_object_to_socklist (&pl->contr->socket, &sl, head); 294 add_object_to_socklist (pl->contr->socket, sl, head);
310 got_one++; 295 got_one++;
311 296
312 if (sl.len >= (MAXSOCKBUF - MAXITEMLEN)) 297 if (sl.length () >= (MAXSOCKBUF - MAXITEMLEN))
313 { 298 {
314 Send_With_Handling (&pl->contr->socket, &sl); 299 Send_With_Handling (&pl->contr->socket, &sl);
300
301 sl.reset ();
315 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd); 302 sl.printf ("item%d ", pl->contr->socket.itemcmd);
316 sl.len = strlen ((char *) sl.buf); 303 sl << uint32 (0);
317 SockList_AddInt (&sl, 0);
318 got_one = 0; 304 got_one = 0;
319 } 305 }
320 } /* If LOOK_OBJ() */ 306 } /* If LOOK_OBJ() */
321 } 307 }
308
322 if (got_one) 309 if (got_one)
323 Send_With_Handling (&pl->contr->socket, &sl); 310 Send_With_Handling (&pl->contr->socket, &sl);
324 311
325 free (sl.buf);
326} 312}
327 313
328/** 314/**
329 * Sends whole inventory. 315 * Sends whole inventory.
330 */ 316 */
331void 317void
332esrv_send_inventory (object *pl, object *op) 318esrv_send_inventory (object *pl, object *op)
333{ 319{
334 object *tmp; 320 object *tmp;
335 int got_one = 0; 321 int got_one = 0;
336 SockList sl;
337 322
338 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 323 packet sl;
339 324
340 sprintf ((char *) sl.buf, "delinv %d", op->count); 325 sl.printf ("delinv %d", op->count);
341 sl.len = strlen ((char *) sl.buf);
342 Send_With_Handling (&pl->contr->socket, &sl); 326 Send_With_Handling (&pl->contr->socket, &sl);
343 327
328 sl.reset ();
344 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd); 329 sl.printf ("item%d ", pl->contr->socket.itemcmd);
345 sl.len = strlen ((char *) sl.buf);
346 330
347 SockList_AddInt (&sl, op->count); 331 sl << uint32 (op->count);
348 332
349 for (tmp = op->inv; tmp; tmp = tmp->below) 333 for (tmp = op->inv; tmp; tmp = tmp->below)
350 { 334 {
351 object *head; 335 object *head;
352 336
355 else 339 else
356 head = tmp; 340 head = tmp;
357 341
358 if (LOOK_OBJ (head)) 342 if (LOOK_OBJ (head))
359 { 343 {
360 add_object_to_socklist (&pl->contr->socket, &sl, head); 344 add_object_to_socklist (pl->contr->socket, sl, head);
361 345
362 got_one++; 346 got_one++;
363 347
364 /* IT is possible for players to accumulate a huge amount of 348 /* IT is possible for players to accumulate a huge amount of
365 * items (especially with some of the bags out there) to 349 * items (especially with some of the bags out there) to
366 * overflow the buffer. IF so, send multiple item commands. 350 * overflow the buffer. IF so, send multiple item commands.
367 */ 351 */
368 if (sl.len >= (MAXSOCKBUF - MAXITEMLEN)) 352 if (sl.length () >= (MAXSOCKBUF - MAXITEMLEN))
369 { 353 {
370 Send_With_Handling (&pl->contr->socket, &sl); 354 Send_With_Handling (&pl->contr->socket, &sl);
355
356 sl.reset ();
371 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd); 357 sl.printf ("item%d ", pl->contr->socket.itemcmd);
372 sl.len = strlen ((char *) sl.buf); 358 sl << uint32 (op->count);
373 SockList_AddInt (&sl, op->count);
374 got_one = 0; 359 got_one = 0;
375 } 360 }
376 } /* If LOOK_OBJ() */ 361 } /* If LOOK_OBJ() */
377 } 362 }
363
378 if (got_one) 364 if (got_one)
379 Send_With_Handling (&pl->contr->socket, &sl); 365 Send_With_Handling (&pl->contr->socket, &sl);
380 free (sl.buf); 366
381} 367}
382 368
383/** 369/**
384 * Updates object *op for player *pl. 370 * Updates object *op for player *pl.
385 * 371 *
389 */ 375 */
390 376
391void 377void
392esrv_update_item (int flags, object *pl, object *op) 378esrv_update_item (int flags, object *pl, object *op)
393{ 379{
394 SockList sl;
395
396 /* If we have a request to send the player item, skip a few checks. */ 380 /* If we have a request to send the player item, skip a few checks. */
397 if (op != pl) 381 if (op != pl)
398 { 382 {
399 if (!LOOK_OBJ (op)) 383 if (!LOOK_OBJ (op))
400 return; 384 return;
401 /* we remove the check for op->env, because in theory, the object 385 /* we remove the check for op->env, because in theory, the object
402 * is hopefully in the same place, so the client should preserve 386 * is hopefully in the same place, so the client should preserve
403 * order. 387 * order.
404 */ 388 */
405 } 389 }
390
406 if (!QUERY_FLAG (op, FLAG_CLIENT_SENT)) 391 if (!QUERY_FLAG (op, FLAG_CLIENT_SENT))
407 { 392 {
408 /* FLAG_CLIENT_SENT is debug only. We are using it to see where 393 /* FLAG_CLIENT_SENT is debug only. We are using it to see where
409 * this is happening - we can set a breakpoint here in the debugger 394 * this is happening - we can set a breakpoint here in the debugger
410 * and track back the call. 395 * and track back the call.
411 */ 396 */
412 LOG (llevDebug, "We have not sent item %s (%d)\n", &op->name, op->count); 397 LOG (llevDebug, "We have not sent item %s (%d)\n", &op->name, op->count);
413 } 398 }
414 sl.buf = (unsigned char *) malloc (MAXSOCKBUF);
415 399
416 strcpy ((char *) sl.buf, "upditem "); 400 packet sl;
417 sl.len = strlen ((char *) sl.buf);
418 401
419 SockList_AddChar (&sl, (char) flags); 402 sl << "upditem "
403 << uint8 (flags);
420 404
421 if (op->head) 405 if (op->head)
422 op = op->head; 406 op = op->head;
423 407
424 SockList_AddInt (&sl, op->count); 408 sl << uint32 (op->count);
425 409
426 if (flags & UPD_LOCATION) 410 if (flags & UPD_LOCATION)
427 SockList_AddInt (&sl, op->env ? op->env->count : 0); 411 sl << uint32 (op->env ? op->env->count : 0);
428 412
429 if (flags & UPD_FLAGS) 413 if (flags & UPD_FLAGS)
430 SockList_AddInt (&sl, query_flags (op)); 414 sl << uint32 (query_flags (op));
431 415
432 if (flags & UPD_WEIGHT) 416 if (flags & UPD_WEIGHT)
433 { 417 {
434 sint32 weight = WEIGHT (op); 418 sint32 weight = WEIGHT (op);
435 419
436 SockList_AddInt (&sl, QUERY_FLAG (op, FLAG_NO_PICK) ? -1 : weight); 420 sl << uint32 (QUERY_FLAG (op, FLAG_NO_PICK) ? -1 : weight);
421
437 if (pl == op) 422 if (pl == op)
438 {
439 op->contr->last_weight = weight; 423 op->contr->last_weight = weight;
440 }
441 } 424 }
442 425
443 if (flags & UPD_FACE) 426 if (flags & UPD_FACE)
444 { 427 {
445 if (!(pl->contr->socket.faces_sent[op->face->number] & NS_FACESENT_FACE)) 428 if (!(pl->contr->socket.faces_sent[op->face->number] & NS_FACESENT_FACE))
446 esrv_send_face (&pl->contr->socket, op->face->number, 0); 429 esrv_send_face (&pl->contr->socket, op->face->number, 0);
447 SockList_AddInt (&sl, op->face->number); 430
431 sl << uint32 (op->face->number);
448 } 432 }
433
449 if (flags & UPD_NAME) 434 if (flags & UPD_NAME)
450 { 435 {
451 int len; 436 int len;
452 const char *item_p; 437 const char *item_p;
453 char item_n[MAX_BUF]; 438 char item_n[MAX_BUF];
468 } 453 }
469 454
470 strncpy (item_n + len + 1, item_p, 127); 455 strncpy (item_n + len + 1, item_p, 127);
471 item_n[254] = 0; 456 item_n[254] = 0;
472 len += strlen (item_n + 1 + len) + 1; 457 len += strlen (item_n + 1 + len) + 1;
473 SockList_AddChar (&sl, (char) len); 458
474 memcpy (sl.buf + sl.len, item_n, len); 459 sl << data8 (item_n, len);
475 sl.len += len;
476 } 460 }
461
477 if (flags & UPD_ANIM) 462 if (flags & UPD_ANIM)
478 SockList_AddShort (&sl, op->animation_id); 463 sl << uint16 (op->animation_id);
479 464
480 if (flags & UPD_ANIMSPEED) 465 if (flags & UPD_ANIMSPEED)
481 { 466 {
482 int anim_speed = 0; 467 int anim_speed = 0;
483 468
492 else if (FABS (op->speed) >= 1.0) 477 else if (FABS (op->speed) >= 1.0)
493 anim_speed = 1; 478 anim_speed = 1;
494 else 479 else
495 anim_speed = (int) (1.0 / FABS (op->speed)); 480 anim_speed = (int) (1.0 / FABS (op->speed));
496 } 481 }
482
497 if (anim_speed > 255) 483 if (anim_speed > 255)
498 anim_speed = 255; 484 anim_speed = 255;
499 } 485 }
500 SockList_AddChar (&sl, (char) anim_speed); 486
487 sl << uint8 (anim_speed);
501 } 488 }
489
502 if (flags & UPD_NROF) 490 if (flags & UPD_NROF)
503 SockList_AddInt (&sl, op->nrof); 491 sl << uint32 (op->nrof);
504 492
505 Send_With_Handling (&pl->contr->socket, &sl); 493 Send_With_Handling (&pl->contr->socket, &sl);
506 free (sl.buf);
507} 494}
508 495
509/** 496/**
510 * Sends item's info to player. 497 * Sends item's info to player.
511 */ 498 */
512void 499void
513esrv_send_item (object *pl, object *op) 500esrv_send_item (object *pl, object *op)
514{ 501{
515 SockList sl;
516
517 /* If this is not the player object, do some more checks */ 502 /* If this is not the player object, do some more checks */
518 if (op != pl) 503 if (op != pl)
519 { 504 {
520 /* We only send 'visibile' objects to the client */ 505 /* We only send 'visibile' objects to the client */
521 if (!LOOK_OBJ (op)) 506 if (!LOOK_OBJ (op))
528 pl->contr->socket.update_look = 1; 513 pl->contr->socket.update_look = 1;
529 return; 514 return;
530 } 515 }
531 } 516 }
532 517
533 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 518 packet sl;
534 519
535 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd); 520 sl.printf ("item%d ", pl->contr->socket.itemcmd);
536 sl.len = strlen ((char *) sl.buf);
537 521
538 if (op->head) 522 if (op->head)
539 op = op->head; 523 op = op->head;
540 524
541 SockList_AddInt (&sl, op->env ? op->env->count : 0); 525 sl << uint32 (op->env ? op->env->count : 0);
542 526
543 add_object_to_socklist (&pl->contr->socket, &sl, op); 527 add_object_to_socklist (pl->contr->socket, sl, op);
544 528
545 Send_With_Handling (&pl->contr->socket, &sl); 529 Send_With_Handling (&pl->contr->socket, &sl);
546 SET_FLAG (op, FLAG_CLIENT_SENT); 530 SET_FLAG (op, FLAG_CLIENT_SENT);
547 free (sl.buf); 531
548} 532}
549 533
550/** 534/**
551 * Tells the client to delete an item. Uses the item 535 * Tells the client to delete an item. Uses the item
552 * command with a -1 location. 536 * command with a -1 location.
553 */ 537 */
554 538
555void 539void
556esrv_del_item (player *pl, int tag) 540esrv_del_item (player *pl, int tag)
557{ 541{
558 SockList sl; 542 packet sl;
559 543
560 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 544 sl << "delitem "
561 545 << uint32 (tag);
562 strcpy ((char *) sl.buf, "delitem ");
563 sl.len = strlen ((char *) sl.buf);
564 SockList_AddInt (&sl, tag);
565 546
566 Send_With_Handling (&pl->socket, &sl); 547 Send_With_Handling (&pl->socket, &sl);
567 free (sl.buf);
568} 548}
569 549
570 550
571/******************************************************************************* 551/*******************************************************************************
572 * 552 *
611 591
612/** Client wants to examine some object. So lets do so. */ 592/** Client wants to examine some object. So lets do so. */
613void 593void
614ExamineCmd (char *buf, int len, player *pl) 594ExamineCmd (char *buf, int len, player *pl)
615{ 595{
616 long tag = atoi (buf); 596 tag_t tag = atoi (buf);
597
598 /* If the high bit is set, player examined a pseudo object. */
599 if (tag & 0x80000000)
600 return;
601
617 object *op = esrv_get_ob_from_count (pl->ob, tag); 602 object *op = esrv_get_ob_from_count (pl->ob, tag);
618 603
619 if (!op) 604 if (!op)
620 { 605 {
621 LOG (llevDebug, "Player '%s' tried to examine the unknown object (%ld)\n", &pl->ob->name, tag); 606 LOG (llevDebug, "Player '%s' tried to examine the unknown object (%ld)\n", &pl->ob->name, tag);
622 return; 607 return;
623 } 608 }
609
624 examine (pl->ob, op); 610 examine (pl->ob, op);
625} 611}
626 612
627/** Client wants to apply some object. Lets do so. */ 613/** Client wants to apply some object. Lets do so. */
628void 614void
629ApplyCmd (char *buf, int len, player *pl) 615ApplyCmd (char *buf, int len, player *pl)
630{ 616{
631 uint32 tag = atoi (buf); 617 tag_t tag = atoi (buf);
632 object *op = esrv_get_ob_from_count (pl->ob, tag);
633 618
634 /* sort of a hack, but if the player saves and the player then manually 619 /* sort of a hack, but if the player saves and the player then manually
635 * applies a savebed (or otherwise tries to do stuff), we run into trouble. 620 * applies a savebed (or otherwise tries to do stuff), we run into trouble.
636 */ 621 */
637 if (QUERY_FLAG (pl->ob, FLAG_REMOVED)) 622 if (QUERY_FLAG (pl->ob, FLAG_REMOVED))
643 pl->socket.look_position = tag & 0x7fffffff; 628 pl->socket.look_position = tag & 0x7fffffff;
644 pl->socket.update_look = 1; 629 pl->socket.update_look = 1;
645 return; 630 return;
646 } 631 }
647 632
633 object *op = esrv_get_ob_from_count (pl->ob, tag);
634
648 if (!op) 635 if (!op)
649 { 636 {
650 LOG (llevDebug, "Player '%s' tried to apply the unknown object (%d)\n", &pl->ob->name, tag); 637 LOG (llevDebug, "Player '%s' tried to apply the unknown object (%d)\n", &pl->ob->name, tag);
651 return; 638 return;
652 } 639 }
640
653 player_apply (pl->ob, op, 0, 0); 641 player_apply (pl->ob, op, 0, 0);
654} 642}
655 643
656/** Client wants to apply some object. Lets do so. */ 644/** Client wants to apply some object. Lets do so. */
657void 645void
658LockItem (uint8 * data, int len, player *pl) 646LockItem (uint8 *data, int len, player *pl)
659{ 647{
660 int flag, tag;
661 object *op;
662
663 flag = data[0]; 648 int flag = data[0];
664 tag = GetInt_String (data + 1); 649 tag_t tag = net_uint32 (data + 1);
665 op = esrv_get_ob_from_count (pl->ob, tag); 650 object *op = esrv_get_ob_from_count (pl->ob, tag);
666 651
667 if (!op) 652 if (!op)
668 { 653 {
669 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Could not find object to lock/unlock"); 654 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Could not find object to lock/unlock");
670 return; 655 return;
671 } 656 }
657
672 if (!flag) 658 if (!flag)
673 CLEAR_FLAG (op, FLAG_INV_LOCKED); 659 CLEAR_FLAG (op, FLAG_INV_LOCKED);
674 else 660 else
675 SET_FLAG (op, FLAG_INV_LOCKED); 661 SET_FLAG (op, FLAG_INV_LOCKED);
662
676 esrv_update_item (UPD_FLAGS, pl->ob, op); 663 esrv_update_item (UPD_FLAGS, pl->ob, op);
677} 664}
678 665
679/** Client wants to apply some object. Lets do so. */ 666/** Client wants to apply some object. Lets do so. */
680void 667void
681MarkItem (uint8 * data, int len, player *pl) 668MarkItem (uint8 * data, int len, player *pl)
682{ 669{
683 int tag; 670 tag_t tag = net_uint32 (data);
684 object *op;
685
686 tag = GetInt_String (data);
687 op = esrv_get_ob_from_count (pl->ob, tag); 671 object *op = esrv_get_ob_from_count (pl->ob, tag);
672
688 if (!op) 673 if (!op)
689 { 674 {
690 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Could not find object to mark"); 675 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Could not find object to mark");
691 return; 676 return;
692 } 677 }
678
693 pl->mark = op; 679 pl->mark = op;
694 pl->mark_count = op->count;
695 new_draw_info_format (NDI_UNIQUE, 0, pl->ob, "Marked item %s", query_name (op)); 680 new_draw_info_format (NDI_UNIQUE, 0, pl->ob, "Marked item %s", query_name (op));
696} 681}
697
698 682
699/** 683/**
700 * look_at prints items on the specified square. 684 * look_at prints items on the specified square.
701 * 685 *
702 * [ removed EARTHWALL check and added check for containers inventory. 686 * [ removed EARTHWALL check and added check for containers inventory.
706look_at (object *op, int dx, int dy) 690look_at (object *op, int dx, int dy)
707{ 691{
708 object *tmp; 692 object *tmp;
709 int flag = 0; 693 int flag = 0;
710 sint16 x, y; 694 sint16 x, y;
711 mapstruct *m; 695 maptile *m;
712 696
713 x = op->x + dx; 697 x = op->x + dx;
714 y = op->y + dy; 698 y = op->y + dy;
715 699
716 if (out_of_map (op->map, x, y)) 700 if (out_of_map (op->map, x, y))
799 return; 783 return;
800 } 784 }
801 785
802 if (!to) 786 if (!to)
803 { /* drop it to the ground */ 787 { /* drop it to the ground */
804
805/* LOG(llevDebug, "Drop it on the ground.\n");*/
806
807 if (op->map && !op->env) 788 if (op->map && !op->env)
808 {
809
810/* LOG(llevDebug,"Dropping object to ground that is already on ground\n");*/
811 return; 789 return;
812 } 790
813 /* If it is an active container, then we should drop all objects 791 /* If it is an active container, then we should drop all objects
814 * in the container and not the container itself. 792 * in the container and not the container itself.
815 */ 793 */
816 if (op->inv && QUERY_FLAG (op, FLAG_APPLIED)) 794 if (op->inv && QUERY_FLAG (op, FLAG_APPLIED))
817 { 795 {
820 for (current = op->inv; current != NULL; current = next) 798 for (current = op->inv; current != NULL; current = next)
821 { 799 {
822 next = current->below; 800 next = current->below;
823 drop_object (pl, current, 0); 801 drop_object (pl, current, 0);
824 } 802 }
803
825 esrv_update_item (UPD_WEIGHT, pl, op); 804 esrv_update_item (UPD_WEIGHT, pl, op);
826 } 805 }
827 else 806 else
828 { 807 {
829 drop_object (pl, op, nrof); 808 drop_object (pl, op, nrof);
838 817
839 pl->contr->count = nrof; 818 pl->contr->count = nrof;
840 pick_up (pl, op); 819 pick_up (pl, op);
841 return; 820 return;
842 } 821 }
822
843 env = esrv_get_ob_from_count (pl, to); 823 env = esrv_get_ob_from_count (pl, to);
844 if (!env) 824 if (!env)
845 { 825 {
846 LOG (llevDebug, "Player '%s' tried to move object to the unknown location (%d)\n", &pl->name, to); 826 LOG (llevDebug, "Player '%s' tried to move object to the unknown location (%d)\n", &pl->name, to);
847 return; 827 return;
848 } 828 }
829
849 /* put_object_in_sack presumes that necessary sanity checking 830 /* put_object_in_sack presumes that necessary sanity checking
850 * has already been done (eg, it can be picked up and fits in 831 * has already been done (eg, it can be picked up and fits in
851 * in a sack, so check for those things. We should also check 832 * in a sack, so check for those things. We should also check
852 * an make sure env is in fact a container for that matter. 833 * an make sure env is in fact a container for that matter.
853 */ 834 */
854 if (env->type == CONTAINER && can_pick (pl, op) && sack_can_hold (pl, env, op, nrof)) 835 if (env->type == CONTAINER && can_pick (pl, op) && sack_can_hold (pl, env, op, nrof))
855 { 836 {
856 put_object_in_sack (pl, env, op, nrof); 837 put_object_in_sack (pl, env, op, nrof);
857 } 838 }
858} 839}
840

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines