Attempting an IRC client via Luasocket

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
Daman
Prole
Posts: 3
Joined: Sun Jul 20, 2008 10:22 pm

Attempting an IRC client via Luasocket

Post by Daman »

Ok, I wanted to try and make an IRC client through Löve. I thought it'd be interesting.

I know of Luasocket for networking, so I figure I could just plop that where needed and include it in the main.lua file. Everything seemed fine. Didn't return errors(I should've had it assert if nil at the beginning. Argh). Then I tried to call the socket.tcp() object from update.

Run-time error: main.lua:43: attempt to index global 'client' (a nil value)

That's no good at all. socket.tcp() returns nil on error.

I really don't know the problem here. Am I applying the luasocket module wrong? Is it added incorrectly? I notice in a 3.2 topic in the other section, you mention modules now being static. Does that mean you have to compile with them included?

I'd love some help, thanks in advance.

Here is the code:

Code: Select all

function load()
	love.graphics.setCaption("LoveIRC")
	font = love.graphics.newFont(love.default_font, 10)
	love.graphics.setFont(font);
	love.graphics.setColor(200, 200, 200);
	
	--I think I'll store the messages sent in one giant array with a subarray for values of the message.. 
	messages = {} 
--	messages[1] = { name="Daman", message="aaaaaaaaaaaaaaaaaaaaaaaa", timesent="043213" } -- Timesent format is hh|mm|ss
--	messages[2] = { name="Seleia", message="bbbbbbbbbbbbbbbbbbbb", timesent="043214" }
	--Here will be where we store the message we want to send
	str = ""
	--And let's keep this for stuff we receive
	rcv = ""
	--Just another variable. Usermessage boolean
	umsg = 0
	
	--Let's include the module. Pretty sure this makes /everything/ under it apply only to the module code. Love functions have left the building for the rest of load()
	local socket = require("socket.core")
	module("socket")

	
	client = socket.tcp()
	host = "cortex.datarealms.com"
	nick = "Loveuser"
	site = "google.com"
	
	--Connect. Please connect.
	client:connect(host, 6667)
	
	--Let's check if we are connected and if so send the stuff we need to to the server to make ourselves recognized. This is the part where I'm unsure of the luasocket end of things.  Perhaps I need to prefix the data with the host address? No clue
	client:send("NICK " .. nick, 1, -1)
	client:send("USER \"" .. site .. "\" \"" .. host .. "\" :doesnotmatter", 1, -1)
	--We'll have to do a the time reply in update, as we need to wait for it to auth us and perform 439 & 931
	


end

function update(dt)
	--Tell me if you can figure out a better way to handle this.
	rcv = client:receive('*a')
	
	
	if rcv then
		if string.sub(rcv, 1, string.find(rcv," ")) == host then -- Handle messages from server(ping, motd, etc) differently
			umsg = 0
		else
			umsg = 1
		end
		--Adding a table to messages with: name, message, timesent, umsg
		table.insert(messages, { name=string.sub(rcv, 1, string.find(rcv," ")), message=string.sub(rcv, string.find(rcv," "), string.len(rcv)), timesent=os.date("%H%M%S"), umsg=umsg })
	end


	--Reply to ctcp time. 
	if string.find(rcv, "\001TIME\001") then
		client:send("NOTICE " .. host .. " :\001TIME" .. os.date() .. "\001", 1, -1)
	end
	
	
	--Unsetting these so the if rcv will only activate when there's a new message.
	umsg = 0
	rcv = ""
end

function draw()
	--If it's a user, add formatting.
	for k,v in ipairs(messages) do
		if v.umsg then
			love.graphics.drawf(v.timesent .. " <" .. v.name .. "> " .. v.message, 300, (400 + font:getHeight() * k), 600)
		else
			love.graphics.drawf(v.timesent .. v.name .. v.message, 300, (400 + font:getHeight() * k), 600)
		end
	end
	
	
	--DEBUG DEBUG DEBUG
	love.graphics.draw("Recieved string: " .. rcv, 100, 100)
	love.graphics.draw("Network: " .. host, 100, 90)
end
User avatar
Lord Tim
Prole
Posts: 30
Joined: Sun Jul 20, 2008 4:07 am

Re: Attempting an IRC client via Luasocket

Post by Lord Tim »

tcp() also returns a message telling you the error, if it returns nil.

Use

Code: Select all

client,msg = socket.tcp()
And then you can print out the error, which should shed some more light. It looks like you've got it included correctly, or it'd give you a bunch of errors about that first.
Daman
Prole
Posts: 3
Joined: Sun Jul 20, 2008 10:22 pm

Re: Attempting an IRC client via Luasocket

Post by Daman »

After changing quite a bit, I'm noticing my fps near-die after finishing connecting to a server, having the motd pass bye and modes set on me. It pretty much comes to one update every minute. I think this is due to I/O blocking, but I set the timeout to 10 seconds. I'm not sure how to get around it. I've added the beginnings of chat ability, but I don't want to go any further in that until I can fix the slowness issues. When it fails to connect to a server, it runs perfectly fine. Not slow at all. It's only when connected to a server.



Code so far:

Code: Select all

function load()
	love.graphics.setCaption("LoveIRC")
	font = love.graphics.newFont(love.default_font, 10)
	love.graphics.setFont(font);
	love.graphics.setColor(200, 200, 200);
	
	--I think I'll store the messages sent in one giant array with a subarray for values of the message.. 
	messages = {} 
--	messages[1] = { name="Daman", message="Dick dick dicks on fish", timesent="043213" } -- Timesent format is hh|mm|ss
--	messages[2] = { name="Seleia", message="STOP IT FAGGOT", timesent="043214" }
	--Here will be where we store the message we want to send
	str = ""
	--And let's keep this for stuff we receive
	rcv = ""
	--Just another variable. Usermessage boolean
	umsg = 0
	fps=0

	--Let's include the module. Pretty sure this makes /everything/ under it apply only to the module code. Love functions have left the building for the rest of load()
	local socket = require("socket.core")
--	module("socket")

	
	client = socket.tcp()
	host = "cortex.datarealms.com"
	nick = "Loveuser"
	
	--Connect. Please connect.
	client:connect(host, 6667)
	client:settimeout(10, t) 
	--Let's check if we are connected and if so send the stuff we need to to the server to make ourselves recognized. This is the part where I'm unsure of the luasocket end of things.  Perhaps I need to prefix the data with the host address? No clue
	client:send("NICK " .. nick .. "\r\n")
	client:send("USER " .. nick .. " 8 * : Love IRC\r\n")

	--We'll have to do a the time reply in update, as we need to wait for it to auth us and perform 439 & 931
	


end

function update(dt)
	fps = love.timer.getFPS()
	rcv = client:receive('*l')
	

	
	if rcv then
		if string.sub(rcv, 1, string.find(rcv," ")) == host then -- Handle messages from server(ping, motd, etc) differently
			umsg = 0
		else
			umsg = 1
		end
		--Adding a table to messages with: name, message, timesent, umsg
		table.insert(messages, { name=string.sub(rcv, 1, string.find(rcv," ")), message=string.sub(rcv, string.find(rcv," "), string.len(rcv)), timesent=os.date("%H%M%S"), umsg=umsg })
	end
	--Tell me if you can figure out a better way to handle this.

--	if rcv and string.find(rcv, "AUTH") then

--	end
	
	--Reply to ctcp time. 
	if rcv and string.find(rcv, "\001TIME\001") then
		client:send("NOTICE " .. host .. " :\001TIME" .. os.date() .. "\001\r\n")
	end
	
	
	--Unsetting these so the if rcv will only activate when there's a new message.
--	umsg = 0
--	rcv = ""
end

