muddy/
muddy/CVS/
muddy/area/
muddy/area/CVS/
muddy/clans/CVS/
muddy/classes/CVS/
muddy/doc/
muddy/doc/CVS/
muddy/etc/CVS/
muddy/etc/i3/
muddy/etc/i3/CVS/
muddy/imc/CVS/
muddy/lang/CVS/
muddy/licenses/CVS/
muddy/msgdb/CVS/
muddy/new/CVS/
muddy/notes/
muddy/player/
muddy/races/CVS/
muddy/religions/CVS/
muddy/src/CVS/
muddy/src/comm/CVS/
muddy/src/db/CVS/
muddy/src/intermud/
muddy/src/intermud/CVS/
muddy/src/irc/CVS/
muddy/src/olc/CVS/
/*  $Id: olc_msg.c,v 1.666 2004/09/20 10:50:30 shrike Exp $ */

/************************************************************************************
 *    Copyright 2004 Astrum Metaphora consortium                                    *
 *                                                                                  *
 *    Licensed under the Apache License, Version 2.0 (the "License");               *
 *    you may not use this file except in compliance with the License.              *
 *    You may obtain a copy of the License at                                       *
 *                                                                                  *
 *    http://www.apache.org/licenses/LICENSE-2.0                                    *
 *                                                                                  *
 *    Unless required by applicable law or agreed to in writing, software           *
 *    distributed under the License is distributed on an "AS IS" BASIS,             *
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.      *
 *    See the License for the specific language governing permissions and           *
 *    limitations under the License.                                                *
 *                                                                                  *
 ************************************************************************************/
/************************************************************************************
 *     ANATOLIA 2.1 is copyright 1996-1997 Serdar BULUT, Ibrahim CANPUNAR           *
 *     ANATOLIA has been brought to you by ANATOLIA consortium                      *
 *       Serdar BULUT {Chronos}         bulut@rorqual.cc.metu.edu.tr                *
 *       Ibrahim Canpunar  {Asena}      canpunar@rorqual.cc.metu.edu.tr             *
 *       Murat BICER  {KIO}             mbicer@rorqual.cc.metu.edu.tr               *
 *       D.Baris ACAR {Powerman}        dbacar@rorqual.cc.metu.edu.tr               *
 *     By using this code, you have agreed to follow the terms of the               *
 *     ANATOLIA license, in the file Anatolia/anatolia.licence                      *
 ***********************************************************************************/

/************************************************************************************
 *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,                 *
 *  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.            *
 *                                                                                  *
 *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael                   *
 *  Chastain, Michael Quan, and Mitchell Tse.                                       *
 *                                                                                  *
 *  In order to use any part of this Merc Diku Mud, you must comply with            *
 *  both the original Diku license in 'license.doc' as well the Merc                *
 *  license in 'license.txt'.  In particular, you may not remove either of          *
 *  these copyright notices.                                                        *
 *                                                                                  *
 *  Much time and thought has gone into this software and you are                   *
 *  benefitting.  We hope that you share your changes too.  What goes               *
 *  around, comes around.                                                           *
 ************************************************************************************/

/************************************************************************************
*       ROM 2.4 is copyright 1993-1995 Russ Taylor                                  *
*       ROM has been brought to you by the ROM consortium                           *
*           Russ Taylor (rtaylor@pacinfo.com)                                       *
*           Gabrielle Taylor (gtaylor@pacinfo.com)                                  *
*           Brian Moore (rom@rom.efn.org)                                           *
*       By using this code, you have agreed to follow the terms of the              *
*       ROM license, in the file Rom24/doc/rom.license                              *
*************************************************************************************/

/************************************************************************************
 * 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.                                                                     *
 ************************************************************************************/
 

#include <stdio.h>
#include <string.h>

#include "merc.h"
#include "olc.h"
#include "db/lang.h"

#define EDIT_MSG(ch, mlp)	(mlp = (mlstring**) ch->desc->pEdit)

DECLARE_OLC_FUN(msged_create        );
DECLARE_OLC_FUN(msged_edit      );
DECLARE_OLC_FUN(msged_show      );
DECLARE_OLC_FUN(msged_list      );

DECLARE_OLC_FUN(msged_msg       );
DECLARE_OLC_FUN(msged_del       );

