/*------------------------------------------------------------------ * 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 * @channel/buffer channel = <maxlines> * @channel/recall channel [= <lines>] * *------------------------------------------------------------------*/ #ifndef __EXTCHAT_H #define __EXTCHAT_H #include "boolexp.h" #include "bufferq.h" #define CU_TITLE_LEN 80 /** A channel user. * This structure represents an object joined to a chat channel. * Each chat channel maintains a linked list of users. */ struct chanuser { dbref who; /**< Dbref of joined object */ long int type; /**< Bitflags for this user */ char title[CU_TITLE_LEN]; /**< User's channel title */ struct chanuser *next; /**< Pointer to next user in list */ }; /* 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 /* channel_broadcast flags */ #define CB_CHECKQUIET 0x1 /* Check for quiet flag on recipients */ #define CB_NOSPOOF 0x2 /* Use nospoof emits */ #define CB_PRESENCE 0x4 /* This is a presence message, not sound */ #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) || (IsPlayer(CUdbref(u)) && 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 /** A chat channel. * This structure represents a MUSH chat channel. Channels are organized * into a sorted linked list. */ struct channel { char name[CHAN_NAME_LEN]; /**< Channel name */ char title[CHAN_TITLE_LEN]; /**< Channel description */ long int type; /**< Channel flags */ long int cost; /**< What it cost to make this channel */ 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 current users */ long int num_messages; /**< How many messages handled by this chan since startup */ boolexp joinlock; /**< Who may join */ boolexp speaklock; /**< Who may speak */ boolexp modifylock; /**< Who may change things and boot people */ boolexp seelock; /**< Who can see this in a list */ boolexp hidelock; /**< Who may hide from view */ struct channel *next; /**< Next channel in linked list */ BUFFERQ *bufferq; /**< Pointer to channel recall buffer queue */ }; /** A list of channels on an object. * This structure is a linked list of channels that is associated * with each object */ struct chanlist { CHAN *chan; /**< Channel data */ struct chanlist *next; /**< Next channel in list */ }; #define Chanlist(x) ((struct chanlist *)get_objdata(x, "CHANNELS")) #define s_Chanlist(x, y) set_objdata(x, "CHANNELS", (void *)y) /** A structure for passing channel data to notify_anything */ struct na_cpass { CHANUSER *u; /**< Pointer to channel user */ int checkquiet; /**< Should quiet property be checked? */ }; /* 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_OPEN 0x80 /* Can you speak if you're not joined? */ #define CHANNEL_NOTITLES 0x100 /* Don't show titles of speakers */ #define CHANNEL_NONAMES 0x200 /* Don't show names of speakers */ #define CHANNEL_NOCEMIT 0x400 /* Disallow @cemit */ #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 ChanBufferQ(c) ((c)->bufferq) #define Channel_Quiet(c) (ChanType(c) & CHANNEL_QUIET) #define Channel_Open(c) (ChanType(c) & CHANNEL_OPEN) #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 Channel_NoTitles(c) (ChanType(c) & CHANNEL_NOTITLES) #define Channel_NoNames(c) (ChanType(c) & CHANNEL_NONAMES) #define Channel_NoCemit(c) (ChanType(c) & CHANNEL_NOCEMIT) #define Chan_Ok_Type(c,o) \ ((IsPlayer(o) && Channel_Player(c)) || \ (IsThing(o) && Channel_Object(c))) #define Chan_Can(p,t) \ (!(t & CHANNEL_DISABLED) && (!(t & CHANNEL_WIZARD) || Wizard(p)) && \ (!(t & CHANNEL_ADMIN) || Hasprivs(p) || (has_power_by_name(p,"CHAT_PRIVS",NOTYPE)))) /* 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_chan_lock(c,p, CLOCK_JOIN))) #define Chan_Can_Speak(c,p) \ (Chan_Can_Access(c,p) && \ (eval_chan_lock(c,p, CLOCK_SPEAK))) #define Chan_Can_Cemit(c,p) \ (!Channel_NoCemit(c) && Chan_Can_Speak(c,p)) #define Chan_Can_Modify(c,p) \ (Wizard(p) || (ChanCreator(c) == (p)) || \ (!Guest(p) && Chan_Can_Access(c,p) && \ (eval_chan_lock(c,p, CLOCK_MOD)))) #define Chan_Can_See(c,p) \ (Hasprivs(p) || See_All(p) || (Chan_Can_Access(c,p) && \ (eval_chan_lock(c,p, CLOCK_SEE)))) #define Chan_Can_Hide(c,p) \ (Can_Hide(p) || (Channel_CanHide(c) && Chan_Can_Access(c,p) && \ (eval_chan_lock(c,p, CLOCK_HIDE)))) #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 */ enum cmatch_type { CMATCH_NONE, CMATCH_EXACT, CMATCH_PARTIAL, CMATCH_AMBIG }; #define CMATCHED(i) (((i) == CMATCH_EXACT) | ((i) == CMATCH_PARTIAL)) /* Some globals */ extern int num_channels; extern void WIN32_CDECL channel_broadcast (CHAN *channel, dbref player, int flags, const char *fmt, ...) __attribute__ ((__format__(__printf__, 4, 5))); 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, int noisy); 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); extern void do_chan_recall(dbref player, const char *name, const char *lines, int quiet); extern void do_chan_buffer(dbref player, const char *name, const char *lines); extern void init_chat(void); extern void do_channel (dbref player, const char *name, const char *target, const char *com); extern void do_chat(dbref player, CHAN *chan, const char *arg1); extern void do_chan_admin (dbref player, char *name, const char *perms, int flag); extern enum cmatch_type find_channel(const char *p, CHAN **chan, dbref player); extern enum cmatch_type find_channel_partial(const char *p, CHAN **chan, dbref player); extern void do_channel_list(dbref player, const char *partname); extern int do_chat_by_name (dbref player, const char *name, const char *msg, int source); extern void do_chan_decompile(dbref player, const char *name, int brief); extern void do_chan_chown(dbref player, const char *name, const char *newowner); extern const char *channel_description(dbref player); enum clock_type { CLOCK_JOIN, CLOCK_SPEAK, CLOCK_SEE, CLOCK_HIDE, CLOCK_MOD }; extern int eval_chan_lock(CHAN *c, dbref p, enum clock_type type); /** Ways to match channels by partial name */ enum chan_match_type { PMATCH_ALL, /**< Match all channels */ PMATCH_OFF, /**< Match channels user isn't on */ PMATCH_ON /**< Match channels user is on */ }; #endif /* __EXTCHAT_H */