Compare commits

..
15 Commits
28 changed files with 3294 additions and 314 deletions
+4 -1
View File
@@ -12,7 +12,7 @@
#服务器的接入IP。给客户端提供是${server.ip}和${http_port}。 #服务器的接入IP。给客户端提供是${server.ip}和${http_port}。
#客户端会从${http_port}端口获取到长链接端口。这个地址一定要改成客户端可以访问到的IP地址 #客户端会从${http_port}端口获取到长链接端口。这个地址一定要改成客户端可以访问到的IP地址
#(如果您部署云服务器上或者具有独立公网出口的服务器上,请改为对应的公网IP;如果您部署在在内网环境下,在内网使用,这个地方改成内网地址) #(如果您部署云服务器上或者具有独立公网出口的服务器上,请改为对应的公网IP;如果您部署在在内网环境下,在内网使用,这个地方改成内网地址)
server.ip 192.168.3.124 server.ip 192.168.1.81
##原生客户端长链接端口 ##原生客户端长链接端口
port 1883 port 1883
@@ -320,6 +320,9 @@ push.ios.server.address http://localhost:8085/ios/push
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!! ##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
#message.mentionmsg.forward.url http://localhost:8888/im_event/message #message.mentionmsg.forward.url http://localhost:8888/im_event/message
##撤回消息转发地址,当用户撤回消息会回调此地址。
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
#message.recallmsg.forward.url http://localhost:8888/im_event/recall_message
##设备信息转发地址 ##设备信息转发地址
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!! ##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
+19
View File
@@ -0,0 +1,19 @@
alter table `t_group` add column `_super_group` tinyint NOT NULL DEFAULT 0;
DROP TABLE IF EXISTS `t_group_messages`;
CREATE TABLE `t_group_messages` (
`_mid` bigint(20) NOT NULL PRIMARY KEY,
`_sender` varchar(64) NOT NULL,
`_gid` varchar(64) NOT NULL,
`_line` int(11) NOT NULL,
`_client_id` varchar(64) NULL,
`_seq` bigint(20) NOT NULL,
`_persist_flag` int(11) NOT NULL,
`_mentioned_type` int(11) NOT NULL,
`_mentioned_targets` BLOB NULL,
`_to` BLOB NULL,
`_cont_type` int(11) NOT NULL DEFAULT 0,
`_duration` int(11) NOT NULL DEFAULT 0,
`_dt` bigint(20) NOT NULL DEFAULT 0,
INDEX `group_message_seq_uid_index` (`_gid` DESC, `_line`, `_seq` DESC)
);
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -5,7 +5,7 @@
<relativePath>../</relativePath> <relativePath>../</relativePath>
<artifactId>wildfirechat-parent</artifactId> <artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId> <groupId>cn.wildfirechat</groupId>
<version>1.1.2</version> <version>1.1.3</version>
</parent> </parent>
<artifactId>moquette-broker</artifactId> <artifactId>moquette-broker</artifactId>
@@ -80,6 +80,11 @@ public class IMAction extends Action {
if (userId == null) { if (userId == null) {
sendResponse(response, ErrorCode.ERROR_CODE_TOKEN_ERROR, null); sendResponse(response, ErrorCode.ERROR_CODE_TOKEN_ERROR, null);
} else { } else {
if(messagesStore.getUserStatus(userId) == ProtoConstants.UserStatus.Forbidden) {
sendResponse(response, ErrorCode.ERROR_CODE_USER_BLOCKED, null);
return true;
}
ServerAPIHelper.sendRequest(userId, wrapper.getClientId(), wrapper.getRequest(), wrapper.getData().toByteArray(), new ServerAPIHelper.Callback() { ServerAPIHelper.sendRequest(userId, wrapper.getClientId(), wrapper.getRequest(), wrapper.getData().toByteArray(), new ServerAPIHelper.Callback() {
@Override @Override
public void onSuccess(byte[] result) { public void onSuccess(byte[] result) {
@@ -39,17 +39,10 @@ public class RouteAction extends Action {
@Override @Override
public boolean action(Request request, Response response) { public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) { if (request.getNettyRequest() instanceof FullHttpRequest) {
response.setContentType("application/octet-stream"); response.setContentType("application/octet-stream");
response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Origin", "*");
FullHttpRequest fullHttpRequest = (FullHttpRequest) request.getNettyRequest(); FullHttpRequest fullHttpRequest = (FullHttpRequest) request.getNettyRequest();
boolean b = false;
if ("web".equalsIgnoreCase(fullHttpRequest.headers().get("p"))) {
b = true;
}
final boolean base64Response = b;
byte[] bytes = Utils.readBytesAndRewind(fullHttpRequest.content()); byte[] bytes = Utils.readBytesAndRewind(fullHttpRequest.content());
@@ -57,15 +50,20 @@ public class RouteAction extends Action {
try { try {
bytes = Base64.getDecoder().decode(str); bytes = Base64.getDecoder().decode(str);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
sendResponse(response, ErrorCode.ERROR_CODE_INVALID_DATA, null, base64Response); sendResponse(response, ErrorCode.ERROR_CODE_INVALID_DATA, null);
return true; return true;
} }
String cid = fullHttpRequest.headers().get("cid"); String cid = fullHttpRequest.headers().get("cid");
byte[] cbytes = Base64.getDecoder().decode(cid); byte[] cbytes = Base64.getDecoder().decode(cid);
cbytes = AES.AESDecrypt(cbytes, "", true); boolean[] invalidTime = new boolean[1];
cbytes = AES.AESDecrypt(cbytes, "", true, invalidTime);
if (cbytes == null) { if (cbytes == null) {
sendResponse(response, ErrorCode.ERROR_CODE_INVALID_DATA, null, base64Response); if(invalidTime[0]) {
sendResponse(response, ErrorCode.ERROR_CODE_TIME_INCONSISTENT, null);
} else {
sendResponse(response, ErrorCode.ERROR_CODE_INVALID_DATA, null);
}
return true; return true;
} }
cid = new String(cbytes); cid = new String(cbytes);
@@ -74,7 +72,7 @@ public class RouteAction extends Action {
byte[] ubytes = Base64.getDecoder().decode(uid); byte[] ubytes = Base64.getDecoder().decode(uid);
ubytes = AES.AESDecrypt(ubytes, "", true); ubytes = AES.AESDecrypt(ubytes, "", true);
if (ubytes == null) { if (ubytes == null) {
sendResponse(response, ErrorCode.ERROR_CODE_INVALID_DATA, null, base64Response); sendResponse(response, ErrorCode.ERROR_CODE_INVALID_DATA, null);
return true; return true;
} }
uid = new String(ubytes); uid = new String(ubytes);
@@ -84,7 +82,7 @@ public class RouteAction extends Action {
if (session == null) { if (session == null) {
ErrorCode errorCode = sessionsStore.loadActiveSession(uid, cid); ErrorCode errorCode = sessionsStore.loadActiveSession(uid, cid);
if (errorCode != ErrorCode.ERROR_CODE_SUCCESS) { if (errorCode != ErrorCode.ERROR_CODE_SUCCESS) {
sendResponse(response, errorCode, null, base64Response); sendResponse(response, errorCode, null);
return true; return true;
} }
session = sessionsStore.sessionForClientAndUser(uid, cid); session = sessionsStore.sessionForClientAndUser(uid, cid);
@@ -94,16 +92,20 @@ public class RouteAction extends Action {
if (session != null) { if (session != null) {
bytes = AES.AESDecrypt(bytes, session.getSecret(), true); bytes = AES.AESDecrypt(bytes, session.getSecret(), true);
} else { } else {
sendResponse(response, ErrorCode.ERROR_CODE_SECRECT_KEY_MISMATCH, null, base64Response); sendResponse(response, ErrorCode.ERROR_CODE_SECRECT_KEY_MISMATCH, null);
return true; return true;
} }
if (bytes == null) { if (bytes == null) {
sendResponse(response, ErrorCode.ERROR_CODE_SECRECT_KEY_MISMATCH, null, base64Response); sendResponse(response, ErrorCode.ERROR_CODE_SECRECT_KEY_MISMATCH, null);
return true; return true;
} }
if(messagesStore.getUserStatus(uid) == ProtoConstants.UserStatus.Forbidden) {
sendResponse(response, ErrorCode.ERROR_CODE_USER_BLOCKED, null);
return true;
}
try { try {
WFCMessage.IMHttpWrapper wrapper = WFCMessage.IMHttpWrapper.parseFrom(bytes); WFCMessage.IMHttpWrapper wrapper = WFCMessage.IMHttpWrapper.parseFrom(bytes);
@@ -111,22 +113,22 @@ public class RouteAction extends Action {
String userId = Tokenor.getUserId(token.getBytes()); String userId = Tokenor.getUserId(token.getBytes());
LOG.info("RouteAction token={}, userId={}", token, userId); LOG.info("RouteAction token={}, userId={}", token, userId);
if (userId == null) { if (userId == null) {
sendResponse(response, ErrorCode.ERROR_CODE_TOKEN_ERROR, null, base64Response); sendResponse(response, ErrorCode.ERROR_CODE_TOKEN_ERROR, null);
} else { } else {
ServerAPIHelper.sendRequest(userId, wrapper.getClientId(), wrapper.getRequest(), wrapper.getData().toByteArray(), new ServerAPIHelper.Callback() { ServerAPIHelper.sendRequest(userId, wrapper.getClientId(), wrapper.getRequest(), wrapper.getData().toByteArray(), new ServerAPIHelper.Callback() {
@Override @Override
public void onSuccess(byte[] result) { public void onSuccess(byte[] result) {
sendResponse(response, null, result, base64Response); sendResponse(response, null, result);
} }
@Override @Override
public void onError(ErrorCode errorCode) { public void onError(ErrorCode errorCode) {
sendResponse(response, errorCode, null, base64Response); sendResponse(response, errorCode, null);
} }
@Override @Override
public void onTimeout() { public void onTimeout() {
sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null, base64Response); sendResponse(response, ErrorCode.ERROR_CODE_TIMEOUT, null);
} }
@Override @Override
@@ -139,25 +141,21 @@ public class RouteAction extends Action {
return false; return false;
} }
} catch (InvalidProtocolBufferException e) { } catch (InvalidProtocolBufferException e) {
sendResponse(response, ErrorCode.ERROR_CODE_INVALID_DATA, null, false); sendResponse(response, ErrorCode.ERROR_CODE_INVALID_DATA, null);
} }
} }
return true; return true;
} }
private void sendResponse(Response response, ErrorCode errorCode, byte[] contents, boolean base64Response) { private void sendResponse(Response response, ErrorCode errorCode, byte[] contents) {
response.setStatus(HttpResponseStatus.OK); response.setStatus(HttpResponseStatus.OK);
if (contents == null) { if (contents == null) {
ByteBuf ackPayload = Unpooled.buffer(); ByteBuf ackPayload = Unpooled.buffer();
ackPayload.ensureWritable(1).writeByte(errorCode.getCode()); ackPayload.ensureWritable(1).writeByte(errorCode.getCode());
contents = ackPayload.array(); contents = ackPayload.array();
} }
if (base64Response) {
byte[] base64Data = Base64.getEncoder().encode(contents); response.setContent(contents);
response.setContent(base64Data);
} else {
response.setContent(contents);
}
response.send(); response.send();
} }
} }
@@ -129,7 +129,7 @@ public final class BrokerConstants {
public static final String MESSAGE_Forward_Types = "message.forward.types"; public static final String MESSAGE_Forward_Types = "message.forward.types";
public static final String MESSAGE_Forward_Exclude_Types = "message.forward.exclude_types"; public static final String MESSAGE_Forward_Exclude_Types = "message.forward.exclude_types";
public static final String MESSAGE_MentionMsg_Forward_Url = "message.mentionmsg.forward.url"; public static final String MESSAGE_MentionMsg_Forward_Url = "message.mentionmsg.forward.url";
public static final String MESSAGE_RecallMsg_Forward_Url = "message.recallmsg.forward.url";
public static final String SERVER_MULTI_ENDPOINT = "server.multi_endpoint"; public static final String SERVER_MULTI_ENDPOINT = "server.multi_endpoint";
public static final String SERVER_MULTI_PC_ENDPOINT = "server.multi_pc_endpoint"; public static final String SERVER_MULTI_PC_ENDPOINT = "server.multi_pc_endpoint";
@@ -2411,59 +2411,55 @@ public class DatabaseStore {
} }
void deleteUserStatus(String userId) { void deleteUserStatus(String userId) {
mScheduler.execute(()->{ Connection connection = null;
Connection connection = null; PreparedStatement statement = null;
PreparedStatement statement = null; try {
try { connection = DBUtil.getConnection();
connection = DBUtil.getConnection(); String sql = "delete from t_user_status where _uid = ?";
statement = connection.prepareStatement(sql);
statement.setString(1, userId);
int count = statement.executeUpdate();
LOG.info("Update rows {}", count);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
}
void updateUserStatus(String userId, int status) {
Connection connection = null;
PreparedStatement statement = null;
try {
connection = DBUtil.getConnection();
if (status == 0) {
String sql = "delete from t_user_status where _uid = ?"; String sql = "delete from t_user_status where _uid = ?";
statement = connection.prepareStatement(sql); statement = connection.prepareStatement(sql);
statement.setString(1, userId); statement.setString(1, userId);
int count = statement.executeUpdate(); int count = statement.executeUpdate();
LOG.info("Update rows {}", count); LOG.info("Update rows {}", count);
} catch (SQLException e) { } else {
// TODO Auto-generated catch block String sql = "insert into t_user_status (`_uid`, `_status`, `_dt`) values(?,?,?) ON DUPLICATE KEY UPDATE `_status` = ?";
e.printStackTrace();
Utility.printExecption(LOG, e, RDBS_Exception); statement = connection.prepareStatement(sql);
} finally { int index = 1;
DBUtil.closeDB(connection, statement); statement.setString(index++, userId);
statement.setInt(index++, status);
statement.setLong(index++, System.currentTimeMillis());
statement.setInt(index++, status);
int count = statement.executeUpdate();
LOG.info("Update rows {}", count);
} }
}); } catch (SQLException e) {
} // TODO Auto-generated catch block
e.printStackTrace();
void updateUserStatus(String userId, int status) { Utility.printExecption(LOG, e, RDBS_Exception);
mScheduler.execute(()->{ } finally {
Connection connection = null; DBUtil.closeDB(connection, statement);
PreparedStatement statement = null; }
try {
connection = DBUtil.getConnection();
if (status == 0) {
String sql = "delete from t_user_status where _uid = ?";
statement = connection.prepareStatement(sql);
statement.setString(1, userId);
int count = statement.executeUpdate();
LOG.info("Update rows {}", count);
} else {
String sql = "insert into t_user_status (`_uid`, `_status`, `_dt`) values(?,?,?) ON DUPLICATE KEY UPDATE `_status` = ?";
statement = connection.prepareStatement(sql);
int index = 1;
statement.setString(index++, userId);
statement.setInt(index++, status);
statement.setLong(index++, System.currentTimeMillis());
statement.setInt(index++, status);
int count = statement.executeUpdate();
LOG.info("Update rows {}", count);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
});
} }
int getGeneratedId() { int getGeneratedId() {
@@ -3342,47 +3338,45 @@ public class DatabaseStore {
} }
void updateChannelListener(final String channelId, final String listener, final boolean listen) { void updateChannelListener(final String channelId, final String listener, final boolean listen) {
LOG.info("Database remove channel {}", channelId); LOG.info("updateChannelListener channel {}, listener {}, listen {}", channelId, listener, listen);
mScheduler.execute(()->{ Connection connection = null;
Connection connection = null; PreparedStatement statement = null;
PreparedStatement statement = null; try {
try { connection = DBUtil.getConnection();
connection = DBUtil.getConnection(); String sql;
String sql; if (listen) {
if (listen) { sql = "insert into t_channel_listener (`_cid`" +
sql = "insert into t_channel_listener (`_cid`" + ", `_mid`" +
", `_mid`" + ", `_dt`) values(?, ?, ?)" +
", `_dt`) values(?, ?, ?)" + " ON DUPLICATE KEY UPDATE " +
" ON DUPLICATE KEY UPDATE " + "`_dt` = ?";
"`_dt` = ?"; statement = connection.prepareStatement(sql);
statement = connection.prepareStatement(sql); int index = 1;
int index = 1; statement.setString(index++, channelId);
statement.setString(index++, channelId); statement.setString(index++, listener);
statement.setString(index++, listener); statement.setLong(index++, System.currentTimeMillis());
statement.setLong(index++, System.currentTimeMillis()); statement.setLong(index++, System.currentTimeMillis());
statement.setLong(index++, System.currentTimeMillis());
int count = statement.executeUpdate(); int count = statement.executeUpdate();
LOG.info("Update rows {}", count); LOG.info("Update rows {}", count);
} else { } else {
sql = "delete from t_channel_listener where `_cid`=? and `_mid`=?"; sql = "delete from t_channel_listener where `_cid`=? and `_mid`=?";
statement = connection.prepareStatement(sql); statement = connection.prepareStatement(sql);
int index = 1; int index = 1;
statement.setString(index++, channelId); statement.setString(index++, channelId);
statement.setString(index++, listener); statement.setString(index++, listener);
int count = statement.executeUpdate(); int count = statement.executeUpdate();
LOG.info("Update rows {}", count); LOG.info("Update rows {}", count);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
} }
}); } catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
} }
List<String> getUserChannels(String userId) { List<String> getUserChannels(String userId) {
@@ -174,6 +174,7 @@ public class MemoryMessagesStore implements IMessagesStore {
private int mGroupForbiddenClientOperation; private int mGroupForbiddenClientOperation;
private int mSyncDataPartSize = 0; private int mSyncDataPartSize = 0;
private boolean keepDisplayNameWhenDestroyUser = true; private boolean keepDisplayNameWhenDestroyUser = true;
private String mRecallForwardUrl = null;
private boolean mForwardMessageWithClientInfo = false; private boolean mForwardMessageWithClientInfo = false;
private boolean mRobotCallbackWithClientInfo = false; private boolean mRobotCallbackWithClientInfo = false;
@@ -518,7 +519,11 @@ public class MemoryMessagesStore implements IMessagesStore {
} catch (Exception e) { } catch (Exception e) {
} }
try {
mRecallForwardUrl = server.getConfig().getProperty(BrokerConstants.MESSAGE_RecallMsg_Forward_Url);
} catch (Exception e) {
}
} }
private void printMissConfigLog(String config, String defaultValue) { private void printMissConfigLog(String config, String defaultValue) {
@@ -1627,13 +1632,17 @@ public class MemoryMessagesStore implements IMessagesStore {
return ErrorCode.ERROR_CODE_NOT_RIGHT; return ErrorCode.ERROR_CODE_NOT_RIGHT;
} }
WFCMessage.GroupMember gm = getGroupMember(groupId, operator);
if (gm == null || gm.getType() == GroupMemberType_Removed) {
return ErrorCode.ERROR_CODE_NOT_IN_GROUP;
}
if (oldInfo.getType() == ProtoConstants.GroupType.GroupType_Restricted || oldInfo.getType() == ProtoConstants.GroupType.GroupType_Organization) { if (oldInfo.getType() == ProtoConstants.GroupType.GroupType_Restricted || oldInfo.getType() == ProtoConstants.GroupType.GroupType_Organization) {
boolean isAllow = false; boolean isAllow = false;
if ((oldInfo.getOwner() != null && oldInfo.getOwner().equals(operator))) { if ((oldInfo.getOwner() != null && oldInfo.getOwner().equals(operator))) {
isAllow = true; isAllow = true;
} else { } else {
WFCMessage.GroupMember gm = getGroupMember(groupId, operator); if (gm.getType() == GroupMemberType_Manager) {
if (gm != null && gm.getType() == GroupMemberType_Manager) {
isAllow = true; isAllow = true;
} }
} }
@@ -1644,9 +1653,8 @@ public class MemoryMessagesStore implements IMessagesStore {
if (oldInfo.getType() == ProtoConstants.GroupType.GroupType_Normal) { if (oldInfo.getType() == ProtoConstants.GroupType.GroupType_Normal) {
if (!operator.equals(oldInfo.getOwner())) { if (!operator.equals(oldInfo.getOwner())) {
WFCMessage.GroupMember gm = getGroupMember(groupId, operator);
boolean isManager = false; boolean isManager = false;
if (gm != null && gm.getType() == GroupMemberType_Manager) { if (gm.getType() == GroupMemberType_Manager) {
isManager = true; isManager = true;
} }
if (!isManager && modifyType != Modify_Group_Name && modifyType != Modify_Group_Portrait && modifyType != Modify_Group_Extra) { if (!isManager && modifyType != Modify_Group_Name && modifyType != Modify_Group_Portrait && modifyType != Modify_Group_Extra) {
@@ -1740,12 +1748,12 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
} }
if (operatorMember == null) { if (operatorMember == null || operatorMember.getType() == GroupMemberType_Removed) {
LOG.error("Modify group member alias error, the operator {} is not in group", operator); LOG.error("Modify group member alias error, the operator {} is not in group", operator);
return ErrorCode.ERROR_CODE_NOT_IN_GROUP; return ErrorCode.ERROR_CODE_NOT_IN_GROUP;
} }
if (targetMember == null) { if (targetMember == null || targetMember.getType() == GroupMemberType_Removed) {
LOG.error("Modify group member alias error, the member {} is not in group", memberId); LOG.error("Modify group member alias error, the member {} is not in group", memberId);
return ErrorCode.ERROR_CODE_NOT_IN_GROUP; return ErrorCode.ERROR_CODE_NOT_IN_GROUP;
} }
@@ -2174,9 +2182,10 @@ public class MemoryMessagesStore implements IMessagesStore {
if (isAdmin) { if (isAdmin) {
canRecall = true; canRecall = true;
} }
if (!isAdmin && message.getFromUser().equals(operatorId)) { boolean isExpired = false;
if (!canRecall && message.getFromUser().equals(operatorId)) {
if (now - message.getServerTimestamp() > mRecallTimeLimit * 1000) { if (now - message.getServerTimestamp() > mRecallTimeLimit * 1000) {
return ErrorCode.ERROR_CODE_RECALL_TIME_EXPIRED; isExpired = true;
} else { } else {
canRecall = true; canRecall = true;
} }
@@ -2193,17 +2202,26 @@ public class MemoryMessagesStore implements IMessagesStore {
canRecall = true; canRecall = true;
} }
MultiMap<String, WFCMessage.GroupMember> groupMembers = hzInstance.getMultiMap(GROUP_MEMBERS); if(!canRecall && !message.getFromUser().equals(operatorId)) {
Collection<WFCMessage.GroupMember> members = groupMembers.get(message.getConversation().getTarget()); boolean isOperatorManager = false;
if (members == null || members.size() == 0) { int senderType = GroupMemberType_Normal;
members = loadGroupMemberFromDB(hzInstance, message.getConversation().getTarget()); MultiMap<String, WFCMessage.GroupMember> groupMembers = hzInstance.getMultiMap(GROUP_MEMBERS);
} Collection<WFCMessage.GroupMember> members = groupMembers.get(message.getConversation().getTarget());
for (WFCMessage.GroupMember member : members) { if (members == null || members.size() == 0) {
if (member.getMemberId().equals(operatorId)) { members = loadGroupMemberFromDB(hzInstance, message.getConversation().getTarget());
if (member.getType() == GroupMemberType_Manager || member.getType() == ProtoConstants.GroupMemberType.GroupMemberType_Owner) { }
canRecall = true; for (WFCMessage.GroupMember member : members) {
if (member.getMemberId().equals(operatorId)) {
if (member.getType() == GroupMemberType_Manager || member.getType() == ProtoConstants.GroupMemberType.GroupMemberType_Owner) {
isOperatorManager = true;
}
} }
break; if(member.getMemberId().equals(message.getFromUser())) {
senderType = member.getType();
}
}
if(isOperatorManager && senderType != GroupMemberType_Manager && senderType != GroupMemberType_Owner) {
canRecall = true;
} }
} }
} }
@@ -2215,13 +2233,30 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
if (!canRecall) { if (!canRecall) {
return ErrorCode.ERROR_CODE_NOT_RIGHT; if(isExpired) {
return ErrorCode.ERROR_CODE_RECALL_TIME_EXPIRED;
} else {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
} }
if(message.getContent().getType() == 80) { if(message.getContent().getType() == 80) {
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
if(!StringUtil.isNullOrEmpty(mRecallForwardUrl)) {
OutputRecallMessageData event = new OutputRecallMessageData(OutputMessageData.fromProtoMessage(message, null), operatorId, System.currentTimeMillis(), isAdmin);
m_Server.getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(mRecallForwardUrl, GsonUtil.gson.toJson(event), HttpUtils.HttpPostType.POST_TYPE_Forward_Recall_Callback);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
}
});
}
JSONObject json = new JSONObject(); JSONObject json = new JSONObject();
json.put("s", message.getFromUser()); json.put("s", message.getFromUser());
json.put("ts", message.getServerTimestamp()); json.put("ts", message.getServerTimestamp());
@@ -3175,7 +3210,7 @@ public class MemoryMessagesStore implements IMessagesStore {
friendsMap.remove(userId); friendsMap.remove(userId);
friendsMap.remove(request.getTargetUid()); friendsMap.remove(request.getTargetUid());
callbackRelationEvent(userId, request.getTargetUid(), 0, "" + request.getStatus()); callbackRelationEvent(userId, request.getTargetUid(), 0, request.getStatus() == 0?"1":"0");
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -108,7 +108,7 @@ public class ProtocolProcessor {
ConnectionDescriptor descriptor = connectionDescriptors.getConnection(session.getClientID()); ConnectionDescriptor descriptor = connectionDescriptors.getConnection(session.getClientID());
try { try {
if (descriptor != null) { if (descriptor != null) {
processDisconnect(descriptor.getChannel(), true, false); processDisconnect(descriptor.getChannel(), false, false);
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
@@ -608,8 +608,9 @@ public class ProtocolProcessor {
channel.closeFuture(); channel.closeFuture();
//disconnect the session //disconnect the session
if(session != null) {
m_sessionsStore.sessionForClient(clientID).disconnect(session.getUsername(), isDup, isRetain); m_sessionsStore.sessionForClient(clientID).disconnect(session.getUsername(), isDup, isRetain);
}
} }
@@ -650,12 +651,22 @@ public class ProtocolProcessor {
if(connectionDescriptors.removeConnection(oldConnDescr)) { if(connectionDescriptors.removeConnection(oldConnDescr)) {
m_interceptor.notifyClientConnectionLost(clientID, username); m_interceptor.notifyClientConnectionLost(clientID, username);
} }
try {
channel.close();
} catch (Exception e) {
e.printStackTrace();
}
}); });
} else { } else {
ConnectionDescriptor oldConnDescr = new ConnectionDescriptor(clientID, channel); ConnectionDescriptor oldConnDescr = new ConnectionDescriptor(clientID, channel);
if(connectionDescriptors.removeConnection(oldConnDescr)) { if(connectionDescriptors.removeConnection(oldConnDescr)) {
m_interceptor.notifyClientConnectionLost(clientID, username); m_interceptor.notifyClientConnectionLost(clientID, username);
} }
try {
channel.close();
} catch (Exception e) {
e.printStackTrace();
}
} }
} }
@@ -252,6 +252,13 @@ public class Qos1PublishHandler extends QosPublishHandler {
MemorySessionStore.Session session = m_sessionStore.getSession(clientID); MemorySessionStore.Session session = m_sessionStore.getSession(clientID);
payloadContent = AES.AESDecrypt(payloadContent, session.getSecret(), true); payloadContent = AES.AESDecrypt(payloadContent, session.getSecret(), true);
if(payloadContent == null) {
ByteBuf ackPayload = Unpooled.buffer();
ackPayload.ensureWritable(1).writeByte(ERROR_CODE_INVALID_DATA.getCode());
sendPubAck(clientID, messageID, ackPayload, ERROR_CODE_INVALID_DATA);
return;
}
imHandler(clientID, username, imtopic, payloadContent, (errorCode, ackPayload) -> sendPubAck(clientID, messageID, ackPayload, errorCode), ProtoConstants.RequestSourceType.Request_From_User); imHandler(clientID, username, imtopic, payloadContent, (errorCode, ackPayload) -> sendPubAck(clientID, messageID, ackPayload, errorCode), ProtoConstants.RequestSourceType.Request_From_User);
} }
@@ -50,7 +50,8 @@ public class HttpUtils {
POST_TYPE_Channel_Message_Callback, POST_TYPE_Channel_Message_Callback,
POST_TYPE_Forward_Message_Callback, POST_TYPE_Forward_Message_Callback,
POST_TYPE_User_Online_Event_Callback, POST_TYPE_User_Online_Event_Callback,
POST_TYPE_Server_Exception_Callback; POST_TYPE_Server_Exception_Callback,
POST_TYPE_Forward_Recall_Callback;
} }
public static void httpJsonPost(String url, String jsonStr, HttpPostType postType) { public static void httpJsonPost(String url, String jsonStr, HttpPostType postType) {
+1 -1
View File
@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>wildfirechat-parent</artifactId> <artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId> <groupId>cn.wildfirechat</groupId>
<version>1.1.2</version> <version>1.1.3</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@@ -48,6 +48,9 @@ public enum ErrorCode {
ERROR_CODE_NOT_YOUR_LOCKED(26, "unload failure, not your lock"), ERROR_CODE_NOT_YOUR_LOCKED(26, "unload failure, not your lock"),
ERROR_CODE_ROBOT_NO_TOKEN(27, "robot no token"), ERROR_CODE_ROBOT_NO_TOKEN(27, "robot no token"),
ERROR_CODE_WS_NOT_CONFIGURED_CORRECTLY(28, "ws not configured correctly"), ERROR_CODE_WS_NOT_CONFIGURED_CORRECTLY(28, "ws not configured correctly"),
ERROR_CODE_TIME_INCONSISTENT(30, "time inconsistent"),
ERROR_CODE_CONFERENCE_ROOM_NOT_EXIST(60, "conference room not exist"), ERROR_CODE_CONFERENCE_ROOM_NOT_EXIST(60, "conference room not exist"),
ERROR_CODE_CONFERENCE_SERVICE_NOT_AVAILABLE(61, "conference service not available"), ERROR_CODE_CONFERENCE_SERVICE_NOT_AVAILABLE(61, "conference service not available"),
@@ -74,7 +77,7 @@ public enum ErrorCode {
ERROR_CODE_SENSITIVE_MATCHED(242, "sensitive matched"), ERROR_CODE_SENSITIVE_MATCHED(242, "sensitive matched"),
ERROR_CODE_SIGN_EXPIRED(243, "sign expired"), ERROR_CODE_SIGN_EXPIRED(243, "sign expired"),
ERROR_CODE_AUTH_FAILURE(244, "auth failure"), ERROR_CODE_AUTH_FAILURE(244, "auth failure"),
ERROR_CODE_CLIENT_COUNT_OUT_OF_LIMIT(245, "client count out of limit"), ERROR_CODE_USER_BLOCKED(245, "user is blocked"),
ERROR_CODE_IN_BLACK_LIST(246, "user in black list"), ERROR_CODE_IN_BLACK_LIST(246, "user in black list"),
ERROR_CODE_FORBIDDEN_SEND_MSG(247, "forbidden send msg globally"), ERROR_CODE_FORBIDDEN_SEND_MSG(247, "forbidden send msg globally"),
ERROR_CODE_NOT_RIGHT(248, "no right to operate"), ERROR_CODE_NOT_RIGHT(248, "no right to operate"),
@@ -65,6 +65,9 @@ public class InputCreateGroup extends InputGroupBase {
if(group_info.max_member_count > 0) { if(group_info.max_member_count > 0) {
groupInfoBuilder.setMaxMemberCount(group_info.max_member_count); groupInfoBuilder.setMaxMemberCount(group_info.max_member_count);
} }
if(group_info.isSuper_group()) {
groupInfoBuilder.setSuperGroup(1);
}
groupBuilder.setGroupInfo(groupInfoBuilder); groupBuilder.setGroupInfo(groupInfoBuilder);
if(group.getMembers() != null) { if(group.getMembers() != null) {
@@ -0,0 +1,58 @@
/*
* This file is part of the Wildfire Chat package.
* (c) Heavyrain2012 <heavyrain.lee@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
package cn.wildfirechat.pojos;
public class OutputRecallMessageData {
private OutputMessageData message;
private String userId;
private long timestamp;
private boolean isAdmin;
public OutputRecallMessageData() {
}
public OutputRecallMessageData(OutputMessageData message, String userId, long timestamp, boolean isAdmin) {
this.message = message;
this.userId = userId;
this.timestamp = timestamp;
this.isAdmin = isAdmin;
}
public OutputMessageData getMessage() {
return message;
}
public void setMessage(OutputMessageData message) {
this.message = message;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public boolean isAdmin() {
return isAdmin;
}
public void setAdmin(boolean admin) {
isAdmin = admin;
}
}
@@ -21,6 +21,7 @@ public class PojoGroupInfo {
int searchable; int searchable;
int max_member_count; int max_member_count;
int history_message; int history_message;
boolean super_group;
public String getTarget_id() { public String getTarget_id() {
return target_id; return target_id;
@@ -117,4 +118,12 @@ public class PojoGroupInfo {
public void setHistory_message(int history_message) { public void setHistory_message(int history_message) {
this.history_message = history_message; this.history_message = history_message;
} }
public boolean isSuper_group() {
return super_group;
}
public void setSuper_group(boolean super_group) {
this.super_group = super_group;
}
} }
@@ -9,6 +9,7 @@ public class ProtoConstants {
int ConversationType_ChatRoom = 2; int ConversationType_ChatRoom = 2;
int ConversationType_Channel = 3; int ConversationType_Channel = 3;
int ConversationType_Things = 4; int ConversationType_Things = 4;
int ConversationType_SecretChat = 5;
} }
//message GroupInfo -> type //message GroupInfo -> type
@@ -1641,6 +1641,16 @@ public final class WFCMessage {
* <code>optional int32 history_message = 15;</code> * <code>optional int32 history_message = 15;</code>
*/ */
int getHistoryMessage(); int getHistoryMessage();
// optional int32 super_group = 16;
/**
* <code>optional int32 super_group = 16;</code>
*/
boolean hasSuperGroup();
/**
* <code>optional int32 super_group = 16;</code>
*/
int getSuperGroup();
} }
/** /**
* Protobuf type {@code GroupInfo} * Protobuf type {@code GroupInfo}
@@ -1768,6 +1778,11 @@ public final class WFCMessage {
historyMessage_ = input.readInt32(); historyMessage_ = input.readInt32();
break; break;
} }
case 128: {
bitField0_ |= 0x00008000;
superGroup_ = input.readInt32();
break;
}
} }
} }
} catch (com.google.protobuf.InvalidProtocolBufferException e) { } catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -2183,6 +2198,22 @@ public final class WFCMessage {
return historyMessage_; return historyMessage_;
} }
// optional int32 super_group = 16;
public static final int SUPER_GROUP_FIELD_NUMBER = 16;
private int superGroup_;
/**
* <code>optional int32 super_group = 16;</code>
*/
public boolean hasSuperGroup() {
return ((bitField0_ & 0x00008000) == 0x00008000);
}
/**
* <code>optional int32 super_group = 16;</code>
*/
public int getSuperGroup() {
return superGroup_;
}
private void initFields() { private void initFields() {
targetId_ = ""; targetId_ = "";
name_ = ""; name_ = "";
@@ -2199,6 +2230,7 @@ public final class WFCMessage {
searchable_ = 0; searchable_ = 0;
maxMemberCount_ = 0; maxMemberCount_ = 0;
historyMessage_ = 0; historyMessage_ = 0;
superGroup_ = 0;
} }
private byte memoizedIsInitialized = -1; private byte memoizedIsInitialized = -1;
public final boolean isInitialized() { public final boolean isInitialized() {
@@ -2265,6 +2297,9 @@ public final class WFCMessage {
if (((bitField0_ & 0x00004000) == 0x00004000)) { if (((bitField0_ & 0x00004000) == 0x00004000)) {
output.writeInt32(15, historyMessage_); output.writeInt32(15, historyMessage_);
} }
if (((bitField0_ & 0x00008000) == 0x00008000)) {
output.writeInt32(16, superGroup_);
}
getUnknownFields().writeTo(output); getUnknownFields().writeTo(output);
} }
@@ -2334,6 +2369,10 @@ public final class WFCMessage {
size += com.google.protobuf.CodedOutputStream size += com.google.protobuf.CodedOutputStream
.computeInt32Size(15, historyMessage_); .computeInt32Size(15, historyMessage_);
} }
if (((bitField0_ & 0x00008000) == 0x00008000)) {
size += com.google.protobuf.CodedOutputStream
.computeInt32Size(16, superGroup_);
}
size += getUnknownFields().getSerializedSize(); size += getUnknownFields().getSerializedSize();
memoizedSerializedSize = size; memoizedSerializedSize = size;
return size; return size;
@@ -2480,6 +2519,8 @@ public final class WFCMessage {
bitField0_ = (bitField0_ & ~0x00002000); bitField0_ = (bitField0_ & ~0x00002000);
historyMessage_ = 0; historyMessage_ = 0;
bitField0_ = (bitField0_ & ~0x00004000); bitField0_ = (bitField0_ & ~0x00004000);
superGroup_ = 0;
bitField0_ = (bitField0_ & ~0x00008000);
return this; return this;
} }
@@ -2568,6 +2609,10 @@ public final class WFCMessage {
to_bitField0_ |= 0x00004000; to_bitField0_ |= 0x00004000;
} }
result.historyMessage_ = historyMessage_; result.historyMessage_ = historyMessage_;
if (((from_bitField0_ & 0x00008000) == 0x00008000)) {
to_bitField0_ |= 0x00008000;
}
result.superGroup_ = superGroup_;
result.bitField0_ = to_bitField0_; result.bitField0_ = to_bitField0_;
onBuilt(); onBuilt();
return result; return result;
@@ -2639,6 +2684,9 @@ public final class WFCMessage {
if (other.hasHistoryMessage()) { if (other.hasHistoryMessage()) {
setHistoryMessage(other.getHistoryMessage()); setHistoryMessage(other.getHistoryMessage());
} }
if (other.hasSuperGroup()) {
setSuperGroup(other.getSuperGroup());
}
this.mergeUnknownFields(other.getUnknownFields()); this.mergeUnknownFields(other.getUnknownFields());
return this; return this;
} }
@@ -3374,6 +3422,39 @@ public final class WFCMessage {
return this; return this;
} }
// optional int32 super_group = 16;
private int superGroup_ ;
/**
* <code>optional int32 super_group = 16;</code>
*/
public boolean hasSuperGroup() {
return ((bitField0_ & 0x00008000) == 0x00008000);
}
/**
* <code>optional int32 super_group = 16;</code>
*/
public int getSuperGroup() {
return superGroup_;
}
/**
* <code>optional int32 super_group = 16;</code>
*/
public Builder setSuperGroup(int value) {
bitField0_ |= 0x00008000;
superGroup_ = value;
onChanged();
return this;
}
/**
* <code>optional int32 super_group = 16;</code>
*/
public Builder clearSuperGroup() {
bitField0_ = (bitField0_ & ~0x00008000);
superGroup_ = 0;
onChanged();
return this;
}
// @@protoc_insertion_point(builder_scope:GroupInfo) // @@protoc_insertion_point(builder_scope:GroupInfo)
} }
@@ -67224,179 +67305,180 @@ public final class WFCMessage {
"dRequest\022\022\n\ntarget_uid\030\001 \002(\t\022\016\n\006reason\030\002" + "dRequest\022\022\n\ntarget_uid\030\001 \002(\t\022\016\n\006reason\030\002" +
" \002(\t\022\r\n\005extra\030\003 \001(\t\":\n\014Conversation\022\014\n\004t" + " \002(\t\022\r\n\005extra\030\003 \001(\t\":\n\014Conversation\022\014\n\004t" +
"ype\030\001 \002(\005\022\016\n\006target\030\002 \002(\t\022\014\n\004line\030\003 \002(\005\"" + "ype\030\001 \002(\005\022\016\n\006target\030\002 \002(\t\022\014\n\004line\030\003 \002(\005\"" +
"\253\002\n\tGroupInfo\022\021\n\ttarget_id\030\001 \001(\t\022\014\n\004name" + "\300\002\n\tGroupInfo\022\021\n\ttarget_id\030\001 \001(\t\022\014\n\004name" +
"\030\002 \002(\t\022\020\n\010portrait\030\003 \001(\t\022\r\n\005owner\030\004 \001(\t\022" + "\030\002 \002(\t\022\020\n\010portrait\030\003 \001(\t\022\r\n\005owner\030\004 \001(\t\022" +
"\014\n\004type\030\005 \002(\005\022\024\n\014member_count\030\006 \001(\005\022\r\n\005e" + "\014\n\004type\030\005 \002(\005\022\024\n\014member_count\030\006 \001(\005\022\r\n\005e" +
"xtra\030\007 \001(\t\022\021\n\tupdate_dt\030\010 \001(\003\022\030\n\020member_" + "xtra\030\007 \001(\t\022\021\n\tupdate_dt\030\010 \001(\003\022\030\n\020member_" +
"update_dt\030\t \001(\003\022\014\n\004mute\030\n \001(\005\022\021\n\tjoin_ty" + "update_dt\030\t \001(\003\022\014\n\004mute\030\n \001(\005\022\021\n\tjoin_ty" +
"pe\030\013 \001(\005\022\024\n\014private_chat\030\014 \001(\005\022\022\n\nsearch", "pe\030\013 \001(\005\022\024\n\014private_chat\030\014 \001(\005\022\022\n\nsearch",
"able\030\r \001(\005\022\030\n\020max_member_count\030\016 \001(\005\022\027\n\017" + "able\030\r \001(\005\022\030\n\020max_member_count\030\016 \001(\005\022\027\n\017" +
"history_message\030\017 \001(\005\"r\n\013GroupMember\022\021\n\t" + "history_message\030\017 \001(\005\022\023\n\013super_group\030\020 \001" +
"member_id\030\001 \002(\t\022\r\n\005alias\030\002 \001(\t\022\014\n\004type\030\003" + "(\005\"r\n\013GroupMember\022\021\n\tmember_id\030\001 \002(\t\022\r\n\005" +
" \002(\005\022\021\n\tupdate_dt\030\004 \001(\003\022\021\n\tcreate_dt\030\005 \001" + "alias\030\002 \001(\t\022\014\n\004type\030\003 \002(\005\022\021\n\tupdate_dt\030\004" +
"(\003\022\r\n\005extra\030\006 \001(\t\"F\n\005Group\022\036\n\ngroup_info" + " \001(\003\022\021\n\tcreate_dt\030\005 \001(\003\022\r\n\005extra\030\006 \001(\t\"F" +
"\030\001 \002(\0132\n.GroupInfo\022\035\n\007members\030\002 \003(\0132\014.Gr" + "\n\005Group\022\036\n\ngroup_info\030\001 \002(\0132\n.GroupInfo\022" +
"oupMember\"\313\001\n\013ChannelMenu\022\014\n\004type\030\001 \002(\t\022" + "\035\n\007members\030\002 \003(\0132\014.GroupMember\"\313\001\n\013Chann" +
"\014\n\004name\030\002 \002(\t\022\013\n\003key\030\003 \001(\t\022\013\n\003url\030\004 \001(\t\022" + "elMenu\022\014\n\004type\030\001 \002(\t\022\014\n\004name\030\002 \002(\t\022\013\n\003ke" +
"\020\n\010media_id\030\005 \001(\t\022\022\n\narticle_id\030\006 \001(\t\022\016\n" + "y\030\003 \001(\t\022\013\n\003url\030\004 \001(\t\022\020\n\010media_id\030\005 \001(\t\022\022" +
"\006app_id\030\007 \001(\t\022\020\n\010app_page\030\010 \001(\t\022\036\n\010sub_m", "\n\narticle_id\030\006 \001(\t\022\016\n\006app_id\030\007 \001(\t\022\020\n\010ap",
"enu\030\t \003(\0132\014.ChannelMenu\022\017\n\007menu_id\030\n \001(\t" + "p_page\030\010 \001(\t\022\036\n\010sub_menu\030\t \003(\0132\014.Channel" +
"\022\r\n\005extra\030\013 \001(\t\"-\n\017ChannelMenuList\022\032\n\004me" + "Menu\022\017\n\007menu_id\030\n \001(\t\022\r\n\005extra\030\013 \001(\t\"-\n\017" +
"nu\030\001 \003(\0132\014.ChannelMenu\"\340\001\n\013ChannelInfo\022\021" + "ChannelMenuList\022\032\n\004menu\030\001 \003(\0132\014.ChannelM" +
"\n\ttarget_id\030\001 \001(\t\022\014\n\004name\030\002 \002(\t\022\020\n\010portr" + "enu\"\340\001\n\013ChannelInfo\022\021\n\ttarget_id\030\001 \001(\t\022\014" +
"ait\030\003 \001(\t\022\r\n\005owner\030\004 \001(\t\022\016\n\006status\030\005 \001(\005" + "\n\004name\030\002 \002(\t\022\020\n\010portrait\030\003 \001(\t\022\r\n\005owner\030" +
"\022\014\n\004desc\030\006 \001(\t\022\r\n\005extra\030\007 \001(\t\022\021\n\tupdate_" + "\004 \001(\t\022\016\n\006status\030\005 \001(\005\022\014\n\004desc\030\006 \001(\t\022\r\n\005e" +
"dt\030\010 \001(\003\022\016\n\006secret\030\t \001(\t\022\020\n\010callback\030\n \001" + "xtra\030\007 \001(\t\022\021\n\tupdate_dt\030\010 \001(\003\022\016\n\006secret\030" +
"(\t\022\021\n\tautomatic\030\013 \001(\005\022\032\n\004menu\030\014 \003(\0132\014.Ch" + "\t \001(\t\022\020\n\010callback\030\n \001(\t\022\021\n\tautomatic\030\013 \001" +
"annelMenu\"D\n\021ModifyChannelInfo\022\022\n\nchanne" + "(\005\022\032\n\004menu\030\014 \003(\0132\014.ChannelMenu\"D\n\021Modify" +
"l_id\030\001 \002(\t\022\014\n\004type\030\002 \002(\005\022\r\n\005value\030\003 \002(\t\"", "ChannelInfo\022\022\n\nchannel_id\030\001 \002(\t\022\014\n\004type\030",
"8\n\017TransferChannel\022\022\n\nchannel_id\030\001 \002(\t\022\021" + "\002 \002(\005\022\r\n\005value\030\003 \002(\t\"8\n\017TransferChannel\022" +
"\n\tnew_owner\030\002 \002(\t\"3\n\017PullChannelInfo\022\022\n\n" + "\022\n\nchannel_id\030\001 \002(\t\022\021\n\tnew_owner\030\002 \002(\t\"3" +
"channel_id\030\001 \002(\t\022\014\n\004head\030\002 \002(\003\"H\n\023PullCh" + "\n\017PullChannelInfo\022\022\n\nchannel_id\030\001 \002(\t\022\014\n" +
"annelListener\022\022\n\nchannel_id\030\001 \002(\t\022\016\n\006off" + "\004head\030\002 \002(\003\"H\n\023PullChannelListener\022\022\n\nch" +
"set\030\002 \002(\005\022\r\n\005count\030\003 \002(\005\"R\n\031PullChannelL" + "annel_id\030\001 \002(\t\022\016\n\006offset\030\002 \002(\005\022\r\n\005count\030" +
"istenerResult\022\023\n\013total_count\030\001 \002(\005\022\016\n\006of" + "\003 \002(\005\"R\n\031PullChannelListenerResult\022\023\n\013to" +
"fset\030\002 \002(\005\022\020\n\010listener\030\003 \003(\t\"3\n\rListenCh" + "tal_count\030\001 \002(\005\022\016\n\006offset\030\002 \002(\005\022\020\n\010liste" +
"annel\022\022\n\nchannel_id\030\001 \002(\t\022\016\n\006listen\030\002 \002(" + "ner\030\003 \003(\t\"3\n\rListenChannel\022\022\n\nchannel_id" +
"\005\"E\n\023SearchChannelResult\022\035\n\007channel\030\001 \003(" + "\030\001 \002(\t\022\016\n\006listen\030\002 \002(\005\"E\n\023SearchChannelR" +
"\0132\014.ChannelInfo\022\017\n\007keyword\030\002 \002(\t\"\235\002\n\016Mes", "esult\022\035\n\007channel\030\001 \003(\0132\014.ChannelInfo\022\017\n\007",
"sageContent\022\014\n\004type\030\001 \002(\005\022\032\n\022searchable_" + "keyword\030\002 \002(\t\"\235\002\n\016MessageContent\022\014\n\004type" +
"content\030\002 \001(\t\022\024\n\014push_content\030\003 \001(\t\022\017\n\007c" + "\030\001 \002(\005\022\032\n\022searchable_content\030\002 \001(\t\022\024\n\014pu" +
"ontent\030\004 \001(\t\022\014\n\004data\030\005 \001(\014\022\021\n\tmediaType\030" + "sh_content\030\003 \001(\t\022\017\n\007content\030\004 \001(\t\022\014\n\004dat" +
"\006 \001(\005\022\026\n\016remoteMediaUrl\030\007 \001(\t\022\024\n\014persist" + "a\030\005 \001(\014\022\021\n\tmediaType\030\006 \001(\005\022\026\n\016remoteMedi" +
"_flag\030\010 \001(\005\022\027\n\017expire_duration\030\t \001(\005\022\026\n\016" + "aUrl\030\007 \001(\t\022\024\n\014persist_flag\030\010 \001(\005\022\027\n\017expi" +
"mentioned_type\030\n \001(\005\022\030\n\020mentioned_target" + "re_duration\030\t \001(\005\022\026\n\016mentioned_type\030\n \001(" +
"\030\013 \003(\t\022\r\n\005extra\030\014 \001(\t\022\021\n\tpush_data\030\r \001(\t" + "\005\022\030\n\020mentioned_target\030\013 \003(\t\022\r\n\005extra\030\014 \001" +
"\"\226\001\n\025AddGroupMemberRequest\022\020\n\010group_id\030\001" + "(\t\022\021\n\tpush_data\030\r \001(\t\"\226\001\n\025AddGroupMember" +
" \002(\t\022\"\n\014added_member\030\002 \003(\0132\014.GroupMember" + "Request\022\020\n\010group_id\030\001 \002(\t\022\"\n\014added_membe" +
"\022\017\n\007to_line\030\003 \003(\005\022\'\n\016notify_content\030\004 \001(", "r\030\002 \003(\0132\014.GroupMember\022\017\n\007to_line\030\003 \003(\005\022\'",
"\0132\017.MessageContent\022\r\n\005extra\030\005 \001(\t\"{\n\022Cre" + "\n\016notify_content\030\004 \001(\0132\017.MessageContent\022" +
"ateGroupRequest\022\025\n\005group\030\001 \002(\0132\006.Group\022\017" + "\r\n\005extra\030\005 \001(\t\"{\n\022CreateGroupRequest\022\025\n\005" +
"\n\007to_line\030\002 \003(\005\022\'\n\016notify_content\030\003 \001(\0132" + "group\030\001 \002(\0132\006.Group\022\017\n\007to_line\030\002 \003(\005\022\'\n\016" +
"\017.MessageContent\022\024\n\014member_extra\030\004 \001(\t\"a" + "notify_content\030\003 \001(\0132\017.MessageContent\022\024\n" +
"\n\023DismissGroupRequest\022\020\n\010group_id\030\001 \002(\t\022" + "\014member_extra\030\004 \001(\t\"a\n\023DismissGroupReque" +
"\017\n\007to_line\030\002 \003(\005\022\'\n\016notify_content\030\003 \001(\013" + "st\022\020\n\010group_id\030\001 \002(\t\022\017\n\007to_line\030\002 \003(\005\022\'\n" +
"2\017.MessageContent\"\245\001\n\rFriendRequest\022\020\n\010f" + "\016notify_content\030\003 \001(\0132\017.MessageContent\"\245" +
"rom_uid\030\001 \001(\t\022\016\n\006to_uid\030\002 \002(\t\022\016\n\006reason\030" + "\001\n\rFriendRequest\022\020\n\010from_uid\030\001 \001(\t\022\016\n\006to" +
"\003 \002(\t\022\016\n\006status\030\004 \001(\005\022\021\n\tupdate_dt\030\005 \001(\003" + "_uid\030\002 \002(\t\022\016\n\006reason\030\003 \002(\t\022\016\n\006status\030\004 \001" +
"\022\030\n\020from_read_status\030\006 \001(\010\022\026\n\016to_read_st", "(\005\022\021\n\tupdate_dt\030\005 \001(\003\022\030\n\020from_read_statu",
"atus\030\007 \001(\010\022\r\n\005extra\030\010 \001(\t\"#\n\rGeneralResu" + "s\030\006 \001(\010\022\026\n\016to_read_status\030\007 \001(\010\022\r\n\005extra" +
"lt\022\022\n\nerror_code\030\001 \002(\005\"?\n\025GetUploadToken" + "\030\010 \001(\t\"#\n\rGeneralResult\022\022\n\nerror_code\030\001 " +
"Request\022\022\n\nmedia_type\030\001 \002(\005\022\022\n\nmedia_pat" + "\002(\005\"?\n\025GetUploadTokenRequest\022\022\n\nmedia_ty" +
"h\030\002 \002(\t\"S\n\024GetUploadTokenResult\022\016\n\006domai" + "pe\030\001 \002(\005\022\022\n\nmedia_path\030\002 \002(\t\"S\n\024GetUploa" +
"n\030\001 \002(\t\022\r\n\005token\030\002 \002(\t\022\016\n\006server\030\003 \002(\t\022\014" + "dTokenResult\022\016\n\006domain\030\001 \002(\t\022\r\n\005token\030\002 " +
"\n\004port\030\004 \001(\005\"H\n\023HandleFriendRequest\022\022\n\nt" + "\002(\t\022\016\n\006server\030\003 \002(\t\022\014\n\004port\030\004 \001(\005\"H\n\023Han" +
"arget_uid\030\001 \002(\t\022\016\n\006status\030\002 \002(\005\022\r\n\005extra" + "dleFriendRequest\022\022\n\ntarget_uid\030\001 \002(\t\022\016\n\006" +
"\030\003 \001(\t\"\023\n\005IDBuf\022\n\n\002id\030\001 \002(\t\"\027\n\tIDListBuf" + "status\030\002 \002(\005\022\r\n\005extra\030\003 \001(\t\"\023\n\005IDBuf\022\n\n\002" +
"\022\n\n\002id\030\001 \003(\t\"\256\001\n\007Message\022#\n\014conversation" + "id\030\001 \002(\t\"\027\n\tIDListBuf\022\n\n\002id\030\001 \003(\t\"\256\001\n\007Me" +
"\030\001 \002(\0132\r.Conversation\022\021\n\tfrom_user\030\002 \002(\t", "ssage\022#\n\014conversation\030\001 \002(\0132\r.Conversati",
"\022 \n\007content\030\003 \002(\0132\017.MessageContent\022\022\n\nme" + "on\022\021\n\tfrom_user\030\002 \002(\t\022 \n\007content\030\003 \002(\0132\017" +
"ssage_id\030\004 \001(\003\022\030\n\020server_timestamp\030\005 \001(\003" + ".MessageContent\022\022\n\nmessage_id\030\004 \001(\003\022\030\n\020s" +
"\022\017\n\007to_user\030\006 \001(\t\022\n\n\002to\030\007 \003(\t\"\353\001\n\004User\022\013" + "erver_timestamp\030\005 \001(\003\022\017\n\007to_user\030\006 \001(\t\022\n" +
"\n\003uid\030\001 \002(\t\022\014\n\004name\030\002 \001(\t\022\024\n\014display_nam" + "\n\002to\030\007 \003(\t\"\353\001\n\004User\022\013\n\003uid\030\001 \002(\t\022\014\n\004name" +
"e\030\003 \001(\t\022\020\n\010portrait\030\004 \001(\t\022\016\n\006mobile\030\005 \001(" + "\030\002 \001(\t\022\024\n\014display_name\030\003 \001(\t\022\020\n\010portrait" +
"\t\022\r\n\005email\030\006 \001(\t\022\017\n\007address\030\007 \001(\t\022\017\n\007com" + "\030\004 \001(\t\022\016\n\006mobile\030\005 \001(\t\022\r\n\005email\030\006 \001(\t\022\017\n" +
"pany\030\010 \001(\t\022\r\n\005extra\030\t \001(\t\022\021\n\tupdate_dt\030\n" + "\007address\030\007 \001(\t\022\017\n\007company\030\010 \001(\t\022\r\n\005extra" +
" \001(\003\022\016\n\006gender\030\013 \001(\005\022\016\n\006social\030\014 \001(\t\022\014\n\004" + "\030\t \001(\t\022\021\n\tupdate_dt\030\n \001(\003\022\016\n\006gender\030\013 \001(" +
"type\030\r \001(\005\022\017\n\007deleted\030\016 \001(\005\"c\n\005Robot\022\013\n\003" + "\005\022\016\n\006social\030\014 \001(\t\022\014\n\004type\030\r \001(\005\022\017\n\007delet" +
"uid\030\001 \002(\t\022\r\n\005state\030\002 \002(\005\022\r\n\005owner\030\003 \001(\t\022", "ed\030\016 \001(\005\"c\n\005Robot\022\013\n\003uid\030\001 \002(\t\022\r\n\005state\030",
"\016\n\006secret\030\004 \001(\t\022\020\n\010callback\030\005 \001(\t\022\r\n\005ext" + "\002 \002(\005\022\r\n\005owner\030\003 \001(\t\022\016\n\006secret\030\004 \001(\t\022\020\n\010" +
"ra\030\006 \001(\t\"(\n\017GetRobotsResult\022\025\n\005entry\030\001 \003" + "callback\030\005 \001(\t\022\r\n\005extra\030\006 \001(\t\"(\n\017GetRobo" +
"(\0132\006.Robot\"g\n\030UploadDeviceTokenRequest\022\020" + "tsResult\022\025\n\005entry\030\001 \003(\0132\006.Robot\"g\n\030Uploa" +
"\n\010platform\030\001 \002(\005\022\020\n\010app_name\030\002 \002(\t\022\024\n\014de" + "dDeviceTokenRequest\022\020\n\010platform\030\001 \002(\005\022\020\n" +
"vice_token\030\003 \002(\t\022\021\n\tpush_type\030\004 \002(\005\"\201\001\n\026" + "\010app_name\030\002 \002(\t\022\024\n\014device_token\030\003 \002(\t\022\021\n" +
"ModifyGroupInfoRequest\022\020\n\010group_id\030\001 \002(\t" + "\tpush_type\030\004 \002(\005\"\201\001\n\026ModifyGroupInfoRequ" +
"\022\014\n\004type\030\002 \002(\005\022\r\n\005value\030\003 \002(\t\022\017\n\007to_line" + "est\022\020\n\010group_id\030\001 \002(\t\022\014\n\004type\030\002 \002(\005\022\r\n\005v" +
"\030\004 \003(\005\022\'\n\016notify_content\030\005 \001(\0132\017.Message" + "alue\030\003 \002(\t\022\017\n\007to_line\030\004 \003(\005\022\'\n\016notify_co" +
"Content\"\203\001\n\026SetGroupManagerRequest\022\020\n\010gr" + "ntent\030\005 \001(\0132\017.MessageContent\"\203\001\n\026SetGrou" +
"oup_id\030\001 \002(\t\022\014\n\004type\030\002 \002(\005\022\017\n\007user_id\030\003 ", "pManagerRequest\022\020\n\010group_id\030\001 \002(\t\022\014\n\004typ",
"\003(\t\022\017\n\007to_line\030\004 \003(\005\022\'\n\016notify_content\030\005" + "e\030\002 \002(\005\022\017\n\007user_id\030\003 \003(\t\022\017\n\007to_line\030\004 \003(" +
" \001(\0132\017.MessageContent\"(\n\tInfoEntry\022\014\n\004ty" + "\005\022\'\n\016notify_content\030\005 \001(\0132\017.MessageConte" +
"pe\030\001 \002(\005\022\r\n\005value\030\002 \002(\t\"0\n\023ModifyMyInfoR" + "nt\"(\n\tInfoEntry\022\014\n\004type\030\001 \002(\005\022\r\n\005value\030\002" +
"equest\022\031\n\005entry\030\001 \003(\0132\n.InfoEntry\";\n\rNot" + " \002(\t\"0\n\023ModifyMyInfoRequest\022\031\n\005entry\030\001 \003" +
"ifyMessage\022\014\n\004type\030\001 \002(\005\022\014\n\004head\030\002 \002(\003\022\016" + "(\0132\n.InfoEntry\";\n\rNotifyMessage\022\014\n\004type\030" +
"\n\006target\030\003 \001(\t\"=\n\022PullMessageRequest\022\n\n\002" + "\001 \002(\005\022\014\n\004head\030\002 \002(\003\022\016\n\006target\030\003 \001(\t\"=\n\022P" +
"id\030\001 \002(\003\022\014\n\004type\030\002 \002(\005\022\r\n\005delay\030\003 \001(\003\"M\n" + "ullMessageRequest\022\n\n\002id\030\001 \002(\003\022\014\n\004type\030\002 " +
"\021PullMessageResult\022\031\n\007message\030\001 \003(\0132\010.Me" + "\002(\005\022\r\n\005delay\030\003 \001(\003\"M\n\021PullMessageResult\022" +
"ssage\022\017\n\007current\030\002 \002(\003\022\014\n\004head\030\003 \002(\003\"/\n\023" + "\031\n\007message\030\001 \003(\0132\010.Message\022\017\n\007current\030\002 " +
"PullGroupInfoResult\022\030\n\004info\030\001 \003(\0132\n.Grou", "\002(\003\022\014\n\004head\030\003 \002(\003\"/\n\023PullGroupInfoResult",
"pInfo\"6\n\026PullGroupMemberRequest\022\016\n\006targe" + "\022\030\n\004info\030\001 \003(\0132\n.GroupInfo\"6\n\026PullGroupM" +
"t\030\001 \002(\t\022\014\n\004head\030\002 \002(\003\"5\n\025PullGroupMember" + "emberRequest\022\016\n\006target\030\001 \002(\t\022\014\n\004head\030\002 \002" +
"Result\022\034\n\006member\030\001 \003(\0132\014.GroupMember\"-\n\013" + "(\003\"5\n\025PullGroupMemberResult\022\034\n\006member\030\001 " +
"UserRequest\022\013\n\003uid\030\001 \002(\t\022\021\n\tupdate_dt\030\002 " + "\003(\0132\014.GroupMember\"-\n\013UserRequest\022\013\n\003uid\030" +
"\001(\003\"0\n\017PullUserRequest\022\035\n\007request\030\001 \003(\0132" + "\001 \002(\t\022\021\n\tupdate_dt\030\002 \001(\003\"0\n\017PullUserRequ" +
"\014.UserRequest\"/\n\nUserResult\022\023\n\004user\030\001 \002(" + "est\022\035\n\007request\030\001 \003(\0132\014.UserRequest\"/\n\nUs" +
"\0132\005.User\022\014\n\004code\030\002 \002(\005\"-\n\016PullUserResult" + "erResult\022\023\n\004user\030\001 \002(\0132\005.User\022\014\n\004code\030\002 " +
"\022\033\n\006result\030\001 \003(\0132\013.UserResult\"^\n\020QuitGro" + "\002(\005\"-\n\016PullUserResult\022\033\n\006result\030\001 \003(\0132\013." +
"upRequest\022\020\n\010group_id\030\001 \002(\t\022\017\n\007to_line\030\002" + "UserResult\"^\n\020QuitGroupRequest\022\020\n\010group_" +
" \003(\005\022\'\n\016notify_content\030\003 \001(\0132\017.MessageCo", "id\030\001 \002(\t\022\017\n\007to_line\030\002 \003(\005\022\'\n\016notify_cont",
"ntent\"~\n\030RemoveGroupMemberRequest\022\020\n\010gro" + "ent\030\003 \001(\0132\017.MessageContent\"~\n\030RemoveGrou" +
"up_id\030\001 \002(\t\022\026\n\016removed_member\030\002 \003(\t\022\017\n\007t" + "pMemberRequest\022\020\n\010group_id\030\001 \002(\t\022\026\n\016remo" +
"o_line\030\003 \003(\005\022\'\n\016notify_content\030\004 \001(\0132\017.M" + "ved_member\030\002 \003(\t\022\017\n\007to_line\030\003 \003(\005\022\'\n\016not" +
"essageContent\"u\n\024TransferGroupRequest\022\020\n" + "ify_content\030\004 \001(\0132\017.MessageContent\"u\n\024Tr" +
"\010group_id\030\001 \002(\t\022\021\n\tnew_owner\030\002 \002(\t\022\017\n\007to" + "ansferGroupRequest\022\020\n\010group_id\030\001 \002(\t\022\021\n\t" +
"_line\030\003 \003(\005\022\'\n\016notify_content\030\004 \001(\0132\017.Me" + "new_owner\030\002 \002(\t\022\017\n\007to_line\030\003 \003(\005\022\'\n\016noti" +
"ssageContent\"\206\001\n\026ModifyGroupMemberAlias\022" + "fy_content\030\004 \001(\0132\017.MessageContent\"\206\001\n\026Mo" +
"\020\n\010group_id\030\001 \002(\t\022\r\n\005alias\030\002 \002(\t\022\017\n\007to_l" + "difyGroupMemberAlias\022\020\n\010group_id\030\001 \002(\t\022\r" +
"ine\030\003 \003(\005\022\'\n\016notify_content\030\004 \001(\0132\017.Mess" + "\n\005alias\030\002 \002(\t\022\017\n\007to_line\030\003 \003(\005\022\'\n\016notify" +
"ageContent\022\021\n\tmember_id\030\005 \001(\t\"\206\001\n\026Modify", "_content\030\004 \001(\0132\017.MessageContent\022\021\n\tmembe",
"GroupMemberExtra\022\020\n\010group_id\030\001 \002(\t\022\017\n\007to" + "r_id\030\005 \001(\t\"\206\001\n\026ModifyGroupMemberExtra\022\020\n" +
"_line\030\002 \003(\005\022\'\n\016notify_content\030\003 \001(\0132\017.Me" + "\010group_id\030\001 \002(\t\022\017\n\007to_line\030\002 \003(\005\022\'\n\016noti" +
"ssageContent\022\r\n\005extra\030\004 \001(\t\022\021\n\tmember_id" + "fy_content\030\003 \001(\0132\017.MessageContent\022\r\n\005ext" +
"\030\005 \001(\t\"P\n\020UserSettingEntry\022\r\n\005scope\030\001 \002(" + "ra\030\004 \001(\t\022\021\n\tmember_id\030\005 \001(\t\"P\n\020UserSetti" +
"\005\022\013\n\003key\030\002 \002(\t\022\r\n\005value\030\003 \002(\t\022\021\n\tupdate_" + "ngEntry\022\r\n\005scope\030\001 \002(\005\022\013\n\003key\030\002 \002(\t\022\r\n\005v" +
"dt\030\004 \002(\003\"A\n\024ModifyUserSettingReq\022\r\n\005scop" + "alue\030\003 \002(\t\022\021\n\tupdate_dt\030\004 \002(\003\"A\n\024ModifyU" +
"e\030\001 \002(\005\022\013\n\003key\030\002 \002(\t\022\r\n\005value\030\003 \002(\t\"\032\n\007V" + "serSettingReq\022\r\n\005scope\030\001 \002(\005\022\013\n\003key\030\002 \002(" +
"ersion\022\017\n\007version\030\001 \002(\003\"8\n\024GetUserSettin" + "\t\022\r\n\005value\030\003 \002(\t\"\032\n\007Version\022\017\n\007version\030\001" +
"gResult\022 \n\005entry\030\001 \003(\0132\021.UserSettingEntr" + " \002(\003\"8\n\024GetUserSettingResult\022 \n\005entry\030\001 " +
"y\"f\n\006Friend\022\013\n\003uid\030\001 \002(\t\022\r\n\005state\030\002 \002(\005\022", "\003(\0132\021.UserSettingEntry\"f\n\006Friend\022\013\n\003uid\030",
"\021\n\tupdate_dt\030\003 \002(\003\022\r\n\005alias\030\004 \001(\t\022\017\n\007bla" + "\001 \002(\t\022\r\n\005state\030\002 \002(\005\022\021\n\tupdate_dt\030\003 \002(\003\022" +
"cked\030\005 \001(\005\022\r\n\005extra\030\006 \001(\t\"*\n\020GetFriendsR" + "\r\n\005alias\030\004 \001(\t\022\017\n\007blacked\030\005 \001(\005\022\r\n\005extra" +
"esult\022\026\n\005entry\030\001 \003(\0132\007.Friend\"7\n\026GetFrie" + "\030\006 \001(\t\"*\n\020GetFriendsResult\022\026\n\005entry\030\001 \003(" +
"ndRequestResult\022\035\n\005entry\030\001 \003(\0132\016.FriendR" + "\0132\007.Friend\"7\n\026GetFriendRequestResult\022\035\n\005" +
"equest\"\243\001\n\021ConnectAckPayload\022\020\n\010msg_head" + "entry\030\001 \003(\0132\016.FriendRequest\"\243\001\n\021ConnectA" +
"\030\001 \001(\003\022\023\n\013friend_head\030\002 \001(\003\022\026\n\016friend_rq" + "ckPayload\022\020\n\010msg_head\030\001 \001(\003\022\023\n\013friend_he" +
"_head\030\003 \001(\003\022\024\n\014setting_head\030\004 \001(\003\022\021\n\tnod" + "ad\030\002 \001(\003\022\026\n\016friend_rq_head\030\003 \001(\003\022\024\n\014sett" +
"e_addr\030\005 \001(\t\022\021\n\tnode_port\030\006 \001(\005\022\023\n\013serve" + "ing_head\030\004 \001(\003\022\021\n\tnode_addr\030\005 \001(\t\022\021\n\tnod" +
"r_time\030\007 \001(\003\"P\n\rIMHttpWrapper\022\r\n\005token\030\001" + "e_port\030\006 \001(\005\022\023\n\013server_time\030\007 \001(\003\"P\n\rIMH" +
" \002(\t\022\021\n\tclient_id\030\002 \002(\t\022\017\n\007request\030\003 \002(\t", "ttpWrapper\022\r\n\005token\030\001 \002(\t\022\021\n\tclient_id\030\002",
"\022\014\n\004data\030\004 \001(\014\"A\n\021SearchUserRequest\022\017\n\007k" + " \002(\t\022\017\n\007request\030\003 \002(\t\022\014\n\004data\030\004 \001(\014\"A\n\021S" +
"eyword\030\001 \002(\t\022\r\n\005fuzzy\030\002 \001(\005\022\014\n\004page\030\003 \001(" + "earchUserRequest\022\017\n\007keyword\030\001 \002(\t\022\r\n\005fuz" +
"\005\"(\n\020SearchUserResult\022\024\n\005entry\030\001 \003(\0132\005.U" + "zy\030\002 \001(\005\022\014\n\004page\030\003 \001(\005\"(\n\020SearchUserResu" +
"ser\"@\n\026GetChatroomInfoRequest\022\023\n\013chatroo" + "lt\022\024\n\005entry\030\001 \003(\0132\005.User\"@\n\026GetChatroomI" +
"m_id\030\001 \002(\t\022\021\n\tupdate_dt\030\002 \001(\003\"\227\001\n\014Chatro" + "nfoRequest\022\023\n\013chatroom_id\030\001 \002(\t\022\021\n\tupdat" +
"omInfo\022\r\n\005title\030\001 \002(\t\022\014\n\004desc\030\002 \001(\t\022\020\n\010p" + "e_dt\030\002 \001(\003\"\227\001\n\014ChatroomInfo\022\r\n\005title\030\001 \002" +
"ortrait\030\003 \001(\t\022\024\n\014member_count\030\004 \001(\005\022\021\n\tc" + "(\t\022\014\n\004desc\030\002 \001(\t\022\020\n\010portrait\030\003 \001(\t\022\024\n\014me" +
"reate_dt\030\005 \001(\003\022\021\n\tupdate_dt\030\006 \001(\003\022\r\n\005ext" + "mber_count\030\004 \001(\005\022\021\n\tcreate_dt\030\005 \001(\003\022\021\n\tu" +
"ra\030\007 \001(\t\022\r\n\005state\030\010 \001(\005\"F\n\034GetChatroomMe" + "pdate_dt\030\006 \001(\003\022\r\n\005extra\030\007 \001(\t\022\r\n\005state\030\010" +
"mberInfoRequest\022\023\n\013chatroom_id\030\001 \002(\t\022\021\n\t", " \001(\005\"F\n\034GetChatroomMemberInfoRequest\022\023\n\013",
"max_count\030\002 \001(\005\";\n\022ChatroomMemberInfo\022\024\n" + "chatroom_id\030\001 \002(\t\022\021\n\tmax_count\030\002 \001(\005\";\n\022" +
"\014member_count\030\001 \001(\005\022\017\n\007members\030\002 \003(\t\"\026\n\010" + "ChatroomMemberInfo\022\024\n\014member_count\030\001 \001(\005" +
"INT64Buf\022\n\n\002id\030\001 \002(\003\"4\n\023NotifyRecallMess" + "\022\017\n\007members\030\002 \003(\t\"\026\n\010INT64Buf\022\n\n\002id\030\001 \002(" +
"age\022\n\n\002id\030\001 \002(\003\022\021\n\tfrom_user\030\002 \002(\t\"/\n\020Bl" + "\003\"4\n\023NotifyRecallMessage\022\n\n\002id\030\001 \002(\003\022\021\n\t" +
"ackUserRequest\022\013\n\003uid\030\001 \002(\t\022\016\n\006status\030\002 " + "from_user\030\002 \002(\t\"/\n\020BlackUserRequest\022\013\n\003u" +
"\002(\005\"\323\001\n\014RouteRequest\022\013\n\003app\030\001 \001(\t\022\020\n\010pla" + "id\030\001 \002(\t\022\016\n\006status\030\002 \002(\005\"\323\001\n\014RouteReques" +
"tform\030\002 \001(\005\022\021\n\tpush_type\030\003 \001(\005\022\023\n\013device" + "t\022\013\n\003app\030\001 \001(\t\022\020\n\010platform\030\002 \001(\005\022\021\n\tpush" +
"_name\030\004 \001(\t\022\026\n\016device_version\030\005 \001(\t\022\022\n\np" + "_type\030\003 \001(\005\022\023\n\013device_name\030\004 \001(\t\022\026\n\016devi" +
"hone_name\030\006 \001(\t\022\020\n\010language\030\007 \001(\t\022\024\n\014car" + "ce_version\030\005 \001(\t\022\022\n\nphone_name\030\006 \001(\t\022\020\n\010" +
"rier_name\030\010 \001(\t\022\023\n\013app_version\030\t \001(\t\022\023\n\013", "language\030\007 \001(\t\022\024\n\014carrier_name\030\010 \001(\t\022\023\n\013",
"sdk_version\030\n \001(\t\"D\n\rRouteResponse\022\014\n\004ho" + "app_version\030\t \001(\t\022\023\n\013sdk_version\030\n \001(\t\"D" +
"st\030\001 \002(\t\022\021\n\tlong_port\030\002 \002(\005\022\022\n\nshort_por" + "\n\rRouteResponse\022\014\n\004host\030\001 \002(\t\022\021\n\tlong_po" +
"t\030\003 \002(\005\"G\n\017GetTokenRequest\022\017\n\007user_id\030\001 " + "rt\030\002 \002(\005\022\022\n\nshort_port\030\003 \002(\005\"G\n\017GetToken" +
"\002(\t\022\021\n\tclient_id\030\002 \002(\t\022\020\n\010platform\030\003 \001(\005" + "Request\022\017\n\007user_id\030\001 \002(\t\022\021\n\tclient_id\030\002 " +
"\"r\n\022LoadRemoteMessages\022#\n\014conversation\030\001" + "\002(\t\022\020\n\010platform\030\003 \001(\005\"r\n\022LoadRemoteMessa" +
" \002(\0132\r.Conversation\022\022\n\nbefore_uid\030\002 \002(\003\022" + "ges\022#\n\014conversation\030\001 \002(\0132\r.Conversation" +
"\r\n\005count\030\003 \002(\005\022\024\n\014content_type\030\004 \003(\005\"a\n\020" + "\022\022\n\nbefore_uid\030\002 \002(\003\022\r\n\005count\030\003 \002(\005\022\024\n\014c" +
"MultiCastMessage\022\021\n\tfrom_user\030\001 \002(\t\022 \n\007c" + "ontent_type\030\004 \003(\005\"a\n\020MultiCastMessage\022\021\n" +
"ontent\030\002 \002(\0132\017.MessageContent\022\n\n\002to\030\003 \003(" + "\tfrom_user\030\001 \002(\t\022 \n\007content\030\002 \002(\0132\017.Mess" +
"\t\022\014\n\004line\030\004 \002(\005\"E\n\035RecallMultiCastMessag", "ageContent\022\n\n\002to\030\003 \003(\t\022\014\n\004line\030\004 \002(\005\"E\n\035",
"eRequest\022\022\n\nmessage_id\030\001 \002(\003\022\020\n\010receiver" + "RecallMultiCastMessageRequest\022\022\n\nmessage" +
"\030\002 \003(\t\"@\n\017AuthCodeRequest\022\021\n\ttarget_id\030\001" + "_id\030\001 \002(\003\022\020\n\010receiver\030\002 \003(\t\"@\n\017AuthCodeR" +
" \002(\t\022\014\n\004type\030\002 \002(\005\022\014\n\004host\030\003 \002(\t\"o\n\030Appl" + "equest\022\021\n\ttarget_id\030\001 \002(\t\022\014\n\004type\030\002 \002(\005\022" +
"icationConfigRequest\022\r\n\005appId\030\001 \002(\t\022\017\n\007a" + "\014\n\004host\030\003 \002(\t\"o\n\030ApplicationConfigReques" +
"ppType\030\002 \002(\005\022\021\n\ttimestamp\030\003 \002(\003\022\r\n\005nonce" + "t\022\r\n\005appId\030\001 \002(\t\022\017\n\007appType\030\002 \002(\005\022\021\n\ttim" +
"\030\004 \002(\t\022\021\n\tsignature\030\005 \002(\tB#\n\025cn.wildfire" + "estamp\030\003 \002(\003\022\r\n\005nonce\030\004 \002(\t\022\021\n\tsignature" +
"chat.protoB\nWFCMessage" "\030\005 \002(\tB/\n\025cn.wildfirechat.protoB\nWFCMess" +
"ageZ\n./go;proto"
}; };
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
@@ -67420,7 +67502,7 @@ public final class WFCMessage {
internal_static_GroupInfo_fieldAccessorTable = new internal_static_GroupInfo_fieldAccessorTable = new
com.google.protobuf.GeneratedMessage.FieldAccessorTable( com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_GroupInfo_descriptor, internal_static_GroupInfo_descriptor,
new java.lang.String[] { "TargetId", "Name", "Portrait", "Owner", "Type", "MemberCount", "Extra", "UpdateDt", "MemberUpdateDt", "Mute", "JoinType", "PrivateChat", "Searchable", "MaxMemberCount", "HistoryMessage", }); new java.lang.String[] { "TargetId", "Name", "Portrait", "Owner", "Type", "MemberCount", "Extra", "UpdateDt", "MemberUpdateDt", "Mute", "JoinType", "PrivateChat", "Searchable", "MaxMemberCount", "HistoryMessage", "SuperGroup", });
internal_static_GroupMember_descriptor = internal_static_GroupMember_descriptor =
getDescriptor().getMessageTypes().get(3); getDescriptor().getMessageTypes().get(3);
internal_static_GroupMember_fieldAccessorTable = new internal_static_GroupMember_fieldAccessorTable = new
@@ -107,15 +107,20 @@ public class AES {
} }
return key; return key;
} }
public static byte[] AESDecrypt(byte[] sSrc, String userKey, boolean checkTime) { public static byte[] AESDecrypt(byte[] sSrc, String userKey, boolean checkTime) {
return AESDecrypt(sSrc, userKey, checkTime, null);
}
public static byte[] AESDecrypt(byte[] sSrc, String userKey, boolean checkTime, boolean[] invalidTime) {
byte[] aesKey = aes_key; byte[] aesKey = aes_key;
if (userKey != null && !userKey.isEmpty()) { if (userKey != null && !userKey.isEmpty()) {
aesKey = convertUserKey(userKey); aesKey = convertUserKey(userKey);
} }
return AESDecrypt(sSrc, aesKey, checkTime); return AESDecrypt(sSrc, aesKey, checkTime, invalidTime);
} }
public static byte[] AESDecrypt(byte[] sSrc, byte[] aesKey, boolean checkTime) { public static byte[] AESDecrypt(byte[] sSrc, byte[] aesKey, boolean checkTime, boolean[] invalidTime) {
try { try {
// 判断Key是否正确 // 判断Key是否正确
@@ -152,6 +157,9 @@ public class AES {
int curhour = (int) ((System.currentTimeMillis()/1000 - 1514736000)/3600); int curhour = (int) ((System.currentTimeMillis()/1000 - 1514736000)/3600);
if (curhour - hours > 24 && checkTime) { if (curhour - hours > 24 && checkTime) {
if(invalidTime != null) {
invalidTime[0] = true;
}
return null; return null;
} }
byte[] neworiginal = new byte[original.length - 4]; byte[] neworiginal = new byte[original.length - 4];
+1 -1
View File
@@ -6,7 +6,7 @@
<!--<relativePath>../pom.xml</relativePath>--> <!--<relativePath>../pom.xml</relativePath>-->
<artifactId>wildfirechat-parent</artifactId> <artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId> <groupId>cn.wildfirechat</groupId>
<version>1.1.2</version> <version>1.1.3</version>
</parent> </parent>
<artifactId>distribution</artifactId> <artifactId>distribution</artifactId>
@@ -318,6 +318,10 @@ push.ios.server.address http://localhost:8085/ios/push
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!! ##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
#message.mentionmsg.forward.url http://localhost:8888/im_event/message #message.mentionmsg.forward.url http://localhost:8888/im_event/message
##撤回消息转发地址,当用户撤回消息会回调此地址。
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
#message.recallmsg.forward.url http://localhost:8888/im_event/recall_message
##设备信息转发地址 ##设备信息转发地址
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!! ##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
#things_message.forward.url http://localhost:8087/im_event/things/message #things_message.forward.url http://localhost:8087/im_event/things/message
@@ -72,6 +72,9 @@ rem set JAVA_OPTS=%JAVA_OPTS% -XX:+UseGCLogFileRotation
rem set JAVA_OPTS=%JAVA_OPTS% -XX:NumberOfGCLogFiles=10 rem set JAVA_OPTS=%JAVA_OPTS% -XX:NumberOfGCLogFiles=10
rem set JAVA_OPTS=%JAVA_OPTS% -XX:GCLogFileSize=10M" rem set JAVA_OPTS=%JAVA_OPTS% -XX:GCLogFileSize=10M"
rem If the JDK version is 9 or above, please open this configuration.
rem set JAVA_OPTS=%JAVA_OPTS% --add-modules java.se --add-exports java.base/jdk.internal.ref=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.management/sun.management=ALL-UNNAMED --add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED
echo echo
echo "Please set Xmx and Xms parameters!" echo "Please set Xmx and Xms parameters!"
echo "Please set Xmx and Xms parameters!" echo "Please set Xmx and Xms parameters!"
@@ -33,6 +33,8 @@ else
fi fi
export JAVA export JAVA
$JAVA -version
WILDFIRECHAT_CONFIG_PATH=$WILDFIRECHAT_HOME WILDFIRECHAT_CONFIG_PATH=$WILDFIRECHAT_HOME
LOG_FILE=$WILDFIRECHAT_CONFIG_PATH/config/log4j2.xml LOG_FILE=$WILDFIRECHAT_CONFIG_PATH/config/log4j2.xml
@@ -84,6 +86,8 @@ JAVA_OPTS="$JAVA_OPTS -XX:MaxGCPauseMillis=500"
#JAVA_OPTS="$JAVA_OPTS -XX:NumberOfGCLogFiles=10" #JAVA_OPTS="$JAVA_OPTS -XX:NumberOfGCLogFiles=10"
#JAVA_OPTS="$JAVA_OPTS -XX:GCLogFileSize=10M" #JAVA_OPTS="$JAVA_OPTS -XX:GCLogFileSize=10M"
#如果JDK版本是9及以上,请打开这个配置
#JAVA_OPTS="$JAVA_OPTS --add-modules java.se --add-exports java.base/jdk.internal.ref=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.management/sun.management=ALL-UNNAMED --add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED"
echo "警告:没有设置JVM内存参数!" echo "警告:没有设置JVM内存参数!"
echo "请设置JVM参数Xmx和Xms,设置为您为IM服务预留的内存大小,注意需要刨除操作系统占用,如果有其它系统也需要相应去除占用。" echo "请设置JVM参数Xmx和Xms,设置为您为IM服务预留的内存大小,注意需要刨除操作系统占用,如果有其它系统也需要相应去除占用。"
+1 -1
View File
@@ -12,7 +12,7 @@
<artifactId>wildfirechat-parent</artifactId> <artifactId>wildfirechat-parent</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<version>1.1.2</version> <version>1.1.3</version>
<name>Wildfire Chat</name> <name>Wildfire Chat</name>
<description>Wildfire Chat Server</description> <description>Wildfire Chat Server</description>
<inceptionYear>2019</inceptionYear> <inceptionYear>2019</inceptionYear>
+10
View File
@@ -12,6 +12,16 @@
# 更新记录 # 更新记录
--------------
Release note 1.1.3:
1. 添加服务器和客户端时间检查功能。
2. 解决用户被block后session失效的问题。
3. 添加消息撤回回调。
4. 优化群组撤回逻辑。
5. 解决用户离开群组后还能修改群昵称的问题。
6. 修改server api修改好友关系回调数据错误问题。
7. 同步超级群组数据库和数据。
-------------- --------------
Release note 1.1.2: Release note 1.1.2:
1. 会议SDK添加查询会议是否存在的接口 1. 会议SDK添加查询会议是否存在的接口
+1 -1
View File
@@ -3,7 +3,7 @@
<parent> <parent>
<artifactId>wildfirechat-parent</artifactId> <artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId> <groupId>cn.wildfirechat</groupId>
<version>1.1.2</version> <version>1.1.3</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@@ -50,10 +50,10 @@ public class Main {
//admin使用的是18080端口,超级管理接口,理论上不能对外开放端口,也不能让非内部服务知悉密钥。 //admin使用的是18080端口,超级管理接口,理论上不能对外开放端口,也不能让非内部服务知悉密钥。
// testAdmin(); testAdmin();
//Robot和Channel都是使用的80端口,第三方可以创建或者为第三方创建,第三方可以使用robot或者channel与IM系统进行对接。 //Robot和Channel都是使用的80端口,第三方可以创建或者为第三方创建,第三方可以使用robot或者channel与IM系统进行对接。
// testRobot(); testRobot();
testChannel(); testChannel();
} }