]>
jfr.im git - irc/evilnet/x3.git/blob - src/mod-webtv.c
1 /* mod-webtv.c - WebTV Module for X3
2 * Copyright 2007 X3 Development Team
4 * This file is part of x3.
6 * x3 is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with srvx; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
23 * /msg opserv bind opserv service *modcmd.joiner
24 * /msg opserv bind opserv service\ add *modcmd.service\ add
25 * /msg opserv bind opserv service\ rename *modcmd.service\ rename
26 * /msg opserv bind opserv service\ trigger *modcmd.service\ trigger
27 * /msg opserv bind opserv service\ remove *modcmd.service\ remove
29 * /msg opserv service add IRC WebTV Service Bot
30 * /msg opserv bind IRC help *modcmd.help
31 * Restart X3 with the updated conf file (as above, butwith "bot"
32 * "IRC"), and bind the commands to it:
33 * /msg opserv bind IRC * *webtv.*
44 #define MAX_CHANNELS_WHOIS 50
46 static const struct message_entry msgtab
[] = {
47 { "WBMSG_NOT_MARKED", "You are not a WebTV client." },
49 { "WBMSG_NICK_PARAMS", "You need to specify a nickname." },
50 { "WBMSG_NICK_SAME", "You are already $b%s$b." },
51 { "WBMSG_NICK_INVALID", "The nickname $b%s$b is invalid." },
52 { "WBMSG_NICK_IN_USE", "The nickname $b%s$b is in use, please choose another." },
54 { "WBMSG_CHANNEL_BANNED", "You are banned on %s." },
55 { "WBMSG_CHANNEL_LIMIT", "%s has reached the maximum allowed chatters." },
56 { "WBMSG_CHANNEL_INVITE", "%s is invite only." },
57 { "WBMSG_CHANNEL_PASSWORD", "%s is password protected." },
59 { "WBMSG_WHOIS_NICKIDENT", "[%s] (%s@%s): %s" },
60 { "WBMSG_WHOIS_CHANNELS", "On %s" },
61 { "WBMSG_WHOIS_SERVER", "[%s] %s : %s" },
62 { "WBMSG_WHOIS_OPER", "[%s] is an IRC Operator" },
63 { "WBMSG_WHOIS_SERVICE", "[%s] is an IRC Service" },
64 { "WBMSG_WHOIS_ACCOUNT", "[%s] is logged in as %s" },
65 { "WBMSG_WHOIS_REALHOST", "[%s] realhost %s@%s %s" },
66 { "WBMSG_WHOIS_SWHOIS", "[%s] %s" },
67 { "WBMSG_WHOIS_DNSBL", "[%s] is DNSBL listed on %s" },
68 { "WBMSG_WHOIS_CONNECTED", "[%s] %s" },
69 { "WBMSG_WHOIS_END", "[%s] End of WHOIS list." },
71 { "WBMSG_ALREADY_JOINED", "I am already in $b%s$b." },
72 { "WBMSG_JOIN_DONE", "I have joined $b%s$b." },
77 struct userNode
*webtv
;
79 #define WEBTV_FUNC(NAME) MODCMD_FUNC(NAME)
80 #define WEBTV_SYNTAX() svccmd_send_help_brief(user, webtv, cmd)
81 #define WEBTV_MIN_PARAMS(N) if(argc < (N)) { \
82 reply("MSG_MISSING_PARAMS", argv[0]); \
89 struct string_list
*valid_marks
;
92 #define OPTION_FUNC(NAME) int NAME(struct svccmd *cmd, struct userNode *user, struct handle_info *hi, UNUSED_ARG(unsigned int override), unsigned int argc, char *argv[])
93 typedef OPTION_FUNC(option_func_t
);
95 extern struct string_list
*autojoin_channels
;
96 const char *webtv_module_deps
[] = { NULL
};
97 static struct module *webtv_module
;
98 static struct log_type
*WB_LOG
;
99 static char *his_servername
;
100 static char *his_servercomment
;
103 int check_mark(struct svccmd
*cmd
, struct userNode
*user
, UNUSED_ARG(struct handle_info
*hi
), UNUSED_ARG(unsigned int override
), UNUSED_ARG(unsigned int argc
), UNUSED_ARG(char *argv
[]))
107 if ((webtv_conf
.required_mark
== 0) || IsOper(user
))
111 reply("WBMSG_NOT_MARKED");
114 for (y
= 0; y
< webtv_conf
.valid_marks
->used
; y
++) {
115 if (!strcasecmp(webtv_conf
.valid_marks
->list
[y
], user
->mark
))
118 reply("WBMSG_NOT_MARKED");
123 static MODCMD_FUNC(cmd_nick
)
125 struct userNode
*nick
;
127 if (!check_mark(cmd
, user
, NULL
, 0, 0, NULL
))
131 reply("WBMSG_NICK_PARAMS");
135 if (!strcasecmp(argv
[1], user
->nick
)) {
136 reply("WBMSG_NICK_SAME", argv
[1]);
140 if (!is_valid_nick(argv
[1])) {
141 reply("WBMSG_NICK_INVALID", argv
[1]);
145 nick
= GetUserH(argv
[1]);
147 reply("WBMSG_NICK_IN_USE", argv
[1]);
151 irc_svsnick(webtv
, user
, argv
[1]);
156 webtv_ison(struct userNode
*bot
, struct userNode
*tell
, struct userNode
*target
, const char *message
)
159 unsigned int count
, here_len
, n
, maxlen
;
162 maxlen
= tell
->handle_info
? tell
->handle_info
->screen_width
: 0;
164 maxlen
= MAX_LINE_SIZE
;
165 for (n
=count
=0; n
<target
->channels
.used
; n
++) {
166 mn
= target
->channels
.list
[n
];
167 if ((mn
->channel
->modes
& (MODE_PRIVATE
|MODE_SECRET
)))
170 here_len
= strlen(mn
->channel
->name
);
171 if ((count
+ here_len
+ 4) > maxlen
) {
173 send_message(tell
, bot
, message
, buff
);
176 if (mn
->modes
& MODE_CHANOP
)
178 if (mn
->modes
& MODE_HALFOP
)
180 if (mn
->modes
& MODE_VOICE
)
182 memcpy(buff
+count
, mn
->channel
->name
, here_len
);
188 send_message(tell
, bot
, message
, buff
);
192 static MODCMD_FUNC(cmd_whois
)
194 struct userNode
*target
;
196 if (!check_mark(cmd
, user
, NULL
, 0, 0, NULL
))
200 reply("WBMSG_NICK_PARAMS");
204 target
= GetUserH(argv
[1]);
206 reply("WBMSG_WHOIS_NICKIDENT", target
->nick
, target
->ident
,
207 IsFakeHost(target
) ? target
->fakehost
: target
->hostname
, target
->info
);
209 if ((target
->channels
.used
<= MAX_CHANNELS_WHOIS
) && !IsService(target
))
210 webtv_ison(cmd
->parent
->bot
, user
, target
, "WBMSG_WHOIS_CHANNELS");
213 reply("WBMSG_WHOIS_SERVER", target
->nick
, target
->uplink
->name
, target
->uplink
->description
);
215 reply("WBMSG_WHOIS_SERVER", target
->nick
, his_servername
? his_servername
: target
->uplink
->name
,
216 his_servercomment
? his_servercomment
: target
->uplink
->description
);
220 reply("WBMSG_WHOIS_OPER", target
->nick
);
222 if (IsService(target
))
223 reply("WBMSG_WHOIS_SERVICE", target
->nick
);
225 if (target
->handle_info
)
226 reply("WBMSG_WHOIS_ACCOUNT", target
->nick
, target
->handle_info
->handle
);
228 if ((target
== user
) && (target
->fakehost
|| IsHiddenHost(target
)))
229 reply("WBMSG_WHOIS_REALHOST", target
->nick
, target
->ident
, target
->hostname
, irc_ntoa(&target
->ip
));
231 if (target
->handle_info
) {
232 if (target
->handle_info
->epithet
)
233 reply("WBMSG_WHOIS_SWHOIS", target
->nick
, target
->handle_info
->epithet
);
237 reply("WBMSG_WHOIS_DNSBL", target
->nick
, target
->mark
);
239 reply("WBMSG_WHOIS_END", target
->nick
);
241 reply("MSG_NICK_UNKNOWN", argv
[1]);
249 part_all_channels(struct userNode
*target
)
254 for (n
=0; n
<target
->channels
.used
; n
++) {
255 mn
= target
->channels
.list
[n
];
256 irc_svspart(webtv
, target
, mn
->channel
);
262 static MODCMD_FUNC(cmd_sjoin
)
264 struct userNode
*bot
= cmd
->parent
->bot
;
266 if (!IsChannelName(argv
[1])) {
267 reply("MSG_NOT_CHANNEL_NAME");
269 } else if (!(channel
= GetChannel(argv
[1]))) {
270 channel
= AddChannel(argv
[1], now
, NULL
, NULL
, NULL
);
271 AddChannelUser(bot
, channel
)->modes
|= MODE_CHANOP
;
272 } else if (GetUserMode(channel
, bot
)) {
273 reply("WBMSG_ALREADY_JOINED", channel
->name
);
276 struct mod_chanmode change
;
277 mod_chanmode_init(&change
);
279 change
.args
[0].mode
= MODE_CHANOP
;
280 change
.args
[0].u
.member
= AddChannelUser(bot
, channel
);
281 modcmd_chanmode_announce(&change
);
283 irc_fetchtopic(bot
, channel
->name
);
284 reply("WBMSG_JOIN_DONE", channel
->name
);
288 static MODCMD_FUNC(cmd_join
)
290 struct chanNode
*target
;
292 if (!check_mark(cmd
, user
, NULL
, 0, 0, NULL
))
295 if(!(target
= GetChannel(argv
[1])))
297 reply("MSG_INVALID_CHANNEL");
301 if (trace_check_bans(user
, target
) == 1) {
302 reply("WBMSG_CHANNEL_BANNED", argv
[1]);
306 if (target
->modes
& MODE_INVITEONLY
) {
307 reply("WBMSG_CHANNEL_INVITE", argv
[1]);
312 if (target
->limit
> 0) {
313 if (target
->members
.used
>= target
->limit
) {
314 reply("WBMSG_CHANNEL_LIMIT", argv
[1]);
322 if (strcmp(argv
[2], target
->key
)) {
323 reply("WBMSG_CHANNEL_PASSWORD", argv
[1]);
327 reply("WBMSG_CHANNEL_PASSWORD", argv
[1]);
332 part_all_channels(user
);
333 irc_svsjoin(webtv
, user
, target
);
337 static MODCMD_FUNC(cmd_part
)
339 struct mod_chanmode change
;
340 struct chanNode
*target
;
342 if (!check_mark(cmd
, user
, NULL
, 0, 0, NULL
))
345 if(!(target
= GetChannel(argv
[1])))
347 reply("MSG_INVALID_CHANNEL");
351 mod_chanmode_init(&change
);
353 change
.args
[0].u
.member
= GetUserMode(target
, user
);
354 if(!change
.args
[0].u
.member
)
357 reply("MSG_CHANNEL_ABSENT", target
->name
);
361 irc_svspart(webtv
, user
, target
);
366 webtv_conf_read(void)
370 struct string_list
*strlist
;
372 str
= "modules/webtv";
373 if (!(conf_node
= conf_get_data(str
, RECDB_OBJECT
))) {
374 log_module(WB_LOG
, LOG_ERROR
, "config node `%s' is missing or has wrong type.", str
);
378 str
= database_get_data(conf_node
, "required_mark", RECDB_QSTRING
);
379 webtv_conf
.required_mark
= str
? atoi(str
) : 0;
381 free_string_list(webtv_conf
.valid_marks
);
382 strlist
= database_get_data(conf_node
, "valid_marks", RECDB_STRING_LIST
);
384 strlist
= string_list_copy(strlist
);
386 strlist
= alloc_string_list(4);
387 webtv_conf
.valid_marks
= strlist
;
389 str
= conf_get_data("server/his_servername", RECDB_QSTRING
);
390 his_servername
= str
? strdup(str
) : NULL
;
391 str
= conf_get_data("server/his_servercomment", RECDB_QSTRING
);
392 his_servercomment
= str
? strdup(str
) : NULL
;
403 WB_LOG
= log_register_type("WebTV", "file:webtv.log");
405 conf_register_reload(webtv_conf_read
);
406 reg_exit_func(webtv_cleanup
);
408 webtv_module
= module_register("WebTV", WB_LOG
, "mod-webtv.help", NULL
);
409 modcmd_register(webtv_module
, "nick", cmd_nick
, 1, 0, NULL
);
410 modcmd_register(webtv_module
, "join", cmd_join
, 1, 0, NULL
);
411 modcmd_register(webtv_module
, "part", cmd_part
, 1, 0, NULL
);
412 modcmd_register(webtv_module
, "whois", cmd_whois
, 1, 0, NULL
);
414 modcmd_register(webtv_module
, "sjoin", cmd_sjoin
, 1, MODCMD_REQUIRE_AUTHED
, "flags", "+oper", NULL
);
416 message_register_table(msgtab
);
421 webtv_finalize(void) {
422 struct chanNode
*chan
;
427 str
= "modules/webtv";
428 if (!(conf_node
= conf_get_data(str
, RECDB_OBJECT
))) {
429 log_module(WB_LOG
, LOG_ERROR
, "config node `%s' is missing or has wrong type.", str
);
433 str
= database_get_data(conf_node
, "bot", RECDB_QSTRING
);
435 webtv
= webtv_conf
.bot
;
436 const char *modes
= conf_get_data("modules/webtv/modes", RECDB_QSTRING
);
437 webtv
= AddService(str
, modes
? modes
: NULL
, "WebTV IRC Service", NULL
);
439 log_module(WB_LOG
, LOG_ERROR
, "database_get_data for webtv_conf.bot failed!");
443 if (autojoin_channels
&& webtv
) {
444 for (i
= 0; i
< autojoin_channels
->used
; i
++) {
445 chan
= AddChannel(autojoin_channels
->list
[i
], now
, "+nt", NULL
, NULL
);
446 AddChannelUser(webtv
, chan
)->modes
|= MODE_CHANOP
;