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.29 by root, Thu Dec 21 23:37:06 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.
36 * This containes item logic for client/server. It doesn't contain 30 * This containes item logic for client/server. It doesn't contain
37 * the actual commands that send the data, but does contain 31 * the actual commands that send the data, but does contain
38 * the logic for what items should be sent. 32 * the logic for what items should be sent.
39 */ 33 */
40 34
41
42#include <global.h> 35#include <global.h>
43#include <object.h> /* LOOK_OBJ */ 36#include <object.h> /* LOOK_OBJ */
44#include <newclient.h>
45#include <newserver.h>
46#include <sproto.h> 37#include <sproto.h>
47 38
48/** This is the maximum number of bytes we expect any one item to take up */ 39/** This is the maximum number of bytes we expect any one item to take up */
49#define MAXITEMLEN 300 40#define MAXITEMLEN 300
41
42#if 0
43tag_t
44client_container::tag () const
45{
46 switch (type)
47 {
48 case CC_INVENTORY:
49 return ns->pl->count;
50 case CC_MAPSPACE:
51 return 0;
52 case CC_CONTAINER:
53 return env->count;
54 }
55
56 abort ();
57}
58
59void
60client_container::clear ()
61{
62 switch (type)
63 {
64 case CC_INVENTORY:
65 abort ();
66
67 case CC_MAPSPACE:
68 case CC_CONTAINER:
69 ns->send_packet_printf ("delinv %d", tag ());
70 break;
71 }
72
73 for (iterator i = begin (); i != end (); ++i)
74 i->op->seen_by = 0;
75
76 vector< refitem, slice_allocator<refitem> >::clear ();
77}
78
79inline iterator
80client_container::merge_item (iterator i, object *op)
81{
82 if (i != end () && i->op == op)
83 return ++i;
84
85 if (op->seen_by)
86 return; // seen by another entity already
87
88 op->seen_by = this;
89
90 refitem ref;
91 ref.op = op;
92
93 return insert (i, ref);
94}
95
96void
97client_container::update (int offset)
98{
99 iterator i = begin ();
100
101 switch (type)
102 {
103 case CC_INVENTORY:
104 case CC_CONTAINER:
105 {
106 object *env = type == CC_INVENTORY
107 ? ns->pl->ob
108 : this->env;
109
110 // pass 1, erase all objects no longer in container
111 for (iterator j = begin (); j != end (); ++j)
112 if (j->op->env != env)
113 {
114 j->op->seen_by = 0;
115 erase (j);
116 }
117
118 // pass 2 merge items
119 for (object *op = env->inv; op; op = op->below)
120 {
121 if (--offset < 0)
122 i = merge_item (i, op);
123 else if (offset < -FLOORBOX_PAGESIZE)
124 break;
125 }
126 }
127 break;
128
129 case CC_MAPSPACE:
130 {
131 // pass 1, erase all objects no longer on space
132 for (iterator j = begin (); j != end (); ++j)
133 if (j->op->x != x || j->op->y != y || j->op->map != map)
134 {
135 j->op->seen_by = 0;
136 erase (j);
137 }
138
139 // pass 2 merge items
140 for (object *op = GET_MAP_OB (map, x, y); op; op = op->above)
141 {
142 if (--offset < 0)
143 i = merge_item (i, op);
144 else if (offset < -FLOORBOX_PAGESIZE)
145 break;
146 }
147 }
148 break;
149 }
150
151 // pass 3, erase all extra items
152 for (iterator j = i; j != end (); ++j)
153 j->op->seen_by = 0;
154
155 if (i != end ())
156 erase (i, end ());
157}
158
159void
160client_container::set_mapspace (maptile *map, int x, int y)
161{
162 if (type == CC_MAPSPACE
163 && this->map == map
164 && this->x == x
165 && this->y == y)
166 return;
167
168 clear ();
169
170 type = CC_MAPSPACE;
171 this->map = map;
172 this->x = x;
173 this->y = y;
174}
175
176void
177client_container::set_container (object *env)
178{
179}
180#endif
50 181
51/******************************************************************************* 182/*******************************************************************************
52 * 183 *
53 * Functions related to sending object data to the client. 184 * Functions related to sending object data to the client.
54 * 185 *
55 ******************************************************************************/ 186 ******************************************************************************/
56 187
57/** 188/**
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
78/**
79 * This is a similar to query_name, but returns flags 189 * This is a similar to query_name, but returns flags
80 * to be sended to client. 190 * to be sent to client.
81 */ 191 */
82unsigned int 192unsigned int
83query_flags (object *op) 193query_flags (object *op)
84{ 194{
85 unsigned int flags = 0; 195 unsigned int flags = 0;
86 196
87 if (QUERY_FLAG (op, FLAG_APPLIED)) 197 if (QUERY_FLAG (op, FLAG_APPLIED))
88 { 198 {
89 switch (op->type) 199 switch (op->type)
90 { 200 {
91 case BOW: 201 case BOW:
92 case WAND: 202 case WAND:
93 case ROD: 203 case ROD:
94 case HORN: 204 case HORN:
95 flags = a_readied; 205 flags = a_readied;
96 break; 206 break;
97 case WEAPON: 207 case WEAPON:
98 flags = a_wielded; 208 flags = a_wielded;
99 break; 209 break;
100 case SKILL: 210 case SKILL:
101 case ARMOUR: 211 case ARMOUR:
102 case HELMET: 212 case HELMET:
103 case SHIELD: 213 case SHIELD:
104 case RING: 214 case RING:
105 case BOOTS: 215 case BOOTS:
106 case GLOVES: 216 case GLOVES:
107 case AMULET: 217 case AMULET:
108 case GIRDLE: 218 case GIRDLE:
109 case BRACERS: 219 case BRACERS:
110 case CLOAK: 220 case CLOAK:
111 flags = a_worn; 221 flags = a_worn;
112 break; 222 break;
113 case CONTAINER: 223 case CONTAINER:
114 flags = a_active; 224 flags = a_active;
115 break; 225 break;
116 default: 226 default:
117 flags = a_applied; 227 flags = a_applied;
118 break; 228 break;
119 } 229 }
120 } 230 }
231
121 if (op->type == CONTAINER && ((op->env && op->env->container == op) || (!op->env && QUERY_FLAG (op, FLAG_APPLIED)))) 232 if (op->type == CONTAINER && ((op->env && op->env->container == op) || (!op->env && QUERY_FLAG (op, FLAG_APPLIED))))
122 flags |= F_OPEN; 233 flags |= F_OPEN;
123 234
124 if (QUERY_FLAG (op, FLAG_KNOWN_CURSED)) 235 if (QUERY_FLAG (op, FLAG_KNOWN_CURSED))
125 { 236 {
126 if (QUERY_FLAG (op, FLAG_DAMNED)) 237 if (QUERY_FLAG (op, FLAG_DAMNED))
127 flags |= F_DAMNED; 238 flags |= F_DAMNED;
128 else if (QUERY_FLAG (op, FLAG_CURSED)) 239 else if (QUERY_FLAG (op, FLAG_CURSED))
129 flags |= F_CURSED; 240 flags |= F_CURSED;
130 } 241 }
242
131 if (QUERY_FLAG (op, FLAG_KNOWN_MAGICAL) && !QUERY_FLAG (op, FLAG_IDENTIFIED)) 243 if (QUERY_FLAG (op, FLAG_KNOWN_MAGICAL) && !QUERY_FLAG (op, FLAG_IDENTIFIED))
132 flags |= F_MAGIC; 244 flags |= F_MAGIC;
133 if (QUERY_FLAG (op, FLAG_UNPAID)) 245 if (QUERY_FLAG (op, FLAG_UNPAID))
134 flags |= F_UNPAID; 246 flags |= F_UNPAID;
135 if (QUERY_FLAG (op, FLAG_INV_LOCKED)) 247 if (QUERY_FLAG (op, FLAG_INV_LOCKED))
136 flags |= F_LOCKED; 248 flags |= F_LOCKED;
137 249
138 return flags; 250 return flags;
139} 251}
140 252
141/* Used in the send_look to put object head into SockList 253/* 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 254 * sl for socket ns. Need socket to know if we need to send
143 * animation of face to the client. 255 * animation of face to the client.
144 */ 256 */
145static void 257static void
146add_object_to_socklist (NewSocket * ns, SockList * sl, object *head) 258add_object_to_socklist (client &ns, packet &sl, object *head)
147{ 259{
148 int flags, len, anim_speed; 260 int flags, len, anim_speed;
149 char item_n[MAX_BUF]; 261 char item_n[MAX_BUF];
150 const char *item_p; 262 const char *item_p;
151 263
152 flags = query_flags (head); 264 flags = query_flags (head);
153 if (QUERY_FLAG (head, FLAG_NO_PICK)) 265 if (QUERY_FLAG (head, FLAG_NO_PICK))
154 flags |= F_NOPICK; 266 flags |= F_NOPICK;
155 267
156 if (!(ns->faces_sent[head->face->number] & NS_FACESENT_FACE)) 268 if (!(ns.faces_sent[head->face->number] & NS_FACESENT_FACE))
157 esrv_send_face (ns, head->face->number, 0); 269 esrv_send_face (&ns, head->face->number, 0);
158 270
159 if (QUERY_FLAG (head, FLAG_ANIMATE) && !ns->anims_sent[head->animation_id]) 271 if (QUERY_FLAG (head, FLAG_ANIMATE) && !ns.anims_sent[head->animation_id])
160 esrv_send_animation (ns, head->animation_id); 272 esrv_send_animation (&ns, head->animation_id);
161 273
162 SockList_AddInt (sl, head->count); 274 sl << uint32 (head->count)
163 SockList_AddInt (sl, flags); 275 << uint32 (flags)
164 SockList_AddInt (sl, QUERY_FLAG (head, FLAG_NO_PICK) ? -1 : WEIGHT (head)); 276 << uint32 (QUERY_FLAG (head, FLAG_NO_PICK) ? -1 : WEIGHT (head))
165 SockList_AddInt (sl, head->face->number); 277 << uint32 (head->face->number);
166 278
167 if (!head->custom_name) 279 if (!head->custom_name)
168 { 280 {
169 strncpy (item_n, query_base_name (head, 0), 127); 281 strncpy (item_n, query_base_name (head, 0), 127);
170 item_n[127] = 0; 282 item_n[127] = 0;
176 strncpy (item_n, head->custom_name, 127); 288 strncpy (item_n, head->custom_name, 127);
177 item_n[127] = 0; 289 item_n[127] = 0;
178 len = strlen (item_n); 290 len = strlen (item_n);
179 item_p = head->custom_name; 291 item_p = head->custom_name;
180 } 292 }
293
181 strncpy (item_n + len + 1, item_p, 127); 294 strncpy (item_n + len + 1, item_p, 127);
182 item_n[254] = 0; 295 item_n[254] = 0;
183 len += strlen (item_n + 1 + len) + 1; 296 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 297
188 SockList_AddShort (sl, head->animation_id); 298 sl << data8 (item_n, len)
299 << uint16 (head->animation_id);
300
189 anim_speed = 0; 301 anim_speed = 0;
190 if (QUERY_FLAG (head, FLAG_ANIMATE)) 302 if (QUERY_FLAG (head, FLAG_ANIMATE))
191 { 303 {
192 if (head->anim_speed) 304 if (head->anim_speed)
193 anim_speed = head->anim_speed; 305 anim_speed = head->anim_speed;
198 else if (FABS (head->speed) >= 1.0) 310 else if (FABS (head->speed) >= 1.0)
199 anim_speed = 1; 311 anim_speed = 1;
200 else 312 else
201 anim_speed = (int) (1.0 / FABS (head->speed)); 313 anim_speed = (int) (1.0 / FABS (head->speed));
202 } 314 }
315
203 if (anim_speed > 255) 316 if (anim_speed > 255)
204 anim_speed = 255; 317 anim_speed = 255;
205 } 318 }
206 SockList_AddChar (sl, (char) anim_speed);
207 SockList_AddInt (sl, head->nrof);
208 319
320 sl << uint8 (anim_speed)
321 << uint32 (head->nrof);
322
209 if (ns->itemcmd == 2) 323 if (ns.itemcmd == 2)
210 SockList_AddShort (sl, head->client_type); 324 sl << uint16 (head->client_type);
211 325
212 SET_FLAG (head, FLAG_CLIENT_SENT); 326 SET_FLAG (head, FLAG_CLIENT_SENT);
213} 327}
214 328
215 329
216/** 330/**
217 * Send the look window. Don't need to do animations here 331 * Send the look window. Don't need to do animations here
218 * This sends all the faces to the client, not just updates. This is 332 * This sends all the faces to the client, not just updates. This is
219 * because object ordering would otherwise be inconsistent 333 * because object ordering would otherwise be inconsistent.
220 */ 334 */
221
222void 335void
223esrv_draw_look (object *pl) 336esrv_draw_look (object *pl)
224{ 337{
225 object *tmp, *last; 338 object *tmp, *last;
226 int got_one = 0, start_look = 0, end_look = 0; 339 int got_one = 0, start_look = 0, end_look = 0;
227 SockList sl;
228 char buf[MAX_BUF]; 340 char buf[MAX_BUF];
229 341
230 if (!pl->contr->socket.update_look) 342 if (!pl->contr->ns->update_look)
231 { 343 {
232 LOG (llevDebug, "esrv_draw_look called when update_look was not set\n"); 344 LOG (llevDebug, "esrv_draw_look called when update_look was not set\n");
233 return; 345 return;
234 } 346 }
235 else 347 else
236 {
237 pl->contr->socket.update_look = 0; 348 pl->contr->ns->update_look = 0;
238 }
239 349
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)) 350 if (QUERY_FLAG (pl, FLAG_REMOVED)
351 || !pl->map
352 || pl->map->in_memory != MAP_IN_MEMORY
353 || out_of_map (pl->map, pl->x, pl->y))
241 return; 354 return;
242 355
243 for (tmp = get_map_ob (pl->map, pl->x, pl->y); tmp && tmp->above; tmp = tmp->above); 356 for (tmp = GET_MAP_OB (pl->map, pl->x, pl->y); tmp && tmp->above; tmp = tmp->above)
357 ;
244 358
245 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 359 pl->contr->ns->send_packet ("delinv 0");
246 360
247 Write_String_To_Socket (&pl->contr->socket, "delinv 0", strlen ("delinv 0")); 361 packet sl;
248 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd); 362 sl.printf ("item%d ", pl->contr->ns->itemcmd);
249 sl.len = strlen ((char *) sl.buf);
250 363
251 SockList_AddInt (&sl, 0); 364 sl << uint32 (0);
252 365
253 if (!(pl->contr->socket.faces_sent[empty_face->number] & NS_FACESENT_FACE)) 366 if (!(pl->contr->ns->faces_sent[empty_face->number] & NS_FACESENT_FACE))
254 esrv_send_face (&pl->contr->socket, empty_face->number, 0); 367 esrv_send_face (pl->contr->ns, empty_face->number, 0);
255 368
256 if (pl->contr->socket.look_position) 369 if (pl->contr->ns->look_position)
257 { 370 {
258 SockList_AddInt (&sl, 0x80000000 | (pl->contr->socket.look_position - NUM_LOOK_OBJECTS)); 371 char buf[80];
259 SockList_AddInt (&sl, 0); 372 snprintf (buf, 80, "Apply this to see %d previous items", FLOORBOX_PAGESIZE);
260 SockList_AddInt (&sl, (uint32) - 1); 373
261 SockList_AddInt (&sl, empty_face->number); 374 sl << uint32 (0x80000000 | (pl->contr->ns->look_position - FLOORBOX_PAGESIZE))
262 sprintf (buf, "Click here to see %d previous items", NUM_LOOK_OBJECTS); 375 << uint32 (0)
263 add_stringlen_to_sockbuf (buf, &sl); 376 << sint32 (-1)
264 SockList_AddShort (&sl, 0); 377 << uint32 (empty_face->number)
265 SockList_AddChar (&sl, 0); 378 << data8 (buf)
266 SockList_AddInt (&sl, 0); 379 << uint16 (0)
380 << uint8 (0)
381 << uint32 (0);
382
267 if (pl->contr->socket.itemcmd == 2) 383 if (pl->contr->ns->itemcmd == 2)
268 SockList_AddShort (&sl, 0); 384 sl << uint16 (0);
269 } 385 }
270 386
271 for (last = NULL; tmp != last; tmp = tmp->below) 387 for (last = NULL; tmp != last; tmp = tmp->below)
272 { 388 {
273 object *head; 389 object *head;
276 { 392 {
277 last = tmp->below; /* assumes double floor mode */ 393 last = tmp->below; /* assumes double floor mode */
278 if (last && QUERY_FLAG (last, FLAG_IS_FLOOR)) 394 if (last && QUERY_FLAG (last, FLAG_IS_FLOOR))
279 last = last->below; 395 last = last->below;
280 } 396 }
397
281 if (LOOK_OBJ (tmp)) 398 if (LOOK_OBJ (tmp))
282 { 399 {
283 if (++start_look < pl->contr->socket.look_position) 400 if (++start_look < pl->contr->ns->look_position)
284 continue; 401 continue;
402
285 end_look++; 403 end_look++;
404
286 if (end_look > NUM_LOOK_OBJECTS) 405 if (end_look > FLOORBOX_PAGESIZE)
287 { 406 {
288 /* What we basically do is make a 'fake' object - when the user applies it, 407 /* 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. 408 * we notice the special tag the object has, and act accordingly.
290 */ 409 */
291 SockList_AddInt (&sl, 0x80000000 | (pl->contr->socket.look_position + NUM_LOOK_OBJECTS)); 410 sl << uint32 (0x80000000 | (pl->contr->ns->look_position + FLOORBOX_PAGESIZE))
292 SockList_AddInt (&sl, 0); 411 << uint32 (0)
293 SockList_AddInt (&sl, (uint32) - 1); 412 << uint32 ((uint32) - 1)
294 SockList_AddInt (&sl, empty_face->number); 413 << uint32 (empty_face->number)
295 sprintf (buf, "Click here to see next group of items"); 414 << data8 ("Apply this to see next group of items")
296 add_stringlen_to_sockbuf (buf, &sl); 415 << uint16 (0)
297 SockList_AddShort (&sl, 0); 416 << uint8 (0)
298 SockList_AddChar (&sl, 0); 417 << uint32 (0);
299 SockList_AddInt (&sl, 0); 418
300 if (pl->contr->socket.itemcmd == 2) 419 if (pl->contr->ns->itemcmd == 2)
301 SockList_AddShort (&sl, 0); 420 sl << uint16 (0);
421
302 break; 422 break;
303 } 423 }
424
304 if (tmp->head) 425 if (tmp->head)
305 head = tmp->head; 426 head = tmp->head;
306 else 427 else
307 head = tmp; 428 head = tmp;
308 429
309 add_object_to_socklist (&pl->contr->socket, &sl, head); 430 add_object_to_socklist (*pl->contr->ns, sl, head);
310 got_one++; 431 got_one++;
311 432
312 if (sl.len >= (MAXSOCKBUF - MAXITEMLEN)) 433 if (sl.length () >= (MAXSOCKBUF - MAXITEMLEN))
313 { 434 {
314 Send_With_Handling (&pl->contr->socket, &sl); 435 pl->contr->ns->send_packet (sl);
436
437 sl.reset ();
315 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd); 438 sl.printf ("item%d ", pl->contr->ns->itemcmd);
316 sl.len = strlen ((char *) sl.buf); 439 sl << uint32 (0);
317 SockList_AddInt (&sl, 0);
318 got_one = 0; 440 got_one = 0;
319 } 441 }
320 } /* If LOOK_OBJ() */ 442 }
321 } 443 }
444
322 if (got_one) 445 if (got_one)
323 Send_With_Handling (&pl->contr->socket, &sl); 446 pl->contr->ns->send_packet (sl);
324 447
325 free (sl.buf);
326} 448}
327 449
328/** 450/**
329 * Sends whole inventory. 451 * Sends whole inventory.
330 */ 452 */
331void 453void
332esrv_send_inventory (object *pl, object *op) 454esrv_send_inventory (object *pl, object *op)
333{ 455{
334 object *tmp; 456 object *tmp;
335 int got_one = 0; 457 int got_one = 0;
336 SockList sl;
337 458
338 sl.buf = (unsigned char *) malloc (MAXSOCKBUF);
339 459
340 sprintf ((char *) sl.buf, "delinv %d", op->count); 460 pl->contr->ns->send_packet_printf ("delinv %d", op->count);
341 sl.len = strlen ((char *) sl.buf);
342 Send_With_Handling (&pl->contr->socket, &sl);
343 461
462 packet sl;
344 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd); 463 sl.printf ("item%d ", pl->contr->ns->itemcmd);
345 sl.len = strlen ((char *) sl.buf);
346 464
347 SockList_AddInt (&sl, op->count); 465 sl << uint32 (op->count);
348 466
349 for (tmp = op->inv; tmp; tmp = tmp->below) 467 for (tmp = op->inv; tmp; tmp = tmp->below)
350 { 468 {
351 object *head; 469 object *head;
352 470
355 else 473 else
356 head = tmp; 474 head = tmp;
357 475
358 if (LOOK_OBJ (head)) 476 if (LOOK_OBJ (head))
359 { 477 {
360 add_object_to_socklist (&pl->contr->socket, &sl, head); 478 add_object_to_socklist (*pl->contr->ns, sl, head);
361 479
362 got_one++; 480 got_one++;
363 481
364 /* IT is possible for players to accumulate a huge amount of 482 /* IT is possible for players to accumulate a huge amount of
365 * items (especially with some of the bags out there) to 483 * items (especially with some of the bags out there) to
366 * overflow the buffer. IF so, send multiple item commands. 484 * overflow the buffer. IF so, send multiple item commands.
367 */ 485 */
368 if (sl.len >= (MAXSOCKBUF - MAXITEMLEN)) 486 if (sl.length () >= (MAXSOCKBUF - MAXITEMLEN))
369 { 487 {
370 Send_With_Handling (&pl->contr->socket, &sl); 488 pl->contr->ns->send_packet (sl);
489
490 sl.reset ();
371 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd); 491 sl.printf ("item%d ", pl->contr->ns->itemcmd);
372 sl.len = strlen ((char *) sl.buf); 492 sl << uint32 (op->count);
373 SockList_AddInt (&sl, op->count);
374 got_one = 0; 493 got_one = 0;
375 } 494 }
376 } /* If LOOK_OBJ() */ 495 } /* If LOOK_OBJ() */
377 } 496 }
497
378 if (got_one) 498 if (got_one)
379 Send_With_Handling (&pl->contr->socket, &sl); 499 pl->contr->ns->send_packet (sl);
380 free (sl.buf);
381} 500}
382 501
383/** 502/**
384 * Updates object *op for player *pl. 503 * Updates object *op for player *pl.
385 * 504 *
389 */ 508 */
390 509
391void 510void
392esrv_update_item (int flags, object *pl, object *op) 511esrv_update_item (int flags, object *pl, object *op)
393{ 512{
394 SockList sl;
395
396 /* If we have a request to send the player item, skip a few checks. */ 513 /* If we have a request to send the player item, skip a few checks. */
397 if (op != pl) 514 if (op != pl)
398 { 515 {
399 if (!LOOK_OBJ (op)) 516 if (!LOOK_OBJ (op))
400 return; 517 return;
401 /* we remove the check for op->env, because in theory, the object 518 /* we remove the check for op->env, because in theory, the object
402 * is hopefully in the same place, so the client should preserve 519 * is hopefully in the same place, so the client should preserve
403 * order. 520 * order.
404 */ 521 */
405 } 522 }
523
406 if (!QUERY_FLAG (op, FLAG_CLIENT_SENT)) 524 if (!QUERY_FLAG (op, FLAG_CLIENT_SENT))
407 { 525 {
408 /* FLAG_CLIENT_SENT is debug only. We are using it to see where 526 /* 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 527 * this is happening - we can set a breakpoint here in the debugger
410 * and track back the call. 528 * and track back the call.
411 */ 529 */
412 LOG (llevDebug, "We have not sent item %s (%d)\n", &op->name, op->count); 530 LOG (llevDebug, "We have not sent item %s (%d)\n", &op->name, op->count);
413 } 531 }
414 sl.buf = (unsigned char *) malloc (MAXSOCKBUF);
415 532
416 strcpy ((char *) sl.buf, "upditem "); 533 packet sl ("upditem");
417 sl.len = strlen ((char *) sl.buf);
418 534
419 SockList_AddChar (&sl, (char) flags); 535 sl << uint8 (flags);
420 536
421 if (op->head) 537 if (op->head)
422 op = op->head; 538 op = op->head;
423 539
424 SockList_AddInt (&sl, op->count); 540 sl << uint32 (op->count);
425 541
426 if (flags & UPD_LOCATION) 542 if (flags & UPD_LOCATION)
427 SockList_AddInt (&sl, op->env ? op->env->count : 0); 543 sl << uint32 (op->env ? op->env->count : 0);
428 544
429 if (flags & UPD_FLAGS) 545 if (flags & UPD_FLAGS)
430 SockList_AddInt (&sl, query_flags (op)); 546 sl << uint32 (query_flags (op));
431 547
432 if (flags & UPD_WEIGHT) 548 if (flags & UPD_WEIGHT)
433 { 549 {
434 sint32 weight = WEIGHT (op); 550 sint32 weight = WEIGHT (op);
435 551
436 SockList_AddInt (&sl, QUERY_FLAG (op, FLAG_NO_PICK) ? -1 : weight); 552 sl << uint32 (QUERY_FLAG (op, FLAG_NO_PICK) ? -1 : weight);
553
437 if (pl == op) 554 if (pl == op)
438 {
439 op->contr->last_weight = weight; 555 op->contr->last_weight = weight;
440 }
441 } 556 }
442 557
443 if (flags & UPD_FACE) 558 if (flags & UPD_FACE)
444 { 559 {
445 if (!(pl->contr->socket.faces_sent[op->face->number] & NS_FACESENT_FACE)) 560 if (!(pl->contr->ns->faces_sent[op->face->number] & NS_FACESENT_FACE))
446 esrv_send_face (&pl->contr->socket, op->face->number, 0); 561 esrv_send_face (pl->contr->ns, op->face->number, 0);
447 SockList_AddInt (&sl, op->face->number); 562
563 sl << uint32 (op->face->number);
448 } 564 }
565
449 if (flags & UPD_NAME) 566 if (flags & UPD_NAME)
450 { 567 {
451 int len; 568 int len;
452 const char *item_p; 569 const char *item_p;
453 char item_n[MAX_BUF]; 570 char item_n[MAX_BUF];
468 } 585 }
469 586
470 strncpy (item_n + len + 1, item_p, 127); 587 strncpy (item_n + len + 1, item_p, 127);
471 item_n[254] = 0; 588 item_n[254] = 0;
472 len += strlen (item_n + 1 + len) + 1; 589 len += strlen (item_n + 1 + len) + 1;
473 SockList_AddChar (&sl, (char) len); 590
474 memcpy (sl.buf + sl.len, item_n, len); 591 sl << data8 (item_n, len);
475 sl.len += len;
476 } 592 }
593
477 if (flags & UPD_ANIM) 594 if (flags & UPD_ANIM)
478 SockList_AddShort (&sl, op->animation_id); 595 sl << uint16 (op->animation_id);
479 596
480 if (flags & UPD_ANIMSPEED) 597 if (flags & UPD_ANIMSPEED)
481 { 598 {
482 int anim_speed = 0; 599 int anim_speed = 0;
483 600
492 else if (FABS (op->speed) >= 1.0) 609 else if (FABS (op->speed) >= 1.0)
493 anim_speed = 1; 610 anim_speed = 1;
494 else 611 else
495 anim_speed = (int) (1.0 / FABS (op->speed)); 612 anim_speed = (int) (1.0 / FABS (op->speed));
496 } 613 }
614
497 if (anim_speed > 255) 615 if (anim_speed > 255)
498 anim_speed = 255; 616 anim_speed = 255;
499 } 617 }
500 SockList_AddChar (&sl, (char) anim_speed); 618
619 sl << uint8 (anim_speed);
501 } 620 }
621
502 if (flags & UPD_NROF) 622 if (flags & UPD_NROF)
503 SockList_AddInt (&sl, op->nrof); 623 sl << uint32 (op->nrof);
504 624
505 Send_With_Handling (&pl->contr->socket, &sl); 625 pl->contr->ns->send_packet (sl);
506 free (sl.buf);
507} 626}
508 627
509/** 628/**
510 * Sends item's info to player. 629 * Sends item's info to player.
511 */ 630 */
512void 631void
513esrv_send_item (object *pl, object *op) 632esrv_send_item (object *pl, object *op)
514{ 633{
515 SockList sl;
516
517 /* If this is not the player object, do some more checks */ 634 /* If this is not the player object, do some more checks */
518 if (op != pl) 635 if (op != pl)
519 { 636 {
520 /* We only send 'visibile' objects to the client */ 637 /* We only send 'visibile' objects to the client */
521 if (!LOOK_OBJ (op)) 638 if (!LOOK_OBJ (op))
523 /* if the item is on the ground, mark that the look needs to 640 /* if the item is on the ground, mark that the look needs to
524 * be updated. 641 * be updated.
525 */ 642 */
526 if (!op->env) 643 if (!op->env)
527 { 644 {
528 pl->contr->socket.update_look = 1; 645 pl->contr->ns->floorbox_update ();
529 return; 646 return;
530 } 647 }
531 } 648 }
532 649
533 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 650 packet sl;
534 651
535 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd); 652 sl.printf ("item%d ", pl->contr->ns->itemcmd);
536 sl.len = strlen ((char *) sl.buf);
537 653
538 if (op->head) 654 if (op->head)
539 op = op->head; 655 op = op->head;
540 656
541 SockList_AddInt (&sl, op->env ? op->env->count : 0); 657 sl << uint32 (op->env ? op->env->count : 0);
542 658
543 add_object_to_socklist (&pl->contr->socket, &sl, op); 659 add_object_to_socklist (*pl->contr->ns, sl, op);
544 660
545 Send_With_Handling (&pl->contr->socket, &sl); 661 pl->contr->ns->send_packet (sl);
546 SET_FLAG (op, FLAG_CLIENT_SENT); 662 SET_FLAG (op, FLAG_CLIENT_SENT);
547 free (sl.buf);
548} 663}
549 664
550/** 665/**
551 * Tells the client to delete an item. Uses the item 666 * Tells the client to delete an item. Uses the item
552 * command with a -1 location. 667 * command with a -1 location.
553 */ 668 */
554 669
555void 670void
556esrv_del_item (player *pl, int tag) 671esrv_del_item (player *pl, int tag)
557{ 672{
558 SockList sl; 673 packet sl ("delitem");
559 674
560 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 675 sl << uint32 (tag);
561 676
562 strcpy ((char *) sl.buf, "delitem "); 677 pl->ns->send_packet (sl);
563 sl.len = strlen ((char *) sl.buf);
564 SockList_AddInt (&sl, tag);
565
566 Send_With_Handling (&pl->socket, &sl);
567 free (sl.buf);
568} 678}
569 679
570 680
571/******************************************************************************* 681/*******************************************************************************
572 * 682 *
593 else if (op->type == CONTAINER && pl->container == op) 703 else if (op->type == CONTAINER && pl->container == op)
594 for (tmp = op->inv; tmp; tmp = tmp->below) 704 for (tmp = op->inv; tmp; tmp = tmp->below)
595 if (tmp->count == count) 705 if (tmp->count == count)
596 return tmp; 706 return tmp;
597 707
598 for (op = get_map_ob (pl->map, pl->x, pl->y); op; op = op->above) 708 for (op = GET_MAP_OB (pl->map, pl->x, pl->y); op; op = op->above)
599 if (op->head != NULL && op->head->count == count) 709 if (op->head && op->head->count == count)
600 return op; 710 return op;
601 else if (op->count == count) 711 else if (op->count == count)
602 return op; 712 return op;
603 else if (op->type == CONTAINER && pl->container == op) 713 else if (op->type == CONTAINER && pl->container == op)
604 for (tmp = op->inv; tmp; tmp = tmp->below) 714 for (tmp = op->inv; tmp; tmp = tmp->below)
605 if (tmp->count == count) 715 if (tmp->count == count)
606 return tmp; 716 return tmp;
607 717
608 return NULL; 718 return 0;
609} 719}
610 720
611 721
612/** Client wants to examine some object. So lets do so. */ 722/** Client wants to examine some object. So lets do so. */
613void 723void
614ExamineCmd (char *buf, int len, player *pl) 724ExamineCmd (char *buf, int len, player *pl)
615{ 725{
616 long tag = atoi (buf); 726 tag_t tag = atoi (buf);
727
728 /* If the high bit is set, player examined a pseudo object. */
729 if (tag & 0x80000000)
730 return;
731
617 object *op = esrv_get_ob_from_count (pl->ob, tag); 732 object *op = esrv_get_ob_from_count (pl->ob, tag);
618 733
619 if (!op) 734 if (!op)
620 { 735 {
621 LOG (llevDebug, "Player '%s' tried to examine the unknown object (%ld)\n", &pl->ob->name, tag); 736 LOG (llevDebug, "Player '%s' tried to examine the unknown object (%ld)\n", &pl->ob->name, tag);
622 return; 737 return;
623 } 738 }
739
624 examine (pl->ob, op); 740 examine (pl->ob, op);
625} 741}
626 742
627/** Client wants to apply some object. Lets do so. */ 743/** Client wants to apply some object. Lets do so. */
628void 744void
629ApplyCmd (char *buf, int len, player *pl) 745ApplyCmd (char *buf, int len, player *pl)
630{ 746{
631 uint32 tag = atoi (buf); 747 tag_t tag = atoi (buf);
632 object *op = esrv_get_ob_from_count (pl->ob, tag);
633 748
634 /* sort of a hack, but if the player saves and the player then manually 749 /* 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. 750 * applies a savebed (or otherwise tries to do stuff), we run into trouble.
636 */ 751 */
637 if (QUERY_FLAG (pl->ob, FLAG_REMOVED)) 752 if (QUERY_FLAG (pl->ob, FLAG_REMOVED))
638 return; 753 return;
639 754
640 /* If the high bit is set, player applied a pseudo object. */ 755 /* If the high bit is set, player applied a pseudo object. */
641 if (tag & 0x80000000) 756 if (tag & 0x80000000)
642 { 757 {
643 pl->socket.look_position = tag & 0x7fffffff; 758 pl->ns->look_position = tag & 0x7fffffff;
644 pl->socket.update_look = 1; 759 pl->ns->floorbox_update ();
645 return; 760 return;
646 } 761 }
762
763 object *op = esrv_get_ob_from_count (pl->ob, tag);
647 764
648 if (!op) 765 if (!op)
649 { 766 {
650 LOG (llevDebug, "Player '%s' tried to apply the unknown object (%d)\n", &pl->ob->name, tag); 767 LOG (llevDebug, "Player '%s' tried to apply the unknown object (%d)\n", &pl->ob->name, tag);
651 return; 768 return;
652 } 769 }
770
653 player_apply (pl->ob, op, 0, 0); 771 player_apply (pl->ob, op, 0, 0);
654} 772}
655 773
656/** Client wants to apply some object. Lets do so. */ 774/** Client wants to lock some object. Lets do so. */
657void 775void
658LockItem (uint8 * data, int len, player *pl) 776LockItem (char *data, int len, player *pl)
659{ 777{
660 int flag, tag;
661 object *op;
662
663 flag = data[0]; 778 int flag = data[0];
664 tag = GetInt_String (data + 1); 779 tag_t tag = net_uint32 ((uint8 *)data + 1);
665 op = esrv_get_ob_from_count (pl->ob, tag); 780 object *op = esrv_get_ob_from_count (pl->ob, tag);
666 781
667 if (!op) 782 if (!op)
668 { 783 {
669 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Could not find object to lock/unlock"); 784 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Could not find object to lock/unlock");
670 return; 785 return;
671 } 786 }
787
672 if (!flag) 788 if (!flag)
673 CLEAR_FLAG (op, FLAG_INV_LOCKED); 789 CLEAR_FLAG (op, FLAG_INV_LOCKED);
674 else 790 else
675 SET_FLAG (op, FLAG_INV_LOCKED); 791 SET_FLAG (op, FLAG_INV_LOCKED);
792
676 esrv_update_item (UPD_FLAGS, pl->ob, op); 793 esrv_update_item (UPD_FLAGS, pl->ob, op);
677} 794}
678 795
679/** Client wants to apply some object. Lets do so. */ 796/** Client wants to mark some object. Lets do so. */
680void 797void
681MarkItem (uint8 * data, int len, player *pl) 798MarkItem (char *data, int len, player *pl)
682{ 799{
683 int tag; 800 tag_t tag = net_uint32 ((uint8 *)data);
684 object *op;
685
686 tag = GetInt_String (data);
687 op = esrv_get_ob_from_count (pl->ob, tag); 801 object *op = esrv_get_ob_from_count (pl->ob, tag);
802
688 if (!op) 803 if (!op)
689 { 804 {
690 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Could not find object to mark"); 805 new_draw_info (NDI_UNIQUE, 0, pl->ob, "Could not find object to mark");
691 return; 806 return;
692 } 807 }
808
693 pl->mark = op; 809 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)); 810 new_draw_info_format (NDI_UNIQUE, 0, pl->ob, "Marked item %s", query_name (op));
696} 811}
697
698 812
699/** 813/**
700 * look_at prints items on the specified square. 814 * look_at prints items on the specified square.
701 * 815 *
702 * [ removed EARTHWALL check and added check for containers inventory. 816 * [ removed EARTHWALL check and added check for containers inventory.
706look_at (object *op, int dx, int dy) 820look_at (object *op, int dx, int dy)
707{ 821{
708 object *tmp; 822 object *tmp;
709 int flag = 0; 823 int flag = 0;
710 sint16 x, y; 824 sint16 x, y;
711 mapstruct *m; 825 maptile *m;
712 826
713 x = op->x + dx; 827 x = op->x + dx;
714 y = op->y + dy; 828 y = op->y + dy;
715 829
716 if (out_of_map (op->map, x, y)) 830 if (out_of_map (op->map, x, y))
718 832
719 m = get_map_from_coord (op->map, &x, &y); 833 m = get_map_from_coord (op->map, &x, &y);
720 if (!m) 834 if (!m)
721 return; 835 return;
722 836
723 for (tmp = get_map_ob (m, x, y); tmp != NULL && tmp->above != NULL; tmp = tmp->above); 837 for (tmp = GET_MAP_OB (m, x, y); tmp != NULL && tmp->above != NULL; tmp = tmp->above);
724 838
725 for (; tmp != NULL; tmp = tmp->below) 839 for (; tmp != NULL; tmp = tmp->below)
726 { 840 {
727 if (tmp->invisible && !QUERY_FLAG (op, FLAG_WIZ)) 841 if (tmp->invisible && !QUERY_FLAG (op, FLAG_WIZ))
728 continue; 842 continue;
775 { 889 {
776 return; 890 return;
777 } 891 }
778 dy = atoi (cp); 892 dy = atoi (cp);
779 893
780 if (FABS (dx) > pl->socket.mapx / 2 || FABS (dy) > pl->socket.mapy / 2) 894 if (FABS (dx) > pl->ns->mapx / 2 || FABS (dy) > pl->ns->mapy / 2)
781 return; 895 return;
782 896
783 if (pl->blocked_los[dx + pl->socket.mapx / 2][dy + pl->socket.mapy / 2]) 897 if (pl->blocked_los[dx + pl->ns->mapx / 2][dy + pl->ns->mapy / 2])
784 return; 898 return;
785 899
786 look_at (pl->ob, dx, dy); 900 look_at (pl->ob, dx, dy);
787} 901}
788 902
799 return; 913 return;
800 } 914 }
801 915
802 if (!to) 916 if (!to)
803 { /* drop it to the ground */ 917 { /* drop it to the ground */
804
805/* LOG(llevDebug, "Drop it on the ground.\n");*/
806
807 if (op->map && !op->env) 918 if (op->map && !op->env)
808 {
809
810/* LOG(llevDebug,"Dropping object to ground that is already on ground\n");*/
811 return; 919 return;
812 } 920
813 /* If it is an active container, then we should drop all objects 921 /* If it is an active container, then we should drop all objects
814 * in the container and not the container itself. 922 * in the container and not the container itself.
815 */ 923 */
816 if (op->inv && QUERY_FLAG (op, FLAG_APPLIED)) 924 if (op->inv && QUERY_FLAG (op, FLAG_APPLIED))
817 { 925 {
820 for (current = op->inv; current != NULL; current = next) 928 for (current = op->inv; current != NULL; current = next)
821 { 929 {
822 next = current->below; 930 next = current->below;
823 drop_object (pl, current, 0); 931 drop_object (pl, current, 0);
824 } 932 }
933
825 esrv_update_item (UPD_WEIGHT, pl, op); 934 esrv_update_item (UPD_WEIGHT, pl, op);
826 } 935 }
827 else 936 else
828 {
829 drop_object (pl, op, nrof); 937 drop_object (pl, op, nrof);
830 } 938
831 return; 939 return;
832 } 940 }
833 else if (to == pl->count) 941 else if (to == pl->count)
834 { /* pick it up to the inventory */ 942 { /* pick it up to the inventory */
835 /* return if player has already picked it up */ 943 /* return if player has already picked it up */
838 946
839 pl->contr->count = nrof; 947 pl->contr->count = nrof;
840 pick_up (pl, op); 948 pick_up (pl, op);
841 return; 949 return;
842 } 950 }
951
843 env = esrv_get_ob_from_count (pl, to); 952 env = esrv_get_ob_from_count (pl, to);
844 if (!env) 953 if (!env)
845 { 954 {
846 LOG (llevDebug, "Player '%s' tried to move object to the unknown location (%d)\n", &pl->name, to); 955 LOG (llevDebug, "Player '%s' tried to move object to the unknown location (%d)\n", &pl->name, to);
847 return; 956 return;
848 } 957 }
958
849 /* put_object_in_sack presumes that necessary sanity checking 959 /* put_object_in_sack presumes that necessary sanity checking
850 * has already been done (eg, it can be picked up and fits in 960 * 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 961 * 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. 962 * an make sure env is in fact a container for that matter.
853 */ 963 */
854 if (env->type == CONTAINER && can_pick (pl, op) && sack_can_hold (pl, env, op, nrof)) 964 if (env->type == CONTAINER && can_pick (pl, op) && sack_can_hold (pl, env, op, nrof))
855 {
856 put_object_in_sack (pl, env, op, nrof); 965 put_object_in_sack (pl, env, op, nrof);
857 }
858} 966}
967

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines