#include "main.h"
-#define SOCKET_FLAG_DEAD 0x01
#define SOCKET_FLAG_CONNECTED 0x02
#define SOCKET_FLAG_READY 0x04
#define SOCKET_FLAG_PREFERRED 0x08 /* prefered bot to send datas to the IRC World (NOTICE's WHO's etc pp) */
#define SOCKET_FLAG_USE_QUEUE 0x10
#define SOCKET_FLAG_RECONNECT 0x20
#define SOCKET_FLAG_SSL 0x40
-#define SOCKET_FLAG_HAVE_SSL 0x80
-#define SOCKET_FLAG_QUITTED 0x100
+
#define SOCKET_FLAG_FAST_JUMP 0x200
#define SOCKET_FLAG_SILENT 0x400
#define SOCKET_FLAG_CHANGENICK 0x800
#define SOCKET_FLAG_REQUEST_INVITE 0x1000
#define SOCKET_FLAG_REQUEST_OP 0x2000
+ #define SOCKET_FLAG_SECRET_BOT 0x4000
#define SOCKET_HAVE_BOTCLASSVALUE1 0x10000000
#define SOCKET_HAVE_BOTCLASSVALUE2 0x20000000
struct UserNode;
struct trigger_cache;
-struct SSLConnection;
+struct IODescriptor;
struct ClientSocket {
- int sock;
+ struct IODescriptor *iofd;
unsigned int flags;
- char buffer[BUF_SIZ*2]; //we need to store up to 2 full commands at once
- unsigned int bufferpos;
char *host;
int port;
char *bind;
unsigned long traffic_in;
unsigned long traffic_out;
time_t connection_time;
- struct SSLConnection *sslconn;
struct BotQueue *queue;
#ifndef DND_FUNCTIONS
/* MODULAR ACCESSIBLE */ struct ClientSocket* create_socket(char *host, int port, char *bindto, char *pass, char *nick, char *ident, char *realname);
-/* MODULAR ACCESSIBLE */ int connect_socket(struct ClientSocket *client);
+/* MODULAR ACCESSIBLE */ void connect_socket(struct ClientSocket *client);
/* MODULAR ACCESSIBLE */ int close_socket(struct ClientSocket *client);
-/* MODULAR ACCESSIBLE */ int disconnect_socket(struct ClientSocket *client);
-int write_socket_force(struct ClientSocket *client, char* msg, int len);
+/* MODULAR ACCESSIBLE */ int destroy_socket(struct ClientSocket *client);
/* MODULAR ACCESSIBLE */ int write_socket(struct ClientSocket *client, char* msg, int len);
#ifdef HAVE_THREADS
int clientsocket_parseorder_top(unsigned int tid);
#endif
-int socket_loop(int timeout_seconds);
/* MODULAR ACCESSIBLE */ void putsock(struct ClientSocket *client, const char *text, ...) PRINTF_LIKE(2, 3);
/* MODULAR ACCESSIBLE */ struct ClientSocket* getBots(int flags, struct ClientSocket* last_bot);
void init_sockets();
int statistics_network_users = 0;
int statistics_network_channels = 0;
-static void parse_line(struct ClientSocket *client, char *line);
static void register_irc_function(char *command, irc_cmd_t *func);
static void parse_raw(struct ClientSocket *client, char *from, char *cmd, char **argv, int argc);
-int parse_lines(struct ClientSocket *client, char *lines, int len) {
- int i, used = 0;
- char *line = lines;
- for(i = 0; i < len; i++) {
- if(lines[i] == '\r') //just zero it out :D
- lines[i] = 0;
- if(lines[i] == '\n') {
- lines[i] = 0;
- parse_line(client, line);
- line = lines+(i+1);
- used = i+1;
- }
- }
- return used;
-}
-
-static void parse_line(struct ClientSocket *client, char *line) {
+void parse_line(struct ClientSocket *client, char *line) {
int argc = 0;
char *argv[MAXNUMPARAMS];
#ifdef HAVE_THREADS
}
}
+ static void increase_viscount_butone(struct ChanNode *chan, struct ChanUser *ignore) {
+ struct ChanUser *chanuser;
+
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ if(chanuser == ignore)
+ continue;
+ chanuser->visCount++;
+ }
+ }
+
+ static void decrease_viscount_butone(struct ChanNode *chan, struct ChanUser *ignore) {
+ struct ChanUser *chanuser, *next_chanuser;
+
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = next_chanuser) {
+ next_chanuser = getChannelUsers(chan, chanuser);
+ if(chanuser == ignore)
+ continue;
+ chanuser->visCount--;
+ if(chanuser->visCount <= 0)
+ delChanUser(chanuser, 1);
+ }
+ }
+
static USERLIST_CALLBACK(got_channel_userlist) {
struct ChanUser *chanuser = data;
+
+ increase_viscount_butone(chanuser->chan, chanuser);
+
event_join(chanuser);
}
event_registered(user, from);
user->flags &= ~USERFLAG_WAS_REGISTERING;
+ } else if(!(chan->flags & CHANFLAG_RECEIVED_USERLIST)) {
+ if(!isBot(user)) {
+ DESYNCHRONIZE(cache_sync);
+ return 1; //ignore join
+ }
+
+ chanuser = addChanUser(chan, user);
+ chanuser->visCount = 1;
+
+ if(isModeSet(chan->modes, 'D')) //if the bot joins a channel it could also be invisible
+ chanuser->flags |= CHANUSERFLAG_INVISIBLE;
+
+ get_userlist_with_invisible(chan, 0, got_channel_userlist, chanuser);
} else if(!isUserOnChan(user, chan)) {
//join user to an existing channel
chanuser = addChanUser(chan, user);
chanuser->visCount = 1;
- if(isBot(user) && isModeSet(chan->modes, 'D')) //if the bot joins a channel it could also be invisible
- chanuser->flags |= CHANUSERFLAG_INVISIBLE;
+ if(isBot(user)) {
+ if(isModeSet(chan->modes, 'D')) //if the bot joins a channel it could also be invisible
+ chanuser->flags |= CHANUSERFLAG_INVISIBLE;
+ increase_viscount_butone(chan, chanuser);
+ }
event_join(chanuser);
//user is already in the channel
chanuser = getChanUser(user, chan);
chanuser->visCount++;
+
+ if(isBot(user) && !(chanuser->flags & CHANUSERFLAG_INVISIBLE))
+ increase_viscount_butone(chan, chanuser);
+
//if multiple bots see the user, it can't be invisible
chanuser->flags &= ~CHANUSERFLAG_INVISIBLE;
}
DESYNCHRONIZE(cache_sync);
return 0;
}
+ if(isBot(user) && user == client->user)
+ decrease_viscount_butone(chan, chanuser);
chanuser->visCount--;
if(chanuser->visCount == 0) {
delChanUser(chanuser, 0); //not free, yet!
DESYNCHRONIZE(cache_sync);
return 0;
}
+ if(isBot(target) && target == client->user)
+ decrease_viscount_butone(chan, chanuser);
chanuser->visCount--;
if(chanuser->visCount == 0) {
delChanUser(chanuser, 0); //not free, yet!
for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = next_chanuser) {
next_chanuser = getUserChannels(user, chanuser);
chanuser->visCount--;
- if(chanuser->visCount == 0) {
+ if(chanuser->visCount <= 0) {
delChanUser(chanuser, 0); //not free, yet!
event_part(chanuser, 1, argv[0]);
if((chanuser->chan->flags & CHANFLAG_RECEIVED_USERLIST) && !(chanuser->chan->flags & CHANFLAG_REJOINING))
struct ChanUser *chanuser, *next_chanuser;
for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = next_chanuser) {
next_chanuser = getUserChannels(user, chanuser);
+ decrease_viscount_butone(chanuser->chan, chanuser);
chanuser->visCount--;
- if(chanuser->visCount == 0) {
+ if(chanuser->visCount <= 0) {
delChanUser(chanuser, 0); //not free, yet!
event_part(chanuser, 1, "QUIT");
- if((chanuser->chan->flags & CHANFLAG_RECEIVED_USERLIST) && !(chanuser->chan->flags & CHANFLAG_REJOINING))
- check_full_rejoin(chanuser->chan);
+ if(chanuser->chan->flags & CHANFLAG_RECEIVED_USERLIST)
+ checkChannelVisibility(chanuser->chan);
freeChanUser(chanuser);
}
}
MYSQL_ROW row;
if(type == MODSTATE_STARTSTOP) {
- printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+ printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind`, `secret` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
res = mysql_use();
while ((row = mysql_fetch_row(res)) != NULL) {
client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
+ client->flags |= (strcmp(row[11], "0") ? SOCKET_FLAG_SECRET_BOT : 0);
client->flags |= SOCKET_FLAG_SILENT;
client->botid = BOTID;
client->clientid = atoi(row[7]);
set_trigger_callback(BOTID, module_id, dummyserv_trigger_callback);
}
-void loop_DummyServ() {
-
-}
-
void free_DummyServ(int type) {
unbind_allcmd(BOTID);
if(type == MODSTATE_STARTSTOP) {
MYSQL_ROW row;
if(type == MODSTATE_STARTSTOP) {
- printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+ printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind`, `secret` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
res = mysql_use();
while ((row = mysql_fetch_row(res)) != NULL) {
client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
+ client->flags |= (strcmp(row[11], "0") ? SOCKET_FLAG_SECRET_BOT : 0);
client->flags |= SOCKET_FLAG_REQUEST_INVITE | SOCKET_FLAG_REQUEST_OP;
client->botid = BOTID;
client->clientid = atoi(row[7]);
register_default_language_table(msgtab);
}
-void loop_NeonBackup() {
-
-}
-
void free_NeonBackup(int type) {
unbind_allcmd(BOTID);
if(type == MODSTATE_STARTSTOP) {
MYSQL_ROW row;
if(type == MODSTATE_STARTSTOP) {
- printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+ printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind`, `secret` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
res = mysql_use();
while ((row = mysql_fetch_row(res)) != NULL) {
client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
+ client->flags |= (strcmp(row[11], "0") ? SOCKET_FLAG_SECRET_BOT : 0);
client->flags |= SOCKET_FLAG_SILENT;
client->flags |= SOCKET_FLAG_REQUEST_INVITE | SOCKET_FLAG_REQUEST_OP;
client->botid = BOTID;
set_trigger_callback(BOTID, module_id, neonfun_trigger_callback);
}
-void loop_NeonFun() {
-
-}
-
void free_NeonFun(int type) {
unbind_allcmd(BOTID);
if(type == MODSTATE_STARTSTOP) {
MYSQL_ROW row;
if(type == MODSTATE_STARTSTOP) {
- printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+ printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind`, `secret` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
res = mysql_use();
while ((row = mysql_fetch_row(res)) != NULL) {
client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
+ client->flags |= (strcmp(row[11], "0") ? SOCKET_FLAG_SECRET_BOT : 0);
client->flags |= SOCKET_FLAG_SILENT;
client->flags |= SOCKET_FLAG_REQUEST_INVITE | SOCKET_FLAG_REQUEST_OP;
client->botid = BOTID;
register_default_language_table(msgtab);
}
-void loop_NeonHelp() {
-
-}
-
void free_NeonHelp(int type) {
unbind_allcmd(BOTID);
if(type == MODSTATE_STARTSTOP) {
{"NS_NICKLIST_STATE", "State"},
{"NS_NICKLIST_ACCESS", "Access"},
{"NS_NICKLIST_SYNC", "use `nicklist sync` to fix all red and orange entrys in the list above (add opped users with %d and voiced with %d access)"},
+ {"NS_NICKLIST_ACCESS_BOT", "Bot"},
+ {"NS_NICKLIST_ACCESS_OPER", "Operator"},
{"NS_SETBOT_UNKNOWN", "`%d` is an unknown botid."}, /* {ARGS: 50} */
{"NS_SETBOT_HEADER", "$bSettings for botid `%d`:$b"}, /* {ARGS: 50} */
{"NS_SETBOT_SETTING", "$b%s$b is an unknown bot setting."}, /* {ARGS: "strangeSetting"} */
MYSQL_ROW row;
if(type == MODSTATE_STARTSTOP) {
- printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+ printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind`, `secret` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
res = mysql_use();
while ((row = mysql_fetch_row(res)) != NULL) {
client = create_socket(row[3], atoi(row[4]), row[10], row[5], row[0], row[1], row[2]);
client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
+ client->flags |= (strcmp(row[11], "0") ? SOCKET_FLAG_SECRET_BOT : 0);
client->flags |= SOCKET_FLAG_REQUEST_INVITE | SOCKET_FLAG_REQUEST_OP;
client->botid = BOTID;
client->clientid = atoi(row[7]);
register_default_language_table(msgtab);
}
-void loop_NeonServ() {
-
-}
-
void free_NeonServ(int type) {
unbind_allcmd(BOTID);
if(type == MODSTATE_STARTSTOP) {
MYSQL_ROW row;
if(type == MODSTATE_STARTSTOP) {
- printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+ printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind`, `secret` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
res = mysql_use();
while ((row = mysql_fetch_row(res)) != NULL) {
client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
+ client->flags |= (strcmp(row[11], "0") ? SOCKET_FLAG_SECRET_BOT : 0);
client->flags |= SOCKET_FLAG_REQUEST_INVITE | SOCKET_FLAG_REQUEST_OP;
client->botid = BOTID;
client->clientid = atoi(row[7]);
register_default_language_table(msgtab);
}
-void loop_NeonSpam() {
-
-}
-
void free_NeonSpam(int type) {
unbind_allcmd(BOTID);
if(type == MODSTATE_STARTSTOP) {