unrealircd.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. module.exports.connected = connected;
  2. module.exports.processMessage = processMessage;
  3. module.exports.processSender = processSender;
  4. module.exports.setHandlers = setHandlers;
  5. module.exports.setSettings = setSettings;
  6. var handlers = {
  7. sendHandler: null,
  8. findServer: null,
  9. findUser: null,
  10. killUser: null,
  11. newServer: null,
  12. newUser: null,
  13. parseUmodes: null,
  14. getChannel: null
  15. };
  16. var settings = {
  17. ID: null,
  18. password: null,
  19. name: null,
  20. description: null,
  21. version: null,
  22. me: null
  23. };
  24. var prefixes = {
  25. '~': 'q',
  26. '&': 'a',
  27. '@': 'o',
  28. '%': 'h',
  29. '+': 'v'
  30. };
  31. function parseModePrefix(text){
  32. var modes = [];
  33. for(var i=0; i<text.length; i++){
  34. var c = text.charAt(i);
  35. if(c in prefixes){
  36. modes[prefixes[c]] = true;
  37. } else break;
  38. }
  39. var uid = text.substring(i);
  40. var user = handlers.findUser(uid);
  41. if(!user){
  42. handlers.killUser(uid);
  43. return null;
  44. }
  45. return { 'user': user, 'modes': modes };
  46. }
  47. function connected(){
  48. ircSend(null, settings.ID, 'PASS', [settings.password]);
  49. ircSend(null, settings.ID, 'PROTOCTL', ['NICKv2', 'VHP', 'UMODE2', 'NICKIP', 'SJOIN', 'SJOIN2', 'SJ3', 'NOQUIT', 'TKLEXT', 'MLOCK', 'SID']);
  50. ircSend(null, settings.ID, 'PROTOCTL', ['EAUTH=' + settings.name + ',,,' + settings.version]);
  51. ircSend(null, settings.ID, 'PROTOCTL', ['SID=' + settings.ID]);
  52. ircSend(null, settings.ID, 'SERVER', [settings.name, '1', settings.description]);
  53. }
  54. /*
  55. this.sender = {
  56. 'nick': '',
  57. 'ident': '',
  58. 'host': '',
  59. 'server': false,
  60. 'user': false
  61. };
  62. */
  63. function processSender(sender){
  64. if(sender.nick){
  65. if(server = handlers.findServer(sender.nick)){
  66. sender.nick = server.name;
  67. sender.server = server;
  68. } else if(user = handlers.findUser(sender.nick)){
  69. sender.nick = user.name
  70. sender.ident = user.ident;
  71. sender.host = user.host;
  72. sender.user = user;
  73. } else {
  74. handlers.killUser(sender.nick);
  75. return false;
  76. }
  77. }
  78. return sender;
  79. }
  80. function processMessage(msg){
  81. if(!msg) return;
  82. if(msg.command in cmdBinds){
  83. cmdBinds[msg.command](msg);
  84. } else {
  85. console.log('Unhandled cmd: '+msg.command);
  86. console.log(msg);
  87. }
  88. }
  89. function setHandlers(newHandlers){
  90. handlers = newHandlers;
  91. }
  92. function setSettings(newSettings){
  93. settings = newSettings;
  94. }
  95. function ircSend(tags, from, cmd, args){
  96. handlers.send(tags, from, cmd, args);
  97. }
  98. var cmdBinds = {
  99. 'PROTOCTL': function(msg){
  100. console.log(msg);
  101. },
  102. 'SERVER': function(msg){
  103. var expr = /^([^-]+)-([^-]+)-([^ ]+) (.*)$/;
  104. var match = expr.exec(msg.args[2]);
  105. if(match){
  106. handlers.newServer(msg.args[0], match[3], match[4], msg.args[1], settings.me);
  107. } else {
  108. throw 'Unknown SERVER message';
  109. }
  110. },
  111. 'MD': function(msg){
  112. },
  113. 'SMOD': function(msg){
  114. },
  115. 'EOS': function(msg){
  116. },
  117. 'SINFO': function(msg){
  118. console.log(msg);
  119. },
  120. 'SID': function(msg){
  121. handlers.newServer(msg.args[0], msg.args[2], msg.args[3], msg.args[1], msg.sender);
  122. },
  123. /*
  124. messagedata {
  125. text: 'James Wheare',
  126. args: [
  127. 'jwheare', // nick 0
  128. '0', // hopcount 1
  129. '1583326466', // TS 2
  130. 'sid2', // ident 3
  131. '192.184.10.9', // host 4
  132. '0932YWXX0', // uid 5
  133. '0', // account 6
  134. '+T', // umodes 7
  135. '192.184.10.9', // vhost 8
  136. '142AA462.921FA108.2DA10B49.IP', // cloakedHost 9
  137. 'wLgKCQ==', // ip 10
  138. 'James Wheare' // realname 11
  139. ],
  140. tags: [],
  141. command: 'UID',
  142. sender: {
  143. nick: 'test1.pirc.pl',
  144. ident: '',
  145. host: '',
  146. server: true,
  147. user: false
  148. },
  149. time: 2020-03-09T08:33:46.447Z,
  150. reply: [Function],
  151. originalString: ':093 UID jwheare 0 1583326466 sid2 192.184.10.9 0932YWXX0 0 +T 192.184.10.9 142AA462.921FA108.2DA10B49.IP wLgKCQ== :James Wheare'
  152. }
  153. */
  154. 'UID': function(msg){ // nick, distance, TS, ident, host, uid, account, umodes, vhost, cloakedHost, ip, realname, uplink
  155. handlers.newUser(msg.args[0], msg.args[1], msg.args[2], msg.args[3], msg.args[4], msg.args[5], msg.args[6], handlers.parseUmodes(msg.args[7]), msg.args[8], msg.args[9], msg.args[10], msg.args[11], msg.sender.server);
  156. },
  157. /*
  158. >>> :143 SJOIN 1580651090 #help +nt :0936CITMS 0931Y7O8W
  159. messagedata {
  160. text: '0936CITMS 0931Y7O8W',
  161. args: [ '1580651090', '#help', '+nt', '0936CITMS 0931Y7O8W' ],
  162. tags: [],
  163. command: 'SJOIN',
  164. sender: {
  165. nick: 'test3.pirc.pl',
  166. ident: '',
  167. host: '',
  168. server: server {
  169. name: 'test3.pirc.pl',
  170. sid: '143',
  171. description: 'serwer testowy!',
  172. distance: '1',
  173. uplink: [server],
  174. introduce: [Function]
  175. },
  176. user: false
  177. },
  178. time: 2020-03-09T10:05:44.305Z,
  179. reply: [Function],
  180. originalString: ':143 SJOIN 1580651090 #help +nt :0936CITMS 0931Y7O8W'
  181. }
  182. >>> :143 SJOIN 1582647660 #jwheare +nt :@0936CITMS
  183. messagedata {
  184. text: '@0936CITMS',
  185. args: [ '1582647660', '#jwheare', '+nt', '@0936CITMS' ],
  186. tags: [],
  187. command: 'SJOIN',
  188. sender: {
  189. nick: 'test3.pirc.pl',
  190. ident: '',
  191. host: '',
  192. server: server {
  193. name: 'test3.pirc.pl',
  194. sid: '143',
  195. description: 'serwer testowy!',
  196. distance: '1',
  197. uplink: [server],
  198. introduce: [Function]
  199. },
  200. user: false
  201. },
  202. time: 2020-03-09T10:05:44.306Z,
  203. reply: [Function],
  204. originalString: ':143 SJOIN 1582647660 #jwheare +nt :@0936CITMS'
  205. }
  206. */
  207. 'SJOIN': function(msg){
  208. var channel = handlers.getChannel(msg.args[1]);
  209. channel.setTS(msg.args[0]);
  210. var modeArgs = [];
  211. for(var i=3; i<msg.args.length - 1; i++){
  212. modeArgs.push(msg.args[i]);
  213. }
  214. channel.addModes(msg.args[2], modeArgs);
  215. var members = msg.text.split(' ');
  216. for(var i=0; i<members.length; i++){
  217. var member = members[i];
  218. var c = member.charAt(0);
  219. if(c == '&'){ // +b
  220. channel.addBan(member.substring(1));
  221. } else if(c == '"'){ // +e
  222. channel.addExcept(member.substring(1));
  223. } else if(c == '\''){ // +I
  224. channel.addInvex(member.substring(1));
  225. } else {
  226. var udata = parseModePrefix(member);
  227. if(!udata) return;
  228. console.log(udata.user.name + ' joined ' + msg.args[1]);
  229. channel.uJoin(udata.user);
  230. channel.setStatusModes(udata.user, udata.modes);
  231. }
  232. }
  233. console.log(channel);
  234. },
  235. 'SWHOIS': function(msg){
  236. },
  237. 'TKL': function(msg){
  238. },
  239. 'METADATA': function(msg){
  240. },
  241. 'NETINFO': function(msg){
  242. console.log(msg);
  243. },
  244. 'SASL': function(msg){
  245. },
  246. 'PING': function(msg){
  247. msg.reply(null, 'PONG', msg.args);
  248. }
  249. };