| 1 | /*------------------------------------------------------------------ |
|---|
| 2 | * Header file for Javelin's extended @chat system |
|---|
| 3 | * Based on the Battletech MUSE comsystem ported to PennMUSH by Kalkin |
|---|
| 4 | * |
|---|
| 5 | * Why: |
|---|
| 6 | * In the old system, channels were represented by bits set in a |
|---|
| 7 | * 4-byte int on the db object. This had disadvantages - a limit |
|---|
| 8 | * of 32 channels, and players could find themselves on null channels. |
|---|
| 9 | * In addition, the old system required recompiles to permanently |
|---|
| 10 | * add channels, since the chaninfo was in the source. |
|---|
| 11 | * How: |
|---|
| 12 | * Channels are a structure in a linked list. |
|---|
| 13 | * Each channel stores a whole bunch of info, including who's |
|---|
| 14 | * on it. |
|---|
| 15 | * We read/write this list using a chatdb file. |
|---|
| 16 | * We also maintain a linked list of channels that the user is |
|---|
| 17 | * connected to on the db object, which we set up at load time. |
|---|
| 18 | * |
|---|
| 19 | * User interface: |
|---|
| 20 | * @chat channel = message |
|---|
| 21 | * +channel message |
|---|
| 22 | * @channel/on channel [= player] (or @channel channel = on) do_channel() |
|---|
| 23 | * @channel/off channel [= player] do_channel() |
|---|
| 24 | * @channel/who channel do_channel() |
|---|
| 25 | * @channel/title channel=title do_chan_title() |
|---|
| 26 | * @channel/list do_chan_list() |
|---|
| 27 | * @channel/add channel do_chan_admin() |
|---|
| 28 | * @channel/priv channel = <privlist> do_chan_admin() |
|---|
| 29 | * Privlist being: wizard, admin, private, moderated, etc. |
|---|
| 30 | * @channel/joinlock channel = lock |
|---|
| 31 | * @channel/speaklock channel = lock |
|---|
| 32 | * @channel/modlock channel = lock |
|---|
| 33 | * @channel/delete channel |
|---|
| 34 | * @channel/quiet channel = yes/no |
|---|
| 35 | * @channel/wipe channel |
|---|
| 36 | * @channel/buffer channel = <maxlines> |
|---|
| 37 | * @channel/recall channel [= <lines>] |
|---|
| 38 | * |
|---|
| 39 | *------------------------------------------------------------------*/ |
|---|
| 40 | |
|---|
| 41 | #ifndef __EXTCHAT_H |
|---|
| 42 | #define __EXTCHAT_H |
|---|
| 43 | |
|---|
| 44 | |
|---|
| 45 | #include "boolexp.h" |
|---|
| 46 | #include "bufferq.h" |
|---|
| 47 | |
|---|
| 48 | #define CU_TITLE_LEN 80 |
|---|
| 49 | |
|---|
| 50 | /** A channel user. |
|---|
| 51 | * This structure represents an object joined to a chat channel. |
|---|
| 52 | * Each chat channel maintains a linked list of users. |
|---|
| 53 | */ |
|---|
| 54 | struct chanuser { |
|---|
| 55 | dbref who; /**< Dbref of joined object */ |
|---|
| 56 | privbits type; /**< Bitflags for this user */ |
|---|
| 57 | char title[CU_TITLE_LEN]; /**< User's channel title */ |
|---|
| 58 | struct chanuser *next; /**< Pointer to next user in list */ |
|---|
| 59 | }; |
|---|
| 60 | |
|---|
| 61 | /* Flags and macros for channel users */ |
|---|
| 62 | #define CU_QUIET 0x1 /* Do not hear connection messages */ |
|---|
| 63 | #define CU_HIDE 0x2 /* Do not appear on the user list */ |
|---|
| 64 | #define CU_GAG 0x4 /* Do not hear any messages */ |
|---|
| 65 | #define CU_DEFAULT_FLAGS 0x0 |
|---|
| 66 | |
|---|
| 67 | /* channel_broadcast flags */ |
|---|
| 68 | #define CB_CHECKQUIET 0x1 /* Check for quiet flag on recipients */ |
|---|
| 69 | #define CB_NOSPOOF 0x2 /* Use nospoof emits */ |
|---|
| 70 | #define CB_PRESENCE 0x4 /* This is a presence message, not sound */ |
|---|
| 71 | |
|---|
| 72 | #define CUdbref(u) ((u)->who) |
|---|
| 73 | #define CUtype(u) ((u)->type) |
|---|
| 74 | #define CUtitle(u) ((u)->title) |
|---|
| 75 | #define CUnext(u) ((u)->next) |
|---|
| 76 | #define Chanuser_Quiet(u) (CUtype(u) & CU_QUIET) |
|---|
| 77 | #define Chanuser_Hide(u) ((CUtype(u) & CU_HIDE) || (IsPlayer(CUdbref(u)) && hidden(CUdbref(u)))) |
|---|
| 78 | #define Chanuser_Gag(u) (CUtype(u) & CU_GAG) |
|---|
| 79 | |
|---|
| 80 | /* This is a chat channel */ |
|---|
| 81 | #define CHAN_NAME_LEN 31 |
|---|
| 82 | #define CHAN_TITLE_LEN 256 |
|---|
| 83 | /** A chat channel. |
|---|
| 84 | * This structure represents a MUSH chat channel. Channels are organized |
|---|
| 85 | * into a sorted linked list. |
|---|
| 86 | */ |
|---|
| 87 | struct channel { |
|---|
| 88 | char name[CHAN_NAME_LEN]; /**< Channel name */ |
|---|
| 89 | char title[CHAN_TITLE_LEN]; /**< Channel description */ |
|---|
| 90 | privbits type; /**< Channel flags */ |
|---|
| 91 | int cost; /**< What it cost to make this channel */ |
|---|
| 92 | dbref creator; /**< This is who paid the cost for the channel */ |
|---|
| 93 | int num_users; /**< Number of connected users */ |
|---|
| 94 | int max_users; /**< Maximum allocated users */ |
|---|
| 95 | struct chanuser *users; /**< Linked list of current users */ |
|---|
| 96 | unsigned long int num_messages; /**< How many messages handled by this chan since startup */ |
|---|
| 97 | boolexp joinlock; /**< Who may join */ |
|---|
| 98 | boolexp speaklock; /**< Who may speak */ |
|---|
| 99 | boolexp modifylock; /**< Who may change things and boot people */ |
|---|
| 100 | boolexp seelock; /**< Who can see this in a list */ |
|---|
| 101 | boolexp hidelock; /**< Who may hide from view */ |
|---|
| 102 | struct channel *next; /**< Next channel in linked list */ |
|---|
| 103 | BUFFERQ *bufferq; /**< Pointer to channel recall buffer queue */ |
|---|
| 104 | }; |
|---|
| 105 | |
|---|
| 106 | /** A list of channels on an object. |
|---|
| 107 | * This structure is a linked list of channels that is associated |
|---|
| 108 | * with each object |
|---|
| 109 | */ |
|---|
| 110 | struct chanlist { |
|---|
| 111 | CHAN *chan; /**< Channel data */ |
|---|
| 112 | struct chanlist *next; /**< Next channel in list */ |
|---|
| 113 | }; |
|---|
| 114 | |
|---|
| 115 | #define Chanlist(x) ((struct chanlist *)get_objdata(x, "CHANNELS")) |
|---|
| 116 | #define s_Chanlist(x, y) set_objdata(x, "CHANNELS", (void *)y) |
|---|
| 117 | |
|---|
| 118 | /** A structure for passing channel data to notify_anything */ |
|---|
| 119 | struct na_cpass { |
|---|
| 120 | CHANUSER *u; /**< Pointer to channel user */ |
|---|
| 121 | bool checkquiet; /**< Should quiet property be checked? */ |
|---|
| 122 | }; |
|---|
| 123 | |
|---|
| 124 | |
|---|
| 125 | /* Channel type flags and macros */ |
|---|
| 126 | #define CHANNEL_PLAYER 0x1U /* Players may join */ |
|---|
| 127 | #define CHANNEL_OBJECT 0x2U /* Objects may join */ |
|---|
| 128 | #define CHANNEL_DISABLED 0x4U /* Channel is turned off */ |
|---|
| 129 | #define CHANNEL_QUIET 0x8U /* No broadcasts connect/disconnect */ |
|---|
| 130 | #define CHANNEL_ADMIN 0x10U /* Wizard and royalty only ok */ |
|---|
| 131 | #define CHANNEL_WIZARD 0x20U /* Wizard only ok */ |
|---|
| 132 | #define CHANNEL_CANHIDE 0x40U /* Can non-DARK Wizards hide here? */ |
|---|
| 133 | #define CHANNEL_OPEN 0x80U /* Can you speak if you're not joined? */ |
|---|
| 134 | #define CHANNEL_NOTITLES 0x100U /* Don't show titles of speakers */ |
|---|
| 135 | #define CHANNEL_NONAMES 0x200U /* Don't show names of speakers */ |
|---|
| 136 | #define CHANNEL_NOCEMIT 0x400U /* Disallow @cemit */ |
|---|
| 137 | #define CHANNEL_INTERACT 0x800U /* Filter channel output through interactions */ |
|---|
| 138 | #define CHANNEL_DEFAULT_FLAGS (CHANNEL_PLAYER) |
|---|
| 139 | #define CL_JOIN 0x1 |
|---|
| 140 | #define CL_SPEAK 0x2 |
|---|
| 141 | #define CL_MOD 0x4 |
|---|
| 142 | #define CL_SEE 0x8 |
|---|
| 143 | #define CL_HIDE 0x10 |
|---|
| 144 | #define CHANNEL_COST (options.chan_cost) |
|---|
| 145 | #define MAX_PLAYER_CHANS (options.max_player_chans) |
|---|
| 146 | #define MAX_CHANNELS (options.max_channels) |
|---|
| 147 | |
|---|
| 148 | #define ChanName(c) ((c)->name) |
|---|
| 149 | #define ChanType(c) ((c)->type) |
|---|
| 150 | #define ChanTitle(c) ((c)->title) |
|---|
| 151 | #define ChanCreator(c) ((c)->creator) |
|---|
| 152 | #define ChanCost(c) ((c)->cost) |
|---|
| 153 | #define ChanNumUsers(c) ((c)->num_users) |
|---|
| 154 | #define ChanMaxUsers(c) ((c)->max_users) |
|---|
| 155 | #define ChanUsers(c) ((c)->users) |
|---|
| 156 | #define ChanNext(c) ((c)->next) |
|---|
| 157 | #define ChanNumMsgs(c) ((c)->num_messages) |
|---|
| 158 | #define ChanJoinLock(c) ((c)->joinlock) |
|---|
| 159 | #define ChanSpeakLock(c) ((c)->speaklock) |
|---|
| 160 | #define ChanModLock(c) ((c)->modifylock) |
|---|
| 161 | #define ChanSeeLock(c) ((c)->seelock) |
|---|
| 162 | #define ChanHideLock(c) ((c)->hidelock) |
|---|
| 163 | #define ChanBufferQ(c) ((c)->bufferq) |
|---|
| 164 | #define Channel_Quiet(c) (ChanType(c) & CHANNEL_QUIET) |
|---|
| 165 | #define Channel_Open(c) (ChanType(c) & CHANNEL_OPEN) |
|---|
| 166 | #define Channel_Object(c) (ChanType(c) & CHANNEL_OBJECT) |
|---|
| 167 | #define Channel_Player(c) (ChanType(c) & CHANNEL_PLAYER) |
|---|
| 168 | #define Channel_Disabled(c) (ChanType(c) & CHANNEL_DISABLED) |
|---|
| 169 | #define Channel_Wizard(c) (ChanType(c) & CHANNEL_WIZARD) |
|---|
| 170 | #define Channel_Admin(c) (ChanType(c) & CHANNEL_ADMIN) |
|---|
| 171 | #define Channel_CanHide(c) (ChanType(c) & CHANNEL_CANHIDE) |
|---|
| 172 | #define Channel_NoTitles(c) (ChanType(c) & CHANNEL_NOTITLES) |
|---|
| 173 | #define Channel_NoNames(c) (ChanType(c) & CHANNEL_NONAMES) |
|---|
| 174 | #define Channel_NoCemit(c) (ChanType(c) & CHANNEL_NOCEMIT) |
|---|
| 175 | #define Channel_Interact(c) (ChanType(c) & CHANNEL_INTERACT) |
|---|
| 176 | #define Chan_Ok_Type(c,o) \ |
|---|
| 177 | ((IsPlayer(o) && Channel_Player(c)) || \ |
|---|
| 178 | (IsThing(o) && Channel_Object(c))) |
|---|
| 179 | #define Chan_Can(p,t) \ |
|---|
| 180 | (!(t & CHANNEL_DISABLED) && (!(t & CHANNEL_WIZARD) || Wizard(p)) && \ |
|---|
| 181 | (!(t & CHANNEL_ADMIN) || Hasprivs(p) || (has_power_by_name(p,"CHAT_PRIVS",NOTYPE)))) |
|---|
| 182 | /* Who can change channel privileges to type t */ |
|---|
| 183 | #define Chan_Can_Priv(p,t) (Wizard(p) || Chan_Can(p,t)) |
|---|
| 184 | #define Chan_Can_Access(c,p) (Chan_Can(p,ChanType(c))) |
|---|
| 185 | #define Chan_Can_Join(c,p) \ |
|---|
| 186 | (Chan_Can_Access(c,p) && \ |
|---|
| 187 | (eval_chan_lock(c,p, CLOCK_JOIN))) |
|---|
| 188 | #define Chan_Can_Speak(c,p) \ |
|---|
| 189 | (Chan_Can_Access(c,p) && \ |
|---|
| 190 | (eval_chan_lock(c,p, CLOCK_SPEAK))) |
|---|
| 191 | #define Chan_Can_Cemit(c,p) \ |
|---|
| 192 | (!Channel_NoCemit(c) && Chan_Can_Speak(c,p)) |
|---|
| 193 | #define Chan_Can_Modify(c,p) \ |
|---|
| 194 | (Wizard(p) || (ChanCreator(c) == (p)) || \ |
|---|
| 195 | (!Guest(p) && Chan_Can_Access(c,p) && \ |
|---|
| 196 | (eval_chan_lock(c,p, CLOCK_MOD)))) |
|---|
| 197 | #define Chan_Can_See(c,p) \ |
|---|
| 198 | (Hasprivs(p) || See_All(p) || (Chan_Can_Access(c,p) && \ |
|---|
| 199 | (eval_chan_lock(c,p, CLOCK_SEE)))) |
|---|
| 200 | #define Chan_Can_Hide(c,p) \ |
|---|
| 201 | (Can_Hide(p) || (Channel_CanHide(c) && Chan_Can_Access(c,p) && \ |
|---|
| 202 | (eval_chan_lock(c,p, CLOCK_HIDE)))) |
|---|
| 203 | #define Chan_Can_Nuke(c,p) (Wizard(p) || (ChanCreator(c) == (p))) |
|---|
| 204 | #define Chan_Can_Decomp(c,p) (See_All(p) || (ChanCreator(c) == (p))) |
|---|
| 205 | |
|---|
| 206 | |
|---|
| 207 | |
|---|
| 208 | /* For use in channel matching */ |
|---|
| 209 | enum cmatch_type { CMATCH_NONE, CMATCH_EXACT, CMATCH_PARTIAL, CMATCH_AMBIG }; |
|---|
| 210 | #define CMATCHED(i) (((i) == CMATCH_EXACT) | ((i) == CMATCH_PARTIAL)) |
|---|
| 211 | |
|---|
| 212 | /* Some globals */ |
|---|
| 213 | extern int num_channels; |
|---|
| 214 | extern void WIN32_CDECL channel_chat |
|---|
| 215 | (CHAN *channel, dbref player, int flags, const char *message, char type, |
|---|
| 216 | const char *fmt, ...) |
|---|
| 217 | __attribute__ ((__format__(__printf__, 6, 7))); |
|---|
| 218 | extern CHANUSER *onchannel(dbref who, CHAN *c); |
|---|
| 219 | extern void init_chatdb(void); |
|---|
| 220 | extern int load_chatdb(FILE * fp); |
|---|
| 221 | extern int save_chatdb(FILE * fp); |
|---|
| 222 | extern void do_cemit |
|---|
| 223 | (dbref player, const char *name, const char *msg, int flags); |
|---|
| 224 | extern void do_chan_user_flags |
|---|
| 225 | (dbref player, char *name, const char *isyn, int flag, int silent); |
|---|
| 226 | extern void do_chan_wipe(dbref player, const char *name); |
|---|
| 227 | extern void do_chan_lock |
|---|
| 228 | (dbref player, const char *name, const char *lockstr, int whichlock); |
|---|
| 229 | extern void do_chan_what(dbref player, const char *partname); |
|---|
| 230 | extern void do_chan_desc(dbref player, const char *name, const char *title); |
|---|
| 231 | extern void do_chan_title(dbref player, const char *name, const char *title); |
|---|
| 232 | extern void do_chan_recall(dbref player, const char *name, char *lineinfo[], |
|---|
| 233 | int quiet); |
|---|
| 234 | extern void do_chan_buffer(dbref player, const char *name, const char *lines); |
|---|
| 235 | extern void init_chat(void); |
|---|
| 236 | extern void do_channel |
|---|
| 237 | (dbref player, const char *name, const char *target, const char *com); |
|---|
| 238 | extern void do_chat(dbref player, CHAN *chan, const char *arg1); |
|---|
| 239 | extern void do_chan_admin |
|---|
| 240 | (dbref player, char *name, const char *perms, int flag); |
|---|
| 241 | extern enum cmatch_type find_channel(const char *p, CHAN **chan, dbref player); |
|---|
| 242 | extern enum cmatch_type find_channel_partial(const char *p, CHAN **chan, |
|---|
| 243 | dbref player); |
|---|
| 244 | extern void do_channel_list(dbref player, const char *partname); |
|---|
| 245 | extern int do_chat_by_name |
|---|
| 246 | (dbref player, const char *name, const char *msg, int source); |
|---|
| 247 | extern void do_chan_decompile(dbref player, const char *name, int brief); |
|---|
| 248 | extern void do_chan_chown(dbref player, const char *name, const char *newowner); |
|---|
| 249 | extern const char *channel_description(dbref player); |
|---|
| 250 | |
|---|
| 251 | enum clock_type { CLOCK_JOIN, CLOCK_SPEAK, CLOCK_SEE, CLOCK_HIDE, CLOCK_MOD }; |
|---|
| 252 | extern int eval_chan_lock(CHAN *c, dbref p, enum clock_type type); |
|---|
| 253 | |
|---|
| 254 | /** Ways to match channels by partial name */ |
|---|
| 255 | enum chan_match_type { |
|---|
| 256 | PMATCH_ALL, /**< Match all channels */ |
|---|
| 257 | PMATCH_OFF, /**< Match channels user isn't on */ |
|---|
| 258 | PMATCH_ON /**< Match channels user is on */ |
|---|
| 259 | }; |
|---|
| 260 | |
|---|
| 261 | |
|---|
| 262 | #endif /* __EXTCHAT_H */ |
|---|