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.24 by root, Sat Dec 16 22:14:42 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 packet sl;
246 220
247 Write_String_To_Socket (&pl->contr->socket, "delinv 0", strlen ("delinv 0")); 221 pl->contr->socket->send_packet ("delinv 0");
222
248 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd); 223 sl.printf ("item%d ", pl->contr->socket->itemcmd);
249 sl.len = strlen ((char *) sl.buf);
250 224
251 SockList_AddInt (&sl, 0); 225 sl << uint32 (0);
252 226
253 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))
254 esrv_send_face (&pl->contr->socket, empty_face->number, 0); 228 esrv_send_face (pl->contr->socket, empty_face->number, 0);
255 229
256 if (pl->contr->socket.look_position) 230 if (pl->contr->socket->look_position)
257 { 231 {
258 SockList_AddInt (&sl, 0x80000000 | (pl->contr->socket.look_position - NUM_LOOK_OBJECTS)); 232 char buf[80];
259 SockList_AddInt (&sl, 0);
260 SockList_AddInt (&sl, (uint32) - 1);
261 SockList_AddInt (&sl, empty_face->number);
262 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);
263 add_stringlen_to_sockbuf (buf, &sl); 234
264 SockList_AddShort (&sl, 0); 235 sl << uint32 (0x80000000 | (pl->contr->socket->look_position - NUM_LOOK_OBJECTS))
265 SockList_AddChar (&sl, 0); 236 << uint32 (0)
266 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
267 if (pl->contr->socket.itemcmd == 2) 244 if (pl->contr->socket->itemcmd == 2)
268 SockList_AddShort (&sl, 0); 245 sl << uint16 (0);
269 } 246 }
270 247
271 for (last = NULL; tmp != last; tmp = tmp->below) 248 for (last = NULL; tmp != last; tmp = tmp->below)
272 { 249 {
273 object *head; 250 object *head;
276 { 253 {
277 last = tmp->below; /* assumes double floor mode */ 254 last = tmp->below; /* assumes double floor mode */
278 if (last && QUERY_FLAG (last, FLAG_IS_FLOOR)) 255 if (last && QUERY_FLAG (last, FLAG_IS_FLOOR))
279 last = last->below; 256 last = last->below;
280 } 257 }
258
281 if (LOOK_OBJ (tmp)) 259 if (LOOK_OBJ (tmp))
282 { 260 {
283 if (++start_look < pl->contr->socket.look_position) 261 if (++start_look < pl->contr->socket->look_position)
284 continue; 262 continue;
263
285 end_look++; 264 end_look++;
265
286 if (end_look > NUM_LOOK_OBJECTS) 266 if (end_look > NUM_LOOK_OBJECTS)
287 { 267 {
288 /* 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,
289 * we notice the special tag the object has, and act accordingly. 269 * we notice the special tag the object has, and act accordingly.
290 */ 270 */
291 SockList_AddInt (&sl, 0x80000000 | (pl->contr->socket.look_position + NUM_LOOK_OBJECTS)); 271 sl << uint32 (0x80000000 | (pl->contr->socket->look_position + NUM_LOOK_OBJECTS))
292 SockList_AddInt (&sl, 0); 272 << uint32 (0)
293 SockList_AddInt (&sl, (uint32) - 1); 273 << uint32 ((uint32) - 1)
294 SockList_AddInt (&sl, empty_face->number); 274 << uint32 (empty_face->number)
295 sprintf (buf, "Click here to see next group of items"); 275 << data8 ("Apply this to see next group of items")
296 add_stringlen_to_sockbuf (buf, &sl); 276 << uint16 (0)
297 SockList_AddShort (&sl, 0); 277 << uint8 (0)
298 SockList_AddChar (&sl, 0); 278 << uint32 (0);
299 SockList_AddInt (&sl, 0); 279
300 if (pl->contr->socket.itemcmd == 2) 280 if (pl->contr->socket->itemcmd == 2)
301 SockList_AddShort (&sl, 0); 281 sl << uint16 (0);
282
302 break; 283 break;
303 } 284 }
285
304 if (tmp->head) 286 if (tmp->head)
305 head = tmp->head; 287 head = tmp->head;
306 else 288 else
307 head = tmp; 289 head = tmp;
308 290
309 add_object_to_socklist (&pl->contr->socket, &sl, head); 291 add_object_to_socklist (*pl->contr->socket, sl, head);
310 got_one++; 292 got_one++;
311 293
312 if (sl.len >= (MAXSOCKBUF - MAXITEMLEN)) 294 if (sl.length () >= (MAXSOCKBUF - MAXITEMLEN))
313 { 295 {
314 Send_With_Handling (&pl->contr->socket, &sl); 296 pl->contr->socket->send_packet (sl);
297
298 sl.reset ();
315 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd); 299 sl.printf ("item%d ", pl->contr->socket->itemcmd);
316 sl.len = strlen ((char *) sl.buf); 300 sl << uint32 (0);
317 SockList_AddInt (&sl, 0);
318 got_one = 0; 301 got_one = 0;
319 } 302 }
320 } /* If LOOK_OBJ() */ 303 }
321 } 304 }
305
322 if (got_one) 306 if (got_one)
323 Send_With_Handling (&pl->contr->socket, &sl); 307 pl->contr->socket->send_packet (sl);
324 308
325 free (sl.buf);
326} 309}
327 310
328/** 311/**
329 * Sends whole inventory. 312 * Sends whole inventory.
330 */ 313 */
331void 314void
332esrv_send_inventory (object *pl, object *op) 315esrv_send_inventory (object *pl, object *op)
333{ 316{
334 object *tmp; 317 object *tmp;
335 int got_one = 0; 318 int got_one = 0;
336 SockList sl;
337 319
338 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 320 packet sl;
339 321
340 sprintf ((char *) sl.buf, "delinv %d", op->count); 322 sl.printf ("delinv %d", op->count);
341 sl.len = strlen ((char *) sl.buf); 323 pl->contr->socket->send_packet (sl);
342 Send_With_Handling (&pl->contr->socket, &sl);
343 324
325 sl.reset ();
344 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd); 326 sl.printf ("item%d ", pl->contr->socket->itemcmd);
345 sl.len = strlen ((char *) sl.buf);
346 327
347 SockList_AddInt (&sl, op->count); 328 sl << uint32 (op->count);
348 329
349 for (tmp = op->inv; tmp; tmp = tmp->below) 330 for (tmp = op->inv; tmp; tmp = tmp->below)
350 { 331 {
351 object *head; 332 object *head;
352 333
355 else 336 else
356 head = tmp; 337 head = tmp;
357 338
358 if (LOOK_OBJ (head)) 339 if (LOOK_OBJ (head))
359 { 340 {
360 add_object_to_socklist (&pl->contr->socket, &sl, head); 341 add_object_to_socklist (*pl->contr->socket, sl, head);
361 342
362 got_one++; 343 got_one++;
363 344
364 /* IT is possible for players to accumulate a huge amount of 345 /* IT is possible for players to accumulate a huge amount of
365 * items (especially with some of the bags out there) to 346 * items (especially with some of the bags out there) to
366 * overflow the buffer. IF so, send multiple item commands. 347 * overflow the buffer. IF so, send multiple item commands.
367 */ 348 */
368 if (sl.len >= (MAXSOCKBUF - MAXITEMLEN)) 349 if (sl.length () >= (MAXSOCKBUF - MAXITEMLEN))
369 { 350 {
370 Send_With_Handling (&pl->contr->socket, &sl); 351 pl->contr->socket->send_packet (sl);
352
353 sl.reset ();
371 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd); 354 sl.printf ("item%d ", pl->contr->socket->itemcmd);
372 sl.len = strlen ((char *) sl.buf); 355 sl << uint32 (op->count);
373 SockList_AddInt (&sl, op->count);
374 got_one = 0; 356 got_one = 0;
375 } 357 }
376 } /* If LOOK_OBJ() */ 358 } /* If LOOK_OBJ() */
377 } 359 }
360
378 if (got_one) 361 if (got_one)
379 Send_With_Handling (&pl->contr->socket, &sl); 362 pl->contr->socket->send_packet (sl);
380 free (sl.buf);
381} 363}
382 364
383/** 365/**
384 * Updates object *op for player *pl. 366 * Updates object *op for player *pl.
385 * 367 *
389 */ 371 */
390 372
391void 373void
392esrv_update_item (int flags, object *pl, object *op) 374esrv_update_item (int flags, object *pl, object *op)
393{ 375{
394 SockList sl;
395
396 /* 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. */
397 if (op != pl) 377 if (op != pl)
398 { 378 {
399 if (!LOOK_OBJ (op)) 379 if (!LOOK_OBJ (op))
400 return; 380 return;
401 /* 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
402 * is hopefully in the same place, so the client should preserve 382 * is hopefully in the same place, so the client should preserve
403 * order. 383 * order.
404 */ 384 */
405 } 385 }
386
406 if (!QUERY_FLAG (op, FLAG_CLIENT_SENT)) 387 if (!QUERY_FLAG (op, FLAG_CLIENT_SENT))
407 { 388 {
408 /* 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
409 * 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
410 * and track back the call. 391 * and track back the call.
411 */ 392 */
412 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);
413 } 394 }
414 sl.buf = (unsigned char *) malloc (MAXSOCKBUF);
415 395
416 strcpy ((char *) sl.buf, "upditem "); 396 packet sl;
417 sl.len = strlen ((char *) sl.buf);
418 397
419 SockList_AddChar (&sl, (char) flags); 398 sl << "upditem "
399 << uint8 (flags);
420 400
421 if (op->head) 401 if (op->head)
422 op = op->head; 402 op = op->head;
423 403
424 SockList_AddInt (&sl, op->count); 404 sl << uint32 (op->count);
425 405
426 if (flags & UPD_LOCATION) 406 if (flags & UPD_LOCATION)
427 SockList_AddInt (&sl, op->env ? op->env->count : 0); 407 sl << uint32 (op->env ? op->env->count : 0);
428 408
429 if (flags & UPD_FLAGS) 409 if (flags & UPD_FLAGS)
430 SockList_AddInt (&sl, query_flags (op)); 410 sl << uint32 (query_flags (op));
431 411
432 if (flags & UPD_WEIGHT) 412 if (flags & UPD_WEIGHT)
433 { 413 {
434 sint32 weight = WEIGHT (op); 414 sint32 weight = WEIGHT (op);
435 415
436 SockList_AddInt (&sl, QUERY_FLAG (op, FLAG_NO_PICK) ? -1 : weight); 416 sl << uint32 (QUERY_FLAG (op, FLAG_NO_PICK) ? -1 : weight);
417
437 if (pl == op) 418 if (pl == op)
438 {
439 op->contr->last_weight = weight; 419 op->contr->last_weight = weight;
440 }
441 } 420 }
442 421
443 if (flags & UPD_FACE) 422 if (flags & UPD_FACE)
444 { 423 {
445 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))
446 esrv_send_face (&pl->contr->socket, op->face->number, 0); 425 esrv_send_face (pl->contr->socket, op->face->number, 0);
447 SockList_AddInt (&sl, op->face->number); 426
427 sl << uint32 (op->face->number);
448 } 428 }
429
449 if (flags & UPD_NAME) 430 if (flags & UPD_NAME)
450 { 431 {
451 int len; 432 int len;
452 const char *item_p; 433 const char *item_p;
453 char item_n[MAX_BUF]; 434 char item_n[MAX_BUF];
468 } 449 }
469 450
470 strncpy (item_n + len + 1, item_p, 127); 451 strncpy (item_n + len + 1, item_p, 127);
471 item_n[254] = 0; 452 item_n[254] = 0;
472 len += strlen (item_n + 1 + len) + 1; 453 len += strlen (item_n + 1 + len) + 1;
473 SockList_AddChar (&sl, (char) len); 454
474 memcpy (sl.buf + sl.len, item_n, len); 455 sl << data8 (item_n, len);
475 sl.len += len;
476 } 456 }
457
477 if (flags & UPD_ANIM) 458 if (flags & UPD_ANIM)
478 SockList_AddShort (&sl, op->animation_id); 459 sl << uint16 (op->animation_id);
479 460
480 if (flags & UPD_ANIMSPEED) 461 if (flags & UPD_ANIMSPEED)
481 { 462 {
482 int anim_speed = 0; 463 int anim_speed = 0;
483 464
492 else if (FABS (op->speed) >= 1.0) 473 else if (FABS (op->speed) >= 1.0)
493 anim_speed = 1; 474 anim_speed = 1;
494 else 475 else
495 anim_speed = (int) (1.0 / FABS (op->speed)); 476 anim_speed = (int) (1.0 / FABS (op->speed));
496 } 477 }
478
497 if (anim_speed > 255) 479 if (anim_speed > 255)
498 anim_speed = 255; 480 anim_speed = 255;
499 } 481 }
500 SockList_AddChar (&sl, (char) anim_speed); 482
483 sl << uint8 (anim_speed);
501 } 484 }
485
502 if (flags & UPD_NROF) 486 if (flags & UPD_NROF)
503 SockList_AddInt (&sl, op->nrof); 487 sl << uint32 (op->nrof);
504 488
505 Send_With_Handling (&pl->contr->socket, &sl); 489 pl->contr->socket->send_packet (sl);
506 free (sl.buf);
507} 490}
508 491
509/** 492/**
510 * Sends item's info to player. 493 * Sends item's info to player.
511 */ 494 */
512void 495void
513esrv_send_item (object *pl, object *op) 496esrv_send_item (object *pl, object *op)
514{ 497{
515 SockList sl;
516
517 /* If this is not the player object, do some more checks */ 498 /* If this is not the player object, do some more checks */
518 if (op != pl) 499 if (op != pl)
519 { 500 {
520 /* We only send 'visibile' objects to the client */ 501 /* We only send 'visibile' objects to the client */
521 if (!LOOK_OBJ (op)) 502 if (!LOOK_OBJ (op))
523 /* 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
524 * be updated. 505 * be updated.
525 */ 506 */
526 if (!op->env) 507 if (!op->env)
527 { 508 {
528 pl->contr->socket.update_look = 1; 509 pl->contr->socket->update_look = 1;
529 return; 510 return;
530 } 511 }
531 } 512 }
532 513
533 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 514 packet sl;
534 515
535 sprintf ((char *) sl.buf, "item%d ", pl->contr->socket.itemcmd); 516 sl.printf ("item%d ", pl->contr->socket->itemcmd);
536 sl.len = strlen ((char *) sl.buf);
537 517
538 if (op->head) 518 if (op->head)
539 op = op->head; 519 op = op->head;
540 520
541 SockList_AddInt (&sl, op->env ? op->env->count : 0); 521 sl << uint32 (op->env ? op->env->count : 0);
542 522
543 add_object_to_socklist (&pl->contr->socket, &sl, op); 523 add_object_to_socklist (*pl->contr->socket, sl, op);
544 524
545 Send_With_Handling (&pl->contr->socket, &sl); 525 pl->contr->socket->send_packet (sl);
546 SET_FLAG (op, FLAG_CLIENT_SENT); 526 SET_FLAG (op, FLAG_CLIENT_SENT);
547 free (sl.buf);
548} 527}
549 528
550/** 529/**
551 * Tells the client to delete an item. Uses the item 530 * Tells the client to delete an item. Uses the item
552 * command with a -1 location. 531 * command with a -1 location.
553 */ 532 */
554 533
555void 534void
556esrv_del_item (player *pl, int tag) 535esrv_del_item (player *pl, int tag)
557{ 536{
558 SockList sl; 537 packet sl;
559 538
560 sl.buf = (unsigned char *) malloc (MAXSOCKBUF); 539 sl << "delitem "
540 << uint32 (tag);
561 541
562 strcpy ((char *) sl.buf, "delitem "); 542 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} 543}
569 544
570 545
571/******************************************************************************* 546/*******************************************************************************
572 * 547 *
594 for (tmp = op->inv; tmp; tmp = tmp->below) 569 for (tmp = op->inv; tmp; tmp = tmp->below)
595 if (tmp->count == count) 570 if (tmp->count == count)
596 return tmp; 571 return tmp;
597 572
598 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)
599 if (op->head != NULL && op->head->count == count) 574 if (op->head && op->head->count == count)
600 return op; 575 return op;
601 else if (op->count == count) 576 else if (op->count == count)
602 return op; 577 return op;
603 else if (op->type == CONTAINER && pl->container == op) 578 else if (op->type == CONTAINER && pl->container == op)
604 for (tmp = op->inv; tmp; tmp = tmp->below) 579 for (tmp = op->inv; tmp; tmp = tmp->below)
605 if (tmp->count == count) 580 if (tmp->count == count)
606 return tmp; 581 return tmp;
607 582
608 return NULL; 583 return 0;
609} 584}
610 585
611 586
612/** Client wants to examine some object. So lets do so. */ 587/** Client wants to examine some object. So lets do so. */
613void 588void
614ExamineCmd (char *buf, int len, player *pl) 589ExamineCmd (char *buf, int len, player *pl)
615{ 590{
616 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
617 object *op = esrv_get_ob_from_count (pl->ob, tag); 597 object *op = esrv_get_ob_from_count (pl->ob, tag);
618 598
619 if (!op) 599 if (!op)
620 { 600 {
621 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);
622 return; 602 return;
623 } 603 }
604
624 examine (pl->ob, op); 605 examine (pl->ob, op);
625} 606}
626 607
627/** Client wants to apply some object. Lets do so. */ 608/** Client wants to apply some object. Lets do so. */
628void 609void
629ApplyCmd (char *buf, int len, player *pl) 610ApplyCmd (char *buf, int len, player *pl)
630{ 611{
631 uint32 tag = atoi (buf); 612 tag_t tag = atoi (buf);
632 object *op = esrv_get_ob_from_count (pl->ob, tag);
633 613
634 /* 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
635 * 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.
636 */ 616 */
637 if (QUERY_FLAG (pl->ob, FLAG_REMOVED)) 617 if (QUERY_FLAG (pl->ob, FLAG_REMOVED))
638 return; 618 return;
639 619
640 /* If the high bit is set, player applied a pseudo object. */ 620 /* If the high bit is set, player applied a pseudo object. */
641 if (tag & 0x80000000) 621 if (tag & 0x80000000)
642 { 622 {
643 pl->socket.look_position = tag & 0x7fffffff; 623 pl->socket->look_position = tag & 0x7fffffff;
644 pl->socket.update_look = 1; 624 pl->socket->update_look = 1;
645 return; 625 return;
646 } 626 }
627
628 object *op = esrv_get_ob_from_count (pl->ob, tag);
647 629
648 if (!op) 630 if (!op)
649 { 631 {
650 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);
651 return; 633 return;
652 } 634 }
635
653 player_apply (pl->ob, op, 0, 0); 636 player_apply (pl->ob, op, 0, 0);
654} 637}
655 638
656/** Client wants to apply some object. Lets do so. */ 639/** Client wants to apply some object. Lets do so. */
657void 640void
658LockItem (uint8 * data, int len, player *pl) 641LockItem (char *data, int len, player *pl)
659{ 642{
660 int flag, tag;
661 object *op;
662
663 flag = data[0]; 643 int flag = data[0];
664 tag = GetInt_String (data + 1); 644 tag_t tag = net_uint32 ((uint8 *)data + 1);
665 op = esrv_get_ob_from_count (pl->ob, tag); 645 object *op = esrv_get_ob_from_count (pl->ob, tag);
666 646
667 if (!op) 647 if (!op)
668 { 648 {
669 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");
670 return; 650 return;
671 } 651 }
652
672 if (!flag) 653 if (!flag)
673 CLEAR_FLAG (op, FLAG_INV_LOCKED); 654 CLEAR_FLAG (op, FLAG_INV_LOCKED);
674 else 655 else
675 SET_FLAG (op, FLAG_INV_LOCKED); 656 SET_FLAG (op, FLAG_INV_LOCKED);
657
676 esrv_update_item (UPD_FLAGS, pl->ob, op); 658 esrv_update_item (UPD_FLAGS, pl->ob, op);
677} 659}
678 660
679/** Client wants to apply some object. Lets do so. */ 661/** Client wants to apply some object. Lets do so. */
680void 662void
681MarkItem (uint8 * data, int len, player *pl) 663MarkItem (char *data, int len, player *pl)
682{ 664{
683 int tag; 665 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); 666 object *op = esrv_get_ob_from_count (pl->ob, tag);
667
688 if (!op) 668 if (!op)
689 { 669 {
690 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");
691 return; 671 return;
692 } 672 }
673
693 pl->mark = op; 674 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)); 675 new_draw_info_format (NDI_UNIQUE, 0, pl->ob, "Marked item %s", query_name (op));
696} 676}
697
698 677
699/** 678/**
700 * look_at prints items on the specified square. 679 * look_at prints items on the specified square.
701 * 680 *
702 * [ removed EARTHWALL check and added check for containers inventory. 681 * [ removed EARTHWALL check and added check for containers inventory.
706look_at (object *op, int dx, int dy) 685look_at (object *op, int dx, int dy)
707{ 686{
708 object *tmp; 687 object *tmp;
709 int flag = 0; 688 int flag = 0;
710 sint16 x, y; 689 sint16 x, y;
711 mapstruct *m; 690 maptile *m;
712 691
713 x = op->x + dx; 692 x = op->x + dx;
714 y = op->y + dy; 693 y = op->y + dy;
715 694
716 if (out_of_map (op->map, x, y)) 695 if (out_of_map (op->map, x, y))
775 { 754 {
776 return; 755 return;
777 } 756 }
778 dy = atoi (cp); 757 dy = atoi (cp);
779 758
780 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)
781 return; 760 return;
782 761
783 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])
784 return; 763 return;
785 764
786 look_at (pl->ob, dx, dy); 765 look_at (pl->ob, dx, dy);
787} 766}
788 767
799 return; 778 return;
800 } 779 }
801 780
802 if (!to) 781 if (!to)
803 { /* drop it to the ground */ 782 { /* drop it to the ground */
804
805/* LOG(llevDebug, "Drop it on the ground.\n");*/
806
807 if (op->map && !op->env) 783 if (op->map && !op->env)
808 {
809
810/* LOG(llevDebug,"Dropping object to ground that is already on ground\n");*/
811 return; 784 return;
812 } 785
813 /* 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
814 * in the container and not the container itself. 787 * in the container and not the container itself.
815 */ 788 */
816 if (op->inv && QUERY_FLAG (op, FLAG_APPLIED)) 789 if (op->inv && QUERY_FLAG (op, FLAG_APPLIED))
817 { 790 {
820 for (current = op->inv; current != NULL; current = next) 793 for (current = op->inv; current != NULL; current = next)
821 { 794 {
822 next = current->below; 795 next = current->below;
823 drop_object (pl, current, 0); 796 drop_object (pl, current, 0);
824 } 797 }
798
825 esrv_update_item (UPD_WEIGHT, pl, op); 799 esrv_update_item (UPD_WEIGHT, pl, op);
826 } 800 }
827 else 801 else
828 {
829 drop_object (pl, op, nrof); 802 drop_object (pl, op, nrof);
830 } 803
831 return; 804 return;
832 } 805 }
833 else if (to == pl->count) 806 else if (to == pl->count)
834 { /* pick it up to the inventory */ 807 { /* pick it up to the inventory */
835 /* return if player has already picked it up */ 808 /* return if player has already picked it up */
838 811
839 pl->contr->count = nrof; 812 pl->contr->count = nrof;
840 pick_up (pl, op); 813 pick_up (pl, op);
841 return; 814 return;
842 } 815 }
816
843 env = esrv_get_ob_from_count (pl, to); 817 env = esrv_get_ob_from_count (pl, to);
844 if (!env) 818 if (!env)
845 { 819 {
846 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);
847 return; 821 return;
848 } 822 }
823
849 /* put_object_in_sack presumes that necessary sanity checking 824 /* put_object_in_sack presumes that necessary sanity checking
850 * 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
851 * 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
852 * 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.
853 */ 828 */
854 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))
855 {
856 put_object_in_sack (pl, env, op, nrof); 830 put_object_in_sack (pl, env, op, nrof);
857 }
858} 831}
832

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines