*
* x3 is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* Restart X3 with the updated conf file (as above, butwith "bot"
* "IRC"), and bind the commands to it:
* /msg opserv bind IRC * *webtv.*
- * /msg opserv bind IRC set *webtv.set
*/
#include "chanserv.h"
#include "saxdb.h"
#include "timeq.h"
+#define MAX_CHANNELS_WHOIS 50
+
static const struct message_entry msgtab[] = {
- { "MSMSG_CANNOT_SEND", "You cannot send to account $b%s$b." },
+ { "WBMSG_NOT_MARKED", "You are not a WebTV client." },
+
+ { "WBMSG_NICK_PARAMS", "You need to specify a nickname." },
+ { "WBMSG_NICK_SAME", "You are already $b%s$b." },
+ { "WBMSG_NICK_INVALID", "The nickname $b%s$b is invalid." },
+ { "WBMSG_NICK_IN_USE", "The nickname $b%s$b is in use, please choose another." },
+
+ { "WBMSG_CHANNEL_BANNED", "You are banned on %s." },
+ { "WBMSG_CHANNEL_LIMIT", "%s has reached the maximum allowed chatters." },
+ { "WBMSG_CHANNEL_INVITE", "%s is invite only." },
+ { "WBMSG_CHANNEL_PASSWORD", "%s is password protected." },
+
+ { "WBMSG_WHOIS_NICKIDENT", "[%s] (%s@%s): %s" },
+ { "WBMSG_WHOIS_CHANNELS", "On %s" },
+ { "WBMSG_WHOIS_SERVER", "[%s] %s : %s" },
+ { "WBMSG_WHOIS_OPER", "[%s] is an IRC Operator" },
+ { "WBMSG_WHOIS_SERVICE", "[%s] is an IRC Service" },
+ { "WBMSG_WHOIS_ACCOUNT", "[%s] is logged in as %s" },
+ { "WBMSG_WHOIS_REALHOST", "[%s] realhost %s@%s %s" },
+ { "WBMSG_WHOIS_SWHOIS", "[%s] %s" },
+ { "WBMSG_WHOIS_DNSBL", "[%s] is DNSBL listed on %s" },
+ { "WBMSG_WHOIS_CONNECTED", "[%s] %s" },
+ { "WBMSG_WHOIS_END", "[%s] End of WHOIS list." },
+
+ { "WBMSG_ALREADY_JOINED", "I am already in $b%s$b." },
+ { "WBMSG_JOIN_DONE", "I have joined $b%s$b." },
{ NULL, NULL }
};
static struct {
struct userNode *bot;
+ int required_mark;
+ struct string_list *valid_marks;
} webtv_conf;
#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[])
const char *webtv_module_deps[] = { NULL };
static struct module *webtv_module;
static struct log_type *WB_LOG;
+static char *his_servername;
+static char *his_servercomment;
+
+
+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[]))
+{
+ unsigned int y = 0;
+
+ if ((webtv_conf.required_mark == 0) || IsOper(user))
+ return 1;
+ else {
+ if (!user->mark) {
+ reply("WBMSG_NOT_MARKED");
+ return 0;
+ }
+ for (y = 0; y < webtv_conf.valid_marks->used; y++) {
+ if (!strcasecmp(webtv_conf.valid_marks->list[y], user->mark))
+ return 1;
+ }
+ reply("WBMSG_NOT_MARKED");
+ return 0;
+ }
+}
+
+static MODCMD_FUNC(cmd_nick)
+{
+ struct userNode *nick;
+
+ if (!check_mark(cmd, user, NULL, 0, 0, NULL))
+ return 0;
+
+ if (argc < 2) {
+ reply("WBMSG_NICK_PARAMS");
+ return 0;
+ }
+
+ if (!strcasecmp(argv[1], user->nick)) {
+ reply("WBMSG_NICK_SAME", argv[1]);
+ return 0;
+ }
+
+ if (!is_valid_nick(argv[1])) {
+ reply("WBMSG_NICK_INVALID", argv[1]);
+ return 0;
+ }
+
+ nick = GetUserH(argv[1]);
+ if (nick) {
+ reply("WBMSG_NICK_IN_USE", argv[1]);
+ return 0;
+ }
+
+ irc_svsnick(webtv, user, argv[1]);
+ return 1;
+}
+
+void
+webtv_ison(struct userNode *bot, struct userNode *tell, struct userNode *target, const char *message)
+{
+ struct modeNode *mn;
+ unsigned int count, here_len, n, maxlen;
+ char buff[MAXLEN];
+
+ maxlen = tell->handle_info ? tell->handle_info->screen_width : 0;
+ if (!maxlen)
+ maxlen = MAX_LINE_SIZE;
+ for (n=count=0; n<target->channels.used; n++) {
+ mn = target->channels.list[n];
+ if ((mn->channel->modes & (MODE_PRIVATE|MODE_SECRET)))
+ continue;
+
+ here_len = strlen(mn->channel->name);
+ if ((count + here_len + 4) > maxlen) {
+ buff[count] = 0;
+ send_message(tell, bot, message, buff);
+ count = 0;
+ }
+ if (mn->modes & MODE_CHANOP)
+ buff[count++] = '@';
+ if (mn->modes & MODE_HALFOP)
+ buff[count++] = '%';
+ if (mn->modes & MODE_VOICE)
+ buff[count++] = '+';
+ memcpy(buff+count, mn->channel->name, here_len);
+ count += here_len;
+ buff[count++] = ' ';
+ }
+ if (count) {
+ buff[count] = 0;
+ send_message(tell, bot, message, buff);
+ }
+}
+
+static MODCMD_FUNC(cmd_whois)
+{
+ struct userNode *target;
+
+ if (!check_mark(cmd, user, NULL, 0, 0, NULL))
+ return 0;
+
+ if (argc < 2) {
+ reply("WBMSG_NICK_PARAMS");
+ return 0;
+ }
+
+ target = GetUserH(argv[1]);
+ if (target) {
+ reply("WBMSG_WHOIS_NICKIDENT", target->nick, target->ident,
+ IsFakeHost(target) ? target->fakehost : target->hostname, target->info);
+
+ if ((target->channels.used <= MAX_CHANNELS_WHOIS) && !IsService(target))
+ webtv_ison(cmd->parent->bot, user, target, "WBMSG_WHOIS_CHANNELS");
+
+ if (target == user)
+ reply("WBMSG_WHOIS_SERVER", target->nick, target->uplink->name, target->uplink->description);
+ else {
+ reply("WBMSG_WHOIS_SERVER", target->nick, his_servername ? his_servername : target->uplink->name,
+ his_servercomment ? his_servercomment : target->uplink->description);
+ }
+
+ if (IsOper(target))
+ reply("WBMSG_WHOIS_OPER", target->nick);
+
+ if (IsService(target))
+ reply("WBMSG_WHOIS_SERVICE", target->nick);
+
+ if (target->handle_info)
+ reply("WBMSG_WHOIS_ACCOUNT", target->nick, target->handle_info->handle);
+
+ if ((target == user) && (target->fakehost || IsHiddenHost(target)))
+ reply("WBMSG_WHOIS_REALHOST", target->nick, target->ident, target->hostname, irc_ntoa(&target->ip));
+
+ if (target->handle_info) {
+ if (target->handle_info->epithet)
+ reply("WBMSG_WHOIS_SWHOIS", target->nick, target->handle_info->epithet);
+ }
+
+ if (target->mark)
+ reply("WBMSG_WHOIS_DNSBL", target->nick, target->mark);
+ reply("WBMSG_WHOIS_END", target->nick);
+ } else {
+ reply("MSG_NICK_UNKNOWN", argv[1]);
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+part_all_channels(struct userNode *target)
+{
+ unsigned int n=0;
+ struct modeNode *mn;
+
+ for (n=0; n<target->channels.used; n++) {
+ mn = target->channels.list[n];
+ irc_svspart(webtv, target, mn->channel);
+ }
+
+ return;
+}
+
+static MODCMD_FUNC(cmd_sjoin)
+{
+ struct userNode *bot = cmd->parent->bot;
+
+ if (!IsChannelName(argv[1])) {
+ reply("MSG_NOT_CHANNEL_NAME");
+ return 0;
+ } else if (!(channel = GetChannel(argv[1]))) {
+ channel = AddChannel(argv[1], now, NULL, NULL, NULL);
+ AddChannelUser(bot, channel)->modes |= MODE_CHANOP;
+ } else if (GetUserMode(channel, bot)) {
+ reply("WBMSG_ALREADY_JOINED", channel->name);
+ return 0;
+ } else {
+ struct mod_chanmode change;
+ mod_chanmode_init(&change);
+ change.argc = 1;
+ change.args[0].mode = MODE_CHANOP;
+ change.args[0].u.member = AddChannelUser(bot, channel);
+ modcmd_chanmode_announce(&change);
+ }
+ irc_fetchtopic(bot, channel->name);
+ reply("WBMSG_JOIN_DONE", channel->name);
+ return 1;
+}
+
+static MODCMD_FUNC(cmd_join)
+{
+ struct chanNode *target;
+
+ if (!check_mark(cmd, user, NULL, 0, 0, NULL))
+ return 0;
+
+ if(!(target = GetChannel(argv[1])))
+ {
+ reply("MSG_INVALID_CHANNEL");
+ return 0;
+ }
+
+ if (trace_check_bans(user, target) == 1) {
+ reply("WBMSG_CHANNEL_BANNED", argv[1]);
+ return 0;
+ }
+ if (target->modes & MODE_INVITEONLY) {
+ reply("WBMSG_CHANNEL_INVITE", argv[1]);
+ return 0;
+ }
+ if (target->limit > 0) {
+ if (target->members.used >= target->limit) {
+ reply("WBMSG_CHANNEL_LIMIT", argv[1]);
+ return 0;
+ }
+ }
+ if (*target->key) {
+ if (argc > 2) {
+ if (strcmp(argv[2], target->key)) {
+ reply("WBMSG_CHANNEL_PASSWORD", argv[1]);
+ return 0;
+ }
+ } else {
+ reply("WBMSG_CHANNEL_PASSWORD", argv[1]);
+ return 0;
+ }
+ }
+
+ part_all_channels(user);
+ irc_svsjoin(webtv, user, target);
+ return 1;
+}
+
+static MODCMD_FUNC(cmd_part)
+{
+ struct mod_chanmode change;
+ struct chanNode *target;
+
+ if (!check_mark(cmd, user, NULL, 0, 0, NULL))
+ return 0;
+
+ if(!(target = GetChannel(argv[1])))
+ {
+ reply("MSG_INVALID_CHANNEL");
+ return 0;
+ }
+
+ mod_chanmode_init(&change);
+ change.argc = 1;
+ change.args[0].u.member = GetUserMode(target, user);
+ if(!change.args[0].u.member)
+ {
+ if(argc)
+ reply("MSG_CHANNEL_ABSENT", target->name);
+ return 0;
+ }
+
+ irc_svspart(webtv, user, target);
+ return 1;
+}
static void
webtv_conf_read(void)
{
dict_t conf_node;
const char *str;
+ struct string_list *strlist;
str = "modules/webtv";
if (!(conf_node = conf_get_data(str, RECDB_OBJECT))) {
log_module(WB_LOG, LOG_ERROR, "config node `%s' is missing or has wrong type.", str);
return;
}
+
+ str = database_get_data(conf_node, "required_mark", RECDB_QSTRING);
+ webtv_conf.required_mark = str ? atoi(str) : 0;
+
+ free_string_list(webtv_conf.valid_marks);
+ strlist = database_get_data(conf_node, "valid_marks", RECDB_STRING_LIST);
+ if(strlist)
+ strlist = string_list_copy(strlist);
+ else
+ strlist = alloc_string_list(4);
+ webtv_conf.valid_marks = strlist;
+
+ str = conf_get_data("server/his_servername", RECDB_QSTRING);
+ his_servername = str ? strdup(str) : NULL;
+ str = conf_get_data("server/his_servercomment", RECDB_QSTRING);
+ his_servercomment = str ? strdup(str) : NULL;
}
static void
reg_exit_func(webtv_cleanup);
webtv_module = module_register("WebTV", WB_LOG, "mod-webtv.help", NULL);
-/*
- modcmd_register(webtv_module, "send", cmd_send, 3, MODCMD_REQUIRE_AUTHED, NULL);
- modcmd_register(webtv_module, "expire", cmd_expire, 1, MODCMD_REQUIRE_AUTHED, "flags", "+oper", NULL);
-*/
+ modcmd_register(webtv_module, "nick", cmd_nick, 1, 0, NULL);
+ modcmd_register(webtv_module, "join", cmd_join, 1, 0, NULL);
+ modcmd_register(webtv_module, "part", cmd_part, 1, 0, NULL);
+ modcmd_register(webtv_module, "whois", cmd_whois, 1, 0, NULL);
+
+ modcmd_register(webtv_module, "sjoin", cmd_sjoin, 1, MODCMD_REQUIRE_AUTHED, "flags", "+oper", NULL);
+
message_register_table(msgtab);
return 1;
}