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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines