|
1 --[[ Lua XMPP MOO Component by Matthew Wild (MattJ) ]] |
|
2 |
|
3 BotName = "Component"; |
|
4 BotPass = ""; |
|
5 |
|
6 function onPresence(msg) |
|
7 success, message = pcall(handlePresence, msg); |
|
8 if not success then print("\nERROR: "..message.."\n"); end |
|
9 end |
|
10 |
|
11 function onConnect() |
|
12 end |
|
13 |
|
14 function onMessage(msg) |
|
15 success, message = pcall(handleMessage, msg); |
|
16 if not success then print("\nERROR: "..message.."\n"); end |
|
17 end |
|
18 |
|
19 |
|
20 function handlePresence(msg) |
|
21 local room, server, nick, id, person; |
|
22 room,server,nick = msg.to:match("^(.+)@(.+)/(.+)$"); |
|
23 if not (room and nick) then print("\nERROR: Invalid room or nick!\n"); return; end -- We need to send an error |
|
24 -- print("Type: "..msg.type.." type of type: "..type(msg.type),"\n"); |
|
25 if msg.type == "available" or msg.type == "" and not people[msg.fromFull] then |
|
26 print("\nRecieved Available presence to join a room\n"); |
|
27 people[msg.fromFull] = { ["nick"] = nick, ["jid"] = msg.fromFull, ["presence"] = msg.type, room = rooms[room], occjid = msg.to, _parent = occupant, group = {}, _contents = { ["in"] = createcontainertable(); } } |
|
28 MoveToRoom(people[msg.fromFull], room); |
|
29 -- rooms[room].people[nick] = people[msg.fromFull]; |
|
30 --for id, person in pairs(rooms[room].people) do |
|
31 -- SendPresence(msg.fromFull, person.presence, "", room.."@"..server.."/"..person.nick); |
|
32 --end |
|
33 elseif msg.type == "unavailable" then |
|
34 RemoveFromRoom(rooms[room], msg.fromFull); |
|
35 people[msg.fromFull] = nil; |
|
36 end |
|
37 print("Returning\n"); |
|
38 SendPresence(msg.fromFull, msg.type, "", msg.to); |
|
39 end |
|
40 |
|
41 |
|
42 |
|
43 function handleMessage(msg) |
|
44 local action, object, room, server, person; |
|
45 person = people[msg.fromFull] |
|
46 if msg.type == MSG_ERROR then print("ERROR MESSAGE from "..msg.fromFull..": ", msg.body); return nil; end |
|
47 if not person then print("No such person as "..msg.fromFull, tostring(people[msg.fromFull]).."\n"); |
|
48 for k,v in pairs(people) do print(string.format("people[\"%s\"]", k),", "); end return nil; end |
|
49 room, server = msg.to:match("^(.+)@(.+)$"); |
|
50 if not (room and server) then print("ERROR! Malformed JID? "..msg.to.."\n"); return nil; end --TODO: Reply with error |
|
51 server = server:lower(); |
|
52 if not rooms[room] then return; end -- TODO: Reply with error |
|
53 |
|
54 person:_processCommand(msg.body); |
|
55 |
|
56 return nil; |
|
57 end |
|
58 |
|
59 function BroadcastPresence(people, fromnick, ptype, text) |
|
60 local nick, t; |
|
61 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 |
|
62 if not people then print("No such room. \n"); return; end |
|
63 for nick, t in pairs(people) do |
|
64 if t and t.jid then |
|
65 SendPresence(t.jid, ptype or "available", text or "", GetJIDParts(t.occjid).node.."@"..GetJIDParts(t.occjid).server.."/"..fromnick); |
|
66 else print("\nOrphaned occupant: "..nick, "\n"); |
|
67 end |
|
68 end |
|
69 end |
|
70 |
|
71 function BroadcastMessage(people_, from, text, mtype, sender_sees) |
|
72 local nick, t |
|
73 for nick, t in pairs(people_) do |
|
74 print("\nMessage sent to: "..t.jid); |
|
75 if t.nick ~= from or sender_sees ~= false then |
|
76 SendMessage(t.jid, GetJIDParts(t.occjid).node.."@"..GetJIDParts(t.occjid).server.."/"..from, text or "", mtype or "groupchat"); |
|
77 end |
|
78 end |
|
79 print("\nDone\n"); |
|
80 end |
|
81 |
|
82 function GetOccupantNick(jid) |
|
83 local pjid, p |
|
84 for pjid, p in pairs(people) do |
|
85 if CompareJIDs(pjid, jid) then return p.nick; end |
|
86 end |
|
87 return "Somebody"; |
|
88 end |
|
89 |
|
90 function CompareJIDs(j1, j2) |
|
91 if not (j1 and j2) then return false; end |
|
92 print("j2: "..type(j2)); |
|
93 j1node, j1server, j1res = j1:match("^(.+)@([%a%.]+)/?(.*)$"); |
|
94 j2node, j2server, j2res = j2:match("^(.+)@([%a%.]+)/?(.*)$"); |
|
95 if j1node == j2node and j1server:lower() == j2server:lower() and (j1res == j2res or j1res == "" or j2res == "") then return true; end |
|
96 return false; |
|
97 end |
|
98 |
|
99 function MoveToRoom(person, room) |
|
100 if not ( person and room) then return; end |
|
101 |
|
102 if type(room) ~= "table" then |
|
103 if not rooms[room] then rooms[room] = CreateObject(classes.obj_room); rooms[room]:_create{ room = room, server = GetJIDParts(person.occjid).server}; end |
|
104 room = rooms[room]; |
|
105 end |
|
106 |
|
107 if person.room ~= room then |
|
108 if person.room then |
|
109 -- Tell everyone in room that user is leaving |
|
110 --BroadcastPresence(person.room.people, person.occjid, "unavailable"); |
|
111 for nick, t in pairs(person.room.people) do |
|
112 -- print(string.format("\nPRESENCE: to: %s, from: %s, type: %s\n", t.jid, )); |
|
113 if nick ~= person.nick then |
|
114 SendPresence(t.jid, "unavailable", "", GetJIDParts(t.occjid).node.."@"..GetJIDParts(t.occjid).server.."/"..person.nick); |
|
115 end |
|
116 end |
|
117 -- Tell user that everyone else in the room has gone (clear room roster in their client) |
|
118 for nick, t in pairs(person.room.people) do |
|
119 if person.nick ~= nick then |
|
120 SendPresence(person.jid, "unavailable", "", GetJIDParts(person.occjid).node.."@"..person.room._properties.server.."/"..t.nick); |
|
121 end |
|
122 end |
|
123 person.room.people[person.nick] = nil; -- Remove from room |
|
124 end |
|
125 end |
|
126 person.room = room; |
|
127 room.people[person.nick] = person; |
|
128 --Tell user about people in the new room |
|
129 for nick, t in pairs(person.room.people) do |
|
130 -- print(string.format("\nPRESENCE: to: %s, from: %s, type: %s\n", t.jid, )); |
|
131 if nick ~= person.nick then |
|
132 SendPresence(person.jid, "available", "", GetJIDParts(person.occjid).node.."@"..GetJIDParts(person.occjid).server.."/"..nick); |
|
133 end |
|
134 end |
|
135 --Tell people in new room that user has joined |
|
136 -- BroadcastPresence(person.room.people, person.nick, "available"); |
|
137 for nick, t in pairs(person.room.people) do |
|
138 -- print(string.format("\nPRESENCE: to: %s, from: %s, type: %s\n", t.jid, )); |
|
139 if nick ~= person.nick then |
|
140 SendPresence(t.jid, "available", "", GetJIDParts(t.occjid).node.."@"..GetJIDParts(t.occjid).server.."/"..person.nick); |
|
141 end |
|
142 end |
|
143 SendPresence(person.jid, "available", "", person.occjid); |
|
144 room:_enter{ room = person.room, person = person, nick = person.nick }; |
|
145 end |
|
146 |
|
147 function RemoveFromRoom(room, jid) |
|
148 if not ( room and jid) then return; end |
|
149 for id, t in pairs(room.people) do |
|
150 if CompareJIDs(t.jid, from) then room.people[id] = nil; end |
|
151 end |
|
152 -- Tell everyone in room that user is leaving |
|
153 for nick, t in pairs(room.people) do |
|
154 SendPresence(t.jid, "unavailable", "", GetJIDParts(t.occjid).node.."@"..GetJIDParts(t.occjid).server.."/"..people[jid].nick); |
|
155 end |
|
156 end |
|
157 |
|
158 function FSay(room, fromnick, text) |
|
159 BroadcastMessage(room.people, fromnick , text); |
|
160 end |
|
161 |
|
162 function PSay(room, tonick, fromnick, text) |
|
163 --print(string.format("Room JID: %s, To: %s, From: %s\n", room.jid, tonick, fromnick)); |
|
164 for k,v in pairs(room.people) do print(string.format("people[\"%s\"]", k),", "); end |
|
165 print("\n"); |
|
166 -- room.jid..(((fromnick and fromnick:len() > 0) and "/"..fromnick) or "") |
|
167 SendMessage(room.people[tonick].jid, room.people[tonick].occjid, text or "", (fromnick and fromnick:len() > 0 and "groupchat") or "groupchat"); |
|
168 end |
|
169 |
|
170 dofile("common.lua"); |
|
171 |
|
172 rooms = rooms or { }; |
|
173 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; |