olc_cmd_t olc_cmds_msg[] =
{
    { "create", msged_create,   5},
    { "edit",   msged_edit, 0},
    { "touch",  olced_dummy,    0},
    { "show",   msged_show, 0},
    { "list",   msged_list, 0},

    { "msg",    msged_msg,  5},
    { "delete_ms",  olced_spell_out,    0},
    { "delete_msg", msged_del,  5},

    { "commands",   show_commands,  0},
    { NULL}
};

/* case-sensitive substring search with [num.]name syntax */
static mlstring **  msg_search(const char *argument);

static const char*  atomsg(const char *argument);
static const char*  msgtoa(const char *argument);

void        msg_dump(BUFFER *buf, mlstring *ml);

OLC_FUN(msged_create)
{
    if (ch->pcdata->security < SECURITY_MSGDB)
    {
        char_puts("MsgEd: Insufficient security.\n", ch);
        return FALSE;
    }

    if (argument[0] == '\0')
    {
        do_help(ch, "'OLC CREATE'");
        return FALSE;
    }

    if (!str_cmp(argument, "$"))
    {
        char_puts("MsgEd: invalid value.\n", ch);
        return FALSE;
    }

    if (msg_lookup(argument = atomsg(argument)))
    {
        char_puts("MsgEd: msg already exists.\n", ch);
        return FALSE;
    }

    if (olced_busy(ch, ED_MSG, NULL, NULL))
        return FALSE;

    ch->desc->pEdit = (void*) msg_add(mlstr_new(argument));
    OLCED(ch)   = olced_lookup(ED_MSG);
    char_puts("Msg created.\n", ch);
    return FALSE;
}

OLC_FUN(msged_edit)
{
    mlstring **mlp;

    if (ch->pcdata->security < SECURITY_MSGDB)
    {
        char_puts("MsgEd: Insufficient security.\n", ch);
        return FALSE;
    }

    if (argument[0] == '\0')
    {
        do_help(ch, "'OLC EDIT'");
        return FALSE;
    }

    if ((mlp = msg_search(atomsg(argument))) == NULL)
    {
        char_puts("MsgEd: msg not found.\n", ch);
        return FALSE;
    }

    ch->desc->pEdit     = (void *) mlp;
    OLCED(ch)   = olced_lookup(ED_MSG);
    return FALSE;
}

OLC_FUN(msged_show)
{
    BUFFER *output;
    mlstring **mlp;

    if (argument[0] == '\0')
    {
        if (IS_EDIT(ch, ED_MSG))
            EDIT_MSG(ch, mlp);
        else
        {
            do_help(ch, "'OLC ASHOW'");
            return FALSE;
        }
    }
    else
    {
        if ((mlp = msg_search(atomsg(argument))) == NULL)
        {
            char_puts("MsgEd: msg not found.\n", ch);
            return FALSE;
        }
    }

    output = buf_new(-1);
    msg_dump(output, *mlp);
    page_to_char(buf_string(output), ch);
    buf_free(output);
    return FALSE;
}

OLC_FUN(msged_list)
{
    int i;
    int num;
    BUFFER *output = NULL;

    if (argument[0] == '\0')
    {
        do_help(ch, "'OLC ALIST'");
        return FALSE;
    }

    argument = atomsg(argument);
    num = 0;    
    for (i = 0; i < MAX_MSG_HASH; i++)
    {
        int j;
        varr *v = msg_hash_table+i;

        if (v == NULL)
            continue;

        for (j = 0; j < v->nused; j++)
        {
            mlstring **mlp = VARR_GET(v, j);
            const char *name = mlstr_mval(*mlp);

            if (strstr(name, argument))
            {
                if (output == NULL)
                    output = buf_new(-1);
                buf_printf(output, "%2d. [%s]\n",
                           ++num, msgtoa(name));
            }
        }
    }

    if (output)
    {
        page_to_char(buf_string(output), ch);
        buf_free(output);
    }
    else
        char_puts("MsgEd: no messages found.\n", ch);

    return FALSE;
}

