user keeping
This commit is contained in:
parent
2779ee566e
commit
9647c5a3b4
@ -50,7 +50,7 @@ _global_script_class_icons={
|
||||
|
||||
[application]
|
||||
|
||||
config/name="tochie"
|
||||
config/name="tochie-facade"
|
||||
run/main_scene="res://scenes/App.tscn"
|
||||
run/low_processor_mode=true
|
||||
config/icon="res://icon.png"
|
||||
|
@ -31,3 +31,7 @@ func _ready():
|
||||
|
||||
for room in rooms_request.value:
|
||||
var me = service.muc.join_room(room, "tochie-facade")
|
||||
if not me.is_done:
|
||||
yield(me, "done")
|
||||
|
||||
print("Chat joined")
|
||||
|
@ -12,7 +12,7 @@ class Connection extends Reference:
|
||||
|
||||
var _id_counter: int = 0
|
||||
var _pending_iqs: Dictionary # of id to GDScriptFunctionState
|
||||
var _presence_sinks: Dictionary # of Jid to [[WeakRef, String]]
|
||||
var _presence_sinks: Dictionary # of Jid to [[WeakRef, String, String]]
|
||||
var _xml_parser := Xml.Parser.new()
|
||||
|
||||
# todo: Route signals to particular receivers, based on 'from' or 'to'
|
||||
@ -59,9 +59,9 @@ class Connection extends Reference:
|
||||
|
||||
return Sums.Result.make_value(null)
|
||||
|
||||
func presence_sink(p_base_jid: String, p_sink: Object, p_signal: String) -> void:
|
||||
func presence_sink(p_base_jid: String, p_sink: Object, p_type: String, p_signal: String) -> void:
|
||||
self._presence_sinks[p_base_jid] = \
|
||||
self._presence_sinks.get(p_base_jid, []) + [[weakref(p_sink), p_signal]]
|
||||
self._presence_sinks.get(p_base_jid, []) + [[weakref(p_sink), p_type, p_signal]]
|
||||
|
||||
## Registry of connections used for poking of pending iqs.
|
||||
var _connections: Array # of WeakRef to Connection
|
||||
@ -91,7 +91,6 @@ func _process_connections() -> void:
|
||||
response = null
|
||||
|
||||
var stanza := connection._xml_parser.take_root()
|
||||
print(stanza.as_string())
|
||||
|
||||
if stanza.name == "iq":
|
||||
if "to" in stanza.attributes and stanza.attributes["to"] != connection.jid:
|
||||
@ -118,8 +117,17 @@ func _process_connections() -> void:
|
||||
if not stanza.attributes["from"].begins_with(base_jid):
|
||||
continue
|
||||
|
||||
for to_emit in connection._presence_sinks[base_jid]:
|
||||
to_emit[0].emit_signal(to_emit[1], stanza)
|
||||
var sink = connection._presence_sinks[base_jid]
|
||||
var sink_idx := 0
|
||||
while sink_idx < sink.size():
|
||||
var ref = sink[sink_idx][0].get_ref()
|
||||
if ref == null:
|
||||
sink.remove(sink_idx)
|
||||
else:
|
||||
if sink[sink_idx][1] == "signal":
|
||||
ref.emit_signal(sink[sink_idx][2], stanza)
|
||||
else: ref.call(sink[sink_idx][2], stanza)
|
||||
sink_idx += 1
|
||||
|
||||
## Collect dropped connections.
|
||||
for idx in range(to_remove.size() - 1, 0, -1):
|
||||
|
@ -8,27 +8,31 @@ class MucRoom extends Reference:
|
||||
var name: String
|
||||
var members: Dictionary # nick to MucMember
|
||||
|
||||
signal presence_received(presence)
|
||||
signal message_received(message)
|
||||
signal member_presence(member)
|
||||
|
||||
func _init() -> void:
|
||||
if self.connect("presence_received", self, "_presence_received") != OK:
|
||||
assert(false)
|
||||
signal _presence_received(presence)
|
||||
|
||||
func _presence_received(presence) -> void:
|
||||
if presence.children.size() == 0:
|
||||
return
|
||||
var x = presence.get_named_child_element("x")
|
||||
if x.name != "x" and x.attributes["xmlns"] != "http://jabber.org/protocol/muc#user":
|
||||
## Member information came.
|
||||
var item = x.get_named_child_element("item")
|
||||
var nick = presence.attributes["from"].rsplit("/").pop_front()
|
||||
var member = MucMember.new()
|
||||
member.jid = presence.attributes["from"]
|
||||
member.nick = nick
|
||||
member.role = item.attributes["role"]
|
||||
member.affiliation = item.attributes["affiliation"]
|
||||
# member.room = self
|
||||
members[nick] = member
|
||||
func _receive_internal_presence(presence) -> void:
|
||||
## First do internal book keeping ...
|
||||
if presence.children.size() > 0:
|
||||
var x = presence.get_named_child_element("x")
|
||||
if x.name == "x" and x.attributes["xmlns"] == "http://jabber.org/protocol/muc#user":
|
||||
## Member information came.
|
||||
var item = x.get_named_child_element("item")
|
||||
var nick = Stanza.extract_resource_part(presence.attributes["from"])
|
||||
var member = MucMember.new()
|
||||
member.jid = presence.attributes["from"]
|
||||
member.nick = nick
|
||||
member.role = item.attributes["role"]
|
||||
member.affiliation = item.attributes["affiliation"]
|
||||
# member.room = self
|
||||
members[nick] = member
|
||||
|
||||
emit_signal("member_presence", member)
|
||||
|
||||
## ... then propagate outside.
|
||||
emit_signal("_presence_received", presence)
|
||||
|
||||
func as_string() -> String:
|
||||
return "MucRoom \"%s\", Jid: \"%s\"" % [name, jid]
|
||||
@ -84,7 +88,7 @@ func _iq_rooms() -> Sums.Result:
|
||||
for item in query.value.children:
|
||||
if item.is_element() and item.name == "item":
|
||||
var muc_room := MucRoom.new()
|
||||
_connection.presence_sink(muc_room.jid, muc_room, "presence_received")
|
||||
_connection.presence_sink(muc_room.jid, muc_room, "method", "_receive_internal_presence")
|
||||
muc_room.jid = item.attributes["jid"]
|
||||
muc_room.name = item.attributes["name"]
|
||||
rooms.push_back(muc_room)
|
||||
@ -103,12 +107,12 @@ func _join_room(room: MucRoom, nick: String) -> Sums.Result:
|
||||
if not result.is_ok:
|
||||
return result
|
||||
|
||||
var response = Stanza.presence_result(yield(room, "presence_received"))
|
||||
var response = Stanza.presence_result(yield(room, "_presence_received"))
|
||||
if not response.is_ok:
|
||||
return response
|
||||
|
||||
while true:
|
||||
response = Stanza.presence_result(yield(room, "presence_received"))
|
||||
response = Stanza.presence_result(yield(room, "_presence_received"))
|
||||
if not response.is_ok:
|
||||
return response
|
||||
|
||||
@ -119,7 +123,7 @@ func _join_room(room: MucRoom, nick: String) -> Sums.Result:
|
||||
if x.name != "x" and x.attributes["xmlns"] != "http://jabber.org/protocol/muc#user":
|
||||
continue
|
||||
for child in x.children:
|
||||
if child.is_element() and child.name == "status" and child.attrbiutes["code"] == "110":
|
||||
if child.is_element() and child.name == "status" and child.attributes["code"] == "110":
|
||||
return Sums.Result.make_value(room.members[nick])
|
||||
|
||||
return Sums.Result.make_error(null)
|
||||
|
@ -19,6 +19,7 @@ func _service_discovery(connection: Connections.Connection) -> Sums.Result:
|
||||
|
||||
var poly_services := Array()
|
||||
for item in query.value.children:
|
||||
# todo: Do this at the same time, in separate coroutines.
|
||||
if not item.is_element() or item.name != "item":
|
||||
continue
|
||||
|
||||
|
@ -43,3 +43,8 @@ static func presence_result(stanza: Xml.XmlElement) -> Sums.Result:
|
||||
return Sums.Result.make_error(stanza)
|
||||
else:
|
||||
return Sums.Result.make_value(stanza)
|
||||
|
||||
static func extract_resource_part(jid: String) -> String:
|
||||
var parts = jid.rsplit("/")
|
||||
assert(parts.size() > 0)
|
||||
return parts[parts.size() - 1]
|
||||
|
Loading…
Reference in New Issue
Block a user