/*- * Copyright (c) 1998 fjoe <fjoe@iclub.nsu.ru> * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Id: olc_rule.c,v 1.8 1999/04/17 06:56:39 fjoe Exp $ */ #include <stdio.h> #include <stdlib.h> #include "merc.h" #include "olc.h" #include "db/lang.h" #define EDIT_RULE(ch, r) (r = (rule_t*) ch->desc->pEdit) #define EDIT_RCL(ch, rcl) (rcl = (rulecl_t*) ch->desc->pEdit2) #define EDIT_ROPS(ch, rops) (rops = (ruleops_t*) cmd->arg1) #define EDIT_LANG(ch, l) \ { \ if ((l = varr_get(&langs, ch->lang)) == NULL) { \ char_puts("RuleEd: unknown current language. " \ "Use 'lang' command to set " \ "correct language.\n", ch); \ return FALSE; \ } \ } typedef struct ruleops_t ruleops_t; struct ruleops_t { rule_t* (*rule_lookup)(rulecl_t *rcl, const char *name); void (*rule_del)(rulecl_t *rcl, rule_t *r); const char * id; flag32_t bit; }; ruleops_t rops_expl = { erule_lookup, erule_del, ED_EXPL, RULES_EXPL_CHANGED }; ruleops_t rops_impl = { irule_lookup, irule_del, ED_IMPL, RULES_IMPL_CHANGED }; DECLARE_OLC_FUN(ruleed_create ); DECLARE_OLC_FUN(ruleed_edit ); DECLARE_OLC_FUN(ruleed_touch ); DECLARE_OLC_FUN(ruleed_show ); DECLARE_OLC_FUN(ruleed_list ); DECLARE_OLC_FUN(ruleed_name ); DECLARE_OLC_FUN(ruleed_base ); DECLARE_OLC_FUN(ruleed_arg ); DECLARE_OLC_FUN(ruleed_add ); DECLARE_OLC_FUN(ruleed_del ); DECLARE_OLC_FUN(ruleed_delete ); DECLARE_OLC_FUN(eruleed_name ); DECLARE_OLC_FUN(iruleed_name ); DECLARE_OLC_FUN(eruleed_list ); olc_cmd_t olc_cmds_expl[] = { { "create", ruleed_create, &rops_expl }, { "edit", ruleed_edit, &rops_expl }, { "touch", ruleed_touch, &rops_expl }, { "show", ruleed_show, &rops_expl }, { "list", ruleed_list, &rops_expl }, { "name", eruleed_name }, { "base", ruleed_base }, { "add", ruleed_add }, { "del", ruleed_del }, { "rule_delet", olced_spell_out }, { "rule_delete", ruleed_delete, &rops_expl }, { "commands", show_commands }, { NULL } }; olc_cmd_t olc_cmds_impl[] = { { "create", ruleed_create, &rops_impl }, { "edit", ruleed_edit, &rops_impl }, { "touch", ruleed_touch, &rops_impl }, { "show", ruleed_show, &rops_impl }, { "list", ruleed_list, &rops_impl }, { "name", iruleed_name }, { "arg", ruleed_arg }, { "add", ruleed_add }, { "del", ruleed_del }, { "delete_rul", olced_spell_out }, { "delete_rule", ruleed_delete, &rops_impl }, { "commands", show_commands }, { NULL } }; OLC_FUN(ruleed_create) { int rulecl; rulecl_t *rcl; ruleops_t *rops; lang_t *l; rule_t rnew; char arg[MAX_STRING_LENGTH]; char arg2[MAX_STRING_LENGTH]; bool impl; if (ch->pcdata->security < SECURITY_MSGDB) { char_puts("RuleEd: Insufficient security.\n", ch); return FALSE; } EDIT_LANG(ch, l); EDIT_ROPS(ch, rops); impl = (rops->id == ED_IMPL); argument = one_argument(argument, arg, sizeof(arg)); if (impl) argument = one_argument(argument, arg2, sizeof(arg2)); if (argument[0] == '\0' || (impl && !is_number(arg2))) { do_help(ch, "'OLC CREATE'"); return FALSE; } if ((rulecl = flag_value(rulecl_names, arg)) < 0) { char_printf(ch, "RuleEd: %s: unknown rule class.\n", arg); return FALSE; } rcl = l->rules + rulecl; if (!impl && erule_lookup(rcl, argument)) { char_printf(ch, "RuleEd: %s: duplicate name.\n", argument); return FALSE; } if (olced_busy(ch, rops->id, NULL, rcl)) return FALSE; rule_init(&rnew); rnew.name = str_dup(argument); OLCED(ch) = olced_lookup(rops->id); ch->desc->pEdit = impl ? irule_insert(rcl, atoi(arg2), &rnew) : erule_add(rcl, &rnew); ch->desc->pEdit2= rcl; SET_BIT(rcl->flags, rops->bit); char_puts("RuleEd: rule created.\n", ch); return FALSE; } OLC_FUN(ruleed_edit) { int rulecl; rulecl_t *rcl; ruleops_t *rops; lang_t *l; rule_t *r; char arg[MAX_INPUT_LENGTH]; if (ch->pcdata->security < SECURITY_MSGDB) { char_puts("RuleEd: Insufficient security.\n", ch); return FALSE; } argument = one_argument(argument, arg, sizeof(arg)); if (argument[0] == '\0') { do_help(ch, "'OLC EDIT'"); return FALSE; } EDIT_LANG(ch, l); EDIT_ROPS(ch, rops); if ((rulecl = flag_value(rulecl_names, arg)) < 0) { char_printf(ch, "RuleEd: %s: unknown rule class.\n", arg); return FALSE; } rcl = l->rules+rulecl; if ((r = rops->rule_lookup(rcl, argument)) == NULL) { char_printf(ch, "RuleEd: %s: not found.\n", argument); return FALSE; } ch->desc->olced = olced_lookup(rops->id); ch->desc->pEdit = r; ch->desc->pEdit2= rcl; return FALSE; } OLC_FUN(ruleed_touch) { rulecl_t *rcl; ruleops_t *rops; EDIT_RCL(ch, rcl); EDIT_ROPS(ch, rops); SET_BIT(rcl->flags, rops->bit); return FALSE; } OLC_FUN(ruleed_show) { int i; rule_t *r; rulecl_t *rcl; ruleops_t *rops; lang_t *l; EDIT_LANG(ch, l); EDIT_ROPS(ch, rops); if (argument[0] == '\0') { if (IS_EDIT(ch, ED_IMPL) || IS_EDIT(ch, ED_EXPL)) { EDIT_RULE(ch, r); EDIT_RCL(ch, rcl); } else { do_help(ch, "'OLC ASHOW'"); return FALSE; } } else { int rulecl; char arg[MAX_INPUT_LENGTH]; argument = one_argument(argument, arg, sizeof(arg)); if (argument[0] == '\0') { do_help(ch, "'OLC ASHOW'"); return FALSE; } if ((rulecl = flag_value(rulecl_names, arg)) < 0) { char_printf(ch, "RuleEd: %s: unknown rule class.\n", arg); return FALSE; } rcl = l->rules + rulecl; if ((r = rops->rule_lookup(rcl, argument)) == NULL) { char_printf(ch, "RuleEd: %s: not found.\n", argument); return FALSE; } } char_printf(ch, "Name: [%s]\n" "Lang: [%s] Class: [%s] Type: [%s]\n", r->name, l->name, flag_string(rulecl_names, rcl->rulecl), rops->id); if (rops->id == ED_IMPL) char_printf(ch, "Arg: [%d]\n", r->arg); else { char buf[MAX_STRING_LENGTH]; strnzncpy(buf, sizeof(buf), r->name, r->arg); char_printf(ch, "Base: [%s] (%d)\n", buf, r->arg); } for (i = 0; i < r->f->v.nused; i++) { char **p = VARR_GET(&r->f->v, i); if (!IS_NULLSTR(*p)) char_printf(ch, "Form: [%d] [%s]\n", i, *p); } return FALSE; } OLC_FUN(ruleed_list) { int i; rule_t *r; rulecl_t *rcl; ruleops_t *rops; lang_t *l; BUFFER *output = NULL; EDIT_LANG(ch, l); EDIT_ROPS(ch, rops); if (IS_EDIT(ch, ED_IMPL) || IS_EDIT(ch, ED_EXPL)) { EDIT_RULE(ch, r); EDIT_RCL(ch, rcl); } else { int rulecl; char arg[MAX_INPUT_LENGTH]; argument = one_argument(argument, arg, sizeof(arg)); if (arg[0] == '\0') { do_help(ch, "'OLC ALIST'"); return FALSE; } if ((rulecl = flag_value(rulecl_names, arg)) < 0) { char_printf(ch, "RuleEd: %s: unknown rule class.\n", arg); return FALSE; } rcl = l->rules + rulecl; } if (rops->id == ED_IMPL) { if (rcl->impl.nused) { output = buf_new(-1); for (i = 0; i < rcl->impl.nused; i++) { rule_t *r = VARR_GET(&rcl->impl, i); buf_printf(output, "%3d. %s\n", i, r->name); } } } else { if (argument[0] == '\0') { do_help(ch, "'OLC ALIST'"); return FALSE; } for (i = 0; i < MAX_RULE_HASH; i++) { int j; for (j = 0; j < rcl->expl[i].nused; j++) { rule_t *r = VARR_GET(rcl->expl+i, j); if (!str_prefix(argument, r->name)) { if (!output) output = buf_new(-1); buf_printf(output, "%s\n", r->name); } } } } if (output) { page_to_char(buf_string(output), ch); buf_free(output); } else char_puts("RuleEd: no rules found.\n", ch); return FALSE; } OLC_FUN(eruleed_name) { rule_t *r; rule_t *r2; rule_t rnew; rulecl_t *rcl; if (argument[0] == '\0') { do_help(ch, "'OLC RULE'"); return FALSE; } EDIT_RULE(ch, r); EDIT_RCL(ch, rcl); if (olced_busy(ch, ED_EXPL, NULL, rcl)) return FALSE; if ((r2 = erule_lookup(rcl, argument)) && r2 != r) { char_printf(ch, "RuleEd: %s: duplicate name.\n", argument); return FALSE; } erule_del(rcl, r); rule_init(&rnew); rnew.name = str_dup(argument); ch->desc->pEdit = erule_add(rcl, &rnew); return TRUE; } OLC_FUN(iruleed_name) { rule_t *r; EDIT_RULE(ch, r); return olced_str(ch, argument, cmd, &r->name); } OLC_FUN(ruleed_base) { char arg[MAX_INPUT_LENGTH]; rule_t *r; EDIT_RULE(ch, r); one_argument(argument, arg, sizeof(arg)); if (str_prefix(arg, r->name)) { char_printf(ch, "RuleEd: %s: not prefix of name (%s).\n", arg, r->name); return FALSE; } r->arg = strlen(arg); return TRUE; } OLC_FUN(ruleed_arg) { rule_t *r; EDIT_RULE(ch, r); return olced_number(ch, argument, cmd, &r->arg); } OLC_FUN(ruleed_add) { rule_t *r; EDIT_RULE(ch, r); return olced_vform_add(ch, argument, cmd, r); } OLC_FUN(ruleed_del) { rule_t *r; EDIT_RULE(ch, r); return olced_vform_del(ch, argument, cmd, r); } OLC_FUN(ruleed_delete) { rule_t *r; rulecl_t *rcl; ruleops_t *rops; EDIT_RULE(ch, r); EDIT_RCL(ch, rcl); EDIT_ROPS(ch, rops); if (olced_busy(ch, rops->id, NULL, rcl)) return FALSE; rops->rule_del(rcl, r); SET_BIT(rcl->flags, rops->bit); edit_done(ch->desc); return FALSE; }