OLC_FUN(msged_msg)
{
    char arg[MAX_STRING_LENGTH];
    int lang;
    int iter;
    const char **p = 0;
    mlstring *ml;

    mlstring **mlp;
    EDIT_MSG(ch, mlp);

    argument = one_argument(argument, arg, sizeof(arg));
    
    lang = lang_lookup(arg);
    if (lang < 0)
    {
        do_help(ch, "'OLC MSG'");
        return FALSE;
    }

    argument = atomsg(argument);
    
    if (!lang)
    {
        /* gonna change name */
        
        if (!str_cmp(argument, "$"))
        {
            char_puts("MsgEd: invalid value.\n", ch);
            return FALSE;
        }

        if (msg_lookup(argument))
        {
            char_puts("MsgEd: duplicate name.\n", ch);
            return FALSE;
        }

        if (olced_busy(ch, ED_MSG, NULL, NULL))
            return FALSE;

        ml = msg_del(mlstr_mval(*mlp));
        mlp = &ml;
    }
    else
        ml = *mlp;
    
    p = mlstr_convert(&ml, lang);
    
    //Change the last string on the argument for 
    //compatible with the changes mlstr_convert function
    for (iter = lang ; iter < langs.nused; iter++) {
	free_string(*p);
	*p = str_dup(atomsg(argument));
	p = p + 1;
    }

    if (!lang)
        ch->desc->pEdit = (void*) msg_add(ml);

    return TRUE;
}

OLC_FUN(msged_del)
{
    mlstring *ml;
    mlstring **mlp;

    if (olced_busy(ch, ED_MSG, NULL, NULL))
        return FALSE;

    EDIT_MSG(ch, mlp);
    ml = msg_del(mlstr_mval(*mlp));
    mlstr_free(ml);
    edit_done(ch->desc);

    return FALSE;
}

/*
 * local functions
 */

/* case-sensitive substring search with [num.]name syntax */
static mlstring **msg_search(const char *argument)
{
    char name[MAX_INPUT_LENGTH];
    int i;
    int num;

    num = number_argument(argument, name, sizeof(name));
    if (name[0] == '\0' || num <= 0)
        return NULL;

    for (i = 0; i < MAX_MSG_HASH; i++)
    {
        int j;
        varr *v = msg_hash_table+i;

        if (v == NULL)
            continue;

        for (j = 0; j < v->nused; j++)
        {
            mlstring **mlp = VARR_GET(v, j);

            if (strstr(mlstr_mval(*mlp), name) && !--num)
                return mlp;
        }
    }

    return NULL;
}

static const char *atomsg(const char *argument)
{
    static char buf[MAX_STRING_LENGTH];
    const char *i;
    int o;

    for (o = 0, i = argument; o < sizeof(buf)-1 && *i; i++, o++)
    {
        if (*i == '\\' && *(i+1))
        {
            switch (*++i)
            {
            case 'a':
                buf[o] = '\a';
                break;
            case 'r':
                buf[o] = '\r';
                break;
            case 'n':
                buf[o] = '\n';
                break;
            default:
                buf[o] = *i;
                break;
            }
            continue;
        }
        buf[o] = *i;
    }
    buf[o] = '\0';

    return buf;
}

static const char* msgtoa(const char *argument)
{
    static char buf[MAX_STRING_LENGTH];
    const char *i;
    int o;

    for (o = 0, i = argument; o < sizeof(buf)-2 && *i; i++, o++)
    {
        switch (*i)
        {
        case '\a':
            buf[o++] = '\\';
            buf[o] = 'a';
            continue;
        case '\n':
            buf[o++] = '\\';
            buf[o] = 'n';
            continue;
        case '\r':
            buf[o++] = '\\';
            buf[o] = 'r';
            continue;
        case '\\':
            buf[o++] = '\\';
            break;
        case '{':
            buf[o++] = *i;
            break;
        }
        buf[o] = *i;
    }
    buf[o] = '\0';

    return buf;
}

void msg_dump(BUFFER *buf, mlstring *ml)
{
    int lang;
    int nlang = mlstr_nlang(ml);
    static char FORMAT[] = "[%s] [%s]\n";

    if (!nlang)
    {
        buf_printf(buf, FORMAT, "all", msgtoa(mlstr_mval(ml)));
        return;
    }

    for (lang = 0; lang < nlang; lang++)
    {
        lang_t *l = VARR_GET(&langs, lang);
        buf_printf(buf, FORMAT, l->name, msgtoa(mlstr_val(ml, lang)));
    }
}