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.6 by root, Tue Sep 12 19:20:09 2006 UTC vs.
Revision 1.13 by root, Thu Dec 14 00:13:26 2006 UTC

16 16
17 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
18 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 20
21 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>
22*/ 22*/
23 23
24/** 24/**
25 * \file 25 * \file
26 * Client/server logic. 26 * Client/server logic.
135/* Used in the send_look to put object head into SockList 135/* Used in the send_look to put object head into SockList
136 * sl for socket ns. Need socket to know if we need to send 136 * sl for socket ns. Need socket to know if we need to send
137 * animation of face to the client. 137 * animation of face to the client.
138 */ 138 */
139static void 139static void
140add_object_to_socklist (NewSocket * ns, SockList * sl, object *head) 140add_object_to_socklist (NewSocket &ns, SockList &sl, object *head)
141{ 141{
142 int flags, len, anim_speed; 142 int flags, len, anim_speed;
143 char item_n[MAX_BUF]; 143 char item_n[MAX_BUF];
144 const char *item_p; 144 const char *item_p;
145 145
146 flags = query_flags (head); 146 flags = query_flags (head);
147 if (QUERY_FLAG (head, FLAG_NO_PICK)) 147 if (QUERY_FLAG (head, FLAG_NO_PICK))
148 flags |= F_NOPICK; 148 flags |= F_NOPICK;
149 149
150 if (!(ns->faces_sent[head->face->number] & NS_FACESENT_FACE)) 150 if (!(ns.faces_sent[head->face->number] & NS_FACESENT_FACE))
151 esrv_send_face (ns, head->face->number, 0); 151 esrv_send_face (&ns, head->face->number, 0);
152 152
153 if (QUERY_FLAG (head, FLAG_ANIMATE) && !ns->anims_sent[head->animation_id]) 153 if (QUERY_FLAG (head, FLAG_ANIMATE) && !ns.anims_sent[head->animation_id])
154 esrv_send_animation (ns, head->animation_id); 154 esrv_send_animation (&ns, head->animation_id);
155 155
156 SockList_AddInt (sl, head->count); 156 sl << uint32 (head->count)
157 SockList_AddInt (sl, flags); 157 << uint32 (flags)
158 SockList_AddInt (sl, QUERY_FLAG (head, FLAG_NO_PICK) ? -1 : WEIGHT (head)); 158 << uint32 (QUERY_FLAG (head, FLAG_NO_PICK) ? -1 : WEIGHT (head))
159 SockList_AddInt (sl, head->face->number); 159 << uint32 (head->face->number);
160 160
161 if (!head->custom_name) 161 if (!head->custom_name)
162 { 162 {
163 strncpy (item_n, query_base_name (head, 0), 127); 163 strncpy (item_n, query_base_name (head, 0), 127);
164 item_n[127] = 0; 164 item_n[127] = 0;
170 strncpy (item_n, head->custom_name, 127); 170 strncpy (item_n, head->custom_name, 127);
171 item_n[127] = 0; 171 item_n[127] = 0;
172 len = strlen (item_n); 172 len = strlen (item_n);
173 item_p = head->custom_name; 173 item_p = head->custom_name;
174 } 174 }
175
175 strncpy (item_n + len + 1, item_p, 127); 176 strncpy (item_n + len + 1, item_p, 127);
176 item_n[254] = 0; 177 item_n[254] = 0;
177 len += strlen (item_n + 1 + len) + 1; 178 len += strlen (item_n + 1 + len) + 1;
178 SockList_AddChar (sl, (char) len);
179 memcpy (sl->buf + sl->len, item_n, len);
180 sl->len += len;
181 179
182 SockList_AddShort (sl, head->animation_id); 180 sl << data8 (item_n, len)
181 << uint16 (head->animation_id);
182
183 anim_speed = 0; 183 anim_speed = 0;
184 if (QUERY_FLAG (head, FLAG_ANIMATE)) 184 if (QUERY_FLAG (head, FLAG_ANIMATE))
185 { 185 {
186 if (head->anim_speed) 186 if (head->anim_speed)
187 anim_speed = head->anim_speed; 187 anim_speed = head->anim_speed;
192 else if (FABS (head->speed) >= 1.0) 192 else if (FABS (head->speed) >= 1.0)
193 anim_speed = 1; 193 anim_speed = 1;
194 else 194 else
195 anim_speed = (int) (1.0 / FABS (head->speed)); 195 anim_speed = (int) (1.0 / FABS (head->speed));
196 } 196 }
197
197 if (anim_speed > 255) 198 if (anim_speed > 255)
198 anim_speed = 255; 199 anim_speed = 255;
199 } 200 }
200 SockList_AddChar (sl, (char) anim_speed);
201 SockList_AddInt (sl, head->nrof);
202 201
202 sl << uint8 (anim_speed)
203 << uint32 (head->nrof);
204
203 if (ns->itemcmd == 2) 205 if (ns.itemcmd == 2)
204 SockList_AddShort (sl, head->client_type); 206 sl << uint16 (head->client_type);
205 207
206 SET_FLAG (head, FLAG_CLIENT_SENT); 208 SET_FLAG (head, FLAG_CLIENT_SENT);
207} 209}
208 210
209 211
216void 218void
217esrv_draw_look (object *pl) 219esrv_draw_look (object *pl)
218{ 220{
219 object *tmp, *last; 221 object *tmp, *last;
220 int got_one = 0, start_look = 0, end_look = 0; 222 int got_one = 0, start_look = 0, end_look = 0;
221 SockList sl;
222 char buf[MAX_BUF]; 223 char buf[MAX_BUF];
223 224
224 if (!pl->contr->socket.update_look) 225 if (!pl->contr->socket.update_look)
225 { 226 {
226 LOG (llevDebug, "esrv_draw_look called when update_look was not set\n"); 227 LOG (llevDebug, "esrv_draw_look called when update_look was not set\n");
227 return; 228 return;
228 } 229 }
229 else 230 else
230 {
231 pl->contr->socket.update_look = 0; 231 pl->contr->socket.update_look = 0;
232 }
233 232
234 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)) 233 if (QUERY_FLAG (pl, FLAG_REMOVED)
234 || !pl->map
235 || pl->map->in_memory != MAP_IN_MEMORY
236 || out_of_map (pl->map, pl->x, pl->y))
235 return; 237 return;
236 238
237 for (tmp = get_map_ob (pl->map, pl->x, pl->y); tmp && tmp->above; tmp = tmp->above); 239 for (tmp = get_map_ob (pl->map, pl->x, pl->y); tmp && tmp->above; tmp = tmp->above);
238 240
239 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 241 SockList sl (MAXSOCKBUF);
240 242
241 Write_String_To_Socket (&pl->contr->socket, "delinv 0", strlen ("delinv 0")); 243 Write_String_To_Socket (&pl->contr->socket, "delinv 0", sizeof ("delinv 0") - 1);
244
242 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd); 245 sl.printf ("item%d ", pl->contr->socket.itemcmd);
243 sl.len = strlen ((char *) sl.buf);
244 246
245 SockList_AddInt (&sl, 0); 247 sl << uint32 (0);
246 248
247 if (!(pl->contr->socket.faces_sent[empty_face->number] & NS_FACESENT_FACE)) 249 if (!(pl->contr->socket.faces_sent[empty_face->number] & NS_FACESENT_FACE))
248 esrv_send_face (&pl->contr->socket, empty_face->number, 0); 250 esrv_send_face (&pl->contr->socket, empty_face->number, 0);
249 251
250 if (pl->contr->socket.look_position) 252 if (pl->contr->socket.look_position)
251 { 253 {
252 SockList_AddInt (&sl, 0x80000000 | (pl->contr->socket.look_position - NUM_LOOK_OBJECTS)); 254 sl << uint32 (0x80000000 | (pl->contr->socket.look_position - NUM_LOOK_OBJECTS))
253 SockList_AddInt (&sl, 0); 255 << uint32 (0)
254 SockList_AddInt (&sl, (uint32) - 1); 256 << sint32 (-1)
255 SockList_AddInt (&sl, empty_face->number); 257 << uint32 (empty_face->number);
258
256 sprintf (buf, "Click here to see %d previous items", NUM_LOOK_OBJECTS); 259 sl.printf ("Click here to see %d previous items", NUM_LOOK_OBJECTS);
257 add_stringlen_to_sockbuf (buf, &sl); 260
258 SockList_AddShort (&sl, 0); 261 sl << uint16 (0)
259 SockList_AddChar (&sl, 0); 262 << uint8 (0)
260 SockList_AddInt (&sl, 0); 263 << uint32 (0);
264
261 if (pl->contr->socket.itemcmd == 2) 265 if (pl->contr->socket.itemcmd == 2)
262 SockList_AddShort (&sl, 0); 266 sl << uint16 (0);
263 } 267 }
264 268
265 for (last = NULL; tmp != last; tmp = tmp->below) 269 for (last = NULL; tmp != last; tmp = tmp->below)
266 { 270 {
267 object *head; 271 object *head;
270 { 274 {
271 last = tmp->below; /* assumes double floor mode */ 275 last = tmp->below; /* assumes double floor mode */
272 if (last && QUERY_FLAG (last, FLAG_IS_FLOOR)) 276 if (last && QUERY_FLAG (last, FLAG_IS_FLOOR))
273 last = last->below; 277 last = last->below;
274 } 278 }
279
275 if (LOOK_OBJ (tmp)) 280 if (LOOK_OBJ (tmp))
276 { 281 {
277 if (++start_look < pl->contr->socket.look_position) 282 if (++start_look < pl->contr->socket.look_position)
278 continue; 283 continue;
284
279 end_look++; 285 end_look++;
286
280 if (end_look > NUM_LOOK_OBJECTS) 287 if (end_look > NUM_LOOK_OBJECTS)
281 { 288 {
282 /* What we basically do is make a 'fake' object - when the user applies it, 289 /* What we basically do is make a 'fake' object - when the user applies it,
283 * we notice the special tag the object has, and act accordingly. 290 * we notice the special tag the object has, and act accordingly.
284 */ 291 */
298 if (tmp->head) 305 if (tmp->head)
299 head = tmp->head; 306 head = tmp->head;
300 else 307 else
301 head = tmp; 308 head = tmp;
302 309
303 add_object_to_socklist (&pl->contr->socket, &sl, head); 310 add_object_to_socklist (pl->contr->socket, sl, head);
304 got_one++; 311 got_one++;
305 312
306 if (sl.len >= (MAXSOCKBUF - MAXITEMLEN)) 313 if (sl.len >= (MAXSOCKBUF - MAXITEMLEN))
307 { 314 {
308 Send_With_Handling (&pl->contr->socket, &sl); 315 Send_With_Handling (&pl->contr->socket, &sl);
311 SockList_AddInt (&sl, 0); 318 SockList_AddInt (&sl, 0);
312 got_one = 0; 319 got_one = 0;
313 } 320 }
314 } /* If LOOK_OBJ() */ 321 } /* If LOOK_OBJ() */
315 } 322 }
323
316 if (got_one) 324 if (got_one)
317 Send_With_Handling (&pl->contr->socket, &sl); 325 Send_With_Handling (&pl->contr->socket, &sl);
318 326
319 free (sl.buf); 327 sl.free ();
320} 328}
321 329
322/** 330/**
323 * Sends whole inventory. 331 * Sends whole inventory.
324 */ 332 */
349 else 357 else
350 head = tmp; 358 head = tmp;
351 359
352 if (LOOK_OBJ (head)) 360 if (LOOK_OBJ (head))
353 { 361 {
354 add_object_to_socklist (&pl->contr->socket, &sl, head); 362 add_object_to_socklist (pl->contr->socket, sl, head);
355 363
356 got_one++; 364 got_one++;
357 365
358 /* IT is possible for players to accumulate a huge amount of 366 /* IT is possible for players to accumulate a huge amount of
359 * items (especially with some of the bags out there) to 367 * items (especially with some of the bags out there) to
369 } 377 }
370 } /* If LOOK_OBJ() */ 378 } /* If LOOK_OBJ() */
371 } 379 }
372 if (got_one) 380 if (got_one)
373 Send_With_Handling (&pl->contr->socket, &sl); 381 Send_With_Handling (&pl->contr->socket, &sl);
374 free (sl.buf); 382 sl.free ();
375} 383}
376 384
377/** 385/**
378 * Updates object *op for player *pl. 386 * Updates object *op for player *pl.
379 * 387 *
395 /* we remove the check for op->env, because in theory, the object 403 /* we remove the check for op->env, because in theory, the object
396 * is hopefully in the same place, so the client should preserve 404 * is hopefully in the same place, so the client should preserve
397 * order. 405 * order.
398 */ 406 */
399 } 407 }
408
400 if (!QUERY_FLAG (op, FLAG_CLIENT_SENT)) 409 if (!QUERY_FLAG (op, FLAG_CLIENT_SENT))
401 { 410 {
402 /* FLAG_CLIENT_SENT is debug only. We are using it to see where 411 /* FLAG_CLIENT_SENT is debug only. We are using it to see where
403 * this is happening - we can set a breakpoint here in the debugger 412 * this is happening - we can set a breakpoint here in the debugger
404 * and track back the call. 413 * and track back the call.
405 */ 414 */
406 LOG (llevDebug, "We have not sent item %s (%d)\n", &op->name, op->count); 415 LOG (llevDebug, "We have not sent item %s (%d)\n", &op->name, op->count);
407 } 416 }
417
408 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 418 sl.buf = (unsigned char *) malloc (MAXSOCKBUF);
409 419
410 strcpy ((char *) sl.buf, "upditem "); 420 strcpy ((char *) sl.buf, "upditem ");
411 sl.len = strlen ((char *) sl.buf); 421 sl.len = strlen ((char *) sl.buf);
412 422
438 { 448 {
439 if (!(pl->contr->socket.faces_sent[op->face->number] & NS_FACESENT_FACE)) 449 if (!(pl->contr->socket.faces_sent[op->face->number] & NS_FACESENT_FACE))
440 esrv_send_face (&pl->contr->socket, op->face->number, 0); 450 esrv_send_face (&pl->contr->socket, op->face->number, 0);
441 SockList_AddInt (&sl, op->face->number); 451 SockList_AddInt (&sl, op->face->number);
442 } 452 }
453
443 if (flags & UPD_NAME) 454 if (flags & UPD_NAME)
444 { 455 {
445 int len; 456 int len;
446 const char *item_p; 457 const char *item_p;
447 char item_n[MAX_BUF]; 458 char item_n[MAX_BUF];
466 len += strlen (item_n + 1 + len) + 1; 477 len += strlen (item_n + 1 + len) + 1;
467 SockList_AddChar (&sl, (char) len); 478 SockList_AddChar (&sl, (char) len);
468 memcpy (sl.buf + sl.len, item_n, len); 479 memcpy (sl.buf + sl.len, item_n, len);
469 sl.len += len; 480 sl.len += len;
470 } 481 }
482
471 if (flags & UPD_ANIM) 483 if (flags & UPD_ANIM)
472 SockList_AddShort (&sl, op->animation_id); 484 SockList_AddShort (&sl, op->animation_id);
473 485
474 if (flags & UPD_ANIMSPEED) 486 if (flags & UPD_ANIMSPEED)
475 { 487 {
495 } 507 }
496 if (flags & UPD_NROF) 508 if (flags & UPD_NROF)
497 SockList_AddInt (&sl, op->nrof); 509 SockList_AddInt (&sl, op->nrof);
498 510
499 Send_With_Handling (&pl->contr->socket, &sl); 511 Send_With_Handling (&pl->contr->socket, &sl);
500 free (sl.buf); 512 sl.free ();
501} 513}
502 514
503/** 515/**
504 * Sends item's info to player. 516 * Sends item's info to player.
505 */ 517 */
532 if (op->head) 544 if (op->head)
533 op = op->head; 545 op = op->head;
534 546
535 SockList_AddInt (&sl, op->env ? op->env->count : 0); 547 SockList_AddInt (&sl, op->env ? op->env->count : 0);
536 548
537 add_object_to_socklist (&pl->contr->socket, &sl, op); 549 add_object_to_socklist (pl->contr->socket, sl, op);
538 550
539 Send_With_Handling (&pl->contr->socket, &sl); 551 Send_With_Handling (&pl->contr->socket, &sl);
540 SET_FLAG (op, FLAG_CLIENT_SENT); 552 SET_FLAG (op, FLAG_CLIENT_SENT);
541 free (sl.buf); 553
554 sl.free ();
542} 555}
543 556
544/** 557/**
545 * Tells the client to delete an item. Uses the item 558 * Tells the client to delete an item. Uses the item
546 * command with a -1 location. 559 * command with a -1 location.
556 strcpy ((char *) sl.buf, "delitem "); 569 strcpy ((char *) sl.buf, "delitem ");
557 sl.len = strlen ((char *) sl.buf); 570 sl.len = strlen ((char *) sl.buf);
558 SockList_AddInt (&sl, tag); 571 SockList_AddInt (&sl, tag);
559 572
560 Send_With_Handling (&pl->socket, &sl); 573 Send_With_Handling (&pl->socket, &sl);
561 free (sl.buf); 574 sl.free ();
562} 575}
563 576
564 577
565/******************************************************************************* 578/*******************************************************************************
566 * 579 *
605 618
606/** Client wants to examine some object. So lets do so. */ 619/** Client wants to examine some object. So lets do so. */
607void 620void
608ExamineCmd (char *buf, int len, player *pl) 621ExamineCmd (char *buf, int len, player *pl)
609{ 622{
610 long tag = atoi (buf); 623 tag_t tag = atoi (buf);
624
625 /* If the high bit is set, player examined a pseudo object. */
626 if (tag & 0x80000000)
627 return;
628
611 object *op = esrv_get_ob_from_count (pl->ob, tag); 629 object *op = esrv_get_ob_from_count (pl->ob, tag);
612 630
613 if (!op) 631 if (!op)
614 { 632 {
615 LOG (llevDebug, "Player '%s' tried to examine the unknown object (%ld)\n", &pl->ob->name, tag); 633 LOG (llevDebug, "Player '%s' tried to examine the unknown object (%ld)\n", &pl->ob->name, tag);
616 return; 634 return;
617 } 635 }
636
618 examine (pl->ob, op); 637 examine (pl->ob, op);
619} 638}
620 639
621/** Client wants to apply some object. Lets do so. */ 640/** Client wants to apply some object. Lets do so. */
622void 641void
623ApplyCmd (char *buf, int len, player *pl) 642ApplyCmd (char *buf, int len, player *pl)
624{ 643{
625 uint32 tag = atoi (buf); 644 tag_t tag = atoi (buf);
626 object *op = esrv_get_ob_from_count (pl->ob, tag);
627 645
628 /* sort of a hack, but if the player saves and the player then manually 646 /* sort of a hack, but if the player saves and the player then manually
629 * applies a savebed (or otherwise tries to do stuff), we run into trouble. 647 * applies a savebed (or otherwise tries to do stuff), we run into trouble.
630 */ 648 */
631 if (QUERY_FLAG (pl->ob, FLAG_REMOVED)) 649 if (QUERY_FLAG (pl->ob, FLAG_REMOVED))
637 pl->socket.look_position = tag & 0x7fffffff; 655 pl->socket.look_position = tag & 0x7fffffff;
638 pl->socket.update_look = 1; 656 pl->socket.update_look = 1;
639 return; 657 return;
640 } 658 }
641 659
660 object *op = esrv_get_ob_from_count (pl->ob, tag);
661
642 if (!op) 662 if (!op)
643 { 663 {
644 LOG (llevDebug, "Player '%s' tried to apply the unknown object (%d)\n", &pl->ob->name, tag); 664 LOG (llevDebug, "Player '%s' tried to apply the unknown object (%d)\n", &pl->ob->name, tag);
645 return; 665 return;
646 } 666 }
667
647 player_apply (pl->ob, op, 0, 0); 668 player_apply (pl->ob, op, 0, 0);
648} 669}
649 670
650/** Client wants to apply some object. Lets do so. */ 671/** Client wants to apply some object. Lets do so. */
651void 672void
652LockItem (uint8 * data, int len, player *pl) 673LockItem (uint8 *data, int len, player *pl)
653{ 674{
654 int flag, tag;
655 object *op;
656
657 flag = data[0]; 675 int flag = data[0];
658 tag = GetInt_String (data + 1); 676 tag_t tag = net_uint32 (data + 1);
659 op = esrv_get_ob_from_count (pl->ob, tag); 677 object *op = esrv_get_ob_from_count (pl->ob, tag);
660 678
661 if (!op) 679 if (!op)
662 { 680 {
663 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Could not find object to lock/unlock"); 681 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Could not find object to lock/unlock");
664 return; 682 return;
665 } 683 }
684
666 if (!flag) 685 if (!flag)
667 CLEAR_FLAG (op, FLAG_INV_LOCKED); 686 CLEAR_FLAG (op, FLAG_INV_LOCKED);
668 else 687 else
669 SET_FLAG (op, FLAG_INV_LOCKED); 688 SET_FLAG (op, FLAG_INV_LOCKED);
689
670 esrv_update_item (UPD_FLAGS, pl->ob, op); 690 esrv_update_item (UPD_FLAGS, pl->ob, op);
671} 691}
672 692
673/** Client wants to apply some object. Lets do so. */ 693/** Client wants to apply some object. Lets do so. */
674void 694void
675MarkItem (uint8 * data, int len, player *pl) 695MarkItem (uint8 * data, int len, player *pl)
676{ 696{
677 int tag; 697 tag_t tag = net_uint32 (data);
678 object *op;
679
680 tag = GetInt_String (data);
681 op = esrv_get_ob_from_count (pl->ob, tag); 698 object *op = esrv_get_ob_from_count (pl->ob, tag);
699
682 if (!op) 700 if (!op)
683 { 701 {
684 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Could not find object to mark"); 702 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Could not find object to mark");
685 return; 703 return;
686 } 704 }
705
687 pl->mark = op; 706 pl->mark = op;
688 pl->mark_count = op->count;
689 new_draw_info_format (NDI_UNIQUE, 0, pl->ob, "Marked item %s", query_name (op)); 707 new_draw_info_format (NDI_UNIQUE, 0, pl->ob, "Marked item %s", query_name (op));
690} 708}
691
692 709
693/** 710/**
694 * look_at prints items on the specified square. 711 * look_at prints items on the specified square.
695 * 712 *
696 * [ removed EARTHWALL check and added check for containers inventory. 713 * [ removed EARTHWALL check and added check for containers inventory.
700look_at (object *op, int dx, int dy) 717look_at (object *op, int dx, int dy)
701{ 718{
702 object *tmp; 719 object *tmp;
703 int flag = 0; 720 int flag = 0;
704 sint16 x, y; 721 sint16 x, y;
705 mapstruct *m; 722 maptile *m;
706 723
707 x = op->x + dx; 724 x = op->x + dx;
708 y = op->y + dy; 725 y = op->y + dy;
709 726
710 if (out_of_map (op->map, x, y)) 727 if (out_of_map (op->map, x, y))

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines