2020-03-25 16:42:30 +08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Collections.Generic;
|
2020-03-27 15:52:34 +08:00
|
|
|
|
using System.Collections.ObjectModel;
|
2020-03-25 16:42:30 +08:00
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
using LeanCloud.Realtime.Protocol;
|
|
|
|
|
using LeanCloud.Storage.Internal;
|
|
|
|
|
using LeanCloud.Storage.Internal.Codec;
|
2020-03-26 16:08:35 +08:00
|
|
|
|
using LeanCloud.Common;
|
2020-03-25 16:42:30 +08:00
|
|
|
|
|
|
|
|
|
namespace LeanCloud.Realtime.Internal.Controller {
|
|
|
|
|
internal class LCIMConversationController : LCIMController {
|
|
|
|
|
internal LCIMConversationController(LCIMClient client) : base(client) {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 15:52:34 +08:00
|
|
|
|
#region 内部接口
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 创建对话
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="members"></param>
|
|
|
|
|
/// <param name="name"></param>
|
|
|
|
|
/// <param name="transient"></param>
|
|
|
|
|
/// <param name="unique"></param>
|
|
|
|
|
/// <param name="temporary"></param>
|
|
|
|
|
/// <param name="temporaryTtl"></param>
|
|
|
|
|
/// <param name="properties"></param>
|
|
|
|
|
/// <returns></returns>
|
2020-03-25 16:42:30 +08:00
|
|
|
|
internal async Task<LCIMConversation> CreateConv(
|
|
|
|
|
IEnumerable<string> members = null,
|
|
|
|
|
string name = null,
|
|
|
|
|
bool transient = false,
|
|
|
|
|
bool unique = true,
|
|
|
|
|
bool temporary = false,
|
|
|
|
|
int temporaryTtl = 86400,
|
|
|
|
|
Dictionary<string, object> properties = null) {
|
|
|
|
|
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Start);
|
|
|
|
|
ConvCommand conv = new ConvCommand {
|
|
|
|
|
Transient = transient,
|
|
|
|
|
Unique = unique,
|
|
|
|
|
};
|
|
|
|
|
if (members != null) {
|
|
|
|
|
conv.M.AddRange(members);
|
|
|
|
|
}
|
|
|
|
|
if (!string.IsNullOrEmpty(name)) {
|
|
|
|
|
conv.N = name;
|
|
|
|
|
}
|
|
|
|
|
if (temporary) {
|
|
|
|
|
conv.TempConv = temporary;
|
|
|
|
|
conv.TempConvTTL = temporaryTtl;
|
|
|
|
|
}
|
|
|
|
|
if (properties != null) {
|
|
|
|
|
conv.Attr = new JsonObjectMessage {
|
|
|
|
|
Data = JsonConvert.SerializeObject(LCEncoder.Encode(properties))
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
if (Client.SignatureFactory != null) {
|
|
|
|
|
LCIMSignature signature = Client.SignatureFactory.CreateStartConversationSignature(Client.Id, members);
|
|
|
|
|
conv.S = signature.Signature;
|
|
|
|
|
conv.T = signature.Timestamp;
|
|
|
|
|
conv.N = signature.Nonce;
|
|
|
|
|
}
|
|
|
|
|
request.ConvMessage = conv;
|
|
|
|
|
GenericCommand response = await Connection.SendRequest(request);
|
|
|
|
|
string convId = response.ConvMessage.Cid;
|
|
|
|
|
if (!Client.ConversationDict.TryGetValue(convId, out LCIMConversation conversation)) {
|
|
|
|
|
if (transient) {
|
|
|
|
|
conversation = new LCIMChatRoom(Client);
|
|
|
|
|
} else if (temporary) {
|
|
|
|
|
conversation = new LCIMTemporaryConversation(Client);
|
|
|
|
|
} else if (properties != null && properties.ContainsKey("system")) {
|
|
|
|
|
conversation = new LCIMServiceConversation(Client);
|
|
|
|
|
} else {
|
|
|
|
|
conversation = new LCIMConversation(Client);
|
|
|
|
|
}
|
|
|
|
|
Client.ConversationDict[convId] = conversation;
|
|
|
|
|
}
|
|
|
|
|
// 合并请求数据
|
|
|
|
|
conversation.Name = name;
|
2020-03-27 15:52:34 +08:00
|
|
|
|
conversation.ids = members != null ? new HashSet<string>(members) : null;
|
2020-03-25 16:42:30 +08:00
|
|
|
|
// 合并服务端推送的数据
|
|
|
|
|
conversation.MergeFrom(response.ConvMessage);
|
|
|
|
|
return conversation;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 15:52:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 查询成员数量
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convId"></param>
|
|
|
|
|
/// <returns></returns>
|
2020-03-25 16:42:30 +08:00
|
|
|
|
internal async Task<int> GetMembersCount(string convId) {
|
|
|
|
|
ConvCommand conv = new ConvCommand {
|
|
|
|
|
Cid = convId,
|
|
|
|
|
};
|
|
|
|
|
GenericCommand command = Client.NewCommand(CommandType.Conv, OpType.Count);
|
|
|
|
|
command.ConvMessage = conv;
|
|
|
|
|
GenericCommand response = await Connection.SendRequest(command);
|
|
|
|
|
return response.ConvMessage.Count;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 15:52:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 标记对话的消息已读
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convId"></param>
|
|
|
|
|
/// <param name="message"></param>
|
|
|
|
|
/// <returns></returns>
|
2020-03-26 16:08:35 +08:00
|
|
|
|
internal async Task Read(string convId,
|
|
|
|
|
LCIMMessage message) {
|
2020-03-25 16:42:30 +08:00
|
|
|
|
ReadCommand read = new ReadCommand();
|
|
|
|
|
ReadTuple tuple = new ReadTuple {
|
|
|
|
|
Cid = convId,
|
|
|
|
|
Mid = message.Id,
|
|
|
|
|
Timestamp = message.SentTimestamp
|
|
|
|
|
};
|
|
|
|
|
read.Convs.Add(tuple);
|
|
|
|
|
GenericCommand request = Client.NewCommand(CommandType.Read, OpType.Open);
|
|
|
|
|
request.ReadMessage = read;
|
|
|
|
|
await Client.Connection.SendRequest(request);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 15:52:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 更新对话属性
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convId"></param>
|
|
|
|
|
/// <param name="attributes"></param>
|
|
|
|
|
/// <returns></returns>
|
2020-03-26 16:08:35 +08:00
|
|
|
|
internal async Task<Dictionary<string, object>> UpdateInfo(string convId,
|
|
|
|
|
Dictionary<string, object> attributes) {
|
2020-03-25 16:42:30 +08:00
|
|
|
|
ConvCommand conv = new ConvCommand {
|
|
|
|
|
Cid = convId,
|
|
|
|
|
};
|
|
|
|
|
conv.Attr = new JsonObjectMessage {
|
|
|
|
|
Data = JsonConvert.SerializeObject(attributes)
|
|
|
|
|
};
|
|
|
|
|
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Update);
|
|
|
|
|
request.ConvMessage = conv;
|
|
|
|
|
GenericCommand response = await Client.Connection.SendRequest(request);
|
|
|
|
|
JsonObjectMessage attr = response.ConvMessage.AttrModified;
|
|
|
|
|
// 更新自定义属性
|
|
|
|
|
if (attr != null) {
|
|
|
|
|
Dictionary<string, object> updatedAttr = JsonConvert.DeserializeObject<Dictionary<string, object>>(attr.Data);
|
|
|
|
|
return updatedAttr;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 15:52:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 增加成员
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convId"></param>
|
|
|
|
|
/// <param name="clientIds"></param>
|
|
|
|
|
/// <returns></returns>
|
2020-03-26 16:08:35 +08:00
|
|
|
|
internal async Task<LCIMPartiallySuccessResult> AddMembers(string convId,
|
|
|
|
|
IEnumerable<string> clientIds) {
|
2020-03-25 16:42:30 +08:00
|
|
|
|
ConvCommand conv = new ConvCommand {
|
|
|
|
|
Cid = convId,
|
|
|
|
|
};
|
|
|
|
|
conv.M.AddRange(clientIds);
|
|
|
|
|
// 签名参数
|
|
|
|
|
if (Client.SignatureFactory != null) {
|
|
|
|
|
LCIMSignature signature = Client.SignatureFactory.CreateConversationSignature(convId,
|
|
|
|
|
Client.Id,
|
|
|
|
|
clientIds,
|
|
|
|
|
LCIMSignatureAction.Invite);
|
|
|
|
|
conv.S = signature.Signature;
|
|
|
|
|
conv.T = signature.Timestamp;
|
|
|
|
|
conv.N = signature.Nonce;
|
|
|
|
|
}
|
|
|
|
|
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Add);
|
|
|
|
|
request.ConvMessage = conv;
|
|
|
|
|
GenericCommand response = await Client.Connection.SendRequest(request);
|
|
|
|
|
List<string> allowedIds = response.ConvMessage.AllowedPids.ToList();
|
|
|
|
|
List<ErrorCommand> errors = response.ConvMessage.FailedPids.ToList();
|
|
|
|
|
return NewPartiallySuccessResult(allowedIds, errors);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 15:52:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 移除成员
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convId"></param>
|
|
|
|
|
/// <param name="removeIds"></param>
|
|
|
|
|
/// <returns></returns>
|
2020-03-26 16:08:35 +08:00
|
|
|
|
internal async Task<LCIMPartiallySuccessResult> RemoveMembers(string convId,
|
|
|
|
|
IEnumerable<string> removeIds) {
|
2020-03-25 16:42:30 +08:00
|
|
|
|
ConvCommand conv = new ConvCommand {
|
|
|
|
|
Cid = convId,
|
|
|
|
|
};
|
|
|
|
|
conv.M.AddRange(removeIds);
|
|
|
|
|
// 签名参数
|
|
|
|
|
if (Client.SignatureFactory != null) {
|
|
|
|
|
LCIMSignature signature = Client.SignatureFactory.CreateConversationSignature(convId,
|
|
|
|
|
Client.Id,
|
|
|
|
|
removeIds,
|
|
|
|
|
LCIMSignatureAction.Kick);
|
|
|
|
|
conv.S = signature.Signature;
|
|
|
|
|
conv.T = signature.Timestamp;
|
|
|
|
|
conv.N = signature.Nonce;
|
|
|
|
|
}
|
|
|
|
|
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Remove);
|
|
|
|
|
request.ConvMessage = conv;
|
|
|
|
|
GenericCommand response = await Client.Connection.SendRequest(request);
|
|
|
|
|
List<string> allowedIds = response.ConvMessage.AllowedPids.ToList();
|
|
|
|
|
List<ErrorCommand> errors = response.ConvMessage.FailedPids.ToList();
|
|
|
|
|
return NewPartiallySuccessResult(allowedIds, errors);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 15:52:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 静音
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convId"></param>
|
|
|
|
|
/// <returns></returns>
|
2020-03-25 16:42:30 +08:00
|
|
|
|
internal async Task Mute(string convId) {
|
|
|
|
|
ConvCommand conv = new ConvCommand {
|
|
|
|
|
Cid = convId
|
|
|
|
|
};
|
|
|
|
|
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Mute);
|
|
|
|
|
request.ConvMessage = conv;
|
|
|
|
|
await Client.Connection.SendRequest(request);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 15:52:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 解除静音
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convId"></param>
|
|
|
|
|
/// <returns></returns>
|
2020-03-25 16:42:30 +08:00
|
|
|
|
internal async Task Unmute(string convId) {
|
|
|
|
|
ConvCommand conv = new ConvCommand {
|
|
|
|
|
Cid = convId
|
|
|
|
|
};
|
|
|
|
|
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Unmute);
|
|
|
|
|
request.ConvMessage = conv;
|
|
|
|
|
await Client.Connection.SendRequest(request);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 15:52:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 禁言用户
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convId"></param>
|
|
|
|
|
/// <param name="clientIds"></param>
|
|
|
|
|
/// <returns></returns>
|
2020-03-26 16:08:35 +08:00
|
|
|
|
internal async Task<LCIMPartiallySuccessResult> MuteMembers(string convId,
|
|
|
|
|
IEnumerable<string> clientIds) {
|
2020-03-25 16:42:30 +08:00
|
|
|
|
if (clientIds == null || clientIds.Count() == 0) {
|
|
|
|
|
throw new ArgumentNullException(nameof(clientIds));
|
|
|
|
|
}
|
|
|
|
|
ConvCommand conv = new ConvCommand {
|
|
|
|
|
Cid = convId
|
|
|
|
|
};
|
|
|
|
|
conv.M.AddRange(clientIds);
|
|
|
|
|
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.AddShutup);
|
|
|
|
|
request.ConvMessage = conv;
|
|
|
|
|
GenericCommand response = await Client.Connection.SendRequest(request);
|
|
|
|
|
return NewPartiallySuccessResult(response.ConvMessage.AllowedPids, response.ConvMessage.FailedPids);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 15:52:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 解除用户禁言
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convId"></param>
|
|
|
|
|
/// <param name="clientIds"></param>
|
|
|
|
|
/// <returns></returns>
|
2020-03-26 16:08:35 +08:00
|
|
|
|
internal async Task<LCIMPartiallySuccessResult> UnmuteMembers(string convId,
|
|
|
|
|
IEnumerable<string> clientIds) {
|
2020-03-25 16:42:30 +08:00
|
|
|
|
ConvCommand conv = new ConvCommand {
|
|
|
|
|
Cid = convId
|
|
|
|
|
};
|
|
|
|
|
conv.M.AddRange(clientIds);
|
|
|
|
|
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Remove);
|
|
|
|
|
request.ConvMessage = conv;
|
|
|
|
|
GenericCommand response = await Client.Connection.SendRequest(request);
|
|
|
|
|
return NewPartiallySuccessResult(response.ConvMessage.AllowedPids, response.ConvMessage.FailedPids);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 15:52:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 拉黑成员
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convId"></param>
|
|
|
|
|
/// <param name="clientIds"></param>
|
|
|
|
|
/// <returns></returns>
|
2020-03-26 16:08:35 +08:00
|
|
|
|
internal async Task<LCIMPartiallySuccessResult> BlockMembers(string convId,
|
|
|
|
|
IEnumerable<string> clientIds) {
|
2020-03-25 16:42:30 +08:00
|
|
|
|
BlacklistCommand blacklist = new BlacklistCommand {
|
|
|
|
|
SrcCid = convId,
|
|
|
|
|
};
|
|
|
|
|
blacklist.ToPids.AddRange(clientIds);
|
|
|
|
|
if (Client.SignatureFactory != null) {
|
|
|
|
|
LCIMSignature signature = Client.SignatureFactory.CreateBlacklistSignature(convId,
|
|
|
|
|
Client.Id,
|
|
|
|
|
clientIds,
|
|
|
|
|
LCIMSignatureAction.ConversationBlockClients);
|
|
|
|
|
blacklist.S = signature.Signature;
|
|
|
|
|
blacklist.T = signature.Timestamp;
|
|
|
|
|
blacklist.N = signature.Nonce;
|
|
|
|
|
}
|
|
|
|
|
GenericCommand request = Client.NewCommand(CommandType.Blacklist, OpType.Block);
|
|
|
|
|
request.BlacklistMessage = blacklist;
|
|
|
|
|
GenericCommand response = await Client.Connection.SendRequest(request);
|
|
|
|
|
return NewPartiallySuccessResult(response.BlacklistMessage.AllowedPids, response.BlacklistMessage.FailedPids);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 15:52:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 移除成员黑名单
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convId"></param>
|
|
|
|
|
/// <param name="clientIds"></param>
|
|
|
|
|
/// <returns></returns>
|
2020-03-26 16:08:35 +08:00
|
|
|
|
internal async Task<LCIMPartiallySuccessResult> UnblockMembers(string convId,
|
|
|
|
|
IEnumerable<string> clientIds) {
|
2020-03-25 16:42:30 +08:00
|
|
|
|
BlacklistCommand blacklist = new BlacklistCommand {
|
|
|
|
|
SrcCid = convId,
|
|
|
|
|
};
|
|
|
|
|
blacklist.ToPids.AddRange(clientIds);
|
|
|
|
|
if (Client.SignatureFactory != null) {
|
|
|
|
|
LCIMSignature signature = Client.SignatureFactory.CreateBlacklistSignature(convId,
|
|
|
|
|
Client.Id,
|
|
|
|
|
clientIds,
|
|
|
|
|
LCIMSignatureAction.ConversationUnblockClients);
|
|
|
|
|
blacklist.S = signature.Signature;
|
|
|
|
|
blacklist.T = signature.Timestamp;
|
|
|
|
|
blacklist.N = signature.Nonce;
|
|
|
|
|
}
|
|
|
|
|
GenericCommand request = Client.NewCommand(CommandType.Blacklist, OpType.Unblock);
|
|
|
|
|
request.BlacklistMessage = blacklist;
|
|
|
|
|
GenericCommand response = await Client.Connection.SendRequest(request);
|
|
|
|
|
return NewPartiallySuccessResult(response.BlacklistMessage.AllowedPids, response.BlacklistMessage.FailedPids);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 15:52:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 修改成员角色
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convId"></param>
|
|
|
|
|
/// <param name="memberId"></param>
|
|
|
|
|
/// <param name="role"></param>
|
|
|
|
|
/// <returns></returns>
|
2020-03-26 16:08:35 +08:00
|
|
|
|
internal async Task UpdateMemberRole(string convId,
|
|
|
|
|
string memberId,
|
|
|
|
|
string role) {
|
2020-03-25 16:42:30 +08:00
|
|
|
|
ConvCommand conv = new ConvCommand {
|
|
|
|
|
Cid = convId,
|
|
|
|
|
TargetClientId = memberId,
|
|
|
|
|
Info = new ConvMemberInfo {
|
|
|
|
|
Pid = memberId,
|
|
|
|
|
Role = role
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.MemberInfoUpdate);
|
|
|
|
|
request.ConvMessage = conv;
|
|
|
|
|
GenericCommand response = await Client.Connection.SendRequest(request);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 15:52:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取所有成员角色
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convId"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
internal async Task<ReadOnlyCollection<LCIMConversationMemberInfo>> GetAllMemberInfo(string convId) {
|
2020-03-25 16:42:30 +08:00
|
|
|
|
string path = "classes/_ConversationMemberInfo";
|
|
|
|
|
string token = await Client.SessionController.GetToken();
|
|
|
|
|
Dictionary<string, object> headers = new Dictionary<string, object> {
|
|
|
|
|
{ "X-LC-IM-Session-Token", token }
|
|
|
|
|
};
|
|
|
|
|
Dictionary<string, object> queryParams = new Dictionary<string, object> {
|
|
|
|
|
{ "client_id", Client.Id },
|
|
|
|
|
{ "cid", convId }
|
|
|
|
|
};
|
|
|
|
|
Dictionary<string, object> response = await LCApplication.HttpClient.Get<Dictionary<string, object>>(path,
|
|
|
|
|
headers: headers, queryParams: queryParams);
|
|
|
|
|
List<object> results = response["results"] as List<object>;
|
2020-03-27 15:52:34 +08:00
|
|
|
|
return results.Select(item => {
|
|
|
|
|
Dictionary<string, object> memberInfo = item as Dictionary<string, object>;
|
|
|
|
|
return new LCIMConversationMemberInfo {
|
|
|
|
|
ConversationId = memberInfo["cid"] as string,
|
|
|
|
|
MemberId = memberInfo["clientId"] as string,
|
|
|
|
|
Role = memberInfo["role"] as string
|
2020-03-25 16:42:30 +08:00
|
|
|
|
};
|
2020-03-27 15:52:34 +08:00
|
|
|
|
}).ToList().AsReadOnly();
|
2020-03-25 16:42:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 15:52:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 查询禁言成员
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convId"></param>
|
|
|
|
|
/// <param name="limit"></param>
|
|
|
|
|
/// <param name="next"></param>
|
|
|
|
|
/// <returns></returns>
|
2020-03-26 16:08:35 +08:00
|
|
|
|
internal async Task<LCIMPageResult> QueryMutedMembers(string convId,
|
|
|
|
|
int limit = 10,
|
|
|
|
|
string next = null) {
|
2020-03-25 16:42:30 +08:00
|
|
|
|
ConvCommand conv = new ConvCommand {
|
|
|
|
|
Cid = convId,
|
|
|
|
|
Limit = limit,
|
|
|
|
|
Next = next
|
|
|
|
|
};
|
|
|
|
|
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.QueryShutup);
|
|
|
|
|
request.ConvMessage = conv;
|
|
|
|
|
GenericCommand response = await Client.Connection.SendRequest(request);
|
|
|
|
|
return new LCIMPageResult {
|
2020-03-27 15:52:34 +08:00
|
|
|
|
Results = new ReadOnlyCollection<string>(response.ConvMessage.M),
|
2020-03-25 16:42:30 +08:00
|
|
|
|
Next = response.ConvMessage.Next
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 15:52:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 查询黑名单用户
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convId"></param>
|
|
|
|
|
/// <param name="limit"></param>
|
|
|
|
|
/// <param name="next"></param>
|
|
|
|
|
/// <returns></returns>
|
2020-03-26 16:08:35 +08:00
|
|
|
|
internal async Task<LCIMPageResult> QueryBlockedMembers(string convId,
|
|
|
|
|
int limit = 10,
|
|
|
|
|
string next = null) {
|
2020-03-25 16:42:30 +08:00
|
|
|
|
BlacklistCommand black = new BlacklistCommand {
|
|
|
|
|
SrcCid = convId,
|
|
|
|
|
Limit = limit,
|
|
|
|
|
Next = next
|
|
|
|
|
};
|
|
|
|
|
GenericCommand request = Client.NewCommand(CommandType.Blacklist, OpType.Query);
|
|
|
|
|
request.BlacklistMessage = black;
|
|
|
|
|
GenericCommand response = await Client.Connection.SendRequest(request);
|
|
|
|
|
return new LCIMPageResult {
|
2020-03-27 15:52:34 +08:00
|
|
|
|
Results = new ReadOnlyCollection<string>(response.BlacklistMessage.BlockedPids),
|
2020-03-25 16:42:30 +08:00
|
|
|
|
Next = response.BlacklistMessage.Next
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 15:52:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 查找
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="query"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
internal async Task<ReadOnlyCollection<LCIMConversation>> Find(LCIMConversationQuery query) {
|
2020-03-26 16:08:35 +08:00
|
|
|
|
GenericCommand command = new GenericCommand {
|
|
|
|
|
Cmd = CommandType.Conv,
|
|
|
|
|
Op = OpType.Query,
|
|
|
|
|
AppId = LCApplication.AppId,
|
|
|
|
|
PeerId = Client.Id,
|
|
|
|
|
};
|
|
|
|
|
ConvCommand convMessage = new ConvCommand();
|
|
|
|
|
string where = query.Condition.BuildWhere();
|
|
|
|
|
if (!string.IsNullOrEmpty(where)) {
|
|
|
|
|
try {
|
|
|
|
|
convMessage.Where = new JsonObjectMessage {
|
|
|
|
|
Data = where
|
|
|
|
|
};
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
LCLogger.Error(e.Message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
command.ConvMessage = convMessage;
|
|
|
|
|
GenericCommand response = await Connection.SendRequest(command);
|
|
|
|
|
JsonObjectMessage results = response.ConvMessage.Results;
|
|
|
|
|
List<object> convs = JsonConvert.DeserializeObject<List<object>>(results.Data, new LCJsonConverter());
|
2020-03-27 15:52:34 +08:00
|
|
|
|
return convs.Select(item => {
|
2020-03-26 16:08:35 +08:00
|
|
|
|
Dictionary<string, object> conv = item as Dictionary<string, object>;
|
|
|
|
|
string convId = conv["objectId"] as string;
|
|
|
|
|
if (!Client.ConversationDict.TryGetValue(convId, out LCIMConversation conversation)) {
|
|
|
|
|
// TODO 解析是哪种类型的对话
|
|
|
|
|
|
|
|
|
|
conversation = new LCIMConversation(Client);
|
|
|
|
|
Client.ConversationDict[convId] = conversation;
|
|
|
|
|
}
|
2020-03-27 17:30:18 +08:00
|
|
|
|
|
2020-03-26 16:08:35 +08:00
|
|
|
|
conversation.MergeFrom(conv);
|
|
|
|
|
return conversation;
|
2020-03-27 15:52:34 +08:00
|
|
|
|
}).ToList().AsReadOnly();
|
2020-03-26 16:08:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal async Task<List<LCIMTemporaryConversation>> GetTemporaryConversations(IEnumerable<string> convIds) {
|
2020-03-27 15:52:34 +08:00
|
|
|
|
if (convIds == null || convIds.Count() == 0) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2020-03-26 16:08:35 +08:00
|
|
|
|
ConvCommand convMessage = new ConvCommand();
|
|
|
|
|
convMessage.TempConvIds.AddRange(convIds);
|
|
|
|
|
GenericCommand request = Client.NewCommand(CommandType.Conv, OpType.Query);
|
|
|
|
|
request.ConvMessage = convMessage;
|
|
|
|
|
GenericCommand response = await Connection.SendRequest(request);
|
|
|
|
|
JsonObjectMessage results = response.ConvMessage.Results;
|
|
|
|
|
List<object> convs = JsonConvert.DeserializeObject<List<object>>(results.Data, new LCJsonConverter());
|
|
|
|
|
List<LCIMTemporaryConversation> convList = convs.Select(item => {
|
|
|
|
|
LCIMTemporaryConversation temporaryConversation = new LCIMTemporaryConversation(Client);
|
|
|
|
|
temporaryConversation.MergeFrom(item as Dictionary<string, object>);
|
|
|
|
|
return temporaryConversation;
|
|
|
|
|
}).ToList();
|
|
|
|
|
return convList;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private LCIMPartiallySuccessResult NewPartiallySuccessResult(IEnumerable<string> succesfulIds,
|
|
|
|
|
IEnumerable<ErrorCommand> errors) {
|
2020-03-25 16:42:30 +08:00
|
|
|
|
LCIMPartiallySuccessResult result = new LCIMPartiallySuccessResult {
|
|
|
|
|
SuccessfulClientIdList = succesfulIds.ToList()
|
|
|
|
|
};
|
|
|
|
|
if (errors != null) {
|
|
|
|
|
result.FailureList = new List<LCIMOperationFailure>();
|
|
|
|
|
foreach (ErrorCommand error in errors) {
|
|
|
|
|
result.FailureList.Add(new LCIMOperationFailure(error));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 15:52:34 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 消息处理
|
|
|
|
|
|
2020-03-25 16:42:30 +08:00
|
|
|
|
internal override async Task OnNotification(GenericCommand notification) {
|
2020-03-27 15:52:34 +08:00
|
|
|
|
ConvCommand convMessage = notification.ConvMessage;
|
2020-03-25 16:42:30 +08:00
|
|
|
|
switch (notification.Op) {
|
|
|
|
|
case OpType.Joined:
|
2020-03-27 15:52:34 +08:00
|
|
|
|
await OnJoined(convMessage);
|
2020-03-25 16:42:30 +08:00
|
|
|
|
break;
|
|
|
|
|
case OpType.MembersJoined:
|
2020-03-27 15:52:34 +08:00
|
|
|
|
await OnMembersJoined(convMessage);
|
2020-03-25 16:42:30 +08:00
|
|
|
|
break;
|
|
|
|
|
case OpType.Left:
|
2020-03-27 15:52:34 +08:00
|
|
|
|
await OnLeft(convMessage);
|
2020-03-25 16:42:30 +08:00
|
|
|
|
break;
|
|
|
|
|
case OpType.MembersLeft:
|
2020-03-27 15:52:34 +08:00
|
|
|
|
await OnMemberLeft(convMessage);
|
|
|
|
|
break;
|
|
|
|
|
case OpType.Blocked:
|
|
|
|
|
await OnBlocked(convMessage);
|
|
|
|
|
break;
|
|
|
|
|
case OpType.MembersBlocked:
|
|
|
|
|
await OnMembersBlocked(convMessage);
|
|
|
|
|
break;
|
|
|
|
|
case OpType.MembersUnblocked:
|
|
|
|
|
await OnMembersUnblocked(convMessage);
|
|
|
|
|
break;
|
|
|
|
|
case OpType.Shutuped:
|
|
|
|
|
await OnMuted(convMessage);
|
|
|
|
|
break;
|
|
|
|
|
case OpType.MembersShutuped:
|
|
|
|
|
await OnMembersMuted(convMessage);
|
|
|
|
|
break;
|
|
|
|
|
case OpType.MembersUnshutuped:
|
|
|
|
|
await OnMembersUnmuted(convMessage);
|
2020-03-25 16:42:30 +08:00
|
|
|
|
break;
|
|
|
|
|
case OpType.Updated:
|
2020-03-27 15:52:34 +08:00
|
|
|
|
await OnPropertiesUpdated(convMessage);
|
2020-03-25 16:42:30 +08:00
|
|
|
|
break;
|
|
|
|
|
case OpType.MemberInfoChanged:
|
2020-03-27 15:52:34 +08:00
|
|
|
|
await OnMemberInfoChanged(convMessage);
|
2020-03-25 16:42:30 +08:00
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 15:52:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 当前用户加入会话
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convMessage"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private async Task OnJoined(ConvCommand convMessage) {
|
|
|
|
|
LCIMConversation conversation = await Client.GetOrQueryConversation(convMessage.Cid);
|
|
|
|
|
conversation.MergeFrom(convMessage);
|
|
|
|
|
Client.OnInvited?.Invoke(conversation, convMessage.InitBy);
|
2020-03-25 16:42:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 15:52:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 有用户加入会话
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convMessage"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private async Task OnMembersJoined(ConvCommand convMessage) {
|
|
|
|
|
LCIMConversation conversation = await Client.GetOrQueryConversation(convMessage.Cid);
|
|
|
|
|
ReadOnlyCollection<string> joinedIds = new ReadOnlyCollection<string>(convMessage.M);
|
|
|
|
|
conversation.ids.Union(joinedIds);
|
|
|
|
|
Client.OnMembersJoined?.Invoke(conversation, joinedIds, convMessage.InitBy);
|
2020-03-25 16:42:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 15:52:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 当前用户离开会话
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convMessage"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private async Task OnLeft(ConvCommand convMessage) {
|
|
|
|
|
LCIMConversation conversation = await Client.GetOrQueryConversation(convMessage.Cid);
|
|
|
|
|
Client.OnKicked?.Invoke(conversation, convMessage.InitBy);
|
|
|
|
|
// TODO 从内存中清除对话
|
|
|
|
|
|
2020-03-25 16:42:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 15:52:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 有成员离开会话
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convMessage"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private async Task OnMemberLeft(ConvCommand convMessage) {
|
|
|
|
|
LCIMConversation conversation = await Client.GetOrQueryConversation(convMessage.Cid);
|
|
|
|
|
ReadOnlyCollection<string> leftIdList = new ReadOnlyCollection<string>(convMessage.M);
|
|
|
|
|
conversation.ids.RemoveWhere(item => leftIdList.Contains(item));
|
|
|
|
|
Client.OnMembersLeft?.Invoke(conversation, leftIdList, convMessage.InitBy);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 当前用户被禁言
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convMessage"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private async Task OnMuted(ConvCommand convMessage) {
|
|
|
|
|
LCIMConversation conversation = await Client.GetOrQueryConversation(convMessage.Cid);
|
|
|
|
|
Client.OnMuted?.Invoke(conversation, convMessage.InitBy);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 有成员被禁言
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convMessage"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private async Task OnMembersMuted(ConvCommand convMessage) {
|
|
|
|
|
LCIMConversation conversation = await Client.GetOrQueryConversation(convMessage.Cid);
|
|
|
|
|
ReadOnlyCollection<string> mutedMemberIds = new ReadOnlyCollection<string>(convMessage.M);
|
|
|
|
|
conversation.mutedIds.Union(mutedMemberIds);
|
|
|
|
|
Client.OnMembersMuted?.Invoke(conversation, mutedMemberIds, convMessage.InitBy);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 有成员被解除禁言
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convMessage"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private async Task OnMembersUnmuted(ConvCommand convMessage) {
|
|
|
|
|
LCIMConversation conversation = await Client.GetOrQueryConversation(convMessage.Cid);
|
|
|
|
|
ReadOnlyCollection<string> unmutedMemberIds = new ReadOnlyCollection<string>(convMessage.M);
|
|
|
|
|
conversation.mutedIds.RemoveWhere(id => unmutedMemberIds.Contains(id));
|
|
|
|
|
Client.OnMembersUnmuted?.Invoke(conversation, unmutedMemberIds, convMessage.InitBy);
|
2020-03-25 16:42:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 15:52:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 当前用户被拉黑
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convMessage"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private async Task OnBlocked(ConvCommand convMessage) {
|
|
|
|
|
LCIMConversation conversation = await Client.GetOrQueryConversation(convMessage.Cid);
|
|
|
|
|
Client.OnBlocked?.Invoke(conversation, convMessage.InitBy);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 有用户被拉黑
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convMessage"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private async Task OnMembersBlocked(ConvCommand convMessage) {
|
|
|
|
|
LCIMConversation conversation = await Client.GetOrQueryConversation(convMessage.Cid);
|
|
|
|
|
ReadOnlyCollection<string> blockedMemberIds = convMessage.M.ToList().AsReadOnly();
|
|
|
|
|
Client.OnMembersBlocked?.Invoke(conversation, blockedMemberIds, convMessage.InitBy);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 有用户被移除黑名单
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="convMessage"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private async Task OnMembersUnblocked(ConvCommand convMessage) {
|
|
|
|
|
LCIMConversation conversation = await Client.GetOrQueryConversation(convMessage.Cid);
|
|
|
|
|
ReadOnlyCollection<string> unblockedMemberIds = convMessage.M.ToList().AsReadOnly();
|
|
|
|
|
Client.OnMembersUnblocked?.Invoke(conversation, unblockedMemberIds, convMessage.InitBy);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 对话属性被修改
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="conv"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private async Task OnPropertiesUpdated(ConvCommand conv) {
|
2020-03-25 16:42:30 +08:00
|
|
|
|
LCIMConversation conversation = await Client.GetOrQueryConversation(conv.Cid);
|
|
|
|
|
Dictionary<string, object> updatedAttr = JsonConvert.DeserializeObject<Dictionary<string, object>>(conv.AttrModified.Data,
|
|
|
|
|
new LCJsonConverter());
|
|
|
|
|
// 更新内存数据
|
|
|
|
|
conversation.MergeInfo(updatedAttr);
|
2020-03-27 15:52:34 +08:00
|
|
|
|
Client.OnConversationInfoUpdated?.Invoke(conversation,
|
|
|
|
|
new ReadOnlyDictionary<string, object>(updatedAttr),
|
|
|
|
|
conv.InitBy);
|
2020-03-25 16:42:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 15:52:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 用户角色被修改
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="conv"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private async Task OnMemberInfoChanged(ConvCommand conv) {
|
2020-03-25 16:42:30 +08:00
|
|
|
|
LCIMConversation conversation = await Client.GetOrQueryConversation(conv.Cid);
|
|
|
|
|
ConvMemberInfo memberInfo = conv.Info;
|
|
|
|
|
Client.OnMemberInfoUpdated?.Invoke(conversation, memberInfo.Pid, memberInfo.Role, conv.InitBy);
|
|
|
|
|
}
|
2020-03-27 15:52:34 +08:00
|
|
|
|
|
|
|
|
|
#endregion
|
2020-03-25 16:42:30 +08:00
|
|
|
|
}
|
|
|
|
|
}
|