SHOW:
|
|
- or go back to the newest paste.
1 | --// dctoirc.lua: A simple passthrough for IRC to dc++ chat | |
2 | ||
3 | debug = false | |
4 | ||
5 | --// if this is intended for multiple users at the IRC end then set this true | |
6 | multiuser = false | |
7 | --//IRC details | |
8 | server = "irc.freenode.net" | |
9 | port = 6667 | |
10 | --// you may use a nick instead of a channel to have it /msg straight to that nick | |
11 | channel = "#channel" | |
12 | --// nick for IRC, the DC++ nick is configured in the client | |
13 | nick = "ZBot" | |
14 | --// show DC++ joins in irc | |
15 | showjoins = false | |
16 | ||
17 | local passthrough = {} | |
18 | socket = require("socket") | |
19 | client = socket.tcp() | |
20 | client:settimeout(1) | |
21 | ||
22 | res,err = client:connect(server, port) | |
23 | DC():PrintDebug(" **dctoirc.lua: connect",res,err) | |
24 | ||
25 | function send(txt) | |
26 | local res = client:send(txt.."\r\n") | |
27 | if not res then | |
28 | print("send","error") | |
29 | else | |
30 | print("send",txt) | |
31 | end | |
32 | end | |
33 | ||
34 | function recv() | |
35 | local res, err = client:receive('*l') | |
36 | if err == 'timeout' then | |
37 | return res, false, true | |
38 | end | |
39 | return res, err, false | |
40 | end | |
41 | ||
42 | function IRCEvents() | |
43 | local events = {} | |
44 | local event = | |
45 | function(trigger, callback) | |
46 | local cb = callback | |
47 | return | |
48 | function() | |
49 | if string.match(res, trigger) then | |
50 | cb() | |
51 | return true | |
52 | else | |
53 | return false | |
54 | end | |
55 | end | |
56 | end | |
57 | return { | |
58 | setListener = | |
59 | function(trigger, callback) | |
60 | table.insert(events,event(trigger,callback)) | |
61 | end, | |
62 | check = | |
63 | function() | |
64 | local res | |
65 | for k,v in pairs(events) do | |
66 | v() | |
67 | end | |
68 | end | |
69 | } | |
70 | end | |
71 | ||
72 | IRC = IRCEvents() | |
73 | --// set up our timer to check the IRC channel 5 times a second: | |
74 | dcpp:setListener( "timer", "Pings", | |
75 | function() | |
76 | --// Timer only calls once a second, not really enough for our needs so we loop within it | |
77 | for variable = 0, 5, 1 do | |
78 | res, err, timeout = recv() | |
79 | if not err and not timeout then | |
80 | if debug then | |
81 | DC():PrintDebug(" **dctoirc.lua: "..res ) | |
82 | end | |
83 | IRC.check() | |
84 | print("RECV", res) | |
85 | end | |
86 | end | |
87 | end | |
88 | ) | |
89 | ||
90 | IRC.setListener("PING ", | |
91 | function() | |
92 | --// normal PING requests from the server | |
93 | if string.sub(res,1,4)=="PING" then | |
94 | response = string.gsub(res,"PING","PONG",1) | |
95 | --// PING requests from other users | |
96 | else | |
97 | from, timestamp = string.match(res, "^:([%a%d]+)!.* PRIVMSG "..nick.." :.PING ([%d]+).") | |
98 | if from and timestamp then | |
99 | response = "NOTICE "..from.." :\001PING "..timestamp.."\001" | |
100 | end | |
101 | end | |
102 | send(response) | |
103 | end | |
104 | ) | |
105 | ||
106 | IRC.setListener("NOTICE Auth", | |
107 | function() | |
108 | --// Only join a channel if channel is a channel rather than user | |
109 | if string.sub(channel,1,1)=="#" then | |
110 | send("JOIN "..channel) | |
111 | end | |
112 | end | |
113 | ) | |
114 | ||
115 | IRC.setListener("PRIVMSG", | |
116 | function() | |
117 | --//would ideally use this regex but lua doesn't like it | |
118 | --if string.find(res,"^:[%a%d]+!.* PRIVMSG "..channel.."|"..nick.." :.*$") then | |
119 | if string.find(res,"^:[%a%d]+!.* PRIVMSG [#%a%d]+ :.*$") then | |
120 | user = string.match(res, "^:([%a%d]+)!") | |
121 | message = string.match(res, "^:[%a%d]+!.* PRIVMSG [#%a%d]+ :(.*)$") | |
122 | --// make /me work | |
123 | if string.match(message, "^\001ACTION ") then | |
124 | message = "/me "..string.match(message, "^\001ACTION (.*)\001") | |
125 | end | |
126 | if debug then | |
127 | DC():PrintDebug(" **dctoirc.lua: user="..user.." message="..message ) | |
128 | end | |
129 | local hubs = dcpp:getHubs() | |
130 | table.foreach(hubs, | |
131 | function(_,shub) | |
132 | if multiuser then | |
133 | shub:sendChat( "<"..user..">"..message ) | |
134 | else | |
135 | shub:sendChat( message ) | |
136 | end | |
137 | end | |
138 | ) | |
139 | end | |
140 | end | |
141 | ) | |
142 | ||
143 | dcpp:setListener( "chat", "passthrough", | |
144 | function( hub, user, text ) | |
145 | send("PRIVMSG "..channel.." :<"..user:getNick()..">"..text) | |
146 | end | |
147 | ) | |
148 | ||
149 | --// you probably don't want it repeating everything you it says on irc | |
150 | --dcpp:setListener( "ownChat", "passthrough", | |
151 | -- function( hub, text ) | |
152 | -- send("PRIVMSG "..channel.." :<"..hub:getOwnNick()..">"..text) | |
153 | -- end | |
154 | --) | |
155 | ||
156 | dcpp:setListener( "unknownChat", "passthrough", | |
157 | function( hub, text ) | |
158 | send("PRIVMSG "..channel.." :**"..text) | |
159 | end | |
160 | ) | |
161 | ||
162 | ||
163 | if showjoins then | |
164 | --//user join, userConnected doesn't seem to work properly | |
165 | dcpp:setListener( "userMyInfo", "passthrough", | |
166 | function( hub, user, stuff ) | |
167 | send("PRIVMSG "..channel.." :** "..user:getNick().." connected") | |
168 | end | |
169 | ) | |
170 | ||
171 | dcpp:setListener( "userQuit", "passthrough", | |
172 | function( hub, nick ) | |
173 | send("PRIVMSG "..channel.." :** "..nick.." quit") | |
174 | end | |
175 | ) | |
176 | end | |
177 | ||
178 | --// Identify | |
179 | send("NICK "..nick) | |
180 | send("USER "..nick.." 0 * : DC++/IRC passthrough by zed0") | |
181 | ||
182 | - | DC():PrintDebug( " ** Loaded dctoirc.lua **" ) |
182 | + | DC():PrintDebug( " ** Loaded dctoirc.lua **" ) |
183 |