//(Thought I was actually going to make a patch file? I don't have that kind of time ;) //Newbie coders: I may be vague in my location specifications some times, so tough it out. //And do note I start from the top of MY files and go down. First off, place the secedit.c file in your src directory. Then dump the secgroup.dat into your data folder. << In olc.h: >> Find the other #define ED_XXX's and add: #define ED_SECURITY 15 Replace 15 with whatever # is next in line in your code. Under 'Interpreter Prototypes' put: void secedit args( ( CHAR_DATA *ch, char *argument ) ); Now with all the other XXX_olc_comm_tables, put this: extern const struct olc_comm_type security_olc_comm_table []; Under 'Editor Commands' put: DECLARE_DO_FUN( do_secedit ); Now, down with the 'Editor prototypes' add this: /* * Security Editor */ DECLARE_OLC_FUN( secedit_list ); DECLARE_OLC_FUN( secedit_show ); DECLARE_OLC_FUN( secedit_name ); DECLARE_OLC_FUN( secedit_bit ); DECLARE_OLC_FUN( secedit_cmd ); DECLARE_OLC_FUN( secedit_new ); DECLARE_OLC_FUN( secedit_delete ); Down with the Macros place this: #define EDIT_SECURITY(Ch, Sec) ( Sec = (SECURITY_DATA*)Ch->desc->pEdit ) << In olc.c >> At the top of the file, just under the: MOB_INDEX_DATA xMob; OBJ_INDEX_DATA xObj; ROOM_INDEX_DATA xRoom; etc, etc, etc, put: SECURITY_DATA xSec; In the run_olc_editor(), add this to the switch statement: case ED_SECURITY: secedit (d->character, incomm); break; In the olc_ed_name(), add this to the switch statement: case ED_SECURITY: sprintf (buf, "SecEdit"); break; In the olc_ed_vnum(), add this to the switch statement: case ED_SECURITY: pSec = (SECURITY_DATA *) ch->desc->pEdit; sprintf( buf, "%s", pSec ? pSec->name : "" ); break; In the get_olc_table(), add this to the switch statement: case ED_SECURITY: return security_olc_comm_table; In process_olc_commands(), add this in the list of variables: SECURITY_DATA *pSec; Now add this in the switch in process_olc_commands() case ED_SECURITY: EDIT_SECURITY(ch, pSec); if (table[temp].argument) puntero = (void *) ((int) table[temp].argument - (int) &xSec + (int) pSec); else puntero = NULL; if ( (*table[temp].function) (table[temp].name, ch, argument, puntero, table[temp].parameter ) ) save_security_table(); return TRUE; break; << In merc.h: >> Place this with all the other typedefs: typedef struct security_type SECURITY_DATA; Now find a place somewhere in your merc.h to place this: struct security_type { char * name; long bit; }; Now, find the pc_data struct and add this somewhere in it: long secgroups; /* KJ: For SecEdit */ << In interp.h: >> Add this to your cmd_type struct: long secgroup; << In command.h: >> Add this somewhere: COMMAND( do_secedit ) COMMAND( do_secgroup ) << In interp.c: >> In the interpret(), find this part of the code and modify it to look like this: /* * Look for command in command table. */ found = FALSE; trust = get_trust( ch ); for ( cmd = 0; cmd_table[cmd].name[0] != '\0'; cmd++ ) { if ( command[0] == cmd_table[cmd].name[0] && !str_prefix( command, cmd_table[cmd].name ) ) { if ( ( cmd_table[cmd].secgroup == 0 && cmd_table[cmd].level <= trust ) || ( ch->pcdata != NULL && IS_SET(cmd_table[cmd].secgroup, ch->pcdata->secgroups) ) ) { found = TRUE; break; } } } /* * Log and snoop. */ Now, replace your do_wizhelp with this one: /* * Wizhelp. Modified by Ammaross Danan to work with SecEdit security */ void do_wizhelp( CHAR_DATA *ch, char *argument ) { char buf[MAX_STRING_LENGTH]; int cmd; int col; col = 0; for ( cmd = 0; cmd_table[cmd].name[0] != '\0'; cmd++ ) { if ( cmd_table[cmd].level >= LEVEL_HERO && cmd_table[cmd].show ) { if ( ( cmd_table[cmd].secgroup == 0 && cmd_table[cmd].level <= get_trust( ch ) ) || ( ch->pcdata != NULL && IS_SET(cmd_table[cmd].secgroup, ch->pcdata->secgroups) ) ) { sprintf( buf, "%-12s", cmd_table[cmd].name ); send_to_char( buf, ch ); if ( ++col % 6 == 0 ) send_to_char( "\n\r", ch ); } } } if ( col % 6 != 0 ) send_to_char( "\n\r", ch ); return; } << In cmdedit.c: >> At then end of your cmdedit_show(), just before the return FALSE;, add this: /* Displays what Security groups the command belongs to */ if ( pCmd->secgroup != 0 ) { BUFFER *pBuf; int i, j; extern SECURITY_DATA *security_table; send_to_char( "Security groups:\n\r", ch ); pBuf = new_buf(); sprintf( buf, "Num %-18.18s Num %-18.18s Num %-18.18s\n\r", "Name", "Name", "Name" ); add_buf( pBuf, buf ); for ( i = 0, j = 0; !IS_NULLSTR(security_table[i].name); i++ ) { if( IS_SET( pCmd->secgroup, security_table[i].bit ) ) { sprintf( buf, "%3d %-18.18s", ++j, security_table[i].name ); if ( j % 3 == 0 ) strcat( buf, "\n\r" ); else strcat( buf, " " ); add_buf( pBuf, buf ); } } if ( j % 3 != 0 ) add_buf( pBuf, "\n\r" ); page_to_char( buf_string(pBuf), ch ); free_buf(pBuf); } In your list_commands, change: if ( cmd_table[i].level < minlev || cmd_table[i].level > maxlev ) to: /* maxlev+1 so you can see commands that are part of security groups */ if ( cmd_table[i].level < minlev || cmd_table[i].level > maxlev+1 ) << In tablesave.c: >> Under: struct cmd_type cmd; At the top of the file, add this: SECURITY_DATA sec; Add this in the cmdsavetable[]: { "secgroup", CAMPO_FLAGVECTOR, (void *) &cmd.secgroup, NULL, NULL }, Add this just under cmdsavetable[]: const struct savetable_type secsavetable [] = { { "name", CAMPO_STRING, (void *) &sec.name, NULL, NULL }, { "bit", CAMPO_FLAGVECTOR, (void *) &sec.bit, NULL, NULL }, { NULL, 0, NULL, NULL, NULL } }; Now at the bottom of the file place these: #define SEC_FILE DATA_DIR "secgroup.dat" /* * Ammaross Danan: * Used to save the security data table. */ void save_security_table( void ) { FILE * fp; SECURITY_DATA * temp; extern SECURITY_DATA * security_table; int cnt = 0; fp = fopen( SEC_FILE, "w" ); if ( !fp ) { perror( "save_security_table" ); return; } for ( temp = security_table; !IS_NULLSTR(temp->name); temp = temp++ ) cnt++; fprintf( fp, "%d\n\n", cnt ); for ( temp = security_table; !IS_NULLSTR(temp->name); temp = temp++ ) { fprintf( fp, "#SECGROUP\n" ); save_struct( fp, &sec, secsavetable, temp ); fprintf( fp, "#END\n\n" ); } fclose(fp); } /* * Ammaross Danan: * Used to load the security data table. */ void load_security( void ) { FILE * fp; extern SECURITY_DATA * security_table; static SECURITY_DATA emptycmd; int i = 0; int size = 0; char * word; fp = fopen( SEC_FILE, "r" ); if ( fp == NULL ) { perror( "load_security_table "); return; } size = fread_number(fp); logf( WORLD_ALL, "Created security_table of length %d, size %d", size + 1, sizeof(SECURITY_DATA) * (size + 1) ); security_table = calloc( sizeof(SECURITY_DATA), size + 1); for ( i = 0; i <= size; i++ ) security_table[i] = emptycmd; // initialize i = 0; while(TRUE) { word = fread_word(fp); if ( str_cmp(word, "#SECGROUP") ) { bugf( "load_security_table : word %s", word ); fclose(fp); return; } load_struct( fp, &sec, secsavetable, &security_table[i++] ); if ( i == size ) { log( "Security table loaded." ); fclose(fp); security_table[i].name = NULL; return; } } } << In tablesave.h: >> Add: void load_security( void ); void save_security_table( void ); << In save.c >> Add this in fwrite char where ever you prefer (in is after the olc security fwrite): fprintf( fp, "SecGroup %s\n", print_flags( ch->pcdata->secgroups ) ); Now add this in fread_char under the case 'S': KEY( "SecGroup", ch->pcdata->secgroups, fread_flag( fp ) ); << In db.c: >> Add this in the boot_db() where all the other load_XXX for OLC are located: load_security(); << In help.are: >> Add this somewhere: -1 SECEDIT SECURITY~ SecEdit is used to create groups of commands for security purposes. secedit list - List current security groups secedit <name> - Edits the group <name> secedit new <name> - Creates a new security group called <name> secedit bit <bit letter> - Sets the group to use <bit>. MUST SET BEFORE ADDING COMMANDS. secedit command add/remove <command> - Adds or removes a command from the group SecEdit was written by Ammaross Danan (ammaross@crosswinds.net) of ArdenmoreMUD. ~ -1 GRANT~ Syntax: grant <player> <group> Grant is used to grant users security groups. ~ Now do a clean make and cross your fingers. *hopes he did not forget anything* Now, I am sure you will want an explaination of how to use it and set it up? Read the aftermath.txt.