Move Jid class to xmpp-vala, partially refactor namespace
This commit is contained in:
parent
d46d071e57
commit
782ae4c049
|
@ -17,7 +17,6 @@ SOURCES
|
||||||
src/entity/conversation.vala
|
src/entity/conversation.vala
|
||||||
src/entity/encryption.vala
|
src/entity/encryption.vala
|
||||||
src/entity/file_transfer.vala
|
src/entity/file_transfer.vala
|
||||||
src/entity/jid.vala
|
|
||||||
src/entity/message.vala
|
src/entity/message.vala
|
||||||
src/entity/settings.vala
|
src/entity/settings.vala
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Entities {
|
namespace Dino.Entities {
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Entities {
|
namespace Dino.Entities {
|
||||||
|
|
||||||
public class Conversation : Object {
|
public class Conversation : Object {
|
||||||
|
@ -11,6 +13,7 @@ public class Conversation : Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int id { get; set; }
|
public int id { get; set; }
|
||||||
|
public Type type_ { get; set; }
|
||||||
public Account account { get; private set; }
|
public Account account { get; private set; }
|
||||||
public Jid counterpart { get; private set; }
|
public Jid counterpart { get; private set; }
|
||||||
public bool active { get; set; default = false; }
|
public bool active { get; set; default = false; }
|
||||||
|
@ -25,7 +28,6 @@ public class Conversation : Object {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public Encryption encryption { get; set; default = Encryption.NONE; }
|
public Encryption encryption { get; set; default = Encryption.NONE; }
|
||||||
public Type type_ { get; set; }
|
|
||||||
public Message? read_up_to { get; set; }
|
public Message? read_up_to { get; set; }
|
||||||
|
|
||||||
public enum NotifySetting { DEFAULT, ON, OFF, HIGHLIGHT }
|
public enum NotifySetting { DEFAULT, ON, OFF, HIGHLIGHT }
|
||||||
|
@ -48,14 +50,14 @@ public class Conversation : Object {
|
||||||
this.db = db;
|
this.db = db;
|
||||||
|
|
||||||
id = row[db.conversation.id];
|
id = row[db.conversation.id];
|
||||||
|
type_ = (Conversation.Type) row[db.conversation.type_];
|
||||||
account = db.get_account_by_id(row[db.conversation.account_id]);
|
account = db.get_account_by_id(row[db.conversation.account_id]);
|
||||||
string? resource = row[db.conversation.resource];
|
string? resource = row[db.conversation.resource];
|
||||||
string jid = db.get_jid_by_id(row[db.conversation.jid_id]);
|
counterpart = Jid.parse(db.get_jid_by_id(row[db.conversation.jid_id]));
|
||||||
counterpart = resource != null ? new Jid.with_resource(jid, resource) : new Jid(jid);
|
if (type_ == Conversation.Type.GROUPCHAT_PM) counterpart = counterpart.with_resource(resource);
|
||||||
active = row[db.conversation.active];
|
active = row[db.conversation.active];
|
||||||
int64? last_active = row[db.conversation.last_active];
|
int64? last_active = row[db.conversation.last_active];
|
||||||
if (last_active != null) this.last_active = new DateTime.from_unix_utc(last_active);
|
if (last_active != null) this.last_active = new DateTime.from_unix_utc(last_active);
|
||||||
type_ = (Conversation.Type) row[db.conversation.type_];
|
|
||||||
encryption = (Encryption) row[db.conversation.encryption];
|
encryption = (Encryption) row[db.conversation.encryption];
|
||||||
int? read_up_to = row[db.conversation.read_up_to];
|
int? read_up_to = row[db.conversation.read_up_to];
|
||||||
if (read_up_to != null) this.read_up_to = db.get_message_by_id(read_up_to);
|
if (read_up_to != null) this.read_up_to = db.get_message_by_id(read_up_to);
|
||||||
|
@ -95,10 +97,10 @@ public class Conversation : Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
public NotifySetting get_notification_default_setting(StreamInteractor stream_interactor) {
|
public NotifySetting get_notification_default_setting(StreamInteractor stream_interactor) {
|
||||||
Xmpp.Core.XmppStream? stream = stream_interactor.get_stream(account);
|
Xmpp.XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (!Application.get_default().settings.notifications) return NotifySetting.OFF;
|
if (!Application.get_default().settings.notifications) return NotifySetting.OFF;
|
||||||
if (type_ == Type.GROUPCHAT) {
|
if (type_ == Type.GROUPCHAT) {
|
||||||
bool members_only = stream.get_flag(Xmpp.Xep.Muc.Flag.IDENTITY).has_room_feature(counterpart.bare_jid.to_string(), Xmpp.Xep.Muc.Feature.MEMBERS_ONLY);
|
bool members_only = stream.get_flag(Xmpp.Xep.Muc.Flag.IDENTITY).has_room_feature(counterpart.bare_jid, Xmpp.Xep.Muc.Feature.MEMBERS_ONLY);
|
||||||
return members_only ? NotifySetting.ON : NotifySetting.HIGHLIGHT;
|
return members_only ? NotifySetting.ON : NotifySetting.HIGHLIGHT;
|
||||||
}
|
}
|
||||||
return NotifySetting.ON;
|
return NotifySetting.ON;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Entities {
|
namespace Dino.Entities {
|
||||||
|
|
||||||
public class FileTransfer : Object {
|
public class FileTransfer : Object {
|
||||||
|
@ -48,11 +50,12 @@ public class FileTransfer : Object {
|
||||||
|
|
||||||
string counterpart_jid = db.get_jid_by_id(row[db.file_transfer.counterpart_id]);
|
string counterpart_jid = db.get_jid_by_id(row[db.file_transfer.counterpart_id]);
|
||||||
string counterpart_resource = row[db.file_transfer.counterpart_resource];
|
string counterpart_resource = row[db.file_transfer.counterpart_resource];
|
||||||
counterpart = counterpart_resource != null ? new Jid.with_resource(counterpart_jid, counterpart_resource) : new Jid(counterpart_jid);
|
counterpart = Jid.parse(counterpart_jid);
|
||||||
|
if (counterpart_resource != null) counterpart = counterpart.with_resource(counterpart_resource);
|
||||||
|
|
||||||
string our_resource = row[db.file_transfer.our_resource];
|
string our_resource = row[db.file_transfer.our_resource];
|
||||||
if (our_resource != null) {
|
if (our_resource != null) {
|
||||||
ourpart = new Jid.with_resource(account.bare_jid.to_string(), our_resource);
|
ourpart = account.bare_jid.with_resource(our_resource);
|
||||||
} else {
|
} else {
|
||||||
ourpart = account.bare_jid;
|
ourpart = account.bare_jid;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Entities {
|
namespace Dino.Entities {
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ public class Message : Object {
|
||||||
marked_ = value;
|
marked_ = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public Xmpp.Message.Stanza stanza { get; set; }
|
public Xmpp.MessageStanza stanza { get; set; }
|
||||||
|
|
||||||
private Database? db;
|
private Database? db;
|
||||||
|
|
||||||
|
@ -67,15 +68,15 @@ public class Message : Object {
|
||||||
stanza_id = row[db.message.stanza_id];
|
stanza_id = row[db.message.stanza_id];
|
||||||
type_ = (Message.Type) row[db.message.type_];
|
type_ = (Message.Type) row[db.message.type_];
|
||||||
|
|
||||||
string counterpart_jid = db.get_jid_by_id(row[db.message.counterpart_id]);
|
counterpart = Jid.parse(db.get_jid_by_id(row[db.message.counterpart_id]));
|
||||||
string counterpart_resource = row[db.message.counterpart_resource];
|
string counterpart_resource = row[db.message.counterpart_resource];
|
||||||
counterpart = counterpart_resource != null ? new Jid.with_resource(counterpart_jid, counterpart_resource) : new Jid(counterpart_jid);
|
if (counterpart_resource != null) counterpart = counterpart.with_resource(counterpart_resource);
|
||||||
|
|
||||||
string our_resource = row[db.message.our_resource];
|
string our_resource = row[db.message.our_resource];
|
||||||
if (type_ == Type.GROUPCHAT && our_resource != null) {
|
if (type_ == Type.GROUPCHAT && our_resource != null) {
|
||||||
ourpart = new Jid.with_resource(counterpart_jid, our_resource);
|
ourpart = counterpart.with_resource(our_resource);
|
||||||
} else if (our_resource != null) {
|
} else if (our_resource != null) {
|
||||||
ourpart = new Jid.with_resource(account.bare_jid.to_string(), our_resource);
|
ourpart = account.bare_jid.with_resource(our_resource);
|
||||||
} else {
|
} else {
|
||||||
ourpart = account.bare_jid;
|
ourpart = account.bare_jid;
|
||||||
}
|
}
|
||||||
|
@ -121,9 +122,9 @@ public class Message : Object {
|
||||||
|
|
||||||
public void set_type_string(string type) {
|
public void set_type_string(string type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Xmpp.Message.Stanza.TYPE_CHAT:
|
case Xmpp.MessageStanza.TYPE_CHAT:
|
||||||
type_ = Type.CHAT; break;
|
type_ = Type.CHAT; break;
|
||||||
case Xmpp.Message.Stanza.TYPE_GROUPCHAT:
|
case Xmpp.MessageStanza.TYPE_GROUPCHAT:
|
||||||
type_ = Type.GROUPCHAT; break;
|
type_ = Type.GROUPCHAT; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,11 +132,11 @@ public class Message : Object {
|
||||||
public new string get_type_string() {
|
public new string get_type_string() {
|
||||||
switch (type_) {
|
switch (type_) {
|
||||||
case Type.CHAT:
|
case Type.CHAT:
|
||||||
return Xmpp.Message.Stanza.TYPE_CHAT;
|
return Xmpp.MessageStanza.TYPE_CHAT;
|
||||||
case Type.GROUPCHAT:
|
case Type.GROUPCHAT:
|
||||||
return Xmpp.Message.Stanza.TYPE_GROUPCHAT;
|
return Xmpp.MessageStanza.TYPE_GROUPCHAT;
|
||||||
default:
|
default:
|
||||||
return Xmpp.Message.Stanza.TYPE_NORMAL;
|
return Xmpp.MessageStanza.TYPE_NORMAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Plugins {
|
namespace Dino.Plugins {
|
||||||
|
|
||||||
|
|
|
@ -41,23 +41,19 @@ public class AvatarManager : StreamInteractionModule, Object {
|
||||||
stream_interactor.module_manager.initialize_account_modules.connect(initialize_avatar_modules);
|
stream_interactor.module_manager.initialize_account_modules.connect(initialize_avatar_modules);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initialize_avatar_modules(Account account, ArrayList<Core.XmppStreamModule> modules) {
|
private void initialize_avatar_modules(Account account, ArrayList<XmppStreamModule> modules) {
|
||||||
modules.add(new Xep.UserAvatars.Module(avatar_storage));
|
modules.add(new Xep.UserAvatars.Module(avatar_storage));
|
||||||
modules.add(new Xep.VCard.Module(avatar_storage));
|
modules.add(new Xep.VCard.Module(avatar_storage));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Pixbuf? get_avatar_by_hash(string hash) {
|
private Pixbuf? get_avatar_by_hash(string hash) {
|
||||||
lock (cached_pixbuf) {
|
|
||||||
if (cached_pixbuf.has_key(hash)) {
|
if (cached_pixbuf.has_key(hash)) {
|
||||||
return cached_pixbuf[hash];
|
return cached_pixbuf[hash];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Pixbuf? image = avatar_storage.get_image(hash);
|
Pixbuf? image = avatar_storage.get_image(hash);
|
||||||
if (image != null) {
|
if (image != null) {
|
||||||
lock (cached_pixbuf) {
|
|
||||||
cached_pixbuf[hash] = image;
|
cached_pixbuf[hash] = image;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,18 +62,14 @@ public class AvatarManager : StreamInteractionModule, Object {
|
||||||
if (!stream_interactor.get_module(MucManager.IDENTITY).is_groupchat_occupant(jid, account)) {
|
if (!stream_interactor.get_module(MucManager.IDENTITY).is_groupchat_occupant(jid, account)) {
|
||||||
jid_ = jid.bare_jid;
|
jid_ = jid.bare_jid;
|
||||||
}
|
}
|
||||||
lock(user_avatars) {
|
|
||||||
string? user_avatars_id = user_avatars[jid_];
|
string? user_avatars_id = user_avatars[jid_];
|
||||||
if (user_avatars_id != null) {
|
if (user_avatars_id != null) {
|
||||||
return get_avatar_by_hash(user_avatars_id);
|
return get_avatar_by_hash(user_avatars_id);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
lock(vcard_avatars) {
|
|
||||||
string? vcard_avatars_id = vcard_avatars[jid_];
|
string? vcard_avatars_id = vcard_avatars[jid_];
|
||||||
if (vcard_avatars_id != null) {
|
if (vcard_avatars_id != null) {
|
||||||
return get_avatar_by_hash(vcard_avatars_id);
|
return get_avatar_by_hash(vcard_avatars_id);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +85,7 @@ public class AvatarManager : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
uint8[] buffer;
|
uint8[] buffer;
|
||||||
pixbuf.save_to_buffer(out buffer, "png");
|
pixbuf.save_to_buffer(out buffer, "png");
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(account);
|
XmppStream stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
stream.get_module(Xep.UserAvatars.Module.IDENTITY).publish_png(stream, buffer, pixbuf.width, pixbuf.height);
|
stream.get_module(Xep.UserAvatars.Module.IDENTITY).publish_png(stream, buffer, pixbuf.width, pixbuf.height);
|
||||||
on_user_avatar_received(account, account.bare_jid, Base64.encode(buffer));
|
on_user_avatar_received(account, account.bare_jid, Base64.encode(buffer));
|
||||||
|
@ -105,33 +97,27 @@ public class AvatarManager : StreamInteractionModule, Object {
|
||||||
|
|
||||||
private void on_account_added(Account account) {
|
private void on_account_added(Account account) {
|
||||||
stream_interactor.module_manager.get_module(account, Xep.UserAvatars.Module.IDENTITY).received_avatar.connect((stream, jid, id) =>
|
stream_interactor.module_manager.get_module(account, Xep.UserAvatars.Module.IDENTITY).received_avatar.connect((stream, jid, id) =>
|
||||||
on_user_avatar_received(account, new Jid(jid), id)
|
on_user_avatar_received(account, jid, id)
|
||||||
);
|
);
|
||||||
stream_interactor.module_manager.get_module(account, Xep.VCard.Module.IDENTITY).received_avatar.connect((stream, jid, id) =>
|
stream_interactor.module_manager.get_module(account, Xep.VCard.Module.IDENTITY).received_avatar.connect((stream, jid, id) =>
|
||||||
on_vcard_avatar_received(account, new Jid(jid), id)
|
on_vcard_avatar_received(account, jid, id)
|
||||||
);
|
);
|
||||||
|
|
||||||
lock (user_avatars) {
|
|
||||||
user_avatars = db.get_avatar_hashes(Source.USER_AVATARS);
|
user_avatars = db.get_avatar_hashes(Source.USER_AVATARS);
|
||||||
foreach (Jid jid in user_avatars.keys) {
|
foreach (Jid jid in user_avatars.keys) {
|
||||||
on_user_avatar_received(account, jid, user_avatars[jid]);
|
on_user_avatar_received(account, jid, user_avatars[jid]);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
lock (vcard_avatars) {
|
|
||||||
vcard_avatars = db.get_avatar_hashes(Source.VCARD);
|
vcard_avatars = db.get_avatar_hashes(Source.VCARD);
|
||||||
foreach (Jid jid in vcard_avatars.keys) {
|
foreach (Jid jid in vcard_avatars.keys) {
|
||||||
on_vcard_avatar_received(account, jid, vcard_avatars[jid]);
|
on_vcard_avatar_received(account, jid, vcard_avatars[jid]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void on_user_avatar_received(Account account, Jid jid, string id) {
|
private void on_user_avatar_received(Account account, Jid jid, string id) {
|
||||||
lock (user_avatars) {
|
|
||||||
if (!user_avatars.has_key(jid) || user_avatars[jid] != id) {
|
if (!user_avatars.has_key(jid) || user_avatars[jid] != id) {
|
||||||
user_avatars[jid] = id;
|
user_avatars[jid] = id;
|
||||||
db.set_avatar_hash(jid, id, Source.USER_AVATARS);
|
db.set_avatar_hash(jid, id, Source.USER_AVATARS);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Pixbuf? avatar = avatar_storage.get_image(id);
|
Pixbuf? avatar = avatar_storage.get_image(id);
|
||||||
if (avatar != null) {
|
if (avatar != null) {
|
||||||
received_avatar(avatar, jid, account);
|
received_avatar(avatar, jid, account);
|
||||||
|
@ -139,14 +125,12 @@ public class AvatarManager : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_vcard_avatar_received(Account account, Jid jid, string id) {
|
private void on_vcard_avatar_received(Account account, Jid jid, string id) {
|
||||||
lock (vcard_avatars) {
|
|
||||||
if (!vcard_avatars.has_key(jid) || vcard_avatars[jid] != id) {
|
if (!vcard_avatars.has_key(jid) || vcard_avatars[jid] != id) {
|
||||||
vcard_avatars[jid] = id;
|
vcard_avatars[jid] = id;
|
||||||
if (!jid.is_full()) { // don't save muc avatars
|
if (!jid.is_full()) { // don't save muc avatars
|
||||||
db.set_avatar_hash(jid, id, Source.VCARD);
|
db.set_avatar_hash(jid, id, Source.VCARD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Pixbuf? avatar = avatar_storage.get_image(id);
|
Pixbuf? avatar = avatar_storage.get_image(id);
|
||||||
if (avatar != null) {
|
if (avatar != null) {
|
||||||
received_avatar(avatar, jid, account);
|
received_avatar(avatar, jid, account);
|
||||||
|
|
|
@ -21,22 +21,22 @@ public class BlockingManager : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool is_blocked(Account account, Jid jid) {
|
public bool is_blocked(Account account, Jid jid) {
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(account);
|
XmppStream stream = stream_interactor.get_stream(account);
|
||||||
return stream != null && stream.get_module(Xmpp.Xep.BlockingCommand.Module.IDENTITY).is_blocked(stream, jid.to_string());
|
return stream != null && stream.get_module(Xmpp.Xep.BlockingCommand.Module.IDENTITY).is_blocked(stream, jid.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void block(Account account, Jid jid) {
|
public void block(Account account, Jid jid) {
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(account);
|
XmppStream stream = stream_interactor.get_stream(account);
|
||||||
stream.get_module(Xmpp.Xep.BlockingCommand.Module.IDENTITY).block(stream, new ArrayList<string>.wrap(new string[] {jid.to_string()}));
|
stream.get_module(Xmpp.Xep.BlockingCommand.Module.IDENTITY).block(stream, new ArrayList<string>.wrap(new string[] {jid.to_string()}));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unblock(Account account, Jid jid) {
|
public void unblock(Account account, Jid jid) {
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(account);
|
XmppStream stream = stream_interactor.get_stream(account);
|
||||||
stream.get_module(Xmpp.Xep.BlockingCommand.Module.IDENTITY).unblock(stream, new ArrayList<string>.wrap(new string[] {jid.to_string()}));
|
stream.get_module(Xmpp.Xep.BlockingCommand.Module.IDENTITY).unblock(stream, new ArrayList<string>.wrap(new string[] {jid.to_string()}));
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool is_supported(Account account) {
|
public bool is_supported(Account account) {
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(account);
|
XmppStream stream = stream_interactor.get_stream(account);
|
||||||
return stream != null && stream.get_module(Xmpp.Xep.BlockingCommand.Module.IDENTITY).is_supported(stream);
|
return stream != null && stream.get_module(Xmpp.Xep.BlockingCommand.Module.IDENTITY).is_supported(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,7 +138,7 @@ public class ChatInteraction : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void send_chat_marker(Conversation conversation, Entities.Message message, string marker) {
|
private void send_chat_marker(Conversation conversation, Entities.Message message, string marker) {
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(conversation.account);
|
XmppStream stream = stream_interactor.get_stream(conversation.account);
|
||||||
if (stream != null &&
|
if (stream != null &&
|
||||||
(marker == Xep.ChatMarkers.MARKER_RECEIVED || conversation.get_send_marker_setting() == Conversation.Setting.ON) &&
|
(marker == Xep.ChatMarkers.MARKER_RECEIVED || conversation.get_send_marker_setting() == Conversation.Setting.ON) &&
|
||||||
Xep.ChatMarkers.Module.requests_marking(message.stanza)) {
|
Xep.ChatMarkers.Module.requests_marking(message.stanza)) {
|
||||||
|
@ -147,17 +147,17 @@ public class ChatInteraction : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void send_delivery_receipt(Conversation conversation, Entities.Message message) {
|
private void send_delivery_receipt(Conversation conversation, Entities.Message message) {
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(conversation.account);
|
XmppStream stream = stream_interactor.get_stream(conversation.account);
|
||||||
if (stream != null && Xep.MessageDeliveryReceipts.Module.requests_receipt(message.stanza)) {
|
if (stream != null && Xep.MessageDeliveryReceipts.Module.requests_receipt(message.stanza)) {
|
||||||
stream.get_module(Xep.MessageDeliveryReceipts.Module.IDENTITY).send_received(stream, message.from.to_string(), message.stanza_id);
|
stream.get_module(Xep.MessageDeliveryReceipts.Module.IDENTITY).send_received(stream, message.from, message.stanza_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void send_chat_state_notification(Conversation conversation, string state) {
|
private void send_chat_state_notification(Conversation conversation, string state) {
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(conversation.account);
|
XmppStream stream = stream_interactor.get_stream(conversation.account);
|
||||||
if (stream != null && conversation.get_send_typing_setting() == Conversation.Setting.ON &&
|
if (stream != null && conversation.get_send_typing_setting() == Conversation.Setting.ON &&
|
||||||
conversation.type_ != Conversation.Type.GROUPCHAT) {
|
conversation.type_ != Conversation.Type.GROUPCHAT) {
|
||||||
stream.get_module(Xep.ChatStateNotifications.Module.IDENTITY).send_state(stream, conversation.counterpart.to_string(), state);
|
stream.get_module(Xep.ChatStateNotifications.Module.IDENTITY).send_state(stream, conversation.counterpart, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ namespace Dino {
|
||||||
|
|
||||||
public class ConnectionManager {
|
public class ConnectionManager {
|
||||||
|
|
||||||
public signal void stream_opened(Account account, Core.XmppStream stream);
|
public signal void stream_opened(Account account, XmppStream stream);
|
||||||
public signal void connection_state_changed(Account account, ConnectionState state);
|
public signal void connection_state_changed(Account account, ConnectionState state);
|
||||||
public signal void connection_error(Account account, ConnectionError error);
|
public signal void connection_error(Account account, ConnectionError error);
|
||||||
|
|
||||||
|
@ -53,11 +53,11 @@ public class ConnectionManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Connection {
|
private class Connection {
|
||||||
public Core.XmppStream stream { get; set; }
|
public XmppStream stream { get; set; }
|
||||||
public ConnectionState connection_state { get; set; default = ConnectionState.DISCONNECTED; }
|
public ConnectionState connection_state { get; set; default = ConnectionState.DISCONNECTED; }
|
||||||
public DateTime established { get; set; }
|
public DateTime established { get; set; }
|
||||||
public DateTime last_activity { get; set; }
|
public DateTime last_activity { get; set; }
|
||||||
public class Connection(Core.XmppStream stream, DateTime established) {
|
public class Connection(XmppStream stream, DateTime established) {
|
||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
this.established = established;
|
this.established = established;
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ public class ConnectionManager {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Core.XmppStream? get_stream(Account account) {
|
public XmppStream? get_stream(Account account) {
|
||||||
if (get_state(account) == ConnectionState.CONNECTED) {
|
if (get_state(account) == ConnectionState.CONNECTED) {
|
||||||
return connections[account].stream;
|
return connections[account].stream;
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,7 @@ public class ConnectionManager {
|
||||||
return connection_todo;
|
return connection_todo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Core.XmppStream? connect(Account account) {
|
public XmppStream? connect(Account account) {
|
||||||
if (!connection_todo.contains(account)) connection_todo.add(account);
|
if (!connection_todo.contains(account)) connection_todo.add(account);
|
||||||
if (!connections.has_key(account)) {
|
if (!connections.has_key(account)) {
|
||||||
return connect_(account);
|
return connect_(account);
|
||||||
|
@ -144,16 +144,16 @@ public class ConnectionManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Core.XmppStream? connect_(Account account, string? resource = null) {
|
private XmppStream? connect_(Account account, string? resource = null) {
|
||||||
if (connections.has_key(account)) connections[account].stream.detach_modules();
|
if (connections.has_key(account)) connections[account].stream.detach_modules();
|
||||||
connection_errors.unset(account);
|
connection_errors.unset(account);
|
||||||
if (resource == null) resource = account.resourcepart;
|
if (resource == null) resource = account.resourcepart;
|
||||||
|
|
||||||
Core.XmppStream stream = new Core.XmppStream();
|
XmppStream stream = new XmppStream();
|
||||||
foreach (Core.XmppStreamModule module in module_manager.get_modules(account, resource)) {
|
foreach (XmppStreamModule module in module_manager.get_modules(account, resource)) {
|
||||||
stream.add_module(module);
|
stream.add_module(module);
|
||||||
}
|
}
|
||||||
stream.log = new Core.XmppLog(account.bare_jid.to_string(), log_options);
|
stream.log = new XmppLog(account.bare_jid.to_string(), log_options);
|
||||||
|
|
||||||
Connection connection = new Connection(stream, new DateTime.now_utc());
|
Connection connection = new Connection(stream, new DateTime.now_utc());
|
||||||
connections[account] = connection;
|
connections[account] = connection;
|
||||||
|
@ -174,7 +174,7 @@ public class ConnectionManager {
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void connect_async(Account account, Core.XmppStream stream) {
|
private async void connect_async(Account account, XmppStream stream) {
|
||||||
try {
|
try {
|
||||||
yield stream.connect(account.domainpart);
|
yield stream.connect(account.domainpart);
|
||||||
} catch (Error e) {
|
} catch (Error e) {
|
||||||
|
@ -184,7 +184,7 @@ public class ConnectionManager {
|
||||||
connections.unset(account);
|
connections.unset(account);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (e is Core.IOStreamError.TLS) {
|
if (e is IOStreamError.TLS) {
|
||||||
set_connection_error(account, new ConnectionError(ConnectionError.Source.TLS, e.message) { reconnect_recomendation=ConnectionError.Reconnect.NEVER});
|
set_connection_error(account, new ConnectionError(ConnectionError.Source.TLS, e.message) { reconnect_recomendation=ConnectionError.Reconnect.NEVER});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -236,8 +236,8 @@ public class ConnectionManager {
|
||||||
private void check_reconnect(Account account) {
|
private void check_reconnect(Account account) {
|
||||||
bool acked = false;
|
bool acked = false;
|
||||||
|
|
||||||
Core.XmppStream stream = connections[account].stream;
|
XmppStream stream = connections[account].stream;
|
||||||
stream.get_module(Xep.Ping.Module.IDENTITY).send_ping(stream, account.domainpart, (stream) => {
|
stream.get_module(Xep.Ping.Module.IDENTITY).send_ping(stream, account.bare_jid.domain_jid, (stream) => {
|
||||||
acked = true;
|
acked = true;
|
||||||
change_connection_state(account, ConnectionState.CONNECTED);
|
change_connection_state(account, ConnectionState.CONNECTED);
|
||||||
});
|
});
|
||||||
|
|
|
@ -33,9 +33,10 @@ public class ConversationManager : StreamInteractionModule, Object {
|
||||||
|
|
||||||
public Conversation create_conversation(Jid jid, Account account, Conversation.Type? type = null) {
|
public Conversation create_conversation(Jid jid, Account account, Conversation.Type? type = null) {
|
||||||
assert(conversations.has_key(account));
|
assert(conversations.has_key(account));
|
||||||
if (conversations[account].has_key(jid)) {
|
Jid store_jid = type == Conversation.Type.GROUPCHAT ? jid.bare_jid : jid;
|
||||||
conversations[account][jid].type_ = type;
|
if (conversations[account].has_key(store_jid)) {
|
||||||
return conversations[account][jid];
|
conversations[account][store_jid].type_ = type;
|
||||||
|
return conversations[account][store_jid];
|
||||||
} else {
|
} else {
|
||||||
Conversation conversation = new Conversation(jid, account, type);
|
Conversation conversation = new Conversation(jid, account, type);
|
||||||
add_conversation(conversation);
|
add_conversation(conversation);
|
||||||
|
@ -84,10 +85,11 @@ public class ConversationManager : StreamInteractionModule, Object {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Gee.List<Conversation> get_active_conversations() {
|
public Gee.List<Conversation> get_active_conversations(Account? account = null) {
|
||||||
Gee.List<Conversation> ret = new ArrayList<Conversation>(Conversation.equals_func);
|
Gee.List<Conversation> ret = new ArrayList<Conversation>(Conversation.equals_func);
|
||||||
foreach (Account account in conversations.keys) {
|
foreach (Account account_ in conversations.keys) {
|
||||||
foreach (Conversation conversation in conversations[account].values) {
|
if (account != null && !account_.equals(account)) continue;
|
||||||
|
foreach (Conversation conversation in conversations[account_].values) {
|
||||||
if(conversation.active) ret.add(conversation);
|
if(conversation.active) ret.add(conversation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,13 +37,13 @@ public class CounterpartInteractionManager : StreamInteractionModule, Object {
|
||||||
|
|
||||||
private void on_account_added(Account account) {
|
private void on_account_added(Account account) {
|
||||||
stream_interactor.module_manager.get_module(account, Xep.ChatMarkers.Module.IDENTITY).marker_received.connect( (stream, jid, marker, id) => {
|
stream_interactor.module_manager.get_module(account, Xep.ChatMarkers.Module.IDENTITY).marker_received.connect( (stream, jid, marker, id) => {
|
||||||
on_chat_marker_received(account, new Jid(jid), marker, id);
|
on_chat_marker_received(account, jid, marker, id);
|
||||||
});
|
});
|
||||||
stream_interactor.module_manager.get_module(account, Xep.MessageDeliveryReceipts.Module.IDENTITY).receipt_received.connect((stream, jid, id) => {
|
stream_interactor.module_manager.get_module(account, Xep.MessageDeliveryReceipts.Module.IDENTITY).receipt_received.connect((stream, jid, id) => {
|
||||||
on_receipt_received(account, new Jid(jid), id);
|
on_receipt_received(account, jid, id);
|
||||||
});
|
});
|
||||||
stream_interactor.module_manager.get_module(account, Xep.ChatStateNotifications.Module.IDENTITY).chat_state_received.connect((stream, jid, state) => {
|
stream_interactor.module_manager.get_module(account, Xep.ChatStateNotifications.Module.IDENTITY).chat_state_received.connect((stream, jid, state) => {
|
||||||
on_chat_state_received(account, new Jid(jid), state);
|
on_chat_state_received(account, jid, state);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -232,7 +232,7 @@ public class Database : Qlite.Database {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Gee.List<Message> get_messages(Jid jid, Account account, Message.Type? type, int count, DateTime? before) {
|
public Gee.List<Message> get_messages(Xmpp.Jid jid, Account account, Message.Type? type, int count, DateTime? before) {
|
||||||
QueryBuilder select = message.select()
|
QueryBuilder select = message.select()
|
||||||
.with(message.counterpart_id, "=", get_jid_id(jid))
|
.with(message.counterpart_id, "=", get_jid_id(jid))
|
||||||
.with(message.account_id, "=", account.id)
|
.with(message.account_id, "=", account.id)
|
||||||
|
@ -255,7 +255,7 @@ public class Database : Qlite.Database {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Gee.List<Message> get_unsend_messages(Account account, Jid? jid = null) {
|
public Gee.List<Message> get_unsend_messages(Account account, Xmpp.Jid? jid = null) {
|
||||||
Gee.List<Message> ret = new ArrayList<Message>();
|
Gee.List<Message> ret = new ArrayList<Message>();
|
||||||
var select = message.select()
|
var select = message.select()
|
||||||
.with(message.account_id, "=", account.id)
|
.with(message.account_id, "=", account.id)
|
||||||
|
@ -308,7 +308,7 @@ public class Database : Qlite.Database {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set_avatar_hash(Jid jid, string hash, int type) {
|
public void set_avatar_hash(Xmpp.Jid jid, string hash, int type) {
|
||||||
avatar.insert().or("REPLACE")
|
avatar.insert().or("REPLACE")
|
||||||
.value(avatar.jid, jid.to_string())
|
.value(avatar.jid, jid.to_string())
|
||||||
.value(avatar.hash, hash)
|
.value(avatar.hash, hash)
|
||||||
|
@ -316,10 +316,10 @@ public class Database : Qlite.Database {
|
||||||
.perform();
|
.perform();
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashMap<Jid, string> get_avatar_hashes(int type) {
|
public HashMap<Xmpp.Jid, string> get_avatar_hashes(int type) {
|
||||||
HashMap<Jid, string> ret = new HashMap<Jid, string>(Jid.hash_func, Jid.equals_func);
|
HashMap<Xmpp.Jid, string> ret = new HashMap<Xmpp.Jid, string>(Xmpp.Jid.hash_func, Xmpp.Jid.equals_func);
|
||||||
foreach (Row row in avatar.select({avatar.jid, avatar.hash}).with(avatar.type_, "=", type)) {
|
foreach (Row row in avatar.select({avatar.jid, avatar.hash}).with(avatar.type_, "=", type)) {
|
||||||
ret[new Jid(row[avatar.jid])] = row[avatar.hash];
|
ret[Xmpp.Jid.parse(row[avatar.jid])] = row[avatar.hash];
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -342,7 +342,7 @@ public class Database : Qlite.Database {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int get_jid_id(Jid jid_obj) {
|
public int get_jid_id(Xmpp.Jid jid_obj) {
|
||||||
string bare_jid = jid_obj.bare_jid.to_string();
|
string bare_jid = jid_obj.bare_jid.to_string();
|
||||||
if (jid_table_reverse.has_key(bare_jid)) {
|
if (jid_table_reverse.has_key(bare_jid)) {
|
||||||
return jid_table_reverse[bare_jid];
|
return jid_table_reverse[bare_jid];
|
||||||
|
@ -372,7 +372,7 @@ public class Database : Qlite.Database {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int add_jid(Jid jid_obj) {
|
private int add_jid(Xmpp.Jid jid_obj) {
|
||||||
string bare_jid = jid_obj.bare_jid.to_string();
|
string bare_jid = jid_obj.bare_jid.to_string();
|
||||||
int id = (int) jid.insert().value(jid.bare_jid, bare_jid).perform();
|
int id = (int) jid.insert().value(jid.bare_jid, bare_jid).perform();
|
||||||
jid_table_cache[id] = bare_jid;
|
jid_table_cache[id] = bare_jid;
|
||||||
|
|
|
@ -9,10 +9,10 @@ public class MessageProcessor : StreamInteractionModule, Object {
|
||||||
public static ModuleIdentity<MessageProcessor> IDENTITY = new ModuleIdentity<MessageProcessor>("message_processor");
|
public static ModuleIdentity<MessageProcessor> IDENTITY = new ModuleIdentity<MessageProcessor>("message_processor");
|
||||||
public string id { get { return IDENTITY.id; } }
|
public string id { get { return IDENTITY.id; } }
|
||||||
|
|
||||||
public signal void pre_message_received(Entities.Message message, Xmpp.Message.Stanza message_stanza, Conversation conversation);
|
public signal void pre_message_received(Entities.Message message, Xmpp.MessageStanza message_stanza, Conversation conversation);
|
||||||
public signal void message_received(Entities.Message message, Conversation conversation);
|
public signal void message_received(Entities.Message message, Conversation conversation);
|
||||||
public signal void build_message_stanza(Entities.Message message, Xmpp.Message.Stanza message_stanza, Conversation conversation);
|
public signal void build_message_stanza(Entities.Message message, Xmpp.MessageStanza message_stanza, Conversation conversation);
|
||||||
public signal void pre_message_send(Entities.Message message, Xmpp.Message.Stanza message_stanza, Conversation conversation);
|
public signal void pre_message_send(Entities.Message message, Xmpp.MessageStanza message_stanza, Conversation conversation);
|
||||||
public signal void message_sent(Entities.Message message, Conversation conversation);
|
public signal void message_sent(Entities.Message message, Conversation conversation);
|
||||||
|
|
||||||
private StreamInteractor stream_interactor;
|
private StreamInteractor stream_interactor;
|
||||||
|
@ -51,7 +51,7 @@ public class MessageProcessor : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_account_added(Account account) {
|
private void on_account_added(Account account) {
|
||||||
stream_interactor.module_manager.get_module(account, Xmpp.Message.Module.IDENTITY).received_message.connect( (stream, message) => {
|
stream_interactor.module_manager.get_module(account, Xmpp.MessageModule.IDENTITY).received_message.connect( (stream, message) => {
|
||||||
on_message_received(account, message);
|
on_message_received(account, message);
|
||||||
});
|
});
|
||||||
stream_interactor.module_manager.get_module(account, Xmpp.Xep.MessageArchiveManagement.Module.IDENTITY).feature_available.connect( (stream) => {
|
stream_interactor.module_manager.get_module(account, Xmpp.Xep.MessageArchiveManagement.Module.IDENTITY).feature_available.connect( (stream) => {
|
||||||
|
@ -60,7 +60,7 @@ public class MessageProcessor : StreamInteractionModule, Object {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_message_received(Account account, Xmpp.Message.Stanza message) {
|
private void on_message_received(Account account, Xmpp.MessageStanza message) {
|
||||||
if (message.body == null) return;
|
if (message.body == null) return;
|
||||||
|
|
||||||
Entities.Message new_message = create_in_message(account, message);
|
Entities.Message new_message = create_in_message(account, message);
|
||||||
|
@ -68,19 +68,18 @@ public class MessageProcessor : StreamInteractionModule, Object {
|
||||||
determine_message_type(account, message, new_message);
|
determine_message_type(account, message, new_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Entities.Message create_in_message(Account account, Xmpp.Message.Stanza message) {
|
private Entities.Message? create_in_message(Account account, Xmpp.MessageStanza message) {
|
||||||
Entities.Message new_message = new Entities.Message(message.body);
|
Entities.Message new_message = new Entities.Message(message.body);
|
||||||
new_message.account = account;
|
new_message.account = account;
|
||||||
new_message.stanza_id = message.id;
|
new_message.stanza_id = message.id;
|
||||||
Jid from_jid = new Jid(message.from);
|
if (!account.bare_jid.equals_bare(message.from) ||
|
||||||
if (!account.bare_jid.equals_bare(from_jid) ||
|
message.from.equals(stream_interactor.get_module(MucManager.IDENTITY).get_own_jid(message.from.bare_jid, account))) {
|
||||||
from_jid.equals(stream_interactor.get_module(MucManager.IDENTITY).get_own_jid(from_jid.bare_jid, account))) {
|
|
||||||
new_message.direction = Entities.Message.DIRECTION_RECEIVED;
|
new_message.direction = Entities.Message.DIRECTION_RECEIVED;
|
||||||
} else {
|
} else {
|
||||||
new_message.direction = Entities.Message.DIRECTION_SENT;
|
new_message.direction = Entities.Message.DIRECTION_SENT;
|
||||||
}
|
}
|
||||||
new_message.counterpart = new_message.direction == Entities.Message.DIRECTION_SENT ? new Jid(message.to) : new Jid(message.from);
|
new_message.counterpart = new_message.direction == Entities.Message.DIRECTION_SENT ? message.to : message.from;
|
||||||
new_message.ourpart = new_message.direction == Entities.Message.DIRECTION_SENT ? new Jid(message.from) : new Jid(message.to);
|
new_message.ourpart = new_message.direction == Entities.Message.DIRECTION_SENT ? message.from : message.to;
|
||||||
new_message.stanza = message;
|
new_message.stanza = message;
|
||||||
|
|
||||||
Xep.MessageArchiveManagement.MessageFlag? mam_message_flag = Xep.MessageArchiveManagement.MessageFlag.get_flag(message);
|
Xep.MessageArchiveManagement.MessageFlag? mam_message_flag = Xep.MessageArchiveManagement.MessageFlag.get_flag(message);
|
||||||
|
@ -94,7 +93,7 @@ public class MessageProcessor : StreamInteractionModule, Object {
|
||||||
return new_message;
|
return new_message;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void process_message(Entities.Message new_message, Xmpp.Message.Stanza stanza) {
|
private void process_message(Entities.Message new_message, Xmpp.MessageStanza stanza) {
|
||||||
Conversation? conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation_for_message(new_message);
|
Conversation? conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation_for_message(new_message);
|
||||||
if (conversation != null) {
|
if (conversation != null) {
|
||||||
pre_message_received(new_message, stanza, conversation);
|
pre_message_received(new_message, stanza, conversation);
|
||||||
|
@ -111,7 +110,7 @@ public class MessageProcessor : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_mam_message = Xep.MessageArchiveManagement.MessageFlag.get_flag(stanza) != null;
|
bool is_mam_message = Xep.MessageArchiveManagement.MessageFlag.get_flag(stanza) != null;
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(conversation.account);
|
XmppStream? stream = stream_interactor.get_stream(conversation.account);
|
||||||
Xep.MessageArchiveManagement.Flag? mam_flag = stream != null ? stream.get_flag(Xep.MessageArchiveManagement.Flag.IDENTITY) : null;
|
Xep.MessageArchiveManagement.Flag? mam_flag = stream != null ? stream.get_flag(Xep.MessageArchiveManagement.Flag.IDENTITY) : null;
|
||||||
if (is_mam_message || (mam_flag != null && mam_flag.cought_up == true)) {
|
if (is_mam_message || (mam_flag != null && mam_flag.cought_up == true)) {
|
||||||
conversation.account.mam_earliest_synced = new_message.local_time;
|
conversation.account.mam_earliest_synced = new_message.local_time;
|
||||||
|
@ -120,11 +119,11 @@ public class MessageProcessor : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void determine_message_type(Account account, Xmpp.Message.Stanza message_stanza, Entities.Message message) {
|
private void determine_message_type(Account account, Xmpp.MessageStanza message_stanza, Entities.Message message) {
|
||||||
if (message_stanza.type_ == Xmpp.Message.Stanza.TYPE_GROUPCHAT) {
|
if (message_stanza.type_ == Xmpp.MessageStanza.TYPE_GROUPCHAT) {
|
||||||
message.type_ = Entities.Message.Type.GROUPCHAT;
|
message.type_ = Entities.Message.Type.GROUPCHAT;
|
||||||
process_message(message, message_stanza);
|
process_message(message, message_stanza);
|
||||||
} else if (message_stanza.type_ == Xmpp.Message.Stanza.TYPE_CHAT) {
|
} else if (message_stanza.type_ == Xmpp.MessageStanza.TYPE_CHAT) {
|
||||||
Conversation? conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation(message.counterpart.bare_jid, account);
|
Conversation? conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation(message.counterpart.bare_jid, account);
|
||||||
if (conversation != null) {
|
if (conversation != null) {
|
||||||
if (conversation.type_ == Conversation.Type.CHAT) {
|
if (conversation.type_ == Conversation.Type.CHAT) {
|
||||||
|
@ -134,8 +133,8 @@ public class MessageProcessor : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
process_message(message, message_stanza);
|
process_message(message, message_stanza);
|
||||||
} else {
|
} else {
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(account);
|
XmppStream stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) stream.get_module(Xep.ServiceDiscovery.Module.IDENTITY).get_entity_categories(stream, message.counterpart.bare_jid.to_string(), (stream, identities) => {
|
if (stream != null) stream.get_module(Xep.ServiceDiscovery.Module.IDENTITY).get_entity_categories(stream, message.counterpart.bare_jid, (stream, identities) => {
|
||||||
if (identities == null) {
|
if (identities == null) {
|
||||||
message.type_ = Entities.Message.Type.CHAT;
|
message.type_ = Entities.Message.Type.CHAT;
|
||||||
process_message(message, message_stanza);
|
process_message(message, message_stanza);
|
||||||
|
@ -168,7 +167,7 @@ public class MessageProcessor : StreamInteractionModule, Object {
|
||||||
message.ourpart = stream_interactor.get_module(MucManager.IDENTITY).get_own_jid(conversation.counterpart, conversation.account) ?? conversation.account.bare_jid;
|
message.ourpart = stream_interactor.get_module(MucManager.IDENTITY).get_own_jid(conversation.counterpart, conversation.account) ?? conversation.account.bare_jid;
|
||||||
message.real_jid = conversation.account.bare_jid;
|
message.real_jid = conversation.account.bare_jid;
|
||||||
} else {
|
} else {
|
||||||
message.ourpart = new Jid.with_resource(conversation.account.bare_jid.to_string(), conversation.account.resourcepart);
|
message.ourpart = conversation.account.bare_jid.with_resource(conversation.account.resourcepart);
|
||||||
}
|
}
|
||||||
message.marked = Entities.Message.Marked.UNSENT;
|
message.marked = Entities.Message.Marked.UNSENT;
|
||||||
message.encryption = conversation.encryption;
|
message.encryption = conversation.encryption;
|
||||||
|
@ -177,16 +176,16 @@ public class MessageProcessor : StreamInteractionModule, Object {
|
||||||
|
|
||||||
public void send_xmpp_message(Entities.Message message, Conversation conversation, bool delayed = false) {
|
public void send_xmpp_message(Entities.Message message, Conversation conversation, bool delayed = false) {
|
||||||
lock (lock_send_unsent) {
|
lock (lock_send_unsent) {
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(conversation.account);
|
XmppStream stream = stream_interactor.get_stream(conversation.account);
|
||||||
message.marked = Entities.Message.Marked.NONE;
|
message.marked = Entities.Message.Marked.NONE;
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
Xmpp.Message.Stanza new_message = new Xmpp.Message.Stanza(message.stanza_id);
|
Xmpp.MessageStanza new_message = new Xmpp.MessageStanza(message.stanza_id);
|
||||||
new_message.to = message.counterpart.to_string();
|
new_message.to = message.counterpart;
|
||||||
new_message.body = message.body;
|
new_message.body = message.body;
|
||||||
if (conversation.type_ == Conversation.Type.GROUPCHAT) {
|
if (conversation.type_ == Conversation.Type.GROUPCHAT) {
|
||||||
new_message.type_ = Xmpp.Message.Stanza.TYPE_GROUPCHAT;
|
new_message.type_ = Xmpp.MessageStanza.TYPE_GROUPCHAT;
|
||||||
} else {
|
} else {
|
||||||
new_message.type_ = Xmpp.Message.Stanza.TYPE_CHAT;
|
new_message.type_ = Xmpp.MessageStanza.TYPE_CHAT;
|
||||||
}
|
}
|
||||||
build_message_stanza(message, new_message, conversation);
|
build_message_stanza(message, new_message, conversation);
|
||||||
pre_message_send(message, new_message, conversation);
|
pre_message_send(message, new_message, conversation);
|
||||||
|
@ -194,7 +193,7 @@ public class MessageProcessor : StreamInteractionModule, Object {
|
||||||
if (delayed) {
|
if (delayed) {
|
||||||
Xmpp.Xep.DelayedDelivery.Module.set_message_delay(new_message, message.time);
|
Xmpp.Xep.DelayedDelivery.Module.set_message_delay(new_message, message.time);
|
||||||
}
|
}
|
||||||
stream.get_module(Xmpp.Message.Module.IDENTITY).send_message(stream, new_message);
|
stream.get_module(Xmpp.MessageModule.IDENTITY).send_message(stream, new_message);
|
||||||
message.stanza_id = new_message.id;
|
message.stanza_id = new_message.id;
|
||||||
message.stanza = new_message;
|
message.stanza = new_message;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -6,17 +6,17 @@ using Xmpp;
|
||||||
namespace Dino {
|
namespace Dino {
|
||||||
|
|
||||||
public class ModuleManager {
|
public class ModuleManager {
|
||||||
private HashMap<Account, ArrayList<Core.XmppStreamModule>> module_map = new HashMap<Account, ArrayList<Core.XmppStreamModule>>();
|
private HashMap<Account, ArrayList<XmppStreamModule>> module_map = new HashMap<Account, ArrayList<XmppStreamModule>>();
|
||||||
|
|
||||||
private EntityCapabilitiesStorage entity_capabilities_storage;
|
private EntityCapabilitiesStorage entity_capabilities_storage;
|
||||||
|
|
||||||
public signal void initialize_account_modules(Account account, ArrayList<Core.XmppStreamModule> modules);
|
public signal void initialize_account_modules(Account account, ArrayList<XmppStreamModule> modules);
|
||||||
|
|
||||||
public ModuleManager(Database db) {
|
public ModuleManager(Database db) {
|
||||||
entity_capabilities_storage = new EntityCapabilitiesStorage(db);
|
entity_capabilities_storage = new EntityCapabilitiesStorage(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
public T? get_module<T>(Account account, Core.ModuleIdentity<T> identity) {
|
public T? get_module<T>(Account account, Xmpp.ModuleIdentity<T> identity) {
|
||||||
if (identity == null) return null;
|
if (identity == null) return null;
|
||||||
lock (module_map) {
|
lock (module_map) {
|
||||||
if (!module_map.has_key(account)) {
|
if (!module_map.has_key(account)) {
|
||||||
|
@ -30,15 +30,15 @@ public class ModuleManager {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<Core.XmppStreamModule> get_modules(Account account, string? resource = null) {
|
public ArrayList<XmppStreamModule> get_modules(Account account, string? resource = null) {
|
||||||
ArrayList<Core.XmppStreamModule> modules = new ArrayList<Core.XmppStreamModule>();
|
ArrayList<XmppStreamModule> modules = new ArrayList<XmppStreamModule>();
|
||||||
|
|
||||||
lock (module_map) {
|
lock (module_map) {
|
||||||
if (!module_map.has_key(account)) initialize(account);
|
if (!module_map.has_key(account)) initialize(account);
|
||||||
foreach (Core.XmppStreamModule module in module_map[account]) modules.add(module);
|
foreach (XmppStreamModule module in module_map[account]) modules.add(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Core.XmppStreamModule module in module_map[account]) {
|
foreach (XmppStreamModule module in module_map[account]) {
|
||||||
if (module.get_id() == Bind.Module.IDENTITY.id) {
|
if (module.get_id() == Bind.Module.IDENTITY.id) {
|
||||||
(module as Bind.Module).requested_resource == null ? account.resourcepart : resource;
|
(module as Bind.Module).requested_resource == null ? account.resourcepart : resource;
|
||||||
} else if (module.get_id() == PlainSasl.Module.IDENTITY.id) {
|
} else if (module.get_id() == PlainSasl.Module.IDENTITY.id) {
|
||||||
|
@ -50,7 +50,7 @@ public class ModuleManager {
|
||||||
|
|
||||||
public void initialize(Account account) {
|
public void initialize(Account account) {
|
||||||
lock(module_map) {
|
lock(module_map) {
|
||||||
module_map[account] = new ArrayList<Core.XmppStreamModule>();
|
module_map[account] = new ArrayList<XmppStreamModule>();
|
||||||
module_map[account].add(new Iq.Module());
|
module_map[account].add(new Iq.Module());
|
||||||
module_map[account].add(new Tls.Module());
|
module_map[account].add(new Tls.Module());
|
||||||
module_map[account].add(new Xep.SrvRecordsTls.Module());
|
module_map[account].add(new Xep.SrvRecordsTls.Module());
|
||||||
|
@ -63,7 +63,7 @@ public class ModuleManager {
|
||||||
module_map[account].add(new Xep.PrivateXmlStorage.Module());
|
module_map[account].add(new Xep.PrivateXmlStorage.Module());
|
||||||
module_map[account].add(new Xep.Bookmarks.Module());
|
module_map[account].add(new Xep.Bookmarks.Module());
|
||||||
module_map[account].add(new Presence.Module());
|
module_map[account].add(new Presence.Module());
|
||||||
module_map[account].add(new Xmpp.Message.Module());
|
module_map[account].add(new Xmpp.MessageModule());
|
||||||
module_map[account].add(new Xep.MessageArchiveManagement.Module());
|
module_map[account].add(new Xep.MessageArchiveManagement.Module());
|
||||||
module_map[account].add(new Xep.MessageCarbons.Module());
|
module_map[account].add(new Xep.MessageCarbons.Module());
|
||||||
module_map[account].add(new Xep.Muc.Module());
|
module_map[account].add(new Xep.Muc.Module());
|
||||||
|
|
|
@ -30,7 +30,7 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void join(Account account, Jid jid, string? nick, string? password) {
|
public void join(Account account, Jid jid, string? nick, string? password) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream == null) return;
|
if (stream == null) return;
|
||||||
string nick_ = nick ?? account.bare_jid.localpart ?? account.bare_jid.domainpart;
|
string nick_ = nick ?? account.bare_jid.localpart ?? account.bare_jid.domainpart;
|
||||||
|
|
||||||
|
@ -41,14 +41,14 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
if (last_message != null) history_since = last_message.time;
|
if (last_message != null) history_since = last_message.time;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream.get_module(Xep.Muc.Module.IDENTITY).enter(stream, jid.bare_jid.to_string(), nick_, password, history_since);
|
stream.get_module(Xep.Muc.Module.IDENTITY).enter(stream, jid.bare_jid, nick_, password, history_since);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void part(Account account, Jid jid) {
|
public void part(Account account, Jid jid) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream == null) return;
|
if (stream == null) return;
|
||||||
unset_autojoin(stream, jid);
|
unset_autojoin(stream, jid);
|
||||||
stream.get_module(Xep.Muc.Module.IDENTITY).exit(stream, jid.bare_jid.to_string());
|
stream.get_module(Xep.Muc.Module.IDENTITY).exit(stream, jid.bare_jid);
|
||||||
|
|
||||||
Conversation? conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation(jid, account);
|
Conversation? conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation(jid, account);
|
||||||
if (conversation != null) stream_interactor.get_module(ConversationManager.IDENTITY).close_conversation(conversation);
|
if (conversation != null) stream_interactor.get_module(ConversationManager.IDENTITY).close_conversation(conversation);
|
||||||
|
@ -56,53 +56,53 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
|
|
||||||
public delegate void OnResult(Jid jid, Xep.DataForms.DataForm data_form);
|
public delegate void OnResult(Jid jid, Xep.DataForms.DataForm data_form);
|
||||||
public void get_config_form(Account account, Jid jid, owned OnResult listener) {
|
public void get_config_form(Account account, Jid jid, owned OnResult listener) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream == null) return;
|
if (stream == null) return;
|
||||||
stream.get_module(Xep.Muc.Module.IDENTITY).get_config_form(stream, jid.to_string(), (stream, jid, data_form) => {
|
stream.get_module(Xep.Muc.Module.IDENTITY).get_config_form(stream, jid, (stream, jid, data_form) => {
|
||||||
listener(new Jid(jid), data_form);
|
listener(jid, data_form);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void change_subject(Account account, Jid jid, string subject) {
|
public void change_subject(Account account, Jid jid, string subject) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).change_subject(stream, jid.bare_jid.to_string(), subject);
|
if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).change_subject(stream, jid.bare_jid, subject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void change_nick(Account account, Jid jid, string new_nick) {
|
public void change_nick(Account account, Jid jid, string new_nick) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).change_nick(stream, jid.bare_jid.to_string(), new_nick);
|
if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).change_nick(stream, jid.bare_jid, new_nick);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void invite(Account account, Jid muc, Jid invitee) {
|
public void invite(Account account, Jid muc, Jid invitee) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).invite(stream, muc.bare_jid.to_string(), invitee.bare_jid.to_string());
|
if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).invite(stream, muc.bare_jid, invitee.bare_jid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void kick(Account account, Jid jid, string nick) {
|
public void kick(Account account, Jid jid, string nick) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).kick(stream, jid.bare_jid.to_string(), nick);
|
if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).kick(stream, jid.bare_jid, nick);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void change_affiliation(Account account, Jid jid, string nick, string role) {
|
public void change_affiliation(Account account, Jid jid, string nick, string role) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).change_affiliation(stream, jid.bare_jid.to_string(), nick, role);
|
if (stream != null) stream.get_module(Xep.Muc.Module.IDENTITY).change_affiliation(stream, jid.bare_jid, nick, role);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool kick_possible(Account account, Jid occupant) {
|
public bool kick_possible(Account account, Jid occupant) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) return stream.get_module(Xep.Muc.Module.IDENTITY).kick_possible(stream, occupant.to_string());
|
if (stream != null) return stream.get_module(Xep.Muc.Module.IDENTITY).kick_possible(stream, occupant);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<Jid>? get_occupants(Jid jid, Account account) {
|
public Gee.List<Jid>? get_occupants(Jid jid, Account account) {
|
||||||
if (is_groupchat(jid, account)) {
|
if (is_groupchat(jid, account)) {
|
||||||
return stream_interactor.get_module(PresenceManager.IDENTITY).get_full_jids(jid, account);
|
return stream_interactor.get_module(PresenceManager.IDENTITY).get_full_jids(jid, account);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<Jid>? get_other_occupants(Jid jid, Account account) {
|
public Gee.List<Jid>? get_other_occupants(Jid jid, Account account) {
|
||||||
ArrayList<Jid>? occupants = get_occupants(jid, account);
|
Gee.List<Jid>? occupants = get_occupants(jid, account);
|
||||||
Jid? own_jid = get_own_jid(jid, account);
|
Jid? own_jid = get_own_jid(jid, account);
|
||||||
if (occupants != null && own_jid != null) {
|
if (occupants != null && own_jid != null) {
|
||||||
occupants.remove(own_jid);
|
occupants.remove(own_jid);
|
||||||
|
@ -120,87 +120,79 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void get_bookmarks(Account account, owned Xep.Bookmarks.Module.OnResult listener) {
|
public void get_bookmarks(Account account, owned Xep.Bookmarks.Module.OnResult listener) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) stream.get_module(Xep.Bookmarks.Module.IDENTITY).get_conferences(stream, (owned)listener);
|
if (stream != null) stream.get_module(Xep.Bookmarks.Module.IDENTITY).get_conferences(stream, (owned)listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add_bookmark(Account account, Xep.Bookmarks.Conference conference) {
|
public void add_bookmark(Account account, Xep.Bookmarks.Conference conference) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
stream.get_module(Xep.Bookmarks.Module.IDENTITY).add_conference(stream, conference);
|
stream.get_module(Xep.Bookmarks.Module.IDENTITY).add_conference(stream, conference);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void replace_bookmark(Account account, Xep.Bookmarks.Conference was, Xep.Bookmarks.Conference replace) {
|
public void replace_bookmark(Account account, Xep.Bookmarks.Conference was, Xep.Bookmarks.Conference replace) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
stream.get_module(Xep.Bookmarks.Module.IDENTITY).replace_conference(stream, was, replace);
|
stream.get_module(Xep.Bookmarks.Module.IDENTITY).replace_conference(stream, was, replace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove_bookmark(Account account, Xep.Bookmarks.Conference conference) {
|
public void remove_bookmark(Account account, Xep.Bookmarks.Conference conference) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
stream.get_module(Xep.Bookmarks.Module.IDENTITY).remove_conference(stream, conference);
|
stream.get_module(Xep.Bookmarks.Module.IDENTITY).remove_conference(stream, conference);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string? get_room_name(Account account, Jid jid) {
|
public string? get_room_name(Account account, Jid jid) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
return stream != null ? stream.get_flag(Xep.Muc.Flag.IDENTITY).get_room_name(jid.to_string()) : null;
|
return stream != null ? stream.get_flag(Xep.Muc.Flag.IDENTITY).get_room_name(jid) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string? get_groupchat_subject(Jid jid, Account account) {
|
public string? get_groupchat_subject(Jid jid, Account account) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
return stream.get_flag(Xep.Muc.Flag.IDENTITY).get_muc_subject(jid.bare_jid.to_string());
|
return stream.get_flag(Xep.Muc.Flag.IDENTITY).get_muc_subject(jid.bare_jid);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Jid? get_real_jid(Jid jid, Account account) {
|
public Jid? get_real_jid(Jid jid, Account account) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
string? real_jid = stream.get_flag(Xep.Muc.Flag.IDENTITY).get_real_jid(jid.to_string());
|
return stream.get_flag(Xep.Muc.Flag.IDENTITY).get_real_jid(jid);
|
||||||
if (real_jid != null) {
|
|
||||||
return new Jid(real_jid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Xep.Muc.Role? get_role(Jid jid, Account account) {
|
public Xep.Muc.Role? get_role(Jid jid, Account account) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) return stream.get_flag(Xep.Muc.Flag.IDENTITY).get_occupant_role(jid.to_string());
|
if (stream != null) return stream.get_flag(Xep.Muc.Flag.IDENTITY).get_occupant_role(jid);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Xep.Muc.Affiliation? get_affiliation(Jid muc_jid, Jid jid, Account account) {
|
public Xep.Muc.Affiliation? get_affiliation(Jid muc_jid, Jid jid, Account account) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) return stream.get_flag(Xep.Muc.Flag.IDENTITY).get_affiliation(muc_jid.to_string(), jid.to_string());
|
if (stream != null) return stream.get_flag(Xep.Muc.Flag.IDENTITY).get_affiliation(muc_jid, jid);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Gee.List<Jid>? get_offline_members(Jid jid, Account account) {
|
public Gee.List<Jid>? get_offline_members(Jid jid, Account account) {
|
||||||
Gee.List<Jid> ret = new ArrayList<Jid>(Jid.equals_func);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
Gee.List<string>? members = stream.get_flag(Xep.Muc.Flag.IDENTITY).get_offline_members(jid.to_string());
|
return stream.get_flag(Xep.Muc.Flag.IDENTITY).get_offline_members(jid);
|
||||||
if (members == null) return null;
|
|
||||||
foreach (string member in members) {
|
|
||||||
ret.add(new Jid(member));
|
|
||||||
}
|
}
|
||||||
}
|
return null;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Jid? get_own_jid(Jid muc_jid, Account account) {
|
public Jid? get_own_jid(Jid muc_jid, Account account) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
Xep.Muc.Flag? flag = stream.get_flag(Xep.Muc.Flag.IDENTITY);
|
Xep.Muc.Flag? flag = stream.get_flag(Xep.Muc.Flag.IDENTITY);
|
||||||
if (flag == null) return null;
|
if (flag == null) return null;
|
||||||
string? nick = flag.get_muc_nick(muc_jid.bare_jid.to_string());
|
string? nick = flag.get_muc_nick(muc_jid);
|
||||||
if (nick != null) return new Jid.with_resource(muc_jid.bare_jid.to_string(), nick);
|
if (nick != null) return muc_jid.with_resource(nick);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -210,23 +202,21 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_account_added(Account account) {
|
private void on_account_added(Account account) {
|
||||||
stream_interactor.module_manager.get_module(account, Xep.Muc.Module.IDENTITY).room_entered.connect( (stream, jid_string, nick) => {
|
stream_interactor.module_manager.get_module(account, Xep.Muc.Module.IDENTITY).room_entered.connect( (stream, jid, nick) => {
|
||||||
Jid jid = new Jid(jid_string);
|
|
||||||
enter_errors.unset(jid);
|
enter_errors.unset(jid);
|
||||||
set_autojoin(stream, jid, nick, null); // TODO password
|
set_autojoin(stream, jid, nick, null); // TODO password
|
||||||
joined(account, jid, nick);
|
joined(account, jid, nick);
|
||||||
stream_interactor.get_module(MessageProcessor.IDENTITY).send_unsent_messages(account, jid);
|
stream_interactor.get_module(MessageProcessor.IDENTITY).send_unsent_messages(account, jid);
|
||||||
});
|
});
|
||||||
stream_interactor.module_manager.get_module(account, Xep.Muc.Module.IDENTITY).room_enter_error.connect( (stream, jid_str, error) => {
|
stream_interactor.module_manager.get_module(account, Xep.Muc.Module.IDENTITY).room_enter_error.connect( (stream, jid, error) => {
|
||||||
Jid jid = new Jid(jid_str);
|
|
||||||
enter_errors[jid] = error;
|
enter_errors[jid] = error;
|
||||||
enter_error(account, jid, error);
|
enter_error(account, jid, error);
|
||||||
});
|
});
|
||||||
stream_interactor.module_manager.get_module(account, Xep.Muc.Module.IDENTITY).self_removed_from_room.connect( (stream, jid, code) => {
|
stream_interactor.module_manager.get_module(account, Xep.Muc.Module.IDENTITY).self_removed_from_room.connect( (stream, jid, code) => {
|
||||||
left(account, new Jid(jid));
|
left(account, jid);
|
||||||
});
|
});
|
||||||
stream_interactor.module_manager.get_module(account, Xep.Muc.Module.IDENTITY).subject_set.connect( (stream, subject, jid) => {
|
stream_interactor.module_manager.get_module(account, Xep.Muc.Module.IDENTITY).subject_set.connect( (stream, subject, jid) => {
|
||||||
subject_set(account, new Jid(jid), subject);
|
subject_set(account, jid, subject);
|
||||||
});
|
});
|
||||||
stream_interactor.module_manager.get_module(account, Xep.Bookmarks.Module.IDENTITY).received_conferences.connect( (stream, conferences) => {
|
stream_interactor.module_manager.get_module(account, Xep.Bookmarks.Module.IDENTITY).received_conferences.connect( (stream, conferences) => {
|
||||||
sync_autojoin_active(account, conferences);
|
sync_autojoin_active(account, conferences);
|
||||||
|
@ -234,29 +224,28 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_stream_negotiated(Account account, Core.XmppStream stream) {
|
private void on_stream_negotiated(Account account, XmppStream stream) {
|
||||||
stream.get_module(Xep.Bookmarks.Module.IDENTITY).get_conferences(stream, (stream, conferences) => {
|
stream.get_module(Xep.Bookmarks.Module.IDENTITY).get_conferences(stream, (stream, conferences) => {
|
||||||
foreach (Xep.Bookmarks.Conference bookmark in conferences) {
|
foreach (Xep.Bookmarks.Conference bookmark in conferences) {
|
||||||
Jid jid = new Jid(bookmark.jid);
|
|
||||||
if (bookmark.autojoin) {
|
if (bookmark.autojoin) {
|
||||||
join(account, jid, bookmark.nick, bookmark.password);
|
join(account, bookmark.jid, bookmark.nick, bookmark.password);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_pre_message_received(Entities.Message message, Xmpp.Message.Stanza message_stanza, Conversation conversation) {
|
private void on_pre_message_received(Entities.Message message, Xmpp.MessageStanza message_stanza, Conversation conversation) {
|
||||||
if (conversation.type_ != Conversation.Type.GROUPCHAT) return;
|
if (conversation.type_ != Conversation.Type.GROUPCHAT) return;
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(conversation.account);
|
XmppStream stream = stream_interactor.get_stream(conversation.account);
|
||||||
if (stream == null) return;
|
if (stream == null) return;
|
||||||
if (Xep.DelayedDelivery.MessageFlag.get_flag(message.stanza) == null) {
|
if (Xep.DelayedDelivery.MessageFlag.get_flag(message.stanza) == null) {
|
||||||
string? real_jid = stream.get_flag(Xep.Muc.Flag.IDENTITY).get_real_jid(message.counterpart.to_string());
|
Jid? real_jid = stream.get_flag(Xep.Muc.Flag.IDENTITY).get_real_jid(message.counterpart);
|
||||||
if (real_jid != null && real_jid != message.counterpart.to_string()) {
|
if (real_jid != null && !real_jid.equals(message.counterpart)) {
|
||||||
message.real_jid = new Jid(real_jid).bare_jid;
|
message.real_jid = real_jid.bare_jid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
string? muc_nick = stream.get_flag(Xep.Muc.Flag.IDENTITY).get_muc_nick(conversation.counterpart.bare_jid.to_string());
|
string? muc_nick = stream.get_flag(Xep.Muc.Flag.IDENTITY).get_muc_nick(conversation.counterpart.bare_jid);
|
||||||
if (muc_nick != null && message.from.equals(new Jid(@"$(message.from.bare_jid)/$muc_nick"))) { // TODO better from own
|
if (muc_nick != null && message.from.equals(message.from.with_resource(muc_nick))) { // TODO better from own
|
||||||
Gee.List<Entities.Message> messages = stream_interactor.get_module(MessageStorage.IDENTITY).get_messages(conversation);
|
Gee.List<Entities.Message> messages = stream_interactor.get_module(MessageStorage.IDENTITY).get_messages(conversation);
|
||||||
foreach (Entities.Message m in messages) { // TODO not here
|
foreach (Entities.Message m in messages) { // TODO not here
|
||||||
if (m.equals(message)) {
|
if (m.equals(message)) {
|
||||||
|
@ -267,7 +256,7 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sync_autojoin_active(Account account, Gee.List<Xep.Bookmarks.Conference> conferences) {
|
private void sync_autojoin_active(Account account, Gee.List<Xep.Bookmarks.Conference> conferences) {
|
||||||
Gee.List<Conversation> conversations = stream_interactor.get_module(ConversationManager.IDENTITY).get_active_conversations();
|
Gee.List<Conversation> conversations = stream_interactor.get_module(ConversationManager.IDENTITY).get_active_conversations(account);
|
||||||
leave_non_autojoin(account, conferences, conversations);
|
leave_non_autojoin(account, conferences, conversations);
|
||||||
join_autojoin(account, conferences, conversations);
|
join_autojoin(account, conferences, conversations);
|
||||||
}
|
}
|
||||||
|
@ -277,7 +266,7 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
if (conversation.type_ != Conversation.Type.GROUPCHAT || !conversation.account.equals(account)) continue;
|
if (conversation.type_ != Conversation.Type.GROUPCHAT || !conversation.account.equals(account)) continue;
|
||||||
bool is_autojoin = false;
|
bool is_autojoin = false;
|
||||||
foreach (Xep.Bookmarks.Conference conference in conferences) {
|
foreach (Xep.Bookmarks.Conference conference in conferences) {
|
||||||
if (conference.jid == conversation.counterpart.to_string()) {
|
if (conference.jid.equals(conversation.counterpart)) {
|
||||||
if (conference.autojoin) is_autojoin = true;
|
if (conference.autojoin) is_autojoin = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -292,19 +281,20 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
if (!conference.autojoin) continue;
|
if (!conference.autojoin) continue;
|
||||||
bool is_active = false;
|
bool is_active = false;
|
||||||
foreach (Conversation conversation in conversations) {
|
foreach (Conversation conversation in conversations) {
|
||||||
if (conference.jid == conversation.counterpart.to_string()) is_active = true;
|
if (conference.jid.equals(conversation.counterpart)) is_active = true;
|
||||||
}
|
}
|
||||||
if (!is_active) {
|
if (!is_active) {
|
||||||
join(account, new Jid(conference.jid), conference.nick, conference.password);
|
join(account, conference.jid, conference.nick, conference.password);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void set_autojoin(Core.XmppStream stream, Jid jid, string? nick, string? password) {
|
private void set_autojoin(XmppStream stream, Jid jid, string? nick, string? password) {
|
||||||
stream.get_module(Xep.Bookmarks.Module.IDENTITY).get_conferences(stream, (stream, conferences) => {
|
stream.get_module(Xep.Bookmarks.Module.IDENTITY).get_conferences(stream, (stream, conferences) => {
|
||||||
Xep.Bookmarks.Conference changed = new Xep.Bookmarks.Conference(jid.to_string()) { nick=nick, password=password, autojoin=true };
|
if (conferences == null) return;
|
||||||
|
Xep.Bookmarks.Conference changed = new Xep.Bookmarks.Conference(jid) { nick=nick, password=password, autojoin=true };
|
||||||
foreach (Xep.Bookmarks.Conference conference in conferences) {
|
foreach (Xep.Bookmarks.Conference conference in conferences) {
|
||||||
if (conference.jid == jid.bare_jid.to_string() && conference.nick == nick && conference.password == password) {
|
if (conference.jid.equals_bare(jid) && conference.nick == nick && conference.password == password) {
|
||||||
if (!conference.autojoin) {
|
if (!conference.autojoin) {
|
||||||
stream.get_module(Xep.Bookmarks.Module.IDENTITY).replace_conference(stream, conference, changed);
|
stream.get_module(Xep.Bookmarks.Module.IDENTITY).replace_conference(stream, conference, changed);
|
||||||
}
|
}
|
||||||
|
@ -315,10 +305,11 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void unset_autojoin(Core.XmppStream stream, Jid jid) {
|
private void unset_autojoin(XmppStream stream, Jid jid) {
|
||||||
stream.get_module(Xep.Bookmarks.Module.IDENTITY).get_conferences(stream, (stream, conferences) => {
|
stream.get_module(Xep.Bookmarks.Module.IDENTITY).get_conferences(stream, (stream, conferences) => {
|
||||||
|
if (conferences == null) return;
|
||||||
foreach (Xep.Bookmarks.Conference conference in conferences) {
|
foreach (Xep.Bookmarks.Conference conference in conferences) {
|
||||||
if (conference.jid == jid.bare_jid.to_string()) {
|
if (conference.jid.equals_bare(jid)) {
|
||||||
if (conference.autojoin) {
|
if (conference.autojoin) {
|
||||||
Xep.Bookmarks.Conference change = new Xep.Bookmarks.Conference(conference.jid) { nick=conference.nick, password=conference.password, autojoin=false };
|
Xep.Bookmarks.Conference change = new Xep.Bookmarks.Conference(conference.jid) { nick=conference.nick, password=conference.password, autojoin=false };
|
||||||
stream.get_module(Xep.Bookmarks.Module.IDENTITY).replace_conference(stream, conference, change);
|
stream.get_module(Xep.Bookmarks.Module.IDENTITY).replace_conference(stream, conference, change);
|
||||||
|
|
|
@ -27,9 +27,9 @@ public class PresenceManager : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Show get_last_show(Jid jid, Account account) {
|
public Show get_last_show(Jid jid, Account account) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
Xmpp.Presence.Stanza? presence = stream.get_flag(Presence.Flag.IDENTITY).get_presence(jid.to_string());
|
Xmpp.Presence.Stanza? presence = stream.get_flag(Presence.Flag.IDENTITY).get_presence(jid);
|
||||||
if (presence != null) {
|
if (presence != null) {
|
||||||
return new Show(jid, presence.show, new DateTime.now_utc());
|
return new Show(jid, presence.show, new DateTime.now_utc());
|
||||||
}
|
}
|
||||||
|
@ -41,20 +41,12 @@ public class PresenceManager : StreamInteractionModule, Object {
|
||||||
return shows[jid];
|
return shows[jid];
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<Jid>? get_full_jids(Jid jid, Account account) {
|
public Gee.List<Jid>? get_full_jids(Jid jid, Account account) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
Xmpp.Presence.Flag flag = stream.get_flag(Presence.Flag.IDENTITY);
|
Xmpp.Presence.Flag flag = stream.get_flag(Presence.Flag.IDENTITY);
|
||||||
if (flag == null) return null;
|
if (flag == null) return null;
|
||||||
Gee.List<string>? resources = flag.get_resources(jid.bare_jid.to_string());
|
return flag.get_resources(jid.bare_jid);
|
||||||
if (resources == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
ArrayList<Jid> ret = new ArrayList<Jid>(Jid.equals_func);
|
|
||||||
foreach (string resource in resources) {
|
|
||||||
ret.add(new Jid(resource));
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -64,40 +56,39 @@ public class PresenceManager : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void request_subscription(Account account, Jid jid) {
|
public void request_subscription(Account account, Jid jid) {
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(account);
|
XmppStream stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) stream.get_module(Xmpp.Presence.Module.IDENTITY).request_subscription(stream, jid.bare_jid.to_string());
|
if (stream != null) stream.get_module(Xmpp.Presence.Module.IDENTITY).request_subscription(stream, jid.bare_jid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void approve_subscription(Account account, Jid jid) {
|
public void approve_subscription(Account account, Jid jid) {
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(account);
|
XmppStream stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
stream.get_module(Xmpp.Presence.Module.IDENTITY).approve_subscription(stream, jid.bare_jid.to_string());
|
stream.get_module(Xmpp.Presence.Module.IDENTITY).approve_subscription(stream, jid.bare_jid);
|
||||||
subscription_requests.remove(jid);
|
subscription_requests.remove(jid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deny_subscription(Account account, Jid jid) {
|
public void deny_subscription(Account account, Jid jid) {
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(account);
|
XmppStream stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
stream.get_module(Xmpp.Presence.Module.IDENTITY).deny_subscription(stream, jid.bare_jid.to_string());
|
stream.get_module(Xmpp.Presence.Module.IDENTITY).deny_subscription(stream, jid.bare_jid);
|
||||||
subscription_requests.remove(jid);
|
subscription_requests.remove(jid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cancel_subscription(Account account, Jid jid) {
|
public void cancel_subscription(Account account, Jid jid) {
|
||||||
Core.XmppStream stream = stream_interactor.get_stream(account);
|
XmppStream stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) stream.get_module(Xmpp.Presence.Module.IDENTITY).cancel_subscription(stream, jid.bare_jid.to_string());
|
if (stream != null) stream.get_module(Xmpp.Presence.Module.IDENTITY).cancel_subscription(stream, jid.bare_jid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_account_added(Account account) {
|
private void on_account_added(Account account) {
|
||||||
stream_interactor.module_manager.get_module(account, Presence.Module.IDENTITY).received_available_show.connect((stream, jid, show) =>
|
stream_interactor.module_manager.get_module(account, Presence.Module.IDENTITY).received_available_show.connect((stream, jid, show) =>
|
||||||
on_received_available_show(account, new Jid(jid), show)
|
on_received_available_show(account, jid, show)
|
||||||
);
|
);
|
||||||
stream_interactor.module_manager.get_module(account, Presence.Module.IDENTITY).received_unavailable.connect((stream, presence) =>
|
stream_interactor.module_manager.get_module(account, Presence.Module.IDENTITY).received_unavailable.connect((stream, presence) =>
|
||||||
on_received_unavailable(account, new Jid(presence.from))
|
on_received_unavailable(account, presence.from)
|
||||||
);
|
);
|
||||||
stream_interactor.module_manager.get_module(account, Presence.Module.IDENTITY).received_subscription_request.connect((stream, jid_str) => {
|
stream_interactor.module_manager.get_module(account, Presence.Module.IDENTITY).received_subscription_request.connect((stream, jid) => {
|
||||||
Jid jid = new Jid(jid_str);
|
|
||||||
if (!subscription_requests.contains(jid)) {
|
if (!subscription_requests.contains(jid)) {
|
||||||
subscription_requests.add(jid);
|
subscription_requests.add(jid);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,18 +40,18 @@ public class RosterManager : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove_jid(Account account, Jid jid) {
|
public void remove_jid(Account account, Jid jid) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) stream.get_module(Xmpp.Roster.Module.IDENTITY).remove_jid(stream, jid.bare_jid.to_string());
|
if (stream != null) stream.get_module(Xmpp.Roster.Module.IDENTITY).remove_jid(stream, jid.bare_jid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add_jid(Account account, Jid jid, string? handle) {
|
public void add_jid(Account account, Jid jid, string? handle) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) stream.get_module(Xmpp.Roster.Module.IDENTITY).add_jid(stream, jid.bare_jid.to_string(), handle);
|
if (stream != null) stream.get_module(Xmpp.Roster.Module.IDENTITY).add_jid(stream, jid.bare_jid, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set_jid_handle(Account account, Jid jid, string? handle) {
|
public void set_jid_handle(Account account, Jid jid, string? handle) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream != null) stream.get_module(Xmpp.Roster.Module.IDENTITY).set_jid_handle(stream, jid.bare_jid.to_string(), handle);
|
if (stream != null) stream.get_module(Xmpp.Roster.Module.IDENTITY).set_jid_handle(stream, jid.bare_jid, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_account_added(Account account) {
|
private void on_account_added(Account account) {
|
||||||
|
@ -61,7 +61,7 @@ public class RosterManager : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
stream_interactor.module_manager.get_module(account, Roster.Module.IDENTITY).item_removed.connect( (stream, roster_item) => {
|
stream_interactor.module_manager.get_module(account, Roster.Module.IDENTITY).item_removed.connect( (stream, roster_item) => {
|
||||||
removed_roster_item(account, new Jid(roster_item.jid), roster_item);
|
removed_roster_item(account, roster_item.jid, roster_item);
|
||||||
});
|
});
|
||||||
stream_interactor.module_manager.get_module(account, Roster.Module.IDENTITY).item_updated.connect( (stream, roster_item) => {
|
stream_interactor.module_manager.get_module(account, Roster.Module.IDENTITY).item_updated.connect( (stream, roster_item) => {
|
||||||
on_roster_item_updated(account, roster_item);
|
on_roster_item_updated(account, roster_item);
|
||||||
|
@ -69,7 +69,7 @@ public class RosterManager : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_roster_item_updated(Account account, Roster.Item roster_item) {
|
private void on_roster_item_updated(Account account, Roster.Item roster_item) {
|
||||||
updated_roster_item(account, new Jid(roster_item.jid), roster_item);
|
updated_roster_item(account, roster_item.jid, roster_item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ public class RosterStoreImpl : Roster.Storage, Object {
|
||||||
private Account account;
|
private Account account;
|
||||||
private Database db;
|
private Database db;
|
||||||
|
|
||||||
private HashMap<string, Roster.Item> items = new HashMap<string, Roster.Item>();
|
private HashMap<Jid, Roster.Item> items = new HashMap<Jid, Roster.Item>(Jid.hash_bare_func, Jid.equals_bare_func);
|
||||||
|
|
||||||
public class RosterStoreImpl(Account account, Database db) {
|
public class RosterStoreImpl(Account account, Database db) {
|
||||||
this.account = account;
|
this.account = account;
|
||||||
|
@ -85,7 +85,7 @@ public class RosterStoreImpl : Roster.Storage, Object {
|
||||||
|
|
||||||
foreach (Qlite.Row row in db.roster.select().with(db.roster.account_id, "=", account.id)) {
|
foreach (Qlite.Row row in db.roster.select().with(db.roster.account_id, "=", account.id)) {
|
||||||
Roster.Item item = new Roster.Item();
|
Roster.Item item = new Roster.Item();
|
||||||
item.jid = row[db.roster.jid];
|
item.jid = Jid.parse(row[db.roster.jid]);
|
||||||
item.name = row[db.roster.handle];
|
item.name = row[db.roster.handle];
|
||||||
item.subscription = row[db.roster.subscription];
|
item.subscription = row[db.roster.subscription];
|
||||||
items[item.jid] = item;
|
items[item.jid] = item;
|
||||||
|
@ -101,7 +101,7 @@ public class RosterStoreImpl : Roster.Storage, Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Roster.Item? get_item(Jid jid) {
|
public Roster.Item? get_item(Jid jid) {
|
||||||
return items.has_key(jid.bare_jid.to_string()) ? items[jid.bare_jid.to_string()] : null;
|
return items.has_key(jid) ? items[jid] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set_roster_version(string version) {
|
public void set_roster_version(string version) {
|
||||||
|
@ -119,7 +119,7 @@ public class RosterStoreImpl : Roster.Storage, Object {
|
||||||
items[item.jid] = item;
|
items[item.jid] = item;
|
||||||
db.roster.insert().or("REPLACE")
|
db.roster.insert().or("REPLACE")
|
||||||
.value(db.roster.account_id, account.id)
|
.value(db.roster.account_id, account.id)
|
||||||
.value(db.roster.jid, item.jid)
|
.value(db.roster.jid, item.jid.to_string())
|
||||||
.value(db.roster.handle, item.name)
|
.value(db.roster.handle, item.name)
|
||||||
.value(db.roster.subscription, item.subscription)
|
.value(db.roster.subscription, item.subscription)
|
||||||
.perform();
|
.perform();
|
||||||
|
@ -129,7 +129,7 @@ public class RosterStoreImpl : Roster.Storage, Object {
|
||||||
items.unset(item.jid);
|
items.unset(item.jid);
|
||||||
db.roster.delete()
|
db.roster.delete()
|
||||||
.with(db.roster.account_id, "=", account.id)
|
.with(db.roster.account_id, "=", account.id)
|
||||||
.with(db.roster.jid, "=", item.jid).perform();
|
.with(db.roster.jid, "=", item.jid.to_string()).perform();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@ public class StreamInteractor {
|
||||||
|
|
||||||
public signal void account_added(Account account);
|
public signal void account_added(Account account);
|
||||||
public signal void account_removed(Account account);
|
public signal void account_removed(Account account);
|
||||||
public signal void stream_negotiated(Account account, Core.XmppStream stream);
|
public signal void stream_negotiated(Account account, XmppStream stream);
|
||||||
public signal void attached_modules(Account account, Core.XmppStream stream);
|
public signal void attached_modules(Account account, XmppStream stream);
|
||||||
|
|
||||||
public ModuleManager module_manager;
|
public ModuleManager module_manager;
|
||||||
public ConnectionManager connection_manager;
|
public ConnectionManager connection_manager;
|
||||||
|
@ -42,7 +42,7 @@ public class StreamInteractor {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Core.XmppStream? get_stream(Account account) {
|
public XmppStream? get_stream(Account account) {
|
||||||
return connection_manager.get_stream(account);
|
return connection_manager.get_stream(account);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ public class StreamInteractor {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_stream_opened(Account account, Core.XmppStream stream) {
|
private void on_stream_opened(Account account, XmppStream stream) {
|
||||||
stream.stream_negotiated.connect( (stream) => {
|
stream.stream_negotiated.connect( (stream) => {
|
||||||
stream_negotiated(account, stream);
|
stream_negotiated(account, stream);
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,6 +2,7 @@ using Gee;
|
||||||
using Gtk;
|
using Gtk;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Ui {
|
namespace Dino.Ui {
|
||||||
|
|
||||||
|
@ -122,7 +123,7 @@ public class AddConferenceDialog : Gtk.Dialog {
|
||||||
ConferenceListRow? conference_row = conference_list.get_selected_row() as ConferenceListRow;
|
ConferenceListRow? conference_row = conference_list.get_selected_row() as ConferenceListRow;
|
||||||
if (conference_row != null) {
|
if (conference_row != null) {
|
||||||
details_fragment.account = conference_row.account;
|
details_fragment.account = conference_row.account;
|
||||||
details_fragment.jid = conference_row.bookmark.jid;
|
details_fragment.jid = conference_row.bookmark.jid.to_string();
|
||||||
details_fragment.nick = conference_row.bookmark.nick;
|
details_fragment.nick = conference_row.bookmark.nick;
|
||||||
if (conference_row.bookmark.password != null) details_fragment.password = conference_row.bookmark.password;
|
if (conference_row.bookmark.password != null) details_fragment.password = conference_row.bookmark.password;
|
||||||
ok_button.grab_focus();
|
ok_button.grab_focus();
|
||||||
|
|
|
@ -2,6 +2,7 @@ using Gee;
|
||||||
using Gtk;
|
using Gtk;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Ui {
|
namespace Dino.Ui {
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ using Gee;
|
||||||
using Gtk;
|
using Gtk;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Ui {
|
namespace Dino.Ui {
|
||||||
|
|
||||||
|
@ -43,7 +44,7 @@ protected class AddGroupchatDialog : Gtk.Dialog {
|
||||||
accounts_stack.set_visible_child_name("label");
|
accounts_stack.set_visible_child_name("label");
|
||||||
account_label.label = account.bare_jid.to_string();
|
account_label.label = account.bare_jid.to_string();
|
||||||
account_combobox.selected = account;
|
account_combobox.selected = account;
|
||||||
jid_entry.text = conference.jid;
|
jid_entry.text = conference.jid.to_string();
|
||||||
nick_entry.text = conference.nick ?? "";
|
nick_entry.text = conference.nick ?? "";
|
||||||
alias_entry.text = conference.name;
|
alias_entry.text = conference.name;
|
||||||
}
|
}
|
||||||
|
@ -64,7 +65,7 @@ protected class AddGroupchatDialog : Gtk.Dialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_ok_button_clicked() {
|
private void on_ok_button_clicked() {
|
||||||
Xmpp.Xep.Bookmarks.Conference conference = new Xmpp.Xep.Bookmarks.Conference(jid_entry.text);
|
Xmpp.Xep.Bookmarks.Conference conference = new Xmpp.Xep.Bookmarks.Conference(Jid.parse(jid_entry.text));
|
||||||
conference.nick = nick_entry.text != "" ? nick_entry.text : null;
|
conference.nick = nick_entry.text != "" ? nick_entry.text : null;
|
||||||
conference.name = alias_entry.text;
|
conference.name = alias_entry.text;
|
||||||
if (edit_conference == null) {
|
if (edit_conference == null) {
|
||||||
|
|
|
@ -2,6 +2,7 @@ using Gdk;
|
||||||
using Gtk;
|
using Gtk;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Ui {
|
namespace Dino.Ui {
|
||||||
|
|
||||||
|
|
|
@ -39,8 +39,12 @@ protected class ConferenceList : FilterableList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_conference_bookmarks_received(Core.XmppStream stream, Account account, Gee.List<Xep.Bookmarks.Conference> conferences) {
|
private void on_conference_bookmarks_received(XmppStream stream, Account account, Gee.List<Xep.Bookmarks.Conference>? conferences) {
|
||||||
|
if (conferences == null) {
|
||||||
|
lists.unset(account);
|
||||||
|
} else {
|
||||||
lists[account] = conferences;
|
lists[account] = conferences;
|
||||||
|
}
|
||||||
refresh_conferences();
|
refresh_conferences();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,15 +81,15 @@ internal class ConferenceListRow : ListRow {
|
||||||
public Xep.Bookmarks.Conference bookmark;
|
public Xep.Bookmarks.Conference bookmark;
|
||||||
|
|
||||||
public ConferenceListRow(StreamInteractor stream_interactor, Xep.Bookmarks.Conference bookmark, Account account) {
|
public ConferenceListRow(StreamInteractor stream_interactor, Xep.Bookmarks.Conference bookmark, Account account) {
|
||||||
this.jid = new Jid(bookmark.jid);
|
this.jid = bookmark.jid;
|
||||||
this.account = account;
|
this.account = account;
|
||||||
this.bookmark = bookmark;
|
this.bookmark = bookmark;
|
||||||
|
|
||||||
name_label.label = bookmark.name ?? bookmark.jid;
|
name_label.label = bookmark.name ?? bookmark.jid.to_string();
|
||||||
if (stream_interactor.get_accounts().size > 1) {
|
if (stream_interactor.get_accounts().size > 1) {
|
||||||
via_label.label = "via " + account.bare_jid.to_string();
|
via_label.label = "via " + account.bare_jid.to_string();
|
||||||
} else if (bookmark.name != null && bookmark.name != bookmark.jid) {
|
} else if (bookmark.name != null && bookmark.name != bookmark.jid.to_string()) {
|
||||||
via_label.label = bookmark.jid;
|
via_label.label = bookmark.jid.to_string();
|
||||||
} else {
|
} else {
|
||||||
via_label.visible = false;
|
via_label.visible = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ using Gee;
|
||||||
using Gtk;
|
using Gtk;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Ui {
|
namespace Dino.Ui {
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ protected class RosterList : FilterableList {
|
||||||
|
|
||||||
private void on_updated_roster_item(Account account, Jid jid, Roster.Item roster_item) {
|
private void on_updated_roster_item(Account account, Jid jid, Roster.Item roster_item) {
|
||||||
on_removed_roster_item(account, jid, roster_item);
|
on_removed_roster_item(account, jid, roster_item);
|
||||||
ListRow row = new ListRow.from_jid(stream_interactor, new Jid(roster_item.jid), account, accounts.size > 1);
|
ListRow row = new ListRow.from_jid(stream_interactor, roster_item.jid, account, accounts.size > 1);
|
||||||
rows[account][jid] = row;
|
rows[account][jid] = row;
|
||||||
add(row);
|
add(row);
|
||||||
invalidate_sort();
|
invalidate_sort();
|
||||||
|
@ -59,7 +59,7 @@ protected class RosterList : FilterableList {
|
||||||
private void fetch_roster_items(Account account) {
|
private void fetch_roster_items(Account account) {
|
||||||
rows[account] = new HashMap<Jid, ListRow>(Jid.hash_func, Jid.equals_func);
|
rows[account] = new HashMap<Jid, ListRow>(Jid.hash_func, Jid.equals_func);
|
||||||
foreach (Roster.Item roster_item in stream_interactor.get_module(RosterManager.IDENTITY).get_roster(account)) {
|
foreach (Roster.Item roster_item in stream_interactor.get_module(RosterManager.IDENTITY).get_roster(account)) {
|
||||||
on_updated_roster_item(account, new Jid(roster_item.jid), roster_item);
|
on_updated_roster_item(account, roster_item.jid, roster_item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ using Gdk;
|
||||||
using Gtk;
|
using Gtk;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Ui {
|
namespace Dino.Ui {
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ using Gee;
|
||||||
using Gtk;
|
using Gtk;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Ui {
|
namespace Dino.Ui {
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ using Gtk;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
using Dino.Ui;
|
using Dino.Ui;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
public class Dino.Ui.Application : Gtk.Application, Dino.Application {
|
public class Dino.Ui.Application : Gtk.Application, Dino.Application {
|
||||||
private Notifications notifications;
|
private Notifications notifications;
|
||||||
|
|
|
@ -4,6 +4,7 @@ using Gdk;
|
||||||
using Gtk;
|
using Gtk;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Ui {
|
namespace Dino.Ui {
|
||||||
|
|
||||||
|
@ -109,7 +110,7 @@ public class AvatarGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Pixbuf draw_groupchat_tile(Jid jid, Account account, int width, int height) {
|
private Pixbuf draw_groupchat_tile(Jid jid, Account account, int width, int height) {
|
||||||
ArrayList<Jid>? occupants = stream_interactor.get_module(MucManager.IDENTITY).get_other_occupants(jid, account);
|
Gee.List<Jid>? occupants = stream_interactor.get_module(MucManager.IDENTITY).get_other_occupants(jid, account);
|
||||||
if (stateless || occupants == null || occupants.size == 0) {
|
if (stateless || occupants == null || occupants.size == 0) {
|
||||||
return draw_chat_tile(jid, account, width, height);
|
return draw_chat_tile(jid, account, width, height);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ public class EncryptionButton : MenuButton {
|
||||||
private Conversation? conversation;
|
private Conversation? conversation;
|
||||||
private RadioButton? button_unencrypted;
|
private RadioButton? button_unencrypted;
|
||||||
private Map<RadioButton, Plugins.EncryptionListEntry> encryption_radios = new HashMap<RadioButton, Plugins.EncryptionListEntry>();
|
private Map<RadioButton, Plugins.EncryptionListEntry> encryption_radios = new HashMap<RadioButton, Plugins.EncryptionListEntry>();
|
||||||
|
private string? current_icon;
|
||||||
|
|
||||||
public EncryptionButton() {
|
public EncryptionButton() {
|
||||||
relief = ReliefStyle.NONE;
|
relief = ReliefStyle.NONE;
|
||||||
|
@ -56,14 +57,17 @@ public class EncryptionButton : MenuButton {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void update_encryption_menu_icon() {
|
private void set_icon(string icon) {
|
||||||
if (conversation.encryption == Encryption.NONE) {
|
if (icon != current_icon) {
|
||||||
set_image(new Image.from_icon_name("changes-allow-symbolic", IconSize.BUTTON));
|
image = new Image.from_icon_name(icon, IconSize.BUTTON);
|
||||||
} else {
|
current_icon = icon;
|
||||||
set_image(new Image.from_icon_name("changes-prevent-symbolic", IconSize.BUTTON));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void update_encryption_menu_icon() {
|
||||||
|
set_icon(conversation.encryption == Encryption.NONE ? "changes-allow-symbolic" : "changes-prevent-symbolic");
|
||||||
|
}
|
||||||
|
|
||||||
public new void set_conversation(Conversation conversation) {
|
public new void set_conversation(Conversation conversation) {
|
||||||
this.conversation = conversation;
|
this.conversation = conversation;
|
||||||
update_encryption_menu_state();
|
update_encryption_menu_state();
|
||||||
|
|
|
@ -3,6 +3,7 @@ using Gee;
|
||||||
using Gtk;
|
using Gtk;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Ui.ChatInput {
|
namespace Dino.Ui.ChatInput {
|
||||||
|
|
||||||
|
|
|
@ -84,8 +84,8 @@ public class View : Box {
|
||||||
stream_interactor.get_module(MucManager.IDENTITY).change_nick(conversation.account, conversation.counterpart, token[1]);
|
stream_interactor.get_module(MucManager.IDENTITY).change_nick(conversation.account, conversation.counterpart, token[1]);
|
||||||
return;
|
return;
|
||||||
case "/ping":
|
case "/ping":
|
||||||
Xmpp.Core.XmppStream? stream = stream_interactor.get_stream(conversation.account);
|
Xmpp.XmppStream? stream = stream_interactor.get_stream(conversation.account);
|
||||||
stream.get_module(Xmpp.Xep.Ping.Module.IDENTITY).send_ping(stream, conversation.counterpart.to_string() + "/" + token[1], null);
|
stream.get_module(Xmpp.Xep.Ping.Module.IDENTITY).send_ping(stream, conversation.counterpart.with_resource(token[1]), null);
|
||||||
return;
|
return;
|
||||||
case "/topic":
|
case "/topic":
|
||||||
stream_interactor.get_module(MucManager.IDENTITY).change_subject(conversation.account, conversation.counterpart, token[1]);
|
stream_interactor.get_module(MucManager.IDENTITY).change_subject(conversation.account, conversation.counterpart, token[1]);
|
||||||
|
|
|
@ -17,7 +17,7 @@ public class MucConfigFormProvider : Plugins.ContactDetailsProvider, Object {
|
||||||
public void populate(Conversation conversation, Plugins.ContactDetails contact_details, Plugins.WidgetType type) {
|
public void populate(Conversation conversation, Plugins.ContactDetails contact_details, Plugins.WidgetType type) {
|
||||||
if (type != Plugins.WidgetType.GTK) return;
|
if (type != Plugins.WidgetType.GTK) return;
|
||||||
if (conversation.type_ == Conversation.Type.GROUPCHAT) {
|
if (conversation.type_ == Conversation.Type.GROUPCHAT) {
|
||||||
Xmpp.Core.XmppStream? stream = stream_interactor.get_stream(conversation.account);
|
Xmpp.XmppStream? stream = stream_interactor.get_stream(conversation.account);
|
||||||
if (stream == null) return;
|
if (stream == null) return;
|
||||||
stream_interactor.get_module(MucManager.IDENTITY).get_config_form(conversation.account, conversation.counterpart, (jid, data_form) => {
|
stream_interactor.get_module(MucManager.IDENTITY).get_config_form(conversation.account, conversation.counterpart, (jid, data_form) => {
|
||||||
contact_details.save.connect(() => { data_form.submit(); });
|
contact_details.save.connect(() => { data_form.submit(); });
|
||||||
|
|
|
@ -3,6 +3,7 @@ using Gee;
|
||||||
using Gtk;
|
using Gtk;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Ui.ConversationSelector {
|
namespace Dino.Ui.ConversationSelector {
|
||||||
|
|
||||||
|
@ -18,7 +19,6 @@ public class ChatRow : ConversationRow {
|
||||||
stream_interactor.get_module(RosterManager.IDENTITY).updated_roster_item.connect((account, jid, roster_item) => {
|
stream_interactor.get_module(RosterManager.IDENTITY).updated_roster_item.connect((account, jid, roster_item) => {
|
||||||
if (conversation.account.equals(account) && conversation.counterpart.equals(jid)) {
|
if (conversation.account.equals(account) && conversation.counterpart.equals(jid)) {
|
||||||
update_name_label();
|
update_name_label();
|
||||||
update_avatar();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ public class ChatRow : ConversationRow {
|
||||||
|
|
||||||
jid_label.label = conversation.counterpart.to_string();
|
jid_label.label = conversation.counterpart.to_string();
|
||||||
|
|
||||||
ArrayList<Jid>? full_jids = stream_interactor.get_module(PresenceManager.IDENTITY).get_full_jids(conversation.counterpart, conversation.account);
|
Gee.List<Jid>? full_jids = stream_interactor.get_module(PresenceManager.IDENTITY).get_full_jids(conversation.counterpart, conversation.account);
|
||||||
if (full_jids != null) {
|
if (full_jids != null) {
|
||||||
for (int i = 0; i < full_jids.size; i++) {
|
for (int i = 0; i < full_jids.size; i++) {
|
||||||
inner_box.add(get_fulljid_box(full_jids[i]));
|
inner_box.add(get_fulljid_box(full_jids[i]));
|
||||||
|
|
|
@ -4,6 +4,7 @@ using Gtk;
|
||||||
using Pango;
|
using Pango;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Ui.ConversationSelector {
|
namespace Dino.Ui.ConversationSelector {
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@ public class GroupchatPmRow : ConversationRow {
|
||||||
tooltip.set_custom(generate_tooltip());
|
tooltip.set_custom(generate_tooltip());
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
update_avatar();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void update_message_label() {
|
protected override void update_message_label() {
|
||||||
|
|
|
@ -8,12 +8,10 @@ public class GroupchatRow : ConversationRow {
|
||||||
base(stream_interactor, conversation);
|
base(stream_interactor, conversation);
|
||||||
has_tooltip = true;
|
has_tooltip = true;
|
||||||
set_tooltip_text(conversation.counterpart.bare_jid.to_string());
|
set_tooltip_text(conversation.counterpart.bare_jid.to_string());
|
||||||
update_avatar();
|
|
||||||
|
|
||||||
closed.connect(() => {
|
closed.connect(() => {
|
||||||
stream_interactor.get_module(MucManager.IDENTITY).part(conversation.account, conversation.counterpart);
|
stream_interactor.get_module(MucManager.IDENTITY).part(conversation.account, conversation.counterpart);
|
||||||
});
|
});
|
||||||
stream_interactor.get_module(MucManager.IDENTITY).left.connect(update_avatar);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void update_message_label() {
|
protected override void update_message_label() {
|
||||||
|
|
|
@ -26,18 +26,6 @@ public class List : ListBox {
|
||||||
stream_interactor.get_module(ConversationManager.IDENTITY).conversation_deactivated.connect(remove_conversation);
|
stream_interactor.get_module(ConversationManager.IDENTITY).conversation_deactivated.connect(remove_conversation);
|
||||||
stream_interactor.get_module(MessageProcessor.IDENTITY).message_received.connect(on_message_received);
|
stream_interactor.get_module(MessageProcessor.IDENTITY).message_received.connect(on_message_received);
|
||||||
stream_interactor.get_module(MessageProcessor.IDENTITY).message_sent.connect(on_message_received);
|
stream_interactor.get_module(MessageProcessor.IDENTITY).message_sent.connect(on_message_received);
|
||||||
stream_interactor.get_module(PresenceManager.IDENTITY).show_received.connect((show, jid, account) => {
|
|
||||||
foreach (Conversation conversation in stream_interactor.get_module(ConversationManager.IDENTITY).get_conversations_for_presence(show, account)) {
|
|
||||||
if (rows.has_key(conversation)) rows[conversation].on_show_received(show);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
stream_interactor.get_module(AvatarManager.IDENTITY).received_avatar.connect((avatar, jid, account) => {
|
|
||||||
Conversation? conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation(jid, account);
|
|
||||||
if (conversation != null && rows.has_key(conversation)) {
|
|
||||||
ChatRow row = rows[conversation] as ChatRow;
|
|
||||||
if (row != null) row.update_avatar();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Timeout.add_seconds(60, () => {
|
Timeout.add_seconds(60, () => {
|
||||||
foreach (ConversationRow row in rows.values) row.update();
|
foreach (ConversationRow row in rows.values) row.update();
|
||||||
return true;
|
return true;
|
||||||
|
@ -99,7 +87,7 @@ public class List : ListBox {
|
||||||
row.closed.connect(() => { select_next_conversation(conversation); });
|
row.closed.connect(() => { select_next_conversation(conversation); });
|
||||||
row.main_revealer.set_reveal_child(true);
|
row.main_revealer.set_reveal_child(true);
|
||||||
}
|
}
|
||||||
invalidate_sort();
|
//invalidate_sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void select_next_conversation(Conversation conversation) {
|
private void select_next_conversation(Conversation conversation) {
|
||||||
|
|
|
@ -2,6 +2,7 @@ using Gdk;
|
||||||
using Gtk;
|
using Gtk;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Ui.ConversationSummary {
|
namespace Dino.Ui.ConversationSummary {
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ public class DefaultFileDisplay : Plugins.MetaConversationItem {
|
||||||
this.stream_interactor = stream_interactor;
|
this.stream_interactor = stream_interactor;
|
||||||
this.file_transfer = file_transfer;
|
this.file_transfer = file_transfer;
|
||||||
|
|
||||||
this.jid = file_transfer.direction == FileTransfer.DIRECTION_SENT ? new Jid.with_resource(file_transfer.account.bare_jid.to_string(), file_transfer.account.resourcepart) : file_transfer.counterpart;
|
this.jid = file_transfer.direction == FileTransfer.DIRECTION_SENT ? file_transfer.account.bare_jid.with_resource(file_transfer.account.resourcepart) : file_transfer.counterpart;
|
||||||
this.sort_time = file_transfer.time;
|
this.sort_time = file_transfer.time;
|
||||||
this.seccondary_sort_indicator = file_transfer.id + 0.2903;
|
this.seccondary_sort_indicator = file_transfer.id + 0.2903;
|
||||||
this.display_time = file_transfer.time;
|
this.display_time = file_transfer.time;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Ui.ConversationSummary {
|
namespace Dino.Ui.ConversationSummary {
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using Gtk;
|
using Gtk;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Ui.ConversationSummary {
|
namespace Dino.Ui.ConversationSummary {
|
||||||
|
|
||||||
|
@ -25,7 +26,7 @@ public class ImageDisplay : Plugins.MetaConversationItem {
|
||||||
this.stream_interactor = stream_interactor;
|
this.stream_interactor = stream_interactor;
|
||||||
this.file_transfer = file_transfer;
|
this.file_transfer = file_transfer;
|
||||||
|
|
||||||
this.jid = file_transfer.direction == FileTransfer.DIRECTION_SENT ? new Jid.with_resource(file_transfer.account.bare_jid.to_string(), file_transfer.account.resourcepart) : file_transfer.counterpart;
|
this.jid = file_transfer.direction == FileTransfer.DIRECTION_SENT ? file_transfer.account.bare_jid.with_resource(file_transfer.account.resourcepart) : file_transfer.counterpart;
|
||||||
this.sort_time = file_transfer.time;
|
this.sort_time = file_transfer.time;
|
||||||
this.seccondary_sort_indicator = file_transfer.id + 0.2903;
|
this.seccondary_sort_indicator = file_transfer.id + 0.2903;
|
||||||
this.display_time = file_transfer.time;
|
this.display_time = file_transfer.time;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using Gtk;
|
using Gtk;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Ui.ConversationSummary {
|
namespace Dino.Ui.ConversationSummary {
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ using Gee;
|
||||||
using Gtk;
|
using Gtk;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Ui.ManageAccounts {
|
namespace Dino.Ui.ManageAccounts {
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ using Gtk;
|
||||||
using Markup;
|
using Markup;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Ui.ManageAccounts {
|
namespace Dino.Ui.ManageAccounts {
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ using Gee;
|
||||||
using Gtk;
|
using Gtk;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Ui.OccupantMenu{
|
namespace Dino.Ui.OccupantMenu{
|
||||||
|
|
||||||
|
@ -39,6 +40,7 @@ public class List : Box {
|
||||||
add_occupant(occupant);
|
add_occupant(occupant);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
list_box.invalidate_filter();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refilter() {
|
private void refilter() {
|
||||||
|
@ -57,8 +59,6 @@ public class List : Box {
|
||||||
public void add_occupant(Jid jid) {
|
public void add_occupant(Jid jid) {
|
||||||
rows[jid] = new ListRow(stream_interactor, conversation.account, jid);
|
rows[jid] = new ListRow(stream_interactor, conversation.account, jid);
|
||||||
list_box.add(rows[jid]);
|
list_box.add(rows[jid]);
|
||||||
list_box.invalidate_filter();
|
|
||||||
list_box.invalidate_sort();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove_occupant(Jid jid) {
|
public void remove_occupant(Jid jid) {
|
||||||
|
@ -77,6 +77,7 @@ public class List : Box {
|
||||||
} else if (show.as != Show.OFFLINE && !rows.has_key(jid)) {
|
} else if (show.as != Show.OFFLINE && !rows.has_key(jid)) {
|
||||||
add_occupant(jid);
|
add_occupant(jid);
|
||||||
}
|
}
|
||||||
|
list_box.invalidate_filter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ using Gee;
|
||||||
using Gtk;
|
using Gtk;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Ui.OccupantMenu {
|
namespace Dino.Ui.OccupantMenu {
|
||||||
public class View : Popover {
|
public class View : Popover {
|
||||||
|
|
|
@ -65,7 +65,7 @@ public static string get_display_name(StreamInteractor stream_interactor, Jid ji
|
||||||
}
|
}
|
||||||
return jid.resourcepart;
|
return jid.resourcepart;
|
||||||
} else {
|
} else {
|
||||||
if (jid.bare_jid.equals(account.bare_jid.bare_jid)) {
|
if (jid.equals_bare(account.bare_jid)) {
|
||||||
if (account.alias == null || account.alias == "") {
|
if (account.alias == null || account.alias == "") {
|
||||||
return account.bare_jid.to_string();
|
return account.bare_jid.to_string();
|
||||||
} else {
|
} else {
|
||||||
|
@ -84,9 +84,24 @@ public static string get_message_display_name(StreamInteractor stream_interactor
|
||||||
return get_display_name(stream_interactor, message.from, account);
|
return get_display_name(stream_interactor, message.from, account);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void image_set_from_scaled_pixbuf(Image image, Gdk.Pixbuf pixbuf, int scale = 0) {
|
public static void image_set_from_scaled_pixbuf(Image image, Gdk.Pixbuf pixbuf, int scale = 0, int width = 0, int height = 0) {
|
||||||
if (scale == 0) scale = image.scale_factor;
|
if (scale == 0) scale = image.scale_factor;
|
||||||
image.set_from_surface(Gdk.cairo_surface_create_from_pixbuf(pixbuf, scale, image.get_window()));
|
Cairo.Surface surface = Gdk.cairo_surface_create_from_pixbuf(pixbuf, scale, image.get_window());
|
||||||
|
if (height == 0 && width != 0) {
|
||||||
|
height = (int) ((double) width / pixbuf.width * pixbuf.height);
|
||||||
|
} else if (height != 0 && width == 0) {
|
||||||
|
width = (int) ((double) height / pixbuf.height * pixbuf.width);
|
||||||
|
}
|
||||||
|
if (width != 0) {
|
||||||
|
Cairo.Surface surface_new = new Cairo.Surface.similar_image(surface, Cairo.Format.ARGB32, width, height);
|
||||||
|
Cairo.Context context = new Cairo.Context(surface_new);
|
||||||
|
context.scale((double) width * scale / pixbuf.width, (double) height * scale / pixbuf.height);
|
||||||
|
context.set_source_surface(surface, 0, 0);
|
||||||
|
context.get_source().set_filter(Cairo.Filter.BEST);
|
||||||
|
context.paint();
|
||||||
|
surface = surface_new;
|
||||||
|
}
|
||||||
|
image.set_from_surface(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
private const string force_background_css = "%s { background-color: %s; }";
|
private const string force_background_css = "%s { background-color: %s; }";
|
||||||
|
|
|
@ -2,6 +2,7 @@ using Gee;
|
||||||
using Gtk;
|
using Gtk;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Plugins.HttpFiles {
|
namespace Dino.Plugins.HttpFiles {
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ public class Manager : StreamInteractionModule, FileSender, Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void send_file(Conversation conversation, FileTransfer file_transfer) {
|
public void send_file(Conversation conversation, FileTransfer file_transfer) {
|
||||||
Xmpp.Core.XmppStream? stream = stream_interactor.get_stream(file_transfer.account);
|
Xmpp.XmppStream? stream = stream_interactor.get_stream(file_transfer.account);
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
stream_interactor.module_manager.get_module(file_transfer.account, UploadStreamModule.IDENTITY).upload(stream, file_transfer.input_stream, file_transfer.server_file_name, file_transfer.size, file_transfer.mime_type,
|
stream_interactor.module_manager.get_module(file_transfer.account, UploadStreamModule.IDENTITY).upload(stream, file_transfer.input_stream, file_transfer.server_file_name, file_transfer.size, file_transfer.mime_type,
|
||||||
(stream, url_down) => {
|
(stream, url_down) => {
|
||||||
|
@ -60,7 +60,7 @@ public class Manager : StreamInteractionModule, FileSender, Object {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_stream_negotiated(Account account, Core.XmppStream stream) {
|
private void on_stream_negotiated(Account account, XmppStream stream) {
|
||||||
stream_interactor.module_manager.get_module(account, UploadStreamModule.IDENTITY).feature_available.connect((stream, max_file_size) => {
|
stream_interactor.module_manager.get_module(account, UploadStreamModule.IDENTITY).feature_available.connect((stream, max_file_size) => {
|
||||||
lock (max_file_sizes) {
|
lock (max_file_sizes) {
|
||||||
max_file_sizes[account] = max_file_size;
|
max_file_sizes[account] = max_file_size;
|
||||||
|
@ -69,7 +69,7 @@ public class Manager : StreamInteractionModule, FileSender, Object {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void check_add_oob(Entities.Message message, Xmpp.Message.Stanza message_stanza, Conversation conversation) {
|
private void check_add_oob(Entities.Message message, Xmpp.MessageStanza message_stanza, Conversation conversation) {
|
||||||
if (message_is_file(db, message)) {
|
if (message_is_file(db, message)) {
|
||||||
Xep.OutOfBandData.add_url_to_message(message_stanza, message_stanza.body);
|
Xep.OutOfBandData.add_url_to_message(message_stanza, message_stanza.body);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
using Xmpp;
|
using Xmpp;
|
||||||
using Xmpp.Core;
|
using Xmpp;
|
||||||
using Xmpp.Xep;
|
using Xmpp.Xep;
|
||||||
|
|
||||||
namespace Dino.Plugins.HttpFiles {
|
namespace Dino.Plugins.HttpFiles {
|
||||||
|
@ -8,7 +8,7 @@ private const string NS_URI = "urn:xmpp:http:upload";
|
||||||
private const string NS_URI_0 = "urn:xmpp:http:upload:0";
|
private const string NS_URI_0 = "urn:xmpp:http:upload:0";
|
||||||
|
|
||||||
public class UploadStreamModule : XmppStreamModule {
|
public class UploadStreamModule : XmppStreamModule {
|
||||||
public static Core.ModuleIdentity<UploadStreamModule> IDENTITY = new Core.ModuleIdentity<UploadStreamModule>(NS_URI, "0363_http_file_upload");
|
public static Xmpp.ModuleIdentity<UploadStreamModule> IDENTITY = new Xmpp.ModuleIdentity<UploadStreamModule>(NS_URI, "0363_http_file_upload");
|
||||||
|
|
||||||
public signal void feature_available(XmppStream stream, long max_file_size);
|
public signal void feature_available(XmppStream stream, long max_file_size);
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ public class UploadStreamModule : XmppStreamModule {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool check_ns_in_info(XmppStream stream, string jid, Xep.ServiceDiscovery.InfoResult info_result) {
|
private bool check_ns_in_info(XmppStream stream, Jid jid, Xep.ServiceDiscovery.InfoResult info_result) {
|
||||||
bool ver_available = false;
|
bool ver_available = false;
|
||||||
bool ver_0_available = false;
|
bool ver_0_available = false;
|
||||||
foreach (string feature in info_result.features) {
|
foreach (string feature in info_result.features) {
|
||||||
|
@ -162,11 +162,11 @@ public class UploadStreamModule : XmppStreamModule {
|
||||||
public class Flag : XmppStreamFlag {
|
public class Flag : XmppStreamFlag {
|
||||||
public static FlagIdentity<Flag> IDENTITY = new FlagIdentity<Flag>(NS_URI, "service_discovery");
|
public static FlagIdentity<Flag> IDENTITY = new FlagIdentity<Flag>(NS_URI, "service_discovery");
|
||||||
|
|
||||||
public string file_store_jid;
|
public Jid file_store_jid;
|
||||||
public string ns_ver;
|
public string ns_ver;
|
||||||
public int? max_file_size;
|
public int? max_file_size;
|
||||||
|
|
||||||
public Flag(string file_store_jid, string ns_ver) {
|
public Flag(Jid file_store_jid, string ns_ver) {
|
||||||
this.file_store_jid = file_store_jid;
|
this.file_store_jid = file_store_jid;
|
||||||
this.ns_ver = ns_ver;
|
this.ns_ver = ns_ver;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
using Signal;
|
using Signal;
|
||||||
using Xmpp.Core;
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Plugins.Omemo {
|
namespace Dino.Plugins.Omemo {
|
||||||
|
|
||||||
|
|
|
@ -69,16 +69,16 @@ public class Manager : StreamInteractionModule, Object {
|
||||||
stream_interactor.get_module(MessageProcessor.IDENTITY).pre_message_send.connect(on_pre_message_send);
|
stream_interactor.get_module(MessageProcessor.IDENTITY).pre_message_send.connect(on_pre_message_send);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_pre_message_received(Entities.Message message, Xmpp.Message.Stanza message_stanza, Conversation conversation) {
|
private void on_pre_message_received(Entities.Message message, Xmpp.MessageStanza message_stanza, Conversation conversation) {
|
||||||
MessageFlag? flag = MessageFlag.get_flag(message_stanza);
|
MessageFlag? flag = MessageFlag.get_flag(message_stanza);
|
||||||
if (flag != null && ((!)flag).decrypted) {
|
if (flag != null && ((!)flag).decrypted) {
|
||||||
message.encryption = Encryption.OMEMO;
|
message.encryption = Encryption.OMEMO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_pre_message_send(Entities.Message message, Xmpp.Message.Stanza message_stanza, Conversation conversation) {
|
private void on_pre_message_send(Entities.Message message, Xmpp.MessageStanza message_stanza, Conversation conversation) {
|
||||||
if (message.encryption == Encryption.OMEMO) {
|
if (message.encryption == Encryption.OMEMO) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(conversation.account);
|
XmppStream? stream = stream_interactor.get_stream(conversation.account);
|
||||||
if (stream == null) {
|
if (stream == null) {
|
||||||
message.marked = Entities.Message.Marked.UNSENT;
|
message.marked = Entities.Message.Marked.UNSENT;
|
||||||
return;
|
return;
|
||||||
|
@ -89,7 +89,7 @@ public class Manager : StreamInteractionModule, Object {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
StreamModule module = (!)module_;
|
StreamModule module = (!)module_;
|
||||||
EncryptState enc_state = module.encrypt(message_stanza, conversation.account.bare_jid.to_string());
|
EncryptState enc_state = module.encrypt(message_stanza, conversation.account.bare_jid);
|
||||||
MessageState state;
|
MessageState state;
|
||||||
lock (message_states) {
|
lock (message_states) {
|
||||||
if (message_states.has_key(message)) {
|
if (message_states.has_key(message)) {
|
||||||
|
@ -111,13 +111,13 @@ public class Manager : StreamInteractionModule, Object {
|
||||||
if (Plugin.DEBUG) print(@"OMEMO: message will be delayed: $state\n");
|
if (Plugin.DEBUG) print(@"OMEMO: message will be delayed: $state\n");
|
||||||
|
|
||||||
if (state.waiting_own_sessions > 0) {
|
if (state.waiting_own_sessions > 0) {
|
||||||
module.start_sessions_with((!)stream, conversation.account.bare_jid.to_string());
|
module.start_sessions_with((!)stream, conversation.account.bare_jid);
|
||||||
}
|
}
|
||||||
if (state.waiting_other_sessions > 0 && message.counterpart != null) {
|
if (state.waiting_other_sessions > 0 && message.counterpart != null) {
|
||||||
module.start_sessions_with((!)stream, ((!)message.counterpart).bare_jid.to_string());
|
module.start_sessions_with((!)stream, ((!)message.counterpart).bare_jid);
|
||||||
}
|
}
|
||||||
if (state.waiting_other_devicelist && message.counterpart != null) {
|
if (state.waiting_other_devicelist && message.counterpart != null) {
|
||||||
module.request_user_devicelist((!)stream, ((!)message.counterpart).bare_jid.to_string());
|
module.request_user_devicelist((!)stream, ((!)message.counterpart).bare_jid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,20 +132,20 @@ public class Manager : StreamInteractionModule, Object {
|
||||||
stream_interactor.module_manager.get_module(account, StreamModule.IDENTITY).session_start_failed.connect((jid, device_id) => on_session_started(account, jid, true));
|
stream_interactor.module_manager.get_module(account, StreamModule.IDENTITY).session_start_failed.connect((jid, device_id) => on_session_started(account, jid, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_stream_negotiated(Account account, Core.XmppStream stream) {
|
private void on_stream_negotiated(Account account, XmppStream stream) {
|
||||||
stream_interactor.module_manager.get_module(account, StreamModule.IDENTITY).request_user_devicelist(stream, account.bare_jid.to_string());
|
stream_interactor.module_manager.get_module(account, StreamModule.IDENTITY).request_user_devicelist(stream, account.bare_jid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_session_started(Account account, string jid, bool failed) {
|
private void on_session_started(Account account, Jid jid, bool failed) {
|
||||||
if (Plugin.DEBUG) print(@"OMEMO: session start between $(account.bare_jid) and $jid $(failed ? "failed" : "successful")\n");
|
if (Plugin.DEBUG) print(@"OMEMO: session start between $(account.bare_jid) and $jid $(failed ? "failed" : "successful")\n");
|
||||||
HashSet<Entities.Message> send_now = new HashSet<Entities.Message>();
|
HashSet<Entities.Message> send_now = new HashSet<Entities.Message>();
|
||||||
lock (message_states) {
|
lock (message_states) {
|
||||||
foreach (Entities.Message msg in message_states.keys) {
|
foreach (Entities.Message msg in message_states.keys) {
|
||||||
if (!msg.account.equals(account)) continue;
|
if (!msg.account.equals(account)) continue;
|
||||||
MessageState state = message_states[msg];
|
MessageState state = message_states[msg];
|
||||||
if (account.bare_jid.to_string() == jid) {
|
if (account.bare_jid.equals(jid)) {
|
||||||
state.waiting_own_sessions--;
|
state.waiting_own_sessions--;
|
||||||
} else if (msg.counterpart != null && ((!)msg.counterpart).bare_jid.to_string() == jid) {
|
} else if (msg.counterpart != null && msg.counterpart.equals_bare(jid)) {
|
||||||
state.waiting_other_sessions--;
|
state.waiting_other_sessions--;
|
||||||
}
|
}
|
||||||
if (state.should_retry_now()) {
|
if (state.should_retry_now()) {
|
||||||
|
@ -162,16 +162,16 @@ public class Manager : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_device_list_loaded(Account account, string jid) {
|
private void on_device_list_loaded(Account account, Jid jid) {
|
||||||
if (Plugin.DEBUG) print(@"OMEMO: received device list for $(account.bare_jid) from $jid\n");
|
if (Plugin.DEBUG) print(@"OMEMO: received device list for $(account.bare_jid) from $jid\n");
|
||||||
HashSet<Entities.Message> send_now = new HashSet<Entities.Message>();
|
HashSet<Entities.Message> send_now = new HashSet<Entities.Message>();
|
||||||
lock (message_states) {
|
lock (message_states) {
|
||||||
foreach (Entities.Message msg in message_states.keys) {
|
foreach (Entities.Message msg in message_states.keys) {
|
||||||
if (!msg.account.equals(account)) continue;
|
if (!msg.account.equals(account)) continue;
|
||||||
MessageState state = message_states[msg];
|
MessageState state = message_states[msg];
|
||||||
if (account.bare_jid.to_string() == jid) {
|
if (account.bare_jid.equals(jid)) {
|
||||||
state.waiting_own_devicelist = false;
|
state.waiting_own_devicelist = false;
|
||||||
} else if (msg.counterpart != null && ((!)msg.counterpart).bare_jid.to_string() == jid) {
|
} else if (msg.counterpart != null && msg.counterpart.equals_bare(jid)) {
|
||||||
state.waiting_other_devicelist = false;
|
state.waiting_other_devicelist = false;
|
||||||
}
|
}
|
||||||
if (state.should_retry_now()) {
|
if (state.should_retry_now()) {
|
||||||
|
@ -188,7 +188,7 @@ public class Manager : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update meta database
|
// Update meta database
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream == null) {
|
if (stream == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -197,10 +197,10 @@ public class Manager : StreamInteractionModule, Object {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ArrayList<int32> device_list = module.get_device_list(jid);
|
ArrayList<int32> device_list = module.get_device_list(jid);
|
||||||
db.identity_meta.insert_device_list(jid, device_list);
|
db.identity_meta.insert_device_list(jid.bare_jid.to_string(), device_list);
|
||||||
int inc = 0;
|
int inc = 0;
|
||||||
foreach (Row row in db.identity_meta.with_address(jid).with_null(db.identity_meta.identity_key_public_base64)) {
|
foreach (Row row in db.identity_meta.with_address(jid.bare_jid.to_string()).with_null(db.identity_meta.identity_key_public_base64)) {
|
||||||
module.fetch_bundle(stream, row[db.identity_meta.address_name], row[db.identity_meta.device_id]);
|
module.fetch_bundle(stream, Jid.parse(row[db.identity_meta.address_name]), row[db.identity_meta.device_id]);
|
||||||
inc++;
|
inc++;
|
||||||
}
|
}
|
||||||
if (inc > 0) {
|
if (inc > 0) {
|
||||||
|
@ -208,8 +208,8 @@ public class Manager : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void on_bundle_fetched(Account account, string jid, int32 device_id, Bundle bundle) {
|
public void on_bundle_fetched(Account account, Jid jid, int32 device_id, Bundle bundle) {
|
||||||
db.identity_meta.insert_device_bundle(jid, device_id, bundle);
|
db.identity_meta.insert_device_bundle(jid.bare_jid.to_string(), device_id, bundle);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_store_created(Account account, Store store) {
|
private void on_store_created(Account account, Store store) {
|
||||||
|
@ -252,11 +252,11 @@ public class Manager : StreamInteractionModule, Object {
|
||||||
|
|
||||||
|
|
||||||
public bool can_encrypt(Entities.Conversation conversation) {
|
public bool can_encrypt(Entities.Conversation conversation) {
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(conversation.account);
|
XmppStream? stream = stream_interactor.get_stream(conversation.account);
|
||||||
if (stream == null) return false;
|
if (stream == null) return false;
|
||||||
StreamModule? module = ((!)stream).get_module(StreamModule.IDENTITY);
|
StreamModule? module = ((!)stream).get_module(StreamModule.IDENTITY);
|
||||||
if (module == null) return false;
|
if (module == null) return false;
|
||||||
return ((!)module).is_known_address(conversation.counterpart.bare_jid.to_string());
|
return ((!)module).is_known_address(conversation.counterpart.bare_jid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void start(StreamInteractor stream_interactor, Database db) {
|
public static void start(StreamInteractor stream_interactor, Database db) {
|
||||||
|
|
|
@ -2,12 +2,12 @@ using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Plugins.Omemo {
|
namespace Dino.Plugins.Omemo {
|
||||||
|
|
||||||
public class MessageFlag : Message.MessageFlag {
|
public class MessageFlag : Xmpp.MessageFlag {
|
||||||
public const string id = "omemo";
|
public const string id = "omemo";
|
||||||
|
|
||||||
public bool decrypted = false;
|
public bool decrypted = false;
|
||||||
|
|
||||||
public static MessageFlag? get_flag(Message.Stanza message) {
|
public static MessageFlag? get_flag(MessageStanza message) {
|
||||||
return (MessageFlag) message.get_flag(NS_URI, id);
|
return (MessageFlag) message.get_flag(NS_URI, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
using Xmpp;
|
using Xmpp;
|
||||||
using Xmpp.Core;
|
using Xmpp;
|
||||||
using Xmpp.Xep;
|
using Xmpp.Xep;
|
||||||
using Signal;
|
using Signal;
|
||||||
|
|
||||||
|
@ -14,33 +14,32 @@ private const string NODE_VERIFICATION = NS_URI + ".verification";
|
||||||
private const int NUM_KEYS_TO_PUBLISH = 100;
|
private const int NUM_KEYS_TO_PUBLISH = 100;
|
||||||
|
|
||||||
public class StreamModule : XmppStreamModule {
|
public class StreamModule : XmppStreamModule {
|
||||||
public static Core.ModuleIdentity<StreamModule> IDENTITY = new Core.ModuleIdentity<StreamModule>(NS_URI, "omemo_module");
|
public static Xmpp.ModuleIdentity<StreamModule> IDENTITY = new Xmpp.ModuleIdentity<StreamModule>(NS_URI, "omemo_module");
|
||||||
|
|
||||||
private Store store;
|
private Store store;
|
||||||
private ConcurrentSet<string> active_bundle_requests = new ConcurrentSet<string>();
|
private ConcurrentSet<string> active_bundle_requests = new ConcurrentSet<string>();
|
||||||
private ConcurrentSet<string> active_devicelist_requests = new ConcurrentSet<string>();
|
private ConcurrentSet<Jid> active_devicelist_requests = new ConcurrentSet<Jid>();
|
||||||
private Map<string, ArrayList<int32>> device_lists = new HashMap<string, ArrayList<int32>>();
|
private Map<Jid, ArrayList<int32>> device_lists = new HashMap<Jid, ArrayList<int32>>(Jid.hash_bare_func, Jid.equals_bare_func);
|
||||||
private Map<string, ArrayList<int32>> ignored_devices = new HashMap<string, ArrayList<int32>>();
|
private Map<Jid, ArrayList<int32>> ignored_devices = new HashMap<Jid, ArrayList<int32>>(Jid.hash_bare_func, Jid.equals_bare_func);
|
||||||
private ReceivedPipelineListener received_pipeline_listener;
|
private ReceivedPipelineListener received_pipeline_listener;
|
||||||
|
|
||||||
public signal void store_created(Store store);
|
public signal void store_created(Store store);
|
||||||
public signal void device_list_loaded(string jid);
|
public signal void device_list_loaded(Jid jid);
|
||||||
public signal void bundle_fetched(string jid, int device_id, Bundle bundle);
|
public signal void bundle_fetched(Jid jid, int device_id, Bundle bundle);
|
||||||
public signal void session_started(string jid, int device_id);
|
public signal void session_started(Jid jid, int device_id);
|
||||||
public signal void session_start_failed(string jid, int device_id);
|
public signal void session_start_failed(Jid jid, int device_id);
|
||||||
|
|
||||||
public EncryptState encrypt(Message.Stanza message, string self_bare_jid) {
|
public EncryptState encrypt(MessageStanza message, Jid self_jid) {
|
||||||
EncryptState status = new EncryptState();
|
EncryptState status = new EncryptState();
|
||||||
if (!Plugin.ensure_context()) return status;
|
if (!Plugin.ensure_context()) return status;
|
||||||
if (message.to == null) return status;
|
if (message.to == null) return status;
|
||||||
try {
|
try {
|
||||||
string name = get_bare_jid((!)message.to);
|
if (!device_lists.has_key(self_jid)) return status;
|
||||||
if (!device_lists.has_key(self_bare_jid)) return status;
|
|
||||||
status.own_list = true;
|
status.own_list = true;
|
||||||
status.own_devices = device_lists.get(self_bare_jid).size;
|
status.own_devices = device_lists.get(self_jid).size;
|
||||||
if (!device_lists.has_key(name)) return status;
|
if (!device_lists.has_key(message.to)) return status;
|
||||||
status.other_list = true;
|
status.other_list = true;
|
||||||
status.other_devices = device_lists.get(name).size;
|
status.other_devices = device_lists.get(message.to).size;
|
||||||
if (status.own_devices == 0 || status.other_devices == 0) return status;
|
if (status.own_devices == 0 || status.other_devices == 0) return status;
|
||||||
|
|
||||||
uint8[] key = new uint8[16];
|
uint8[] key = new uint8[16];
|
||||||
|
@ -59,9 +58,9 @@ public class StreamModule : XmppStreamModule {
|
||||||
.put_node(new StanzaNode.build("payload", NS_URI)
|
.put_node(new StanzaNode.build("payload", NS_URI)
|
||||||
.put_node(new StanzaNode.text(Base64.encode(ciphertext))));
|
.put_node(new StanzaNode.text(Base64.encode(ciphertext))));
|
||||||
|
|
||||||
Address address = new Address(name, 0);
|
Address address = new Address(message.to.bare_jid.to_string(), 0);
|
||||||
foreach(int32 device_id in device_lists[name]) {
|
foreach(int32 device_id in device_lists[message.to]) {
|
||||||
if (is_ignored_device(name, device_id)) {
|
if (is_ignored_device(message.to, device_id)) {
|
||||||
status.other_lost++;
|
status.other_lost++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -75,9 +74,9 @@ public class StreamModule : XmppStreamModule {
|
||||||
else status.other_failure++;
|
else status.other_failure++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
address.name = self_bare_jid;
|
address.name = self_jid.bare_jid.to_string();
|
||||||
foreach(int32 device_id in device_lists[self_bare_jid]) {
|
foreach(int32 device_id in device_lists[self_jid]) {
|
||||||
if (is_ignored_device(self_bare_jid, device_id)) {
|
if (is_ignored_device(self_jid, device_id)) {
|
||||||
status.own_lost++;
|
status.own_lost++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -119,26 +118,26 @@ public class StreamModule : XmppStreamModule {
|
||||||
this.store = Plugin.get_context().create_store();
|
this.store = Plugin.get_context().create_store();
|
||||||
store_created(store);
|
store_created(store);
|
||||||
received_pipeline_listener = new ReceivedPipelineListener(store);
|
received_pipeline_listener = new ReceivedPipelineListener(store);
|
||||||
stream.get_module(Message.Module.IDENTITY).received_pipeline.connect(received_pipeline_listener);
|
stream.get_module(MessageModule.IDENTITY).received_pipeline.connect(received_pipeline_listener);
|
||||||
stream.get_module(Pubsub.Module.IDENTITY).add_filtered_notification(stream, NODE_DEVICELIST, (stream, jid, id, node) => on_devicelist(stream, jid, id, node));
|
stream.get_module(Pubsub.Module.IDENTITY).add_filtered_notification(stream, NODE_DEVICELIST, (stream, jid, id, node) => on_devicelist(stream, jid, id, node));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void detach(XmppStream stream) {
|
public override void detach(XmppStream stream) {
|
||||||
stream.get_module(Message.Module.IDENTITY).received_pipeline.disconnect(received_pipeline_listener);
|
stream.get_module(MessageModule.IDENTITY).received_pipeline.disconnect(received_pipeline_listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void request_user_devicelist(XmppStream stream, string jid) {
|
public void request_user_devicelist(XmppStream stream, Jid jid) {
|
||||||
if (active_devicelist_requests.add(jid)) {
|
if (active_devicelist_requests.add(jid)) {
|
||||||
if (Plugin.DEBUG) print(@"OMEMO: requesting device list for $jid\n");
|
if (Plugin.DEBUG) print(@"OMEMO: requesting device list for $jid\n");
|
||||||
stream.get_module(Pubsub.Module.IDENTITY).request(stream, jid, NODE_DEVICELIST, (stream, jid, id, node) => on_devicelist(stream, jid, id, node));
|
stream.get_module(Pubsub.Module.IDENTITY).request(stream, jid, NODE_DEVICELIST, (stream, jid, id, node) => on_devicelist(stream, jid, id, node));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void on_devicelist(XmppStream stream, string jid, string? id, StanzaNode? node_) {
|
public void on_devicelist(XmppStream stream, Jid jid, string? id, StanzaNode? node_) {
|
||||||
StanzaNode node = node_ ?? new StanzaNode.build("list", NS_URI).add_self_xmlns();
|
StanzaNode node = node_ ?? new StanzaNode.build("list", NS_URI).add_self_xmlns();
|
||||||
string? my_jid = stream.get_flag(Bind.Flag.IDENTITY).my_jid;
|
Jid? my_jid = stream.get_flag(Bind.Flag.IDENTITY).my_jid;
|
||||||
if (my_jid == null) return;
|
if (my_jid == null) return;
|
||||||
if (jid == get_bare_jid((!)my_jid) && store.local_registration_id != 0) {
|
if (jid.equals_bare(my_jid) && store.local_registration_id != 0) {
|
||||||
bool am_on_devicelist = false;
|
bool am_on_devicelist = false;
|
||||||
foreach (StanzaNode device_node in node.get_subnodes("device")) {
|
foreach (StanzaNode device_node in node.get_subnodes("device")) {
|
||||||
int device_id = device_node.get_attribute_int("id");
|
int device_id = device_node.get_attribute_int("id");
|
||||||
|
@ -164,17 +163,17 @@ public class StreamModule : XmppStreamModule {
|
||||||
device_list_loaded(jid);
|
device_list_loaded(jid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start_sessions_with(XmppStream stream, string bare_jid) {
|
public void start_sessions_with(XmppStream stream, Jid jid) {
|
||||||
if (!device_lists.has_key(bare_jid)) {
|
if (!device_lists.has_key(jid)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Address address = new Address(bare_jid, 0);
|
Address address = new Address(jid.bare_jid.to_string(), 0);
|
||||||
foreach(int32 device_id in device_lists[bare_jid]) {
|
foreach(int32 device_id in device_lists[jid]) {
|
||||||
if (!is_ignored_device(bare_jid, device_id)) {
|
if (!is_ignored_device(jid, device_id)) {
|
||||||
address.device_id = device_id;
|
address.device_id = device_id;
|
||||||
try {
|
try {
|
||||||
if (!store.contains_session(address)) {
|
if (!store.contains_session(address)) {
|
||||||
start_session_with(stream, bare_jid, device_id);
|
start_session_with(stream, jid, device_id);
|
||||||
}
|
}
|
||||||
} catch (Error e) {
|
} catch (Error e) {
|
||||||
// Ignore
|
// Ignore
|
||||||
|
@ -184,25 +183,25 @@ public class StreamModule : XmppStreamModule {
|
||||||
address.device_id = 0;
|
address.device_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start_session_with(XmppStream stream, string bare_jid, int device_id) {
|
public void start_session_with(XmppStream stream, Jid jid, int device_id) {
|
||||||
if (active_bundle_requests.add(bare_jid + @":$device_id")) {
|
if (active_bundle_requests.add(jid.bare_jid.to_string() + @":$device_id")) {
|
||||||
if (Plugin.DEBUG) print(@"OMEMO: Asking for bundle from $bare_jid:$device_id\n");
|
if (Plugin.DEBUG) print(@"OMEMO: Asking for bundle from $(jid.bare_jid.to_string()):$device_id\n");
|
||||||
stream.get_module(Pubsub.Module.IDENTITY).request(stream, bare_jid, @"$NODE_BUNDLES:$device_id", (stream, jid, id, node) => {
|
stream.get_module(Pubsub.Module.IDENTITY).request(stream, jid.bare_jid, @"$NODE_BUNDLES:$device_id", (stream, jid, id, node) => {
|
||||||
on_other_bundle_result(stream, jid, device_id, id, node);
|
on_other_bundle_result(stream, jid, device_id, id, node);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fetch_bundle(XmppStream stream, string bare_jid, int device_id) {
|
public void fetch_bundle(XmppStream stream, Jid jid, int device_id) {
|
||||||
if (active_bundle_requests.add(bare_jid + @":$device_id")) {
|
if (active_bundle_requests.add(jid.bare_jid.to_string() + @":$device_id")) {
|
||||||
if (Plugin.DEBUG) print(@"OMEMO: Asking for bundle from $bare_jid:$device_id\n");
|
if (Plugin.DEBUG) print(@"OMEMO: Asking for bundle from $(jid.bare_jid.to_string()):$device_id\n");
|
||||||
stream.get_module(Pubsub.Module.IDENTITY).request(stream, bare_jid, @"$NODE_BUNDLES:$device_id", (stream, jid, id, node) => {
|
stream.get_module(Pubsub.Module.IDENTITY).request(stream, jid.bare_jid, @"$NODE_BUNDLES:$device_id", (stream, jid, id, node) => {
|
||||||
bundle_fetched(jid, device_id, new Bundle(node));
|
bundle_fetched(jid, device_id, new Bundle(node));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<int32> get_device_list(string jid) {
|
public ArrayList<int32> get_device_list(Jid jid) {
|
||||||
if (is_known_address(jid)) {
|
if (is_known_address(jid)) {
|
||||||
return device_lists[jid];
|
return device_lists[jid];
|
||||||
} else {
|
} else {
|
||||||
|
@ -210,11 +209,11 @@ public class StreamModule : XmppStreamModule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool is_known_address(string name) {
|
public bool is_known_address(Jid jid) {
|
||||||
return device_lists.has_key(name);
|
return device_lists.has_key(jid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ignore_device(string jid, int32 device_id) {
|
public void ignore_device(Jid jid, int32 device_id) {
|
||||||
if (device_id <= 0) return;
|
if (device_id <= 0) return;
|
||||||
lock (ignored_devices) {
|
lock (ignored_devices) {
|
||||||
if (!ignored_devices.has_key(jid)) {
|
if (!ignored_devices.has_key(jid)) {
|
||||||
|
@ -225,14 +224,14 @@ public class StreamModule : XmppStreamModule {
|
||||||
session_start_failed(jid, device_id);
|
session_start_failed(jid, device_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool is_ignored_device(string jid, int32 device_id) {
|
public bool is_ignored_device(Jid jid, int32 device_id) {
|
||||||
if (device_id <= 0) return true;
|
if (device_id <= 0) return true;
|
||||||
lock (ignored_devices) {
|
lock (ignored_devices) {
|
||||||
return ignored_devices.has_key(jid) && ignored_devices[jid].contains(device_id);
|
return ignored_devices.has_key(jid) && ignored_devices[jid].contains(device_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_other_bundle_result(XmppStream stream, string jid, int device_id, string? id, StanzaNode? node) {
|
private void on_other_bundle_result(XmppStream stream, Jid jid, int device_id, string? id, StanzaNode? node) {
|
||||||
bool fail = false;
|
bool fail = false;
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
// Device not registered, shouldn't exist
|
// Device not registered, shouldn't exist
|
||||||
|
@ -255,7 +254,7 @@ public class StreamModule : XmppStreamModule {
|
||||||
if (pre_key_id < 0 || pre_key == null) {
|
if (pre_key_id < 0 || pre_key == null) {
|
||||||
fail = true;
|
fail = true;
|
||||||
} else {
|
} else {
|
||||||
Address address = new Address(jid, device_id);
|
Address address = new Address(jid.bare_jid.to_string(), device_id);
|
||||||
try {
|
try {
|
||||||
if (store.contains_session(address)) {
|
if (store.contains_session(address)) {
|
||||||
return;
|
return;
|
||||||
|
@ -273,16 +272,16 @@ public class StreamModule : XmppStreamModule {
|
||||||
if (fail) {
|
if (fail) {
|
||||||
stream.get_module(IDENTITY).ignore_device(jid, device_id);
|
stream.get_module(IDENTITY).ignore_device(jid, device_id);
|
||||||
}
|
}
|
||||||
stream.get_module(IDENTITY).active_bundle_requests.remove(jid + @":$device_id");
|
stream.get_module(IDENTITY).active_bundle_requests.remove(jid.bare_jid.to_string() + @":$device_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void publish_bundles_if_needed(XmppStream stream, string jid) {
|
public void publish_bundles_if_needed(XmppStream stream, Jid jid) {
|
||||||
if (active_bundle_requests.add(jid + @":$(store.local_registration_id)")) {
|
if (active_bundle_requests.add(jid.bare_jid.to_string() + @":$(store.local_registration_id)")) {
|
||||||
stream.get_module(Pubsub.Module.IDENTITY).request(stream, jid, @"$NODE_BUNDLES:$(store.local_registration_id)", on_self_bundle_result);
|
stream.get_module(Pubsub.Module.IDENTITY).request(stream, jid, @"$NODE_BUNDLES:$(store.local_registration_id)", on_self_bundle_result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_self_bundle_result(XmppStream stream, string jid, string? id, StanzaNode? node) {
|
private void on_self_bundle_result(XmppStream stream, Jid jid, string? id, StanzaNode? node) {
|
||||||
if (!Plugin.ensure_context()) return;
|
if (!Plugin.ensure_context()) return;
|
||||||
Map<int, ECPublicKey> keys = new HashMap<int, ECPublicKey>();
|
Map<int, ECPublicKey> keys = new HashMap<int, ECPublicKey>();
|
||||||
ECPublicKey? identity_key = null;
|
ECPublicKey? identity_key = null;
|
||||||
|
@ -350,7 +349,7 @@ public class StreamModule : XmppStreamModule {
|
||||||
} catch (Error e) {
|
} catch (Error e) {
|
||||||
if (Plugin.DEBUG) print(@"Unexpected error while publishing bundle: $(e.message)\n");
|
if (Plugin.DEBUG) print(@"Unexpected error while publishing bundle: $(e.message)\n");
|
||||||
}
|
}
|
||||||
stream.get_module(IDENTITY).active_bundle_requests.remove(jid + @":$(store.local_registration_id)");
|
stream.get_module(IDENTITY).active_bundle_requests.remove(jid.bare_jid.to_string() + @":$(store.local_registration_id)");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void publish_bundles(XmppStream stream, SignedPreKeyRecord signed_pre_key_record, IdentityKeyPair identity_key_pair, Set<PreKeyRecord> pre_key_records, int32 device_id) throws Error {
|
public static void publish_bundles(XmppStream stream, SignedPreKeyRecord signed_pre_key_record, IdentityKeyPair identity_key_pair, Set<PreKeyRecord> pre_key_records, int32 device_id) throws Error {
|
||||||
|
@ -385,7 +384,7 @@ public class StreamModule : XmppStreamModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class ReceivedPipelineListener : StanzaListener<Message.Stanza> {
|
public class ReceivedPipelineListener : StanzaListener<MessageStanza> {
|
||||||
|
|
||||||
private const string[] after_actions_const = {"EXTRACT_MESSAGE_2"};
|
private const string[] after_actions_const = {"EXTRACT_MESSAGE_2"};
|
||||||
|
|
||||||
|
@ -398,7 +397,7 @@ public class ReceivedPipelineListener : StanzaListener<Message.Stanza> {
|
||||||
this.store = store;
|
this.store = store;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async void run(Core.XmppStream stream, Message.Stanza message) {
|
public override async void run(XmppStream stream, MessageStanza message) {
|
||||||
StanzaNode? _encrypted = message.stanza.get_subnode("encrypted", NS_URI);
|
StanzaNode? _encrypted = message.stanza.get_subnode("encrypted", NS_URI);
|
||||||
if (_encrypted == null || MessageFlag.get_flag(message) != null || message.from == null) return;
|
if (_encrypted == null || MessageFlag.get_flag(message) != null || message.from == null) return;
|
||||||
StanzaNode encrypted = (!)_encrypted;
|
StanzaNode encrypted = (!)_encrypted;
|
||||||
|
@ -419,7 +418,7 @@ public class ReceivedPipelineListener : StanzaListener<Message.Stanza> {
|
||||||
uint8[] key;
|
uint8[] key;
|
||||||
uint8[] ciphertext = Base64.decode((!)payload);
|
uint8[] ciphertext = Base64.decode((!)payload);
|
||||||
uint8[] iv = Base64.decode((!)iv_node);
|
uint8[] iv = Base64.decode((!)iv_node);
|
||||||
Address address = new Address(get_bare_jid((!)message.from), header.get_attribute_int("sid"));
|
Address address = new Address(message.from.bare_jid.to_string(), header.get_attribute_int("sid"));
|
||||||
if (key_node.get_attribute_bool("prekey")) {
|
if (key_node.get_attribute_bool("prekey")) {
|
||||||
PreKeySignalMessage msg = Plugin.get_context().deserialize_pre_key_signal_message(Base64.decode((!)key_node_content));
|
PreKeySignalMessage msg = Plugin.get_context().deserialize_pre_key_signal_message(Base64.decode((!)key_node_content));
|
||||||
SessionCipher cipher = store.create_session_cipher(address);
|
SessionCipher cipher = store.create_session_cipher(address);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using Qlite;
|
using Qlite;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Plugins.OpenPgp {
|
namespace Dino.Plugins.OpenPgp {
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
using Dino.Entities;
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Plugins.OpenPgp {
|
namespace Dino.Plugins.OpenPgp {
|
||||||
|
|
||||||
|
|
|
@ -63,17 +63,17 @@ public class Manager : StreamInteractionModule, Object {
|
||||||
return gpgkeys;
|
return gpgkeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_pre_message_received(Entities.Message message, Xmpp.Message.Stanza message_stanza, Conversation conversation) {
|
private void on_pre_message_received(Entities.Message message, Xmpp.MessageStanza message_stanza, Conversation conversation) {
|
||||||
if (MessageFlag.get_flag(message_stanza) != null && MessageFlag.get_flag(message_stanza).decrypted) {
|
if (MessageFlag.get_flag(message_stanza) != null && MessageFlag.get_flag(message_stanza).decrypted) {
|
||||||
message.encryption = Encryption.PGP;
|
message.encryption = Encryption.PGP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void check_encypt(Entities.Message message, Xmpp.Message.Stanza message_stanza, Conversation conversation) {
|
private void check_encypt(Entities.Message message, Xmpp.MessageStanza message_stanza, Conversation conversation) {
|
||||||
try {
|
try {
|
||||||
if (message.encryption == Encryption.PGP) {
|
if (message.encryption == Encryption.PGP) {
|
||||||
GPG.Key[] keys = get_key_fprs(conversation);
|
GPG.Key[] keys = get_key_fprs(conversation);
|
||||||
Core.XmppStream? stream = stream_interactor.get_stream(conversation.account);
|
XmppStream? stream = stream_interactor.get_stream(conversation.account);
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
bool encrypted = stream.get_module(Module.IDENTITY).encrypt(message_stanza, keys);
|
bool encrypted = stream.get_module(Module.IDENTITY).encrypt(message_stanza, keys);
|
||||||
if (!encrypted) message.marked = Entities.Message.Marked.WONTSEND;
|
if (!encrypted) message.marked = Entities.Message.Marked.WONTSEND;
|
||||||
|
@ -91,7 +91,7 @@ public class Manager : StreamInteractionModule, Object {
|
||||||
|
|
||||||
private void on_account_added(Account account) {
|
private void on_account_added(Account account) {
|
||||||
stream_interactor.module_manager.get_module(account, Module.IDENTITY).received_jid_key_id.connect((stream, jid, key_id) => {
|
stream_interactor.module_manager.get_module(account, Module.IDENTITY).received_jid_key_id.connect((stream, jid, key_id) => {
|
||||||
on_jid_key_received(account, new Jid(jid), key_id);
|
on_jid_key_received(account, jid, key_id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ public class Plugin : Plugins.RootInterface, Object {
|
||||||
|
|
||||||
public void shutdown() { }
|
public void shutdown() { }
|
||||||
|
|
||||||
private void on_initialize_account_modules(Account account, ArrayList<Xmpp.Core.XmppStreamModule> modules) {
|
private void on_initialize_account_modules(Account account, ArrayList<Xmpp.XmppStreamModule> modules) {
|
||||||
Module module = new Module(db.get_account_key(account));
|
Module module = new Module(db.get_account_key(account));
|
||||||
this.modules[account] = module;
|
this.modules[account] = module;
|
||||||
modules.add(module);
|
modules.add(module);
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
using Xmpp;
|
using Xmpp;
|
||||||
using Xmpp.Core;
|
using Xmpp;
|
||||||
|
|
||||||
namespace Dino.Plugins.OpenPgp {
|
namespace Dino.Plugins.OpenPgp {
|
||||||
|
|
||||||
public class Flag : XmppStreamFlag {
|
public class Flag : XmppStreamFlag {
|
||||||
public static FlagIdentity<Flag> IDENTITY = new FlagIdentity<Flag>(NS_URI, "pgp");
|
public static FlagIdentity<Flag> IDENTITY = new FlagIdentity<Flag>(NS_URI, "pgp");
|
||||||
|
|
||||||
public HashMap<string, string> key_ids = new HashMap<string, string>();
|
public HashMap<Jid, string> key_ids = new HashMap<Jid, string>(Jid.hash_bare_func, Jid.equals_bare_func);
|
||||||
|
|
||||||
public string? get_key_id(string jid) { return key_ids[get_bare_jid(jid)]; }
|
public string? get_key_id(Jid jid) { return key_ids[jid]; }
|
||||||
|
|
||||||
public void set_key_id(string jid, string key) { key_ids[get_bare_jid(jid)] = key; }
|
public void set_key_id(Jid jid, string key) { key_ids[jid] = key; }
|
||||||
|
|
||||||
public override string get_ns() { return NS_URI; }
|
public override string get_ns() { return NS_URI; }
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using GPG;
|
using GPG;
|
||||||
|
|
||||||
using Xmpp;
|
using Xmpp;
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Dino.Plugins.OpenPgp {
|
namespace Dino.Plugins.OpenPgp {
|
||||||
private const string NS_URI = "jabber:x";
|
private const string NS_URI = "jabber:x";
|
||||||
|
@ -9,9 +8,9 @@ namespace Dino.Plugins.OpenPgp {
|
||||||
private const string NS_URI_SIGNED = NS_URI + ":signed";
|
private const string NS_URI_SIGNED = NS_URI + ":signed";
|
||||||
|
|
||||||
public class Module : XmppStreamModule {
|
public class Module : XmppStreamModule {
|
||||||
public static Core.ModuleIdentity<Module> IDENTITY = new Core.ModuleIdentity<Module>(NS_URI, "0027_current_pgp_usage");
|
public static Xmpp.ModuleIdentity<Module> IDENTITY = new Xmpp.ModuleIdentity<Module>(NS_URI, "0027_current_pgp_usage");
|
||||||
|
|
||||||
public signal void received_jid_key_id(XmppStream stream, string jid, string key_id);
|
public signal void received_jid_key_id(XmppStream stream, Jid jid, string key_id);
|
||||||
|
|
||||||
private string? signed_status = null;
|
private string? signed_status = null;
|
||||||
private Key? own_key = null;
|
private Key? own_key = null;
|
||||||
|
@ -33,7 +32,7 @@ namespace Dino.Plugins.OpenPgp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool encrypt(Message.Stanza message, GPG.Key[] keys) {
|
public bool encrypt(MessageStanza message, GPG.Key[] keys) {
|
||||||
string? enc_body = gpg_encrypt(message.body, keys);
|
string? enc_body = gpg_encrypt(message.body, keys);
|
||||||
if (enc_body != null) {
|
if (enc_body != null) {
|
||||||
message.stanza.put_node(new StanzaNode.build("x", NS_URI_ENCRYPTED).add_self_xmlns().put_node(new StanzaNode.text(enc_body)));
|
message.stanza.put_node(new StanzaNode.build("x", NS_URI_ENCRYPTED).add_self_xmlns().put_node(new StanzaNode.text(enc_body)));
|
||||||
|
@ -46,14 +45,14 @@ namespace Dino.Plugins.OpenPgp {
|
||||||
public override void attach(XmppStream stream) {
|
public override void attach(XmppStream stream) {
|
||||||
stream.get_module(Presence.Module.IDENTITY).received_presence.connect(on_received_presence);
|
stream.get_module(Presence.Module.IDENTITY).received_presence.connect(on_received_presence);
|
||||||
stream.get_module(Presence.Module.IDENTITY).pre_send_presence_stanza.connect(on_pre_send_presence_stanza);
|
stream.get_module(Presence.Module.IDENTITY).pre_send_presence_stanza.connect(on_pre_send_presence_stanza);
|
||||||
stream.get_module(Message.Module.IDENTITY).received_pipeline.connect(received_pipeline_decrypt_listener);
|
stream.get_module(MessageModule.IDENTITY).received_pipeline.connect(received_pipeline_decrypt_listener);
|
||||||
stream.add_flag(new Flag());
|
stream.add_flag(new Flag());
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void detach(XmppStream stream) {
|
public override void detach(XmppStream stream) {
|
||||||
stream.get_module(Presence.Module.IDENTITY).received_presence.disconnect(on_received_presence);
|
stream.get_module(Presence.Module.IDENTITY).received_presence.disconnect(on_received_presence);
|
||||||
stream.get_module(Presence.Module.IDENTITY).pre_send_presence_stanza.disconnect(on_pre_send_presence_stanza);
|
stream.get_module(Presence.Module.IDENTITY).pre_send_presence_stanza.disconnect(on_pre_send_presence_stanza);
|
||||||
stream.get_module(Message.Module.IDENTITY).received_pipeline.disconnect(received_pipeline_decrypt_listener);
|
stream.get_module(MessageModule.IDENTITY).received_pipeline.disconnect(received_pipeline_decrypt_listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void require(XmppStream stream) {
|
public static void require(XmppStream stream) {
|
||||||
|
@ -121,12 +120,12 @@ namespace Dino.Plugins.OpenPgp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MessageFlag : Message.MessageFlag {
|
public class MessageFlag : Xmpp.MessageFlag {
|
||||||
public const string id = "pgp";
|
public const string id = "pgp";
|
||||||
|
|
||||||
public bool decrypted = false;
|
public bool decrypted = false;
|
||||||
|
|
||||||
public static MessageFlag? get_flag(Message.Stanza message) {
|
public static MessageFlag? get_flag(MessageStanza message) {
|
||||||
return (MessageFlag) message.get_flag(NS_URI, id);
|
return (MessageFlag) message.get_flag(NS_URI, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,14 +133,14 @@ namespace Dino.Plugins.OpenPgp {
|
||||||
public override string get_id() { return id; }
|
public override string get_id() { return id; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ReceivedPipelineDecryptListener : StanzaListener<Message.Stanza> {
|
public class ReceivedPipelineDecryptListener : StanzaListener<MessageStanza> {
|
||||||
|
|
||||||
private const string[] after_actions_const = {"MODIFY_BODY"};
|
private const string[] after_actions_const = {"MODIFY_BODY"};
|
||||||
|
|
||||||
public override string action_group { get { return "ENCRYPT_BODY"; } }
|
public override string action_group { get { return "ENCRYPT_BODY"; } }
|
||||||
public override string[] after_actions { get { return after_actions_const; } }
|
public override string[] after_actions { get { return after_actions_const; } }
|
||||||
|
|
||||||
public override async void run(Core.XmppStream stream, Message.Stanza message) {
|
public override async void run(XmppStream stream, MessageStanza message) {
|
||||||
string? encrypted = get_cyphertext(message);
|
string? encrypted = get_cyphertext(message);
|
||||||
if (encrypted != null) {
|
if (encrypted != null) {
|
||||||
MessageFlag flag = new MessageFlag();
|
MessageFlag flag = new MessageFlag();
|
||||||
|
@ -171,7 +170,7 @@ public class ReceivedPipelineDecryptListener : StanzaListener<Message.Stanza> {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string? get_cyphertext(Message.Stanza message) {
|
private string? get_cyphertext(MessageStanza message) {
|
||||||
StanzaNode? x_node = message.stanza.get_subnode("x", NS_URI_ENCRYPTED);
|
StanzaNode? x_node = message.stanza.get_subnode("x", NS_URI_ENCRYPTED);
|
||||||
return x_node == null ? null : x_node.get_string_content();
|
return x_node == null ? null : x_node.get_string_content();
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ SOURCES
|
||||||
"src/module/bind.vala"
|
"src/module/bind.vala"
|
||||||
"src/module/iq/module.vala"
|
"src/module/iq/module.vala"
|
||||||
"src/module/iq/stanza.vala"
|
"src/module/iq/stanza.vala"
|
||||||
|
"src/module/jid.vala"
|
||||||
"src/module/message/module.vala"
|
"src/module/message/module.vala"
|
||||||
"src/module/message/stanza.vala"
|
"src/module/message/stanza.vala"
|
||||||
"src/module/presence/flag.vala"
|
"src/module/presence/flag.vala"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
namespace Xmpp.Core {
|
namespace Xmpp {
|
||||||
|
|
||||||
public class NamespaceState {
|
public class NamespaceState {
|
||||||
private HashMap<string, string> uri_to_name = new HashMap<string, string> ();
|
private HashMap<string, string> uri_to_name = new HashMap<string, string> ();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
namespace Xmpp.Core {
|
namespace Xmpp {
|
||||||
|
|
||||||
public class StanzaAttribute : StanzaEntry {
|
public class StanzaAttribute : StanzaEntry {
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
namespace Xmpp.Core {
|
namespace Xmpp {
|
||||||
|
|
||||||
public abstract class StanzaEntry {
|
public abstract class StanzaEntry {
|
||||||
protected const string ANSI_COLOR_END = "\x1b[0m";
|
protected const string ANSI_COLOR_END = "\x1b[0m";
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
namespace Xmpp.Core {
|
namespace Xmpp {
|
||||||
|
|
||||||
public const string XMLNS_URI = "http://www.w3.org/2000/xmlns/";
|
public const string XMLNS_URI = "http://www.w3.org/2000/xmlns/";
|
||||||
public const string XML_URI = "http://www.w3.org/XML/1998/namespace";
|
public const string XML_URI = "http://www.w3.org/XML/1998/namespace";
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
namespace Xmpp.Core {
|
namespace Xmpp {
|
||||||
|
|
||||||
public class StanzaWriter {
|
public class StanzaWriter {
|
||||||
private OutputStream output;
|
private OutputStream output;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
namespace Xmpp.Core {
|
namespace Xmpp {
|
||||||
|
|
||||||
public class XmppLog {
|
public class XmppLog {
|
||||||
protected const string ANSI_COLOR_END = "\x1b[0m";
|
protected const string ANSI_COLOR_END = "\x1b[0m";
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
namespace Xmpp.Core {
|
namespace Xmpp {
|
||||||
|
|
||||||
public errordomain IOStreamError {
|
public errordomain IOStreamError {
|
||||||
READ,
|
READ,
|
||||||
|
@ -13,7 +13,7 @@ public errordomain IOStreamError {
|
||||||
public class XmppStream {
|
public class XmppStream {
|
||||||
public const string NS_URI = "http://etherx.jabber.org/streams";
|
public const string NS_URI = "http://etherx.jabber.org/streams";
|
||||||
|
|
||||||
public string remote_name;
|
public Jid remote_name;
|
||||||
public XmppLog log = new XmppLog();
|
public XmppLog log = new XmppLog();
|
||||||
public StanzaNode? features { get; private set; default = new StanzaNode.build("features", NS_URI); }
|
public StanzaNode? features { get; private set; default = new StanzaNode.build("features", NS_URI); }
|
||||||
|
|
||||||
|
@ -43,13 +43,13 @@ public class XmppStream {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void connect(string? remote_name = null) throws IOStreamError {
|
public async void connect(string? remote_name = null) throws IOStreamError {
|
||||||
if (remote_name != null) this.remote_name = (!)remote_name;
|
if (remote_name != null) this.remote_name = Jid.parse(remote_name);
|
||||||
attach_negotation_modules();
|
attach_negotation_modules();
|
||||||
try {
|
try {
|
||||||
int min_priority = -1;
|
int min_priority = -1;
|
||||||
ConnectionProvider? best_provider = null;
|
ConnectionProvider? best_provider = null;
|
||||||
foreach (ConnectionProvider connection_provider in connection_providers) {
|
foreach (ConnectionProvider connection_provider in connection_providers) {
|
||||||
int? priority = yield connection_provider.get_priority(remote_name);
|
int? priority = yield connection_provider.get_priority(this.remote_name);
|
||||||
if (priority != null && (priority < min_priority || min_priority == -1)) {
|
if (priority != null && (priority < min_priority || min_priority == -1)) {
|
||||||
min_priority = priority;
|
min_priority = priority;
|
||||||
best_provider = connection_provider;
|
best_provider = connection_provider;
|
||||||
|
@ -60,7 +60,7 @@ public class XmppStream {
|
||||||
stream = yield best_provider.connect(this);
|
stream = yield best_provider.connect(this);
|
||||||
}
|
}
|
||||||
if (stream == null) {
|
if (stream == null) {
|
||||||
stream = yield (new SocketClient()).connect_async(new NetworkService("xmpp-client", "tcp", this.remote_name));
|
stream = yield (new SocketClient()).connect_async(new NetworkService("xmpp-client", "tcp", this.remote_name.to_string()));
|
||||||
}
|
}
|
||||||
if (stream == null) {
|
if (stream == null) {
|
||||||
throw new IOStreamError.CONNECT("client.connect() returned null");
|
throw new IOStreamError.CONNECT("client.connect() returned null");
|
||||||
|
@ -187,7 +187,7 @@ public class XmppStream {
|
||||||
|
|
||||||
private async void setup() throws IOStreamError {
|
private async void setup() throws IOStreamError {
|
||||||
StanzaNode outs = new StanzaNode.build("stream", "http://etherx.jabber.org/streams")
|
StanzaNode outs = new StanzaNode.build("stream", "http://etherx.jabber.org/streams")
|
||||||
.put_attribute("to", remote_name)
|
.put_attribute("to", remote_name.to_string())
|
||||||
.put_attribute("version", "1.0")
|
.put_attribute("version", "1.0")
|
||||||
.put_attribute("xmlns", "jabber:client")
|
.put_attribute("xmlns", "jabber:client")
|
||||||
.put_attribute("stream", "http://etherx.jabber.org/streams", XMLNS_URI);
|
.put_attribute("stream", "http://etherx.jabber.org/streams", XMLNS_URI);
|
||||||
|
@ -349,7 +349,7 @@ public abstract class XmppStreamNegotiationModule : XmppStreamModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class ConnectionProvider {
|
public abstract class ConnectionProvider {
|
||||||
public async abstract int? get_priority(string remote_name);
|
public async abstract int? get_priority(Jid remote_name);
|
||||||
public async abstract IOStream? connect(XmppStream stream);
|
public async abstract IOStream? connect(XmppStream stream);
|
||||||
public abstract string get_id();
|
public abstract string get_id();
|
||||||
}
|
}
|
||||||
|
@ -357,11 +357,11 @@ public abstract class ConnectionProvider {
|
||||||
public class StartTlsConnectionProvider : ConnectionProvider {
|
public class StartTlsConnectionProvider : ConnectionProvider {
|
||||||
private SrvTarget? srv_target;
|
private SrvTarget? srv_target;
|
||||||
|
|
||||||
public async override int? get_priority(string remote_name) {
|
public async override int? get_priority(Jid remote_name) {
|
||||||
GLib.List<SrvTarget>? xmpp_target = null;
|
GLib.List<SrvTarget>? xmpp_target = null;
|
||||||
try {
|
try {
|
||||||
GLibFixes.Resolver resolver = GLibFixes.Resolver.get_default();
|
GLibFixes.Resolver resolver = GLibFixes.Resolver.get_default();
|
||||||
xmpp_target = yield resolver.lookup_service_async("xmpp-client", "tcp", remote_name, null);
|
xmpp_target = yield resolver.lookup_service_async("xmpp-client", "tcp", remote_name.to_string(), null);
|
||||||
} catch (Error e) {
|
} catch (Error e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp.Bind {
|
namespace Xmpp.Bind {
|
||||||
private const string NS_URI = "urn:ietf:params:xml:ns:xmpp-bind";
|
private const string NS_URI = "urn:ietf:params:xml:ns:xmpp-bind";
|
||||||
|
|
||||||
|
@ -9,7 +7,7 @@ namespace Xmpp.Bind {
|
||||||
|
|
||||||
public string requested_resource { get; set; }
|
public string requested_resource { get; set; }
|
||||||
|
|
||||||
public signal void bound_to_resource(XmppStream stream, string my_jid);
|
public signal void bound_to_resource(XmppStream stream, Jid my_jid);
|
||||||
|
|
||||||
public Module(string requested_resource) {
|
public Module(string requested_resource) {
|
||||||
this.requested_resource = requested_resource;
|
this.requested_resource = requested_resource;
|
||||||
|
@ -20,7 +18,7 @@ namespace Xmpp.Bind {
|
||||||
if (flag == null || flag.finished) return;
|
if (flag == null || flag.finished) return;
|
||||||
|
|
||||||
if (iq.type_ == Iq.Stanza.TYPE_RESULT) {
|
if (iq.type_ == Iq.Stanza.TYPE_RESULT) {
|
||||||
flag.my_jid = iq.stanza.get_subnode("jid", NS_URI, true).get_string_content();
|
flag.my_jid = Jid.parse(iq.stanza.get_subnode("jid", NS_URI, true).get_string_content());
|
||||||
flag.finished = true;
|
flag.finished = true;
|
||||||
bound_to_resource(stream, flag.my_jid);
|
bound_to_resource(stream, flag.my_jid);
|
||||||
}
|
}
|
||||||
|
@ -62,7 +60,7 @@ namespace Xmpp.Bind {
|
||||||
|
|
||||||
public class Flag : XmppStreamFlag {
|
public class Flag : XmppStreamFlag {
|
||||||
public static FlagIdentity<Flag> IDENTITY = new FlagIdentity<Flag>(NS_URI, "bind");
|
public static FlagIdentity<Flag> IDENTITY = new FlagIdentity<Flag>(NS_URI, "bind");
|
||||||
public string? my_jid;
|
public Jid? my_jid;
|
||||||
public bool finished = false;
|
public bool finished = false;
|
||||||
|
|
||||||
public override string get_ns() { return NS_URI; }
|
public override string get_ns() { return NS_URI; }
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp.Iq {
|
namespace Xmpp.Iq {
|
||||||
private const string NS_URI = "jabber:client";
|
private const string NS_URI = "jabber:client";
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp.Iq {
|
namespace Xmpp.Iq {
|
||||||
|
|
||||||
public class Stanza : Xmpp.Stanza {
|
public class Stanza : Xmpp.Stanza {
|
||||||
|
@ -44,7 +42,7 @@ public class Stanza : Xmpp.Stanza {
|
||||||
stanza.put_node(associated_child);
|
stanza.put_node(associated_child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public Stanza.from_stanza(StanzaNode stanza_node, string? my_jid) {
|
public Stanza.from_stanza(StanzaNode stanza_node, Jid? my_jid) {
|
||||||
base.incoming(stanza_node, my_jid);
|
base.incoming(stanza_node, my_jid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,36 @@
|
||||||
public class Dino.Entities.Jid : Object {
|
namespace Xmpp {
|
||||||
public string? localpart { get; set; }
|
|
||||||
public string domainpart { get; set; }
|
public class Jid {
|
||||||
public string? resourcepart { get; set; }
|
public string? localpart;
|
||||||
|
public string domainpart;
|
||||||
|
public string? resourcepart;
|
||||||
|
|
||||||
public Jid bare_jid {
|
public Jid bare_jid {
|
||||||
owned get { return localpart != null ? new Jid(@"$localpart@$domainpart") : new Jid(domainpart); }
|
owned get { return is_bare() ? this : new Jid.components(localpart, domainpart, null); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private string jid { get; private set; }
|
public Jid domain_jid {
|
||||||
|
owned get { return is_domain() ? this : new Jid.components(null, domainpart, null); }
|
||||||
|
}
|
||||||
|
|
||||||
|
private string jid;
|
||||||
|
|
||||||
public Jid(string jid) {
|
public Jid(string jid) {
|
||||||
Jid? parsed = Jid.parse(jid);
|
Jid? parsed = Jid.parse(jid);
|
||||||
string? localpart = parsed != null ? parsed.localpart : null;
|
string? localpart = parsed != null ? (owned) parsed.localpart : null;
|
||||||
string domainpart = parsed != null ? parsed.domainpart : jid;
|
string domainpart = parsed != null ? (owned) parsed.domainpart : jid;
|
||||||
string? resourcepart = parsed != null ? parsed.resourcepart : null;
|
string? resourcepart = parsed != null ? (owned) parsed.resourcepart : null;
|
||||||
this.components(localpart, domainpart, resourcepart);
|
this.intern(jid, (owned) localpart, (owned) domainpart, (owned) resourcepart);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Jid.with_resource(string bare_jid, string resource) {
|
private Jid.intern(owned string jid, owned string? localpart, owned string domainpart, owned string? resourcepart) {
|
||||||
Jid? parsed = Jid.parse(bare_jid);
|
this.jid = (owned) jid;
|
||||||
this.components(parsed.localpart, parsed.domainpart, resource);
|
this.localpart = (owned) localpart;
|
||||||
|
this.domainpart = (owned) domainpart;
|
||||||
|
this.resourcepart = (owned) resourcepart;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Jid.components(string? localpart, string domainpart, string? resourcepart) {
|
public Jid.components(owned string? localpart, owned string domainpart, owned string? resourcepart) {
|
||||||
string jid = domainpart;
|
string jid = domainpart;
|
||||||
if (localpart != null) {
|
if (localpart != null) {
|
||||||
jid = @"$localpart@$jid";
|
jid = @"$localpart@$jid";
|
||||||
|
@ -31,9 +39,9 @@ public class Dino.Entities.Jid : Object {
|
||||||
jid = @"$jid/$resourcepart";
|
jid = @"$jid/$resourcepart";
|
||||||
}
|
}
|
||||||
this.jid = jid;
|
this.jid = jid;
|
||||||
this.localpart = localpart;
|
this.localpart = (owned) localpart;
|
||||||
this.domainpart = domainpart;
|
this.domainpart = (owned) domainpart;
|
||||||
this.resourcepart = resourcepart;
|
this.resourcepart = (owned) resourcepart;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Jid? parse(string jid) {
|
public static Jid? parse(string jid) {
|
||||||
|
@ -48,9 +56,17 @@ public class Dino.Entities.Jid : Object {
|
||||||
if (slash_index != -1 && resourcepart == "") return null;
|
if (slash_index != -1 && resourcepart == "") return null;
|
||||||
if (at_index != -1 && localpart == "") return null;
|
if (at_index != -1 && localpart == "") return null;
|
||||||
|
|
||||||
|
return new Jid.intern(jid, (owned) localpart, (owned) domainpart, (owned) resourcepart);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Jid with_resource(string? resourcepart) {
|
||||||
return new Jid.components(localpart, domainpart, resourcepart);
|
return new Jid.components(localpart, domainpart, resourcepart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool is_domain() {
|
||||||
|
return localpart == null && resourcepart == null;
|
||||||
|
}
|
||||||
|
|
||||||
public bool is_bare() {
|
public bool is_bare() {
|
||||||
return localpart != null && resourcepart == null;
|
return localpart != null && resourcepart == null;
|
||||||
}
|
}
|
||||||
|
@ -87,3 +103,5 @@ public class Dino.Entities.Jid : Object {
|
||||||
return jid.to_string().hash();
|
return jid.to_string().hash();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,27 +1,27 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp.Message {
|
|
||||||
|
namespace Xmpp {
|
||||||
private const string NS_URI = "jabber:client";
|
private const string NS_URI = "jabber:client";
|
||||||
|
|
||||||
public class Module : XmppStreamModule {
|
public class MessageModule : XmppStreamModule {
|
||||||
public static ModuleIdentity<Module> IDENTITY = new ModuleIdentity<Module>(NS_URI, "message_module");
|
public static ModuleIdentity<MessageModule> IDENTITY = new ModuleIdentity<MessageModule>(NS_URI, "message_module");
|
||||||
|
|
||||||
public StanzaListenerHolder<Message.Stanza> received_pipeline = new StanzaListenerHolder<Message.Stanza>();
|
public StanzaListenerHolder<MessageStanza> received_pipeline = new StanzaListenerHolder<MessageStanza>();
|
||||||
public StanzaListenerHolder<Message.Stanza> send_pipeline = new StanzaListenerHolder<Message.Stanza>();
|
public StanzaListenerHolder<MessageStanza> send_pipeline = new StanzaListenerHolder<MessageStanza>();
|
||||||
|
|
||||||
public signal void pre_received_message(XmppStream stream, Message.Stanza message);
|
public signal void pre_received_message(XmppStream stream, MessageStanza message);
|
||||||
public signal void received_message(XmppStream stream, Message.Stanza message);
|
public signal void received_message(XmppStream stream, MessageStanza message);
|
||||||
|
|
||||||
public void send_message(XmppStream stream, Message.Stanza message) {
|
public void send_message(XmppStream stream, MessageStanza message) {
|
||||||
send_pipeline.run.begin(stream, message, (obj, res) => {
|
send_pipeline.run.begin(stream, message, (obj, res) => {
|
||||||
stream.write(message.stanza);
|
stream.write(message.stanza);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void received_message_stanza_async(XmppStream stream, StanzaNode node) {
|
public async void received_message_stanza_async(XmppStream stream, StanzaNode node) {
|
||||||
Message.Stanza message = new Message.Stanza.from_stanza(node, stream.get_flag(Bind.Flag.IDENTITY).my_jid);
|
MessageStanza message = new MessageStanza.from_stanza(node, stream.get_flag(Bind.Flag.IDENTITY).my_jid);
|
||||||
yield received_pipeline.run(stream, message);
|
yield received_pipeline.run(stream, message);
|
||||||
received_message(stream, message);
|
received_message(stream, message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
using Xmpp.Core;
|
namespace Xmpp {
|
||||||
|
|
||||||
namespace Xmpp.Message {
|
public class MessageStanza : Xmpp.Stanza {
|
||||||
|
|
||||||
public class Stanza : Xmpp.Stanza {
|
|
||||||
public const string NODE_BODY = "body";
|
public const string NODE_BODY = "body";
|
||||||
public const string NODE_SUBJECT = "subject";
|
public const string NODE_SUBJECT = "subject";
|
||||||
public const string NODE_THREAD = "thread";
|
public const string NODE_THREAD = "thread";
|
||||||
|
@ -40,12 +38,12 @@ public class Stanza : Xmpp.Stanza {
|
||||||
set { base.type_ = value; }
|
set { base.type_ = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public Stanza(string? id = null) {
|
public MessageStanza(string? id = null) {
|
||||||
base.outgoing(new StanzaNode.build("message"));
|
base.outgoing(new StanzaNode.build("message"));
|
||||||
stanza.set_attribute(ATTRIBUTE_ID, id ?? random_uuid());
|
stanza.set_attribute(ATTRIBUTE_ID, id ?? random_uuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Stanza.from_stanza(StanzaNode stanza_node, string my_jid) {
|
public MessageStanza.from_stanza(StanzaNode stanza_node, Jid my_jid) {
|
||||||
base.incoming(stanza_node, my_jid);
|
base.incoming(stanza_node, my_jid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,60 +1,60 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp.Presence {
|
namespace Xmpp.Presence {
|
||||||
|
|
||||||
public class Flag : XmppStreamFlag {
|
public class Flag : XmppStreamFlag {
|
||||||
public static FlagIdentity<Flag> IDENTITY = new FlagIdentity<Flag>(NS_URI, "presence");
|
public static FlagIdentity<Flag> IDENTITY = new FlagIdentity<Flag>(NS_URI, "presence");
|
||||||
|
|
||||||
private HashMap<string, ConcurrentList<string>> resources = new HashMap<string, ConcurrentList<string>>();
|
private HashMap<Jid, Gee.List<Jid>> resources = new HashMap<Jid, Gee.List<Jid>>(Jid.hash_bare_func, Jid.equals_bare_func);
|
||||||
private HashMap<string, Presence.Stanza> presences = new HashMap<string, Presence.Stanza>();
|
private HashMap<Jid, Presence.Stanza> presences = new HashMap<Jid, Presence.Stanza>(Jid.hash_func, Jid.equals_func);
|
||||||
|
|
||||||
public Set<string> get_available_jids() {
|
public Set<Jid> get_available_jids() {
|
||||||
return resources.keys;
|
return resources.keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Gee.List<string>? get_resources(string bare_jid) {
|
public Gee.List<Jid>? get_resources(Jid jid) {
|
||||||
return resources[bare_jid];
|
return resources[jid];
|
||||||
}
|
}
|
||||||
|
|
||||||
public Presence.Stanza? get_presence(string full_jid) {
|
public Presence.Stanza? get_presence(Jid full_jid) {
|
||||||
return presences[full_jid];
|
return presences[full_jid];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add_presence(Presence.Stanza presence) {
|
public void add_presence(Presence.Stanza presence) {
|
||||||
string bare_jid = get_bare_jid(presence.from);
|
if (!resources.has_key(presence.from)) {
|
||||||
if (!resources.has_key(bare_jid)) {
|
resources[presence.from] = new ArrayList<Jid>(Jid.equals_func);
|
||||||
resources[bare_jid] = new ConcurrentList<string>();
|
|
||||||
}
|
}
|
||||||
if (resources[bare_jid].contains(presence.from)) {
|
if (resources[presence.from].contains(presence.from)) {
|
||||||
resources[bare_jid].remove(presence.from);
|
resources[presence.from].remove(presence.from);
|
||||||
}
|
}
|
||||||
resources[bare_jid].add(presence.from);
|
resources[presence.from].add(presence.from);
|
||||||
presences[presence.from] = presence;
|
presences[presence.from] = presence;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove_presence(string jid) {
|
public void remove_presence(Jid jid) {
|
||||||
string bare_jid = get_bare_jid(jid);
|
if (resources.has_key(jid)) {
|
||||||
if (resources.has_key(bare_jid)) {
|
if (jid.is_bare()) {
|
||||||
if (is_bare_jid(jid)) {
|
foreach (Jid full_jid in resources[jid]) {
|
||||||
foreach (string full_jid in resources[jid]) {
|
|
||||||
presences.unset(full_jid);
|
presences.unset(full_jid);
|
||||||
}
|
}
|
||||||
resources.unset(jid);
|
resources.unset(jid);
|
||||||
} else {
|
} else {
|
||||||
resources[bare_jid].remove(jid);
|
resources[jid].remove(jid);
|
||||||
if (resources[bare_jid].size == 0) {
|
if (resources[jid].size == 0) {
|
||||||
resources.unset(bare_jid);
|
resources.unset(jid);
|
||||||
}
|
}
|
||||||
presences.unset(jid);
|
presences.unset(jid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string get_ns() { return NS_URI; }
|
public override string get_ns() {
|
||||||
|
return NS_URI;
|
||||||
|
}
|
||||||
|
|
||||||
public override string get_id() { return IDENTITY.id; }
|
public override string get_id() {
|
||||||
|
return IDENTITY.id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,5 +1,3 @@
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp.Presence {
|
namespace Xmpp.Presence {
|
||||||
private const string NS_URI = "jabber:client";
|
private const string NS_URI = "jabber:client";
|
||||||
|
|
||||||
|
@ -10,39 +8,39 @@ namespace Xmpp.Presence {
|
||||||
public signal void pre_send_presence_stanza(XmppStream stream, Presence.Stanza presence);
|
public signal void pre_send_presence_stanza(XmppStream stream, Presence.Stanza presence);
|
||||||
public signal void initial_presence_sent(XmppStream stream, Presence.Stanza presence);
|
public signal void initial_presence_sent(XmppStream stream, Presence.Stanza presence);
|
||||||
public signal void received_available(XmppStream stream, Presence.Stanza presence);
|
public signal void received_available(XmppStream stream, Presence.Stanza presence);
|
||||||
public signal void received_available_show(XmppStream stream, string jid, string show);
|
public signal void received_available_show(XmppStream stream, Jid jid, string show);
|
||||||
public signal void received_unavailable(XmppStream stream, Presence.Stanza presence);
|
public signal void received_unavailable(XmppStream stream, Presence.Stanza presence);
|
||||||
public signal void received_subscription_request(XmppStream stream, string jid);
|
public signal void received_subscription_request(XmppStream stream, Jid jid);
|
||||||
public signal void received_unsubscription(XmppStream stream, string jid);
|
public signal void received_unsubscription(XmppStream stream, Jid jid);
|
||||||
|
|
||||||
public bool available_resource = true;
|
public bool available_resource = true;
|
||||||
|
|
||||||
public void request_subscription(XmppStream stream, string bare_jid) {
|
public void request_subscription(XmppStream stream, Jid bare_jid) {
|
||||||
Presence.Stanza presence = new Presence.Stanza();
|
Presence.Stanza presence = new Presence.Stanza();
|
||||||
presence.to = bare_jid;
|
presence.to = bare_jid;
|
||||||
presence.type_ = Presence.Stanza.TYPE_SUBSCRIBE;
|
presence.type_ = Presence.Stanza.TYPE_SUBSCRIBE;
|
||||||
send_presence(stream, presence);
|
send_presence(stream, presence);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void approve_subscription(XmppStream stream, string bare_jid) {
|
public void approve_subscription(XmppStream stream, Jid bare_jid) {
|
||||||
Presence.Stanza presence = new Presence.Stanza();
|
Presence.Stanza presence = new Presence.Stanza();
|
||||||
presence.to = bare_jid;
|
presence.to = bare_jid;
|
||||||
presence.type_ = Presence.Stanza.TYPE_SUBSCRIBED;
|
presence.type_ = Presence.Stanza.TYPE_SUBSCRIBED;
|
||||||
send_presence(stream, presence);
|
send_presence(stream, presence);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deny_subscription(XmppStream stream, string bare_jid) {
|
public void deny_subscription(XmppStream stream, Jid bare_jid) {
|
||||||
cancel_subscription(stream, bare_jid);
|
cancel_subscription(stream, bare_jid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cancel_subscription(XmppStream stream, string bare_jid) {
|
public void cancel_subscription(XmppStream stream, Jid bare_jid) {
|
||||||
Presence.Stanza presence = new Presence.Stanza();
|
Presence.Stanza presence = new Presence.Stanza();
|
||||||
presence.to = bare_jid;
|
presence.to = bare_jid;
|
||||||
presence.type_ = Presence.Stanza.TYPE_UNSUBSCRIBED;
|
presence.type_ = Presence.Stanza.TYPE_UNSUBSCRIBED;
|
||||||
send_presence(stream, presence);
|
send_presence(stream, presence);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unsubscribe(XmppStream stream, string bare_jid) {
|
public void unsubscribe(XmppStream stream, Jid bare_jid) {
|
||||||
Presence.Stanza presence = new Presence.Stanza();
|
Presence.Stanza presence = new Presence.Stanza();
|
||||||
presence.to = bare_jid;
|
presence.to = bare_jid;
|
||||||
presence.type_ = Presence.Stanza.TYPE_UNSUBSCRIBE;
|
presence.type_ = Presence.Stanza.TYPE_UNSUBSCRIBE;
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp.Presence {
|
namespace Xmpp.Presence {
|
||||||
|
|
||||||
public class Stanza : Xmpp.Stanza {
|
public class Stanza : Xmpp.Stanza {
|
||||||
|
@ -85,7 +83,7 @@ public class Stanza : Xmpp.Stanza {
|
||||||
this.id = id ?? random_uuid();
|
this.id = id ?? random_uuid();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Stanza.from_stanza(StanzaNode stanza_node, string my_jid) {
|
public Stanza.from_stanza(StanzaNode stanza_node, Jid my_jid) {
|
||||||
base.incoming(stanza_node, my_jid);
|
base.incoming(stanza_node, my_jid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp.Roster {
|
namespace Xmpp.Roster {
|
||||||
|
|
||||||
public class Flag : XmppStreamFlag {
|
public class Flag : XmppStreamFlag {
|
||||||
public const string ID = "roster";
|
public const string ID = "roster";
|
||||||
public static FlagIdentity<Flag> IDENTITY = new FlagIdentity<Flag>(NS_URI, ID);
|
public static FlagIdentity<Flag> IDENTITY = new FlagIdentity<Flag>(NS_URI, ID);
|
||||||
|
|
||||||
public HashMap<string, Item> roster_items = new HashMap<string, Item>();
|
public HashMap<Jid, Item> roster_items = new HashMap<Jid, Item>();
|
||||||
|
|
||||||
public string? iq_id;
|
public string? iq_id;
|
||||||
|
|
||||||
|
@ -16,7 +14,7 @@ public class Flag : XmppStreamFlag {
|
||||||
return roster_items.values;
|
return roster_items.values;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Item? get_item(string jid) {
|
public Item? get_item(Jid jid) {
|
||||||
return roster_items[jid];
|
return roster_items[jid];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp.Roster {
|
namespace Xmpp.Roster {
|
||||||
|
|
||||||
public class Item {
|
public class Item {
|
||||||
|
@ -18,9 +16,10 @@ public class Item {
|
||||||
|
|
||||||
public StanzaNode stanza_node;
|
public StanzaNode stanza_node;
|
||||||
|
|
||||||
public string jid {
|
private Jid jid_;
|
||||||
get { return stanza_node.get_attribute(NODE_JID); }
|
public Jid jid {
|
||||||
set { stanza_node.set_attribute(NODE_JID, value); }
|
get { return jid_ ?? (jid_ = Jid.parse(stanza_node.get_attribute(NODE_JID))); }
|
||||||
|
set { stanza_node.set_attribute(NODE_JID, value.to_string()); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public string? name {
|
public string? name {
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp.Roster {
|
namespace Xmpp.Roster {
|
||||||
|
|
||||||
private const string NS_URI = "jabber:iq:roster";
|
private const string NS_URI = "jabber:iq:roster";
|
||||||
|
@ -16,7 +14,7 @@ public class Module : XmppStreamModule, Iq.Handler {
|
||||||
|
|
||||||
public bool interested_resource = true;
|
public bool interested_resource = true;
|
||||||
|
|
||||||
public void add_jid(XmppStream stream, string jid, string? handle = null) {
|
public void add_jid(XmppStream stream, Jid jid, string? handle = null) {
|
||||||
Item roster_item = new Item();
|
Item roster_item = new Item();
|
||||||
roster_item.jid = jid;
|
roster_item.jid = jid;
|
||||||
if (handle != null) {
|
if (handle != null) {
|
||||||
|
@ -25,7 +23,7 @@ public class Module : XmppStreamModule, Iq.Handler {
|
||||||
roster_set(stream, roster_item);
|
roster_set(stream, roster_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove_jid(XmppStream stream, string jid) {
|
public void remove_jid(XmppStream stream, Jid jid) {
|
||||||
Item roster_item = new Item();
|
Item roster_item = new Item();
|
||||||
roster_item.jid = jid;
|
roster_item.jid = jid;
|
||||||
roster_item.subscription = Item.SUBSCRIPTION_REMOVE;
|
roster_item.subscription = Item.SUBSCRIPTION_REMOVE;
|
||||||
|
@ -37,7 +35,7 @@ public class Module : XmppStreamModule, Iq.Handler {
|
||||||
* Set a handle for a jid
|
* Set a handle for a jid
|
||||||
* @param handle Handle to be set. If null, any handle will be removed.
|
* @param handle Handle to be set. If null, any handle will be removed.
|
||||||
*/
|
*/
|
||||||
public void set_jid_handle(XmppStream stream, string jid, string? handle) {
|
public void set_jid_handle(XmppStream stream, Jid jid, string? handle) {
|
||||||
Flag flag = stream.get_flag(Flag.IDENTITY);
|
Flag flag = stream.get_flag(Flag.IDENTITY);
|
||||||
Item item = flag.get_item(jid) ?? new Item() { jid=jid };
|
Item item = flag.get_item(jid) ?? new Item() { jid=jid };
|
||||||
item.name = handle != null ? handle : "";
|
item.name = handle != null ? handle : "";
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp.Roster {
|
namespace Xmpp.Roster {
|
||||||
|
|
||||||
public class VersioningModule : XmppStreamModule {
|
public class VersioningModule : XmppStreamModule {
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp.PlainSasl {
|
namespace Xmpp.PlainSasl {
|
||||||
private const string NS_URI = "urn:ietf:params:xml:ns:xmpp-sasl";
|
private const string NS_URI = "urn:ietf:params:xml:ns:xmpp-sasl";
|
||||||
|
|
||||||
|
@ -56,16 +54,16 @@ namespace Xmpp.PlainSasl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!supportsPlain) {
|
if (!supportsPlain) {
|
||||||
stderr.printf("Server at %s does not support %s auth, use full-features Sasl implementation!\n", stream.remote_name, MECHANISM);
|
stderr.printf("Server at %s does not support %s auth, use full-features Sasl implementation!\n", stream.remote_name.to_string(), MECHANISM);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!name.contains("@")) {
|
if (!name.contains("@")) {
|
||||||
name = "%s@%s".printf(name, stream.remote_name);
|
name = "%s@%s".printf(name, stream.remote_name.to_string());
|
||||||
}
|
}
|
||||||
if (!use_full_name && name.contains("@")) {
|
if (!use_full_name && name.contains("@")) {
|
||||||
var split = name.split("@");
|
var split = name.split("@");
|
||||||
if (split[1] == stream.remote_name) {
|
if (split[1] == stream.remote_name.to_string()) {
|
||||||
name = split[0];
|
name = split[0];
|
||||||
} else {
|
} else {
|
||||||
use_full_name = true;
|
use_full_name = true;
|
||||||
|
@ -74,7 +72,7 @@ namespace Xmpp.PlainSasl {
|
||||||
var name = this.name;
|
var name = this.name;
|
||||||
if (!use_full_name && name.contains("@")) {
|
if (!use_full_name && name.contains("@")) {
|
||||||
var split = name.split("@");
|
var split = name.split("@");
|
||||||
if (split[1] == stream.remote_name) {
|
if (split[1] == stream.remote_name.to_string()) {
|
||||||
name = split[0];
|
name = split[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
/* Legacy. RFC 3921 3*/
|
/* Legacy. RFC 3921 3*/
|
||||||
namespace Xmpp.Session {
|
namespace Xmpp.Session {
|
||||||
private const string NS_URI = "urn:ietf:params:xml:ns:xmpp-session";
|
private const string NS_URI = "urn:ietf:params:xml:ns:xmpp-session";
|
||||||
|
@ -24,7 +22,7 @@ public class Module : XmppStreamNegotiationModule {
|
||||||
public override string get_ns() { return NS_URI; }
|
public override string get_ns() { return NS_URI; }
|
||||||
public override string get_id() { return IDENTITY.id; }
|
public override string get_id() { return IDENTITY.id; }
|
||||||
|
|
||||||
private void on_bound_resource(XmppStream stream, string my_jid) {
|
private void on_bound_resource(XmppStream stream, Jid my_jid) {
|
||||||
StanzaNode? session_node = stream.features.get_subnode("session", NS_URI);
|
StanzaNode? session_node = stream.features.get_subnode("session", NS_URI);
|
||||||
if (session_node != null && session_node.get_subnode("optional", NS_URI) == null) {
|
if (session_node != null && session_node.get_subnode("optional", NS_URI) == null) {
|
||||||
stream.add_flag(new Flag());
|
stream.add_flag(new Flag());
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp {
|
namespace Xmpp {
|
||||||
|
|
||||||
public class Stanza : Object {
|
public class Stanza : Object {
|
||||||
|
|
||||||
public const string ATTRIBUTE_FROM = "from";
|
public const string ATTRIBUTE_FROM = "from";
|
||||||
public const string ATTRIBUTE_ID = "id";
|
public const string ATTRIBUTE_ID = "id";
|
||||||
|
@ -11,21 +9,22 @@ namespace Xmpp {
|
||||||
|
|
||||||
public const string TYPE_ERROR = "error";
|
public const string TYPE_ERROR = "error";
|
||||||
|
|
||||||
private string? my_jid;
|
private Jid? my_jid;
|
||||||
|
private Jid? from_;
|
||||||
|
private Jid? to_;
|
||||||
|
|
||||||
public virtual string? from {
|
public virtual Jid? from {
|
||||||
owned get {
|
owned get {
|
||||||
string? from_attribute = stanza.get_attribute(ATTRIBUTE_FROM);
|
string? from_attribute = stanza.get_attribute(ATTRIBUTE_FROM);
|
||||||
// "when a client receives a stanza that does not include a 'from' attribute, it MUST assume that the stanza
|
// "when a client receives a stanza that does not include a 'from' attribute, it MUST assume that the stanza
|
||||||
// is from the user's account on the server." (RFC6120 8.1.2.1)
|
// is from the user's account on the server." (RFC6120 8.1.2.1)
|
||||||
if (from_attribute != null) return from_attribute;
|
if (from_attribute != null) return from_ = Jid.parse(from_attribute);
|
||||||
if (my_jid != null) {
|
if (my_jid != null) {
|
||||||
string my_bare_jid = get_bare_jid(my_jid); // has to be left-side value
|
return my_jid.bare_jid;
|
||||||
return my_bare_jid;
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
set { stanza.set_attribute(ATTRIBUTE_FROM, value); }
|
set { stanza.set_attribute(ATTRIBUTE_FROM, value.to_string()); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual string? id {
|
public virtual string? id {
|
||||||
|
@ -33,14 +32,14 @@ namespace Xmpp {
|
||||||
set { stanza.set_attribute(ATTRIBUTE_ID, value); }
|
set { stanza.set_attribute(ATTRIBUTE_ID, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual string? to {
|
public virtual Jid? to {
|
||||||
owned get {
|
owned get {
|
||||||
string? to_attribute = stanza.get_attribute(ATTRIBUTE_TO);
|
string? to_attribute = stanza.get_attribute(ATTRIBUTE_TO);
|
||||||
// "if the stanza does not include a 'to' address then the client MUST treat it as if the 'to' address were
|
// "if the stanza does not include a 'to' address then the client MUST treat it as if the 'to' address were
|
||||||
// included with a value of the client's full JID." (RFC6120 8.1.1.1)
|
// included with a value of the client's full JID." (RFC6120 8.1.1.1)
|
||||||
return to_attribute == null ? my_jid : to_attribute;
|
return to_attribute == null ? my_jid : to_ = Jid.parse(to_attribute);
|
||||||
}
|
}
|
||||||
set { stanza.set_attribute(ATTRIBUTE_TO, value); }
|
set { stanza.set_attribute(ATTRIBUTE_TO, value.to_string()); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual string? type_ {
|
public virtual string? type_ {
|
||||||
|
@ -50,7 +49,7 @@ namespace Xmpp {
|
||||||
|
|
||||||
public StanzaNode stanza;
|
public StanzaNode stanza;
|
||||||
|
|
||||||
public Stanza.incoming(StanzaNode stanza, string? my_jid) {
|
public Stanza.incoming(StanzaNode stanza, Jid? my_jid) {
|
||||||
this.stanza = stanza;
|
this.stanza = stanza;
|
||||||
this.my_jid = my_jid;
|
this.my_jid = my_jid;
|
||||||
}
|
}
|
||||||
|
@ -66,5 +65,6 @@ namespace Xmpp {
|
||||||
public ErrorStanza? get_error() {
|
public ErrorStanza? get_error() {
|
||||||
return new ErrorStanza.from_stanza(this.stanza);
|
return new ErrorStanza.from_stanza(this.stanza);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,7 +1,5 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp {
|
namespace Xmpp {
|
||||||
|
|
||||||
public class ErrorStanza {
|
public class ErrorStanza {
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp.StreamError {
|
namespace Xmpp.StreamError {
|
||||||
private const string NS_URI = "jabber:client";
|
private const string NS_URI = "jabber:client";
|
||||||
private const string NS_ERROR = "urn:ietf:params:xml:ns:xmpp-streams";
|
private const string NS_ERROR = "urn:ietf:params:xml:ns:xmpp-streams";
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp.Tls {
|
namespace Xmpp.Tls {
|
||||||
private const string NS_URI = "urn:ietf:params:xml:ns:xmpp-tls";
|
private const string NS_URI = "urn:ietf:params:xml:ns:xmpp-tls";
|
||||||
|
|
||||||
|
@ -52,7 +50,7 @@ namespace Xmpp.Tls {
|
||||||
stream.write(new StanzaNode.build("starttls", NS_URI).add_self_xmlns());
|
stream.write(new StanzaNode.build("starttls", NS_URI).add_self_xmlns());
|
||||||
}
|
}
|
||||||
if (identity == null) {
|
if (identity == null) {
|
||||||
identity = new NetworkService("xmpp-client", "tcp", stream.remote_name);
|
identity = new NetworkService("xmpp-client", "tcp", stream.remote_name.to_string());
|
||||||
}
|
}
|
||||||
stream.add_flag(new Flag());
|
stream.add_flag(new Flag());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,8 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
namespace Xmpp {
|
namespace Xmpp {
|
||||||
public string get_bare_jid(string jid) {
|
|
||||||
return jid.split("/")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool is_bare_jid(string jid) {
|
public string random_uuid() {
|
||||||
return !jid.contains("/");
|
|
||||||
}
|
|
||||||
|
|
||||||
public string? get_resource_part(string jid) {
|
|
||||||
return jid.split("/")[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
public string random_uuid() {
|
|
||||||
uint32 b1 = Random.next_int();
|
uint32 b1 = Random.next_int();
|
||||||
uint16 b2 = (uint16)Random.next_int();
|
uint16 b2 = (uint16)Random.next_int();
|
||||||
uint16 b3 = (uint16)(Random.next_int() | 0x4000u) & ~0xb000u;
|
uint16 b3 = (uint16)(Random.next_int() | 0x4000u) & ~0xb000u;
|
||||||
|
@ -21,12 +10,13 @@ namespace Xmpp {
|
||||||
uint16 b5_1 = (uint16)Random.next_int();
|
uint16 b5_1 = (uint16)Random.next_int();
|
||||||
uint32 b5_2 = Random.next_int();
|
uint32 b5_2 = Random.next_int();
|
||||||
return "%08x-%04x-%04x-%04x-%04x%08x".printf(b1, b2, b3, b4, b5_1, b5_2);
|
return "%08x-%04x-%04x-%04x-%04x%08x".printf(b1, b2, b3, b4, b5_1, b5_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class StanzaListener<T> : Object {
|
public abstract class StanzaListener<T> : Object {
|
||||||
public abstract string action_group { get; }
|
public abstract string action_group { get; }
|
||||||
public abstract string[] after_actions { get; }
|
public abstract string[] after_actions { get; }
|
||||||
public abstract async void run(Core.XmppStream stream, T stanza);
|
|
||||||
|
public abstract async void run(XmppStream stream, T stanza);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class StanzaListenerHolder<T> : Object {
|
public class StanzaListenerHolder<T> : Object {
|
||||||
|
@ -42,14 +32,14 @@ public class StanzaListenerHolder<T> : Object {
|
||||||
resort_list();
|
resort_list();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void run(Core.XmppStream stream, T stanza) {
|
public async void run(XmppStream stream, T stanza) {
|
||||||
foreach (StanzaListener<T> l in listeners) {
|
foreach (StanzaListener<T> l in listeners) {
|
||||||
yield l.run(stream, stanza);
|
yield l.run(stream, stanza);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool set_contains_action(Gee.List<StanzaListener<T>> s, string[] actions) {
|
private bool set_contains_action(Gee.List<StanzaListener<T>> s, string[] actions) {
|
||||||
foreach(StanzaListener<T> l in s) {
|
foreach (StanzaListener<T> l in s) {
|
||||||
if (l.action_group in actions) {
|
if (l.action_group in actions) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp.Xep.DataForms {
|
namespace Xmpp.Xep.DataForms {
|
||||||
|
|
||||||
public const string NS_URI = "jabber:x:data";
|
public const string NS_URI = "jabber:x:data";
|
||||||
|
|
|
@ -1,22 +1,20 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp.Xep.ServiceDiscovery {
|
namespace Xmpp.Xep.ServiceDiscovery {
|
||||||
|
|
||||||
public class Flag : XmppStreamFlag {
|
public class Flag : XmppStreamFlag {
|
||||||
public static FlagIdentity<Flag> IDENTITY = new FlagIdentity<Flag>(NS_URI, "service_discovery");
|
public static FlagIdentity<Flag> IDENTITY = new FlagIdentity<Flag>(NS_URI, "service_discovery");
|
||||||
|
|
||||||
private HashMap<string, Gee.List<string>?> entity_features = new HashMap<string, Gee.List<string>?>();
|
private HashMap<Jid, Gee.List<string>?> entity_features = new HashMap<Jid, Gee.List<string>?>(Jid.hash_func, Jid.equals_func);
|
||||||
private HashMap<string, Gee.List<Identity>?> entity_identities = new HashMap<string, Gee.List<Identity>?>();
|
private HashMap<Jid, Gee.List<Identity>?> entity_identities = new HashMap<Jid, Gee.List<Identity>?>(Jid.hash_func, Jid.equals_func);
|
||||||
private HashMap<string, Gee.List<Item>?> entity_items = new HashMap<string, Gee.List<Item>?>();
|
private HashMap<Jid, Gee.List<Item>?> entity_items = new HashMap<Jid, Gee.List<Item>?>(Jid.hash_func, Jid.equals_func);
|
||||||
public Gee.List<string> features = new ArrayList<string>();
|
public Gee.List<string> features = new ArrayList<string>();
|
||||||
|
|
||||||
public Gee.List<Identity>? get_entity_categories(string jid) {
|
public Gee.List<Identity>? get_entity_categories(Jid jid) {
|
||||||
return entity_identities.has_key(jid) ? entity_identities[jid] : null; // TODO isn’t this default for hashmap
|
return entity_identities.has_key(jid) ? entity_identities[jid] : null; // TODO isn’t this default for hashmap
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool? has_entity_identity(string jid, string category, string type) {
|
public bool? has_entity_identity(Jid jid, string category, string type) {
|
||||||
if (!entity_identities.has_key(jid)) return null;
|
if (!entity_identities.has_key(jid)) return null;
|
||||||
if (entity_identities[jid] == null) return false;
|
if (entity_identities[jid] == null) return false;
|
||||||
foreach (Identity identity in entity_identities[jid]) {
|
foreach (Identity identity in entity_identities[jid]) {
|
||||||
|
@ -25,21 +23,21 @@ public class Flag : XmppStreamFlag {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool? has_entity_feature(string jid, string feature) {
|
public bool? has_entity_feature(Jid jid, string feature) {
|
||||||
if (!entity_features.has_key(jid)) return null;
|
if (!entity_features.has_key(jid)) return null;
|
||||||
if (entity_features[jid] == null) return false;
|
if (entity_features[jid] == null) return false;
|
||||||
return entity_features[jid].contains(feature);
|
return entity_features[jid].contains(feature);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set_entity_identities(string jid, Gee.List<Identity>? identities) {
|
public void set_entity_identities(Jid jid, Gee.List<Identity>? identities) {
|
||||||
entity_identities[jid] = identities;
|
entity_identities[jid] = identities;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set_entity_features(string jid, Gee.List<string>? features) {
|
public void set_entity_features(Jid jid, Gee.List<string>? features) {
|
||||||
entity_features[jid] = features;
|
entity_features[jid] = features;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set_entity_items(string jid, Gee.List<Item>? features) {
|
public void set_entity_items(Jid jid, Gee.List<Item>? features) {
|
||||||
entity_items[jid] = features;
|
entity_items[jid] = features;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp.Xep.ServiceDiscovery {
|
namespace Xmpp.Xep.ServiceDiscovery {
|
||||||
|
|
||||||
public class InfoResult {
|
public class InfoResult {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
namespace Xmpp.Xep.ServiceDiscovery {
|
namespace Xmpp.Xep.ServiceDiscovery {
|
||||||
|
|
||||||
public class Item {
|
public class Item {
|
||||||
public string jid;
|
public Jid jid;
|
||||||
public string? name;
|
public string? name;
|
||||||
public string? node;
|
public string? node;
|
||||||
|
|
||||||
public Item(string jid, string? name = null, string? node = null) {
|
public Item(Jid jid, string? name = null, string? node = null) {
|
||||||
this.jid = jid;
|
this.jid = jid;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.node = node;
|
this.node = node;
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp.Xep.ServiceDiscovery {
|
namespace Xmpp.Xep.ServiceDiscovery {
|
||||||
|
|
||||||
public class ItemsResult {
|
public class ItemsResult {
|
||||||
|
@ -11,7 +9,7 @@ public class ItemsResult {
|
||||||
owned get {
|
owned get {
|
||||||
ArrayList<Item> ret = new ArrayList<Item>();
|
ArrayList<Item> ret = new ArrayList<Item>();
|
||||||
foreach (StanzaNode feature_node in iq.stanza.get_subnode("query", NS_URI_ITEMS).get_subnodes("item", NS_URI_ITEMS)) {
|
foreach (StanzaNode feature_node in iq.stanza.get_subnode("query", NS_URI_ITEMS).get_subnodes("item", NS_URI_ITEMS)) {
|
||||||
ret.add(new Item(feature_node.get_attribute("jid", NS_URI_ITEMS),
|
ret.add(new Item(Jid.parse(feature_node.get_attribute("jid", NS_URI_ITEMS)),
|
||||||
feature_node.get_attribute("name", NS_URI_ITEMS),
|
feature_node.get_attribute("name", NS_URI_ITEMS),
|
||||||
feature_node.get_attribute("node", NS_URI_ITEMS)));
|
feature_node.get_attribute("node", NS_URI_ITEMS)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp.Xep.ServiceDiscovery {
|
namespace Xmpp.Xep.ServiceDiscovery {
|
||||||
|
|
||||||
private const string NS_URI = "http://jabber.org/protocol/disco";
|
private const string NS_URI = "http://jabber.org/protocol/disco";
|
||||||
|
@ -30,7 +28,7 @@ public class Module : XmppStreamModule, Iq.Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
public delegate void HasEntryCategoryRes(XmppStream stream, Gee.List<Identity>? identities);
|
public delegate void HasEntryCategoryRes(XmppStream stream, Gee.List<Identity>? identities);
|
||||||
public void get_entity_categories(XmppStream stream, string jid, owned HasEntryCategoryRes listener) {
|
public void get_entity_categories(XmppStream stream, Jid jid, owned HasEntryCategoryRes listener) {
|
||||||
Gee.List<Identity>? res = stream.get_flag(Flag.IDENTITY).get_entity_categories(jid);
|
Gee.List<Identity>? res = stream.get_flag(Flag.IDENTITY).get_entity_categories(jid);
|
||||||
if (res != null) listener(stream, res);
|
if (res != null) listener(stream, res);
|
||||||
request_info(stream, jid, (stream, query_result) => {
|
request_info(stream, jid, (stream, query_result) => {
|
||||||
|
@ -39,7 +37,7 @@ public class Module : XmppStreamModule, Iq.Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
public delegate void OnInfoResult(XmppStream stream, InfoResult? query_result);
|
public delegate void OnInfoResult(XmppStream stream, InfoResult? query_result);
|
||||||
public void request_info(XmppStream stream, string jid, owned OnInfoResult listener) {
|
public void request_info(XmppStream stream, Jid jid, owned OnInfoResult listener) {
|
||||||
Iq.Stanza iq = new Iq.Stanza.get(new StanzaNode.build("query", NS_URI_INFO).add_self_xmlns());
|
Iq.Stanza iq = new Iq.Stanza.get(new StanzaNode.build("query", NS_URI_INFO).add_self_xmlns());
|
||||||
iq.to = jid;
|
iq.to = jid;
|
||||||
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, (stream, iq) => {
|
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, (stream, iq) => {
|
||||||
|
@ -51,7 +49,7 @@ public class Module : XmppStreamModule, Iq.Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
public delegate void OnItemsResult(XmppStream stream, ItemsResult query_result);
|
public delegate void OnItemsResult(XmppStream stream, ItemsResult query_result);
|
||||||
public void request_items(XmppStream stream, string jid, owned OnItemsResult listener) {
|
public void request_items(XmppStream stream, Jid jid, owned OnItemsResult listener) {
|
||||||
Iq.Stanza iq = new Iq.Stanza.get(new StanzaNode.build("query", NS_URI_ITEMS).add_self_xmlns());
|
Iq.Stanza iq = new Iq.Stanza.get(new StanzaNode.build("query", NS_URI_ITEMS).add_self_xmlns());
|
||||||
iq.to = jid;
|
iq.to = jid;
|
||||||
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, (stream, iq) => {
|
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, (stream, iq) => {
|
||||||
|
|
|
@ -1,128 +1,123 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp.Xep.Muc {
|
namespace Xmpp.Xep.Muc {
|
||||||
|
|
||||||
public class Flag : XmppStreamFlag {
|
public class Flag : XmppStreamFlag {
|
||||||
public static FlagIdentity<Flag> IDENTITY = new FlagIdentity<Flag>(NS_URI, "muc");
|
public static FlagIdentity<Flag> IDENTITY = new FlagIdentity<Flag>(NS_URI, "muc");
|
||||||
|
|
||||||
private HashMap<string, Gee.List<Feature>> room_features = new HashMap<string, Gee.List<Feature>>();
|
private HashMap<Jid, Gee.List<Feature>> room_features = new HashMap<Jid, Gee.List<Feature>>(Jid.hash_bare_func, Jid.equals_bare_func);
|
||||||
private HashMap<string, string> room_names = new HashMap<string, string>();
|
private HashMap<Jid, string> room_names = new HashMap<Jid, string>(Jid.hash_bare_func, Jid.equals_bare_func);
|
||||||
|
|
||||||
private HashMap<string, string> enter_ids = new HashMap<string, string>();
|
private HashMap<Jid, string> enter_ids = new HashMap<Jid, string>(Jid.hash_bare_func, Jid.equals_bare_func);
|
||||||
private HashMap<string, string> own_nicks = new HashMap<string, string>();
|
private HashMap<Jid, string> own_nicks = new HashMap<Jid, string>(Jid.hash_bare_func, Jid.equals_bare_func);
|
||||||
private HashMap<string, string> subjects = new HashMap<string, string>();
|
private HashMap<Jid, string> subjects = new HashMap<Jid, string>(Jid.hash_bare_func, Jid.equals_bare_func);
|
||||||
private HashMap<string, string> subjects_by = new HashMap<string, string>();
|
private HashMap<Jid, Jid> subjects_by = new HashMap<Jid, Jid>(Jid.hash_bare_func, Jid.equals_bare_func);
|
||||||
|
|
||||||
private HashMap<string, string> occupant_real_jids = new HashMap<string, string>();
|
private HashMap<Jid, Jid> occupant_real_jids = new HashMap<Jid, Jid>(Jid.hash_func, Jid.equals_bare_func);
|
||||||
private HashMap<string, HashMap<string, Affiliation>> affiliations = new HashMap<string, HashMap<string, Affiliation>>();
|
private HashMap<Jid, HashMap<Jid, Affiliation>> affiliations = new HashMap<Jid, HashMap<Jid, Affiliation>>(Jid.hash_bare_func, Jid.equals_bare_func);
|
||||||
private HashMap<string, Role> occupant_role = new HashMap<string, Role>();
|
private HashMap<Jid, Role> occupant_role = new HashMap<Jid, Role>(Jid.hash_func, Jid.equals_func);
|
||||||
|
|
||||||
public string? get_room_name(string jid) { return room_names.has_key(jid) ? room_names[jid] : null; }
|
public string? get_room_name(Jid muc_jid) { return room_names.has_key(muc_jid.bare_jid) ? room_names[muc_jid.bare_jid] : null; }
|
||||||
|
|
||||||
public bool has_room_feature(string jid, Feature feature) {
|
public bool has_room_feature(Jid muc_jid, Feature feature) {
|
||||||
return room_features.has_key(jid) && room_features[jid].contains(feature);
|
return room_features.has_key(muc_jid.bare_jid) && room_features[muc_jid.bare_jid].contains(feature);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string? get_real_jid(string full_jid) { return occupant_real_jids[full_jid]; }
|
public Jid? get_real_jid(Jid full_jid) { return occupant_real_jids[full_jid]; }
|
||||||
|
|
||||||
public Gee.List<string> get_offline_members(string muc_jid) {
|
public Gee.List<Jid> get_offline_members(Jid muc_jid) {
|
||||||
Gee.List<string> ret = new ArrayList<string>();
|
Gee.List<Jid> ret = new ArrayList<Jid>(Jid.equals_func);
|
||||||
HashMap<string, Affiliation>? muc_affiliations = affiliations[muc_jid];
|
HashMap<Jid, Affiliation>? muc_affiliations = affiliations[muc_jid.bare_jid];
|
||||||
if (muc_affiliations != null) {
|
if (muc_affiliations != null) {
|
||||||
foreach (string jid in muc_affiliations.keys) {
|
foreach (Jid jid in muc_affiliations.keys) {
|
||||||
if (!jid.has_prefix(muc_jid)) ret.add(jid);
|
if (!jid.equals_bare(muc_jid)) ret.add(jid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Affiliation get_affiliation(string muc_jid, string full_jid) {
|
public Affiliation get_affiliation(Jid muc_jid, Jid full_jid) {
|
||||||
HashMap<string, Affiliation>? muc_affiliations = affiliations[muc_jid];
|
HashMap<Jid, Affiliation>? muc_affiliations = affiliations[muc_jid.bare_jid];
|
||||||
if (muc_affiliations != null) return muc_affiliations[full_jid];
|
if (muc_affiliations != null) return muc_affiliations[full_jid];
|
||||||
return Affiliation.NONE;
|
return Affiliation.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Role? get_occupant_role(string full_jid) {
|
public Role? get_occupant_role(Jid full_jid) {
|
||||||
if (occupant_role.has_key(full_jid)) return occupant_role[full_jid];
|
if (occupant_role.has_key(full_jid)) return occupant_role[full_jid];
|
||||||
return Role.NONE;
|
return Role.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string? get_muc_nick(string bare_jid) { return own_nicks[bare_jid]; }
|
public string? get_muc_nick(Jid muc_jid) { return own_nicks[muc_jid.bare_jid]; }
|
||||||
|
|
||||||
public string? get_enter_id(string bare_jid) { return enter_ids[bare_jid]; }
|
public string? get_enter_id(Jid muc_jid) { return enter_ids[muc_jid.bare_jid]; }
|
||||||
|
|
||||||
public bool is_muc(string jid) { return own_nicks[jid] != null; }
|
public bool is_muc(Jid jid) { return own_nicks[jid] != null; }
|
||||||
|
|
||||||
public bool is_occupant(string jid) {
|
public bool is_occupant(Jid jid) {
|
||||||
string bare_jid = get_bare_jid(jid);
|
return own_nicks.has_key(jid.bare_jid) || enter_ids.has_key(jid.bare_jid);
|
||||||
return own_nicks.has_key(bare_jid) || enter_ids.has_key(bare_jid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool is_muc_enter_outstanding() { return enter_ids.size != 0; }
|
public bool is_muc_enter_outstanding() { return enter_ids.size != 0; }
|
||||||
|
|
||||||
public string? get_muc_subject(string bare_jid) { return subjects[bare_jid]; }
|
public string? get_muc_subject(Jid muc_jid) { return subjects[muc_jid.bare_jid]; }
|
||||||
|
|
||||||
internal void set_room_name(string jid, string name) {
|
internal void set_room_name(Jid muc_jid, string name) {
|
||||||
room_names[jid] = name;
|
room_names[muc_jid.bare_jid] = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void set_room_features(string jid, Gee.List<Feature> features) {
|
internal void set_room_features(Jid muc_jid, Gee.List<Feature> features) {
|
||||||
room_features[jid] = features;
|
room_features[muc_jid.bare_jid] = features;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void set_real_jid(string full_jid, string real_jid) { occupant_real_jids[full_jid] = real_jid; }
|
internal void set_real_jid(Jid full_jid, Jid real_jid) { occupant_real_jids[full_jid] = real_jid; }
|
||||||
|
|
||||||
internal void set_offline_member(string muc_jid, string real_jid, Affiliation affiliation) {
|
internal void set_offline_member(Jid muc_jid, Jid real_jid, Affiliation affiliation) {
|
||||||
set_affiliation(muc_jid, real_jid, affiliation);
|
set_affiliation(muc_jid.bare_jid, real_jid, affiliation);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void set_affiliation(string muc_jid, string full_jid, Affiliation affiliation) {
|
internal void set_affiliation(Jid muc_jid, Jid full_jid, Affiliation affiliation) {
|
||||||
if (!affiliations.has_key(muc_jid)) affiliations[muc_jid] = new HashMap<string, Affiliation>();
|
if (!affiliations.has_key(muc_jid.bare_jid)) affiliations[muc_jid.bare_jid] = new HashMap<Jid, Affiliation>(Jid.hash_func, Jid.equals_func);
|
||||||
if (affiliation == Affiliation.NONE) {
|
if (affiliation == Affiliation.NONE) {
|
||||||
affiliations[muc_jid].unset(full_jid);
|
affiliations[muc_jid.bare_jid].unset(full_jid);
|
||||||
} else {
|
} else {
|
||||||
affiliations[muc_jid][full_jid] = affiliation;
|
affiliations[muc_jid.bare_jid][full_jid] = affiliation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void set_occupant_role(string full_jid, Role role) {
|
internal void set_occupant_role(Jid full_jid, Role role) {
|
||||||
occupant_role[full_jid] = role;
|
occupant_role[full_jid] = role;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void set_muc_subject(string full_jid, string? subject) {
|
internal void set_muc_subject(Jid full_jid, string? subject) {
|
||||||
string bare_jid = get_bare_jid(full_jid);
|
subjects[full_jid.bare_jid] = subject;
|
||||||
subjects[bare_jid] = subject;
|
subjects_by[full_jid.bare_jid] = full_jid;
|
||||||
subjects_by[bare_jid] = full_jid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void start_muc_enter(string bare_jid, string presence_id) {
|
internal void start_muc_enter(Jid jid, string presence_id) {
|
||||||
enter_ids[bare_jid] = presence_id;
|
enter_ids[jid.bare_jid] = presence_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void finish_muc_enter(string bare_jid, string? nick = null) {
|
internal void finish_muc_enter(Jid jid, string? nick = null) {
|
||||||
if (nick != null) own_nicks[bare_jid] = nick;
|
if (nick != null) own_nicks[jid.bare_jid] = nick;
|
||||||
enter_ids.unset(bare_jid);
|
enter_ids.unset(jid.bare_jid);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void left_muc(XmppStream stream, string muc) {
|
internal void left_muc(XmppStream stream, Jid muc_jid) {
|
||||||
own_nicks.unset(muc);
|
own_nicks.unset(muc_jid);
|
||||||
subjects.unset(muc);
|
subjects.unset(muc_jid);
|
||||||
subjects_by.unset(muc);
|
subjects_by.unset(muc_jid);
|
||||||
Gee.List<string>? occupants = stream.get_flag(Presence.Flag.IDENTITY).get_resources(muc);
|
Gee.List<Jid>? occupants = stream.get_flag(Presence.Flag.IDENTITY).get_resources(muc_jid);
|
||||||
if (occupants != null) {
|
if (occupants != null) {
|
||||||
foreach (string occupant in occupants) {
|
foreach (Jid occupant in occupants) {
|
||||||
remove_occupant_info(occupant);
|
remove_occupant_info(occupant);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void remove_occupant_info(string full_jid) {
|
internal void remove_occupant_info(Jid jid) {
|
||||||
occupant_real_jids.unset(full_jid);
|
occupant_real_jids.unset(jid);
|
||||||
string bare_jid = get_bare_jid(full_jid);
|
if (affiliations.has_key(jid)) affiliations[jid].unset(jid);
|
||||||
if (affiliations.has_key(full_jid)) affiliations[bare_jid].unset(full_jid);
|
occupant_role.unset(jid);
|
||||||
occupant_role.unset(full_jid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal override string get_ns() { return NS_URI; }
|
internal override string get_ns() { return NS_URI; }
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp.Xep.Muc {
|
namespace Xmpp.Xep.Muc {
|
||||||
|
|
||||||
private const string NS_URI = "http://jabber.org/protocol/muc";
|
private const string NS_URI = "http://jabber.org/protocol/muc";
|
||||||
|
@ -58,20 +56,20 @@ public enum Feature {
|
||||||
public class Module : XmppStreamModule {
|
public class Module : XmppStreamModule {
|
||||||
public static ModuleIdentity<Module> IDENTITY = new ModuleIdentity<Module>(NS_URI, "0045_muc_module");
|
public static ModuleIdentity<Module> IDENTITY = new ModuleIdentity<Module>(NS_URI, "0045_muc_module");
|
||||||
|
|
||||||
public signal void received_occupant_affiliation(XmppStream stream, string jid, Affiliation? affiliation);
|
public signal void received_occupant_affiliation(XmppStream stream, Jid jid, Affiliation? affiliation);
|
||||||
public signal void received_occupant_jid(XmppStream stream, string jid, string? real_jid);
|
public signal void received_occupant_jid(XmppStream stream, Jid jid, Jid? real_jid);
|
||||||
public signal void received_occupant_role(XmppStream stream, string jid, Role? role);
|
public signal void received_occupant_role(XmppStream stream, Jid jid, Role? role);
|
||||||
public signal void subject_set(XmppStream stream, string subject, string jid);
|
public signal void subject_set(XmppStream stream, string? subject, Jid jid);
|
||||||
public signal void room_configuration_changed(XmppStream stream, string jid, StatusCode code);
|
public signal void room_configuration_changed(XmppStream stream, Jid jid, StatusCode code);
|
||||||
|
|
||||||
public signal void room_entered(XmppStream stream, string jid, string nick);
|
public signal void room_entered(XmppStream stream, Jid jid, string nick);
|
||||||
public signal void room_enter_error(XmppStream stream, string jid, MucEnterError? error); // TODO "?" shoudln't be necessary (vala bug), remove someday
|
public signal void room_enter_error(XmppStream stream, Jid jid, MucEnterError? error); // TODO "?" shoudln't be necessary (vala bug), remove someday
|
||||||
public signal void self_removed_from_room(XmppStream stream, string jid, StatusCode code);
|
public signal void self_removed_from_room(XmppStream stream, Jid jid, StatusCode code);
|
||||||
public signal void removed_from_room(XmppStream stream, string jid, StatusCode? code);
|
public signal void removed_from_room(XmppStream stream, Jid jid, StatusCode? code);
|
||||||
|
|
||||||
public void enter(XmppStream stream, string bare_jid, string nick, string? password, DateTime? history_since) {
|
public void enter(XmppStream stream, Jid bare_jid, string nick, string? password, DateTime? history_since) {
|
||||||
Presence.Stanza presence = new Presence.Stanza();
|
Presence.Stanza presence = new Presence.Stanza();
|
||||||
presence.to = bare_jid + "/" + nick;
|
presence.to = bare_jid.with_resource(nick);
|
||||||
StanzaNode x_node = new StanzaNode.build("x", NS_URI).add_self_xmlns();
|
StanzaNode x_node = new StanzaNode.build("x", NS_URI).add_self_xmlns();
|
||||||
if (password != null) {
|
if (password != null) {
|
||||||
x_node.put_node(new StanzaNode.build("password", NS_URI).put_node(new StanzaNode.text(password)));
|
x_node.put_node(new StanzaNode.build("password", NS_URI).put_node(new StanzaNode.text(password)));
|
||||||
|
@ -89,47 +87,47 @@ public class Module : XmppStreamModule {
|
||||||
stream.get_module(Presence.Module.IDENTITY).send_presence(stream, presence);
|
stream.get_module(Presence.Module.IDENTITY).send_presence(stream, presence);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exit(XmppStream stream, string jid) {
|
public void exit(XmppStream stream, Jid jid) {
|
||||||
string nick = stream.get_flag(Flag.IDENTITY).get_muc_nick(jid);
|
string nick = stream.get_flag(Flag.IDENTITY).get_muc_nick(jid);
|
||||||
Presence.Stanza presence = new Presence.Stanza();
|
Presence.Stanza presence = new Presence.Stanza();
|
||||||
presence.to = jid + "/" + nick;
|
presence.to = jid.with_resource(nick);
|
||||||
presence.type_ = Presence.Stanza.TYPE_UNAVAILABLE;
|
presence.type_ = Presence.Stanza.TYPE_UNAVAILABLE;
|
||||||
stream.get_module(Presence.Module.IDENTITY).send_presence(stream, presence);
|
stream.get_module(Presence.Module.IDENTITY).send_presence(stream, presence);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void change_subject(XmppStream stream, string jid, string subject) {
|
public void change_subject(XmppStream stream, Jid jid, string subject) {
|
||||||
Message.Stanza message = new Message.Stanza();
|
MessageStanza message = new MessageStanza();
|
||||||
message.to = jid;
|
message.to = jid;
|
||||||
message.type_ = Message.Stanza.TYPE_GROUPCHAT;
|
message.type_ = MessageStanza.TYPE_GROUPCHAT;
|
||||||
message.stanza.put_node((new StanzaNode.build("subject")).put_node(new StanzaNode.text(subject)));
|
message.stanza.put_node((new StanzaNode.build("subject")).put_node(new StanzaNode.text(subject)));
|
||||||
stream.get_module(Message.Module.IDENTITY).send_message(stream, message);
|
stream.get_module(MessageModule.IDENTITY).send_message(stream, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void change_nick(XmppStream stream, string jid, string new_nick) {
|
public void change_nick(XmppStream stream, Jid jid, string new_nick) {
|
||||||
Presence.Stanza presence = new Presence.Stanza();
|
Presence.Stanza presence = new Presence.Stanza();
|
||||||
presence.to = jid + "/" + new_nick;
|
presence.to = jid.with_resource(new_nick);
|
||||||
stream.get_module(Presence.Module.IDENTITY).send_presence(stream, presence);
|
stream.get_module(Presence.Module.IDENTITY).send_presence(stream, presence);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void invite(XmppStream stream, string to_muc, string jid) {
|
public void invite(XmppStream stream, Jid to_muc, Jid jid) {
|
||||||
Message.Stanza message = new Message.Stanza();
|
MessageStanza message = new MessageStanza();
|
||||||
message.to = to_muc;
|
message.to = to_muc;
|
||||||
StanzaNode invite_node = new StanzaNode.build("x", NS_URI_USER).add_self_xmlns()
|
StanzaNode invite_node = new StanzaNode.build("x", NS_URI_USER).add_self_xmlns()
|
||||||
.put_node(new StanzaNode.build("invite", NS_URI_USER).put_attribute("to", jid));
|
.put_node(new StanzaNode.build("invite", NS_URI_USER).put_attribute("to", jid.to_string()));
|
||||||
message.stanza.put_node(invite_node);
|
message.stanza.put_node(invite_node);
|
||||||
stream.get_module(Message.Module.IDENTITY).send_message(stream, message);
|
stream.get_module(MessageModule.IDENTITY).send_message(stream, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void kick(XmppStream stream, string jid, string nick) {
|
public void kick(XmppStream stream, Jid jid, string nick) {
|
||||||
change_role(stream, jid, nick, "none");
|
change_role(stream, jid, nick, "none");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XEP 0046: "A user cannot be kicked by a moderator with a lower affiliation." (XEP 0045 8.2) */
|
/* XEP 0046: "A user cannot be kicked by a moderator with a lower affiliation." (XEP 0045 8.2) */
|
||||||
public bool kick_possible(XmppStream stream, string occupant) {
|
public bool kick_possible(XmppStream stream, Jid occupant) {
|
||||||
string muc_jid = get_bare_jid(occupant);
|
Jid muc_jid = occupant.bare_jid;
|
||||||
Flag flag = stream.get_flag(Flag.IDENTITY);
|
Flag flag = stream.get_flag(Flag.IDENTITY);
|
||||||
string own_nick = flag.get_muc_nick(muc_jid);
|
string own_nick = flag.get_muc_nick(muc_jid);
|
||||||
Affiliation my_affiliation = flag.get_affiliation(muc_jid, muc_jid + "/" + own_nick);
|
Affiliation my_affiliation = flag.get_affiliation(muc_jid, muc_jid.with_resource(own_nick));
|
||||||
Affiliation other_affiliation = flag.get_affiliation(muc_jid, occupant);
|
Affiliation other_affiliation = flag.get_affiliation(muc_jid, occupant);
|
||||||
switch (my_affiliation) {
|
switch (my_affiliation) {
|
||||||
case Affiliation.MEMBER:
|
case Affiliation.MEMBER:
|
||||||
|
@ -142,22 +140,22 @@ public class Module : XmppStreamModule {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void change_role(XmppStream stream, string jid, string nick, string new_role) {
|
public void change_role(XmppStream stream, Jid jid, string nick, string new_role) {
|
||||||
StanzaNode query = new StanzaNode.build("query", NS_URI_ADMIN).add_self_xmlns();
|
StanzaNode query = new StanzaNode.build("query", NS_URI_ADMIN).add_self_xmlns();
|
||||||
query.put_node(new StanzaNode.build("item", NS_URI_ADMIN).put_attribute("nick", nick, NS_URI_ADMIN).put_attribute("role", new_role, NS_URI_ADMIN));
|
query.put_node(new StanzaNode.build("item", NS_URI_ADMIN).put_attribute("nick", nick, NS_URI_ADMIN).put_attribute("role", new_role, NS_URI_ADMIN));
|
||||||
Iq.Stanza iq = new Iq.Stanza.set(query) { to=jid };
|
Iq.Stanza iq = new Iq.Stanza.set(query) { to=jid };
|
||||||
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq);
|
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void change_affiliation(XmppStream stream, string jid, string nick, string new_affiliation) {
|
public void change_affiliation(XmppStream stream, Jid jid, string nick, string new_affiliation) {
|
||||||
StanzaNode query = new StanzaNode.build("query", NS_URI_ADMIN).add_self_xmlns();
|
StanzaNode query = new StanzaNode.build("query", NS_URI_ADMIN).add_self_xmlns();
|
||||||
query.put_node(new StanzaNode.build("item", NS_URI_ADMIN).put_attribute("nick", nick, NS_URI_ADMIN).put_attribute("affiliation", new_affiliation, NS_URI_ADMIN));
|
query.put_node(new StanzaNode.build("item", NS_URI_ADMIN).put_attribute("nick", nick, NS_URI_ADMIN).put_attribute("affiliation", new_affiliation, NS_URI_ADMIN));
|
||||||
Iq.Stanza iq = new Iq.Stanza.set(query) { to=jid };
|
Iq.Stanza iq = new Iq.Stanza.set(query) { to=jid };
|
||||||
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq);
|
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq);
|
||||||
}
|
}
|
||||||
|
|
||||||
public delegate void OnConfigFormResult(XmppStream stream, string jid, DataForms.DataForm data_form);
|
public delegate void OnConfigFormResult(XmppStream stream, Jid jid, DataForms.DataForm data_form);
|
||||||
public void get_config_form(XmppStream stream, string jid, owned OnConfigFormResult listener) {
|
public void get_config_form(XmppStream stream, Jid jid, owned OnConfigFormResult listener) {
|
||||||
Iq.Stanza get_iq = new Iq.Stanza.get(new StanzaNode.build("query", NS_URI_OWNER).add_self_xmlns()) { to=jid };
|
Iq.Stanza get_iq = new Iq.Stanza.get(new StanzaNode.build("query", NS_URI_OWNER).add_self_xmlns()) { to=jid };
|
||||||
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, get_iq, (stream, form_iq) => {
|
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, get_iq, (stream, form_iq) => {
|
||||||
StanzaNode? x_node = form_iq.stanza.get_deep_subnode(NS_URI_OWNER + ":query", DataForms.NS_URI + ":x");
|
StanzaNode? x_node = form_iq.stanza.get_deep_subnode(NS_URI_OWNER + ":query", DataForms.NS_URI + ":x");
|
||||||
|
@ -176,7 +174,7 @@ public class Module : XmppStreamModule {
|
||||||
|
|
||||||
public override void attach(XmppStream stream) {
|
public override void attach(XmppStream stream) {
|
||||||
stream.add_flag(new Muc.Flag());
|
stream.add_flag(new Muc.Flag());
|
||||||
stream.get_module(Message.Module.IDENTITY).received_message.connect(on_received_message);
|
stream.get_module(MessageModule.IDENTITY).received_message.connect(on_received_message);
|
||||||
stream.get_module(Presence.Module.IDENTITY).received_presence.connect(check_for_enter_error);
|
stream.get_module(Presence.Module.IDENTITY).received_presence.connect(check_for_enter_error);
|
||||||
stream.get_module(Presence.Module.IDENTITY).received_available.connect(on_received_available);
|
stream.get_module(Presence.Module.IDENTITY).received_available.connect(on_received_available);
|
||||||
stream.get_module(Presence.Module.IDENTITY).received_unavailable.connect(on_received_unavailable);
|
stream.get_module(Presence.Module.IDENTITY).received_unavailable.connect(on_received_unavailable);
|
||||||
|
@ -192,7 +190,7 @@ public class Module : XmppStreamModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void detach(XmppStream stream) {
|
public override void detach(XmppStream stream) {
|
||||||
stream.get_module(Message.Module.IDENTITY).received_message.disconnect(on_received_message);
|
stream.get_module(MessageModule.IDENTITY).received_message.disconnect(on_received_message);
|
||||||
stream.get_module(Presence.Module.IDENTITY).received_presence.disconnect(check_for_enter_error);
|
stream.get_module(Presence.Module.IDENTITY).received_presence.disconnect(check_for_enter_error);
|
||||||
stream.get_module(Presence.Module.IDENTITY).received_available.disconnect(on_received_available);
|
stream.get_module(Presence.Module.IDENTITY).received_available.disconnect(on_received_available);
|
||||||
stream.get_module(Presence.Module.IDENTITY).received_unavailable.disconnect(on_received_unavailable);
|
stream.get_module(Presence.Module.IDENTITY).received_unavailable.disconnect(on_received_unavailable);
|
||||||
|
@ -201,8 +199,8 @@ public class Module : XmppStreamModule {
|
||||||
public override string get_ns() { return NS_URI; }
|
public override string get_ns() { return NS_URI; }
|
||||||
public override string get_id() { return IDENTITY.id; }
|
public override string get_id() { return IDENTITY.id; }
|
||||||
|
|
||||||
private void on_received_message(XmppStream stream, Message.Stanza message) {
|
private void on_received_message(XmppStream stream, MessageStanza message) {
|
||||||
if (message.type_ == Message.Stanza.TYPE_GROUPCHAT) {
|
if (message.type_ == MessageStanza.TYPE_GROUPCHAT) {
|
||||||
StanzaNode? subject_node = message.stanza.get_subnode("subject");
|
StanzaNode? subject_node = message.stanza.get_subnode("subject");
|
||||||
if (subject_node != null) {
|
if (subject_node != null) {
|
||||||
string subject = subject_node.get_string_content();
|
string subject = subject_node.get_string_content();
|
||||||
|
@ -215,7 +213,7 @@ public class Module : XmppStreamModule {
|
||||||
private void check_for_enter_error(XmppStream stream, Presence.Stanza presence) {
|
private void check_for_enter_error(XmppStream stream, Presence.Stanza presence) {
|
||||||
Flag flag = stream.get_flag(Flag.IDENTITY);
|
Flag flag = stream.get_flag(Flag.IDENTITY);
|
||||||
if (presence.is_error() && flag.is_muc_enter_outstanding() && flag.is_occupant(presence.from)) {
|
if (presence.is_error() && flag.is_muc_enter_outstanding() && flag.is_occupant(presence.from)) {
|
||||||
string bare_jid = get_bare_jid(presence.from);
|
Jid bare_jid = presence.from.bare_jid;
|
||||||
ErrorStanza? error_stanza = presence.get_error();
|
ErrorStanza? error_stanza = presence.get_error();
|
||||||
if (flag.get_enter_id(bare_jid) == presence.id) {
|
if (flag.get_enter_id(bare_jid) == presence.id) {
|
||||||
MucEnterError error = MucEnterError.NONE;
|
MucEnterError error = MucEnterError.NONE;
|
||||||
|
@ -258,20 +256,21 @@ public class Module : XmppStreamModule {
|
||||||
if (x_node != null) {
|
if (x_node != null) {
|
||||||
ArrayList<int> status_codes = get_status_codes(x_node);
|
ArrayList<int> status_codes = get_status_codes(x_node);
|
||||||
if (status_codes.contains(StatusCode.SELF_PRESENCE)) {
|
if (status_codes.contains(StatusCode.SELF_PRESENCE)) {
|
||||||
string bare_jid = get_bare_jid(presence.from);
|
Jid bare_jid = presence.from.bare_jid;
|
||||||
if (flag.get_enter_id(bare_jid) != null) {
|
if (flag.get_enter_id(bare_jid) != null) {
|
||||||
room_entered(stream, bare_jid, get_resource_part(presence.from));
|
room_entered(stream, bare_jid, presence.from.resourcepart);
|
||||||
flag.finish_muc_enter(bare_jid, get_resource_part(presence.from));
|
flag.finish_muc_enter(bare_jid, presence.from.resourcepart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
string? affiliation_str = x_node.get_deep_attribute("item", "affiliation");
|
string? affiliation_str = x_node.get_deep_attribute("item", "affiliation");
|
||||||
if (affiliation_str != null) {
|
if (affiliation_str != null) {
|
||||||
Affiliation affiliation = parse_affiliation(affiliation_str);
|
Affiliation affiliation = parse_affiliation(affiliation_str);
|
||||||
flag.set_affiliation(get_bare_jid(presence.from), presence.from, affiliation);
|
flag.set_affiliation(presence.from.bare_jid, presence.from, affiliation);
|
||||||
received_occupant_affiliation(stream, presence.from, affiliation);
|
received_occupant_affiliation(stream, presence.from, affiliation);
|
||||||
}
|
}
|
||||||
string? jid = x_node.get_deep_attribute("item", "jid");
|
string? jid_ = x_node.get_deep_attribute("item", "jid");
|
||||||
if (jid != null) {
|
if (jid_ != null) {
|
||||||
|
Jid? jid = Jid.parse(jid_);
|
||||||
flag.set_real_jid(presence.from, jid);
|
flag.set_real_jid(presence.from, jid);
|
||||||
received_occupant_jid(stream, presence.from, jid);
|
received_occupant_jid(stream, presence.from, jid);
|
||||||
}
|
}
|
||||||
|
@ -301,10 +300,10 @@ public class Module : XmppStreamModule {
|
||||||
foreach (StatusCode code in USER_REMOVED_CODES) {
|
foreach (StatusCode code in USER_REMOVED_CODES) {
|
||||||
if (code in status_codes) {
|
if (code in status_codes) {
|
||||||
if (StatusCode.SELF_PRESENCE in status_codes) {
|
if (StatusCode.SELF_PRESENCE in status_codes) {
|
||||||
flag.left_muc(stream, get_bare_jid(presence.from));
|
flag.left_muc(stream, presence.from.bare_jid);
|
||||||
self_removed_from_room(stream, presence.from, code);
|
self_removed_from_room(stream, presence.from, code);
|
||||||
Presence.Flag presence_flag = stream.get_flag(Presence.Flag.IDENTITY);
|
Presence.Flag presence_flag = stream.get_flag(Presence.Flag.IDENTITY);
|
||||||
presence_flag.remove_presence(get_bare_jid(presence.from));
|
presence_flag.remove_presence(presence.from.bare_jid);
|
||||||
} else {
|
} else {
|
||||||
removed_from_room(stream, presence.from, code);
|
removed_from_room(stream, presence.from, code);
|
||||||
}
|
}
|
||||||
|
@ -312,7 +311,7 @@ public class Module : XmppStreamModule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void query_room_info(XmppStream stream, string jid) {
|
private void query_room_info(XmppStream stream, Jid jid) {
|
||||||
stream.get_module(ServiceDiscovery.Module.IDENTITY).request_info(stream, jid, (stream, query_result) => {
|
stream.get_module(ServiceDiscovery.Module.IDENTITY).request_info(stream, jid, (stream, query_result) => {
|
||||||
|
|
||||||
Gee.List<Feature> features = new ArrayList<Feature>();
|
Gee.List<Feature> features = new ArrayList<Feature>();
|
||||||
|
@ -351,8 +350,8 @@ public class Module : XmppStreamModule {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public delegate void OnAffiliationResult(XmppStream stream, Gee.List<string> jids);
|
public delegate void OnAffiliationResult(XmppStream stream, Gee.List<Jid> jids);
|
||||||
private void query_affiliation(XmppStream stream, string jid, string affiliation, owned OnAffiliationResult? listener) {
|
private void query_affiliation(XmppStream stream, Jid jid, string affiliation, owned OnAffiliationResult? listener) {
|
||||||
Iq.Stanza iq = new Iq.Stanza.get(
|
Iq.Stanza iq = new Iq.Stanza.get(
|
||||||
new StanzaNode.build("query", NS_URI_ADMIN)
|
new StanzaNode.build("query", NS_URI_ADMIN)
|
||||||
.add_self_xmlns()
|
.add_self_xmlns()
|
||||||
|
@ -364,9 +363,9 @@ public class Module : XmppStreamModule {
|
||||||
StanzaNode? query_node = iq.stanza.get_subnode("query", NS_URI_ADMIN);
|
StanzaNode? query_node = iq.stanza.get_subnode("query", NS_URI_ADMIN);
|
||||||
if (query_node == null) return;
|
if (query_node == null) return;
|
||||||
Gee.List<StanzaNode> item_nodes = query_node.get_subnodes("item", NS_URI_ADMIN);
|
Gee.List<StanzaNode> item_nodes = query_node.get_subnodes("item", NS_URI_ADMIN);
|
||||||
Gee.List<string> ret_jids = new ArrayList<string>();
|
Gee.List<Jid> ret_jids = new ArrayList<Jid>(Jid.equals_func);
|
||||||
foreach (StanzaNode item in item_nodes) {
|
foreach (StanzaNode item in item_nodes) {
|
||||||
string? jid_ = item.get_attribute("jid");
|
Jid? jid_ = Jid.parse(item.get_attribute("jid"));
|
||||||
string? affiliation_ = item.get_attribute("affiliation");
|
string? affiliation_ = item.get_attribute("affiliation");
|
||||||
if (jid_ != null && affiliation_ != null) {
|
if (jid_ != null && affiliation_ != null) {
|
||||||
stream.get_flag(Muc.Flag.IDENTITY).set_offline_member(iq.from, jid_, parse_affiliation(affiliation_));
|
stream.get_flag(Muc.Flag.IDENTITY).set_offline_member(iq.from, jid_, parse_affiliation(affiliation_));
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp.Xep.Bookmarks {
|
namespace Xmpp.Xep.Bookmarks {
|
||||||
|
|
||||||
public class Conference : Object {
|
public class Conference : Object {
|
||||||
|
@ -21,9 +19,10 @@ public class Conference : Object {
|
||||||
set { stanza_node.set_attribute(ATTRIBUTE_AUTOJOIN, value.to_string()); }
|
set { stanza_node.set_attribute(ATTRIBUTE_AUTOJOIN, value.to_string()); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public string jid {
|
private Jid jid_;
|
||||||
get { return stanza_node.get_attribute(ATTRIBUTE_JID); }
|
public Jid jid {
|
||||||
set { stanza_node.set_attribute(ATTRIBUTE_JID, value); }
|
get { return jid_ ?? (jid_ = Jid.parse(stanza_node.get_attribute(ATTRIBUTE_JID))); }
|
||||||
|
set { stanza_node.set_attribute(ATTRIBUTE_JID, value.to_string()); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public string? name {
|
public string? name {
|
||||||
|
@ -73,7 +72,7 @@ public class Conference : Object {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Conference(string jid) {
|
public Conference(Jid jid) {
|
||||||
this.stanza_node = new StanzaNode.build("conference", NS_URI);
|
this.stanza_node = new StanzaNode.build("conference", NS_URI);
|
||||||
this.jid = jid;
|
this.jid = jid;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp.Xep.Bookmarks {
|
namespace Xmpp.Xep.Bookmarks {
|
||||||
private const string NS_URI = "storage:bookmarks";
|
private const string NS_URI = "storage:bookmarks";
|
||||||
|
|
||||||
|
@ -10,12 +8,16 @@ public class Module : XmppStreamModule {
|
||||||
|
|
||||||
public signal void received_conferences(XmppStream stream, Gee.List<Conference> conferences);
|
public signal void received_conferences(XmppStream stream, Gee.List<Conference> conferences);
|
||||||
|
|
||||||
public delegate void OnResult(XmppStream stream, Gee.List<Conference> conferences);
|
public delegate void OnResult(XmppStream stream, Gee.List<Conference>? conferences);
|
||||||
public void get_conferences(XmppStream stream, owned OnResult listener) {
|
public void get_conferences(XmppStream stream, owned OnResult listener) {
|
||||||
StanzaNode get_node = new StanzaNode.build("storage", NS_URI).add_self_xmlns();
|
StanzaNode get_node = new StanzaNode.build("storage", NS_URI).add_self_xmlns();
|
||||||
stream.get_module(PrivateXmlStorage.Module.IDENTITY).retrieve(stream, get_node, (stream, node) => {
|
stream.get_module(PrivateXmlStorage.Module.IDENTITY).retrieve(stream, get_node, (stream, node) => {
|
||||||
|
if (node == null) {
|
||||||
|
listener(stream, null);
|
||||||
|
} else {
|
||||||
Gee.List<Conference> conferences = get_conferences_from_stanza(node);
|
Gee.List<Conference> conferences = get_conferences_from_stanza(node);
|
||||||
listener(stream, conferences);
|
listener(stream, conferences);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +41,7 @@ public class Module : XmppStreamModule {
|
||||||
public void replace_conference(XmppStream stream, Conference orig_conference, Conference modified_conference) {
|
public void replace_conference(XmppStream stream, Conference orig_conference, Conference modified_conference) {
|
||||||
get_conferences(stream, (stream, conferences) => {
|
get_conferences(stream, (stream, conferences) => {
|
||||||
foreach (Conference conference in conferences) {
|
foreach (Conference conference in conferences) {
|
||||||
if (conference.autojoin == orig_conference.autojoin && conference.jid == orig_conference.jid &&
|
if (conference.autojoin == orig_conference.autojoin && conference.jid.equals(orig_conference.jid) &&
|
||||||
conference.name == orig_conference.name && conference.nick == orig_conference.nick) {
|
conference.name == orig_conference.name && conference.nick == orig_conference.nick) {
|
||||||
conference.autojoin = modified_conference.autojoin;
|
conference.autojoin = modified_conference.autojoin;
|
||||||
conference.jid = modified_conference.jid;
|
conference.jid = modified_conference.jid;
|
||||||
|
@ -56,7 +58,7 @@ public class Module : XmppStreamModule {
|
||||||
get_conferences(stream, (stream, conferences) => {
|
get_conferences(stream, (stream, conferences) => {
|
||||||
Conference? rem = null;
|
Conference? rem = null;
|
||||||
foreach (Conference conference in conferences) {
|
foreach (Conference conference in conferences) {
|
||||||
if (conference.name == conference_remove.name && conference.jid == conference_remove.jid && conference.autojoin == conference_remove.autojoin) {
|
if (conference.name == conference_remove.name && conference.jid.equals(conference_remove.jid) && conference.autojoin == conference_remove.autojoin) {
|
||||||
rem = conference;
|
rem = conference;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using Gee;
|
using Gee;
|
||||||
|
|
||||||
using Xmpp.Core;
|
|
||||||
|
|
||||||
namespace Xmpp.Xep.PrivateXmlStorage {
|
namespace Xmpp.Xep.PrivateXmlStorage {
|
||||||
private const string NS_URI = "jabber:iq:private";
|
private const string NS_URI = "jabber:iq:private";
|
||||||
|
|
||||||
|
@ -17,7 +15,7 @@ namespace Xmpp.Xep.PrivateXmlStorage {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public delegate void OnResponse(XmppStream stream, StanzaNode node);
|
public delegate void OnResponse(XmppStream stream, StanzaNode? node);
|
||||||
public void retrieve(XmppStream stream, StanzaNode node, owned OnResponse listener) {
|
public void retrieve(XmppStream stream, StanzaNode node, owned OnResponse listener) {
|
||||||
StanzaNode queryNode = new StanzaNode.build("query", NS_URI).add_self_xmlns().put_node(node);
|
StanzaNode queryNode = new StanzaNode.build("query", NS_URI).add_self_xmlns().put_node(node);
|
||||||
Iq.Stanza iq = new Iq.Stanza.get(queryNode);
|
Iq.Stanza iq = new Iq.Stanza.get(queryNode);
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue