diff -r 000000000000 -r cc66ad6b0d75 bot.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bot.lua Sat Mar 27 17:43:08 2010 +0000 @@ -0,0 +1,173 @@ +--[[ Lua XMPP MOO Component by Matthew Wild (MattJ) ]] + +BotName = "Component"; +BotPass = ""; + +function onPresence(msg) + success, message = pcall(handlePresence, msg); + if not success then print("\nERROR: "..message.."\n"); end +end + +function onConnect() +end + +function onMessage(msg) + success, message = pcall(handleMessage, msg); + if not success then print("\nERROR: "..message.."\n"); end +end + + +function handlePresence(msg) + local room, server, nick, id, person; + room,server,nick = msg.to:match("^(.+)@(.+)/(.+)$"); + if not (room and nick) then print("\nERROR: Invalid room or nick!\n"); return; end -- We need to send an error + -- print("Type: "..msg.type.." type of type: "..type(msg.type),"\n"); + if msg.type == "available" or msg.type == "" and not people[msg.fromFull] then + print("\nRecieved Available presence to join a room\n"); + people[msg.fromFull] = { ["nick"] = nick, ["jid"] = msg.fromFull, ["presence"] = msg.type, room = rooms[room], occjid = msg.to, _parent = occupant, group = {}, _contents = { ["in"] = createcontainertable(); } } + MoveToRoom(people[msg.fromFull], room); + -- rooms[room].people[nick] = people[msg.fromFull]; + --for id, person in pairs(rooms[room].people) do + -- SendPresence(msg.fromFull, person.presence, "", room.."@"..server.."/"..person.nick); + --end + elseif msg.type == "unavailable" then + RemoveFromRoom(rooms[room], msg.fromFull); + people[msg.fromFull] = nil; + end + print("Returning\n"); + SendPresence(msg.fromFull, msg.type, "", msg.to); +end + + + +function handleMessage(msg) + local action, object, room, server, person; + person = people[msg.fromFull] + if msg.type == MSG_ERROR then print("ERROR MESSAGE from "..msg.fromFull..": ", msg.body); return nil; end + if not person then print("No such person as "..msg.fromFull, tostring(people[msg.fromFull]).."\n"); + for k,v in pairs(people) do print(string.format("people[\"%s\"]", k),", "); end return nil; end + room, server = msg.to:match("^(.+)@(.+)$"); + if not (room and server) then print("ERROR! Malformed JID? "..msg.to.."\n"); return nil; end --TODO: Reply with error + server = server:lower(); + if not rooms[room] then return; end -- TODO: Reply with error + + person:_processCommand(msg.body); + + return nil; +end + +function BroadcastPresence(people, fromnick, ptype, text) + local nick, t; + if type(people) == "string" then if not rooms[people] then print("No room called '"..people.."'","\n"); return; else print("\nLooking up room: "..people, "\n"); people = rooms[people].people; end end + if not people then print("No such room. \n"); return; end + for nick, t in pairs(people) do + if t and t.jid then + SendPresence(t.jid, ptype or "available", text or "", GetJIDParts(t.occjid).node.."@"..GetJIDParts(t.occjid).server.."/"..fromnick); + else print("\nOrphaned occupant: "..nick, "\n"); + end + end +end + +function BroadcastMessage(people_, from, text, mtype, sender_sees) + local nick, t + for nick, t in pairs(people_) do + print("\nMessage sent to: "..t.jid); + if t.nick ~= from or sender_sees ~= false then + SendMessage(t.jid, GetJIDParts(t.occjid).node.."@"..GetJIDParts(t.occjid).server.."/"..from, text or "", mtype or "groupchat"); + end + end + print("\nDone\n"); +end + +function GetOccupantNick(jid) + local pjid, p + for pjid, p in pairs(people) do + if CompareJIDs(pjid, jid) then return p.nick; end + end + return "Somebody"; +end + +function CompareJIDs(j1, j2) + if not (j1 and j2) then return false; end + print("j2: "..type(j2)); + j1node, j1server, j1res = j1:match("^(.+)@([%a%.]+)/?(.*)$"); + j2node, j2server, j2res = j2:match("^(.+)@([%a%.]+)/?(.*)$"); + if j1node == j2node and j1server:lower() == j2server:lower() and (j1res == j2res or j1res == "" or j2res == "") then return true; end + return false; +end + +function MoveToRoom(person, room) + if not ( person and room) then return; end + + if type(room) ~= "table" then + if not rooms[room] then rooms[room] = CreateObject(classes.obj_room); rooms[room]:_create{ room = room, server = GetJIDParts(person.occjid).server}; end + room = rooms[room]; + end + + if person.room ~= room then + if person.room then + -- Tell everyone in room that user is leaving + --BroadcastPresence(person.room.people, person.occjid, "unavailable"); + for nick, t in pairs(person.room.people) do + -- print(string.format("\nPRESENCE: to: %s, from: %s, type: %s\n", t.jid, )); + if nick ~= person.nick then + SendPresence(t.jid, "unavailable", "", GetJIDParts(t.occjid).node.."@"..GetJIDParts(t.occjid).server.."/"..person.nick); + end + end + -- Tell user that everyone else in the room has gone (clear room roster in their client) + for nick, t in pairs(person.room.people) do + if person.nick ~= nick then + SendPresence(person.jid, "unavailable", "", GetJIDParts(person.occjid).node.."@"..person.room._properties.server.."/"..t.nick); + end + end + person.room.people[person.nick] = nil; -- Remove from room + end + end + person.room = room; + room.people[person.nick] = person; + --Tell user about people in the new room + for nick, t in pairs(person.room.people) do + -- print(string.format("\nPRESENCE: to: %s, from: %s, type: %s\n", t.jid, )); + if nick ~= person.nick then + SendPresence(person.jid, "available", "", GetJIDParts(person.occjid).node.."@"..GetJIDParts(person.occjid).server.."/"..nick); + end + end + --Tell people in new room that user has joined + -- BroadcastPresence(person.room.people, person.nick, "available"); + for nick, t in pairs(person.room.people) do + -- print(string.format("\nPRESENCE: to: %s, from: %s, type: %s\n", t.jid, )); + if nick ~= person.nick then + SendPresence(t.jid, "available", "", GetJIDParts(t.occjid).node.."@"..GetJIDParts(t.occjid).server.."/"..person.nick); + end + end + SendPresence(person.jid, "available", "", person.occjid); + room:_enter{ room = person.room, person = person, nick = person.nick }; +end + +function RemoveFromRoom(room, jid) + if not ( room and jid) then return; end + for id, t in pairs(room.people) do + if CompareJIDs(t.jid, from) then room.people[id] = nil; end + end + -- Tell everyone in room that user is leaving + for nick, t in pairs(room.people) do + SendPresence(t.jid, "unavailable", "", GetJIDParts(t.occjid).node.."@"..GetJIDParts(t.occjid).server.."/"..people[jid].nick); + end +end + +function FSay(room, fromnick, text) + BroadcastMessage(room.people, fromnick , text); +end + +function PSay(room, tonick, fromnick, text) + --print(string.format("Room JID: %s, To: %s, From: %s\n", room.jid, tonick, fromnick)); + for k,v in pairs(room.people) do print(string.format("people[\"%s\"]", k),", "); end + print("\n"); + -- room.jid..(((fromnick and fromnick:len() > 0) and "/"..fromnick) or "") + SendMessage(room.people[tonick].jid, room.people[tonick].occjid, text or "", (fromnick and fromnick:len() > 0 and "groupchat") or "groupchat"); +end + +dofile("common.lua"); + +rooms = rooms or { }; +people = people or setmetatable({ default = {} }, { __newindex = function (t, k, v) if not rawget(v, "_parent") then rawset(v, "_parent", rawget(t, "default")); end return rawset(t, k, setmetatable(v, { __index = occupant })); end }); -- This is our inheritance code;