/***************************************************************************** * DikuMUD (C) 1990, 1991 by: * * Sebastian Hammer, Michael Seifert, Hans Henrik Staefeldt, Tom Madsen, * * and Katja Nyboe. * *---------------------------------------------------------------------------* * MERC 2.1 (C) 1992, 1993 by: * * Michael Chastain, Michael Quan, and Mitchell Tse. * *---------------------------------------------------------------------------* * SMAUG 1.4 (C) 1994, 1995, 1996, 1998 by: Derek Snider. * * Team: Thoric, Altrag, Blodkai, Narn, Haus, Scryn, Rennard, Swordbearer, * * gorog, Grishnakh, Nivek, Tricops, and Fireblade. * *---------------------------------------------------------------------------* * SMAUG 1.7 FUSS by: Samson and others of the SMAUG community. * * Their contributions are greatly appreciated. * *---------------------------------------------------------------------------* * LoP (C) 2006, 2007, 2008, 2009 by: the LoP team. * *****************************************************************************/ #include <ctype.h> #include <string.h> #include <stdio.h> #include "h/mud.h" #define LOCKER_FILE SYSTEM_DIR "lockers.dat" typedef struct lshare_data LSHARE_DATA; struct lshare_data { LSHARE_DATA *next, *prev; char *name; }; typedef struct lockershare_data LOCKERSHARE_DATA; struct lockershare_data { LOCKERSHARE_DATA *next, *prev; LSHARE_DATA *first_lshare, *last_lshare; char *locker; }; LOCKERSHARE_DATA *first_locker, *last_locker; void free_lshare( LSHARE_DATA *lshare ) { if( !lshare ) return; STRFREE( lshare->name ); DISPOSE( lshare ); } void free_all_lshare( LOCKERSHARE_DATA *locker ) { LSHARE_DATA *lshare, *lshare_next; if( !locker ) return; for( lshare = locker->first_lshare; lshare; lshare = lshare_next ) { lshare_next = lshare->next; UNLINK( lshare, locker->first_lshare, locker->last_lshare, next, prev ); free_lshare( lshare ); } } void free_lockershare( LOCKERSHARE_DATA *locker ) { if( !locker ) return; STRFREE( locker->locker ); free_all_lshare( locker ); DISPOSE( locker ); } void free_all_lockershare( void ) { LOCKERSHARE_DATA *locker, *locker_next; for( locker = first_locker; locker; locker = locker_next ) { locker_next = locker->next; UNLINK( locker, first_locker, last_locker, next, prev ); free_lockershare( locker ); } } void save_lockers( void ) { LOCKERSHARE_DATA *locker; LSHARE_DATA *lshare; FILE *fp; if( !first_locker ) { remove( LOCKER_FILE ); return; } if( !( fp = fopen( LOCKER_FILE, "w" ) ) ) { bug( "%s: Can't open %s for writing.", __FUNCTION__, LOCKER_FILE ); perror( LOCKER_FILE ); return; } for( locker = first_locker; locker; locker = locker->next ) { fprintf( fp, "%s", "#LOCKER\n" ); fprintf( fp, "Name %s~\n", locker->locker ); for( lshare = locker->first_lshare; lshare; lshare = lshare->next ) if( lshare->name ) fprintf( fp, "Shared %s~\n", lshare->name ); fprintf( fp, "%s", "End\n\n" ); } fprintf( fp, "%s", "#END\n" ); fclose( fp ); fp = NULL; } LOCKERSHARE_DATA *new_lockershare( void ) { LOCKERSHARE_DATA *locker = NULL; CREATE( locker, LOCKERSHARE_DATA, 1 ); if( !locker ) { bug( "%s: locker is NULL after CREATE.", __FUNCTION__ ); return NULL; } locker->locker = NULL; locker->first_lshare = locker->last_lshare = NULL; return locker; } void fread_locker( FILE *fp ) { LOCKERSHARE_DATA *locker; const char *word; bool fMatch; locker = new_lockershare( ); for( ;; ) { word = feof( fp ) ? "End" : fread_word( fp ); fMatch = false; switch( UPPER( word[0] ) ) { case '*': fMatch = true; fread_to_eol( fp ); break; case 'E': if( !str_cmp( word, "End" ) ) { LINK( locker, first_locker, last_locker, next, prev ); return; } break; case 'N': KEY( "Name", locker->locker, fread_string( fp ) ); break; case 'S': if( !str_cmp( word, "Shared" ) ) { LSHARE_DATA *shared; char *tmpstr = fread_flagstring( fp ); CREATE( shared, LSHARE_DATA, 1 ); shared->name = STRALLOC( tmpstr ); LINK( shared, locker->first_lshare, locker->last_lshare, next, prev ); fMatch = true; break; } break; } if( !fMatch ) { bug( "%s: no match: %s", __FUNCTION__, word ); fread_to_eol( fp ); } } free_lockershare( locker ); } /* Check all lockers and make sure everything is valid if not update and save */ void check_lockers( void ) { LOCKERSHARE_DATA *locker, *locker_next; LSHARE_DATA *lshare, *lshare_next; bool changed = false; for( locker = first_locker; locker; locker = locker_next ) { locker_next = locker->next; /* First toss through the lshare data and free any that no longer exist */ for( lshare = locker->first_lshare; lshare; lshare = lshare_next ) { lshare_next = lshare->next; if( !valid_pfile( lshare->name ) ) { UNLINK( lshare, locker->first_lshare, locker->last_lshare, next, prev ); free_lshare( lshare ); changed = true; } } /* Now if not being shared anymore remove it all from the list */ if( !locker->first_lshare ) { UNLINK( locker, first_locker, last_locker, next, prev ); free_lockershare( locker ); changed = true; } } if( changed ) save_lockers( ); } void load_lockershares( void ) { FILE *fp; first_locker = last_locker = NULL; if( !( fp = fopen( LOCKER_FILE, "r" ) ) ) return; for( ;; ) { char letter; char *word; letter = fread_letter( fp ); if( letter == '*' ) { fread_to_eol( fp ); continue; } if( letter != '#' ) { bug( "%s: # not found.", __FUNCTION__ ); break; } word = fread_word( fp ); if( !str_cmp( word, "LOCKER" ) ) { fread_locker( fp ); continue; } else if( !str_cmp( word, "END" ) ) break; else { bug( "%s: bad section (%s).", __FUNCTION__, word ); fread_to_eol( fp ); continue; } } fclose( fp ); fp = NULL; check_lockers( ); } /* Check to see if a locker is shared */ bool is_locker_shared( char *name ) { LOCKERSHARE_DATA *locker; if( !name || name[0] == '\0' ) return false; for( locker = first_locker; locker; locker = locker->next ) { if( !str_cmp( locker->locker, name ) ) return true; } return false; } LOCKERSHARE_DATA *find_locker( char *name ) { LOCKERSHARE_DATA *locker; if( !name || name[0] == '\0' ) return NULL; for( locker = first_locker; locker; locker = locker->next ) { if( !str_cmp( locker->locker, name ) ) return locker; } return NULL; } void rename_lockershare( char *name, char *newname ) { LOCKERSHARE_DATA *locker; if( !name || !newname || name[0] == '\0' || newname[0] == '\0' ) return; if( !( locker = find_locker( name ) ) ) return; STRSET( locker->locker, newname ); /* Set it to the newname */ save_lockers( ); } /* Can the ch access the locker? */ bool can_use_locker( CHAR_DATA *ch, char *name ) { LOCKERSHARE_DATA *locker; LSHARE_DATA *lshare; if( !ch || !name || name[0] == '\0' || is_npc( ch ) ) return false; if( is_immortal( ch ) ) /* Immortals can access all lockers, only use for checking etc... */ return true; if( !str_cmp( ch->name, name ) ) /* Allow them to access their own lockers */ return true; if( !( locker = find_locker( name ) ) ) /* Not shared so can't access it */ return false; for( lshare = locker->first_lshare; lshare; lshare = lshare->next ) { if( !str_cmp( lshare->name, ch->name ) ) /* Is shared with them so allow them access */ return true; } return false; /* Shared but not with them */ } void fwrite_locker( CHAR_DATA *ch, OBJ_DATA *locker, char *uname ) { FILE *fp = NULL; char lockerfile[MIL], *name; if( !ch || is_npc( ch ) ) return; if( !locker ) { bug( "%s: NULL object. for character %s", __FUNCTION__, ch->name); send_to_char( "There was a problem trying to write the locker file!\r\n", ch ); return; } name = capitalize( uname ); snprintf( lockerfile, sizeof( lockerfile ), "%s%s", LOCKER_DIR, uname ); if( !( fp = fopen( lockerfile, "w" ) ) ) { bug( "%s: Couldn't open %s for write", __FUNCTION__, lockerfile ); send_to_char( "There was some problem in writing your locker file!\r\n", ch ); return; } fwrite_obj( ch, locker, fp, 0, OS_LOCKER, false ); fprintf( fp, "%s", "#END\n" ); fclose( fp ); } CMDF( do_locker ) { OBJ_DATA *locker, *locker_next; OBJ_INDEX_DATA *ilocker; LOCKERSHARE_DATA *slocker = NULL; LSHARE_DATA *lshare; FILE *fp = NULL; char buf[MIL], arg[MIL], *name = NULL; bool nlocker = false; if( !ch || is_npc( ch ) ) return; argument = one_argument( argument, arg ); /* Allow it to be shared */ if( arg != NULL && arg[0] != '\0' && !str_cmp( arg, "share" ) ) { char tmparg[MIL]; one_argument( argument, tmparg ); /* Lets see if maybe there is someone named share lol and if it should go on if so let it */ /* If no arg or arg isn't put, get or list */ if( tmparg == NULL || tmparg[0] == '\0' || ( str_cmp( tmparg, "put" ) && str_cmp( tmparg, "get" ) && str_cmp( tmparg, "list" ) ) ) { /* Show shared list */ if( tmparg == NULL || tmparg[0] == '\0' ) { if( !( slocker = find_locker( ch->name ) ) ) { send_to_char( "You aren't currently sharing your locker with anyone.\r\n", ch ); return; } send_to_char( "You are currently sharing your locker with:\r\n", ch ); for( lshare = slocker->first_lshare; lshare; lshare = lshare->next ) ch_printf( ch, "%s\r\n", lshare->name ); return; } /* No slocker so create one */ if( !( slocker = find_locker( ch->name ) ) ) { slocker = new_lockershare( ); slocker->locker = STRALLOC( ch->name ); nlocker = true; } /* Check to see if it is already in the list */ for( lshare = slocker->first_lshare; lshare; lshare = lshare->next ) { if( !str_cmp( lshare->name, tmparg ) ) { UNLINK( lshare, slocker->first_lshare, slocker->last_lshare, next, prev ); free_lshare( lshare ); if( !slocker->first_lshare ) /* If no more on shared list remove them all */ { UNLINK( slocker, first_locker, last_locker, next, prev ); free_lockershare( slocker ); } ch_printf( ch, "Removed %s from your locker share list.\r\n", tmparg ); return; } } if( !valid_pfile( tmparg ) ) { send_to_char( "You can't share your locker with them currently.\r\n", ch ); if( nlocker ) /* New lockers don't have any yet so free them up */ free_lockershare( slocker ); return; } if( !str_cmp( ch->name, tmparg ) ) { send_to_char( "You already have access to your locker.\r\n", ch ); if( nlocker ) /* New lockers don't have any yet so free them up */ free_lockershare( slocker ); return; } /* Ok so not on the list yet so lets add it */ CREATE( lshare, LSHARE_DATA, 1 ); lshare->name = STRALLOC( capitalize( tmparg ) ); lshare->next = NULL; lshare->prev = NULL; LINK( lshare, slocker->first_lshare, slocker->last_lshare, next, prev ); if( nlocker ) /* Need to add new lockers to the list */ LINK( slocker, first_locker, last_locker, next, prev ); save_lockers( ); ch_printf( ch, "You are now sharing your locker with %s.\r\n", lshare->name ); return; } } /* Lets see if we are specifying what locker to open */ if( arg != NULL && arg[0] != '\0' && str_cmp( arg, "put" ) && str_cmp( arg, "get" ) && str_cmp( arg, "list" ) ) { name = capitalize( arg ); argument = one_argument( argument, arg ); if( !can_use_locker( ch, name ) ) { send_to_char( "You don't have permission to access that locker.\r\n", ch ); return; } } if( arg == NULL || arg[0] == '\0' || ( str_cmp( arg, "put" ) && str_cmp( arg, "get" ) && str_cmp( arg, "list" ) ) ) { send_to_char( "Usage: locker put/get all\r\nUsage: locker put/get <object name>\r\nUsage: locker list\r\n", ch ); return; } if( !xIS_SET( ch->in_room->room_flags, ROOM_LOCKER ) ) { send_to_char( "You need to be in a locker room!\r\n", ch ); return; } if( !name || name[0] == '\0' ) name = capitalize( ch->name ); snprintf( buf, sizeof( buf ), "%s%s", LOCKER_DIR, name ); if( ( fp = fopen( buf, "r" ) ) != NULL ) { for( ;; ) { char letter; char *word; letter = fread_letter( fp ); if( letter == '#' ) { word = fread_word( fp ); if( !strcmp( word, "LOCKER" ) ) fread_obj( ch, NULL, fp, OS_LOCKER ); else if( !strcmp( word, "OBJECT" ) ) fread_obj( ch, NULL, fp, OS_CARRY ); else if( !strcmp( word, "END" ) ) break; else { bug( "%s: bad section.", __FUNCTION__ ); break; } } } fclose( fp ); fp = NULL; } else { if( !( ilocker = get_obj_index( OBJ_VNUM_LOCKER ) ) ) { send_to_char( "There is no locker to use currently.\r\n", ch ); bug( "%s: Can't find the index locker! Vnum %d.", __FUNCTION__, OBJ_VNUM_LOCKER ); return; } if( !( locker = create_object( ilocker, 0 ) ) ) { send_to_char( "There is no locker to use currently.\r\n", ch ); bug( "%s: Failed to create a locker! Vnum %d.", __FUNCTION__, OBJ_VNUM_LOCKER ); return; } snprintf( buf, sizeof( buf ), locker->name, name ); STRSET( locker->name, buf ); snprintf( buf, sizeof( buf ), locker->short_descr, name ); STRSET( locker->short_descr, buf ); snprintf( buf, sizeof( buf ), locker->description, name ); STRSET( locker->description, buf ); obj_to_room( locker, ch->in_room ); } if( !str_cmp( arg, "put" ) ) { snprintf( buf, sizeof( buf ), "put %s %s", argument, name ); interpret( ch, buf ); } else if( !str_cmp( arg, "get" ) ) { snprintf( buf, sizeof( buf ), "get %s %s", argument, name ); interpret( ch, buf ); } else if( !str_cmp( arg, "list" ) ) { snprintf( buf, sizeof( buf ), "look in %s", name ); interpret( ch, buf ); } for( locker = ch->in_room->first_content; locker; locker = locker_next ) { locker_next = locker->next_content; if( locker->pIndexData->vnum != OBJ_VNUM_LOCKER ) continue; if( locker->first_content ) fwrite_locker( ch, locker, locker->name ); else { snprintf( buf, sizeof( buf ), "%s%s", LOCKER_DIR, locker->name ); remove_file( buf ); } extract_obj( locker ); } } void rename_locker( CHAR_DATA *ch, char *newname ) { OBJ_DATA *locker; FILE *fp; char name[MSL], uname[MSL], buf[MSL]; snprintf( name, sizeof( name ), "%s", capitalize( ch->name ) ); snprintf( uname, sizeof( uname ), "%s", capitalize( newname ) ); snprintf( buf, sizeof( buf ), "%s%s", LOCKER_DIR, name ); if( ( fp = fopen( buf, "r" ) ) != NULL ) { for( ;; ) { char letter; char *word; letter = fread_letter( fp ); if( letter == '#' ) { word = fread_word( fp ); if( !strcmp( word, "END" ) ) break; if( !strcmp( word, "OBJECT" ) ) fread_obj( ch, NULL, fp, OS_LOCKER ); } } fclose( fp ); } for( locker = ch->in_room->first_content; locker; locker = locker->next_content ) if( locker->pIndexData->vnum == OBJ_VNUM_LOCKER && !str_cmp( locker->name, ch->name ) ) break; if( locker ) { if( locker->first_content ) { snprintf( buf, sizeof( buf ), locker->pIndexData->name, uname ); STRSET( locker->name, buf ); snprintf( buf, sizeof( buf ), locker->pIndexData->short_descr, uname ); STRSET( locker->short_descr, buf ); snprintf( buf, sizeof( buf ), locker->pIndexData->description, uname ); STRSET( locker->description, buf ); fwrite_locker( ch, locker, uname ); } else { snprintf( buf, sizeof( buf ), "%s%s", LOCKER_DIR, name ); remove_file( buf ); } extract_obj( locker ); } }