function draw()

	
	--If it's a user, add formatting.
	for k,v in ipairs(messages) do
		if k > 50 then
			table.remove(messages, 1)
		end
		love.graphics.draw(k, 50, (90 + (k * 5)))
		if v.umsg then
			love.graphics.drawf(v.timesent .. " <" .. v.name .. "> " .. v.message, 100, (0 + font:getHeight() * k), 800)
		else
			love.graphics.drawf(v.timesent .. v.name .. v.message, 300, (400 + font:getHeight() * k), 800)
		end
	end
	
	
	--DEBUG DEBUG DEBUG
--	love.graphics.draw("Recieved string: " .. rcv, 100, 100)
	love.graphics.drawf("Network: " .. host, 10, 22, 100)
	
	--str
	love.graphics.draw("Message: " .. str, 100, 590)

	love.graphics.draw("FPS: " .. fps, 10, 10)
end

function keypressed(key)
	if key == love.key_q then
		str = str .. "q"
	end
	if key == love.key_w then
		str = str .. "w"
	end
	if key == love.key_e then
		str = str .. "e"
	end
	if key == love.key_r then
		str = str .. "r"
	end
	if key == love.key_t then
		str = str .. "t"
	end
	if key == love.key_y then
		str = str .. "y"
	end
	if key == love.key_u then
		str = str .. "u"
	end
	if key == love.key_i then
		str = str .. "i"
	end
	if key == love.key_o then
		str = str .. "o"
	end
	if key == love.key_p then
		str = str .. "p"
	end
	if key == love.key_a then
		str = str .. "a"
	end
	if key == love.key_s then
		str = str .. "s"
	end
	if key == love.key_d then
		str = str .. "d"
	end
	if key == love.key_f then
		str = str .. "f"
	end
	if key == love.key_g then
		str = str .. "g"
	end
	if key == love.key_h then
		str = str .. "h"
	end
	if key == love.key_j then
		str = str .. "j"
	end
	if key == love.key_k then
		str = str .. "k"
	end
	if key == love.key_l then
		str = str .. "l"
	end
	if key == love.key_z then
		str = str .. "z"
	end
	if key == love.key_x then
		str = str .. "x"
	end
	if key == love.key_c then
		str = str .. "c"
	end
	if key == love.key_v then
		str = str .. "v"
	end
	if key == love.key_b then
		str = str .. "b"
	end
	if key == love.key_n then
		str = str .. "n"
	end 
	if key == love.key_m then
		str = str .. "m"
	end
	if key == love.key_slash then
		str = str .. "/"
	end
	if key == love.key_period then
		str = str .. "."
	end
	if key == love.key_comma then
		str = str .. ","
	end
	if key == love.key_hash then
		str = str .. "#"
	end
	if key == love.key_space then
		str = str .. " "
	end
	if key == love.key_return then
		if string.sub(str, 1, string.find(str," ")) == "/join" or string.sub(str, 1, string.find(str," ")) == "/j" then
			client:send("JOIN #" .. string.sub(str, 2, string.find(str," ")))
		end
		client:send("PRIVMSG #drlchat :" .. str)
		str = ""
	end
end
User avatar
Lord Tim
Prole
Posts: 30
Joined: Sun Jul 20, 2008 4:07 am

Re: Attempting an IRC client via Luasocket

Post by Lord Tim »

You know, for the keypressed bit, you could just do like

Code: Select all

if string.find(key,"[%w%p]") then str .. string.char(key) end
Daman
Prole
Posts: 3
Joined: Sun Jul 20, 2008 10:22 pm

Re: Attempting an IRC client via Luasocket

Post by Daman »

Yeah, I just copied that out of something else I made. Trying to get this to not lag so I can do more stuff in that.
Hexxeh
Prole
Posts: 3
Joined: Sun Jul 27, 2008 10:26 am

Re: Attempting an IRC client via Luasocket

Post by Hexxeh »

Setting the timeout to zero will give you a non-blocking socket.
Post Reply

Who is online

Users browsing this forum: No registered users and 10 guests