From dee558f3ebe913895821c756e8cacd3d36307b84 Mon Sep 17 00:00:00 2001 From: Ari Johnson Date: Fri, 23 Feb 2007 01:11:55 +0000 Subject: [PATCH] cdesc(), cusers(), cmsgs(), cbuffer(), cstatus(), and clflags() --- game/txt/hlp/cobra_chat.hlp | 30 +++++- src/extchat.c | 177 +++++++++++++++++++++++++----------- src/function.c | 6 ++ win32/funs.h | 2 + 4 files changed, 161 insertions(+), 54 deletions(-) diff --git a/game/txt/hlp/cobra_chat.hlp b/game/txt/hlp/cobra_chat.hlp index 082f794..fbd6491 100644 --- a/game/txt/hlp/cobra_chat.hlp +++ b/game/txt/hlp/cobra_chat.hlp @@ -241,6 +241,25 @@ specific indirect lock instead of the default one: Returns 's @chan/title on . You must either be able to examine the object, or it must visible be on a channel which you are allowed to join. +& CSTATUS() + cstatus(,) + + Returns 's status with respect to , which may be + "Off", "On", or "Gag". You must either be able to examine the object, + or it must visible be on the channel; "Off" is returned for + objects that you can not see on the channel. +& CDESC() +& CUSERS() +& CMSGS() +& CBUFFER() + cdesc() + cusers() + cmsgs() + cbuffer() + + Return the description, number of users, number of messages, + or buffer size of , respectively. This information is + also displayed in @chan/list. & CWHO() cwho() @@ -255,8 +274,11 @@ specific indirect lock instead of the default one: If the third argument is a true value, the channel name will be prepended to the message, behaving like @cemit/noisy. & CFLAGS() +& CLFLAGS() cflags() cflags(,) + clflags() + clflags(,) With one argument, cflags() returns a list of flags set on the given channel, represented as a string of characters. See @@ -270,6 +292,9 @@ specific indirect lock instead of the default one: You must be able to see that channel and to examine the object to use this function. If the object is not on the channel, an error is returned. + + The clflags versions return a space-separated list of flag names, + rather than a string of flag characters. & CHANNELS() channels([]) channels() @@ -301,5 +326,6 @@ specific indirect lock instead of the default one: & Channel functions Channel functions work with the channel system. - cemit() cflags() channels() clock() cowner() - ctitle() cwho() + cbuffer() cdesc() cemit() cflags() channels() + clflags() clock() cmsgs() cowner() cstatus() + ctitle() cusers() cwho() diff --git a/src/extchat.c b/src/extchat.c index 40d2f93..d5da9a5 100644 --- a/src/extchat.c +++ b/src/extchat.c @@ -92,8 +92,7 @@ static enum cmatch_type find_channel_partial_on(const char *name, CHAN **chan, dbref player); static enum cmatch_type find_channel_partial_off(const char *name, CHAN **chan, dbref player); -static char *list_cflags(CHAN *c); -static char *list_cuflags(CHANUSER *u); +static char *list_cuflags(CHANUSER *u, int verbose); static void channel_join_self(dbref player, const char *name); static void channel_leave_self(dbref player, const char *name); static void do_channel_who(dbref player, CHAN *chan); @@ -144,6 +143,13 @@ static PRIV priv_table[] = { {NULL, '\0', 0, 0} }; +static PRIV chanuser_priv[] = { + {"Quiet", 'Q', CU_QUIET, CU_QUIET}, + {"Hide", 'H', CU_HIDE, CU_HIDE}, + {"Gag", 'G', CU_GAG, CU_GAG}, + {NULL, '\0', 0, 0} +}; + /** Get a player's CHANUSER entry if they're on a channel. * This function checks to see if a given player is on a given channel. @@ -2163,8 +2169,8 @@ do_channel_list(dbref player, const char *partname) CHANUSER *u; char numusers[BUFFER_LEN]; char cleanname[CHAN_NAME_LEN]; - const char thirtyblanks[31] = " "; char blanks[31]; + int len; int numblanks; if (SUPPORT_PUEBLO) @@ -2182,9 +2188,21 @@ do_channel_list(dbref player, const char *partname) TAG_START, TAG_END); else sprintf(numusers, "%5ld", ChanNumUsers(c)); - numblanks = strlen(ChanName(c)) - strlen(cleanname); - if (numblanks > 0 && numblanks < 31) { - strcpy(blanks, thirtyblanks); + /* Display length is strlen(cleanname), but actual length is + * strlen(ChanName(c)). There are two different cases: + * 1. actual length <= 30. No problems. + * 2. actual length > 30, we must reduce the number of + * blanks we add by the (actual length-30) because our + * %-30s is going to overflow as well. + */ + len = strlen(ChanName(c)); + numblanks = len - strlen(cleanname); + if (numblanks > 0 && numblanks < CHAN_NAME_LEN) { + memset(blanks, ' ', CHAN_NAME_LEN - 1); + if (len > 30) + numblanks -= (len - 30); + if (numblanks < 0) + numblanks = 0; blanks[numblanks] = '\0'; } else { blanks[0] = '\0'; @@ -2219,55 +2237,24 @@ do_channel_list(dbref player, const char *partname) } static char * -list_cflags(CHAN *c) +list_cuflags(CHANUSER *u, int verbose) { static char tbuf1[BUFFER_LEN]; char *bp; + /* We have to handle hide separately, since it can be the player */ bp = tbuf1; - if (Channel_Disabled(c)) - safe_chr('D', tbuf1, &bp); - if (Channel_Player(c)) - safe_chr('P', tbuf1, &bp); - if (Channel_Object(c)) - safe_chr('O', tbuf1, &bp); - if (Channel_Admin(c)) - safe_chr('A', tbuf1, &bp); - if (Channel_Director(c)) - safe_chr('W', tbuf1, &bp); - if (Channel_Quiet(c)) - safe_chr('Q', tbuf1, &bp); - if (Channel_CanHide(c)) - safe_chr('H', tbuf1, &bp); - if (Channel_Open(c)) - safe_chr('o', tbuf1, &bp); - if (Channel_NoTitles(c)) - safe_chr('T', tbuf1, &bp); - if (Channel_NoNames(c)) - safe_chr('N', tbuf1, &bp); - if (Channel_NoCemit(c)) - safe_chr('C', tbuf1, &bp); - if (Channel_Interact(c)) - safe_chr('I', tbuf1, &bp); - if(ChanType(c) & CHANNEL_COBJ) - safe_chr('Z', tbuf1, &bp); - *bp = '\0'; - return tbuf1; -} - -static char * -list_cuflags(CHANUSER *u) -{ - static char tbuf1[BUFFER_LEN]; - char *bp; - - bp = tbuf1; - if (Chanuser_Gag(u)) - safe_chr('G', tbuf1, &bp); - if (Chanuser_Quiet(u)) - safe_chr('Q', tbuf1, &bp); - if (Chanuser_Hide(u)) - safe_chr('H', tbuf1, &bp); + if (verbose) { + if (Chanuser_Hide(u)) + safe_str("Hide ", tbuf1, &bp); + safe_str(privs_to_string(chanuser_priv, CUtype(u) & ~CU_HIDE), tbuf1, &bp); + if (bp > tbuf1 && *bp == ' ') + bp--; + } else { + if (Chanuser_Hide(u)) + safe_chr('H', tbuf1, &bp); + safe_str(privs_to_letters(chanuser_priv, CUtype(u) & ~CU_HIDE), tbuf1, &bp); + } *bp = '\0'; return tbuf1; } @@ -2332,7 +2319,10 @@ FUNCTION(fun_cflags) return; } if (nargs == 1) { - safe_str(list_cflags(c), buff, bp); + if (string_prefix(called_as, "CL")) + safe_str(privs_to_string(priv_table, ChanType(c)), buff, bp); + else + safe_str(privs_to_letters(priv_table, ChanType(c)), buff, bp); return; } thing = match_thing(executor, args[1]); @@ -2349,11 +2339,43 @@ FUNCTION(fun_cflags) safe_str(T("#-1 NOT ON CHANNEL"), buff, bp); return; } - safe_str(list_cuflags(u), buff, bp); + safe_str(list_cuflags(u, string_prefix(called_as, "CL") ? 1 : 0), buff, bp); break; } } +/* ARGSUSED */ +FUNCTION(fun_cinfo) +{ + /* Can be called as CDESC, CBUFFER, CUSERS, CMSGS */ + CHAN *c; + if (!args[0] || !*args[0]) { + safe_str(T("#-1 NO CHANNEL GIVEN"), buff, bp); + return; + } + switch (find_channel(args[0], &c, executor)) { + case CMATCH_NONE: + safe_str(T("#-1 NO SUCH CHANNEL"), buff, bp); + return; + case CMATCH_AMBIG: + safe_str(T("#-1 AMBIGUOUS CHANNEL NAME"), buff, bp); + return; + default: + if (!Chan_Can_See(c, executor)) { + safe_str(T("#-1 NO SUCH CHANNEL"), buff, bp); + return; + } + if (string_prefix(called_as, "CD")) + safe_str(ChanTitle(c), buff, bp); + else if (string_prefix(called_as, "CB")) + safe_integer(BufferQSize(ChanBufferQ(c)), buff, bp); + else if (string_prefix(called_as, "CU")) + safe_integer(ChanNumUsers(c), buff, bp); + else if (string_prefix(called_as, "CM")) + safe_integer(ChanNumMsgs(c), buff, bp); + } +} + /* ARGSUSED */ FUNCTION(fun_ctitle) @@ -2413,6 +2435,57 @@ FUNCTION(fun_ctitle) } } +/* ARGSUSED */ +FUNCTION(fun_cstatus) +{ + /* cstatus(,) returns the object's status on that chan. + * You must pass the channel's see-lock, and + * either you must either be able to examine , or + * you must be Priv_Who or must not be hidden + */ + CHAN *c; + CHANUSER *u; + dbref thing; + + if (!args[0] || !*args[0]) { + safe_str(T("#-1 NO CHANNEL GIVEN"), buff, bp); + return; + } + switch (find_channel(args[0], &c, executor)) { + case CMATCH_NONE: + safe_str(T("#-1 NO SUCH CHANNEL"), buff, bp); + return; + case CMATCH_AMBIG: + safe_str(T("#-1 AMBIGUOUS CHANNEL NAME"), buff, bp); + return; + default: + thing = match_thing(executor, args[1]); + if (thing == NOTHING) { + safe_str(T(e_match), buff, bp); + return; + } + if (!Chan_Can_See(c, executor)) { + safe_str(T("#-1 NO SUCH CHANNEL"), buff, bp); + return; + } + u = onchannel(thing, c); + if (!u ||(!IsThing(thing) && !Connected(thing))) { + /* Easy, they're not on it or a disconnected player */ + safe_str("Off", buff, bp); + return; + } + /* They're on the channel, but maybe we can't see them? */ + if (Chanuser_Hide(u) && + !(Priv_Who(executor) || Can_Examine(executor, thing))) { + safe_str("Off", buff, bp); + return; + } + /* We can see them, so we report if they're On or Gag */ + safe_str(Chanuser_Gag(u) ? "Gag" : "On", buff, bp); + return; + } +} + FUNCTION(fun_cowner) { /* Return the dbref of the owner of a channel. */ diff --git a/src/function.c b/src/function.c index 2188e40..52afc12 100644 --- a/src/function.c +++ b/src/function.c @@ -306,12 +306,18 @@ FUNTAB flist[] = { {"CASEALL", fun_switch, 3, INT_MAX, FN_NOPARSE}, {"CAT", fun_cat, 1, INT_MAX, FN_REG}, #ifdef CHAT_SYSTEM + {"CBUFFER", fun_cinfo, 1, 1, FN_REG}, + {"CDESC", fun_cinfo, 1, 1, FN_REG}, {"CEMIT", fun_cemit, 2, 3, FN_REG}, {"CFLAGS", fun_cflags, 1, 2, FN_REG}, {"CHANNELS", fun_channels, 0, 2, FN_REG}, + {"CLFLAGS", fun_cflags, 1, 2, FN_REG}, {"CLOCK", fun_clock, 1, 2, FN_REG}, + {"CMSGS", fun_cinfo, 1, 1, FN_REG}, {"COWNER", fun_cowner, 1, 1, FN_REG}, + {"CSTATUS", fun_cinfo, 1, 1, FN_REG}, {"CTITLE", fun_ctitle, 2, 2, FN_REG}, + {"CUSERS", fun_cinfo, 1, 1, FN_REG}, {"CWHO", fun_cwho, 1, 1, FN_REG}, #endif /* CHAT_SYSTEM */ {"CENTER", fun_center, 2, 4, FN_REG}, diff --git a/win32/funs.h b/win32/funs.h index c7ef7cb..5870375 100644 --- a/win32/funs.h +++ b/win32/funs.h @@ -45,6 +45,7 @@ FUNCTION_PROTO(fun_channels); FUNCTION_PROTO(fun_checkknow); FUNCTION_PROTO(fun_checkpass); FUNCTION_PROTO(fun_chr); +FUNCTION_PROTO(fun_cinfo); FUNCTION_PROTO(fun_clock); FUNCTION_PROTO(fun_clone); FUNCTION_PROTO(fun_cmds); @@ -61,6 +62,7 @@ FUNCTION_PROTO(fun_cos); FUNCTION_PROTO(fun_cowner); FUNCTION_PROTO(fun_create); FUNCTION_PROTO(fun_crplog); +FUNCTION_PROTO(fun_cstatus); FUNCTION_PROTO(fun_ctime); FUNCTION_PROTO(fun_ctitle); FUNCTION_PROTO(fun_ctu); -- 2.30.2