mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 13:45:10 +00:00
[ADD] Filtering XMPP commands
This allows us to have commands apply to admins or MUCs only(which would help with many things I want to implement).
This commit is contained in:
parent
7c60ab28cb
commit
9a16d96323
9 changed files with 127 additions and 31 deletions
|
|
@ -55,7 +55,8 @@ parsee-config \
|
||||||
-H 'blow.hole' \ # Matrix homeserver name
|
-H 'blow.hole' \ # Matrix homeserver name
|
||||||
-J 'parsee.blow.hole' \ # XMPP component host, must be reachable
|
-J 'parsee.blow.hole' \ # XMPP component host, must be reachable
|
||||||
-s 'A very secure XMPP component secret' \
|
-s 'A very secure XMPP component secret' \
|
||||||
-p 5347
|
-p 5347 \
|
||||||
|
-M 65535 # Maximum stanza size. Stanzas larger than this from Parsee will be dropped to avoid stream closures. Leave this empty if you're unsure.
|
||||||
```
|
```
|
||||||
|
|
||||||
If everything goes well, it should generate a `parsee.json` file.
|
If everything goes well, it should generate a `parsee.json` file.
|
||||||
|
|
@ -72,7 +73,12 @@ Currently, the main sources of documentation are the Ayadocs(for headers) and th
|
||||||
|
|
||||||
## TODOS before 1.0 rolls around
|
## TODOS before 1.0 rolls around
|
||||||
- Make Parsee actually go *vroooooooooommmmmmm*.
|
- Make Parsee actually go *vroooooooooommmmmmm*.
|
||||||
|
- Make sure Parsee can easily run on just about any reasonable POSIX
|
||||||
|
system.
|
||||||
- Avoid making 'back-puppets' from Matrix as much as possible
|
- Avoid making 'back-puppets' from Matrix as much as possible
|
||||||
|
- Extension support. I'd need to design a good system, and maybe do it
|
||||||
|
with either shared libraries(`dlopen`/`dlclose` on POSIX) or use a
|
||||||
|
language like Janet or Lua.
|
||||||
- Add [libomemo](https://github.com/gkdr/libomemo) or something as an optional dependency.
|
- Add [libomemo](https://github.com/gkdr/libomemo) or something as an optional dependency.
|
||||||
- It depends on more stuff anyways, and I don't want to weigh down the
|
- It depends on more stuff anyways, and I don't want to weigh down the
|
||||||
dependency list of Parsee for that.
|
dependency list of Parsee for that.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
CODE=tomboyish-bridges-adventure
|
CODE=star-of-hope
|
||||||
NAME=Parsee
|
NAME=Parsee
|
||||||
VERSION=0.1.0
|
VERSION=0.2.0
|
||||||
BINARY=parsee
|
BINARY=parsee
|
||||||
SOURCE=src
|
SOURCE=src
|
||||||
INCLUDES=src/include
|
INCLUDES=src/include
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,13 @@ GetRandomQuote(void)
|
||||||
NAME ": the federated world's little little kobashi",
|
NAME ": the federated world's little little kobashi",
|
||||||
|
|
||||||
"Go take a look at your stanzas!",
|
"Go take a look at your stanzas!",
|
||||||
"Go take a look at your objects!"
|
"Go take a look at your objects!",
|
||||||
|
|
||||||
|
"DEC Alpha AXP-Certified!",
|
||||||
|
|
||||||
|
"this is the moment parsee started parsing or smth idk"
|
||||||
|
" - another wise person",
|
||||||
|
"Ah, merde, mon TGV est en retard de 53 minutes !"
|
||||||
};
|
};
|
||||||
const size_t count = sizeof(quotes)/sizeof(*quotes);
|
const size_t count = sizeof(quotes)/sizeof(*quotes);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,14 @@ struct XMPPCommandManager {
|
||||||
HashMap *sessions;
|
HashMap *sessions;
|
||||||
|
|
||||||
void *cookie;
|
void *cookie;
|
||||||
|
|
||||||
|
XMPPCmdFilter filter;
|
||||||
};
|
};
|
||||||
|
static bool
|
||||||
|
XMPPDefaultFilter(XMPPCommandManager *manager, char *id, XMLElement *stanza)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
static void
|
static void
|
||||||
XMPPDestroySession(XMPPSession *session)
|
XMPPDestroySession(XMPPSession *session)
|
||||||
{
|
{
|
||||||
|
|
@ -118,6 +125,7 @@ XMPPCreateManager(void *cookie)
|
||||||
ret->commands = HashMapCreate();
|
ret->commands = HashMapCreate();
|
||||||
ret->sessions = HashMapCreate();
|
ret->sessions = HashMapCreate();
|
||||||
ret->cookie = cookie;
|
ret->cookie = cookie;
|
||||||
|
ret->filter = XMPPDefaultFilter;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -161,12 +169,12 @@ XMPPFreeManager(XMPPCommandManager *manager)
|
||||||
Free(manager);
|
Free(manager);
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
XMPPShoveCommandList(XMPPCommandManager *m, char *jid, XMLElement *p)
|
XMPPShoveCommandList(XMPPCommandManager *m, char *jid, XMLElement *p, XMLElement *s)
|
||||||
{
|
{
|
||||||
char *node_name;
|
char *node_name;
|
||||||
XMPPCommand *val;
|
XMPPCommand *val;
|
||||||
XMLElement *item;
|
XMLElement *item;
|
||||||
if (!m || !p || !jid)
|
if (!m || !p || !jid || !s)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -174,11 +182,14 @@ XMPPShoveCommandList(XMPPCommandManager *m, char *jid, XMLElement *p)
|
||||||
pthread_mutex_lock(&m->lock);
|
pthread_mutex_lock(&m->lock);
|
||||||
while (HashMapIterate(m->commands, &node_name, (void **) &val))
|
while (HashMapIterate(m->commands, &node_name, (void **) &val))
|
||||||
{
|
{
|
||||||
item = XMLCreateTag("item");
|
if (m->filter(m, node_name, s))
|
||||||
XMLAddAttr(item, "jid", jid);
|
{
|
||||||
XMLAddAttr(item, "node", node_name);
|
item = XMLCreateTag("item");
|
||||||
XMLAddAttr(item, "name", XMPPGetCommandDesc(val));
|
XMLAddAttr(item, "jid", jid);
|
||||||
XMLAddChild(p, item);
|
XMLAddAttr(item, "node", node_name);
|
||||||
|
XMLAddAttr(item, "name", XMPPGetCommandDesc(val));
|
||||||
|
XMLAddChild(p, item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&m->lock);
|
pthread_mutex_unlock(&m->lock);
|
||||||
}
|
}
|
||||||
|
|
@ -206,6 +217,16 @@ XMPPVerifySession(XMPPCommandManager *mgr, char *s_id, char *from, char *to)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
XMPPManagerSetFilter(XMPPCommandManager *manager, XMPPCmdFilter filter)
|
||||||
|
{
|
||||||
|
if (!manager || !filter)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
manager->filter = filter;
|
||||||
|
}
|
||||||
bool
|
bool
|
||||||
XMPPManageCommand(XMPPCommandManager *m, XMLElement *stanza, ParseeData *data)
|
XMPPManageCommand(XMPPCommandManager *m, XMLElement *stanza, ParseeData *data)
|
||||||
{
|
{
|
||||||
|
|
@ -242,7 +263,7 @@ XMPPManageCommand(XMPPCommandManager *m, XMLElement *stanza, ParseeData *data)
|
||||||
/* This is an execution. */
|
/* This is an execution. */
|
||||||
cmd = HashMapGet(m->commands, node);
|
cmd = HashMapGet(m->commands, node);
|
||||||
|
|
||||||
if (!cmd)
|
if (!cmd || !m->filter(m, node, stanza))
|
||||||
{
|
{
|
||||||
/* TODO: Set an error note */
|
/* TODO: Set an error note */
|
||||||
goto end;
|
goto end;
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,49 @@ ParseeCongestion(void)
|
||||||
|
|
||||||
return congestion;
|
return congestion;
|
||||||
}
|
}
|
||||||
|
bool
|
||||||
|
XMPPCommandFilter(XMPPCommandManager *m, char *id, XMLElement *stanza)
|
||||||
|
{
|
||||||
|
ParseeData *args = XMPPGetManagerCookie(m);
|
||||||
|
char *trimmed_from;
|
||||||
|
char *from;
|
||||||
|
char *chat_id;
|
||||||
|
bool is_muc;
|
||||||
|
if (!m || !id || !stanza)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
from = HashMapGet(stanza->attrs, "from");
|
||||||
|
trimmed_from = ParseeTrimJID(from);
|
||||||
|
is_muc = !!(chat_id = ParseeGetFromMUCID(args, trimmed_from));
|
||||||
|
Free(trimmed_from);
|
||||||
|
Free(chat_id);
|
||||||
|
#define XMPP_COMMAND(f,l,n,t,s) \
|
||||||
|
if (StrEquals(n, id)) \
|
||||||
|
{ \
|
||||||
|
if (l == XMPPCMD_ALL) \
|
||||||
|
{ \
|
||||||
|
return true; \
|
||||||
|
} \
|
||||||
|
else if (l == XMPPCMD_MUC) \
|
||||||
|
{ \
|
||||||
|
return is_muc; \
|
||||||
|
} \
|
||||||
|
else if (l == XMPPCMD_ADMINS) \
|
||||||
|
{ \
|
||||||
|
bool is_admin; \
|
||||||
|
trimmed_from = ParseeTrimJID(from); \
|
||||||
|
is_admin = ParseeIsAdmin(args, trimmed_from); \
|
||||||
|
Free(trimmed_from); \
|
||||||
|
return is_admin; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
XMPPCOMMANDS
|
||||||
|
#undef XMPP_COMMAND
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
ParseeXMPPThread(void *argp)
|
ParseeXMPPThread(void *argp)
|
||||||
|
|
@ -143,9 +186,10 @@ ParseeXMPPThread(void *argp)
|
||||||
|
|
||||||
/* Initialise the managers, and add all handlers. */
|
/* Initialise the managers, and add all handlers. */
|
||||||
info.m = XMPPCreateManager(args);
|
info.m = XMPPCreateManager(args);
|
||||||
|
XMPPManagerSetFilter(info.m, XMPPCommandFilter);
|
||||||
{
|
{
|
||||||
XMPPCommand *cmd;
|
XMPPCommand *cmd;
|
||||||
#define XMPP_COMMAND(f,n,t,s) \
|
#define XMPP_COMMAND(f,l,n,t,s) \
|
||||||
cmd = XMPPBasicCmd( \
|
cmd = XMPPBasicCmd( \
|
||||||
n, t, f \
|
n, t, f \
|
||||||
); \
|
); \
|
||||||
|
|
|
||||||
|
|
@ -409,7 +409,7 @@ IQGet(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
|
||||||
XMLElement *q = XMLCreateTag("query");
|
XMLElement *q = XMLCreateTag("query");
|
||||||
XMLAddAttr(q, "xmlns", "http://jabber.org/protocol/disco#items");
|
XMLAddAttr(q, "xmlns", "http://jabber.org/protocol/disco#items");
|
||||||
XMLAddAttr(q, "node", "http://jabber.org/protocol/commands");
|
XMLAddAttr(q, "node", "http://jabber.org/protocol/commands");
|
||||||
XMPPShoveCommandList(thr->info->m, to, q);
|
XMPPShoveCommandList(thr->info->m, to, q, stanza);
|
||||||
XMLAddChild(iq_reply, q);
|
XMLAddChild(iq_reply, q);
|
||||||
}
|
}
|
||||||
XMPPSendStanza(jabber, iq_reply, args->config->max_stanza_size);
|
XMPPSendStanza(jabber, iq_reply, args->config->max_stanza_size);
|
||||||
|
|
|
||||||
|
|
@ -472,13 +472,13 @@ end_error:
|
||||||
reaction = ArrayGet(react_child, i);
|
reaction = ArrayGet(react_child, i);
|
||||||
react_data = ArrayGet(reaction->children, 0);
|
react_data = ArrayGet(reaction->children, 0);
|
||||||
|
|
||||||
event_id = LazySend(
|
Free(LazySend(
|
||||||
args, encoded, mroom_id, "m.reaction",
|
args, encoded, mroom_id, "m.reaction",
|
||||||
ShoveStanza(
|
ShoveStanza(
|
||||||
MatrixCreateReact(event_id, react_data->data),
|
MatrixCreateReact(event_id, react_data->data),
|
||||||
stanza
|
stanza
|
||||||
)
|
)
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
Free(event_id);
|
Free(event_id);
|
||||||
event_id = NULL;
|
event_id = NULL;
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ typedef struct XMPPCommand XMPPCommand;
|
||||||
typedef struct XMPPOption XMPPOption;
|
typedef struct XMPPOption XMPPOption;
|
||||||
typedef void (*XMPPCmdCallback)(XMPPCommandManager *, char *, XMLElement *, XMLElement *);
|
typedef void (*XMPPCmdCallback)(XMPPCommandManager *, char *, XMLElement *, XMLElement *);
|
||||||
typedef void (*XMPPOptionWriter)(XMPPCommandManager *, XMPPCommand *, char *);
|
typedef void (*XMPPOptionWriter)(XMPPCommandManager *, XMPPCommand *, char *);
|
||||||
|
typedef bool (*XMPPCmdFilter)(XMPPCommandManager *, char *id, XMLElement *stanza);
|
||||||
|
|
||||||
/** Creates a simple XMPP command manager, which routes commands
|
/** Creates a simple XMPP command manager, which routes commands
|
||||||
* with a single-stage form system, with a {cookie}
|
* with a single-stage form system, with a {cookie}
|
||||||
|
|
@ -19,16 +20,28 @@ typedef void (*XMPPOptionWriter)(XMPPCommandManager *, XMPPCommand *, char *);
|
||||||
* Returns: An opaque command manager[LA:HEAP]
|
* Returns: An opaque command manager[LA:HEAP]
|
||||||
* Modifies: NOTHING
|
* Modifies: NOTHING
|
||||||
* See-Also: XMPPFreeManager */
|
* See-Also: XMPPFreeManager */
|
||||||
extern XMPPCommandManager * XMPPCreateManager(void *cookie);
|
extern XMPPCommandManager * XMPPCreateManager(void *cookie);
|
||||||
extern void * XMPPGetManagerCookie(XMPPCommandManager *manager);
|
extern void * XMPPGetManagerCookie(XMPPCommandManager *manager);
|
||||||
|
|
||||||
|
/** Changes the filter used for the command manager. This function
|
||||||
|
* takes in the source stanza and the command "ID" to filter, and
|
||||||
|
* returns true IFF the command should be shown to the requester.
|
||||||
|
* -----------
|
||||||
|
* Returns: NOTHING
|
||||||
|
* Modifies: the manager's filter
|
||||||
|
* See-Also: XMPPCreateManager */
|
||||||
|
extern void
|
||||||
|
XMPPManagerSetFilter(XMPPCommandManager *manager, XMPPCmdFilter filter);
|
||||||
|
|
||||||
/** Create a basic command with a node and name description
|
/** Create a basic command with a node and name description
|
||||||
* -----------------------------------------------------
|
* -----------------------------------------------------
|
||||||
* Returns: A command to be used with {XMPPRegisterCommand}[LA:HEAP]
|
* Returns: A command to be used with {XMPPRegisterCommand}[LA:HEAP]
|
||||||
* Modifies: NOTHING
|
* Modifies: NOTHING
|
||||||
* See-Also: XMPPRegisterCommand */
|
* See-Also: XMPPRegisterCommand */
|
||||||
extern XMPPCommand * XMPPBasicCmd(char *node, char *name, XMPPCmdCallback cb);
|
extern XMPPCommand *
|
||||||
extern void XMPPCmdOptionsCreator(XMPPCommand *cmd, XMPPOptionWriter writer);
|
XMPPBasicCmd(char *node, char *name, XMPPCmdCallback cb);
|
||||||
|
extern void
|
||||||
|
XMPPCmdOptionsCreator(XMPPCommand *cmd, XMPPOptionWriter writer);
|
||||||
extern void XMPPAddOption(XMPPCommand *cmd, XMPPOption *opt);
|
extern void XMPPAddOption(XMPPCommand *cmd, XMPPOption *opt);
|
||||||
extern XMLElement * XMPPFormifyCommand(XMPPCommandManager *m, XMPPCommand *cmd, char *from);
|
extern XMLElement * XMPPFormifyCommand(XMPPCommandManager *m, XMPPCommand *cmd, char *from);
|
||||||
extern char * XMPPGetCommandNode(XMPPCommand *cmd);
|
extern char * XMPPGetCommandNode(XMPPCommand *cmd);
|
||||||
|
|
@ -71,11 +84,12 @@ extern bool XMPPVerifyForm(XMPPCommand *cmd, XMLElement *form);
|
||||||
extern void XMPPRegisterCommand(XMPPCommandManager *m, XMPPCommand *cmd);
|
extern void XMPPRegisterCommand(XMPPCommandManager *m, XMPPCommand *cmd);
|
||||||
|
|
||||||
/** Shoves all {m} commands into XML as children of {p}, and a {jid}
|
/** Shoves all {m} commands into XML as children of {p}, and a {jid}
|
||||||
|
* (and with the stanza source)
|
||||||
* -----------------------------------------------------
|
* -----------------------------------------------------
|
||||||
* Returns: NOTHING
|
* Returns: NOTHING
|
||||||
* Modifies: {p}
|
* Modifies: {p}
|
||||||
* See-Also: XMPPCreateManager */
|
* See-Also: XMPPCreateManager */
|
||||||
extern void XMPPShoveCommandList(XMPPCommandManager *m, char *jid, XMLElement *p);
|
extern void XMPPShoveCommandList(XMPPCommandManager *m, char *jid, XMLElement *p, XMLElement *s);
|
||||||
|
|
||||||
/** Destroys all memory related to the command {manager}.
|
/** Destroys all memory related to the command {manager}.
|
||||||
* -----------------------------------------------------
|
* -----------------------------------------------------
|
||||||
|
|
@ -95,7 +109,7 @@ extern bool XMPPManageCommand(XMPPCommandManager *m, XMLElement *stanza, ParseeD
|
||||||
/* --------------------------------- COMMANDS --------------------------------- */
|
/* --------------------------------- COMMANDS --------------------------------- */
|
||||||
/* Please edit stc/XMPPThread.c (you can just force-save) for these to apply! */
|
/* Please edit stc/XMPPThread.c (you can just force-save) for these to apply! */
|
||||||
|
|
||||||
#define XMPP_COMMAND(f,n,t,s) \
|
#define XMPP_COMMAND(f,l,n,t,s) \
|
||||||
extern void \
|
extern void \
|
||||||
f(XMPPCommandManager *, char *, XMLElement *, XMLElement *); \
|
f(XMPPCommandManager *, char *, XMLElement *, XMLElement *); \
|
||||||
/* This symbol might not exist. We do, however, not care, as
|
/* This symbol might not exist. We do, however, not care, as
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,15 @@
|
||||||
/* C X-macro file */
|
/* C X-macro file */
|
||||||
|
typedef enum XMPPCommandFlags {
|
||||||
|
XMPPCMD_ALL = 0,
|
||||||
|
XMPPCMD_MUC , /* Only for MUCs */
|
||||||
|
XMPPCMD_ADMINS /* Only for administrators */
|
||||||
|
} XMPPCommandFlags;
|
||||||
#define XMPPCOMMANDS \
|
#define XMPPCOMMANDS \
|
||||||
XMPP_COMMAND(StatusCallback, "stats", "Get Parsee statistics", {}) \
|
XMPP_COMMAND(StatusCallback, XMPPCMD_ALL, "stats", "Get Parsee statistics", {}) \
|
||||||
XMPP_COMMAND(CleanCallback, "clean", "Cleanup temporary Parsee data", {}) \
|
XMPP_COMMAND(CleanCallback, XMPPCMD_ADMINS, "clean", "Cleanup temporary Parsee data", {}) \
|
||||||
XMPP_COMMAND(AdminsCallback, "admin", "Get Parsee admin list", {}) \
|
XMPP_COMMAND(AdminsCallback, XMPPCMD_ALL, "admin", "Get Parsee admin list", {}) \
|
||||||
XMPP_COMMAND(NoflyCallback, "nofly", "Get Parsee nofly list", {}) \
|
XMPP_COMMAND(NoflyCallback, XMPPCMD_ADMINS, "nofly", "Get Parsee nofly list", {}) \
|
||||||
XMPP_COMMAND(AddAdminCallback, "add-admin", "Adds glob as admin", { \
|
XMPP_COMMAND(AddAdminCallback, XMPPCMD_ADMINS, "add-admin", "Adds glob as admin", { \
|
||||||
XMPPOption *glob = XMPPCreateText(true, "glob", ""); \
|
XMPPOption *glob = XMPPCreateText(true, "glob", ""); \
|
||||||
XMPPSetDescription(glob, "Glob pattern to set as admin"); \
|
XMPPSetDescription(glob, "Glob pattern to set as admin"); \
|
||||||
XMPPAddOption(cmd, glob); \
|
XMPPAddOption(cmd, glob); \
|
||||||
|
|
@ -12,12 +17,12 @@
|
||||||
XMPPSetFormTitle(cmd, "Admin addition form"); \
|
XMPPSetFormTitle(cmd, "Admin addition form"); \
|
||||||
XMPPSetFormInstruction(cmd, "Select a glob pattern to add as an admin"); \
|
XMPPSetFormInstruction(cmd, "Select a glob pattern to add as an admin"); \
|
||||||
}) \
|
}) \
|
||||||
XMPP_COMMAND(DelAdminCallback, "del-admin", "Removes glob from being admin", { \
|
XMPP_COMMAND(DelAdminCallback, XMPPCMD_ADMINS, "del-admin", "Removes glob from being admin", { \
|
||||||
XMPPCmdOptionsCreator(cmd, FormDelAdminCallback); \
|
XMPPCmdOptionsCreator(cmd, FormDelAdminCallback); \
|
||||||
XMPPSetFormTitle(cmd, "Admin removal form"); \
|
XMPPSetFormTitle(cmd, "Admin removal form"); \
|
||||||
XMPPSetFormInstruction(cmd, "Select a glob pattern to remove as an admin"); \
|
XMPPSetFormInstruction(cmd, "Select a glob pattern to remove as an admin"); \
|
||||||
}) \
|
}) \
|
||||||
XMPP_COMMAND(AddNoflyCallback, "add-nofly", "Adds user to nofly", { \
|
XMPP_COMMAND(AddNoflyCallback, XMPPCMD_ADMINS, "add-nofly", "Adds user to nofly", { \
|
||||||
XMPPOption *entity = XMPPCreateText(true, "entity", ""); \
|
XMPPOption *entity = XMPPCreateText(true, "entity", ""); \
|
||||||
XMPPOption *reason = XMPPCreateText(false, "reason", "Not behaving"); \
|
XMPPOption *reason = XMPPCreateText(false, "reason", "Not behaving"); \
|
||||||
XMPPSetDescription(entity, "Entity(glob) to no-fly"); \
|
XMPPSetDescription(entity, "Entity(glob) to no-fly"); \
|
||||||
|
|
@ -28,8 +33,8 @@
|
||||||
XMPPSetFormTitle(cmd, "No-fly addition form"); \
|
XMPPSetFormTitle(cmd, "No-fly addition form"); \
|
||||||
XMPPSetFormInstruction(cmd, "Select a glob pattern to add to the nofly"); \
|
XMPPSetFormInstruction(cmd, "Select a glob pattern to add to the nofly"); \
|
||||||
}) \
|
}) \
|
||||||
XMPP_COMMAND(ClearWhitelistCallback, "clear-wl", "Removes the chat whitelist", {}) \
|
XMPP_COMMAND(ClearWhitelistCallback, XMPPCMD_ADMINS, "clear-wl", "Removes the chat whitelist", {}) \
|
||||||
XMPP_COMMAND(AddWhitelistCallback, "add-wl", "Adds server to chat whitelist", { \
|
XMPP_COMMAND(AddWhitelistCallback, XMPPCMD_ADMINS, "add-wl", "Adds server to chat whitelist", { \
|
||||||
XMPPOption *serv = XMPPCreateText(true, "entity", ""); \
|
XMPPOption *serv = XMPPCreateText(true, "entity", ""); \
|
||||||
XMPPSetDescription(serv, "Server to mark as admin"); \
|
XMPPSetDescription(serv, "Server to mark as admin"); \
|
||||||
XMPPAddOption(cmd, serv); \
|
XMPPAddOption(cmd, serv); \
|
||||||
|
|
@ -37,6 +42,6 @@
|
||||||
XMPPSetFormTitle(cmd, "Chatlist addition form"); \
|
XMPPSetFormTitle(cmd, "Chatlist addition form"); \
|
||||||
XMPPSetFormInstruction(cmd, "Add a server to whitelist"); \
|
XMPPSetFormInstruction(cmd, "Add a server to whitelist"); \
|
||||||
}) \
|
}) \
|
||||||
XMPP_COMMAND(WhitelistCallback, "wl", "Get Parsee's chat whitelist", {}) \
|
XMPP_COMMAND(WhitelistCallback, XMPPCMD_ADMINS, "wl", "Get Parsee's chat whitelist", {}) \
|
||||||
|
|
||||||
XMPPCOMMANDS
|
XMPPCOMMANDS
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue