Compare commits

...
4 Commits
14 changed files with 222 additions and 70 deletions
+1 -1
View File
@@ -5,7 +5,7 @@
<relativePath>../</relativePath>
<artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId>
<version>1.1.5</version>
<version>1.1.6</version>
</parent>
<artifactId>moquette-broker</artifactId>
@@ -0,0 +1,23 @@
package io.moquette.imhandler;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage;
import io.moquette.spi.impl.Qos1PublishHandler;
import io.netty.buffer.ByteBuf;
import win.liyufan.im.IMTopic;
import java.util.List;
@Handler(IMTopic.ListenedChannelListTopic)
public class ChannelListenedListHandler extends IMHandler<Void> {
@Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, ProtoConstants.RequestSourceType requestSourceType, Void request, Qos1PublishHandler.IMCallback callback) {
List<String> channelInfoList = m_messagesStore.getListenedChannels(fromUser);
WFCMessage.IDListBuf.Builder builder = WFCMessage.IDListBuf.newBuilder();
builder.addAllId(channelInfoList);
byte[] data = builder.build().toByteArray();
ackPayload.ensureWritable(data.length).writeBytes(data);
return ErrorCode.ERROR_CODE_SUCCESS;
}
}
@@ -39,6 +39,7 @@ import static cn.wildfirechat.common.IMExceptionEvent.EventType.RDBS_Exception;
import static cn.wildfirechat.proto.ProtoConstants.PersistFlag.Transparent;
import static io.moquette.server.Constants.MAX_MESSAGE_QUEUE;
import static cn.wildfirechat.proto.ProtoConstants.SearchUserType.*;
import static win.liyufan.im.UserSettingScope.kUserSettingPrivacySearchable;
public class DatabaseStore {
private static final Logger LOG = LoggerFactory.getLogger(DatabaseStore.class);
@@ -161,18 +162,15 @@ public class DatabaseStore {
}
return null;
}
//searchType
// 0 模糊匹配displayName, 精确匹配账户名和电话号码
// 1 精确匹配账户名和电话号码
// 2 精确匹配账户名
// 3 精确匹配电话号码
List<WFCMessage.User> searchUserFromDB(String keyword, int searchType, int page) {
List<WFCMessage.User> searchUserByNameMobile(String keyword, int searchType, int page) {
ArrayList<WFCMessage.User> out = new ArrayList<>();
if(page > 0) {
return out;
}
Connection connection = null;
PreparedStatement statement = null;
ResultSet rs = null;
ArrayList<WFCMessage.User> out = new ArrayList<>();
try {
connection = DBUtil.getConnection();
String sql = "select `_uid`, `_name`" +
@@ -185,61 +183,34 @@ public class DatabaseStore {
", `_company`" +
", `_social`" +
", `_extra`" +
", `_dt` from t_user";
switch (searchType) {
case SearchUserType_Name_Mobile:
sql += " where (`_name` = ? or `_mobile` = ?) ";
break;
case SearchUserType_Name:
sql += " where `_name` = ? ";
break;
case SearchUserType_Mobile:
sql += " where `_mobile` = ? ";
break;
case SearchUserType_General:
default:
sql += " where (`_display_name` like ? or `_name` = ? or `_mobile` = ?) ";
break;
}
", `_dt`, `_type` from t_user";
if(searchType == SearchUserType_Name) {
sql += " where `_name` = ? ";
} else if(searchType == SearchUserType_Mobile) {
sql += " where `_mobile` = ? ";
} else {
sql += " where (`_name` = ? or `_mobile` = ?) ";
}
sql += " and `_type` <> 2 and `_deleted` = 0"; //can search normal user(0) and robot(1) and admin(100), can not search things
if (searchType == SearchUserType_Name_Mobile || searchType == SearchUserType_Name || searchType == SearchUserType_Mobile) {
if(searchType == SearchUserType_Name || searchType == SearchUserType_Mobile) {
sql += " limit 1";
} else {
sql += " limit 20";
}
if (page > 0) {
sql += " offset " + page * 20;
sql += " limit 2";
}
statement = connection.prepareStatement(sql);
int index = 1;
switch (searchType) {
case SearchUserType_Name_Mobile:
statement.setString(index++, keyword);
statement.setString(index++, keyword);
break;
case SearchUserType_Name:
case SearchUserType_Mobile:
statement.setString(index++, keyword);
break;
case SearchUserType_General:
default:
statement.setString(index++, "%" + keyword + "%");
statement.setString(index++, keyword);
statement.setString(index++, keyword);
break;
statement.setString(1, keyword);
if(searchType != SearchUserType_Name && searchType != SearchUserType_Mobile) {
statement.setString(2, keyword);
}
rs = statement.executeQuery();
while (rs.next()) {
WFCMessage.User.Builder builder = WFCMessage.User.newBuilder();
index = 1;
int index = 1;
String value = rs.getString(index++);
value = (value == null ? "" : value);
@@ -287,6 +258,9 @@ public class DatabaseStore {
long longValue = rs.getLong(index++);
builder.setUpdateDt(longValue);
int type = rs.getInt(index++);
builder.setType( type);
WFCMessage.User user = builder.build();
out.add(user);
@@ -298,6 +272,142 @@ public class DatabaseStore {
} finally {
DBUtil.closeDB(connection, statement, rs);
}
List<WFCMessage.User> filter = new ArrayList<>();
for (WFCMessage.User user : out) {
WFCMessage.UserSettingEntry userSettingEntry = Server.getServer().getStore().messagesStore().getUserSetting(user.getUid(), kUserSettingPrivacySearchable, null);
if(userSettingEntry != null) {
int value = 0;
try {
value = StringUtil.isNullOrEmpty(userSettingEntry.getValue())?0:Integer.parseInt(userSettingEntry.getValue());
} catch (NumberFormatException e) {
e.printStackTrace();
}
if((value & ProtoConstants.DisableSearchMask.DisableSearchNameMask) > 0) {
if (searchType == SearchUserType_Name) {
filter.add(user);
continue;
} else if(searchType != SearchUserType_Mobile) {
if(keyword.equals(user.getName())) {
if(!keyword.equals(user.getMobile())) {
filter.add(user);
continue;
} else if((value & ProtoConstants.DisableSearchMask.DisableSearchMobileMask) > 0) {
filter.add(user);
continue;
}
}
}
}
if ((value & ProtoConstants.DisableSearchMask.DisableSearchMobileMask) > 0) {
if (searchType == SearchUserType_Mobile) {
filter.add(user);
} else if(searchType != SearchUserType_Name) {
if(keyword.equals(user.getMobile()) && !keyword.equals(user.getName())) {
filter.add(user);
}
}
}
}
}
out.removeAll(filter);
return out;
}
List<WFCMessage.User> searchUserByDisplayName(String keyword, int page) {
Connection connection = null;
PreparedStatement statement = null;
ResultSet rs = null;
ArrayList<WFCMessage.User> out = new ArrayList<>();
try {
connection = DBUtil.getConnection();
String sql = "select u._uid, u._name, u._display_name, u._portrait, u._mobile, u._gender, u._email, u._address, u._company, u._social, u._extra, u._dt, u._type " +
" from t_user u left join (select _uid, _value from t_user_setting where _scope = 27) s on u._uid = s._uid " +
" where u._display_name like ? and u._type <> 2 and u._deleted = 0 and (s._value is null or (s._value <> 1 and s._value <> 3 and s._value <> 5 and s._value <> 7)) limit 20";
if (page > 0) {
sql += " offset " + page * 20;
}
statement = connection.prepareStatement(sql);
statement.setString(1, "%" + keyword + "%");
rs = statement.executeQuery();
while (rs.next()) {
WFCMessage.User.Builder builder = WFCMessage.User.newBuilder();
int index = 1;
String value = rs.getString(index++);
value = (value == null ? "" : value);
builder.setUid(value);
value = rs.getString(index++);
value = (value == null ? "" : value);
builder.setName(value);
value = rs.getString(index++);
value = (value == null ? "" : value);
builder.setDisplayName(value);
value = rs.getString(index++);
value = (value == null ? "" : value);
builder.setPortrait(value);
value = rs.getString(index++);
value = (value == null ? "" : value);
builder.setMobile(value);
int gender = rs.getInt(index++);
builder.setGender(gender);
value = rs.getString(index++);
value = (value == null ? "" : value);
builder.setEmail(value);
value = rs.getString(index++);
value = (value == null ? "" : value);
builder.setAddress(value);
value = rs.getString(index++);
value = (value == null ? "" : value);
builder.setCompany(value);
value = rs.getString(index++);
value = (value == null ? "" : value);
builder.setSocial(value);
value = rs.getString(index++);
value = (value == null ? "" : value);
builder.setExtra(value);
long longValue = rs.getLong(index++);
builder.setUpdateDt(longValue);
int type = rs.getInt(index++);
builder.setType(type);
WFCMessage.User user = builder.build();
out.add(user);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
return out;
}
List<WFCMessage.User> searchUserFromDB(String keyword, int searchType, int page) {
List<WFCMessage.User> out = searchUserByNameMobile(keyword, searchType, page);
if(searchType == SearchUserType_General) {
List<WFCMessage.User> general = searchUserByDisplayName(keyword, page);
out.addAll(general);
}
return out;
}
@@ -4139,6 +4139,11 @@ public class MemoryMessagesStore implements IMessagesStore {
return databaseStore.searchChannelFromDB(keyword, buzzy, page);
}
@Override
public List<String> getListenedChannels(String userId) {
return databaseStore.getUserChannels(userId);
}
@Override
public ErrorCode listenChannel(String operator, String channelId, boolean listen) {
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
@@ -218,6 +218,7 @@ public interface IMessagesStore {
ErrorCode transferChannel(String operator, String channelId, String newOwner);
ErrorCode destroyChannel(String operator, String channelId, boolean isAdmin);
List<WFCMessage.ChannelInfo> searchChannel(String keyword, boolean buzzy, int page);
List<String> getListenedChannels(String userId);
ErrorCode listenChannel(String operator, String channelId, boolean listen);
WFCMessage.ChannelInfo getChannelInfo(String channelId);
boolean canSendMessageInChannel(String user, String channelId);
@@ -243,20 +243,15 @@ public class Qos1PublishHandler extends QosPublishHandler {
String imtopic = topic.getTopic();
ByteBuf payload = msg.payload();
byte[] payloadContent = readBytesAndRewind(payload);
if(payloadContent.length == 0) {
ByteBuf ackPayload = Unpooled.buffer();
ackPayload.ensureWritable(1).writeByte(ERROR_CODE_INVALID_DATA.getCode());
sendPubAck(clientID, messageID, ackPayload, ERROR_CODE_INVALID_DATA);
return;
}
MemorySessionStore.Session session = m_sessionStore.getSession(clientID);
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;
if(payloadContent.length > 0) {
MemorySessionStore.Session session = m_sessionStore.getSession(clientID);
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);
@@ -77,6 +77,7 @@ public interface IMTopic {
String ChannelSearchTopic = "CHS";
String ChannelListenTopic = "CHL";
String ChannelPullTopic = "CHP";
String ListenedChannelListTopic = "CHLL";
String GetTokenTopic = "GETTOKEN";
String DestroyUserTopic = "DESTROYUSER";
@@ -14,5 +14,10 @@ public interface UserSettingScope {
int kUserSettingConversationDraft = 19;
int kUserSettingDisableSyncDraft = 20;
int kUserSettingVoipSilent = 21;
int kUserSettingPttReserved = 22;
int kUserSettingCustomState = 23;
int kUserSettingDisableSecretChat = 24;
int kUserSettingPttSilent = 25;
int kUserSettingGroupRemark = 26;
int kUserSettingPrivacySearchable = 27;
}
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId>
<version>1.1.5</version>
<version>1.1.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -218,6 +218,12 @@ public class ProtoConstants {
int SearchUserType_Mobile = 3;
}
public interface DisableSearchMask {
int DisableSearchDisplayNameMask = 1;
int DisableSearchNameMask = 2;
int DisableSearchMobileMask = 4;
}
public interface UserStatus {
int Normal = 0;
int Muted = 1;
+1 -1
View File
@@ -6,7 +6,7 @@
<!--<relativePath>../pom.xml</relativePath>-->
<artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId>
<version>1.1.5</version>
<version>1.1.6</version>
</parent>
<artifactId>distribution</artifactId>
+1 -1
View File
@@ -12,7 +12,7 @@
<artifactId>wildfirechat-parent</artifactId>
<packaging>pom</packaging>
<version>1.1.5</version>
<version>1.1.6</version>
<name>Wildfire Chat</name>
<description>Wildfire Chat Server</description>
<inceptionYear>2019</inceptionYear>
+6
View File
@@ -12,6 +12,12 @@
# 更新记录
--------------
Release note 1.1.6:
1. 支持用户设置查找自己的方法。
2. 解决获取用户信息返回type无效的问题。
3. 添加用户获取频道的功能。
--------------
Release note 1.1.5:
1. 添加获取所有用户的Server API。
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId>
<version>1.1.5</version>
<version>1.1.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>