pennmush/game/
pennmush/game/data/
pennmush/game/log/
pennmush/game/save/
pennmush/game/txt/evt/
pennmush/game/txt/nws/
pennmush/os2/
/*------------------------------------------------------------------
 * Header file for Javelin's extended @chat system
 * Based on the Battletech MUSE comsystem ported to PennMUSH by Kalkin
 *
 * Why:
 *  In the old system, channels were represented by bits set in a
 *  4-byte int on the db object. This had disadvantages - a limit
 *  of 32 channels, and players could find themselves on null channels.
 *  In addition, the old system required recompiles to permanently
 *  add channels, since the chaninfo was in the source.
 * How:
 *  Channels are a structure in a linked list.
 *  Each channel stores a whole bunch of info, including who's
 *  on it.
 *  We read/write this list using a chatdb file.
 *  We also maintain a linked list of channels that the user is
 *   connected to on the db object, which we set up at load time.
 *
 * User interface:
 * @chat channel = message
 * +channel message
 * @channel/on channel [= player] (or @channel channel = on)  do_channel()
 * @channel/off channel [= player] do_channel()
 * @channel/who channel do_channel()
 * @channel/title channel=title do_chan_title()
 * @channel/list do_chan_list()
 * @channel/add channel do_chan_admin()
 * @channel/priv channel = <privlist>  do_chan_admin()
 *  Privlist being: wizard, admin, private, moderated, etc.
 * @channel/joinlock channel = lock
 * @channel/speaklock channel = lock
 * @channel/modlock channel = lock
 * @channel/delete channel
 * @channel/quiet channel = yes/no
 * @channel/wipe channel
 *
 *------------------------------------------------------------------*/

#ifndef __EXTCHAT_H
#define __EXTCHAT_H

#ifdef CHAT_SYSTEM

#define CU_TITLE_LEN 80

/* This is a user - someone who's listening on a chat channel */
struct chanuser {
  dbref who;
  long int type;
  char title[CU_TITLE_LEN];
  struct chanuser *next;
};
typedef struct chanuser CHANUSER;

/* Flags and macros for channel users */
#define CU_QUIET    0x1		/* Do not hear connection messages */
#define CU_HIDE     0x2		/* Do not appear on the user list */
#define CU_GAG	    0x4		/* Do not hear any messages */
#define CU_DEFAULT_FLAGS 0x0

#define CUdbref(u) ((u)->who)
#define CUtype(u) ((u)->type)
#define CUtitle(u) ((u)->title)
#define CUnext(u) ((u)->next)
#define Chanuser_Quiet(u)	(CUtype(u) & CU_QUIET)
#define Chanuser_Hide(u) ((CUtype(u) & CU_HIDE) || hidden(CUdbref(u)))
#define Chanuser_Gag(u) (CUtype(u) & CU_GAG)

/* This is a chat channel */
#define CHAN_NAME_LEN 31
#define CHAN_TITLE_LEN 256
struct channel {
  char name[CHAN_NAME_LEN];	/* Channel name */
  char title[CHAN_TITLE_LEN];	/* Channel description */
  long int type;		/* Channel flags */
  long int cost;		/* Anyone can make a channel, but this is the cost */
  long int creator;		/* This is who paid the cost for the channel */
  long int num_users;		/* Number of connected users */
  long int max_users;		/* Maximum allocated users */
  struct chanuser *users;	/* Linked list of who is on */
  long int num_messages;	/* How many messages handled by this chan since startup */
  struct boolexp *joinlock;	/* Who may join */
  struct boolexp *speaklock;	/* Who may speak */
  struct boolexp *modifylock;	/* Who may change things and boot people */
  struct boolexp *seelock;	/* Who can see this in a list */
  struct boolexp *hidelock;	/* Who may hide from view */
  struct channel *next;		/* Next in linked list */
};
typedef struct channel CHAN;

struct chanlist {
  CHAN *chan;
  struct chanlist *next;
};
typedef struct chanlist CHANLIST;
#define Chanlist(x) db[(x)].channels

/* Channel type flags and macros */
#define CHANNEL_PLAYER  0x1	/* Players may join */
#define CHANNEL_OBJECT	0x2	/* Objects may join */
#define CHANNEL_DISABLED 0x4	/* Channel is turned off */
#define CHANNEL_QUIET	0x8	/* No broadcasts connect/disconnect */
#define CHANNEL_ADMIN   0x10	/* Wizard and royalty only ok */
#define CHANNEL_WIZARD  0x20	/* Wizard only ok */
#define CHANNEL_CANHIDE 0x40	/* Can non-DARK Wizards hide here? */
#define CHANNEL_DEFAULT_FLAGS	(CHANNEL_PLAYER)
#define CL_JOIN 0x1
#define CL_SPEAK 0x2
#define CL_MOD 0x4
#define CL_SEE 0x8
#define CL_HIDE 0x10
#define CHANNEL_COST (options.chan_cost)
#define MAX_PLAYER_CHANS (options.max_player_chans)
#define MAX_CHANNELS (options.max_channels)

#define ChanName(c) ((c)->name)
#define ChanType(c) ((c)->type)
#define ChanTitle(c) ((c)->title)
#define ChanCreator(c) ((c)->creator)
#define ChanCost(c) ((c)->cost)
#define ChanNumUsers(c) ((c)->num_users)
#define ChanMaxUsers(c) ((c)->max_users)
#define ChanUsers(c) ((c)->users)
#define ChanNext(c) ((c)->next)
#define ChanNumMsgs(c) ((c)->num_messages)
#define ChanJoinLock(c) ((c)->joinlock)
#define ChanSpeakLock(c) ((c)->speaklock)
#define ChanModLock(c) ((c)->modifylock)
#define ChanSeeLock(c) ((c)->seelock)
#define ChanHideLock(c) ((c)->hidelock)
#define Channel_Quiet(c)	(ChanType(c) & CHANNEL_QUIET)
#define Channel_Object(c) (ChanType(c) & CHANNEL_OBJECT)
#define Channel_Player(c) (ChanType(c) & CHANNEL_PLAYER)
#define Channel_Disabled(c) (ChanType(c) & CHANNEL_DISABLED)
#define Channel_Wizard(c) (ChanType(c) & CHANNEL_WIZARD)
#define Channel_Admin(c) (ChanType(c) & CHANNEL_ADMIN)
#define Channel_CanHide(c) (ChanType(c) & CHANNEL_CANHIDE)
#define Chan_Ok_Type(c,o) \
	(((Typeof(o) == TYPE_PLAYER) && Channel_Player(c)) || \
	 ((Typeof(o) == TYPE_THING) && Channel_Object(c)))
#define Chan_Can(p,t) \
     (!(t & CHANNEL_DISABLED) && (!(t & CHANNEL_WIZARD) || Wizard(p)) && \
      (!(t & CHANNEL_ADMIN) || Hasprivs(p) || (Powers(p) & CHAT_PRIVS)))
/* Who can change channel privileges to type t */
#define Chan_Can_Priv(p,t) (Wizard(p) || Chan_Can(p,t))
#define Chan_Can_Access(c,p) (Chan_Can(p,ChanType(c)))
#define Chan_Can_Join(c,p) \
     (Chan_Can_Access(c,p) && \
     (eval_boolexp(p,ChanJoinLock(c),p,0,"ChanJoinlock")))
#define Chan_Can_Speak(c,p) \
     (Chan_Can_Access(c,p) && \
     (eval_boolexp(p,ChanSpeakLock(c),p,0,"ChanSpeaklock")))
#define Chan_Can_Modify(c,p) \
     (Wizard(p) || (ChanCreator(c) == (p)) || \
     (!Guest(p) && Chan_Can_Access(c,p) && \
     (eval_boolexp(p,ChanModLock(c),p,0,"ChanModlock"))))
#define Chan_Can_See(c,p) \
     (Wizard(p) || (Chan_Can_Access(c,p) && \
     (eval_boolexp(p,ChanSeeLock(c),p,0,"ChanSeelock"))))
#define Chan_Can_Hide(c,p) \
     (Can_Hide(p) || (Channel_CanHide(c) && Chan_Can_Access(c,p) && \
     (eval_boolexp(p,ChanHideLock(c),p,0,"ChanHidelock"))))
#define Chan_Can_Nuke(c,p) (Wizard(p) || (ChanCreator(c) == (p)))
#define Chan_Can_Decomp(c,p) (See_All(p) || (ChanCreator(c) == (p)))



     /* For use in channel matching */
#define CMATCH_NONE 0
#define CMATCH_EXACT 1
#define CMATCH_PARTIAL 2
#define CMATCH_AMBIG 3
#define CMATCHED(i) (((i) == CMATCH_EXACT) | ((i) == CMATCH_PARTIAL))

     /* Some globals */
extern int num_channels;
extern void channel_broadcast _((CHAN *channel, int flags, const char *fmt,...));
extern CHANUSER *onchannel _((dbref who, CHAN *c));
extern void init_chatdb _((void));
extern int load_chatdb _((FILE * fp));
extern int save_chatdb _((FILE * fp));
extern void do_cemit _((dbref player, const char *name, const char *msg));
extern void do_chan_user_flags _((dbref player, char *name, const char *isyn, int flag, int silent));
extern void do_chan_wipe _((dbref player, const char *name));
extern void do_chan_lock _((dbref player, const char *name, const char *lockstr, int whichlock));
extern void do_chan_what _((dbref player, const char *partname));
extern void do_chan_desc _((dbref player, const char *name, const char *title));
extern void do_chan_title _((dbref player, const char *name, const char *title));

#endif				/* CHAT_SYSTEM */
#endif				/* __EXTCHAT_H */