/* * IMC2 - an inter-mud communications protocol * * icec-mercbase.c: IMC-channel-extensions (ICE) Merc-specific client code * * Copyright (C) 1997 Oliver Jowett <oliver@jowett.manawatu.planet.co.nz> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program (see the file COPYING); if not, write to the * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #if defined(macintosh) #include <types.h> #else #include <sys/types.h> #include <sys/time.h> #endif #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> #include <stdarg.h> #include <string.h> #include <ctype.h> #define IN_IMC #include "imc.h" #include "imc-mercbase.h" #include "icec.h" #include "icec-mercbase.h" static ice_channel *saved_channel_list; void icec_save_channels(void) { ice_channel *c; FILE *fp; char name[MAX_STRING_LENGTH]; strcpy(name, imc_prefix); strcat(name, "icec"); fp=fopen(name, "w"); if (!fp) { imc_logerror("Can't write to %s", name); return; } for (c=saved_channel_list; c; c=c->next) { /* update */ ice_channel *current=icec_findlchannel(c->local->name); if (current) { imc_strfree(c->name); imc_strfree(c->local->format1); imc_strfree(c->local->format2); c->name=imc_strdup(current->name); c->local->format1=imc_strdup(current->local->format1); c->local->format2=imc_strdup(current->local->format2); c->local->level=current->local->level; } /* save */ fprintf(fp, "%s %s %d\n" "%s\n" "%s\n", c->name, c->local->name, c->local->level, c->local->format1, c->local->format2); } fclose(fp); } void icec_load_channels(void) { FILE *fp; char name[MAX_STRING_LENGTH]; char buf1[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH]; char buf3[MAX_STRING_LENGTH]; char buf4[MAX_STRING_LENGTH]; int l; strcpy(name, imc_prefix); strcat(name, "icec"); fp=fopen(name, "r"); if (!fp) { imc_logerror("Can't open %s", name); return; } while (fscanf(fp, "%s %s %d\n" "%[^\n]\n" "%[^\n]\n", buf1, buf2, &l, buf3, buf4) == 5) { ice_channel *c=imc_malloc(sizeof(*c)); c->local=imc_malloc(sizeof(*c->local)); c->name=imc_strdup(buf1); c->local->name=imc_strdup(buf2); c->local->format1=imc_strdup(buf3); c->local->format2=imc_strdup(buf4); c->local->level=l; c->next=saved_channel_list; saved_channel_list=c; imc_logstring("ICEc: configured %s as %s", c->name, c->local->name); } fclose(fp); } ice_channel *icec_findlchannel(const char *name) { ice_channel *c; for (c=icec_channel_list; c; c=c->next) if (c->local && !str_cmp(c->local->name, name)) return c; return NULL; } void icec_localfree(ice_channel *c) { if (c->local) { imc_strfree(c->local->name); imc_strfree(c->local->format1); imc_strfree(c->local->format2); imc_free(c->local, sizeof(icec_lchannel)); c->local=NULL; } } /* need exactly 2 %s's, and no other format specifiers */ static bool verify_format(const char *fmt) { const char *c; int i=0; c=fmt; while((c=strchr(c, '%'))!=NULL) { if (*(c+1)=='%') /* %% */ { c+=2; continue; } if (*(c+1)!='s') /* not %s */ return FALSE; c++; i++; } if (i!=2) return FALSE; return TRUE; } DEFINE_DO_FUN(do_icommand) { #ifdef CIRCLE skip_spaces(&argument); #endif send_to_char(icec_command(ch->name, argument), ch); send_to_char("\n\r", ch); } DEFINE_DO_FUN(do_isetup) { char cmd[IMC_NAME_LENGTH]; char chan[IMC_NAME_LENGTH]; char arg1[IMC_DATA_LENGTH]; ice_channel *c; const char *a, *a1; #ifdef CIRCLE skip_spaces(&argument); #endif a=imc_getarg(argument, cmd, IMC_NAME_LENGTH); a=a1=imc_getarg(a, chan, IMC_NAME_LENGTH); a=imc_getarg(a, arg1, IMC_DATA_LENGTH); if (!cmd[0] || !chan[0]) { send_to_char("Syntax: isetup <command> <channel> [<data..>]\n\r", ch); return; } c=icec_findchannel(chan); if (!c) { c=icec_findlchannel(chan); if (!c) { send_to_char("Unknown channel.\n\r", ch); return; } } if (!strcasecmp(cmd, "add")) { char buf[IMC_DATA_LENGTH]; ice_channel *newc; if (c->local) { send_to_char("Channel is already active.\n\r", ch); return; } if (!arg1[0]) { send_to_char("Syntax: isetup add <channel> <local name>\n\r", ch); return; } c->local=imc_malloc(sizeof(*c->local)); c->local->name=imc_strdup(arg1); c->local->level=LEVEL_IMMORTAL; sprintf(buf, "(%s) %%s: %%s", arg1); c->local->format1=imc_strdup(buf); sprintf(buf, "(%s) %%s %%s", arg1); c->local->format2=imc_strdup(buf); imc_addname(&ch->pcdata->ice_listen, c->local->name); newc=imc_malloc(sizeof(*newc)); newc->name=imc_strdup(c->name); newc->local=imc_malloc(sizeof(*newc->local)); newc->local->name=imc_strdup(arg1); newc->local->level=LEVEL_IMMORTAL; newc->local->format1=imc_strdup(c->local->format1); newc->local->format2=imc_strdup(c->local->format2); newc->next=saved_channel_list; saved_channel_list=newc; send_to_char("Channel added.\n\r", ch); icec_save_channels(); return; } if (!c->local) { send_to_char("Channel is not locally configured, use 'isetup add' first.\n\r", ch); return; } if (!strcasecmp(cmd, "delete")) { ice_channel *saved, **last; for (last=&saved_channel_list, saved=*last; saved; saved=*last) { if (!strcasecmp(saved->local->name, c->local->name)) { icec_localfree(saved); imc_strfree(saved->name); *last=saved->next; imc_free(saved, sizeof(*saved)); } else last=&saved->next; } icec_localfree(c); send_to_char("Channel is no longer locally configured.\n\r", ch); icec_save_channels(); return; } if (!strcasecmp(cmd, "rename")) { if (!arg1[0]) { send_to_char("Syntax: isetup <channel> rename <newname>\n\r", ch); return; } if (icec_findlchannel(arg1)) { send_to_char("New channel name already exists.\n\r", ch); return; } imc_strfree(c->local->name); c->local->name=imc_strdup(arg1); send_to_char("Renamed ok.\n\r", ch); icec_save_channels(); return; } if (!strcasecmp(cmd, "format1")) { if (!a1[0]) { send_to_char("Syntax: isetup <channel> format1 <string>\n\r", ch); return; } if (!verify_format(a1)) { send_to_char("Bad format - must contain exactly 2 %s's.\n\r", ch); return; } imc_strfree(c->local->format1); c->local->format1=imc_strdup(a1); send_to_char("Format1 changed.\n\r", ch); icec_save_channels(); return; } if (!strcasecmp(cmd, "format2")) { if (!a1[0]) { send_to_char("Syntax: isetup <channel> format2 <string>\n\r", ch); return; } if (!verify_format(a1)) { send_to_char("Bad format - must contain exactly 2 %s's.\n\r", ch); return; } imc_strfree(c->local->format2); c->local->format2=imc_strdup(a1); send_to_char("Format2 changed.\n\r", ch); icec_save_channels(); return; } if (!strcasecmp(cmd, "level")) { if (!arg1[0]) { send_to_char("Syntax: isetup <channel> level <level>\n\r", ch); return; } if (atoi(arg1)<=0) { send_to_char("Positive level, please.\n\r", ch); return; } c->local->level=atoi(arg1); send_to_char("Level changed.\n\r", ch); icec_save_channels(); return; } send_to_char("Unknown command.\n\r" "Available commands: add delete rename format1 format2 level.\n\r", ch); } DEFINE_DO_FUN(do_ilist) { char buf[MAX_STRING_LENGTH]; ice_channel *c; if (argument[0]) { c=icec_findlchannel(argument); if (!c) c=icec_findchannel(argument); if (!c) { send_to_char("No such channel.\n\r", ch); return; } sprintf(buf, "Channel %s:\n" " Local name: %s\n" " Format 1: %s\n" " Format 2: %s\n" " Level: %d\n" "\n" " Policy: %s\n" " Owner: %s\n" " Operators: %s\n" " Invited: %s\n" " Excluded: %s\n", c->name, c->local ? c->local->name : "", c->local ? c->local->format1 : "", c->local ? c->local->format2 : "", c->local ? c->local->level : 0, c->policy == ICE_OPEN ? "open" : c->policy == ICE_CLOSED ? "closed" : "private", c->owner, c->operators, c->invited, c->excluded); send_to_char(buf, ch); return; } sprintf(buf, "%-15s %-15s %-15s %s\n\r", "Name", "Local name", "Owner", "Policy"); for (c=icec_channel_list; c; c=c->next) { sprintf(buf+strlen(buf), "%-15s %-15s %-15s %s\n\r", c->name, c->local ? c->local->name : "(not local)", c->owner, c->policy == ICE_OPEN ? "open" : c->policy == ICE_CLOSED ? "closed" : "private"); } for (c=saved_channel_list; c; c=c->next) { if (!icec_findchannel(c->name)) { sprintf(buf+strlen(buf), "%-15s %-15s %-15s %-7s (inactive)\n\r", c->name, c->local ? c->local->name : "(not local)", "", ""); } } page_to_char(buf, ch); } DEFINE_DO_FUN(do_ichannels) { char arg[MAX_STRING_LENGTH]; argument=one_argument(argument, arg); if (!arg[0]) { send_to_char("Currently tuned into:\n\r", ch); send_to_char(ch->pcdata->ice_listen, ch); send_to_char("\n\r", ch); return; } smash_tilde(arg); if (imc_hasname(ch->pcdata->ice_listen, arg)) { imc_removename(&ch->pcdata->ice_listen, arg); send_to_char("Removed.\n\r", ch); } else { if (!icec_findlchannel(arg)) { send_to_char("No such channel configured locally.\n\r", ch); return; } imc_addname(&ch->pcdata->ice_listen, arg); send_to_char("Added.\n\r", ch); } } void icec_showchannel(ice_channel *c, const char *from, const char *txt, int emote) { DESCRIPTOR_DATA *d, *dnext; CHAR_DATA *ch; char buf[MAX_STRING_LENGTH]; if (!c->local) return; sprintf(buf, emote ? c->local->format2 : c->local->format1, from, color_itom(txt)); strcat(buf, "\n\r"); for (d=descriptor_list; d; d=dnext) { dnext=d->next; ch=d->original ? d->original : d->character; if (!ch || IS_NPC(ch) || get_trust(ch) < c->local->level || !ice_audible(c, imc_makename(ch->name, imc_name)) || !imc_hasname(ch->pcdata->ice_listen, c->local->name)) continue; send_to_char(buf, ch); } } /* check for icec channels, return TRUE to stop command processing, FALSE otherwise */ bool icec_command_hook(CHAR_DATA *ch, const char *command, const char *argument) { ice_channel *c; char arg[MAX_STRING_LENGTH]; const char *word2; int emote=0; if (IS_NPC(ch)) return FALSE; #ifdef CIRCLE skip_spaces(&argument); #endif c=icec_findlchannel(command); if (!c || !c->local) return FALSE; if (c->local->level > get_trust(ch)) return FALSE; if (!imc_hasname(ch->pcdata->ice_listen, c->local->name)) return FALSE; if (!ice_audible(c, imc_makename(ch->name, imc_name))) { send_to_char("You cannot use that channel.\n\r", ch); return TRUE; } word2=imc_getarg(argument, arg, MAX_STRING_LENGTH); if (!arg[0]) { send_to_char("Use ichan to toggle the channel - or provide some text.\n\r", ch); return TRUE; } if (!str_cmp(arg, ",") || !str_cmp(arg, "emote")) { emote=1; argument=word2; } icec_sendmessage(c, ch->name, color_mtoi(argument), emote); return TRUE; } void icec_notify_update(ice_channel *c) { if (!c->local) { /* saved channel? */ ice_channel *saved; for (saved=saved_channel_list; saved; saved=saved->next) if (!strcasecmp(saved->name, c->name)) { c->local=imc_malloc(sizeof(icec_lchannel)); c->local->name=imc_strdup(saved->local->name); c->local->format1=imc_strdup(saved->local->format1); c->local->format2=imc_strdup(saved->local->format2); c->local->level=saved->local->level; return; } } }