1 | /* |
1 | /* |
2 | * static char *rcsid_login_c = |
2 | * static char *rcsid_login_c = |
3 | * "$Id: login.C,v 1.4 2006/08/28 07:07:42 root Exp $"; |
3 | * "$Id: login.C,v 1.5 2006/08/28 14:05:24 root Exp $"; |
4 | */ |
4 | */ |
5 | |
5 | |
6 | /* |
6 | /* |
7 | CrossFire, A Multiplayer game for X-windows |
7 | CrossFire, A Multiplayer game for X-windows |
8 | |
8 | |
… | |
… | |
223 | * will be saved at the emergency save location. |
223 | * will be saved at the emergency save location. |
224 | * Returns non zero if successful. |
224 | * Returns non zero if successful. |
225 | */ |
225 | */ |
226 | |
226 | |
227 | int save_player(object *op, int flag) { |
227 | int save_player(object *op, int flag) { |
228 | FILE *fp; |
228 | char filename[MAX_BUF]; |
229 | char filename[MAX_BUF], *tmpfilename,backupfile[MAX_BUF]; |
|
|
230 | object *tmp, *container=NULL; |
229 | object *tmp, *container=NULL; |
231 | player *pl = op->contr; |
230 | player *pl = op->contr; |
232 | int i,wiz=QUERY_FLAG(op,FLAG_WIZ); |
231 | int i,wiz=QUERY_FLAG(op,FLAG_WIZ); |
233 | long checksum; |
232 | long checksum; |
234 | #ifdef BACKUP_SAVE_AT_HOME |
233 | #ifdef BACKUP_SAVE_AT_HOME |
… | |
… | |
254 | * mostly exited. |
253 | * mostly exited. |
255 | */ |
254 | */ |
256 | if (pl->state != ST_PLAYING && pl->state != ST_GET_PARTY_PASSWORD) |
255 | if (pl->state != ST_PLAYING && pl->state != ST_GET_PARTY_PASSWORD) |
257 | return 0; |
256 | return 0; |
258 | |
257 | |
|
|
258 | INVOKE_PLAYER (SAVE, op->contr, ARG_STRING (filename)); |
|
|
259 | |
259 | if (flag == 0) |
260 | if (flag == 0) |
260 | terminate_all_pets(op); |
261 | terminate_all_pets(op); |
261 | |
262 | |
262 | /* Delete old style file */ |
|
|
263 | sprintf(filename,"%s/%s/%s.pl",settings.localdir,settings.playerdir,op->name); |
|
|
264 | unlink(filename); |
|
|
265 | |
|
|
266 | sprintf(filename,"%s/%s/%s/%s.pl",settings.localdir,settings.playerdir,op->name,op->name); |
263 | sprintf(filename,"%s/%s/%s/%s.pl",settings.localdir,settings.playerdir,op->name,op->name); |
267 | make_path_to_file(filename); |
264 | make_path_to_file(filename); |
268 | |
265 | |
269 | tmpfilename = tempnam_local(settings.tmpdir,NULL); |
266 | object_freezer fp (filename); |
270 | fp=fopen(tmpfilename, "w"); |
267 | |
271 | if(!fp) { |
268 | if (!fp) |
|
|
269 | { |
272 | new_draw_info(NDI_UNIQUE, 0,op, "Can't open file for save."); |
270 | new_draw_info(NDI_UNIQUE, 0,op, "Can't open file for save."); |
273 | LOG(llevDebug,"Can't open file for save (%s).\n",tmpfilename); |
|
|
274 | free(tmpfilename); |
|
|
275 | return 0; |
271 | return 0; |
276 | } |
272 | } |
277 | |
273 | |
278 | /* Eneq(@csd.uu.se): If we have an open container hide it. */ |
274 | /* Eneq(@csd.uu.se): If we have an open container hide it. */ |
279 | if (op->container) { |
275 | if (op->container) |
|
|
276 | { |
280 | container=op->container; |
277 | container = op->container; |
281 | op->container=NULL; |
278 | op->container = NULL; |
282 | } |
279 | } |
283 | |
|
|
284 | INVOKE_PLAYER (SAVE, op->contr, ARG_STRING (filename)); |
|
|
285 | |
|
|
286 | object_freezer freezer (filename); |
|
|
287 | |
280 | |
288 | fprintf(fp,"password %s\n",pl->password); |
281 | fprintf(fp,"password %s\n",pl->password); |
|
|
282 | |
289 | if (settings.set_title == TRUE) |
283 | if (settings.set_title == TRUE) |
290 | if(pl->own_title[0]!='\0') |
284 | if(pl->own_title[0]!='\0') |
291 | fprintf(fp,"title %s\n",pl->own_title); |
285 | fprintf(fp,"title %s\n",pl->own_title); |
292 | |
286 | |
293 | fprintf(fp,"explore %d\n",pl->explore); |
287 | fprintf(fp,"explore %d\n",pl->explore); |
… | |
… | |
309 | (pl->usekeys==keyrings?"keyrings":"containers")); |
303 | (pl->usekeys==keyrings?"keyrings":"containers")); |
310 | /* Match the enumerations but in string form */ |
304 | /* Match the enumerations but in string form */ |
311 | fprintf(fp,"unapply %s\n", pl->unapply==unapply_nochoice?"unapply_nochoice": |
305 | fprintf(fp,"unapply %s\n", pl->unapply==unapply_nochoice?"unapply_nochoice": |
312 | (pl->unapply==unapply_never?"unapply_never":"unapply_always")); |
306 | (pl->unapply==unapply_never?"unapply_never":"unapply_always")); |
313 | |
307 | |
314 | |
|
|
315 | |
|
|
316 | #ifdef BACKUP_SAVE_AT_HOME |
308 | #ifdef BACKUP_SAVE_AT_HOME |
317 | if (op->map!=NULL && flag==0) |
309 | if (op->map!=NULL && flag==0) |
318 | #else |
310 | #else |
319 | if (op->map!=NULL) |
311 | if (op->map!=NULL) |
320 | #endif |
312 | #endif |
… | |
… | |
338 | fprintf(fp,"%d\n",pl->levhp[i]); |
330 | fprintf(fp,"%d\n",pl->levhp[i]); |
339 | fprintf(fp,"%d\n",pl->levsp[i]); |
331 | fprintf(fp,"%d\n",pl->levsp[i]); |
340 | fprintf(fp,"%d\n",pl->levgrace[i]); |
332 | fprintf(fp,"%d\n",pl->levgrace[i]); |
341 | } |
333 | } |
342 | |
334 | |
343 | freezer.put (fp, op->contr); |
335 | fp.put (op->contr); |
344 | |
336 | |
345 | fprintf(fp,"endplst\n"); |
337 | fprintf(fp,"endplst\n"); |
346 | |
338 | |
347 | SET_FLAG(op, FLAG_NO_FIX_PLAYER); |
339 | SET_FLAG(op, FLAG_NO_FIX_PLAYER); |
348 | CLEAR_FLAG(op, FLAG_WIZ); |
340 | CLEAR_FLAG(op, FLAG_WIZ); |
… | |
… | |
354 | op->y = -1; |
346 | op->y = -1; |
355 | } |
347 | } |
356 | /* Save objects, but not unpaid objects. Don't remove objects from |
348 | /* Save objects, but not unpaid objects. Don't remove objects from |
357 | * inventory. |
349 | * inventory. |
358 | */ |
350 | */ |
359 | save_object(fp, freezer, op, 2); |
351 | save_object(fp, op, 2); |
360 | if (flag) { |
352 | if (flag) { |
361 | op->x = backup_x; |
353 | op->x = backup_x; |
362 | op->y = backup_y; |
354 | op->y = backup_y; |
363 | } |
355 | } |
364 | #else |
356 | #else |
365 | save_object(fp, freezer, op, 3); /* don't check and don't remove */ |
357 | save_object(fp, op, 3); /* don't check and don't remove */ |
366 | #endif |
358 | #endif |
367 | |
359 | |
368 | CLEAR_FLAG(op, FLAG_NO_FIX_PLAYER); |
360 | CLEAR_FLAG(op, FLAG_NO_FIX_PLAYER); |
369 | |
361 | |
370 | if(!flag) |
362 | if(!flag) |
371 | while ((tmp = op->inv)) |
363 | while ((tmp = op->inv)) |
372 | destroy_object (tmp); |
364 | destroy_object (tmp); |
373 | |
365 | |
374 | if (fclose(fp) == EOF) { /* make sure the write succeeded */ |
|
|
375 | new_draw_info(NDI_UNIQUE, 0,op, "Can't save character."); |
|
|
376 | unlink(tmpfilename); |
|
|
377 | free(tmpfilename); |
|
|
378 | return 0; |
|
|
379 | } |
|
|
380 | |
|
|
381 | checksum = 0; |
|
|
382 | sprintf(backupfile, "%s.tmp", filename); |
|
|
383 | rename(filename, backupfile); |
|
|
384 | fp = fopen(filename,"w"); |
|
|
385 | if(!fp) { |
|
|
386 | new_draw_info(NDI_UNIQUE, 0,op, "Can't open file for save."); |
|
|
387 | unlink(tmpfilename); |
|
|
388 | free(tmpfilename); |
|
|
389 | return 0; |
|
|
390 | } |
|
|
391 | fprintf(fp,"checksum %lx\n",checksum); |
|
|
392 | copy_file(tmpfilename, fp); |
|
|
393 | unlink(tmpfilename); |
|
|
394 | free(tmpfilename); |
|
|
395 | if (fclose(fp) == EOF) { /* got write error */ |
|
|
396 | new_draw_info(NDI_UNIQUE, 0,op, "Can't close file for save."); |
|
|
397 | rename(backupfile, filename); /* Restore the original */ |
|
|
398 | return 0; |
|
|
399 | } |
|
|
400 | else |
|
|
401 | unlink(backupfile); |
|
|
402 | |
|
|
403 | /* Eneq(@csd.uu.se): Reveal the container if we have one. */ |
366 | /* Eneq(@csd.uu.se): Reveal the container if we have one. */ |
404 | if (flag&&container!=NULL) |
367 | if (flag&&container!=NULL) |
405 | op->container = container; |
368 | op->container = container; |
406 | |
369 | |
407 | if (wiz) SET_FLAG(op,FLAG_WIZ); |
370 | if (wiz) SET_FLAG(op,FLAG_WIZ); |
|
|
371 | |
408 | if(!flag) |
372 | if(!flag) |
409 | esrv_send_inventory(op, op); |
373 | esrv_send_inventory(op, op); |
410 | |
374 | |
411 | chmod(filename,SAVE_MODE); |
|
|
412 | |
|
|
413 | return 1; |
375 | return 1; |
414 | } |
376 | } |
415 | |
|
|
416 | void copy_file(const char *filename, FILE *fpout) { |
|
|
417 | FILE *fp; |
|
|
418 | char buf[MAX_BUF]; |
|
|
419 | if((fp = fopen(filename,"r")) == NULL) |
|
|
420 | return; |
|
|
421 | while(fgets(buf,MAX_BUF,fp)!=NULL) |
|
|
422 | fputs(buf,fpout); |
|
|
423 | fclose(fp); |
|
|
424 | } |
|
|
425 | |
|
|
426 | |
377 | |
427 | void check_login(object *op) { |
378 | void check_login(object *op) { |
428 | FILE *fp; |
379 | FILE *fp; |
429 | char filename[MAX_BUF]; |
380 | char filename[MAX_BUF]; |
430 | char buf[MAX_BUF],bufall[MAX_BUF]; |
381 | char buf[MAX_BUF],bufall[MAX_BUF]; |
… | |
… | |
435 | time_t elapsed_save_time=0; |
386 | time_t elapsed_save_time=0; |
436 | struct stat statbuf; |
387 | struct stat statbuf; |
437 | |
388 | |
438 | strcpy (pl->maplevel,first_map_path); |
389 | strcpy (pl->maplevel,first_map_path); |
439 | |
390 | |
440 | /* First, lets check for newest form of save */ |
|
|
441 | sprintf(filename,"%s/%s/%s/%s.pl",settings.localdir,settings.playerdir,op->name,op->name); |
391 | sprintf(filename,"%s/%s/%s/%s.pl",settings.localdir,settings.playerdir,op->name,op->name); |
442 | if (access(filename, F_OK)==-1) { |
|
|
443 | /* not there, Try the old style */ |
|
|
444 | |
|
|
445 | sprintf(filename,"%s/%s/%s.pl",settings.localdir,settings.playerdir,op->name); |
|
|
446 | /* Ok - old style exists. Lets make the new style directory */ |
|
|
447 | if (access(filename, F_OK)==0) { |
|
|
448 | sprintf(buf,"%s/%s/%s",settings.localdir,settings.playerdir,op->name); |
|
|
449 | make_path_to_file(buf); |
|
|
450 | } |
|
|
451 | } |
|
|
452 | |
392 | |
453 | /* If no file, must be a new player, so lets get confirmation of |
393 | /* If no file, must be a new player, so lets get confirmation of |
454 | * the password. Return control to the higher level dispatch, |
394 | * the password. Return control to the higher level dispatch, |
455 | * since the rest of this just deals with loading of the file. |
395 | * since the rest of this just deals with loading of the file. |
456 | */ |
396 | */ |
… | |
… | |
467 | LOG(llevError,"Player file %s was saved in the future? (%d time)\n", filename, elapsed_save_time); |
407 | LOG(llevError,"Player file %s was saved in the future? (%d time)\n", filename, elapsed_save_time); |
468 | elapsed_save_time=0; |
408 | elapsed_save_time=0; |
469 | } |
409 | } |
470 | } |
410 | } |
471 | |
411 | |
472 | object_thawer thawer (filename); |
412 | object_thawer thawer (fp, filename); |
473 | |
413 | |
474 | if(fgets(bufall,MAX_BUF,fp) != NULL) { |
414 | if(fgets(bufall,MAX_BUF,fp) != NULL) { |
475 | if(!strncmp(bufall,"checksum ",9)) { |
415 | if(!strncmp(bufall,"checksum ",9)) { |
476 | checksum = strtol(bufall+9,(char **) NULL, 16); |
416 | checksum = strtol(bufall+9,(char **) NULL, 16); |
477 | (void) fgets(bufall,MAX_BUF,fp); |
417 | (void) fgets(bufall,MAX_BUF,fp); |
… | |
… | |
639 | reset_object(op); |
579 | reset_object(op); |
640 | op->contr = pl; |
580 | op->contr = pl; |
641 | pl->ob = op; |
581 | pl->ob = op; |
642 | |
582 | |
643 | /* this loads the standard objects values. */ |
583 | /* this loads the standard objects values. */ |
644 | load_object(fp, thawer, op, LO_NEWFILE,0); |
584 | load_object(thawer, op, LO_NEWFILE,0); |
645 | close_and_delete(fp, comp); |
585 | close_and_delete(fp, comp); |
646 | |
586 | |
647 | CLEAR_FLAG(op, FLAG_NO_FIX_PLAYER); |
587 | CLEAR_FLAG(op, FLAG_NO_FIX_PLAYER); |
648 | |
588 | |
649 | strncpy(pl->title, op->arch->clone.name, sizeof(pl->title)-1); |
589 | strncpy(pl->title, op->arch->clone.name, sizeof(pl->title)-1); |