===========================================================================
This snippet was written by Erwin S. Andreasen, erwin@pip.dknet.dk. You may
use this code freely, as long as you retain my name in all of the files. You
also have to mail me telling that you are using it. I am giving this,
hopefully useful, piece of source code to you for free, and all I require
from you is some feedback.
Please mail me if you find any bugs or have any new ideas or just comments.
All my snippets are publically available at:
http://pip.dknet.dk/~pip1773/
If you do not have WWW access, try ftp'ing to pip.dknet.dk and examine
the /pub/pip1773 directory.
===========================================================================
Disabling of commands
---------------------
Usage:
disable - shows lists
disable <command> - disable command or reenable it if disabled.
When a command is disabled, no players can use it. It is useful for
disabling buggy commands or disabling certain commands for use with quests.
I am thinking of expanding this to include spells to, watch out for version
2 ! :)
The changes are the output of a diff -bBp : + denotes new lines. Lines
without + are existing lines of code, included for reference.
db.c 1995/12/28 16:08:03
===========================
Add loading of disabled commands at boot.
*************** void boot_db( void )
load_notes( );
+ load_disabled();
interp.c 1995/12/28 16:23:58
===================================
At top of the file: include file <unistd.h> for unlink() prototype and
declare prototype of this local function + some more.
#include <time.h>
+ #include <unistd.h> /* unlink() */
#include "merc.h"
+ bool check_disabled (const struct cmd_type *command);
+ DISABLED_DATA *disabled_first;
+
+ #define END_MARKER "END" /* for load_disabled() and save_disabled() */
In interpret, add check for disabled commands.
*************** void interpret( CHAR_DATA *ch, char *arg
send_to_char( "Huh?\n\r", ch );
return;
}
+ else /* a normal valid command.. check if it is disabled */
+ if (check_disabled (&cmd_table[cmd]))
+ {
+ send_to_char ("This command has been temporarily disabled.\n\r",ch);
+ return;
+ }
/*
* Character not in position for command?
Add this to interp.c: command to disable commands, function to check if a
command is diabled and the 2 functions to save/load disabled commands.
/* Syntax is:
disable - shows disabled commands
disable <command> - toggles disable status of command
*/
void do_disable (CHAR_DATA *ch, char *argument)
{
int i;
DISABLED_DATA *p,*q;
char buf[100];
if (IS_NPC(ch))
{
send_to_char ("RETURN first.\n\r",ch);
return;
}
if (!argument[0]) /* Nothing specified. Show disabled commands. */
{
if (!disabled_first) /* Any disabled at all ? */
{
send_to_char ("There are no commands disabled.\n\r",ch);
return;
}
send_to_char ("Disabled commands:\n\r"
"Command Level Disabled by\n\r",ch);
for (p = disabled_first; p; p = p->next)
{
sprintf (buf, "%-12s %5d %-12s\n\r",p->command->name, p->level, p->disabled_by);
send_to_char (buf,ch);
}
return;
}
/* command given */
/* First check if it is one of the disabled commands */
for (p = disabled_first; p ; p = p->next)
if (!str_cmp(argument, p->command->name))
break;
if (p) /* this command is disabled */
{
/* Optional: The level of the imm to enable the command must equal or exceed level
of the one that disabled it */
if (get_trust(ch) < p->level)
{
send_to_char ("This command was disabled by a higher power.\n\r",ch);
return;
}
/* Remove */
if (disabled_first == p) /* node to be removed == head ? */
disabled_first = p->next;
else /* Find the node before this one */
{
for (q = disabled_first; q->next != p; q = q->next); /* empty for */
q->next = p->next;
}
free_string (p->disabled_by); /* free name of disabler */
free_mem (p,sizeof(DISABLED_DATA)); /* free node */
save_disabled(); /* save to disk */
send_to_char ("Command enabled.\n\r",ch);
}
else /* not a disabled command, check if that command exists */
{
/* IQ test */
if (!str_cmp(argument,"disable"))
{
send_to_char ("You cannot disable the disable command.\n\r",ch);
return;
}
/* Search for the command */
for (i = 0; cmd_table[i].name[0] != '\0'; i++)
if (!str_cmp(cmd_table[i].name, argument))
break;
/* Found? */
if (cmd_table[i].name[0] == '\0')
{
send_to_char ("No such command.\n\r",ch);
return;
}
/* Can the imm use this command at all ? */
if (cmd_table[i].level > get_trust(ch))
{
send_to_char ("You dot have access to that command; you cannot disable it.\n\r",ch);
return;
}
/* Disable the command */
p = alloc_mem (sizeof(DISABLED_DATA));
p->command = &cmd_table[i];
p->disabled_by = str_dup (ch->name); /* save name of disabler */
p->level = get_trust(ch); /* save trust */
p->next = disabled_first;
disabled_first = p; /* add before the current first element */
send_to_char ("Command disabled.\n\r",ch);
save_disabled(); /* save to disk */
}
}
/* Check if that command is disabled
Note that we check for equivalence of the do_fun pointers; this means
that disabling 'chat' will also disable the '.' command
*/
bool check_disabled (const struct cmd_type *command)
{
DISABLED_DATA *p;
for (p = disabled_first; p ; p = p->next)
if (p->command->do_fun == command->do_fun)
return TRUE;
return FALSE;
}
/* Load disabled commands */
void load_disabled()
{
FILE *fp;
DISABLED_DATA *p;
char *name;
int i;
disabled_first = NULL;
fp = fopen (DISABLED_FILE, "r");
if (!fp) /* No disabled file.. no disabled commands : */
return;
name = fread_word (fp);
while (str_cmp(name, END_MARKER)) /* as long as name is NOT END_MARKER :) */
{
/* Find the command in the table */
for (i = 0; cmd_table[i].name[0] ; i++)
if (!str_cmp(cmd_table[i].name, name))
break;
if (!cmd_table[i].name[0]) /* command does not exist? */
{
bug ("Skipping uknown command in " DISABLED_FILE " file.",0);
fread_number(fp); /* level */
fread_word(fp); /* disabled_by */
}
else /* add new disabled command */
{
p = alloc_mem(sizeof(DISABLED_DATA));
p->command = &cmd_table[i];
p->level = fread_number(fp);
p->disabled_by = str_dup(fread_word(fp));
p->next = disabled_first;
disabled_first = p;
}
name = fread_word(fp);
}
fclose (fp);
}
/* Save disabled commands */
void save_disabled()
{
FILE *fp;
DISABLED_DATA *p;
if (!disabled_first) /* delete file if no commands are disabled */
{
unlink (DISABLED_FILE);
return;
}
fp = fopen (DISABLED_FILE, "w");
if (!fp)
{
bug ("Could not open " DISABLED_FILE " for writing",0);
return;
}
for (p = disabled_first; p ; p = p->next)
fprintf (fp, "%s %d %s\n", p->command->name, p->level, p->disabled_by);
fprintf (fp, "%s\n",END_MARKER);
fclose (fp);
}
merc.h 1995/12/28 16:10:52
===========================
structures, defines of file locations etc.
+ typedef struct disabled_data DISABLED_DATA;
+ /* one disabled command */
+ struct disabled_data
+ {
+ DISABLED_DATA *next; /* pointer to next node */
+ struct cmd_type const *command; /* pointer to the command struct*/
+ char *disabled_by; /* name of disabler */
+ sh_int level; /* level of disabler */
+ };
+
+ extern DISABLED_DATA * disabled_first; /* interp.c */
+ DECLARE_DO_FUN( do_disable ); /* dec95 EA */
+ #define DISABLED_FILE "disabled.txt" /* disabled commands */
/* prototypes from db.c */
+ void load_disabled args( ( void ) );
+ void save_disabled args( ( void ) );