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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines