-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathircsocketconnect.js
165 lines (145 loc) · 6.58 KB
/
ircsocketconnect.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
var irc = require('irc');
var mongoose = require('mongoose');
var config = require('../config').config;
// establish models from mongoose model
var User = mongoose.model('User');
var Message = mongoose.model('Message');
var IRCSocketConnect = function (hostname, port, ssl, selfSigned, nick, realName, password, rejoin, encoding, keepAlive, channels) {
var that = this;
this.sockets = new Array();
this.server = hostname;
var parsedPort = parseInt(port);
if (!parsedPort)
parsedPort = (ssl ? 6697 : 6667);
if (channels === undefined || !rejoin)
var channels = new Array();
//from http://node-irc.readthedocs.org/en/latest/
var connectOptions = {
userName: nick,
realName: realName,
port: parsedPort,
debug: true,
showErrors: true,
autoRejoin: rejoin,
autoConnect: true, //Setting autoConnect to false prevents the Client from connecting on instantiation. You will need to call connect() on the client instance:
channels: channels, //Starting channels, for this will be null usually (no client fields yet)
secure: ssl, //SORT OF BROKEN
selfSigned: selfSigned, //SORT OF BROKEN
certExpired: false,
floodProtection: true,
floodProtectionDelay: 1000,
stripColors: true,
retryCount: 1,
encoding: encoding
};
if (password) {
//node-irc interprets "" password as blank, this is a workaround
connectOptions.password = password;
}
this.nodeircInstance = new irc.Client(hostname, nick, connectOptions);
this.keepAlive = keepAlive; //Used when logged in user wants to restore active connection
//All the events that need to be handled and forwarded to socket.io
//from http://node-irc.readthedocs.org/en/latest/
//just a nice way to say what I catch, and what parameters the function has
this.events = {
'join': ['channel', 'nick'],
'part': ['channel', 'nick'],
'quit': ['nick', 'reason', 'channels', 'message'],
'topic': ['channel', 'topic', 'nick'],
'nick': ['oldNick', 'newNick', 'channels', 'message'],
'names': ['channel', 'nicks'],
'message': ['from', 'to', 'text'],
'pm': ['nick', 'text'],
'motd': ['motd'],
'notice': ['nick', 'to', 'text', 'message'],
'error': ['message'],
'netError': ['message'],
'abort': ['retryCount'],
'registered': ['message'],
'action': ['from', 'to', 'text'],
'whois': ['info'],
'channellist': ['channel_list'] // Emitted when the server has finished returning a channel list. The channel_list array is simply a list of the objects that were returned in the intervening channellist_item events.
};
// Add a listener on client for the given event & argument names
this.callbackCreator = function (event, argNames) {
//How to add a listnener for a specific event
//https://node-irc.readthedocs.org/en/latest/index.html?highlight=addListener
that.nodeircInstance.addListener (event, function() {
//This method forwards everything to the client end, atleast all events that the above has
//Using a nice loop to generate the callback function, rather than manually do it for each
// Associate specified names with callback arguments
var callbackArgs = arguments; //arguments being a javascirpt global thing for the function - node-irc is sending these arguments to this event
var args = {};
argNames.forEach(function(arg, index) {
args[arg] = callbackArgs[index]; //taking them, and formatting them the exact way node-irc does, but in an object that can be sent via sockets
});
// emit the event
for (var i = 0; i < that.sockets.length; i++) {
that.sockets[i].emit(event, args);
}
//If it is a message, we want to log that
if (event == 'message') {
if (that.username) {
var channelOrUser;
if (args.to[0] != '#') //PM workaround
channelOrUser = args.from.toLowerCase(); //PM, which means to is ME, so we want them
else
channelOrUser = args.to.toLowerCase(); //Normal message, should be #channel
// log this message
that.logMessage(channelOrUser, args.from, args.text);
}
}
});
};
//Attach event handlers for the stuff node-irc spews out
for (var event in this.events) {
this.callbackCreator(event, this.events[event]);
}
}
// properties and methods
IRCSocketConnect.prototype = {
associateUser: function(username) {
//Attach the users username to this instance
this.username = username;
},
connect: function() {
//Calls node-irc's connect
this.nodeircInstance.connect();
},
disconnect: function() {
//Calls node-irc's disconnect
this.nodeircInstance.disconnect();
},
addSocket: function(socket) {
this.sockets.push(socket);
},
removeSocket: function(s) {
//Remove the socket if it exists
var foundSocket = this.sockets.indexOf(s);
if (foundSocket != -1) {
this.sockets.splice(foundSocket, 1); //At index foundSocket, remove 1
}
},
logMessage: function(channel, fromUser, theMessage) {
//If we're logged in
if (this.username) {
//Save the message
var message = new Message({channel: channel.toLowerCase(), server: this.server.toLowerCase(), ofuser: this.username, user: fromUser, message: theMessage});
message.save();
// keep log size in check (only need so much backlog for each user
//Remove the excess messages (can increase pretty big for a zillion users so we limit it via config.js)
Message.count({}, function(err, count) {
if (count > config.max_log) {
//Get the oldest messages
Message.find({}, null, {sort: {date: 1}, limit: count - config.max}, function (err, records) {
records.forEach(function(record){
record.remove();
});
});
}
});
}
}
};
//Make it a module that socket file can incorporate
module.exports = IRCSocketConnect;