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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines