View difference between Paste ID: B49r6Sz8 and ZPpDtMsn
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