1 | /* |
1 | /* |
2 | * static char *rcsid_login_c = |
2 | * static char *rcsid_login_c = |
3 | * "$Id: login.C,v 1.7 2006/08/30 06:06:27 root Exp $"; |
3 | * "$Id: login.C,v 1.11 2006/09/03 22:45:57 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 | |
… | |
… | |
93 | void delete_character(const char *name, int newchar) { |
93 | void delete_character(const char *name, int newchar) { |
94 | char buf[MAX_BUF]; |
94 | char buf[MAX_BUF]; |
95 | |
95 | |
96 | sprintf(buf,"%s/%s/%s.pl",settings.localdir,settings.playerdir,name); |
96 | sprintf(buf,"%s/%s/%s.pl",settings.localdir,settings.playerdir,name); |
97 | if(unlink(buf)== -1) |
97 | if(unlink(buf)== -1) |
98 | LOG(llevDebug, "Cannot delete character file %s: %s\n", buf, strerror_local(errno)); |
98 | LOG(llevDebug, "Cannot delete character file %s: %s\n", buf, strerror(errno)); |
99 | if (newchar) { |
99 | if (newchar) { |
100 | sprintf(buf,"%s/%s/%s",settings.localdir,settings.playerdir,name); |
100 | sprintf(buf,"%s/%s/%s",settings.localdir,settings.playerdir,name); |
101 | /* this effectively does an rm -rf on the directory */ |
101 | /* this effectively does an rm -rf on the directory */ |
102 | remove_directory(buf); |
102 | remove_directory(buf); |
103 | } |
103 | } |
… | |
… | |
196 | } else { |
196 | } else { |
197 | stat(savedir, buf); |
197 | stat(savedir, buf); |
198 | if (!S_ISDIR(buf->st_mode)) |
198 | if (!S_ISDIR(buf->st_mode)) |
199 | if (mkdir(savedir, SAVE_DIR_MODE)) |
199 | if (mkdir(savedir, SAVE_DIR_MODE)) |
200 | { |
200 | { |
201 | LOG(llevError, "Unable to create player savedir %s: %s\n", savedir, strerror_local(errno)); |
201 | LOG(llevError, "Unable to create player savedir %s: %s\n", savedir, strerror(errno)); |
202 | return 0; |
202 | return 0; |
203 | } |
203 | } |
204 | free(buf); |
204 | free(buf); |
205 | } |
205 | } |
206 | return 1; |
206 | return 1; |
… | |
… | |
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 | char filename[MAX_BUF]; |
|
|
229 | object *tmp, *container=NULL; |
228 | object *tmp, *container=NULL; |
230 | player *pl = op->contr; |
229 | player *pl = op->contr; |
231 | int i,wiz=QUERY_FLAG(op,FLAG_WIZ); |
230 | int i,wiz=QUERY_FLAG(op,FLAG_WIZ); |
232 | long checksum; |
231 | long checksum; |
233 | #ifdef BACKUP_SAVE_AT_HOME |
232 | #ifdef BACKUP_SAVE_AT_HOME |
… | |
… | |
253 | * mostly exited. |
252 | * mostly exited. |
254 | */ |
253 | */ |
255 | if (pl->state != ST_PLAYING && pl->state != ST_GET_PARTY_PASSWORD) |
254 | if (pl->state != ST_PLAYING && pl->state != ST_GET_PARTY_PASSWORD) |
256 | return 0; |
255 | return 0; |
257 | |
256 | |
258 | INVOKE_PLAYER (SAVE, op->contr, ARG_STRING (filename)); |
257 | INVOKE_PLAYER (SAVE, op->contr); |
259 | |
258 | |
260 | if (flag == 0) |
259 | if (flag == 0) |
261 | terminate_all_pets(op); |
260 | terminate_all_pets(op); |
262 | |
261 | |
263 | sprintf(filename,"%s/%s/%s/%s.pl",settings.localdir,settings.playerdir,op->name,op->name); |
|
|
264 | make_path_to_file(filename); |
|
|
265 | |
|
|
266 | object_freezer fp (filename); |
262 | object_freezer freezer; |
267 | |
263 | |
268 | if (!fp) |
264 | /* Eneq(@csd.uu.se): If we have an open container hide it. */ |
|
|
265 | if (op->container) |
269 | { |
266 | { |
270 | new_draw_info(NDI_UNIQUE, 0,op, "Can't open file for save."); |
|
|
271 | return 0; |
|
|
272 | } |
|
|
273 | |
|
|
274 | /* Eneq(@csd.uu.se): If we have an open container hide it. */ |
|
|
275 | if (op->container) |
|
|
276 | { |
|
|
277 | container = op->container; |
267 | container = op->container; |
278 | op->container = NULL; |
268 | op->container = NULL; |
279 | } |
269 | } |
280 | |
270 | |
281 | fprintf(fp,"password %s\n",pl->password); |
271 | fprintf(freezer,"password %s\n",pl->password); |
282 | |
272 | |
283 | if (settings.set_title == TRUE) |
273 | if (settings.set_title == TRUE) |
284 | if(pl->own_title[0]!='\0') |
274 | if(pl->own_title[0]!='\0') |
285 | fprintf(fp,"title %s\n",pl->own_title); |
275 | fprintf(freezer,"title %s\n",pl->own_title); |
286 | |
276 | |
287 | fprintf(fp,"explore %d\n",pl->explore); |
277 | fprintf(freezer,"explore %d\n",pl->explore); |
288 | fprintf(fp,"gen_hp %d\n",pl->gen_hp); |
278 | fprintf(freezer,"gen_hp %d\n",pl->gen_hp); |
289 | fprintf(fp,"gen_sp %d\n",pl->gen_sp); |
279 | fprintf(freezer,"gen_sp %d\n",pl->gen_sp); |
290 | fprintf(fp,"gen_grace %d\n",pl->gen_grace); |
280 | fprintf(freezer,"gen_grace %d\n",pl->gen_grace); |
291 | fprintf(fp,"listening %d\n",pl->listening); |
281 | fprintf(freezer,"listening %d\n",pl->listening); |
292 | fprintf(fp,"shoottype %d\n",pl->shoottype); |
282 | fprintf(freezer,"shoottype %d\n",pl->shoottype); |
293 | fprintf(fp,"bowtype %d\n",pl->bowtype); |
283 | fprintf(freezer,"bowtype %d\n",pl->bowtype); |
294 | fprintf(fp,"petmode %d\n",pl->petmode); |
284 | fprintf(freezer,"petmode %d\n",pl->petmode); |
295 | fprintf(fp,"peaceful %d\n",pl->peaceful); |
285 | fprintf(freezer,"peaceful %d\n",pl->peaceful); |
296 | fprintf(fp,"no_shout %d\n",pl->no_shout); |
286 | fprintf(freezer,"no_shout %d\n",pl->no_shout); |
297 | fprintf(fp,"digestion %d\n",pl->digestion); |
287 | fprintf(freezer,"digestion %d\n",pl->digestion); |
298 | fprintf(fp,"pickup %d\n", pl->mode); |
288 | fprintf(freezer,"pickup %d\n", pl->mode); |
299 | fprintf(fp,"outputs_sync %d\n", pl->outputs_sync); |
289 | fprintf(freezer,"outputs_sync %d\n", pl->outputs_sync); |
300 | fprintf(fp,"outputs_count %d\n", pl->outputs_count); |
290 | fprintf(freezer,"outputs_count %d\n", pl->outputs_count); |
301 | /* Match the enumerations but in string form */ |
291 | /* Match the enumerations but in string form */ |
302 | fprintf(fp,"usekeys %s\n", pl->usekeys==key_inventory?"key_inventory": |
292 | fprintf(freezer,"usekeys %s\n", pl->usekeys==key_inventory?"key_inventory": |
303 | (pl->usekeys==keyrings?"keyrings":"containers")); |
293 | (pl->usekeys==keyrings?"keyrings":"containers")); |
304 | /* Match the enumerations but in string form */ |
294 | /* Match the enumerations but in string form */ |
305 | fprintf(fp,"unapply %s\n", pl->unapply==unapply_nochoice?"unapply_nochoice": |
295 | fprintf(freezer,"unapply %s\n", pl->unapply==unapply_nochoice?"unapply_nochoice": |
306 | (pl->unapply==unapply_never?"unapply_never":"unapply_always")); |
296 | (pl->unapply==unapply_never?"unapply_never":"unapply_always")); |
307 | |
297 | |
308 | #ifdef BACKUP_SAVE_AT_HOME |
298 | #ifdef BACKUP_SAVE_AT_HOME |
309 | if (op->map!=NULL && flag==0) |
299 | if (op->map!=NULL && flag==0) |
310 | #else |
300 | #else |
311 | if (op->map!=NULL) |
301 | if (op->map!=NULL) |
312 | #endif |
302 | #endif |
313 | fprintf(fp,"map %s\n",op->map->path); |
303 | fprintf(freezer,"map %s\n",op->map->path); |
314 | else |
304 | else |
315 | fprintf(fp,"map %s\n",settings.emergency_mapname); |
305 | fprintf(freezer,"map %s\n",settings.emergency_mapname); |
316 | |
306 | |
317 | fprintf(fp,"savebed_map %s\n", pl->savebed_map); |
307 | fprintf(freezer,"savebed_map %s\n", pl->savebed_map); |
318 | fprintf(fp,"bed_x %d\nbed_y %d\n", pl->bed_x, pl->bed_y); |
308 | fprintf(freezer,"bed_x %d\nbed_y %d\n", pl->bed_x, pl->bed_y); |
319 | fprintf(fp,"weapon_sp %f\n",pl->weapon_sp); |
309 | fprintf(freezer,"weapon_sp %f\n",pl->weapon_sp); |
320 | fprintf(fp,"Str %d\n",pl->orig_stats.Str); |
310 | fprintf(freezer,"Str %d\n",pl->orig_stats.Str); |
321 | fprintf(fp,"Dex %d\n",pl->orig_stats.Dex); |
311 | fprintf(freezer,"Dex %d\n",pl->orig_stats.Dex); |
322 | fprintf(fp,"Con %d\n",pl->orig_stats.Con); |
312 | fprintf(freezer,"Con %d\n",pl->orig_stats.Con); |
323 | fprintf(fp,"Int %d\n",pl->orig_stats.Int); |
313 | fprintf(freezer,"Int %d\n",pl->orig_stats.Int); |
324 | fprintf(fp,"Pow %d\n",pl->orig_stats.Pow); |
314 | fprintf(freezer,"Pow %d\n",pl->orig_stats.Pow); |
325 | fprintf(fp,"Wis %d\n",pl->orig_stats.Wis); |
315 | fprintf(freezer,"Wis %d\n",pl->orig_stats.Wis); |
326 | fprintf(fp,"Cha %d\n",pl->orig_stats.Cha); |
316 | fprintf(freezer,"Cha %d\n",pl->orig_stats.Cha); |
327 | |
317 | |
328 | fprintf(fp,"lev_array %d\n",op->level>10?10:op->level); |
318 | fprintf(freezer,"lev_array %d\n",op->level>10?10:op->level); |
329 | for(i=1;i<=pl->last_level&&i<=10;i++) { |
319 | for(i=1;i<=pl->last_level&&i<=10;i++) { |
330 | fprintf(fp,"%d\n",pl->levhp[i]); |
320 | fprintf(freezer,"%d\n",pl->levhp[i]); |
331 | fprintf(fp,"%d\n",pl->levsp[i]); |
321 | fprintf(freezer,"%d\n",pl->levsp[i]); |
332 | fprintf(fp,"%d\n",pl->levgrace[i]); |
322 | fprintf(freezer,"%d\n",pl->levgrace[i]); |
333 | } |
323 | } |
334 | |
324 | |
335 | fp.put (op->contr); |
325 | freezer.put (op->contr); |
336 | |
326 | |
337 | fprintf(fp,"endplst\n"); |
327 | fprintf(freezer,"endplst\n"); |
338 | |
328 | |
339 | SET_FLAG(op, FLAG_NO_FIX_PLAYER); |
329 | SET_FLAG(op, FLAG_NO_FIX_PLAYER); |
340 | CLEAR_FLAG(op, FLAG_WIZ); |
330 | CLEAR_FLAG(op, FLAG_WIZ); |
341 | #ifdef BACKUP_SAVE_AT_HOME |
331 | #ifdef BACKUP_SAVE_AT_HOME |
342 | if (flag) { |
332 | if (flag) { |
… | |
… | |
346 | op->y = -1; |
336 | op->y = -1; |
347 | } |
337 | } |
348 | /* Save objects, but not unpaid objects. Don't remove objects from |
338 | /* Save objects, but not unpaid objects. Don't remove objects from |
349 | * inventory. |
339 | * inventory. |
350 | */ |
340 | */ |
351 | save_object(fp, op, 2); |
341 | save_object(freezer, op, 2); |
352 | if (flag) { |
342 | if (flag) { |
353 | op->x = backup_x; |
343 | op->x = backup_x; |
354 | op->y = backup_y; |
344 | op->y = backup_y; |
355 | } |
345 | } |
356 | #else |
346 | #else |
357 | save_object(fp, op, 3); /* don't check and don't remove */ |
347 | save_object(freezer, op, 3); /* don't check and don't remove */ |
358 | #endif |
348 | #endif |
|
|
349 | |
|
|
350 | char filename[MAX_BUF]; |
|
|
351 | sprintf(filename,"%s/%s/%s/%s.pl",settings.localdir,settings.playerdir,&op->name,&op->name); |
|
|
352 | make_path_to_file(filename); |
|
|
353 | freezer.save (filename); |
359 | |
354 | |
360 | CLEAR_FLAG(op, FLAG_NO_FIX_PLAYER); |
355 | CLEAR_FLAG(op, FLAG_NO_FIX_PLAYER); |
361 | |
356 | |
362 | if(!flag) |
357 | if(!flag) |
363 | while ((tmp = op->inv)) |
358 | while ((tmp = op->inv)) |
364 | destroy_object (tmp); |
359 | destroy_object (tmp); |
365 | |
360 | |
366 | /* Eneq(@csd.uu.se): Reveal the container if we have one. */ |
361 | /* Eneq(@csd.uu.se): Reveal the container if we have one. */ |
367 | if (flag&&container!=NULL) |
362 | if (flag && container!=NULL) |
368 | op->container = container; |
363 | op->container = container; |
369 | |
364 | |
370 | if (wiz) SET_FLAG(op,FLAG_WIZ); |
365 | if (wiz) SET_FLAG (op, FLAG_WIZ); |
371 | |
366 | |
372 | if(!flag) |
367 | if(!flag) |
373 | esrv_send_inventory(op, op); |
368 | esrv_send_inventory(op, op); |
374 | |
369 | |
375 | return 1; |
370 | return 1; |
… | |
… | |
382 | long checksum = 0; |
377 | long checksum = 0; |
383 | player *pl = op->contr; |
378 | player *pl = op->contr; |
384 | int correct = 0; |
379 | int correct = 0; |
385 | |
380 | |
386 | strcpy (pl->maplevel,first_map_path); |
381 | strcpy (pl->maplevel,first_map_path); |
387 | sprintf(filename,"%s/%s/%s/%s.pl",settings.localdir,settings.playerdir,op->name,op->name); |
382 | sprintf(filename,"%s/%s/%s/%s.pl",settings.localdir,settings.playerdir,&op->name,&op->name); |
388 | |
383 | |
389 | object_thawer thawer (filename); |
384 | object_thawer thawer (filename); |
390 | /* If no file, must be a new player, so lets get confirmation of |
385 | /* If no file, must be a new player, so lets get confirmation of |
391 | * the password. Return control to the higher level dispatch, |
386 | * the password. Return control to the higher level dispatch, |
392 | * since the rest of this just deals with loading of the file. |
387 | * since the rest of this just deals with loading of the file. |
… | |
… | |
412 | } |
407 | } |
413 | if (!correct) { |
408 | if (!correct) { |
414 | new_draw_info(NDI_UNIQUE, 0,op," "); |
409 | new_draw_info(NDI_UNIQUE, 0,op," "); |
415 | new_draw_info(NDI_UNIQUE, 0,op,"Wrong Password!"); |
410 | new_draw_info(NDI_UNIQUE, 0,op,"Wrong Password!"); |
416 | new_draw_info(NDI_UNIQUE, 0,op," "); |
411 | new_draw_info(NDI_UNIQUE, 0,op," "); |
417 | FREE_AND_COPY(op->name, "noname"); |
412 | op->name = |
418 | FREE_AND_COPY(op->name_pl, "noname"); |
413 | op->name_pl = "noname"; |
419 | op->contr->socket.password_fails++; |
414 | op->contr->socket.password_fails++; |
420 | if (op->contr->socket.password_fails >= MAX_PASSWORD_FAILURES) { |
415 | if (op->contr->socket.password_fails >= MAX_PASSWORD_FAILURES) { |
421 | new_draw_info(NDI_UNIQUE, 0,op, |
416 | new_draw_info(NDI_UNIQUE, 0,op, |
422 | "You gave an incorrect password too many times, you will now be dropped from the server."); |
417 | "You gave an incorrect password too many times, you will now be dropped from the server."); |
423 | LOG(llevInfo, "A player connecting from %s has been dropped for password failure\n", |
418 | LOG(llevInfo, "A player connecting from %s has been dropped for password failure\n", |
… | |
… | |
524 | else if (!strcmp(bufall+8,"unapply_always\n")) |
519 | else if (!strcmp(bufall+8,"unapply_always\n")) |
525 | pl->unapply=unapply_always; |
520 | pl->unapply=unapply_always; |
526 | else LOG(llevDebug,"load_player: got unknown unapply type: %s\n", bufall+8); |
521 | else LOG(llevDebug,"load_player: got unknown unapply type: %s\n", bufall+8); |
527 | } |
522 | } |
528 | else if (!strcmp(buf,"lev_array")){ |
523 | else if (!strcmp(buf,"lev_array")){ |
529 | for(i=1;i<=value;i++) { |
524 | for(i=1;i<=value;i++) |
530 | int j; |
525 | { |
531 | fscanf(thawer,"%d\n",&j); |
526 | char line[128]; |
532 | pl->levhp[i]=j; |
527 | fgets (line, 128, thawer); pl->levhp[i] = atoi (line); |
533 | fscanf(thawer,"%d\n",&j); |
528 | fgets (line, 128, thawer); pl->levsp[i] = atoi (line); |
534 | pl->levsp[i]=j; |
529 | fgets (line, 128, thawer); pl->levgrace[i] = atoi (line); |
535 | fscanf(thawer,"%d\n",&j); |
|
|
536 | pl->levgrace[i]=j; |
|
|
537 | } |
530 | } |
538 | /* spell_array code removed - don't know when that was last used. |
531 | /* spell_array code removed - don't know when that was last used. |
539 | * Even the load code below will someday be replaced by spells being |
532 | * Even the load code below will someday be replaced by spells being |
540 | * objects. |
533 | * objects. |
541 | */ |
534 | */ |
542 | } else if (!strcmp(buf,"known_spell")) { |
535 | } else if (!strcmp(buf,"known_spell")) { |
… | |
… | |
564 | reset_object(op); |
557 | reset_object(op); |
565 | op->contr = pl; |
558 | op->contr = pl; |
566 | pl->ob = op; |
559 | pl->ob = op; |
567 | |
560 | |
568 | /* this loads the standard objects values. */ |
561 | /* this loads the standard objects values. */ |
569 | load_object(thawer, op, LO_NEWFILE,0); |
562 | load_object (thawer, op, 0); |
570 | |
563 | |
571 | CLEAR_FLAG(op, FLAG_NO_FIX_PLAYER); |
564 | CLEAR_FLAG(op, FLAG_NO_FIX_PLAYER); |
572 | |
565 | |
573 | strncpy(pl->title, op->arch->clone.name, sizeof(pl->title)-1); |
566 | strncpy(pl->title, op->arch->clone.name, sizeof(pl->title)-1); |
574 | pl->title[sizeof(pl->title)-1] = '\0'; |
567 | pl->title[sizeof(pl->title)-1] = '\0'; |
… | |
… | |
624 | set_dragon_name(op, abil, skin); |
617 | set_dragon_name(op, abil, skin); |
625 | } |
618 | } |
626 | |
619 | |
627 | new_draw_info(NDI_UNIQUE, 0,op,"Welcome Back!"); |
620 | new_draw_info(NDI_UNIQUE, 0,op,"Welcome Back!"); |
628 | new_draw_info_format(NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, NULL, |
621 | new_draw_info_format(NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, 5, NULL, |
629 | "%s has entered the game.",pl->ob->name); |
622 | "%s has entered the game.", &pl->ob->name); |
630 | |
623 | |
631 | INVOKE_PLAYER (LOAD, pl, ARG_STRING (filename)); |
624 | INVOKE_PLAYER (LOAD, pl, ARG_STRING (filename)); |
632 | INVOKE_PLAYER (LOGIN, pl); |
625 | INVOKE_PLAYER (LOGIN, pl); |
633 | |
626 | |
634 | op->contr->socket.update_look=1; |
627 | op->contr->socket.update_look=1; |
… | |
… | |
641 | if (op->stats.hp<0) { |
634 | if (op->stats.hp<0) { |
642 | new_draw_info(NDI_UNIQUE, 0,op,"Your character was dead last your played."); |
635 | new_draw_info(NDI_UNIQUE, 0,op,"Your character was dead last your played."); |
643 | kill_player(op); |
636 | kill_player(op); |
644 | if (pl->state != ST_PLAYING) return; |
637 | if (pl->state != ST_PLAYING) return; |
645 | } |
638 | } |
646 | LOG(llevInfo,"LOGIN: Player named %s from ip %s\n", op->name, |
639 | LOG(llevInfo,"LOGIN: Player named %s from ip %s\n", &op->name, op->contr->socket.host); |
647 | op->contr->socket.host); |
|
|
648 | |
640 | |
649 | /* Do this after checking for death - no reason sucking up bandwidth if |
641 | /* Do this after checking for death - no reason sucking up bandwidth if |
650 | * the data isn't needed. |
642 | * the data isn't needed. |
651 | */ |
643 | */ |
652 | esrv_new_player(op->contr,op->weight+op->carrying); |
644 | esrv_new_player(op->contr,op->weight+op->carrying); |