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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines